5 /* This implementation support Openwall-style TCB passwords in place of
6 * traditional shadow, if the appropriate directories and files exist.
7 * Thus, it is careful to avoid following symlinks or blocking on fifos
8 * which a malicious user might create in place of his or her TCB shadow
9 * file. It also avoids any allocation to prevent memory-exhaustion
10 * attacks via huge TCB shadow files. */
12 int getspnam_r(const char *name, struct spwd *sp, char *buf, size_t size, struct spwd **res)
14 char path[20+NAME_MAX];
18 size_t k, l = strlen(name);
24 /* Disallow potentially-malicious user names */
25 if (*name=='.' || strchr(name, '/') || !l)
28 /* Buffer size must at least be able to hold name, plus some.. */
29 if (size < l+100) return ERANGE;
31 /* Protect against truncation */
32 if (snprintf(path, sizeof path, "/etc/tcb/%s/shadow", name) >= sizeof path)
35 fd = open(path, O_RDONLY|O_NOFOLLOW|O_NONBLOCK);
43 f = fopen("/etc/shadow", "rb");
47 while (fgets(buf, size, f) && (k=strlen(buf))>0) {
48 if (skip || strncmp(name, buf, l)) {
49 skip = buf[k-1] != '\n';
52 if (buf[k-1] != '\n') {
60 if (!(s = strchr(s, ':'))) continue;
62 *s++ = 0; sp->sp_pwdp = s;
63 if (!(s = strchr(s, ':'))) continue;
65 *s++ = 0; sp->sp_lstchg = atol(s);
66 if (!(s = strchr(s, ':'))) continue;
68 *s++ = 0; sp->sp_min = atol(s);
69 if (!(s = strchr(s, ':'))) continue;
71 *s++ = 0; sp->sp_max = atol(s);
72 if (!(s = strchr(s, ':'))) continue;
74 *s++ = 0; sp->sp_warn = atol(s);
75 if (!(s = strchr(s, ':'))) continue;
77 *s++ = 0; sp->sp_inact = atol(s);
78 if (!(s = strchr(s, ':'))) continue;
80 *s++ = 0; sp->sp_expire = atol(s);
81 if (!(s = strchr(s, ':'))) continue;
83 *s++ = 0; sp->sp_flag = atol(s);