source: trunk/minix/commands/simple/su.c@ 15

Last change on this file since 15 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 3.4 KB
RevLine 
[9]1/* su - become super-user Author: Patrick van Kleef */
2
3#include <sys/types.h>
4#include <pwd.h>
5#include <grp.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9#include <unistd.h>
10#include <limits.h>
11#include <fcntl.h>
12#include <time.h>
13#if __minix_vmd
14#include <sys/syslog.h>
15#endif
16#include <minix/minlib.h>
17
18_PROTOTYPE(int main, (int argc, char **argv));
19
20int main(argc, argv)
21int argc;
22char *argv[];
23{
24 register char *name, *password;
25 char *shell, sh0[100];
26 char from_user[8+1], from_shell[100];
27 register struct passwd *pwd;
28 char USER[20], LOGNAME[25], HOME[100], SHELL[100];
29 char *envv[20], **envp;
30 int smallenv;
31 char *p;
32 int super;
33 int loginshell;
34#if __minix_vmd
35 gid_t groups[NGROUPS_MAX];
36 int ngroups;
37 int g;
38#endif
39
40 smallenv = 0;
41 loginshell = 0;
42 if (argc > 1 && (strcmp(argv[1], "-") == 0 || strcmp(argv[1], "-e") == 0)) {
43 if (argv[1][1] == 0)
44 loginshell= 1; /* 'su -' reads .profile */
45 argv[1] = argv[0];
46 argv++;
47 argc--;
48 smallenv = 1; /* Use small environment. */
49 }
50 if (argc > 1) {
51 if (argv[1][0] == '-') {
52 fprintf(stderr,
53 "Usage: su [-[e]] [user [shell-arguments ...]]\n");
54 exit(1);
55 }
56 name = argv[1];
57 argv[1] = argv[0];
58 argv++;
59 } else {
60 name = "root";
61 }
62
63 if ((pwd = getpwuid(getuid())) == 0) {
64 fprintf(stderr, "You do not exist\n");
65 exit(1);
66 }
67 strncpy(from_user, pwd->pw_name, 8);
68 from_user[8]= 0;
69 strncpy(from_shell, pwd->pw_shell[0] == '\0' ? "/bin/sh" : pwd->pw_shell,
70 sizeof(from_shell)-1);
71 from_shell[sizeof(from_shell)-1]= 0;
72
73 if ((pwd = getpwnam(name)) == 0) {
74 fprintf(stderr, "Unknown id: %s\n", name);
75 exit(1);
76 }
77 super = 0;
78 if (getgid() == 0) super = 1;
79#if __minix_vmd
80 ngroups = getgroups(NGROUPS_MAX, groups);
81 for (g = 0; g < ngroups; g++) if (groups[g] == 0) super = 1;
82#endif
83
84 if (!super && strcmp(pwd->pw_passwd, crypt("", pwd->pw_passwd)) != 0) {
85#if __minix_vmd
86 openlog("su", 0, LOG_AUTH);
87#endif
88 password = getpass("Password:");
89 if (password == 0
90 || strcmp(pwd->pw_passwd, crypt(password, pwd->pw_passwd)) != 0) {
91 if (password != 0 && *password != 0) {
92#if __minix_vmd
93 syslog(LOG_WARNING, "su %s failed for %s",
94 name, from_user);
95#endif
96 }
97 fprintf(stderr, "Sorry\n");
98 exit(2);
99 }
100#if __minix_vmd
101 syslog(LOG_NOTICE, "su %s succeeded for %s", name, from_user);
102 closelog();
103#endif
104 }
105
106#if __minix_vmd
107 initgroups(pwd->pw_name, pwd->pw_gid);
108#endif
109 setgid(pwd->pw_gid);
110 setuid(pwd->pw_uid);
111 if (loginshell) {
112 shell = pwd->pw_shell[0] == '\0' ? "/bin/sh" : pwd->pw_shell;
113 } else {
114 if ((shell = getenv("SHELL")) == NULL) shell = from_shell;
115 }
116 if ((p= strrchr(shell, '/')) == 0) p= shell; else p++;
117 sh0[0]= '-';
118 strcpy(loginshell ? sh0+1 : sh0, p);
119 argv[0]= sh0;
120
121 if (smallenv) {
122 envp = envv;
123 *envp++ = "PATH=:/bin:/usr/bin",
124 strcpy(USER, "USER=");
125 strcpy(USER + 5, name);
126 *envp++ = USER;
127 strcpy(LOGNAME, "LOGNAME=");
128 strcpy(LOGNAME + 8, name);
129 *envp++ = LOGNAME;
130 strcpy(SHELL, "SHELL=");
131 strcpy(SHELL + 6, shell);
132 *envp++ = SHELL;
133 strcpy(HOME, "HOME=");
134 strcpy(HOME + 5, pwd->pw_dir);
135 *envp++ = HOME;
136 if ((p = getenv("TERM")) != NULL) {
137 *envp++ = p - 5;
138 }
139 if ((p = getenv("TERMCAP")) != NULL) {
140 *envp++ = p - 8;
141 }
142 if ((p = getenv("TZ")) != NULL) {
143 *envp++ = p - 3;
144 }
145 *envp = NULL;
146 (void) chdir(pwd->pw_dir);
147 execve(shell, argv, envv);
148 perror(shell);
149 } else {
150 execv(shell, argv);
151 perror(shell);
152 }
153 fprintf(stderr, "No shell\n");
154 return(3);
155}
Note: See TracBrowser for help on using the repository browser.