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
;
34 gid_t groups
[NGROUPS_MAX
];
40 if (argc
> 1 && (strcmp(argv
[1], "-") == 0 || strcmp(argv
[1], "-e") == 0)) {
42 loginshell
= 1; /* 'su -' reads .profile */
46 smallenv
= 1; /* Use small environment. */
49 if (argv
[1][0] == '-') {
51 "Usage: su [-[e]] [user [shell-arguments ...]]\n");
61 if ((pwd
= getpwuid(getuid())) == 0) {
62 fprintf(stderr
, "You do not exist\n");
65 strncpy(from_user
, pwd
->pw_name
, 8);
67 strncpy(from_shell
, pwd
->pw_shell
[0] == '\0' ? "/bin/sh" : pwd
->pw_shell
,
68 sizeof(from_shell
)-1);
69 from_shell
[sizeof(from_shell
)-1]= 0;
71 if ((pwd
= getpwnam(name
)) == 0) {
72 fprintf(stderr
, "Unknown id: %s\n", name
);
76 if (getgid() == 0) super
= 1;
77 ngroups
= getgroups(NGROUPS_MAX
, groups
);
78 for (g
= 0; g
< ngroups
; g
++) if (groups
[g
] == 0) super
= 1;
80 if (!super
&& strcmp(pwd
->pw_passwd
, crypt("", pwd
->pw_passwd
)) != 0) {
82 openlog("su", 0, LOG_AUTH
);
84 password
= getpass("Password:");
86 || strcmp(pwd
->pw_passwd
, crypt(password
, pwd
->pw_passwd
)) != 0) {
87 if (password
!= 0 && *password
!= 0) {
89 syslog(LOG_WARNING
, "su %s failed for %s",
93 fprintf(stderr
, "Sorry\n");
97 syslog(LOG_NOTICE
, "su %s succeeded for %s", name
, from_user
);
102 initgroups(pwd
->pw_name
, pwd
->pw_gid
);
106 shell
= pwd
->pw_shell
[0] == '\0' ? "/bin/sh" : pwd
->pw_shell
;
108 if ((shell
= getenv("SHELL")) == NULL
) shell
= from_shell
;
110 if ((p
= strrchr(shell
, '/')) == 0) p
= shell
; else p
++;
112 strcpy(loginshell
? sh0
+1 : sh0
, p
);
117 *envp
++ = "PATH=:/bin:/usr/bin",
118 strcpy(USER
, "USER=");
119 strcpy(USER
+ 5, name
);
121 strcpy(LOGNAME
, "LOGNAME=");
122 strcpy(LOGNAME
+ 8, name
);
124 strcpy(SHELL
, "SHELL=");
125 strcpy(SHELL
+ 6, shell
);
127 strcpy(HOME
, "HOME=");
128 strcpy(HOME
+ 5, pwd
->pw_dir
);
130 if ((p
= getenv("TERM")) != NULL
) {
133 if ((p
= getenv("TERMCAP")) != NULL
) {
136 if ((p
= getenv("TZ")) != NULL
) {
140 (void) chdir(pwd
->pw_dir
);
141 execve(shell
, argv
, envv
);
147 fprintf(stderr
, "No shell\n");