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