=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/sudo/Attic/sudo.c,v retrieving revision 1.10 retrieving revision 1.10.2.1 diff -c -r1.10 -r1.10.2.1 *** src/usr.bin/sudo/Attic/sudo.c 2001/08/23 21:46:17 1.10 --- src/usr.bin/sudo/Attic/sudo.c 2002/01/18 16:14:46 1.10.2.1 *************** *** 1,5 **** /* ! * Copyright (c) 1994-1996,1998-2000 Todd C. Miller * All rights reserved. * * Redistribution and use in source and binary forms, with or without --- 1,5 ---- /* ! * Copyright (c) 1993-1996,1998-2002 Todd C. Miller * All rights reserved. * * Redistribution and use in source and binary forms, with or without *************** *** 39,72 **** #include "config.h" #include #ifdef STDC_HEADERS ! #include #endif /* STDC_HEADERS */ - #ifdef HAVE_UNISTD_H - #include - #endif /* HAVE_UNISTD_H */ #ifdef HAVE_STRING_H ! #include #endif /* HAVE_STRING_H */ ! #ifdef HAVE_STRINGS_H ! #include ! #endif /* HAVE_STRINGS_H */ #include #include #include #include #include #include - #include - #include - #include #include #include - #ifdef HAVE_SETRLIMIT - #include - #include - #endif #if defined(HAVE_GETPRPWNAM) && defined(HAVE_SET_AUTH_PARAMETERS) # ifdef __hpux # undef MAXINT --- 39,82 ---- #include "config.h" + #include + #include + #include + #include + #ifdef HAVE_SETRLIMIT + # include + # include + #endif #include #ifdef STDC_HEADERS ! # include ! # include ! #else ! # ifdef HAVE_STDLIB_H ! # include ! # endif #endif /* STDC_HEADERS */ #ifdef HAVE_STRING_H ! # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS) ! # include ! # endif ! # include ! #else ! # ifdef HAVE_STRINGS_H ! # include ! # endif #endif /* HAVE_STRING_H */ ! #ifdef HAVE_UNISTD_H ! # include ! #endif /* HAVE_UNISTD_H */ #include #include #include #include #include #include #include #include #if defined(HAVE_GETPRPWNAM) && defined(HAVE_SET_AUTH_PARAMETERS) # ifdef __hpux # undef MAXINT *************** *** 87,124 **** #include "interfaces.h" #include "version.h" - #ifndef STDC_HEADERS - extern char *getenv __P((char *)); - #endif /* STDC_HEADERS */ - #ifndef lint ! static const char rcsid[] = "$Sudo: sudo.c,v 1.278 2000/03/24 20:13:12 millert Exp $"; #endif /* lint */ /* - * Local type declarations - */ - struct env_table { - char *name; - int len; - }; - - /* * Prototypes */ - static int parse_args __P((void)); - static void usage __P((int)); - static void usage_excl __P((int)); - static void check_sudoers __P((void)); static int init_vars __P((int)); ! static void set_loginclass __P((struct passwd *)); ! static void add_env __P((int)); ! static void clean_env __P((char **, struct env_table *)); static void initial_setup __P((void)); static struct passwd *get_authpw __P((void)); - extern struct passwd *sudo_getpwuid __P((uid_t)); - extern struct passwd *sudo_getpwnam __P((const char *)); extern void list_matches __P((void)); /* * Globals --- 97,122 ---- #include "interfaces.h" #include "version.h" #ifndef lint ! static const char rcsid[] = "$Sudo: sudo.c,v 1.318 2002/01/15 23:43:59 millert Exp $"; #endif /* lint */ /* * Prototypes */ static int init_vars __P((int)); ! static int parse_args __P((void)); ! static void check_sudoers __P((void)); static void initial_setup __P((void)); + static void set_loginclass __P((struct passwd *)); + static void usage __P((int)); + static void usage_excl __P((int)); static struct passwd *get_authpw __P((void)); extern void list_matches __P((void)); + extern char **rebuild_env __P((int, char **)); + extern char **zero_env __P((char **)); + extern struct passwd *sudo_getpwnam __P((const char *)); + extern struct passwd *sudo_getpwuid __P((uid_t)); /* * Globals *************** *** 134,140 **** int num_interfaces; int tgetpass_flags; extern int errorlineno; - static char *runas_homedir = NULL; /* XXX */ #if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL) static struct rlimit corelimit; #endif /* RLIMIT_CORE */ --- 132,137 ---- *************** *** 144,194 **** #ifdef HAVE_BSD_AUTH_H char *login_style; #endif /* HAVE_BSD_AUTH_H */ - /* - * Table of "bad" envariables to remove and len for strncmp() - */ - static struct env_table badenv_table[] = { - { "IFS=", 4 }, - { "LOCALDOMAIN=", 12 }, - { "RES_OPTIONS=", 12 }, - { "HOSTALIASES=", 12 }, - { "LD_", 3 }, - { "_RLD", 4 }, - #ifdef __hpux - { "SHLIB_PATH=", 11 }, - #endif /* __hpux */ - #ifdef _AIX - { "LIBPATH=", 8 }, - #endif /* _AIX */ - #ifdef HAVE_KERB4 - { "KRB_CONF", 8 }, - #endif /* HAVE_KERB4 */ - #ifdef HAVE_KERB5 - { "KRB5_CONFIG", 11 }, - #endif /* HAVE_KERB5 */ - { "ENV=", 4 }, - { "BASH_ENV=", 9 }, - { (char *) NULL, 0 } - }; - int ! main(argc, argv) int argc; char **argv; { int validated; int fd; int cmnd_status; int sudo_mode; ! #ifdef POSIX_SIGNALS ! sigset_t set, oset; ! #else ! int omask; ! #endif /* POSIX_SIGNALS */ ! extern char **environ; extern int printmatches; /* Must be done as the first thing... */ #if defined(HAVE_GETPRPWNAM) && defined(HAVE_SET_AUTH_PARAMETERS) --- 141,164 ---- #ifdef HAVE_BSD_AUTH_H char *login_style; #endif /* HAVE_BSD_AUTH_H */ + void (*set_perms) __P((int, int)); int ! main(argc, argv, envp) int argc; char **argv; + char **envp; { int validated; int fd; int cmnd_status; int sudo_mode; ! int pwflag; ! char **new_environ; ! sigaction_t sa; extern int printmatches; + extern char **environ; /* Must be done as the first thing... */ #if defined(HAVE_GETPRPWNAM) && defined(HAVE_SET_AUTH_PARAMETERS) *************** *** 198,203 **** --- 168,176 ---- # endif #endif /* HAVE_GETPRPWNAM && HAVE_SET_AUTH_PARAMETERS */ + /* Zero out the environment. */ + environ = zero_env(envp); + Argv = argv; Argc = argc; *************** *** 207,241 **** } /* ! * Block signals so the user cannot interrupt us at some point and ! * avoid the logging. */ ! #ifdef POSIX_SIGNALS ! (void) sigemptyset(&set); ! (void) sigaddset(&set, SIGINT); ! (void) sigaddset(&set, SIGQUIT); ! (void) sigaddset(&set, SIGTSTP); ! (void) sigprocmask(SIG_BLOCK, &set, &oset); ! #else ! omask = sigblock(sigmask(SIGINT)|sigmask(SIGQUIT)|sigmask(SIGTSTP)); ! #endif /* POSIX_SIGNALS */ /* * Setup signal handlers, turn off core dumps, and close open files. */ initial_setup(); - /* - * Set the prompt based on $SUDO_PROMPT (can be overridden by `-p') - */ - user_prompt = getenv("SUDO_PROMPT"); - /* Parse our arguments. */ sudo_mode = parse_args(); /* Setup defaults data structures. */ init_defaults(); if (sudo_mode & MODE_SHELL) user_cmnd = "shell"; else --- 180,211 ---- } /* ! * Ignore keyboard-generated signals so the user cannot interrupt ! * us at some point and avoid the logging. */ ! sigemptyset(&sa.sa_mask); ! sa.sa_flags = SA_RESTART; ! sa.sa_handler = SIG_IGN; ! (void) sigaction(SIGINT, &sa, NULL); ! (void) sigaction(SIGQUIT, &sa, NULL); ! (void) sigaction(SIGTSTP, &sa, NULL); /* * Setup signal handlers, turn off core dumps, and close open files. */ initial_setup(); + setpwent(); /* Parse our arguments. */ sudo_mode = parse_args(); /* Setup defaults data structures. */ init_defaults(); + /* Load the list of local ip addresses and netmasks. */ + load_interfaces(); + + pwflag = 0; if (sudo_mode & MODE_SHELL) user_cmnd = "shell"; else *************** *** 246,251 **** --- 216,223 ---- putchar('\n'); dump_auth_methods(); dump_defaults(); + dump_interfaces(); + dump_badenv(); } exit(0); break; *************** *** 254,263 **** --- 226,237 ---- break; case MODE_VALIDATE: user_cmnd = "validate"; + pwflag = I_VERIFYPW_I; break; case MODE_KILL: case MODE_INVALIDATE: user_cmnd = "kill"; + pwflag = -1; break; case MODE_LISTDEFS: list_options(); *************** *** 265,270 **** --- 239,245 ---- break; case MODE_LIST: user_cmnd = "list"; + pwflag = I_LISTPW_I; printmatches = 1; break; } *************** *** 273,291 **** if (user_cmnd == NULL && NewArgc == 0) usage(1); - clean_env(environ, badenv_table); - cmnd_status = init_vars(sudo_mode); - /* At this point, ruid == euid == 0 */ - check_sudoers(); /* check mode/owner on _PATH_SUDOERS */ - add_env(!(sudo_mode & MODE_SHELL)); /* add in SUDO_* envariables */ - /* Validate the user but don't search for pseudo-commands. */ ! validated = sudoers_lookup(sudo_mode); /* This goes after the sudoers parse since we honor sudoers options. */ if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) { remove_timestamp((sudo_mode == MODE_KILL)); --- 248,292 ---- if (user_cmnd == NULL && NewArgc == 0) usage(1); cmnd_status = init_vars(sudo_mode); check_sudoers(); /* check mode/owner on _PATH_SUDOERS */ /* Validate the user but don't search for pseudo-commands. */ ! validated = sudoers_lookup(pwflag); + /* + * If we have POSIX saved uids and the stay_setuid flag was not set, + * set the real, effective and saved uids to 0 and use set_perms_fallback() + * instead of set_perms_posix(). + */ + #if !defined(NO_SAVED_IDS) && defined(_SC_SAVED_IDS) && defined(_SC_VERSION) + if (!def_flag(I_STAY_SETUID) && set_perms == set_perms_posix) { + if (setuid(0)) { + perror("setuid(0)"); + exit(1); + } + set_perms = set_perms_fallback; + } + #endif + + /* + * Look up runas user passwd struct. If we are given a uid then + * there may be no corresponding passwd(5) entry (which is OK). + */ + if (**user_runas == '#') { + runas_pw = sudo_getpwuid(atoi(*user_runas + 1)); + if (runas_pw == NULL) { + runas_pw = emalloc(sizeof(struct passwd)); + (void) memset((VOID *)runas_pw, 0, sizeof(struct passwd)); + runas_pw->pw_uid = atoi(*user_runas + 1); + } + } else { + runas_pw = sudo_getpwnam(*user_runas); + if (runas_pw == NULL) + log_error(NO_MAIL|MSG_ONLY, "no passwd entry for %s!", *user_runas); + } + /* This goes after the sudoers parse since we honor sudoers options. */ if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) { remove_timestamp((sudo_mode == MODE_KILL)); *************** *** 303,314 **** exit(1); } /* If no command line args and "set_home" is not set, error out. */ if ((sudo_mode & MODE_IMPLIED_SHELL) && !def_flag(I_SHELL_NOARGS)) usage(1); ! /* May need to set $HOME to target user. */ ! if ((sudo_mode & MODE_SHELL) && def_flag(I_SET_HOME)) sudo_mode |= MODE_RESET_HOME; /* Bail if a tty is required and we don't have one. */ --- 304,320 ---- exit(1); } + /* If given the -P option, set the "preserve_groups" flag. */ + if (sudo_mode & MODE_PRESERVE_GROUPS) + def_flag(I_PRESERVE_GROUPS) = TRUE; + /* If no command line args and "set_home" is not set, error out. */ if ((sudo_mode & MODE_IMPLIED_SHELL) && !def_flag(I_SHELL_NOARGS)) usage(1); ! /* May need to set $HOME to target user if we are running a command. */ ! if ((sudo_mode & MODE_RUN) && (def_flag(I_ALWAYS_SET_HOME) || ! ((sudo_mode & MODE_SHELL) && def_flag(I_SET_HOME)))) sudo_mode |= MODE_RESET_HOME; /* Bail if a tty is required and we don't have one. */ *************** *** 326,331 **** --- 332,340 ---- if (!(validated & FLAG_NOPASS)) check_user(); + /* Build up custom environment that avoids any nasty bits. */ + new_environ = rebuild_env(sudo_mode, envp); + if (validated & VALIDATE_OK) { /* Finally tell the user if the command did not exist. */ if (cmnd_status == NOT_FOUND_DOT) { *************** *** 348,376 **** /* This *must* have been set if we got a match but... */ if (safe_cmnd == NULL) { log_error(MSG_ONLY, ! "internal error, cmnd_safe never got set for %s; %s", user_cmnd, "please report this error at http://courtesan.com/sudo/bugs/"); } ! if (def_ival(I_LOGFACSTR)) ! closelog(); ! /* Reset signal mask before we exec. */ ! #ifdef POSIX_SIGNALS ! (void) sigprocmask(SIG_SETMASK, &oset, NULL); ! #else ! (void) sigsetmask(omask); ! #endif /* POSIX_SIGNALS */ /* Override user's umask if configured to do so. */ if (def_ival(I_UMASK) != 0777) (void) umask(def_mode(I_UMASK)); - /* Replace the PATH envariable with a secure one. */ - if (def_str(I_SECURE_PATH) && !user_is_exempt()) - sudo_setenv("PATH", def_str(I_SECURE_PATH)); - /* Restore coredumpsize resource limit. */ #if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL) (void) setrlimit(RLIMIT_CORE, &corelimit); --- 357,382 ---- /* This *must* have been set if we got a match but... */ if (safe_cmnd == NULL) { log_error(MSG_ONLY, ! "internal error, safe_cmnd never got set for %s; %s", user_cmnd, "please report this error at http://courtesan.com/sudo/bugs/"); } ! /* Reset signal handlers before we exec. */ ! sigemptyset(&sa.sa_mask); ! sa.sa_flags = SA_RESTART; ! sa.sa_handler = SIG_DFL; ! (void) sigaction(SIGINT, &sa, NULL); ! (void) sigaction(SIGQUIT, &sa, NULL); ! (void) sigaction(SIGTSTP, &sa, NULL); ! /* Close the password file */ ! endpwent(); /* Override user's umask if configured to do so. */ if (def_ival(I_UMASK) != 0777) (void) umask(def_mode(I_UMASK)); /* Restore coredumpsize resource limit. */ #if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL) (void) setrlimit(RLIMIT_CORE, &corelimit); *************** *** 379,387 **** /* Become specified user or root. */ set_perms(PERM_RUNAS, sudo_mode); ! /* Set $HOME for `sudo -H'. Only valid at PERM_RUNAS. */ ! if ((sudo_mode & MODE_RESET_HOME) && runas_homedir) ! sudo_setenv("HOME", runas_homedir); #ifndef PROFILING if ((sudo_mode & MODE_BACKGROUND) && fork() > 0) --- 385,392 ---- /* Become specified user or root. */ set_perms(PERM_RUNAS, sudo_mode); ! /* Install the new environment. */ ! environ = new_environ; #ifndef PROFILING if ((sudo_mode & MODE_BACKGROUND) && fork() > 0) *************** *** 396,402 **** */ (void) fprintf(stderr, "%s: unable to exec %s: %s\n", Argv[0], safe_cmnd, strerror(errno)); ! exit(-1); } else if ((validated & FLAG_NO_USER) || (validated & FLAG_NO_HOST)) { log_auth(validated, 1); exit(1); --- 401,407 ---- */ (void) fprintf(stderr, "%s: unable to exec %s: %s\n", Argv[0], safe_cmnd, strerror(errno)); ! exit(127); } else if ((validated & FLAG_NO_USER) || (validated & FLAG_NO_HOST)) { log_auth(validated, 1); exit(1); *************** *** 438,443 **** --- 443,449 ---- int sudo_mode; { char *p, thost[MAXHOSTNAMELEN]; + int nohostname, rval; /* Sanity check command from user. */ if (user_cmnd == NULL && strlen(NewArgv[0]) >= MAXPATHLEN) { *************** *** 461,480 **** * "host" is the (possibly fully-qualified) hostname and * "shost" is the unqualified form of the hostname. */ ! if ((gethostname(thost, sizeof(thost)))) { ! user_host = "localhost"; ! log_error(USE_ERRNO|MSG_ONLY, "can't get hostname"); ! } else ! user_host = estrdup(thost); ! if (def_flag(I_FQDN)) ! set_fqdn(); else { ! if ((p = strchr(user_host, '.'))) { ! *p = '\0'; ! user_shost = estrdup(user_host); ! *p = '.'; ! } else { user_shost = user_host; } } --- 467,488 ---- * "host" is the (possibly fully-qualified) hostname and * "shost" is the unqualified form of the hostname. */ ! nohostname = gethostname(thost, sizeof(thost)); ! if (nohostname) ! user_host = user_shost = "localhost"; else { ! user_host = estrdup(thost); ! if (def_flag(I_FQDN)) { ! /* Defer call to set_fqdn() until log_error() is safe. */ user_shost = user_host; + } else { + if ((p = strchr(user_host, '.'))) { + *p = '\0'; + user_shost = estrdup(user_host); + *p = '.'; + } else { + user_shost = user_host; + } } } *************** *** 503,512 **** --- 511,531 ---- log_error(0, "uid %ld does not exist in the passwd file!", (long) pw.pw_uid); } + if (user_shell == NULL || *user_shell == '\0') + user_shell = sudo_user.pw->pw_shell; /* It is now safe to use log_error() and set_perms() */ /* + * Must defer set_fqdn() until it is safe to call log_error() + */ + if (def_flag(I_FQDN)) + set_fqdn(); + + if (nohostname) + log_error(USE_ERRNO|MSG_ONLY, "can't get hostname"); + + /* * Get current working directory. Try as user, fall back to root. */ set_perms(PERM_USER, sudo_mode); *************** *** 521,532 **** set_perms(PERM_ROOT, sudo_mode); /* - * Load the list of local ip addresses and netmasks into - * the interfaces array. - */ - load_interfaces(); - - /* * If we were given the '-s' option (run shell) we need to redo * NewArgv and NewArgc. */ --- 540,545 ---- *************** *** 550,559 **** set_loginclass(sudo_user.pw); /* Resolve the path and return. */ ! if ((sudo_mode & MODE_RUN)) ! return(find_path(NewArgv[0], &user_cmnd)); ! else ! return(FOUND); } /* --- 563,605 ---- set_loginclass(sudo_user.pw); /* Resolve the path and return. */ ! if ((sudo_mode & MODE_RUN)) { ! /* XXX - should call this as runas user, not root. */ ! rval = find_path(NewArgv[0], &user_cmnd, user_path); ! if (rval != FOUND) { ! /* Failed as root, try as invoking user. */ ! set_perms(PERM_USER, sudo_mode); ! rval = find_path(NewArgv[0], &user_cmnd, user_path); ! set_perms(PERM_ROOT, sudo_mode); ! } ! ! /* set user_args */ ! if (NewArgc > 1) { ! char *to, **from; ! size_t size; ! ! /* If MODE_SHELL not set then NewArgv is contiguous so just count */ ! if (!(sudo_mode & MODE_SHELL)) { ! size = (size_t) (NewArgv[NewArgc-1] - NewArgv[1]) + ! strlen(NewArgv[NewArgc-1]) + 1; ! } else { ! for (size = 0, from = NewArgv + 1; *from; from++) ! size += strlen(*from) + 1; ! } ! ! /* alloc and copy. */ ! to = user_args = (char *) emalloc(size); ! for (from = NewArgv + 1; *from; from++) { ! (void) strcpy(to, *from); ! to += strlen(*from); ! *to++ = ' '; ! } ! *--to = '\0'; ! } ! } else ! rval = FOUND; ! ! return(rval); } /* *************** *** 623,629 **** usage(1); login_class = NewArgv[1]; ! def_flag(I_LOGINCLASS) = TRUE; /* Shift Argv over and adjust Argc. */ NewArgc--; --- 669,675 ---- usage(1); login_class = NewArgv[1]; ! def_flag(I_USE_LOGINCLASS) = TRUE; /* Shift Argv over and adjust Argc. */ NewArgc--; *************** *** 684,689 **** --- 730,738 ---- case 'H': rval |= MODE_RESET_HOME; break; + case 'P': + rval |= MODE_PRESERVE_GROUPS; + break; case 'S': tgetpass_flags |= TGP_STDIN; break; *************** *** 713,782 **** } /* - * Add sudo-specific variables into the environment. - * Sets ``cmnd_args'' as a side effect. - */ - static void - add_env(contiguous) - int contiguous; - { - char idstr[MAX_UID_T_LEN + 1]; - size_t size; - char *buf; - - /* Add the SUDO_COMMAND envariable (cmnd + args). */ - size = strlen(user_cmnd) + 1; - if (NewArgc > 1) { - char *to, **from; - - if (contiguous) { - size += (size_t) (NewArgv[NewArgc-1] - NewArgv[1]) + - strlen(NewArgv[NewArgc-1]) + 1; - } else { - for (from = &NewArgv[1]; *from; from++) - size += strlen(*from) + 1; - } - - buf = (char *) emalloc(size); - - /* - * Copy the command and it's arguments info buf. - */ - (void) strcpy(buf, user_cmnd); - to = buf + strlen(user_cmnd); - for (from = &NewArgv[1]; *from; from++) { - *to++ = ' '; - (void) strcpy(to, *from); - to += strlen(*from); - } - } else { - buf = user_cmnd; - } - sudo_setenv("SUDO_COMMAND", buf); - if (NewArgc > 1) - free(buf); - - /* Grab a pointer to the flat arg string from the environment. */ - if (NewArgc > 1 && (user_args = getenv("SUDO_COMMAND"))) { - if ((user_args = strchr(user_args, ' '))) - user_args++; - else - user_args = NULL; - } - - /* Add the SUDO_USER, SUDO_UID, SUDO_GID environment variables. */ - sudo_setenv("SUDO_USER", user_name); - (void) sprintf(idstr, "%ld", (long) user_uid); - sudo_setenv("SUDO_UID", idstr); - (void) sprintf(idstr, "%ld", (long) user_gid); - sudo_setenv("SUDO_GID", idstr); - - /* Set PS1 if SUDO_PS1 is set. */ - if ((buf = getenv("SUDO_PS1"))) - sudo_setenv("PS1", buf); - } - - /* * Sanity check sudoers mode/owner/type. * Leaves a file pointer to the sudoers file open in ``fp''. */ --- 762,767 ---- *************** *** 858,1034 **** } /* - * Remove environment variables that match the entries in badenv_table. - */ - static void - clean_env(envp, badenv_table) - char **envp; - struct env_table *badenv_table; - { - struct env_table *bad; - char **cur; - - /* - * Remove any envars that match entries in badenv_table. - */ - for (cur = envp; *cur; cur++) { - for (bad = badenv_table; bad->name; bad++) { - if (strncmp(*cur, bad->name, bad->len) == 0) { - /* Got a match so remove it. */ - char **move; - - for (move = cur; *move; move++) - *move = *(move + 1); - - cur--; - - break; - } - } - } - } - - /* - * Set real and effective uids and gids based on perm. - */ - void - set_perms(perm, sudo_mode) - int perm; - int sudo_mode; - { - struct passwd *pw; - - /* - * First, set real & effective uids to root. - * If perm is PERM_ROOT then we don't need to do anything else. - */ - if (setuid(0)) { - perror("setuid(0)"); - exit(1); - } - - switch (perm) { - case PERM_USER: - (void) setgid(user_gid); - - if (seteuid(user_uid)) { - perror("seteuid(user_uid)"); - exit(1); - } - break; - - case PERM_FULL_USER: - (void) setgid(user_gid); - - if (setuid(user_uid)) { - perror("setuid(user_uid)"); - exit(1); - } - break; - - case PERM_RUNAS: - /* XXX - add group/gid support */ - if (**user_runas == '#') { - if (setuid(atoi(*user_runas + 1))) { - (void) fprintf(stderr, - "%s: cannot set uid to %s: %s\n", - Argv[0], *user_runas, strerror(errno)); - exit(1); - } - } else { - if (!(pw = getpwnam(*user_runas))) { - (void) fprintf(stderr, - "%s: no passwd entry for %s!\n", - Argv[0], *user_runas); - exit(1); - } - - /* Set $USER and $LOGNAME to target user */ - if (def_flag(I_LOGNAME)) { - sudo_setenv("USER", pw->pw_name); - sudo_setenv("LOGNAME", pw->pw_name); - } - - #ifdef HAVE_LOGIN_CAP_H - if (def_flag(I_LOGINCLASS)) { - /* - * setusercontext() will set uid/gid/etc - * for us so no need to do it below. - */ - if (setusercontext(lc, pw, pw->pw_uid, - LOGIN_SETUSER|LOGIN_SETGROUP|LOGIN_SETRESOURCES|LOGIN_SETPRIORITY)) - log_error( - NO_MAIL|USE_ERRNO|MSG_ONLY, - "setusercontext() failed for login class %s", - login_class); - else - break; - } - #endif /* HAVE_LOGIN_CAP_H */ - - if (setgid(pw->pw_gid)) { - (void) fprintf(stderr, - "%s: cannot set gid to %ld: %s\n", - Argv[0], (long) pw->pw_gid, - strerror(errno)); - exit(1); - } - #ifdef HAVE_INITGROUPS - /* - * Initialize group vector only if are - * going to run as a non-root user. - */ - if (strcmp(*user_runas, "root") != 0 && - initgroups(*user_runas, pw->pw_gid) - == -1) { - (void) fprintf(stderr, - "%s: cannot set group vector: %s\n", - Argv[0], strerror(errno)); - exit(1); - } - #endif /* HAVE_INITGROUPS */ - if (setuid(pw->pw_uid)) { - (void) fprintf(stderr, - "%s: cannot set uid to %ld: %s\n", - Argv[0], (long) pw->pw_uid, - strerror(errno)); - exit(1); - } - if (sudo_mode & MODE_RESET_HOME) - runas_homedir = pw->pw_dir; - } - break; - - case PERM_SUDOERS: - if (setgid(SUDOERS_GID)) { - perror("setgid(SUDOERS_GID)"); - exit(1); - } - - /* - * If SUDOERS_UID == 0 and SUDOERS_MODE - * is group readable we use a non-zero - * uid in order to avoid NFS lossage. - * Using uid 1 is a bit bogus but should - * work on all OS's. - */ - if (SUDOERS_UID == 0) { - if ((SUDOERS_MODE & 040) && seteuid(1)) { - perror("seteuid(1)"); - exit(1); - } - } else { - if (seteuid(SUDOERS_UID)) { - perror("seteuid(SUDOERS_UID)"); - exit(1); - } - } - break; - } - } - - /* * Close all open files (except std*) and turn off core dumps. */ static void initial_setup() --- 843,850 ---- } /* * Close all open files (except std*) and turn off core dumps. + * Also sets the set_perms() pointer to the correct function. */ static void initial_setup() *************** *** 1037,1045 **** #ifdef HAVE_SETRLIMIT struct rlimit rl; #endif ! #ifdef POSIX_SIGNALS ! struct sigaction sa; ! #endif #if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL) /* --- 853,859 ---- #ifdef HAVE_SETRLIMIT struct rlimit rl; #endif ! sigaction_t sa; #if defined(RLIMIT_CORE) && !defined(SUDO_DEVEL) /* *************** *** 1069,1081 **** (void) close(fd); /* Catch children as they die... */ ! #ifdef POSIX_SIGNALS ! (void) memset((VOID *)&sa, 0, sizeof(sa)); sa.sa_handler = reapchild; (void) sigaction(SIGCHLD, &sa, NULL); ! #else ! (void) signal(SIGCHLD, reapchild); ! #endif /* POSIX_SIGNALS */ } #ifdef HAVE_LOGIN_CAP_H --- 883,900 ---- (void) close(fd); /* Catch children as they die... */ ! sigemptyset(&sa.sa_mask); ! sa.sa_flags = SA_RESTART; sa.sa_handler = reapchild; (void) sigaction(SIGCHLD, &sa, NULL); ! ! /* Set set_perms pointer to the correct function */ ! #if !defined(NO_SAVED_IDS) && defined(_SC_SAVED_IDS) && defined(_SC_VERSION) ! if (sysconf(_SC_SAVED_IDS) == 1 && sysconf(_SC_VERSION) >= 199009) ! set_perms = set_perms_posix; ! else ! #endif ! set_perms = set_perms_fallback; } #ifdef HAVE_LOGIN_CAP_H *************** *** 1111,1117 **** lc = login_getclass(login_class); if (!lc || !lc->lc_class || strcmp(lc->lc_class, login_class) != 0) { log_error(errflags, "unknown login class: %s", login_class); ! lc = login_getclass(NULL); /* Fall back on default login class */ } } #else --- 930,937 ---- lc = login_getclass(login_class); if (!lc || !lc->lc_class || strcmp(lc->lc_class, login_class) != 0) { log_error(errflags, "unknown login class: %s", login_class); ! if (!lc) ! lc = login_getclass(NULL); /* needed for login_getstyle() later */ } } #else *************** *** 1131,1147 **** struct hostent *hp; char *p; ! if (def_flag(I_FQDN)) { ! if (!(hp = gethostbyname(user_host))) { ! log_error(USE_ERRNO|MSG_ONLY|NO_EXIT, ! "unable to lookup %s via gethostbyname()", user_host); ! } else { ! free(user_host); ! user_host = estrdup(hp->h_name); ! } } - if (user_shost != user_host) - free(user_shost); if ((p = strchr(user_host, '.'))) { *p = '\0'; user_shost = estrdup(user_host); --- 951,965 ---- struct hostent *hp; char *p; ! if (!(hp = gethostbyname(user_host))) { ! log_error(MSG_ONLY|NO_EXIT, ! "unable to lookup %s via gethostbyname()", user_host); ! } else { ! if (user_shost != user_host) ! free(user_shost); ! free(user_host); ! user_host = estrdup(hp->h_name); } if ((p = strchr(user_host, '.'))) { *p = '\0'; user_shost = estrdup(user_host); *************** *** 1164,1172 **** if ((pw = sudo_getpwuid(0)) == NULL) log_error(0, "uid 0 does not exist in the passwd file!"); } else if (def_ival(I_RUNASPW)) { ! if ((pw = sudo_getpwnam(def_str(I_RUNAS_DEF))) == NULL) log_error(0, "user %s does not exist in the passwd file!", ! def_str(I_RUNAS_DEF)); } else if (def_ival(I_TARGETPW)) { if (**user_runas == '#') { if ((pw = sudo_getpwuid(atoi(*user_runas + 1))) == NULL) --- 982,990 ---- if ((pw = sudo_getpwuid(0)) == NULL) log_error(0, "uid 0 does not exist in the passwd file!"); } else if (def_ival(I_RUNASPW)) { ! if ((pw = sudo_getpwnam(def_str(I_RUNAS_DEFAULT))) == NULL) log_error(0, "user %s does not exist in the passwd file!", ! def_str(I_RUNAS_DEFAULT)); } else if (def_ival(I_TARGETPW)) { if (**user_runas == '#') { if ((pw = sudo_getpwuid(atoi(*user_runas + 1))) == NULL) *************** *** 1204,1210 **** { (void) fprintf(stderr, "usage: sudo -V | -h | -L | -l | -v | -k | -K | %s", ! "[-H] [-S] [-b] [-p prompt]\n [-u username/#uid] "); #ifdef HAVE_LOGIN_CAP_H (void) fprintf(stderr, "[-c class] "); #endif --- 1022,1028 ---- { (void) fprintf(stderr, "usage: sudo -V | -h | -L | -l | -v | -k | -K | %s", ! "[-H] [-P] [-S] [-b] [-p prompt]\n [-u username/#uid] "); #ifdef HAVE_LOGIN_CAP_H (void) fprintf(stderr, "[-c class] "); #endif