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