136864Sbostic /*
2*66651Spendry * Copyright (c) 1988, 1993, 1994
361940Sbostic * The Regents of the University of California. All rights reserved.
436864Sbostic *
542722Sbostic * %sccs.include.redist.c%
636864Sbostic */
736864Sbostic
836864Sbostic #ifndef lint
9*66651Spendry static char sccsid[] = "@(#)field.c 8.4 (Berkeley) 04/02/94";
1036864Sbostic #endif /* not lint */
1136864Sbostic
1236864Sbostic #include <sys/param.h>
1366621Spendry
1466621Spendry #include <ctype.h>
1566621Spendry #include <err.h>
1666621Spendry #include <errno.h>
1766621Spendry #include <grp.h>
1837023Sbostic #include <pwd.h>
1966621Spendry #include <stdio.h>
2066621Spendry #include <stdlib.h>
2142055Sbostic #include <string.h>
2266621Spendry #include <unistd.h>
2366621Spendry
2437867Sbostic #include "chpass.h"
2537023Sbostic #include "pathnames.h"
2636864Sbostic
2736864Sbostic /* ARGSUSED */
2866621Spendry int
p_login(p,pw,ep)2936864Sbostic p_login(p, pw, ep)
3036864Sbostic char *p;
3136864Sbostic struct passwd *pw;
3246392Sbostic ENTRY *ep;
3336864Sbostic {
3436864Sbostic if (!*p) {
3566621Spendry warnx("empty login field");
3666621Spendry return (1);
3736864Sbostic }
3836870Sbostic if (*p == '-') {
3966621Spendry warnx("login names may not begin with a hyphen");
4066621Spendry return (1);
4136870Sbostic }
4236864Sbostic if (!(pw->pw_name = strdup(p))) {
4366621Spendry warnx("can't save entry");
4466621Spendry return (1);
4536864Sbostic }
4666621Spendry if (strchr(p, '.'))
4766621Spendry warnx("\'.\' is dangerous in a login name");
4837186Sbostic for (; *p; ++p)
4937186Sbostic if (isupper(*p)) {
5066621Spendry warnx("upper-case letters are dangerous in a login name");
5137186Sbostic break;
5237186Sbostic }
5366621Spendry return (0);
5436864Sbostic }
5536864Sbostic
5636864Sbostic /* ARGSUSED */
5766621Spendry int
p_passwd(p,pw,ep)5837135Sbostic p_passwd(p, pw, ep)
5937135Sbostic char *p;
6037135Sbostic struct passwd *pw;
6146392Sbostic ENTRY *ep;
6237135Sbostic {
6337135Sbostic if (!*p)
6437135Sbostic pw->pw_passwd = ""; /* "NOLOGIN"; */
6537135Sbostic else if (!(pw->pw_passwd = strdup(p))) {
6666621Spendry warnx("can't save password entry");
6766621Spendry return (1);
6837135Sbostic }
6937135Sbostic
7066621Spendry return (0);
7137135Sbostic }
7237135Sbostic
7337135Sbostic /* ARGSUSED */
7466621Spendry int
p_uid(p,pw,ep)7536864Sbostic p_uid(p, pw, ep)
7666621Spendry char *p;
7736864Sbostic struct passwd *pw;
7846392Sbostic ENTRY *ep;
7936864Sbostic {
8065364Spendry uid_t id;
8165364Spendry char *np;
8236864Sbostic
8336864Sbostic if (!*p) {
8466621Spendry warnx("empty uid field");
8566621Spendry return (1);
8636864Sbostic }
8736864Sbostic if (!isdigit(*p)) {
8866621Spendry warnx("illegal uid");
8966621Spendry return (1);
9036864Sbostic }
9165364Spendry errno = 0;
9265364Spendry id = strtoul(p, &np, 10);
9365364Spendry if (*np || (id == ULONG_MAX && errno == ERANGE)) {
9466621Spendry warnx("illegal uid");
9566621Spendry return (1);
9636864Sbostic }
9736864Sbostic pw->pw_uid = id;
9866621Spendry return (0);
9936864Sbostic }
10036864Sbostic
10136864Sbostic /* ARGSUSED */
10266621Spendry int
p_gid(p,pw,ep)10336864Sbostic p_gid(p, pw, ep)
10466621Spendry char *p;
10536864Sbostic struct passwd *pw;
10646392Sbostic ENTRY *ep;
10736864Sbostic {
10836864Sbostic struct group *gr;
10965364Spendry gid_t id;
11065364Spendry char *np;
11136864Sbostic
11236864Sbostic if (!*p) {
11366621Spendry warnx("empty gid field");
11466621Spendry return (1);
11536864Sbostic }
11636864Sbostic if (!isdigit(*p)) {
11736864Sbostic if (!(gr = getgrnam(p))) {
11866621Spendry warnx("unknown group %s", p);
11966621Spendry return (1);
12036864Sbostic }
12136864Sbostic pw->pw_gid = gr->gr_gid;
12266621Spendry return (0);
12336864Sbostic }
12465364Spendry errno = 0;
12565364Spendry id = strtoul(p, &np, 10);
12665364Spendry if (*np || (id == ULONG_MAX && errno == ERANGE)) {
12766621Spendry warnx("illegal gid");
12866621Spendry return (1);
12936864Sbostic }
13036864Sbostic pw->pw_gid = id;
13166621Spendry return (0);
13236864Sbostic }
13336864Sbostic
13436864Sbostic /* ARGSUSED */
13566621Spendry int
p_class(p,pw,ep)13636864Sbostic p_class(p, pw, ep)
13736864Sbostic char *p;
13836864Sbostic struct passwd *pw;
13946392Sbostic ENTRY *ep;
14036864Sbostic {
14137120Sbostic if (!*p)
14237120Sbostic pw->pw_class = "";
14337120Sbostic else if (!(pw->pw_class = strdup(p))) {
14466621Spendry warnx("can't save entry");
14566621Spendry return (1);
14636864Sbostic }
14737120Sbostic
14866621Spendry return (0);
14936864Sbostic }
15036864Sbostic
15136864Sbostic /* ARGSUSED */
15266621Spendry int
p_change(p,pw,ep)15336864Sbostic p_change(p, pw, ep)
15436864Sbostic char *p;
15536864Sbostic struct passwd *pw;
15646392Sbostic ENTRY *ep;
15736864Sbostic {
15836864Sbostic if (!atot(p, &pw->pw_change))
15966621Spendry return (0);
16066621Spendry warnx("illegal date for change field");
16166621Spendry return (1);
16236864Sbostic }
16336864Sbostic
16436864Sbostic /* ARGSUSED */
16566621Spendry int
p_expire(p,pw,ep)16636864Sbostic p_expire(p, pw, ep)
16736864Sbostic char *p;
16836864Sbostic struct passwd *pw;
16946392Sbostic ENTRY *ep;
17036864Sbostic {
17136864Sbostic if (!atot(p, &pw->pw_expire))
17266621Spendry return (0);
17366621Spendry warnx("illegal date for expire field");
17466621Spendry return (1);
17536864Sbostic }
17636864Sbostic
17736864Sbostic /* ARGSUSED */
17866621Spendry int
p_gecos(p,pw,ep)17937120Sbostic p_gecos(p, pw, ep)
18036864Sbostic char *p;
18136864Sbostic struct passwd *pw;
18246392Sbostic ENTRY *ep;
18336864Sbostic {
18437120Sbostic if (!*p)
18537120Sbostic ep->save = "";
18637120Sbostic else if (!(ep->save = strdup(p))) {
18766621Spendry warnx("can't save entry");
18866621Spendry return (1);
18936864Sbostic }
19066621Spendry return (0);
19136864Sbostic }
19236864Sbostic
19336864Sbostic /* ARGSUSED */
19466621Spendry int
p_hdir(p,pw,ep)19536864Sbostic p_hdir(p, pw, ep)
19636864Sbostic char *p;
19736864Sbostic struct passwd *pw;
19846392Sbostic ENTRY *ep;
19936864Sbostic {
20036864Sbostic if (!*p) {
20166621Spendry warnx("empty home directory field");
20266621Spendry return (1);
20336864Sbostic }
20436864Sbostic if (!(pw->pw_dir = strdup(p))) {
20566621Spendry warnx("can't save entry");
20666621Spendry return (1);
20736864Sbostic }
20866621Spendry return (0);
20936864Sbostic }
21036864Sbostic
21136864Sbostic /* ARGSUSED */
21266621Spendry int
p_shell(p,pw,ep)21336864Sbostic p_shell(p, pw, ep)
21466621Spendry char *p;
21536864Sbostic struct passwd *pw;
21646392Sbostic ENTRY *ep;
21736864Sbostic {
21838212Sbostic char *t, *ok_shell();
21936864Sbostic
22036864Sbostic if (!*p) {
22137023Sbostic pw->pw_shell = _PATH_BSHELL;
22266621Spendry return (0);
22336864Sbostic }
22438212Sbostic /* only admin can change from or to "restricted" shells */
22538212Sbostic if (uid && pw->pw_shell && !ok_shell(pw->pw_shell)) {
22666621Spendry warnx("%s: current shell non-standard", pw->pw_shell);
22766621Spendry return (1);
22838212Sbostic }
22938212Sbostic if (!(t = ok_shell(p))) {
23038212Sbostic if (uid) {
23166621Spendry warnx("%s: non-standard shell", p);
23266621Spendry return (1);
23336864Sbostic }
23436864Sbostic }
23538212Sbostic else
23638212Sbostic p = t;
23736864Sbostic if (!(pw->pw_shell = strdup(p))) {
23866621Spendry warnx("can't save entry");
23966621Spendry return (1);
24036864Sbostic }
24166621Spendry return (0);
24236864Sbostic }
243