summaryrefslogtreecommitdiffstats
path: root/usr.bin/su
diff options
context:
space:
mode:
authormarkm <markm@FreeBSD.org>2001-05-26 09:52:36 +0000
committermarkm <markm@FreeBSD.org>2001-05-26 09:52:36 +0000
commitbcb0f2f3e276545287d3e032ec684a144d5b941c (patch)
tree1dba2dac4d19724fa19569a2d6f3fc54c5fe4b32 /usr.bin/su
parent05d9777e736db7b42c83178491117ee572c81d77 (diff)
downloadFreeBSD-src-bcb0f2f3e276545287d3e032ec684a144d5b941c.zip
FreeBSD-src-bcb0f2f3e276545287d3e032ec684a144d5b941c.tar.gz
Deconvolute the authentication mess, and hand total responsiblity
for authentication to PAM. This meens that WHEELSU-type logic can now be effected in the pam.conf "su" configuration stack. While here, clean up the mess that the code had assumed over years of hacking by folks using different styles. ANSIfy. There is more policy in here that can be handed over to PAM. This will be revisited.
Diffstat (limited to 'usr.bin/su')
-rw-r--r--usr.bin/su/Makefile20
-rw-r--r--usr.bin/su/su.144
-rw-r--r--usr.bin/su/su.c520
3 files changed, 226 insertions, 358 deletions
diff --git a/usr.bin/su/Makefile b/usr.bin/su/Makefile
index 6908e37..8a349da 100644
--- a/usr.bin/su/Makefile
+++ b/usr.bin/su/Makefile
@@ -2,25 +2,9 @@
# $FreeBSD$
PROG= su
-SRCS= su.c
-DPADD+= ${LIBUTIL}
-LDADD+= -lutil
-
-.if !defined(NOPAM)
-CFLAGS+= -DUSE_PAM
-DPADD+= ${LIBPAM}
-LDADD+= ${MINUSLPAM}
-.else
-COPTS+= -DSKEY
-DPADD+= ${LIBSKEY} ${LIBMD} ${LIBCRYPT}
-LDADD+= -lskey -lmd -lcrypt
-.endif
-
-.if defined(WHEELSU)
-COPTS+= -DWHEELSU
-.endif
-CFLAGS+= -Wall
+DPADD+= ${LIBUTIL} ${LIBPAM}
+LDADD+= -lutil ${MINUSLPAM}
BINMODE=4555
INSTALLFLAGS=-fschg
diff --git a/usr.bin/su/su.1 b/usr.bin/su/su.1
index 00ff324..f6f0e5a 100644
--- a/usr.bin/su/su.1
+++ b/usr.bin/su/su.1
@@ -32,7 +32,6 @@
.\" @(#)su.1 8.2 (Berkeley) 4/18/94
.\" $FreeBSD$
.\"
-.\" this is for hilit19's braindeadness: "
.Dd April 18, 1994
.Dt SU 1
.Os
@@ -47,24 +46,12 @@
.Op Ar login Op Ar args
.Sh DESCRIPTION
.Nm Su
-requests the superuser password for
-.Ar login
-(or if Kerberos PAMs are used for
-.Dq Ar login Ns .root
-or
-.Dq Ar login Ns /root
-as appropriate),
-and switches to that user ID.
+requests appropriate user credentials via PAM
+and switches to that user ID
+(the default user is the superuser).
A shell is then executed.
-.Nm Su
-will resort to the local password file to find the password for
-.Ar login
-if there is a PAM error.
-If
-.Nm
-is executed by root, no password is requested and a shell
-with the appropriate user ID is executed;
-no additional PAM work is done.
+.Pp
+PAM is used to set all policy.
.Pp
By default, the environment is unmodified with the exception of
.Ev USER ,
@@ -154,38 +141,21 @@ If the optional
are provided on the command line, they are passed to the login shell of
the target login.
.Pp
-Only users who are a member of group 0 (normally
-.Dq wheel )
-can
-.Nm
-to
-.Dq root .
-\ If group 0 is missing or empty, any user can
-.Nm
-to
-.Dq root .
-.Pp
By default (unless the prompt is reset by a startup file) the super-user
prompt is set to
.Dq Sy \&#
to remind one of its awesome power.
.Sh FILES
-.Bl -tag -width /etc/auth.conf -compact
-.It Pa /etc/auth.conf
-configure authentication services
+.Bl -tag -width /etc/pam.conf -compact
.It Pa /etc/pam.conf
-if
.Nm
-is configured with PAM support, it uses
+is configured with PAM support; it uses
.Pa /etc/pam.conf
entries with service name
.Dq su
.El
.Sh SEE ALSO
.Xr csh 1 ,
-.Xr kerberos 1 ,
-.Xr kinit 1 ,
-.Xr login 1 ,
.Xr sh 1 ,
.Xr group 5 ,
.Xr login.conf 5 ,
diff --git a/usr.bin/su/su.c b/usr.bin/su/su.c
index 616a2c2..008a815 100644
--- a/usr.bin/su/su.c
+++ b/usr.bin/su/su.c
@@ -48,90 +48,89 @@ static const char rcsid[] =
#include <sys/param.h>
#include <sys/time.h>
#include <sys/resource.h>
+#include <sys/wait.h>
#include <err.h>
#include <errno.h>
#include <grp.h>
+#include <libutil.h>
+#include <login_cap.h>
#include <paths.h>
#include <pwd.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
-#include <libutil.h>
-#include <login_cap.h>
-#ifdef USE_PAM
#include <security/pam_appl.h>
#include <security/pam_misc.h>
-#include <signal.h>
-#include <sys/wait.h>
-static int export_pam_environment __P((void));
-static int ok_to_export __P((const char *));
+#define PAM_END do { \
+ int local_ret; \
+ if (pamh != NULL && creds_set) { \
+ local_ret = pam_setcred(pamh, PAM_DELETE_CRED); \
+ if (local_ret != PAM_SUCCESS) \
+ syslog(LOG_ERR, "pam_setcred: %s", \
+ pam_strerror(pamh, local_ret)); \
+ local_ret = pam_end(pamh, local_ret); \
+ if (local_ret != PAM_SUCCESS) \
+ syslog(LOG_ERR, "pam_end: %s", \
+ pam_strerror(pamh, local_ret)); \
+ } \
+} while (0)
+
+
+#define PAM_SET_ITEM(what, item) do { \
+ int local_ret; \
+ local_ret = pam_set_item(pamh, what, item); \
+ if (local_ret != PAM_SUCCESS) { \
+ syslog(LOG_ERR, "pam_set_item(" #what "): %s", \
+ pam_strerror(pamh, local_ret)); \
+ errx(1, "pam_set_item(" #what "): %s", \
+ pam_strerror(pamh, local_ret)); \
+ } \
+} while (0)
+
+#define ARGSTR "-flmc:"
+
+enum tristate { UNSET, YES, NO };
static pam_handle_t *pamh = NULL;
-static char **environ_pam;
-
-#define PAM_END { \
- if ((retcode = pam_setcred(pamh, PAM_DELETE_CRED)) != PAM_SUCCESS) { \
- syslog(LOG_ERR, "pam_setcred: %s", pam_strerror(pamh, retcode)); \
- } \
- if ((retcode = pam_end(pamh,retcode)) != PAM_SUCCESS) { \
- syslog(LOG_ERR, "pam_end: %s", pam_strerror(pamh, retcode)); \
- } \
-}
-#else /* !USE_PAM */
-#ifdef SKEY
-#include <skey.h>
-#endif
-#endif /* USE_PAM */
+static int creds_set = 0;
+static char **environ_pam;
-#define ARGSTR "-flmc:"
+static char *ontty(void);
+static int chshell(char *);
+static void usage(void);
+static int export_pam_environment(void);
+static int ok_to_export(const char *);
-char *ontty __P((void));
-int chshell __P((char *));
-static void usage __P((void));
+extern char **environ;
int
-main(argc, argv)
- int argc;
- char **argv;
+main(int argc, char *argv[])
{
- extern char **environ;
- struct passwd *pwd;
-#ifdef WHEELSU
- char *targetpass;
- int iswheelsu;
-#endif /* WHEELSU */
- char *p, *user, *shell=NULL, *username, *cleanenv = NULL, **nargv, **np;
- uid_t ruid;
- gid_t gid;
- int asme, ch, asthem, fastlogin, prio, i;
- enum { UNSET, YES, NO } iscsh = UNSET;
- login_cap_t *lc;
- char *class=NULL;
- int setwhat;
-#ifdef USE_PAM
- int retcode;
- struct pam_conv conv = { misc_conv, NULL };
- char myhost[MAXHOSTNAMELEN + 1], *mytty;
- int statusp=0;
- int child_pid, child_pgrp, ret_pid;
-#else /* !USE_PAM */
- char **g;
- struct group *gr;
-#endif /* USE_PAM */
- char shellbuf[MAXPATHLEN];
-
-#ifdef WHEELSU
- iswheelsu =
-#endif /* WHEELSU */
- asme = asthem = fastlogin = 0;
+ struct passwd *pwd;
+ struct pam_conv conv = {misc_conv, NULL};
+ enum tristate iscsh;
+ login_cap_t *lc;
+ uid_t ruid;
+ gid_t gid;
+ int asme, ch, asthem, fastlogin, prio, i, setwhat, retcode,
+ statusp, child_pid, child_pgrp, ret_pid;
+ char *p, *user, *shell, *username, *cleanenv, **nargv, **np,
+ *class, *mytty, shellbuf[MAXPATHLEN],
+ myhost[MAXHOSTNAMELEN + 1];
+
+ shell = class = cleanenv = NULL;
+ asme = asthem = fastlogin = statusp = 0;
user = "root";
- while((ch = getopt(argc, argv, ARGSTR)) != -1)
- switch((char)ch) {
+ iscsh = UNSET;
+
+ while ((ch = getopt(argc, argv, ARGSTR)) != -1)
+ switch ((char)ch) {
case 'f':
fastlogin = 1;
break;
@@ -155,20 +154,19 @@ main(argc, argv)
if (optind < argc)
user = argv[optind++];
- if (strlen(user) > MAXLOGNAME - 1) {
- errx(1, "username too long");
- }
-
if (user == NULL)
usage();
- if ((nargv = malloc (sizeof (char *) * (argc + 4))) == NULL) {
- errx(1, "malloc failure");
- }
+ if (strlen(user) > MAXLOGNAME - 1)
+ errx(1, "username too long");
+
+ nargv = malloc(sizeof(char *) * (argc + 4));
+ if (nargv == NULL)
+ errx(1, "malloc failure");
nargv[argc + 3] = NULL;
for (i = argc; i >= optind; i--)
- nargv[i + 3] = argv[i];
+ nargv[i + 3] = argv[i];
np = &nargv[i + 3];
argv += optind;
@@ -177,33 +175,38 @@ main(argc, argv)
prio = getpriority(PRIO_PROCESS, 0);
if (errno)
prio = 0;
- (void)setpriority(PRIO_PROCESS, 0, -2);
+
+ setpriority(PRIO_PROCESS, 0, -2);
openlog("su", LOG_CONS, LOG_AUTH);
- /* get current login name and shell */
+ /* get current login name, real uid and shell */
ruid = getuid();
username = getlogin();
- if (username == NULL || (pwd = getpwnam(username)) == NULL ||
- pwd->pw_uid != ruid)
+ pwd = getpwnam(username);
+ if (username == NULL || pwd == NULL || pwd->pw_uid != ruid)
pwd = getpwuid(ruid);
if (pwd == NULL)
errx(1, "who are you?");
- username = strdup(pwd->pw_name);
gid = pwd->pw_gid;
+
+ username = strdup(pwd->pw_name);
if (username == NULL)
- err(1, NULL);
+ err(1, "strdup failure");
+
if (asme) {
if (pwd->pw_shell != NULL && *pwd->pw_shell != '\0') {
- /* copy: pwd memory is recycled */
- shell = strncpy(shellbuf, pwd->pw_shell, sizeof shellbuf);
- shellbuf[sizeof shellbuf - 1] = '\0';
- } else {
+ /* must copy - pwd memory is recycled */
+ shell = strncpy(shellbuf, pwd->pw_shell,
+ sizeof(shellbuf));
+ shellbuf[sizeof(shellbuf) - 1] = '\0';
+ }
+ else {
shell = _PATH_BSHELL;
iscsh = NO;
}
}
-#ifdef USE_PAM
+ /* Do the whole PAM startup thing */
retcode = pam_start("su", user, &conv, &pamh);
if (retcode != PAM_SUCCESS) {
syslog(LOG_ERR, "pam_start: %s", pam_strerror(pamh, retcode));
@@ -211,144 +214,66 @@ main(argc, argv)
}
gethostname(myhost, sizeof(myhost));
- retcode = pam_set_item(pamh, PAM_RHOST, myhost);
- if (retcode != PAM_SUCCESS) {
- syslog(LOG_ERR, "pam_set_item(PAM_RHOST): %s", pam_strerror(pamh, retcode));
- errx(1, "pam_set_item(PAM_RHOST): %s", pam_strerror(pamh, retcode));
- }
+ PAM_SET_ITEM(PAM_RHOST, myhost);
mytty = ttyname(STDERR_FILENO);
if (!mytty)
mytty = "tty";
- retcode = pam_set_item(pamh, PAM_TTY, mytty);
+ PAM_SET_ITEM(PAM_TTY, mytty);
+
+ retcode = pam_authenticate(pamh, 0);
if (retcode != PAM_SUCCESS) {
- syslog(LOG_ERR, "pam_set_item(PAM_TTY): %s", pam_strerror(pamh, retcode));
- errx(1, "pam_set_item(PAM_TTY): %s", pam_strerror(pamh, retcode));
+ syslog(LOG_ERR, "pam_authenticate: %s",
+ pam_strerror(pamh, retcode));
+ errx(1, "Sorry");
}
-
- if (ruid) {
- retcode = pam_authenticate(pamh, 0);
- if (retcode != PAM_SUCCESS) {
- syslog(LOG_ERR, "pam_authenticate: %s", pam_strerror(pamh, retcode));
- errx(1, "Sorry");
- }
-
- if ((retcode = pam_get_item(pamh, PAM_USER, (const void **) &p)) == PAM_SUCCESS) {
- user = p;
- } else
- syslog(LOG_ERR, "pam_get_item(PAM_USER): %s",
- pam_strerror(pamh, retcode));
-
- retcode = pam_acct_mgmt(pamh, 0);
- if (retcode == PAM_NEW_AUTHTOK_REQD) {
- retcode = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
- if (retcode != PAM_SUCCESS) {
- syslog(LOG_ERR, "pam_chauthtok: %s", pam_strerror(pamh, retcode));
- errx(1, "Sorry");
- }
- }
+ retcode = pam_get_item(pamh, PAM_USER, (const void **)&p);
+ if (retcode == PAM_SUCCESS)
+ user = p;
+ else
+ syslog(LOG_ERR, "pam_get_item(PAM_USER): %s",
+ pam_strerror(pamh, retcode));
+
+ retcode = pam_acct_mgmt(pamh, 0);
+ if (retcode == PAM_NEW_AUTHTOK_REQD) {
+ retcode = pam_chauthtok(pamh,
+ PAM_CHANGE_EXPIRED_AUTHTOK);
if (retcode != PAM_SUCCESS) {
- syslog(LOG_ERR, "pam_acct_mgmt: %s", pam_strerror(pamh, retcode));
+ syslog(LOG_ERR, "pam_chauthtok: %s",
+ pam_strerror(pamh, retcode));
errx(1, "Sorry");
}
}
-#endif /* USE_PAM */
+ if (retcode != PAM_SUCCESS) {
+ syslog(LOG_ERR, "pam_acct_mgmt: %s",
+ pam_strerror(pamh, retcode));
+ errx(1, "Sorry");
+ }
/* get target login information, default to root */
- if ((pwd = getpwnam(user)) == NULL) {
+ pwd = getpwnam(user);
+ if (pwd == NULL)
errx(1, "unknown login: %s", user);
- }
- if (class==NULL) {
+ if (class == NULL)
lc = login_getpwclass(pwd);
- } else {
- if (ruid)
+ else {
+ if (ruid != 0)
errx(1, "only root may use -c");
lc = login_getclass(class);
if (lc == NULL)
errx(1, "unknown class: %s", class);
}
-#ifndef USE_PAM
-#ifdef WHEELSU
- targetpass = strdup(pwd->pw_passwd);
-#endif /* WHEELSU */
-
- if (ruid) {
- {
- /*
- * Only allow those with pw_gid==0 or those listed in
- * group zero to su to root. If group zero entry is
- * missing or empty, then allow anyone to su to root.
- * iswheelsu will only be set if the user is EXPLICITLY
- * listed in group zero.
- */
- if (pwd->pw_uid == 0 && (gr = getgrgid((gid_t)0)) &&
- gr->gr_mem && *(gr->gr_mem))
- for (g = gr->gr_mem;; ++g) {
- if (!*g) {
- if (gid == 0)
- break;
- else
- errx(1,
- "you are not in the correct group (%s) to su %s.",
- gr->gr_name,
- user);
- }
- if (strcmp(username, *g) == 0) {
-#ifdef WHEELSU
- iswheelsu = 1;
-#endif /* WHEELSU */
- break;
- }
- }
- }
- /* if target requires a password, verify it */
- if (*pwd->pw_passwd) {
-#ifdef SKEY
-#ifdef WHEELSU
- if (iswheelsu) {
- pwd = getpwnam(username);
- }
-#endif /* WHEELSU */
- p = skey_getpass("Password:", pwd, 1);
- if (!(!strcmp(pwd->pw_passwd, skey_crypt(p, pwd->pw_passwd, pwd, 1))
-#ifdef WHEELSU
- || (iswheelsu && !strcmp(targetpass, crypt(p,targetpass)))
-#endif /* WHEELSU */
- ))
-#else /* !SKEY */
- p = getpass("Password:");
- if (strcmp(pwd->pw_passwd, crypt(p, pwd->pw_passwd)))
-#endif /* SKEY */
- {
- {
- syslog(LOG_AUTH|LOG_WARNING, "BAD SU %s to %s%s", username, user, ontty());
- errx(1, "Sorry");
- }
- }
-#ifdef WHEELSU
- if (iswheelsu) {
- pwd = getpwnam(user);
- }
-#endif /* WHEELSU */
- }
- if (pwd->pw_expire && time(NULL) >= pwd->pw_expire) {
- syslog(LOG_AUTH|LOG_WARNING,
- "BAD SU %s to %s%s", username,
- user, ontty());
- errx(1, "Sorry - account expired");
- }
- }
-#endif /* USE_PAM */
-
+ /* if asme and non-standard target shell, must be root */
if (asme) {
- /* if asme and non-standard target shell, must be root */
- if (ruid && !chshell(pwd->pw_shell))
+ if (ruid != 0 && !chshell(pwd->pw_shell))
errx(1, "permission denied (shell).");
- } else if (pwd->pw_shell && *pwd->pw_shell) {
+ }
+ else if (pwd->pw_shell && *pwd->pw_shell) {
shell = pwd->pw_shell;
iscsh = UNSET;
- } else {
+ }
+ else {
shell = _PATH_BSHELL;
iscsh = NO;
}
@@ -360,24 +285,23 @@ main(argc, argv)
++p;
else
p = shell;
- if ((iscsh = strcmp(p, "csh") ? NO : YES) == NO)
- iscsh = strcmp(p, "tcsh") ? NO : YES;
+ iscsh = strcmp(p, "csh") ? (strcmp(p, "tcsh") ? NO : YES) : YES;
}
-
- (void)setpriority(PRIO_PROCESS, 0, prio);
+ setpriority(PRIO_PROCESS, 0, prio);
/*
- * PAM modules might add supplementary groups in
- * pam_setcred(), so initialize them first.
+ * PAM modules might add supplementary groups in pam_setcred(), so
+ * initialize them first.
*/
if (setusercontext(lc, pwd, pwd->pw_uid, LOGIN_SETGROUP) < 0)
err(1, "setusercontext");
-#ifdef USE_PAM
retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED);
- if (retcode != PAM_SUCCESS) {
- syslog(LOG_ERR, "pam_setcred: %s", pam_strerror(pamh, retcode));
- }
+ if (retcode != PAM_SUCCESS)
+ syslog(LOG_ERR, "pam_setcred(pamh, PAM_ESTABLISH_CRED): %s",
+ pam_strerror(pamh, retcode));
+ else
+ creds_set = 1;
/*
* We must fork() before setuid() because we need to call
@@ -385,109 +309,99 @@ main(argc, argv)
*/
statusp = 1;
- switch ((child_pid = fork())) {
+ child_pid = fork();
+ switch (child_pid) {
default:
- while ((ret_pid = waitpid(child_pid, &statusp, WUNTRACED)) != -1) {
- if (WIFSTOPPED(statusp)) {
- child_pgrp = tcgetpgrp(1);
- kill(getpid(), SIGSTOP);
- tcsetpgrp(1, child_pgrp);
- kill(child_pid, SIGCONT);
- statusp = 1;
- continue;
+ while ((ret_pid = waitpid(child_pid, &statusp, WUNTRACED)) != -1) {
+ if (WIFSTOPPED(statusp)) {
+ child_pgrp = tcgetpgrp(1);
+ kill(getpid(), SIGSTOP);
+ tcsetpgrp(1, child_pgrp);
+ kill(child_pid, SIGCONT);
+ statusp = 1;
+ continue;
+ }
+ break;
}
- break;
- }
- if (ret_pid == -1)
- err(1, "waitpid");
- PAM_END;
- exit(statusp);
+ if (ret_pid == -1)
+ err(1, "waitpid");
+ PAM_END;
+ exit(statusp);
case -1:
- err(1, "fork");
- PAM_END;
- exit (1);
+ err(1, "fork");
+ PAM_END;
+ exit(1);
case 0:
-#endif /* USE_PAM */
-
- /*
- * Set all user context except for:
- * Environmental variables
- * Umask
- * Login records (wtmp, etc)
- * Path
- */
- setwhat = LOGIN_SETALL & ~(LOGIN_SETENV | LOGIN_SETUMASK |
- LOGIN_SETLOGIN | LOGIN_SETPATH | LOGIN_SETGROUP);
-
- /*
- * Don't touch resource/priority settings if -m has been
- * used or -l and -c hasn't, and we're not su'ing to root.
- */
- if ((asme || (!asthem && class == NULL)) && pwd->pw_uid)
- setwhat &= ~(LOGIN_SETPRIORITY|LOGIN_SETRESOURCES);
- if (setusercontext(lc, pwd, pwd->pw_uid, setwhat) < 0)
- err(1, "setusercontext");
-
- if (!asme) {
- if (asthem) {
- p = getenv("TERM");
- environ = &cleanenv;
-
-#ifdef USE_PAM
- /*
- * Add any environmental variables that the
- * PAM modules may have set.
- */
- environ_pam = pam_getenvlist(pamh);
- if (environ_pam)
- export_pam_environment();
-#endif /* USE_PAM */
-
- /* set the su'd user's environment & umask */
- setusercontext(lc, pwd, pwd->pw_uid, LOGIN_SETPATH|LOGIN_SETUMASK|LOGIN_SETENV);
- if (p)
- (void)setenv("TERM", p, 1);
- if (chdir(pwd->pw_dir) < 0)
- errx(1, "no directory");
+ /*
+ * Set all user context except for: Environmental variables
+ * Umask Login records (wtmp, etc) Path
+ */
+ setwhat = LOGIN_SETALL & ~(LOGIN_SETENV | LOGIN_SETUMASK |
+ LOGIN_SETLOGIN | LOGIN_SETPATH | LOGIN_SETGROUP);
+ /*
+ * Don't touch resource/priority settings if -m has been used
+ * or -l and -c hasn't, and we're not su'ing to root.
+ */
+ if ((asme || (!asthem && class == NULL)) && pwd->pw_uid)
+ setwhat &= ~(LOGIN_SETPRIORITY | LOGIN_SETRESOURCES);
+ if (setusercontext(lc, pwd, pwd->pw_uid, setwhat) < 0)
+ err(1, "setusercontext");
+
+ if (!asme) {
+ if (asthem) {
+ p = getenv("TERM");
+ environ = &cleanenv;
+
+ /*
+ * Add any environmental variables that the
+ * PAM modules may have set.
+ */
+ environ_pam = pam_getenvlist(pamh);
+ if (environ_pam)
+ export_pam_environment();
+
+ /* set the su'd user's environment & umask */
+ setusercontext(lc, pwd, pwd->pw_uid,
+ LOGIN_SETPATH | LOGIN_SETUMASK |
+ LOGIN_SETENV);
+ if (p)
+ setenv("TERM", p, 1);
+ if (chdir(pwd->pw_dir) < 0)
+ errx(1, "no directory");
+ }
+ if (asthem || pwd->pw_uid)
+ setenv("USER", pwd->pw_name, 1);
+ setenv("HOME", pwd->pw_dir, 1);
+ setenv("SHELL", shell, 1);
}
- if (asthem || pwd->pw_uid)
- (void)setenv("USER", pwd->pw_name, 1);
- (void)setenv("HOME", pwd->pw_dir, 1);
- (void)setenv("SHELL", shell, 1);
- }
-
- login_close(lc);
-
- if (iscsh == YES) {
- if (fastlogin)
- *np-- = "-f";
- if (asme)
- *np-- = "-m";
- }
+ login_close(lc);
- /* csh strips the first character... */
- *np = asthem ? "-su" : iscsh == YES ? "_su" : "su";
+ if (iscsh == YES) {
+ if (fastlogin)
+ *np-- = "-f";
+ if (asme)
+ *np-- = "-m";
+ }
+ /* csh strips the first character... */
+ *np = asthem ? "-su" : iscsh == YES ? "_su" : "su";
- if (ruid != 0)
- syslog(LOG_NOTICE, "%s to %s%s",
- username, user, ontty());
+ if (ruid != 0)
+ syslog(LOG_NOTICE, "%s to %s%s", username, user,
+ ontty());
- execv(shell, np);
- err(1, "%s", shell);
-#ifdef USE_PAM
+ execv(shell, np);
+ err(1, "%s", shell);
}
-#endif /* USE_PAM */
}
-#ifdef USE_PAM
static int
-export_pam_environment()
+export_pam_environment(void)
{
char **pp;
for (pp = environ_pam; *pp != NULL; pp++) {
if (ok_to_export(*pp))
- (void) putenv(*pp);
+ putenv(*pp);
free(*pp);
}
return PAM_SUCCESS;
@@ -501,8 +415,7 @@ export_pam_environment()
* Solaris pam_putenv(3) man page.
*/
static int
-ok_to_export(s)
- const char *s;
+ok_to_export(const char *s)
{
static const char *noexport[] = {
"SHELL", "HOME", "LOGNAME", "MAIL", "CDPATH",
@@ -522,30 +435,31 @@ ok_to_export(s)
}
return 1;
}
-#endif /* USE_PAM */
static void
-usage()
+usage(void)
{
errx(1, "usage: su [%s] [login [args]]", ARGSTR);
}
-int
-chshell(sh)
- char *sh;
+static int
+chshell(char *sh)
{
- int r = 0;
+ int r;
char *cp;
+ r = 0;
setusershell();
- while (!r && (cp = getusershell()) != NULL)
- r = strcmp(cp, sh) == 0;
+ do {
+ cp = getusershell();
+ r = strcmp(cp, sh);
+ } while (!r && cp != NULL);
endusershell();
return r;
}
-char *
-ontty()
+static char *
+ontty(void)
{
char *p;
static char buf[MAXPATHLEN + 4];
@@ -554,5 +468,5 @@ ontty()
p = ttyname(STDERR_FILENO);
if (p)
snprintf(buf, sizeof(buf), " on %s", p);
- return (buf);
+ return buf;
}
OpenPOWER on IntegriCloud