From 777948e773de4f9c0866f5228a97c56104e84605 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Sun, 24 Mar 1996 17:43:41 +0000 Subject: Protoize and reorder functions. --- src/su.c | 425 ++++++++++++++++++++++++++++++--------------------------------- 1 file changed, 199 insertions(+), 226 deletions(-) (limited to 'src') diff --git a/src/su.c b/src/su.c index 71452bfa4..ef068cba2 100644 --- a/src/su.c +++ b/src/su.c @@ -79,7 +79,6 @@ #if defined(HAVE_SYSLOG_H) && defined(HAVE_SYSLOG) #include -static void log_su (); #else /* !HAVE_SYSLOG_H */ #ifdef SYSLOG_SUCCESS #undef SYSLOG_SUCCESS @@ -138,16 +137,6 @@ char *xmalloc (); char *xrealloc (); char *xstrdup (); -static char *concat (); -static int correct_password (); -static int elements (); -static int restricted_shell (); -static void change_identity (); -static void modify_environment (); -static void run_shell (); -static void usage (); -static void xputenv (); - extern char **environ; /* The name this program was run with. */ @@ -180,134 +169,86 @@ static struct option const longopts[] = {0, 0, 0, 0} }; -int -main (argc, argv) - int argc; - char **argv; -{ - int optc; - const char *new_user = DEFAULT_USER; - char *command = 0; - char **additional_args = 0; - char *shell = 0; - struct passwd *pw; - struct passwd pw_copy; - - program_name = argv[0]; - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); - - fast_startup = 0; - simulate_login = 0; - change_environment = 1; - - while ((optc = getopt_long (argc, argv, "c:flmps:", longopts, (int *) 0)) - != EOF) - { - switch (optc) - { - case 0: - break; - - case 'c': - command = optarg; - break; +/* Add VAL to the environment, checking for out of memory errors. */ - case 'f': - fast_startup = 1; - break; +static void +xputenv (const char *val) +{ + if (putenv (val)) + error (1, 0, _("virtual memory exhausted")); +} - case 'l': - simulate_login = 1; - break; +/* Return a newly-allocated string whose contents concatenate + those of S1, S2, S3. */ - case 'm': - case 'p': - change_environment = 0; - break; +static char * +concat (const char *s1, const char *s2, const char *s3) +{ + int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3); + char *result = (char *) xmalloc (len1 + len2 + len3 + 1); - case 's': - shell = optarg; - break; + strcpy (result, s1); + strcpy (result + len1, s2); + strcpy (result + len1 + len2, s3); + result[len1 + len2 + len3] = 0; - default: - usage (1); - } - } + return result; +} - if (show_version) - { - printf ("su - %s\n", PACKAGE_VERSION); - exit (0); - } +/* Return the number of elements in ARR, a null-terminated array. */ - if (show_help) - usage (0); +static int +elements (char **arr) +{ + int n = 0; - if (optind < argc && !strcmp (argv[optind], "-")) - { - simulate_login = 1; - ++optind; - } - if (optind < argc) - new_user = argv[optind++]; - if (optind < argc) - additional_args = argv + optind; + for (n = 0; *arr; ++arr) + ++n; + return n; +} - pw = getpwnam (new_user); - if (pw == 0) - error (1, 0, _("user %s does not exist"), new_user); - endpwent (); +#if defined (SYSLOG_SUCCESS) || defined (SYSLOG_FAILURE) +/* Log the fact that someone has run su to the user given by PW; + if SUCCESSFUL is nonzero, they gave the correct password, etc. */ - /* Make a copy of the password information and point pw at the local - copy instead. Otherwise, some systems (e.g. Linux) would clobber - the static data through the getlogin call from log_su. */ - pw_copy = *pw; - pw = &pw_copy; - pw->pw_name = xstrdup (pw->pw_name); - pw->pw_dir = xstrdup (pw->pw_dir); - pw->pw_shell = xstrdup (pw->pw_shell); +static void +log_su (const struct passwd *pw, int successful) +{ + const char *new_user, *old_user, *tty; - if (!correct_password (pw)) - { -#ifdef SYSLOG_FAILURE - log_su (pw, 0); +#ifndef SYSLOG_NON_ROOT + if (pw->pw_uid) + return; #endif - error (1, 0, _("incorrect password")); - } -#ifdef SYSLOG_SUCCESS - else - { - log_su (pw, 1); - } + new_user = pw->pw_name; + /* The utmp entry (via getlogin) is probably the best way to identify + the user, especially if someone su's from a su-shell. */ + old_user = getlogin (); + if (old_user == NULL) + old_user = ""; + tty = ttyname (2); + if (tty == NULL) + tty = ""; + /* 4.2BSD openlog doesn't have the third parameter. */ + openlog (basename (program_name), 0 +#ifdef LOG_AUTH + , LOG_AUTH #endif - - if (pw->pw_shell == 0 || pw->pw_shell[0] == 0) - pw->pw_shell = (char *) DEFAULT_SHELL; - if (shell == 0 && change_environment == 0) - shell = getenv ("SHELL"); - if (shell != 0 && getuid () && restricted_shell (pw->pw_shell)) - { - /* The user being su'd to has a nonstandard shell, and so is - probably a uucp account or has restricted access. Don't - compromise the account by allowing access with a standard - shell. */ - error (0, 0, _("using restricted shell %s"), pw->pw_shell); - shell = 0; - } - if (shell == 0) - { - shell = xstrdup (pw->pw_shell); - } - modify_environment (pw, shell); - - change_identity (pw); - if (simulate_login && chdir (pw->pw_dir)) - error (0, errno, _("warning: cannot change directory to %s"), pw->pw_dir); - - run_shell (shell, command, additional_args); + ); + syslog (LOG_NOTICE, +#ifdef SYSLOG_NON_ROOT + "%s(to %s) %s on %s", +#else + "%s%s on %s", +#endif + successful ? "" : "FAILED SU ", +#ifdef SYSLOG_NON_ROOT + new_user, +#endif + old_user, tty); + closelog (); } +#endif /* Ask the user for a password. Return 1 if the user gives the correct password for entry PW, @@ -315,8 +256,7 @@ main (argc, argv) or if PW has an empty password. */ static int -correct_password (pw) - struct passwd *pw; +correct_password (const struct passwd *pw) { char *unencrypted, *encrypted, *correct; #ifdef HAVE_SHADOW_H @@ -348,9 +288,7 @@ correct_password (pw) the value for the SHELL environment variable. */ static void -modify_environment (pw, shell) - struct passwd *pw; - char *shell; +modify_environment (const struct passwd *pw, const char *shell) { char *term; @@ -390,8 +328,7 @@ modify_environment (pw, shell) /* Become the user and group(s) specified by PW. */ static void -change_identity (pw) - struct passwd *pw; +change_identity (const struct passwd *pw) { #ifdef HAVE_INITGROUPS errno = 0; @@ -411,10 +348,7 @@ change_identity (pw) arguments. */ static void -run_shell (shell, command, additional_args) - char *shell; - char *command; - char **additional_args; +run_shell (const char *shell, const char *command, char **additional_args) { const char **args; int argno = 1; @@ -452,57 +386,11 @@ run_shell (shell, command, additional_args) error (1, errno, _("cannot run %s"), shell); } -#if defined (SYSLOG_SUCCESS) || defined (SYSLOG_FAILURE) -/* Log the fact that someone has run su to the user given by PW; - if SUCCESSFUL is nonzero, they gave the correct password, etc. */ - -static void -log_su (pw, successful) - struct passwd *pw; - int successful; -{ - const char *new_user, *old_user, *tty; - -#ifndef SYSLOG_NON_ROOT - if (pw->pw_uid) - return; -#endif - new_user = pw->pw_name; - /* The utmp entry (via getlogin) is probably the best way to identify - the user, especially if someone su's from a su-shell. */ - old_user = getlogin (); - if (old_user == NULL) - old_user = ""; - tty = ttyname (2); - if (tty == NULL) - tty = ""; - /* 4.2BSD openlog doesn't have the third parameter. */ - openlog (basename (program_name), 0 -#ifdef LOG_AUTH - , LOG_AUTH -#endif - ); - syslog (LOG_NOTICE, -#ifdef SYSLOG_NON_ROOT - "%s(to %s) %s on %s", -#else - "%s%s on %s", -#endif - successful ? "" : "FAILED SU ", -#ifdef SYSLOG_NON_ROOT - new_user, -#endif - old_user, tty); - closelog (); -} -#endif - /* Return 1 if SHELL is a restricted shell (one not returned by getusershell), else 0, meaning it is a standard shell. */ static int -restricted_shell (shell) - char *shell; +restricted_shell (const char *shell) { char *line; @@ -519,50 +407,8 @@ restricted_shell (shell) return 1; } -/* Return the number of elements in ARR, a null-terminated array. */ - -static int -elements (arr) - char **arr; -{ - int n = 0; - - for (n = 0; *arr; ++arr) - ++n; - return n; -} - -/* Add VAL to the environment, checking for out of memory errors. */ - -static void -xputenv (val) - char *val; -{ - if (putenv (val)) - error (1, 0, _("virtual memory exhausted")); -} - -/* Return a newly-allocated string whose contents concatenate - those of S1, S2, S3. */ - -static char * -concat (s1, s2, s3) - char *s1, *s2, *s3; -{ - int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3); - char *result = (char *) xmalloc (len1 + len2 + len3 + 1); - - strcpy (result, s1); - strcpy (result + len1, s2); - strcpy (result + len1 + len2, s3); - result[len1 + len2 + len3] = 0; - - return result; -} - static void -usage (status) - int status; +usage (int status) { if (status != 0) fprintf (stderr, _("Try `%s --help' for more information.\n"), @@ -587,3 +433,130 @@ A mere - implies -l. If USER not given, assume root.\n\ } exit (status); } + +int +main (int argc, char **argv) +{ + int optc; + const char *new_user = DEFAULT_USER; + char *command = 0; + char **additional_args = 0; + char *shell = 0; + struct passwd *pw; + struct passwd pw_copy; + + program_name = argv[0]; + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + fast_startup = 0; + simulate_login = 0; + change_environment = 1; + + while ((optc = getopt_long (argc, argv, "c:flmps:", longopts, (int *) 0)) + != EOF) + { + switch (optc) + { + case 0: + break; + + case 'c': + command = optarg; + break; + + case 'f': + fast_startup = 1; + break; + + case 'l': + simulate_login = 1; + break; + + case 'm': + case 'p': + change_environment = 0; + break; + + case 's': + shell = optarg; + break; + + default: + usage (1); + } + } + + if (show_version) + { + printf ("su - %s\n", PACKAGE_VERSION); + exit (0); + } + + if (show_help) + usage (0); + + if (optind < argc && !strcmp (argv[optind], "-")) + { + simulate_login = 1; + ++optind; + } + if (optind < argc) + new_user = argv[optind++]; + if (optind < argc) + additional_args = argv + optind; + + pw = getpwnam (new_user); + if (pw == 0) + error (1, 0, _("user %s does not exist"), new_user); + endpwent (); + + /* Make a copy of the password information and point pw at the local + copy instead. Otherwise, some systems (e.g. Linux) would clobber + the static data through the getlogin call from log_su. */ + pw_copy = *pw; + pw = &pw_copy; + pw->pw_name = xstrdup (pw->pw_name); + pw->pw_dir = xstrdup (pw->pw_dir); + pw->pw_shell = xstrdup (pw->pw_shell); + + if (!correct_password (pw)) + { +#ifdef SYSLOG_FAILURE + log_su (pw, 0); +#endif + error (1, 0, _("incorrect password")); + } +#ifdef SYSLOG_SUCCESS + else + { + log_su (pw, 1); + } +#endif + + if (pw->pw_shell == 0 || pw->pw_shell[0] == 0) + pw->pw_shell = (char *) DEFAULT_SHELL; + if (shell == 0 && change_environment == 0) + shell = getenv ("SHELL"); + if (shell != 0 && getuid () && restricted_shell (pw->pw_shell)) + { + /* The user being su'd to has a nonstandard shell, and so is + probably a uucp account or has restricted access. Don't + compromise the account by allowing access with a standard + shell. */ + error (0, 0, _("using restricted shell %s"), pw->pw_shell); + shell = 0; + } + if (shell == 0) + { + shell = xstrdup (pw->pw_shell); + } + modify_environment (pw, shell); + + change_identity (pw); + if (simulate_login && chdir (pw->pw_dir)) + error (0, errno, _("warning: cannot change directory to %s"), pw->pw_dir); + + run_shell (shell, command, additional_args); +} -- cgit v1.2.3-54-g00ecf