Commit | Line | Data |
---|---|---|
3a265c7a BJ |
1 | static char *sccsid = "@(#)su.c 4.1 (Berkeley) %G%"; |
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 | } |