clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name pwd_mkdb.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/pwd_mkdb/obj -resource-dir /usr/local/lib/clang/13.0.0 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/pwd_mkdb/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.sbin/pwd_mkdb/pwd_mkdb.c
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 | #include <sys/types.h> |
35 | #include <sys/stat.h> |
36 | |
37 | #include <db.h> |
38 | #include <err.h> |
39 | #include <errno.h> |
40 | #include <fcntl.h> |
41 | #include <grp.h> |
42 | #include <limits.h> |
43 | #include <pwd.h> |
44 | #include <signal.h> |
45 | #include <stdarg.h> |
46 | #include <stdio.h> |
47 | #include <stdlib.h> |
48 | #include <string.h> |
49 | #include <unistd.h> |
50 | #include <limits.h> |
51 | #include <util.h> |
52 | |
53 | #define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) |
54 | #define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) |
55 | #define _MAXBSIZE (64 * 1024) |
56 | |
57 | #define INSECURE 1 |
58 | #define SECURE 2 |
59 | #define PERM_INSECURE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) |
60 | #define PERM_SECURE (S_IRUSR|S_IWUSR) |
61 | |
62 | #define FILE_SECURE 0x01 |
63 | #define FILE_INSECURE 0x02 |
64 | #define FILE_ORIG 0x04 |
65 | |
66 | #define SHADOW_GROUP "_shadow" |
67 | |
68 | HASHINFO openinfo = { |
69 | 4096, |
70 | 32, |
71 | 256, |
72 | 2048 * 1024, |
73 | NULL, |
74 | 0 |
75 | }; |
76 | |
77 | static char *pname; |
78 | static char *basedir; |
79 | static int clean; |
80 | static int hasyp; |
81 | |
82 | void cleanup(void); |
83 | __dead void fatal(const char *, ...) |
84 | __attribute__((__format__ (printf, 1, 2))); |
85 | __dead void fatalc(int, const char *, ...) |
86 | __attribute__((__format__ (printf, 2, 3))); |
87 | __dead void fatalx(const char *, ...) |
88 | __attribute__((__format__ (printf, 1, 2))); |
89 | int write_old_entry(FILE *, const struct passwd *); |
90 | |
91 | void cp(char *, char *, mode_t); |
92 | void mv(char *, char *); |
93 | int scan(FILE *, struct passwd *, int *); |
94 | void usage(void); |
95 | char *changedir(char *path, char *dir); |
96 | void db_store(FILE *, FILE *, DB *, DB *,struct passwd *, int, char *, uid_t); |
97 | |
98 | int |
99 | main(int argc, char **argv) |
100 | { |
101 | DB *dp, *edp; |
102 | DBT data, key; |
103 | FILE *fp, *oldfp = NULL; |
104 | struct stat st; |
105 | struct passwd pwd; |
106 | struct group *grp; |
107 | sigset_t set; |
108 | uid_t olduid; |
| 1 | 'olduid' declared without an initial value | |
|
109 | gid_t shadow; |
110 | int ch, tfd, makeold, secureonly, flags, checkonly; |
111 | char *username, buf[MAXIMUM(PATH_MAX, LINE_MAX * 2)]; |
112 | |
113 | flags = checkonly = makeold = secureonly = 0; |
114 | username = NULL; |
115 | while ((ch = getopt(argc, argv, "cd:psu:v")) != -1) |
| 2 | | Assuming the condition is false | |
|
| 3 | | Loop condition is false. Execution continues on line 142 | |
|
116 | switch (ch) { |
117 | case 'c': |
118 | checkonly = 1; |
119 | break; |
120 | case 'd': |
121 | basedir = optarg; |
122 | if (strlen(basedir) > PATH_MAX - 40) |
123 | errx(1, "basedir too long"); |
124 | break; |
125 | case 'p': |
126 | makeold = 1; |
127 | break; |
128 | case 's': |
129 | secureonly = 1; |
130 | break; |
131 | case 'u': |
132 | username = optarg; |
133 | if (strlen(username) > _PW_NAME_LEN) |
134 | errx(1, "username too long"); |
135 | break; |
136 | case 'v': |
137 | break; |
138 | case '?': |
139 | default: |
140 | usage(); |
141 | } |
142 | argc -= optind; |
143 | argv += optind; |
144 | |
145 | if (argc != 1 || (makeold && secureonly) || |
| 4 | | Assuming 'argc' is equal to 1 | |
|
146 | (username && (*username == '+' || *username == '-'))) |
147 | usage(); |
148 | |
149 | if ((grp = getgrnam(SHADOW_GROUP)) == NULL) |
| 5 | | Assuming the condition is false | |
|
| |
150 | errx(1, "cannot find `%s' in the group database, aborting", |
151 | SHADOW_GROUP); |
152 | shadow = grp->gr_gid; |
153 | |
154 | |
155 | |
156 | |
157 | |
158 | sigemptyset(&set); |
159 | sigaddset(&set, SIGTSTP); |
160 | sigaddset(&set, SIGHUP); |
161 | sigaddset(&set, SIGINT); |
162 | sigaddset(&set, SIGQUIT); |
163 | sigaddset(&set, SIGTERM); |
164 | (void)sigprocmask(SIG_BLOCK, &set, (sigset_t *)NULL); |
165 | |
166 | |
167 | (void)umask(0); |
168 | |
169 | if (**argv != '/' && basedir == NULL) |
| 7 | | Assuming the condition is false | |
|
170 | errx(1, "%s must be specified as an absolute path", *argv); |
171 | |
172 | if ((pname = strdup(changedir(*argv, basedir))) == NULL) |
| 8 | | Assuming the condition is false | |
|
| |
173 | err(1, NULL); |
174 | |
175 | if (!(fp = fopen(pname, "r"))) |
| 10 | | Assuming 'fp' is non-null | |
|
| |
176 | fatal("%s", pname); |
177 | |
178 | |
179 | if (checkonly) { |
| |
180 | u_int cnt; |
181 | |
182 | for (cnt = 1; scan(fp, &pwd, &flags); ++cnt) |
183 | ; |
184 | exit(0); |
185 | } |
186 | |
187 | if (fstat(fileno(fp), &st) == -1) |
| 13 | | Assuming '__isthreaded' is 0 | |
|
| |
| 15 | | Assuming the condition is false | |
|
| |
188 | fatal("%s", pname); |
189 | |
190 | |
191 | if (st.st_size > (off_t)100*1024) |
| 17 | | Assuming the condition is false | |
|
| |
192 | openinfo.cachesize = MINIMUM(st.st_size * 20, (off_t)12*1024*1024); |
193 | |
194 | if (st.st_size / 128 * 3 > openinfo.nelem) |
| 19 | | Assuming the condition is false | |
|
| |
195 | openinfo.nelem = st.st_size / 128 * 3; |
196 | |
197 | |
198 | if (username) { |
| |
199 | dp = dbopen(_PATH_MP_DB, O_RDONLY, 0, DB_HASH, NULL); |
200 | if (dp == NULL) |
201 | fatal(_PATH_MP_DB); |
202 | buf[0] = _PW_KEYBYNAME; |
203 | strlcpy(buf + 1, username, sizeof(buf) - 1); |
204 | key.data = (u_char *)buf; |
205 | key.size = strlen(buf + 1) + 1; |
206 | if ((dp->get)(dp, &key, &data, 0) == 0) { |
207 | char *p = (char *)data.data; |
208 | |
209 | while (*p++ != '\0') |
210 | ; |
211 | while (*p++ != '\0') |
212 | ; |
213 | memcpy(&olduid, p, sizeof(olduid)); |
214 | } else |
215 | olduid = -1; |
216 | (dp->close)(dp); |
217 | } |
218 | |
219 | |
220 | (void)snprintf(buf, sizeof(buf), "%s.tmp", |
221 | changedir(_PATH_SMP_DB, basedir)); |
222 | if (username) { |
| |
223 | cp(changedir(_PATH_SMP_DB, basedir), buf, PERM_SECURE); |
224 | edp = dbopen(buf, |
225 | O_RDWR, PERM_SECURE, DB_HASH, &openinfo); |
226 | } else { |
227 | edp = dbopen(buf, |
228 | O_RDWR|O_CREAT|O_EXCL, PERM_SECURE, DB_HASH, &openinfo); |
229 | } |
230 | if (!edp) |
| 23 | | Assuming 'edp' is non-null | |
|
| |
231 | fatal("%s", buf); |
232 | if (fchown(edp->fd(edp), -1, shadow) != 0) |
| 25 | | Assuming the condition is true | |
|
| |
233 | warn("%s: unable to set group to %s", _PATH_SMP_DB, |
234 | SHADOW_GROUP); |
235 | else if (fchmod(edp->fd(edp), PERM_SECURE|S_IRGRP) != 0) |
236 | warn("%s: unable to make group readable", _PATH_SMP_DB); |
237 | clean |= FILE_SECURE; |
238 | |
239 | if (pledge("stdio rpath wpath cpath getpw fattr flock", NULL) == -1) |
| 27 | | Assuming the condition is false | |
|
| |
240 | err(1, "pledge"); |
241 | |
242 | |
243 | if (!secureonly) { |
| |
244 | (void)snprintf(buf, sizeof(buf), "%s.tmp", |
245 | changedir(_PATH_MP_DB, basedir)); |
246 | if (username) { |
| |
247 | cp(changedir(_PATH_MP_DB, basedir), buf, PERM_INSECURE); |
248 | dp = dbopen(buf, O_RDWR, PERM_INSECURE, DB_HASH, |
249 | &openinfo); |
250 | } else { |
251 | dp = dbopen(buf, O_RDWR|O_CREAT|O_EXCL, PERM_INSECURE, |
252 | DB_HASH, &openinfo); |
253 | } |
254 | if (dp == NULL) |
| 31 | | Assuming 'dp' is not equal to NULL | |
|
| |
255 | fatal("%s", buf); |
256 | clean |= FILE_INSECURE; |
257 | } else |
258 | dp = NULL; |
259 | |
260 | |
261 | |
262 | |
263 | |
264 | |
265 | |
266 | |
267 | if (makeold) { |
| |
268 | (void)snprintf(buf, sizeof(buf), "%s.orig", pname); |
269 | if ((tfd = open(buf, |
270 | O_WRONLY|O_CREAT|O_EXCL, PERM_INSECURE)) == -1) |
271 | fatal("%s", buf); |
272 | if ((oldfp = fdopen(tfd, "w")) == NULL) |
273 | fatal("%s", buf); |
274 | clean |= FILE_ORIG; |
275 | } |
276 | |
277 | |
278 | |
279 | |
280 | |
281 | |
282 | |
283 | |
284 | |
285 | |
286 | |
287 | |
288 | |
289 | |
290 | |
291 | |
292 | |
293 | |
294 | |
295 | |
296 | |
297 | |
298 | |
299 | db_store(fp, oldfp, edp, dp, &pwd, _PW_KEYBYNAME, username, olduid); |
| 34 | | 8th function call argument is an uninitialized value |
|
300 | db_store(fp, oldfp, edp, dp, &pwd, _PW_KEYBYUID, username, olduid); |
301 | db_store(fp, oldfp, edp, dp, &pwd, _PW_KEYBYNUM, username, olduid); |
302 | |
303 | |
304 | if (hasyp && !username) { |
305 | key.data = (u_char *)_PW_YPTOKEN; |
306 | key.size = strlen(_PW_YPTOKEN); |
307 | data.data = (u_char *)NULL; |
308 | data.size = 0; |
309 | |
310 | if ((edp->put)(edp, &key, &data, R_NOOVERWRITE) == -1) |
311 | fatal("put"); |
312 | |
313 | if (dp && (dp->put)(dp, &key, &data, R_NOOVERWRITE) == -1) |
314 | fatal("put"); |
315 | } |
316 | |
317 | if ((edp->close)(edp)) |
318 | fatal("close edp"); |
319 | if (dp && (dp->close)(dp)) |
320 | fatal("close dp"); |
321 | if (makeold) { |
322 | if (fclose(oldfp) == EOF) |
323 | fatal("close old"); |
324 | } |
325 | |
326 | |
327 | (void)fchmod(fileno(fp), S_IRUSR|S_IWUSR); |
328 | if (fclose(fp) != 0) |
329 | fatal("fclose"); |
330 | |
331 | |
332 | if (!secureonly) { |
333 | (void)snprintf(buf, sizeof(buf), "%s.tmp", |
334 | changedir(_PATH_MP_DB, basedir)); |
335 | mv(buf, changedir(_PATH_MP_DB, basedir)); |
336 | } |
337 | (void)snprintf(buf, sizeof(buf), "%s.tmp", |
338 | changedir(_PATH_SMP_DB, basedir)); |
339 | mv(buf, changedir(_PATH_SMP_DB, basedir)); |
340 | if (makeold) { |
341 | (void)snprintf(buf, sizeof(buf), "%s.orig", pname); |
342 | mv(buf, changedir(_PATH_PASSWD, basedir)); |
343 | } |
344 | |
345 | |
346 | |
347 | |
348 | |
349 | |
350 | |
351 | mv(pname, changedir(_PATH_MASTERPASSWD, basedir)); |
352 | exit(0); |
353 | } |
354 | |
355 | int |
356 | scan(FILE *fp, struct passwd *pw, int *flags) |
357 | { |
358 | static int lcnt; |
359 | static char line[LINE_MAX]; |
360 | char *p; |
361 | |
362 | if (fgets(line, sizeof(line), fp) == NULL) |
363 | return (0); |
364 | ++lcnt; |
365 | |
366 | |
367 | |
368 | |
369 | |
370 | p = line; |
371 | if (*p != '\0' && *(p += strlen(line) - 1) != '\n') { |
372 | warnx("line too long"); |
373 | goto fmt; |
374 | } |
375 | *p = '\0'; |
376 | *flags = 0; |
377 | if (!pw_scan(line, pw, flags)) { |
378 | warnx("at line #%d", lcnt); |
379 | fmt: fatalc(EFTYPE, "%s", pname); |
380 | } |
381 | |
382 | return (1); |
383 | } |
384 | |
385 | void |
386 | cp(char *from, char *to, mode_t mode) |
387 | { |
388 | static char buf[_MAXBSIZE]; |
389 | int from_fd, rcount, to_fd, wcount; |
390 | |
391 | if ((from_fd = open(from, O_RDONLY)) == -1) |
392 | fatal("%s", from); |
393 | if ((to_fd = open(to, O_WRONLY|O_CREAT|O_EXCL, mode)) == -1) |
394 | fatal("%s", to); |
395 | while ((rcount = read(from_fd, buf, sizeof buf)) > 0) { |
396 | wcount = write(to_fd, buf, rcount); |
397 | if (rcount != wcount || wcount == -1) |
398 | fatal("%s to %s", from, to); |
399 | } |
400 | if (rcount == -1) |
401 | fatal("%s to %s", from, to); |
402 | close(to_fd); |
403 | close(from_fd); |
404 | } |
405 | |
406 | void |
407 | mv(char *from, char *to) |
408 | { |
409 | if (rename(from, to)) |
410 | fatal("%s to %s", from, to); |
411 | } |
412 | |
413 | void |
414 | fatal(const char *fmt, ...) |
415 | { |
416 | va_list ap; |
417 | |
418 | va_start(ap, fmt); |
419 | vwarn(fmt, ap); |
420 | va_end(ap); |
421 | cleanup(); |
422 | exit(EXIT_FAILURE); |
423 | } |
424 | |
425 | void |
426 | fatalc(int code, const char *fmt, ...) |
427 | { |
428 | va_list ap; |
429 | |
430 | va_start(ap, fmt); |
431 | vwarnc(code, fmt, ap); |
432 | va_end(ap); |
433 | cleanup(); |
434 | exit(EXIT_FAILURE); |
435 | } |
436 | |
437 | void |
438 | fatalx(const char *fmt, ...) |
439 | { |
440 | va_list ap; |
441 | |
442 | va_start(ap, fmt); |
443 | vwarnx(fmt, ap); |
444 | va_end(ap); |
445 | cleanup(); |
446 | exit(EXIT_FAILURE); |
447 | } |
448 | |
449 | void |
450 | cleanup(void) |
451 | { |
452 | char buf[PATH_MAX]; |
453 | |
454 | if (clean & FILE_ORIG) { |
455 | (void)snprintf(buf, sizeof(buf), "%s.orig", pname); |
456 | (void)unlink(buf); |
457 | } |
458 | if (clean & FILE_SECURE) { |
459 | (void)snprintf(buf, sizeof(buf), "%s.tmp", |
460 | changedir(_PATH_SMP_DB, basedir)); |
461 | (void)unlink(buf); |
462 | } |
463 | if (clean & FILE_INSECURE) { |
464 | (void)snprintf(buf, sizeof(buf), "%s.tmp", |
465 | changedir(_PATH_MP_DB, basedir)); |
466 | (void)unlink(buf); |
467 | } |
468 | } |
469 | |
470 | void |
471 | usage(void) |
472 | { |
473 | (void)fprintf(stderr, |
474 | "usage: pwd_mkdb [-c] [-p | -s] [-d directory] [-u username] file\n"); |
475 | exit(EXIT_FAILURE); |
476 | } |
477 | |
478 | char * |
479 | changedir(char *path, char *dir) |
480 | { |
481 | static char fixed[PATH_MAX]; |
482 | char *p; |
483 | |
484 | if (!dir) |
485 | return (path); |
486 | |
487 | if ((p = strrchr(path, '/')) != NULL) |
488 | path = p + 1; |
489 | snprintf(fixed, sizeof(fixed), "%s/%s", dir, path); |
490 | return (fixed); |
491 | } |
492 | |
493 | int |
494 | write_old_entry(FILE *to, const struct passwd *pw) |
495 | { |
496 | char gidstr[16], uidstr[16]; |
497 | |
498 | if (to == NULL) |
499 | return (0); |
500 | |
501 | |
502 | if (pw->pw_gid == (gid_t)-1) |
503 | strlcpy(gidstr, "-1", sizeof(gidstr)); |
504 | else |
505 | snprintf(gidstr, sizeof(gidstr), "%u", (u_int)pw->pw_gid); |
506 | |
507 | if (pw->pw_uid == -1) |
508 | strlcpy(uidstr, "-1", sizeof(uidstr)); |
509 | else |
510 | snprintf(uidstr, sizeof(uidstr), "%u", (u_int)pw->pw_uid); |
511 | |
512 | return (fprintf(to, "%s:*:%s:%s:%s:%s:%s\n", pw->pw_name, uidstr, |
513 | gidstr, pw->pw_gecos, pw->pw_dir, pw->pw_shell)); |
514 | } |
515 | |
516 | void |
517 | db_store(FILE *fp, FILE *oldfp, DB *edp, DB *dp, struct passwd *pw, |
518 | int keytype, char *username, uid_t olduid) |
519 | { |
520 | char *p, *t, buf[LINE_MAX * 2], tbuf[_PW_BUF_LEN]; |
521 | int flags = 0, dbmode, found = 0; |
522 | static int firsttime = 1; |
523 | DBT data, key; |
524 | size_t len; |
525 | u_int cnt; |
526 | |
527 | |
528 | dbmode = username ? 0 : R_NOOVERWRITE; |
529 | |
530 | rewind(fp); |
531 | data.data = (u_char *)buf; |
532 | key.data = (u_char *)tbuf; |
533 | for (cnt = 1; scan(fp, pw, &flags); ++cnt) { |
534 | |
535 | if (firsttime) { |
536 | |
537 | if ((pw->pw_name[0] == '+') || (pw->pw_name[0] == '-')) |
538 | hasyp++; |
539 | |
540 | |
541 | if (pw->pw_name[0] == '+') { |
542 | if (!(flags & _PASSWORD_NOUID) && !pw->pw_uid) |
543 | warnx("line %d: superuser override in " |
544 | "YP inclusion", cnt); |
545 | if (!(flags & _PASSWORD_NOGID) && !pw->pw_gid) |
546 | warnx("line %d: wheel override in " |
547 | "YP inclusion", cnt); |
548 | } |
549 | |
550 | |
551 | if (write_old_entry(oldfp, pw) == -1) |
552 | fatal("write old"); |
553 | } |
554 | |
555 | |
556 | if (username) { |
557 | if (strcmp(username, pw->pw_name) != 0) |
558 | continue; |
559 | found = 1; |
560 | |
561 | if (olduid != -1 && olduid != pw->pw_uid) { |
562 | tbuf[0] = _PW_KEYBYUID; |
563 | memcpy(tbuf + 1, &olduid, sizeof(olduid)); |
564 | key.size = sizeof(olduid) + 1; |
565 | (edp->del)(edp, &key, 0); |
566 | if (dp) |
567 | (dp->del)(dp, &key, 0); |
568 | } |
569 | |
570 | } |
571 | |
572 | |
573 | tbuf[0] = keytype; |
574 | switch (keytype) { |
575 | case _PW_KEYBYNUM: |
576 | memmove(tbuf + 1, &cnt, sizeof(cnt)); |
577 | key.size = sizeof(cnt) + 1; |
578 | break; |
579 | |
580 | case _PW_KEYBYNAME: |
581 | len = strlen(pw->pw_name); |
582 | memmove(tbuf + 1, pw->pw_name, len); |
583 | key.size = len + 1; |
584 | break; |
585 | |
586 | case _PW_KEYBYUID: |
587 | memmove(tbuf + 1, &pw->pw_uid, sizeof(pw->pw_uid)); |
588 | key.size = sizeof(pw->pw_uid) + 1; |
589 | break; |
590 | } |
591 | |
592 | #define COMPACT(e) t = e; while ((*p++ = *t++)); |
593 | |
594 | p = buf; |
595 | COMPACT(pw->pw_name); |
596 | COMPACT(pw->pw_passwd); |
597 | memmove(p, &pw->pw_uid, sizeof(uid_t)); |
598 | p += sizeof(uid_t); |
599 | memmove(p, &pw->pw_gid, sizeof(gid_t)); |
600 | p += sizeof(gid_t); |
601 | memmove(p, &pw->pw_change, sizeof(time_t)); |
602 | p += sizeof(time_t); |
603 | COMPACT(pw->pw_class); |
604 | COMPACT(pw->pw_gecos); |
605 | COMPACT(pw->pw_dir); |
606 | COMPACT(pw->pw_shell); |
607 | memmove(p, &pw->pw_expire, sizeof(time_t)); |
608 | p += sizeof(time_t); |
609 | memmove(p, &flags, sizeof(int)); |
610 | p += sizeof(int); |
611 | data.size = p - buf; |
612 | |
613 | |
614 | if ((edp->put)(edp, &key, &data, dbmode) == -1) |
615 | fatal("put"); |
616 | |
617 | if (dp == NULL) |
618 | continue; |
619 | |
620 | |
621 | p = buf + strlen(pw->pw_name) + 1; |
622 | len = strlen(pw->pw_passwd); |
623 | explicit_bzero(p, len); |
624 | t = p + len + 1; |
625 | if (len != 0) |
626 | *p++ = '*'; |
627 | *p++ = '\0'; |
628 | memmove(p, t, data.size - (t - buf)); |
629 | data.size -= len - 1; |
630 | |
631 | |
632 | if ((dp->put)(dp, &key, &data, dbmode) == -1) |
633 | fatal("put"); |
634 | } |
635 | if (firsttime) { |
636 | firsttime = 0; |
637 | if (username && !found && olduid != -1) |
638 | fatalx("can't find user in master.passwd"); |
639 | } |
640 | } |