#if defined(LIBC_SCCS) && !defined(lint)
static const char rcsid[] = "$OpenBSD: passwd.c,v 1.42 2003/06/26 16:34:42 deraadt Exp $";
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <pwd.h>
#include <err.h>
#include <errno.h>
#include <paths.h>
#include <signal.h>
#include <limits.h>
#include "util.h"
int
pw_scan(char *bp, struct passwd *pw, int *flags)
{
u_long id;
int root;
char *p, *sh, *p2;
if (flags != (int *)NULL)
*flags = 0;
#ifdef __APPLE__
if (bp[0] == '#') {
pw->pw_name = NULL;
return(1);
}
#endif
if (!(p = strsep(&bp, ":")) || *p == '\0')
goto fmt;
pw->pw_name = p;
root = !strcmp(pw->pw_name, "root");
if (!(pw->pw_passwd = strsep(&bp, ":")))
goto fmt;
if (!(p = strsep(&bp, ":")))
goto fmt;
id = strtoul(p, &p2, 10);
if (root && id) {
warnx("root uid should be 0");
return (0);
}
if (*p2 != '\0') {
warnx("illegal uid field");
return (0);
}
#ifndef __APPLE__
if (id > UID_MAX) {
warnx("uid greater than %u", UID_MAX-1);
return (0);
}
#endif
pw->pw_uid = (uid_t)id;
if ((*p == '\0') && (flags != (int *)NULL))
*flags |= _PASSWORD_NOUID;
if (!(p = strsep(&bp, ":")))
goto fmt;
id = strtoul(p, &p2, 10);
if (*p2 != '\0') {
warnx("illegal gid field");
return (0);
}
#ifndef __APPLE__
if (id > UID_MAX) {
warnx("gid greater than %u", UID_MAX-1);
return (0);
}
#endif
pw->pw_gid = (gid_t)id;
if ((*p == '\0') && (flags != (int *)NULL))
*flags |= _PASSWORD_NOGID;
pw->pw_class = strsep(&bp, ":");
if (!(p = strsep(&bp, ":")))
goto fmt;
pw->pw_change = atol(p);
if ((*p == '\0') && (flags != (int *)NULL))
*flags |= _PASSWORD_NOCHG;
if (!(p = strsep(&bp, ":")))
goto fmt;
pw->pw_expire = atol(p);
if ((*p == '\0') && (flags != (int *)NULL))
*flags |= _PASSWORD_NOEXP;
pw->pw_gecos = strsep(&bp, ":");
pw->pw_dir = strsep(&bp, ":");
if (!(pw->pw_shell = strsep(&bp, ":")))
goto fmt;
p = pw->pw_shell;
if (root && *p) {
for (setusershell();;) {
if (!(sh = getusershell())) {
warnx("warning, unknown root shell");
break;
}
if (!strcmp(p, sh))
break;
}
endusershell();
}
if ((p = strsep(&bp, ":"))) {
fmt: warnx("corrupted entry");
return (0);
}
return (1);
}