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