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
42static int str_check(char *s, char *p)
43{
44 if (strnstr(s, p) || strnstr(p, s)) return 1;
45 return 0;
46}
47
48
49static void strength_check(char *newp, char *oldp, char *user)
50{
51 char *msg = NULL;
52
53 if (strlen(newp) < 6) {
54 msg = "too short";
55 xprintf("BAD PASSWORD: %s\n",msg);
56 }
57 if (!newp[0]) return;
58
59 if (str_check(newp, user)) {
60 msg = "user based password";
61 xprintf("BAD PASSWORD: %s\n",msg);
62 }
63
64 if (oldp[0] && str_check(newp, oldp)) {
65 msg = "based on old passwd";
66 xprintf("BAD PASSWORD: %s\n",msg);
67 }
68}
69
70static int verify_passwd(char * pwd)
71{
72 char * pass;
73
74 if (!pwd) return 1;
75 if (pwd[0] == '!' || pwd[0] == '*') return 1;
76
77 pass = crypt(toybuf, pwd);
78 if (pass && !strcmp(pass, pwd)) return 0;
79
80 return 1;
81}
82
83static char *new_password(char *oldp, char *user)
84{
85 char *newp = NULL;
86
87 if (read_password(toybuf, sizeof(toybuf), "New password:"))
88 return NULL;
89
90 newp = xstrdup(toybuf);
91 if (CFG_PASSWD_SAD) strength_check(newp, oldp, user);
92 if (read_password(toybuf, sizeof(toybuf), "Retype password:")) {
93 free(newp);
94 return NULL;
95 }
96
97 if (!strcmp(newp, toybuf)) return newp;
98 else error_msg("Passwords do not match.\n");
99
100 free(newp);
101 return NULL;
102}
103
104void passwd_main(void)
105{
106 uid_t myuid;
107 struct passwd *pw;
108 struct spwd *sp;
109 char *name = NULL, *pass = NULL, *encrypted = NULL, *newp = NULL,
110 *orig = (char *)"", salt[MAX_SALT_LEN];
111 int ret = -1;
112
113 myuid = getuid();
114 if (myuid && (toys.optflags & (FLAG_l | FLAG_u | FLAG_d)))
115 error_exit("Not root");
116
117 pw = xgetpwuid(myuid);
118
119 if (*toys.optargs) name = toys.optargs[0];
120 else name = xstrdup(pw->pw_name);
121
122 pw = xgetpwnam(name);
123
124 if (myuid && (myuid != pw->pw_uid)) error_exit("Not root");
125
126 pass = pw->pw_passwd;
127 if (pw->pw_passwd[0] == 'x') {
128
129 sp = getspnam(name);
130 if (sp) pass = sp->sp_pwdp;
131 }
132
133
134 if (!(toys.optflags & (FLAG_l | FLAG_u | FLAG_d))) {
135
136 if (!(toys.optflags & FLAG_a)) TT.algo = "des";
137 if (get_salt(salt, TT.algo) == -1)
138 error_exit("Error: Unkown encryption algorithm\n");
139
140 printf("Changing password for %s\n",name);
141 if (myuid && pass[0] == '!')
142 error_exit("Can't change, password is locked for %s",name);
143 if (myuid) {
144
145
146 if (read_password(toybuf, sizeof(toybuf), "Origial password:")) {
147 if (!toys.optargs[0]) free(name);
148 return;
149 }
150 orig = toybuf;
151 if (verify_passwd(pass)) error_exit("Authentication failed\n");
152 }
153
154 orig = xstrdup(orig);
155
156
157 newp = new_password(orig, name);
158 if (!newp) {
159 free(orig);
160 if (!toys.optargs[0]) free(name);
161 return;
162 }
163
164 encrypted = crypt(newp, salt);
165 free(newp);
166 free(orig);
167 } else if (toys.optflags & FLAG_l) {
168 if (pass[0] == '!') error_exit("password is already locked for %s",name);
169 printf("Locking password for %s\n",name);
170 encrypted = xmprintf("!%s",pass);
171 } else if (toys.optflags & FLAG_u) {
172 if (pass[0] != '!') error_exit("password is already unlocked for %s",name);
173
174 printf("Unlocking password for %s\n",name);
175 encrypted = xstrdup(&pass[1]);
176 } else if (toys.optflags & FLAG_d) {
177 printf("Deleting password for %s\n",name);
178 encrypted = xstrdup("");
179 }
180
181
182 if (pw->pw_passwd[0] == 'x')
183 ret = update_password("/etc/shadow", name, encrypted);
184 else ret = update_password("/etc/passwd", name, encrypted);
185
186 if ((toys.optflags & (FLAG_l | FLAG_u | FLAG_d))) free(encrypted);
187
188 if (!toys.optargs[0]) free(name);
189 if (!ret) error_msg("Success");
190 else error_msg("Failure");
191}
192