1 /* su - become super-user Author: Patrick van Kleef */
14 #include <sys/syslog.h>
16 #include <minix/minlib.h>
18 _PROTOTYPE(int main
, (int argc
, char **argv
));
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
;
35 gid_t groups
[NGROUPS_MAX
];
42 if (argc
> 1 && (strcmp(argv
[1], "-") == 0 || strcmp(argv
[1], "-e") == 0)) {
44 loginshell
= 1; /* 'su -' reads .profile */
48 smallenv
= 1; /* Use small environment. */
51 if (argv
[1][0] == '-') {
53 "Usage: su [-[e]] [user [shell-arguments ...]]\n");
63 if ((pwd
= getpwuid(getuid())) == 0) {
64 fprintf(stderr
, "You do not exist\n");
67 strncpy(from_user
, pwd
->pw_name
, 8);
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;
73 if ((pwd
= getpwnam(name
)) == 0) {
74 fprintf(stderr
, "Unknown id: %s\n", name
);
78 if (getgid() == 0) super
= 1;
80 ngroups
= getgroups(NGROUPS_MAX
, groups
);
81 for (g
= 0; g
< ngroups
; g
++) if (groups
[g
] == 0) super
= 1;
84 if (!super
&& strcmp(pwd
->pw_passwd
, crypt("", pwd
->pw_passwd
)) != 0) {
86 openlog("su", 0, LOG_AUTH
);
88 password
= getpass("Password:");
90 || strcmp(pwd
->pw_passwd
, crypt(password
, pwd
->pw_passwd
)) != 0) {
91 if (password
!= 0 && *password
!= 0) {
93 syslog(LOG_WARNING
, "su %s failed for %s",
97 fprintf(stderr
, "Sorry\n");
101 syslog(LOG_NOTICE
, "su %s succeeded for %s", name
, from_user
);
107 initgroups(pwd
->pw_name
, pwd
->pw_gid
);
112 shell
= pwd
->pw_shell
[0] == '\0' ? "/bin/sh" : pwd
->pw_shell
;
114 if ((shell
= getenv("SHELL")) == NULL
) shell
= from_shell
;
116 if ((p
= strrchr(shell
, '/')) == 0) p
= shell
; else p
++;
118 strcpy(loginshell
? sh0
+1 : sh0
, p
);
123 *envp
++ = "PATH=:/bin:/usr/bin",
124 strcpy(USER
, "USER=");
125 strcpy(USER
+ 5, name
);
127 strcpy(LOGNAME
, "LOGNAME=");
128 strcpy(LOGNAME
+ 8, name
);
130 strcpy(SHELL
, "SHELL=");
131 strcpy(SHELL
+ 6, shell
);
133 strcpy(HOME
, "HOME=");
134 strcpy(HOME
+ 5, pwd
->pw_dir
);
136 if ((p
= getenv("TERM")) != NULL
) {
139 if ((p
= getenv("TERMCAP")) != NULL
) {
142 if ((p
= getenv("TZ")) != NULL
) {
146 (void) chdir(pwd
->pw_dir
);
147 execve(shell
, argv
, envv
);
153 fprintf(stderr
, "No shell\n");