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