xref: /original-bsd/usr.bin/su/su.c (revision 6b7db209)
1 static char *sccsid = "@(#)su.c	4.3 (Berkeley) 4.3";
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 	initgroups(nptr, pwd->pw_gid);
56 	setuid(pwd->pw_uid);
57 	if (pwd->pw_shell && *pwd->pw_shell)
58 		shell = pwd->pw_shell;
59 	homeis(pwd->pw_dir);
60 	shellis(shell);
61 	nice(-niced);
62 	execl(shell, "su", 0);
63 	printf("No shell\n");
64 	exit(3);
65 }
66 
67 char	**environ;
68 
69 homeis(hp)
70 	char *hp;
71 {
72 	register char *cp, *dp;
73 	register char **ep = environ;
74 	static char homebuf[128];
75 
76 	while (dp = *ep++) {
77 		for (cp = "HOME"; *cp == *dp && *cp; cp++, dp++)
78 			continue;
79 		if (*cp == 0 && (*dp == '=' || *dp == 0)) {
80 			strcpy(homebuf, "HOME=");
81 			strcat(homebuf, hp);
82 			*--ep = homebuf;
83 			return;
84 		}
85 	}
86 }
87 
88 shellis(sp)
89 	char *sp;
90 {
91 	register char *cp, *dp;
92 	register char **ep = environ;
93 	static char shellbuf[128];
94 
95 	while (dp = *ep++) {
96 		for (cp = "SHELL"; *cp == *dp && *cp; cp++, dp++)
97 			continue;
98 		if (*cp == 0 && (*dp == '=' || *dp == 0)) {
99 			strcpy(shellbuf, "SHELL=");
100 			strcat(shellbuf, sp);
101 			*--ep = shellbuf;
102 			return;
103 		}
104 	}
105 }
106