1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#define FOR_chsh
24#include "toys.h"
25
26GLOBALS(
27 char *s, *R;
28)
29
30void chsh_main()
31{
32 FILE *file;
33 char *user, *line, *shell, *encrypted;
34 struct passwd *passwd_info;
35 struct spwd *shadow_info;
36
37
38
39 if ((user = *toys.optargs)) {
40 if (strcmp((passwd_info = xgetpwnam(user))->pw_name, user))
41 if (geteuid()) errno = EPERM, error_exit(0);
42 } else user = (passwd_info = xgetpwuid(getuid()))->pw_name;
43
44
45 if (mlock(toybuf, sizeof(toybuf))) perror_exit("mlock");
46 if (!(shadow_info = getspnam(passwd_info->pw_name))) perror_exit("getspnam");
47 if (read_password(toybuf, sizeof(toybuf), "Password: ")) *toybuf = 0;
48 if (!(encrypted = crypt(toybuf, shadow_info->sp_pwdp))) perror_exit("crypt");
49 memset(toybuf, 0, sizeof(toybuf));
50 munlock(toybuf, sizeof(toybuf));
51 if (strcmp(encrypted, shadow_info->sp_pwdp)) perror_exit("Bad password");
52
53
54 file = xfopen("/etc/shells", "r");
55 if (toys.optflags) shell = TT.s;
56 else {
57 xprintf("Login shell for %s [%s]:", user, passwd_info->pw_shell);
58 if (!(shell = xgetline(stdin))) xexit();
59 if (!*shell) xexit();
60 }
61
62
63 if (*shell) while ((line = xgetline(file)) && strcmp(shell, line)) free(line);
64 else do line = xgetline(file); while (line && *line != '/');
65 if (!line) error_exit("Shell not found in '/etc/shells'");
66
67
68 if (!update_password("/etc/passwd", user, line,6)) perror_exit("/etc/passwd");
69}
70