1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34#define FOR_passwd
35#include "toys.h"
36
37GLOBALS(
38 char *a;
39)
40
41
42static void weak_check(char *new, char *old, char *user)
43{
44 char *msg = 0;
45
46 if (strlen(new) < 6) msg = "too short";
47 if (*new) {
48 if (strcasestr(new, user) || strcasestr(user, new)) msg = "user";
49 if (*old && (strcasestr(new, old) || strcasestr(old, new))) msg = "old";
50 }
51 if (msg) xprintf("BAD PASSWORD: %s\n",msg);
52}
53
54void passwd_main(void)
55{
56 uid_t myuid;
57 struct passwd *pw = 0;
58 struct spwd *sp;
59 char *pass, *name, *encrypted = 0, salt[MAX_SALT_LEN];
60
61
62 if (!(myuid = getuid()) || !(toys.optflags&(FLAG_l|FLAG_u|FLAG_d))) {
63 if (*toys.optargs) pw = xgetpwnam(*toys.optargs);
64 else pw = xgetpwuid(myuid);
65 }
66 if (!pw || (myuid && (myuid != pw->pw_uid))) error_exit("Not root");
67
68
69
70 name = pw->pw_name;
71 if (*(pass = pw->pw_passwd)=='x' && (sp = getspnam(name))) pass = sp->sp_pwdp;
72
73 if (FLAG(l)) {
74 if (*pass=='!') error_exit("already locked");
75 printf("Locking '%s'\n", name);
76 encrypted = xmprintf("!%s", pass);
77 } else if (FLAG(u)) {
78 if (*pass!='!') error_exit("already unlocked");
79 printf("Unlocking '%s'\n", name);
80 encrypted = pass+1;
81 } else if (FLAG(d)) {
82 printf("Deleting password for '%s'\n", name);
83 *(encrypted = toybuf) = 0;
84 } else {
85 if (!TT.a) TT.a = "des";
86 if (get_salt(salt, TT.a)<0) error_exit("bad -a '%s'", TT.a);
87
88 printf("Changing password for %s\n", name);
89 if (myuid) {
90 if (*pass=='!') error_exit("'%s' locked", name);
91
92 if (read_password(toybuf+2048, 2048, "Old password:")) return;
93 pass = crypt(toybuf+2048, pw->pw_passwd);
94 if (!pass || strcmp(pass, pw->pw_passwd)) error_exit("No");
95 }
96
97 if (read_password(toybuf, 2048, "New password:")) return;
98
99 if (CFG_PASSWD_SAD) weak_check(toybuf, toybuf+2048, name);
100 if (read_password(toybuf+2048, 2048, "Retype password:")) return;
101 if (strcmp(toybuf, toybuf+2048)) error_exit("Passwords do not match.");
102
103 encrypted = crypt(toybuf, salt);
104 }
105
106
107 if (update_password(*pw->pw_passwd=='x' ? "/etc/shadow" : "/etc/passwd",
108 name, encrypted, 1)) error_msg("Failure");
109 else fprintf(stderr, "Success\n");
110
111 memset(toybuf, 0, sizeof(toybuf));
112 memset(encrypted, 0, strlen(encrypted));
113 free(encrypted);
114}
115