date and time created 83/02/11 15:44:08 by rrh
[unix-history] / usr / src / usr.bin / su / su.c
CommitLineData
13dd8b1d
SL
1#ifndef lint
2static char *sccsid = "@(#)su.c 4.4 (Berkeley) 4.4";
3#endif
4
3a265c7a
BJ
5#include <stdio.h>
6#include <pwd.h>
7
8struct passwd *pwd,*getpwnam();
9char *crypt();
10char *getpass();
11
12main(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 }
41ok:
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
72char **environ;
73
74homeis(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
93shellis(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}