* Copyright (c) 1988 The Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
"@(#) Copyright (c) 1988 The Regents of the University of California.\n\
static char sccsid
[] = "@(#)su.c 5.6 (Berkeley) %G%";
#include <sys/resource.h>
extern int errno
, optind
;
register struct passwd
*pwd
;
int ch
, fulllogin
, fastlogin
, prio
;
char *user
, *shell
, *username
, nbuf
[50];
char *crypt(), *getpass(), *getenv(), *getlogin(), *strcpy();
fulllogin
= fastlogin
= 0;
while ((ch
= getopt(argc
, argv
, "-fl")) != EOF
)
fprintf(stderr
, "usage: su [-fl] [login]\n");
if ((pwd
= getpwuid(getuid())) == NULL
) {
fprintf(stderr
, "su: who are you?\n");
username
= strcpy(nbuf
, pwd
->pw_name
);
if ((pwd
= getpwnam(user
)) == NULL
) {
fprintf(stderr
, "su: unknown login %s\n", user
);
/* only allow those in group zero to su to root. */
if (pwd
->pw_uid
== 0 && (gr
= getgrgid(0)))
for (g
= gr
->gr_mem
;; ++g
) {
fprintf(stderr
, "su: you are not in the correct group to su %s.\n", user
);
if (!strcmp(username
, *g
))
openlog("su", LOG_ODELAY
, LOG_AUTH
);
prio
= getpriority(PRIO_PROCESS
, 0);
(void)setpriority(PRIO_PROCESS
, 0, -2);
if ((p
= getlogin()) && *p
)
if (pwd
->pw_passwd
[0] && getuid()) {
p
= getpass("Password:");
if (strcmp(pwd
->pw_passwd
, crypt(p
, pwd
->pw_passwd
))) {
fprintf(stderr
, "Sorry\n");
syslog(LOG_CRIT
, "BAD SU %s on %s",
if (setgid(pwd
->pw_gid
) < 0) {
if (initgroups(user
, pwd
->pw_gid
)) {
fprintf(stderr
, "su: initgroups failed\n");
if (setuid(pwd
->pw_uid
) < 0) {
if (pwd
->pw_shell
&& *pwd
->pw_shell
)
cleanenv
[0] = "PATH=:/usr/ucb:/bin:/usr/bin";
(void)setenv("TERM", p
, 1);
if (chdir(pwd
->pw_dir
) < 0) {
fprintf(stderr
, "su: no directory\n");
(void)setenv("USER", pwd
->pw_name
, 1);
else if (strcmp(user
, "root"))
(void)setenv("USER", pwd
->pw_name
, 1);
(void)setenv("SHELL", shell
, 1);
(void)setenv("HOME", pwd
->pw_dir
, 1);
*argv
= fulllogin
? "-su" : "su";
syslog(LOG_NOTICE
, "%s on %s", username
, ttyname(2));
(void)setpriority(PRIO_PROCESS
, 0, prio
);
fprintf(stderr
, "su: no shell\n");