1*5c007436SBen Gras /* $NetBSD: field.c,v 1.12 2009/04/11 12:10:02 lukem Exp $ */
2*5c007436SBen Gras
3*5c007436SBen Gras /*
4*5c007436SBen Gras * Copyright (c) 1988, 1993, 1994
5*5c007436SBen Gras * The Regents of the University of California. All rights reserved.
6*5c007436SBen Gras *
7*5c007436SBen Gras * Redistribution and use in source and binary forms, with or without
8*5c007436SBen Gras * modification, are permitted provided that the following conditions
9*5c007436SBen Gras * are met:
10*5c007436SBen Gras * 1. Redistributions of source code must retain the above copyright
11*5c007436SBen Gras * notice, this list of conditions and the following disclaimer.
12*5c007436SBen Gras * 2. Redistributions in binary form must reproduce the above copyright
13*5c007436SBen Gras * notice, this list of conditions and the following disclaimer in the
14*5c007436SBen Gras * documentation and/or other materials provided with the distribution.
15*5c007436SBen Gras * 3. Neither the name of the University nor the names of its contributors
16*5c007436SBen Gras * may be used to endorse or promote products derived from this software
17*5c007436SBen Gras * without specific prior written permission.
18*5c007436SBen Gras *
19*5c007436SBen Gras * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20*5c007436SBen Gras * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*5c007436SBen Gras * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*5c007436SBen Gras * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23*5c007436SBen Gras * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24*5c007436SBen Gras * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25*5c007436SBen Gras * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26*5c007436SBen Gras * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27*5c007436SBen Gras * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28*5c007436SBen Gras * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29*5c007436SBen Gras * SUCH DAMAGE.
30*5c007436SBen Gras */
31*5c007436SBen Gras
32*5c007436SBen Gras #include <sys/cdefs.h>
33*5c007436SBen Gras #ifndef lint
34*5c007436SBen Gras #if 0
35*5c007436SBen Gras static char sccsid[] = "@(#)field.c 8.4 (Berkeley) 4/2/94";
36*5c007436SBen Gras #else
37*5c007436SBen Gras __RCSID("$NetBSD: field.c,v 1.12 2009/04/11 12:10:02 lukem Exp $");
38*5c007436SBen Gras #endif
39*5c007436SBen Gras #endif /* not lint */
40*5c007436SBen Gras
41*5c007436SBen Gras #include <sys/param.h>
42*5c007436SBen Gras
43*5c007436SBen Gras #include <ctype.h>
44*5c007436SBen Gras #include <err.h>
45*5c007436SBen Gras #include <errno.h>
46*5c007436SBen Gras #include <grp.h>
47*5c007436SBen Gras #include <pwd.h>
48*5c007436SBen Gras #include <stdio.h>
49*5c007436SBen Gras #include <stdlib.h>
50*5c007436SBen Gras #include <string.h>
51*5c007436SBen Gras #include <unistd.h>
52*5c007436SBen Gras
53*5c007436SBen Gras #include "chpass.h"
54*5c007436SBen Gras #include "pathnames.h"
55*5c007436SBen Gras
56*5c007436SBen Gras /* ARGSUSED */
57*5c007436SBen Gras int
p_login(const char * p,struct passwd * pw,ENTRY * ep)58*5c007436SBen Gras p_login(const char *p, struct passwd *pw, ENTRY *ep)
59*5c007436SBen Gras {
60*5c007436SBen Gras
61*5c007436SBen Gras if (!*p) {
62*5c007436SBen Gras warnx("empty login field");
63*5c007436SBen Gras return (1);
64*5c007436SBen Gras }
65*5c007436SBen Gras if (*p == '-') {
66*5c007436SBen Gras warnx("login names may not begin with a hyphen");
67*5c007436SBen Gras return (1);
68*5c007436SBen Gras }
69*5c007436SBen Gras if (!(pw->pw_name = strdup(p))) {
70*5c007436SBen Gras warnx("can't save entry");
71*5c007436SBen Gras return (1);
72*5c007436SBen Gras }
73*5c007436SBen Gras if (strchr(p, '.'))
74*5c007436SBen Gras warnx("\'.\' is dangerous in a login name");
75*5c007436SBen Gras for (; *p; ++p)
76*5c007436SBen Gras if (isupper((unsigned char)*p)) {
77*5c007436SBen Gras warnx("upper-case letters are dangerous in a login name");
78*5c007436SBen Gras break;
79*5c007436SBen Gras }
80*5c007436SBen Gras return (0);
81*5c007436SBen Gras }
82*5c007436SBen Gras
83*5c007436SBen Gras /* ARGSUSED */
84*5c007436SBen Gras int
p_passwd(const char * p,struct passwd * pw,ENTRY * ep)85*5c007436SBen Gras p_passwd(const char *p, struct passwd *pw, ENTRY *ep)
86*5c007436SBen Gras {
87*5c007436SBen Gras
88*5c007436SBen Gras if (!(pw->pw_passwd = strdup(p))) {
89*5c007436SBen Gras warnx("can't save password entry");
90*5c007436SBen Gras return (1);
91*5c007436SBen Gras }
92*5c007436SBen Gras
93*5c007436SBen Gras return (0);
94*5c007436SBen Gras }
95*5c007436SBen Gras
96*5c007436SBen Gras /* ARGSUSED */
97*5c007436SBen Gras int
p_uid(const char * p,struct passwd * pw,ENTRY * ep)98*5c007436SBen Gras p_uid(const char *p, struct passwd *pw, ENTRY *ep)
99*5c007436SBen Gras {
100*5c007436SBen Gras unsigned long id;
101*5c007436SBen Gras char *np;
102*5c007436SBen Gras
103*5c007436SBen Gras if (!*p) {
104*5c007436SBen Gras warnx("empty uid field");
105*5c007436SBen Gras return (1);
106*5c007436SBen Gras }
107*5c007436SBen Gras if (!isdigit((unsigned char)*p)) {
108*5c007436SBen Gras warnx("illegal uid");
109*5c007436SBen Gras return (1);
110*5c007436SBen Gras }
111*5c007436SBen Gras errno = 0;
112*5c007436SBen Gras id = strtoul(p, &np, 10);
113*5c007436SBen Gras /*
114*5c007436SBen Gras * We don't need to check the return value of strtoul()
115*5c007436SBen Gras * since ULONG_MAX is greater than UID_MAX.
116*5c007436SBen Gras */
117*5c007436SBen Gras if (*np || id > UID_MAX) {
118*5c007436SBen Gras warnx("illegal uid");
119*5c007436SBen Gras return (1);
120*5c007436SBen Gras }
121*5c007436SBen Gras pw->pw_uid = (uid_t)id;
122*5c007436SBen Gras return (0);
123*5c007436SBen Gras }
124*5c007436SBen Gras
125*5c007436SBen Gras /* ARGSUSED */
126*5c007436SBen Gras int
p_gid(const char * p,struct passwd * pw,ENTRY * ep)127*5c007436SBen Gras p_gid(const char *p, struct passwd *pw, ENTRY *ep)
128*5c007436SBen Gras {
129*5c007436SBen Gras struct group *gr;
130*5c007436SBen Gras unsigned long id;
131*5c007436SBen Gras char *np;
132*5c007436SBen Gras
133*5c007436SBen Gras if (!*p) {
134*5c007436SBen Gras warnx("empty gid field");
135*5c007436SBen Gras return (1);
136*5c007436SBen Gras }
137*5c007436SBen Gras if (!isdigit((unsigned char)*p)) {
138*5c007436SBen Gras if (!(gr = getgrnam(p))) {
139*5c007436SBen Gras warnx("unknown group %s", p);
140*5c007436SBen Gras return (1);
141*5c007436SBen Gras }
142*5c007436SBen Gras pw->pw_gid = gr->gr_gid;
143*5c007436SBen Gras return (0);
144*5c007436SBen Gras }
145*5c007436SBen Gras errno = 0;
146*5c007436SBen Gras id = strtoul(p, &np, 10);
147*5c007436SBen Gras /*
148*5c007436SBen Gras * We don't need to check the return value of strtoul()
149*5c007436SBen Gras * since ULONG_MAX is greater than GID_MAX.
150*5c007436SBen Gras */
151*5c007436SBen Gras if (*np || id > GID_MAX) {
152*5c007436SBen Gras warnx("illegal gid");
153*5c007436SBen Gras return (1);
154*5c007436SBen Gras }
155*5c007436SBen Gras pw->pw_gid = (gid_t)id;
156*5c007436SBen Gras return (0);
157*5c007436SBen Gras }
158*5c007436SBen Gras
159*5c007436SBen Gras /* ARGSUSED */
160*5c007436SBen Gras int
p_class(const char * p,struct passwd * pw,ENTRY * ep)161*5c007436SBen Gras p_class(const char *p, struct passwd *pw, ENTRY *ep)
162*5c007436SBen Gras {
163*5c007436SBen Gras
164*5c007436SBen Gras if (!(pw->pw_class = strdup(p))) {
165*5c007436SBen Gras warnx("can't save entry");
166*5c007436SBen Gras return (1);
167*5c007436SBen Gras }
168*5c007436SBen Gras
169*5c007436SBen Gras return (0);
170*5c007436SBen Gras }
171*5c007436SBen Gras
172*5c007436SBen Gras /* ARGSUSED */
173*5c007436SBen Gras int
p_change(const char * p,struct passwd * pw,ENTRY * ep)174*5c007436SBen Gras p_change(const char *p, struct passwd *pw, ENTRY *ep)
175*5c007436SBen Gras {
176*5c007436SBen Gras
177*5c007436SBen Gras if (!atot(p, &pw->pw_change))
178*5c007436SBen Gras return (0);
179*5c007436SBen Gras warnx("illegal date for change field");
180*5c007436SBen Gras return (1);
181*5c007436SBen Gras }
182*5c007436SBen Gras
183*5c007436SBen Gras /* ARGSUSED */
184*5c007436SBen Gras int
p_expire(const char * p,struct passwd * pw,ENTRY * ep)185*5c007436SBen Gras p_expire(const char *p, struct passwd *pw, ENTRY *ep)
186*5c007436SBen Gras {
187*5c007436SBen Gras
188*5c007436SBen Gras if (!atot(p, &pw->pw_expire))
189*5c007436SBen Gras return (0);
190*5c007436SBen Gras warnx("illegal date for expire field");
191*5c007436SBen Gras return (1);
192*5c007436SBen Gras }
193*5c007436SBen Gras
194*5c007436SBen Gras /* ARGSUSED */
195*5c007436SBen Gras int
p_gecos(const char * p,struct passwd * pw,ENTRY * ep)196*5c007436SBen Gras p_gecos(const char *p, struct passwd *pw, ENTRY *ep)
197*5c007436SBen Gras {
198*5c007436SBen Gras
199*5c007436SBen Gras if (!(ep->save = strdup(p))) {
200*5c007436SBen Gras warnx("can't save entry");
201*5c007436SBen Gras return (1);
202*5c007436SBen Gras }
203*5c007436SBen Gras return (0);
204*5c007436SBen Gras }
205*5c007436SBen Gras
206*5c007436SBen Gras /* ARGSUSED */
207*5c007436SBen Gras int
p_hdir(const char * p,struct passwd * pw,ENTRY * ep)208*5c007436SBen Gras p_hdir(const char *p, struct passwd *pw, ENTRY *ep)
209*5c007436SBen Gras {
210*5c007436SBen Gras
211*5c007436SBen Gras if (!*p) {
212*5c007436SBen Gras warnx("empty home directory field");
213*5c007436SBen Gras return (1);
214*5c007436SBen Gras }
215*5c007436SBen Gras if (!(pw->pw_dir = strdup(p))) {
216*5c007436SBen Gras warnx("can't save entry");
217*5c007436SBen Gras return (1);
218*5c007436SBen Gras }
219*5c007436SBen Gras return (0);
220*5c007436SBen Gras }
221*5c007436SBen Gras
222*5c007436SBen Gras /* ARGSUSED */
223*5c007436SBen Gras int
p_shell(const char * p,struct passwd * pw,ENTRY * ep)224*5c007436SBen Gras p_shell(const char *p, struct passwd *pw, ENTRY *ep)
225*5c007436SBen Gras {
226*5c007436SBen Gras const char *t;
227*5c007436SBen Gras
228*5c007436SBen Gras if (!*p) {
229*5c007436SBen Gras if (!(pw->pw_shell = strdup(_PATH_BSHELL))) {
230*5c007436SBen Gras warnx("can't save entry");
231*5c007436SBen Gras return (1);
232*5c007436SBen Gras }
233*5c007436SBen Gras return (0);
234*5c007436SBen Gras }
235*5c007436SBen Gras /* only admin can change from or to "restricted" shells */
236*5c007436SBen Gras if (uid && pw->pw_shell && !ok_shell(pw->pw_shell)) {
237*5c007436SBen Gras warnx("%s: current shell non-standard", pw->pw_shell);
238*5c007436SBen Gras return (1);
239*5c007436SBen Gras }
240*5c007436SBen Gras if (!(t = ok_shell(p))) {
241*5c007436SBen Gras if (uid) {
242*5c007436SBen Gras warnx("%s: non-standard shell", p);
243*5c007436SBen Gras return (1);
244*5c007436SBen Gras }
245*5c007436SBen Gras }
246*5c007436SBen Gras else
247*5c007436SBen Gras p = t;
248*5c007436SBen Gras if (!(pw->pw_shell = strdup(p))) {
249*5c007436SBen Gras warnx("can't save entry");
250*5c007436SBen Gras return (1);
251*5c007436SBen Gras }
252*5c007436SBen Gras return (0);
253*5c007436SBen Gras }
254