summaryrefslogtreecommitdiff
path: root/src/su.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>1994-07-26 03:44:37 +0000
committerJim Meyering <jim@meyering.net>1994-07-26 03:44:37 +0000
commit7b5a41383b0a6534f9cccc10a716479f554bc9be (patch)
tree6d75cbadaac03bc5c896d4e9d738c3fddc9c0112 /src/su.c
parent6cab7081628395d62eb223d9225b792ebccf7313 (diff)
downloadcoreutils-7b5a41383b0a6534f9cccc10a716479f554bc9be.tar.xz
.
Diffstat (limited to 'src/su.c')
-rw-r--r--src/su.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/src/su.c b/src/su.c
index 96785fbb2..a5abd95e3 100644
--- a/src/su.c
+++ b/src/su.c
@@ -150,6 +150,7 @@ void setusershell ();
char *basename ();
char *xmalloc ();
char *xrealloc ();
+char *xstrdup ();
void error ();
static char *concat ();
@@ -205,6 +206,7 @@ main (argc, argv)
char **additional_args = 0;
char *shell = 0;
struct passwd *pw;
+ struct passwd pw_copy;
program_name = argv[0];
fast_startup = 0;
@@ -268,6 +270,16 @@ main (argc, argv)
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
@@ -296,13 +308,21 @@ main (argc, argv)
shell = 0;
}
if (shell == 0)
- shell = pw->pw_shell;
- shell = strcpy (xmalloc (strlen (shell) + 1), shell);
+ {
+ /* FIXME: Using malloc (through xstrdup) to allocate this space
+ is a minor memory leak. Consider using alloca instead. */
+ 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);
+
+ free (pw->pw_name);
+ free (pw->pw_dir);
+ free (pw->pw_shell);
+
run_shell (shell, command, additional_args);
}
@@ -439,7 +459,7 @@ run_shell (shell, command, additional_args)
if (additional_args)
for (; *additional_args; ++additional_args)
args[argno++] = *additional_args;
- args[argno] = 0;
+ args[argno] = NULL;
execv (shell, args);
error (1, errno, "cannot run %s", shell);
}
@@ -463,10 +483,10 @@ log_su (pw, successful)
/* 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 == 0)
+ if (old_user == NULL)
old_user = "";
tty = ttyname (2);
- if (tty == 0)
+ if (tty == NULL)
tty = "";
/* 4.2BSD openlog doesn't have the third parameter. */
openlog (basename (program_name), 0