static char *sccsid
= "@(#)su.c 4.5 (Berkeley) %G%";
#include <sys/resource.h>
char userbuf
[16] = "USER=";
char homebuf
[128] = "HOME=";
char shellbuf
[128] = "SHELL=";
char pathbuf
[128] = "PATH=:/usr/ucb:/bin:/usr/bin";
char *cleanenv
[] = { userbuf
, homebuf
, shellbuf
, pathbuf
, 0, 0 };
struct passwd
*pwd
,*getpwnam();
if (argc
> 1 && strcmp(argv
[1], "-f") == 0) {
if (argc
> 1 && strcmp(argv
[1], "-") == 0) {
if (argc
> 1 && argv
[1][0] != '-') {
if (strcmp(user
, "root") == 0)
setpriority(PRIO_PROCESS
, 0, -2);
if ((pwd
= getpwnam(user
)) == NULL
) {
fprintf(stderr
, "Unknown login: %s\n", user
);
if (pwd
->pw_passwd
[0] == '\0' || getuid() == 0)
password
= getpass("Password:");
if (strcmp(pwd
->pw_passwd
, crypt(password
, pwd
->pw_passwd
)) != 0) {
fprintf(stderr
, "Sorry\n");
FILE *console
= fopen("/dev/console", "w");
fprintf(console
, "BADSU: %s %s\r\n",
FILE *console
= fopen("/dev/console", "w");
fprintf(console
, "SU: %s %s\r\n",
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
[4] = getenv("TERM");
setenv("USER", pwd
->pw_name
, userbuf
);
setenv("SHELL", shell
, shellbuf
);
setenv("HOME", pwd
->pw_dir
, homebuf
);
setpriority(PRIO_PROCESS
, 0, 0);
if (chdir(pwd
->pw_dir
) < 0) {
fprintf(stderr
, "No directory\n");
fprintf(stderr
, "No shell\n");
char *ename
, *eval
, *buf
;
register char **ep
= environ
;
* this assumes an environment variable "ename" already exists
for (cp
= ename
; *cp
== *dp
&& *cp
; cp
++, dp
++)
if (*cp
== 0 && (*dp
== '=' || *dp
== 0)) {
register char **ep
= environ
;
for (cp
= ename
; *cp
== *dp
&& *cp
; cp
++, dp
++)
if (*cp
== 0 && (*dp
== '=' || *dp
== 0))