missing bounds check
[unix-history] / usr / src / usr.bin / su / su.c
CommitLineData
3c336b04 1static char *sccsid = "@(#)su.c 4.2 (Berkeley) 4.2";
3a265c7a
BJ
2#include <stdio.h>
3#include <pwd.h>
4
5struct passwd *pwd,*getpwnam();
6char *crypt();
7char *getpass();
8
9main(argc,argv)
10int argc;
11char **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)) {
34bad:
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 }
45ok:
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);
3c336b04 55 inigrp(nptr, pwd->pw_gid);
3a265c7a
BJ
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
67char **environ;
68
69homeis(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
88shellis(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}