Protoize and reorder functions.
authorJim Meyering <jim@meyering.net>
Sun, 24 Mar 1996 17:43:41 +0000 (17:43 +0000)
committerJim Meyering <jim@meyering.net>
Sun, 24 Mar 1996 17:43:41 +0000 (17:43 +0000)
src/su.c

index 71452bf..ef068cb 100644 (file)
--- a/src/su.c
+++ b/src/su.c
@@ -79,7 +79,6 @@
 
 #if defined(HAVE_SYSLOG_H) && defined(HAVE_SYSLOG)
 #include <syslog.h>
-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);
+}