xref: /original-bsd/usr.bin/su/su.c (revision d25e1985)
1 static char *sccsid = "@(#)su.c	4.1 (Berkeley) 10/01/80";
2 #include <stdio.h>
3 #include <pwd.h>
4 
5 struct	passwd *pwd,*getpwnam();
6 char	*crypt();
7 char	*getpass();
8 
9 main(argc,argv)
10 int	argc;
11 char	**argv;
12 {
13 	char *nptr;
14 	char *password;
15 	int badsw = 0;
16 	char *shell = "/bin/sh";
17 	int niced = 0;
18 
19 	if(argc > 1)
20 		nptr = argv[1];
21 	else {
22 		nptr = "root";
23 		nice(-4);
24 		niced = -4;
25 	}
26 	if((pwd=getpwnam(nptr)) == NULL) {
27 		printf("Unknown id: %s\n",nptr);
28 		exit(1);
29 	}
30 	if(pwd->pw_passwd[0] == '\0' || getuid() == 0)
31 		goto ok;
32 	password = getpass("Password:");
33 	if(badsw || (strcmp(pwd->pw_passwd, crypt(password, pwd->pw_passwd)) != 0)) {
34 bad:
35 		printf("Sorry\n");
36 		if(pwd->pw_uid == 0) {
37 			FILE *console = fopen("/dev/console", "w");
38 			if (console != NULL) {
39 				fprintf(console, "BADSU: %s %s\r\n", getlogin(), ttyname(2));
40 				fclose(console);
41 			}
42 		}
43 		exit(2);
44 	}
45 ok:
46 	endpwent();
47 	if(pwd->pw_uid == 0) {
48 		FILE *console = fopen("/dev/console", "w");
49 		if (console != NULL) {
50 			fprintf(console, "SU: %s %s\r\n", getlogin(), ttyname(2));
51 			fclose(console);
52 		}
53 	}
54 	setgid(pwd->pw_gid);
55 	setuid(pwd->pw_uid);
56 	if (pwd->pw_shell && *pwd->pw_shell)
57 		shell = pwd->pw_shell;
58 	homeis(pwd->pw_dir);
59 	shellis(shell);
60 	nice(-niced);
61 	execl(shell, "su", 0);
62 	printf("No shell\n");
63 	exit(3);
64 }
65 
66 char	**environ;
67 
68 homeis(hp)
69 	char *hp;
70 {
71 	register char *cp, *dp;
72 	register char **ep = environ;
73 	static char homebuf[128];
74 
75 	while (dp = *ep++) {
76 		for (cp = "HOME"; *cp == *dp && *cp; cp++, dp++)
77 			continue;
78 		if (*cp == 0 && (*dp == '=' || *dp == 0)) {
79 			strcpy(homebuf, "HOME=");
80 			strcat(homebuf, hp);
81 			*--ep = homebuf;
82 			return;
83 		}
84 	}
85 }
86 
87 shellis(sp)
88 	char *sp;
89 {
90 	register char *cp, *dp;
91 	register char **ep = environ;
92 	static char shellbuf[128];
93 
94 	while (dp = *ep++) {
95 		for (cp = "SHELL"; *cp == *dp && *cp; cp++, dp++)
96 			continue;
97 		if (*cp == 0 && (*dp == '=' || *dp == 0)) {
98 			strcpy(shellbuf, "SHELL=");
99 			strcat(shellbuf, sp);
100 			*--ep = shellbuf;
101 			return;
102 		}
103 	}
104 }
105