summaryrefslogtreecommitdiffstats
path: root/login-utils/su.c
diff options
context:
space:
mode:
authorJim Meyering1996-03-24 18:43:41 +0100
committerJim Meyering1996-03-24 18:43:41 +0100
commit59b95363256156a9d2b60b901ed829f038475618 (patch)
tree1df3a0efd7d51105f83b5252a838cc85d1944cf3 /login-utils/su.c
parent(main): Declare to be of type int, not void. (diff)
downloadkernel-qcow2-util-linux-59b95363256156a9d2b60b901ed829f038475618.tar.gz
kernel-qcow2-util-linux-59b95363256156a9d2b60b901ed829f038475618.tar.xz
kernel-qcow2-util-linux-59b95363256156a9d2b60b901ed829f038475618.zip
Protoize and reorder functions.
Diffstat (limited to 'login-utils/su.c')
-rw-r--r--login-utils/su.c425
1 files changed, 199 insertions, 226 deletions
diff --git a/login-utils/su.c b/login-utils/su.c
index 71452bfa4..ef068cba2 100644
--- a/login-utils/su.c
+++ b/login-utils/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);
+}