--- embedaddon/sudo/src/sudo.c 2013/07/22 10:46:13 1.1.1.4 +++ embedaddon/sudo/src/sudo.c 2014/06/15 16:12:55 1.1.1.6 @@ -54,7 +54,7 @@ #include #include #include -#if TIME_WITH_SYS_TIME +#ifdef TIME_WITH_SYS_TIME # include #endif #ifdef HAVE_LOGIN_CAP_H @@ -83,18 +83,18 @@ # include #endif /* HAVE_GETPRPWNAM && HAVE_SET_AUTH_PARAMETERS */ +#include #include "sudo.h" #include "sudo_plugin.h" #include "sudo_plugin_int.h" -#include "sudo_usage.h" /* * Local variables */ struct plugin_container policy_plugin; -struct plugin_container_list io_plugins; +struct plugin_container_list io_plugins = TAILQ_HEAD_INITIALIZER(io_plugins); struct user_details user_details; -const char *list_user, *runas_user, *runas_group; /* extern for parse_args.c */ +const char *list_user; /* extern for parse_args.c */ static struct command_details command_details; static int sudo_mode; @@ -133,8 +133,8 @@ static void iolog_unlink(struct plugin_container *plug #ifdef RLIMIT_CORE static struct rlimit corelimit; -#endif /* RLIMIT_CORE */ -#if defined(__linux__) +#endif +#ifdef __linux__ static struct rlimit nproclimit; #endif @@ -200,7 +200,7 @@ main(int argc, char *argv[], char *envp[]) /* Load plugins. */ if (!sudo_load_plugins(&policy_plugin, &io_plugins)) - fatalx(_("fatal error, unable to load plugins")); + fatalx(U_("fatal error, unable to load plugins")); /* Open policy plugin. */ ok = policy_open(&policy_plugin, settings, user_info, envp); @@ -208,7 +208,7 @@ main(int argc, char *argv[], char *envp[]) if (ok == -2) usage(1); else - fatalx(_("unable to initialize policy plugin")); + fatalx(U_("unable to initialize policy plugin")); } init_signals(); @@ -216,7 +216,7 @@ main(int argc, char *argv[], char *envp[]) switch (sudo_mode & MODE_MASK) { case MODE_VERSION: policy_show_version(&policy_plugin, !user_details.uid); - tq_foreach_fwd(&io_plugins, plugin) { + TAILQ_FOREACH(plugin, &io_plugins, entries) { ok = iolog_open(plugin, settings, user_info, NULL, nargc, nargv, envp); if (ok != -1) @@ -250,8 +250,7 @@ main(int argc, char *argv[], char *envp[]) exit(1); /* plugin printed error message */ } /* Open I/O plugins once policy plugin succeeds. */ - for (plugin = io_plugins.first; plugin != NULL; plugin = next) { - next = plugin->next; + TAILQ_FOREACH_SAFE(plugin, &io_plugins, entries, next) { ok = iolog_open(plugin, settings, user_info, command_info, nargc, nargv, envp); switch (ok) { @@ -265,7 +264,7 @@ main(int argc, char *argv[], char *envp[]) usage(1); break; default: - fatalx(_("error initializing I/O plugin %s"), + fatalx(U_("error initializing I/O plugin %s"), plugin->name); } } @@ -291,7 +290,7 @@ main(int argc, char *argv[], char *envp[]) /* The close method was called by sudo_edit/run_command. */ break; default: - fatalx(_("unexpected sudo mode 0x%x"), sudo_mode); + fatalx(U_("unexpected sudo mode 0x%x"), sudo_mode); } sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, exitcode); exit(exitcode); @@ -300,9 +299,9 @@ main(int argc, char *argv[], char *envp[]) int os_init_common(int argc, char *argv[], char *envp[]) { -#if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME) - if (argc > 0) - setprogname(argv[0]); + initprogname(argc > 0 ? argv[0] : "sudo"); +#ifdef STATIC_SUDOERS_PLUGIN + preload_static_symbols(); #endif return 0; } @@ -326,7 +325,7 @@ fix_fds(void) miss[STDERR_FILENO] = fcntl(STDERR_FILENO, F_GETFL, 0) == -1; if (miss[STDIN_FILENO] || miss[STDOUT_FILENO] || miss[STDERR_FILENO]) { if ((devnull = open(_PATH_DEVNULL, O_RDWR, 0644)) == -1) - fatal(_("unable to open %s"), _PATH_DEVNULL); + fatal(U_("unable to open %s"), _PATH_DEVNULL); if (miss[STDIN_FILENO] && dup2(devnull, STDIN_FILENO) == -1) fatal("dup2"); if (miss[STDOUT_FILENO] && dup2(devnull, STDOUT_FILENO) == -1) @@ -354,7 +353,7 @@ fill_group_list(struct user_details *ud, int system_ma * trying getgrouplist() until we have enough room in the array. */ ud->ngroups = sudo_conf_max_groups(); - if (ud->ngroups != -1) { + if (ud->ngroups > 0) { ud->groups = emalloc2(ud->ngroups, sizeof(GETGROUPS_T)); /* No error on insufficient space if user specified max_groups. */ (void)getgrouplist(ud->username, ud->gid, ud->groups, &ud->ngroups); @@ -411,7 +410,7 @@ get_user_groups(struct user_details *ud) * Typically, this is because NFS can only support up to 16 groups. */ if (fill_group_list(ud, maxgroups) == -1) - fatal(_("unable to get group vector")); + fatal(U_("unable to get group vector")); } /* @@ -463,11 +462,11 @@ get_user_info(struct user_details *ud) pw = getpwuid(ud->uid); if (pw == NULL) - fatalx(_("unknown uid %u: who are you?"), (unsigned int)ud->uid); + fatalx(U_("unknown uid %u: who are you?"), (unsigned int)ud->uid); user_info[i] = fmt_string("user", pw->pw_name); if (user_info[i] == NULL) - fatalx(NULL); + fatal(NULL); ud->username = user_info[i] + sizeof("user=") - 1; /* Stash user's shell for use with the -s flag; don't pass to plugin. */ @@ -493,14 +492,14 @@ get_user_info(struct user_details *ud) if (getcwd(cwd, sizeof(cwd)) != NULL) { user_info[++i] = fmt_string("cwd", cwd); if (user_info[i] == NULL) - fatalx(NULL); + fatal(NULL); ud->cwd = user_info[i] + sizeof("cwd=") - 1; } if ((cp = get_process_ttyname()) != NULL) { user_info[++i] = fmt_string("tty", cp); if (user_info[i] == NULL) - fatalx(NULL); + fatal(NULL); ud->tty = user_info[i] + sizeof("tty=") - 1; efree(cp); } @@ -511,7 +510,7 @@ get_user_info(struct user_details *ud) strlcpy(host, "localhost", sizeof(host)); user_info[++i] = fmt_string("host", host); if (user_info[i] == NULL) - fatalx(NULL); + fatal(NULL); ud->host = user_info[i] + sizeof("host=") - 1; get_ttysize(&ud->ts_lines, &ud->ts_cols); @@ -530,13 +529,14 @@ static void command_info_to_details(char * const info[], struct command_details *details) { int i; - long lval; - unsigned long ulval; - char *cp, *ep; + id_t id; + char *cp; + const char *errstr; debug_decl(command_info_to_details, SUDO_DEBUG_PCOMM) memset(details, 0, sizeof(*details)); details->closefrom = -1; + TAILQ_INIT(&details->preserved_fds); #define SET_STRING(s, n) \ if (strncmp(s, info[i], sizeof(s) - 1) == 0 && info[i][sizeof(s) - 1]) { \ @@ -554,16 +554,9 @@ command_info_to_details(char * const info[], struct co SET_STRING("cwd=", cwd) if (strncmp("closefrom=", info[i], sizeof("closefrom=") - 1) == 0) { cp = info[i] + sizeof("closefrom=") - 1; - if (*cp == '\0') - break; - errno = 0; - lval = strtol(cp, &ep, 0); - if (*cp != '\0' && *ep == '\0' && - !(errno == ERANGE && - (lval == LONG_MAX || lval == LONG_MIN)) && - lval < INT_MAX && lval > INT_MIN) { - details->closefrom = (int)lval; - } + details->closefrom = strtonum(cp, 0, INT_MAX, &errstr); + if (errstr != NULL) + fatalx(U_("%s: %s"), info[i], U_(errstr)); break; } break; @@ -578,20 +571,12 @@ command_info_to_details(char * const info[], struct co SET_STRING("login_class=", login_class) break; case 'n': - /* XXX - bounds check -NZERO to NZERO (inclusive). */ if (strncmp("nice=", info[i], sizeof("nice=") - 1) == 0) { cp = info[i] + sizeof("nice=") - 1; - if (*cp == '\0') - break; - errno = 0; - lval = strtol(cp, &ep, 0); - if (*cp != '\0' && *ep == '\0' && - !(errno == ERANGE && - (lval == LONG_MAX || lval == LONG_MIN)) && - lval < INT_MAX && lval > INT_MIN) { - details->priority = (int)lval; - SET(details->flags, CD_SET_PRIORITY); - } + details->priority = strtonum(cp, INT_MIN, INT_MAX, &errstr); + if (errstr != NULL) + fatalx(U_("%s: %s"), info[i], U_(errstr)); + SET(details->flags, CD_SET_PRIORITY); break; } if (strncmp("noexec=", info[i], sizeof("noexec=") - 1) == 0) { @@ -606,111 +591,75 @@ command_info_to_details(char * const info[], struct co SET(details->flags, CD_PRESERVE_GROUPS); break; } + if (strncmp("preserve_fds=", info[i], sizeof("preserve_fds=") - 1) == 0) { + parse_preserved_fds(&details->preserved_fds, + info[i] + sizeof("preserve_fds=") - 1); + break; + } break; case 'r': if (strncmp("runas_egid=", info[i], sizeof("runas_egid=") - 1) == 0) { cp = info[i] + sizeof("runas_egid=") - 1; - if (*cp == '\0') - break; - errno = 0; - ulval = strtoul(cp, &ep, 0); - if (*cp != '\0' && *ep == '\0' && - (errno != ERANGE || ulval != ULONG_MAX)) { - details->egid = (gid_t)ulval; - SET(details->flags, CD_SET_EGID); - } + id = atoid(cp, NULL, NULL, &errstr); + if (errstr != NULL) + fatalx(U_("%s: %s"), info[i], U_(errstr)); + details->egid = (gid_t)id; + SET(details->flags, CD_SET_EGID); break; } if (strncmp("runas_euid=", info[i], sizeof("runas_euid=") - 1) == 0) { cp = info[i] + sizeof("runas_euid=") - 1; - if (*cp == '\0') - break; - errno = 0; - ulval = strtoul(cp, &ep, 0); - if (*cp != '\0' && *ep == '\0' && - (errno != ERANGE || ulval != ULONG_MAX)) { - details->euid = (uid_t)ulval; - SET(details->flags, CD_SET_EUID); - } + id = atoid(cp, NULL, NULL, &errstr); + if (errstr != NULL) + fatalx(U_("%s: %s"), info[i], U_(errstr)); + details->euid = (uid_t)id; + SET(details->flags, CD_SET_EUID); break; } if (strncmp("runas_gid=", info[i], sizeof("runas_gid=") - 1) == 0) { cp = info[i] + sizeof("runas_gid=") - 1; - if (*cp == '\0') - break; - errno = 0; - ulval = strtoul(cp, &ep, 0); - if (*cp != '\0' && *ep == '\0' && - (errno != ERANGE || ulval != ULONG_MAX)) { - details->gid = (gid_t)ulval; - SET(details->flags, CD_SET_GID); - } + id = atoid(cp, NULL, NULL, &errstr); + if (errstr != NULL) + fatalx(U_("%s: %s"), info[i], U_(errstr)); + details->gid = (gid_t)id; + SET(details->flags, CD_SET_GID); break; } if (strncmp("runas_groups=", info[i], sizeof("runas_groups=") - 1) == 0) { - int j; - - /* count groups, alloc and fill in */ + /* parse_gid_list() will call fatalx() on error. */ cp = info[i] + sizeof("runas_groups=") - 1; - if (*cp == '\0') - break; - for (;;) { - details->ngroups++; - if ((cp = strchr(cp, ',')) == NULL) - break; - cp++; - } - if (details->ngroups != 0) { - details->groups = - emalloc2(details->ngroups, sizeof(GETGROUPS_T)); - cp = info[i] + sizeof("runas_groups=") - 1; - for (j = 0; j < details->ngroups;) { - errno = 0; - ulval = strtoul(cp, &ep, 0); - if (*cp == '\0' || (*ep != ',' && *ep != '\0') || - (ulval == ULONG_MAX && errno == ERANGE)) { - break; - } - details->groups[j++] = (gid_t)ulval; - cp = ep + 1; - } - details->ngroups = j; - } + details->ngroups = parse_gid_list(cp, NULL, &details->groups); break; } if (strncmp("runas_uid=", info[i], sizeof("runas_uid=") - 1) == 0) { cp = info[i] + sizeof("runas_uid=") - 1; - if (*cp == '\0') - break; - errno = 0; - ulval = strtoul(cp, &ep, 0); - if (*cp != '\0' && *ep == '\0' && - (errno != ERANGE || ulval != ULONG_MAX)) { - details->uid = (uid_t)ulval; - SET(details->flags, CD_SET_UID); - } + id = atoid(cp, NULL, NULL, &errstr); + if (errstr != NULL) + fatalx(U_("%s: %s"), info[i], U_(errstr)); + details->uid = (uid_t)id; + SET(details->flags, CD_SET_UID); break; } #ifdef HAVE_PRIV_SET if (strncmp("runas_privs=", info[i], sizeof("runas_privs=") - 1) == 0) { const char *endp; cp = info[i] + sizeof("runas_privs=") - 1; - if (*cp == '\0') - break; - errno = 0; - details->privs = priv_str_to_set(cp, ",", &endp); - if (details->privs == NULL) + if (*cp != '\0') { + details->privs = priv_str_to_set(cp, ",", &endp); + if (details->privs == NULL) warning("invalid runas_privs %s", endp); + } + break; } if (strncmp("runas_limitprivs=", info[i], sizeof("runas_limitprivs=") - 1) == 0) { const char *endp; cp = info[i] + sizeof("runas_limitprivs=") - 1; - if (*cp == '\0') - break; - errno = 0; - details->limitprivs = priv_str_to_set(cp, ",", &endp); - if (details->limitprivs == NULL) + if (*cp != '\0') { + details->limitprivs = priv_str_to_set(cp, ",", &endp); + if (details->limitprivs == NULL) warning("invalid runas_limitprivs %s", endp); + } + break; } #endif /* HAVE_PRIV_SET */ break; @@ -731,32 +680,20 @@ command_info_to_details(char * const info[], struct co case 't': if (strncmp("timeout=", info[i], sizeof("timeout=") - 1) == 0) { cp = info[i] + sizeof("timeout=") - 1; - if (*cp == '\0') - break; - errno = 0; - lval = strtol(cp, &ep, 0); - if (*cp != '\0' && *ep == '\0' && - !(errno == ERANGE && - (lval == LONG_MAX || lval == LONG_MIN)) && - lval <= INT_MAX && lval >= 0) { - details->timeout = (int)lval; - SET(details->flags, CD_SET_TIMEOUT); - } + details->timeout = strtonum(cp, 0, INT_MAX, &errstr); + if (errstr != NULL) + fatalx(U_("%s: %s"), info[i], U_(errstr)); + SET(details->flags, CD_SET_TIMEOUT); break; } break; case 'u': if (strncmp("umask=", info[i], sizeof("umask=") - 1) == 0) { cp = info[i] + sizeof("umask=") - 1; - if (*cp == '\0') - break; - errno = 0; - ulval = strtoul(cp, &ep, 8); - if (*cp != '\0' && *ep == '\0' && - (errno != ERANGE || ulval != ULONG_MAX)) { - details->umask = (uid_t)ulval; - SET(details->flags, CD_SET_UMASK); - } + details->umask = atomode(cp, &errstr); + if (errstr != NULL) + fatalx(U_("%s: %s"), info[i], U_(errstr)); + SET(details->flags, CD_SET_UMASK); break; } if (strncmp("use_pty=", info[i], sizeof("use_pty=") - 1) == 0) { @@ -777,7 +714,7 @@ command_info_to_details(char * const info[], struct co #endif details->pw = getpwuid(details->euid); if (details->pw != NULL && (details->pw = pw_dup(details->pw)) == NULL) - fatalx(NULL); + fatal(NULL); #ifdef HAVE_SETAUTHDB aix_restoreauthdb(); #endif @@ -790,26 +727,54 @@ command_info_to_details(char * const info[], struct co } static void -sudo_check_suid(const char *path) +sudo_check_suid(const char *sudo) { + char pathbuf[PATH_MAX]; struct stat sb; + bool qualified; debug_decl(sudo_check_suid, SUDO_DEBUG_PCOMM) if (geteuid() != 0) { - if (strchr(path, '/') != NULL && stat(path, &sb) == 0) { + /* Search for sudo binary in PATH if not fully qualified. */ + qualified = strchr(sudo, '/') != NULL; + if (!qualified) { + char *path = getenv_unhooked("PATH"); + if (path != NULL) { + int len; + char *cp, *colon; + + cp = path = estrdup(path); + do { + if ((colon = strchr(cp, ':'))) + *colon = '\0'; + len = snprintf(pathbuf, sizeof(pathbuf), "%s/%s", cp, sudo); + if (len <= 0 || (size_t)len >= sizeof(pathbuf)) + continue; + if (access(pathbuf, X_OK) == 0) { + sudo = pathbuf; + qualified = true; + break; + } + cp = colon + 1; + } while (colon); + efree(path); + } + } + + if (qualified && stat(sudo, &sb) == 0) { /* Try to determine why sudo was not running as root. */ if (sb.st_uid != ROOT_UID || !ISSET(sb.st_mode, S_ISUID)) { fatalx( - _("%s must be owned by uid %d and have the setuid bit set"), - path, ROOT_UID); + U_("%s must be owned by uid %d and have the setuid bit set"), + sudo, ROOT_UID); } else { - fatalx(_("effective uid is not %d, is %s on a file system " + fatalx(U_("effective uid is not %d, is %s on a file system " "with the 'nosuid' option set or an NFS file system without" - " root privileges?"), ROOT_UID, path); + " root privileges?"), ROOT_UID, sudo); } } else { fatalx( - _("effective uid is not %d, is sudo installed setuid root?"), + U_("effective uid is not %d, is sudo installed setuid root?"), ROOT_UID); } } @@ -824,27 +789,11 @@ sudo_check_suid(const char *path) static void disable_coredumps(void) { -#if defined(__linux__) || defined(RLIMIT_CORE) +#if defined(RLIMIT_CORE) struct rlimit rl; -#endif debug_decl(disable_coredumps, SUDO_DEBUG_UTIL) -#if defined(__linux__) /* - * Unlimit the number of processes since Linux's setuid() will - * apply resource limits when changing uid and return EAGAIN if - * nproc would be violated by the uid switch. - */ - (void) getrlimit(RLIMIT_NPROC, &nproclimit); - rl.rlim_cur = rl.rlim_max = RLIM_INFINITY; - if (setrlimit(RLIMIT_NPROC, &rl)) { - memcpy(&rl, &nproclimit, sizeof(struct rlimit)); - rl.rlim_cur = rl.rlim_max; - (void)setrlimit(RLIMIT_NPROC, &rl); - } -#endif /* __linux__ */ -#ifdef RLIMIT_CORE - /* * Turn off core dumps? */ if (sudo_conf_disable_coredump()) { @@ -853,11 +802,49 @@ disable_coredumps(void) rl.rlim_cur = 0; (void) setrlimit(RLIMIT_CORE, &rl); } + debug_return; #endif /* RLIMIT_CORE */ +} + +/* + * Unlimit the number of processes since Linux's setuid() will + * apply resource limits when changing uid and return EAGAIN if + * nproc would be exceeded by the uid switch. + */ +static void +unlimit_nproc(void) +{ +#ifdef __linux__ + struct rlimit rl; + debug_decl(unlimit_nproc, SUDO_DEBUG_UTIL) + + (void) getrlimit(RLIMIT_NPROC, &nproclimit); + rl.rlim_cur = rl.rlim_max = RLIM_INFINITY; + if (setrlimit(RLIMIT_NPROC, &rl) != 0) { + memcpy(&rl, &nproclimit, sizeof(struct rlimit)); + rl.rlim_cur = rl.rlim_max; + (void)setrlimit(RLIMIT_NPROC, &rl); + } debug_return; +#endif /* __linux__ */ } /* + * Restore saved value of RLIMIT_NPROC. + */ +static void +restore_nproc(void) +{ +#ifdef __linux__ + debug_decl(restore_nproc, SUDO_DEBUG_UTIL) + + (void) setrlimit(RLIMIT_NPROC, &nproclimit); + + debug_return; +#endif /* __linux__ */ +} + +/* * Setup the execution environment immediately prior to the call to execve() * Returns true on success and false on failure. */ @@ -913,7 +900,7 @@ exec_setup(struct command_details *details, const char */ lc = login_getclass((char *)details->login_class); if (!lc) { - warningx(_("unknown login class %s"), details->login_class); + warningx(U_("unknown login class %s"), details->login_class); errno = ENOENT; goto done; } @@ -926,11 +913,9 @@ exec_setup(struct command_details *details, const char flags = LOGIN_SETRESOURCES|LOGIN_SETPRIORITY; } if (setusercontext(lc, details->pw, details->pw->pw_uid, flags)) { - if (details->pw->pw_uid != ROOT_UID) { - warning(_("unable to set user context")); + warning(U_("unable to set user context")); + if (details->pw->pw_uid != ROOT_UID) goto done; - } else - warning(_("unable to set user context")); } } #endif /* HAVE_LOGIN_CAP_H */ @@ -942,27 +927,27 @@ exec_setup(struct command_details *details, const char if (!ISSET(details->flags, CD_PRESERVE_GROUPS)) { if (details->ngroups >= 0) { if (sudo_setgroups(details->ngroups, details->groups) < 0) { - warning(_("unable to set supplementary group IDs")); + warning(U_("unable to set supplementary group IDs")); goto done; } } } #ifdef HAVE_SETEUID if (ISSET(details->flags, CD_SET_EGID) && setegid(details->egid)) { - warning(_("unable to set effective gid to runas gid %u"), + warning(U_("unable to set effective gid to runas gid %u"), (unsigned int)details->egid); goto done; } #endif if (ISSET(details->flags, CD_SET_GID) && setgid(details->gid)) { - warning(_("unable to set gid to runas gid %u"), + warning(U_("unable to set gid to runas gid %u"), (unsigned int)details->gid); goto done; } if (ISSET(details->flags, CD_SET_PRIORITY)) { if (setpriority(PRIO_PROCESS, 0, details->priority) != 0) { - warning(_("unable to set process priority")); + warning(U_("unable to set process priority")); goto done; } } @@ -970,31 +955,40 @@ exec_setup(struct command_details *details, const char (void) umask(details->umask); if (details->chroot) { if (chroot(details->chroot) != 0 || chdir("/") != 0) { - warning(_("unable to change root to %s"), details->chroot); + warning(U_("unable to change root to %s"), details->chroot); goto done; } } + /* + * Unlimit the number of processes since Linux's setuid() will + * return EAGAIN if RLIMIT_NPROC would be exceeded by the uid switch. + */ + unlimit_nproc(); + #ifdef HAVE_SETRESUID if (setresuid(details->uid, details->euid, details->euid) != 0) { - warning(_("unable to change to runas uid (%u, %u)"), details->uid, + warning(U_("unable to change to runas uid (%u, %u)"), details->uid, details->euid); goto done; } -#elif HAVE_SETREUID +#elif defined(HAVE_SETREUID) if (setreuid(details->uid, details->euid) != 0) { - warning(_("unable to change to runas uid (%u, %u)"), + warning(U_("unable to change to runas uid (%u, %u)"), (unsigned int)details->uid, (unsigned int)details->euid); goto done; } #else if (seteuid(details->euid) != 0 || setuid(details->euid) != 0) { - warning(_("unable to change to runas uid (%u, %u)"), details->uid, + warning(U_("unable to change to runas uid (%u, %u)"), details->uid, details->euid); goto done; } #endif /* !HAVE_SETRESUID && !HAVE_SETREUID */ + /* Restore previous value of RLIMIT_NPROC. */ + restore_nproc(); + /* * Only change cwd if we have chroot()ed or the policy modules * specifies a different cwd. Must be done after uid change. @@ -1003,39 +997,12 @@ exec_setup(struct command_details *details, const char if (details->chroot || strcmp(details->cwd, user_details.cwd) != 0) { /* Note: cwd is relative to the new root, if any. */ if (chdir(details->cwd) != 0) { - warning(_("unable to change directory to %s"), details->cwd); + warning(U_("unable to change directory to %s"), details->cwd); goto done; } } } - /* - * SuSE Enterprise Linux uses RLIMIT_NPROC and _SC_CHILD_MAX - * interchangably. This causes problems when setting RLIMIT_NPROC - * to RLIM_INFINITY due to a bug in bash where bash tries to honor - * the value of _SC_CHILD_MAX but treats a value of -1 as an error, - * and uses a default value of 32 instead. - * - * To work around this problem, we restore the nproc resource limit - * if sysconf(_SC_CHILD_MAX) is negative. In most cases, pam_limits - * will set RLIMIT_NPROC for us. - * - * We must do this *after* the uid change to avoid potential EAGAIN - * from setuid(). - */ -#if defined(__linux__) && defined(_SC_CHILD_MAX) - { - struct rlimit rl; - long l; - errno = 0; - l = sysconf(_SC_CHILD_MAX); - if (l == -1 && errno == 0 && getrlimit(RLIMIT_NPROC, &rl) == 0) { - if (rl.rlim_cur == RLIM_INFINITY && rl.rlim_max == RLIM_INFINITY) - (void) setrlimit(RLIMIT_NPROC, &nproclimit); - } - } -#endif - rval = true; done: @@ -1064,7 +1031,7 @@ run_command(struct command_details *details) sudo_debug_printf(SUDO_DEBUG_DEBUG, "calling policy close with errno %d", cstat.val); policy_close(&policy_plugin, 0, cstat.val); - tq_foreach_fwd(&io_plugins, plugin) { + TAILQ_FOREACH(plugin, &io_plugins, entries) { sudo_debug_printf(SUDO_DEBUG_DEBUG, "calling I/O close with errno %d", cstat.val); iolog_close(plugin, 0, cstat.val); @@ -1076,7 +1043,7 @@ run_command(struct command_details *details) sudo_debug_printf(SUDO_DEBUG_DEBUG, "calling policy close with wait status %d", cstat.val); policy_close(&policy_plugin, cstat.val, 0); - tq_foreach_fwd(&io_plugins, plugin) { + TAILQ_FOREACH(plugin, &io_plugins, entries) { sudo_debug_printf(SUDO_DEBUG_DEBUG, "calling I/O close with wait status %d", cstat.val); iolog_close(plugin, cstat.val, 0); @@ -1087,7 +1054,7 @@ run_command(struct command_details *details) exitcode = WTERMSIG(cstat.val) | 128; break; default: - warningx(_("unexpected child termination condition: %d"), cstat.type); + warningx(U_("unexpected child termination condition: %d"), cstat.type); break; } debug_return_int(exitcode); @@ -1124,7 +1091,7 @@ policy_close(struct plugin_container *plugin, int exit if (plugin->u.policy->close != NULL) plugin->u.policy->close(exit_status, error); else - warning(_("unable to execute %s"), command_details.command); + warning(U_("unable to execute %s"), command_details.command); debug_return; } @@ -1144,7 +1111,7 @@ policy_check(struct plugin_container *plugin, int argc { debug_decl(policy_check, SUDO_DEBUG_PCOMM) if (plugin->u.policy->check_policy == NULL) { - fatalx(_("policy plugin %s is missing the `check_policy' method"), + fatalx(U_("policy plugin %s is missing the `check_policy' method"), plugin->name); } debug_return_bool(plugin->u.policy->check_policy(argc, argv, env_add, @@ -1157,7 +1124,7 @@ policy_list(struct plugin_container *plugin, int argc, { debug_decl(policy_list, SUDO_DEBUG_PCOMM) if (plugin->u.policy->list == NULL) { - warningx(_("policy plugin %s does not support listing privileges"), + warningx(U_("policy plugin %s does not support listing privileges"), plugin->name); debug_return_bool(false); } @@ -1169,7 +1136,7 @@ policy_validate(struct plugin_container *plugin) { debug_decl(policy_validate, SUDO_DEBUG_PCOMM) if (plugin->u.policy->validate == NULL) { - warningx(_("policy plugin %s does not support the -v option"), + warningx(U_("policy plugin %s does not support the -v option"), plugin->name); debug_return_bool(false); } @@ -1181,7 +1148,7 @@ policy_invalidate(struct plugin_container *plugin, int { debug_decl(policy_invalidate, SUDO_DEBUG_PCOMM) if (plugin->u.policy->invalidate == NULL) { - fatalx(_("policy plugin %s does not support the -k/-K options"), + fatalx(U_("policy plugin %s does not support the -k/-K options"), plugin->name); } plugin->u.policy->invalidate(remove); @@ -1275,7 +1242,7 @@ iolog_unlink(struct plugin_container *plugin) deregister_hook); } /* Remove from io_plugins list and free. */ - tq_remove(&io_plugins, plugin); + TAILQ_REMOVE(&io_plugins, plugin, entries); efree(plugin); debug_return;