]> git.cameronkatri.com Git - pw-darwin.git/blob - chpass/field.c
Typo fix.
[pw-darwin.git] / chpass / field.c
1 /*
2 * Copyright (c) 1988, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 2002 Networks Associates Technology, Inc.
5 * All rights reserved.
6 *
7 * Portions of this software were developed for the FreeBSD Project by
8 * ThinkSec AS and NAI Labs, the Security Research Division of Network
9 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035
10 * ("CBOSS"), as part of the DARPA CHATS research program.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the University of
23 * California, Berkeley and its contributors.
24 * 4. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 */
40
41 #if 0
42 #ifndef lint
43 static char sccsid[] = "@(#)field.c 8.4 (Berkeley) 4/2/94";
44 #endif /* not lint */
45 #endif
46
47 #include <sys/cdefs.h>
48 __FBSDID("$FreeBSD$");
49
50 #include <sys/param.h>
51 #include <sys/stat.h>
52
53 #include <ctype.h>
54 #include <err.h>
55 #include <errno.h>
56 #include <grp.h>
57 #include <paths.h>
58 #include <pwd.h>
59 #include <stdlib.h>
60 #include <string.h>
61
62 #include "chpass.h"
63
64 /* ARGSUSED */
65 int
66 p_login(char *p, struct passwd *pw, ENTRY *ep __unused)
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(char *p, struct passwd *pw, ENTRY *ep __unused)
93 {
94 if (!(pw->pw_passwd = strdup(p))) {
95 warnx("can't save password entry");
96 return (-1);
97 }
98
99 return (0);
100 }
101
102 /* ARGSUSED */
103 int
104 p_uid(char *p, struct passwd *pw, ENTRY *ep __unused)
105 {
106 uid_t id;
107 char *np;
108
109 if (!*p) {
110 warnx("empty uid field");
111 return (-1);
112 }
113 if (!isdigit(*p)) {
114 warnx("illegal uid");
115 return (-1);
116 }
117 errno = 0;
118 id = strtoul(p, &np, 10);
119 if (*np || (id == (uid_t)ULONG_MAX && errno == ERANGE)) {
120 warnx("illegal uid");
121 return (-1);
122 }
123 pw->pw_uid = id;
124 return (0);
125 }
126
127 /* ARGSUSED */
128 int
129 p_gid(char *p, struct passwd *pw, ENTRY *ep __unused)
130 {
131 struct group *gr;
132 gid_t id;
133 char *np;
134
135 if (!*p) {
136 warnx("empty gid field");
137 return (-1);
138 }
139 if (!isdigit(*p)) {
140 if (!(gr = getgrnam(p))) {
141 warnx("unknown group %s", p);
142 return (-1);
143 }
144 pw->pw_gid = gr->gr_gid;
145 return (0);
146 }
147 errno = 0;
148 id = strtoul(p, &np, 10);
149 if (*np || (id == (uid_t)ULONG_MAX && errno == ERANGE)) {
150 warnx("illegal gid");
151 return (-1);
152 }
153 pw->pw_gid = id;
154 return (0);
155 }
156
157 /* ARGSUSED */
158 int
159 p_class(char *p, struct passwd *pw, ENTRY *ep __unused)
160 {
161 if (!(pw->pw_class = strdup(p))) {
162 warnx("can't save entry");
163 return (-1);
164 }
165
166 return (0);
167 }
168
169 /* ARGSUSED */
170 int
171 p_change(char *p, struct passwd *pw, ENTRY *ep __unused)
172 {
173 if (!atot(p, &pw->pw_change))
174 return (0);
175 warnx("illegal date for change field");
176 return (-1);
177 }
178
179 /* ARGSUSED */
180 int
181 p_expire(char *p, struct passwd *pw, ENTRY *ep __unused)
182 {
183 if (!atot(p, &pw->pw_expire))
184 return (0);
185 warnx("illegal date for expire field");
186 return (-1);
187 }
188
189 /* ARGSUSED */
190 int
191 p_gecos(char *p, struct passwd *pw __unused, ENTRY *ep)
192 {
193 if (!(ep->save = strdup(p))) {
194 warnx("can't save entry");
195 return (-1);
196 }
197 return (0);
198 }
199
200 /* ARGSUSED */
201 int
202 p_hdir(char *p, struct passwd *pw, ENTRY *ep __unused)
203 {
204 if (!*p) {
205 warnx("empty home directory field");
206 return (-1);
207 }
208 if (!(pw->pw_dir = strdup(p))) {
209 warnx("can't save entry");
210 return (-1);
211 }
212 return (0);
213 }
214
215 /* ARGSUSED */
216 int
217 p_shell(char *p, struct passwd *pw, ENTRY *ep __unused)
218 {
219 struct stat sbuf;
220
221 if (!*p) {
222 pw->pw_shell = strdup(_PATH_BSHELL);
223 return (0);
224 }
225 /* only admin can change from or to "restricted" shells */
226 if (!master_mode && pw->pw_shell && !ok_shell(pw->pw_shell)) {
227 warnx("%s: current shell non-standard", pw->pw_shell);
228 return (-1);
229 }
230 if (!ok_shell(p)) {
231 if (!master_mode) {
232 warnx("%s: non-standard shell", p);
233 return (-1);
234 }
235 pw->pw_shell = strdup(p);
236 }
237 else
238 pw->pw_shell = dup_shell(p);
239 if (!pw->pw_shell) {
240 warnx("can't save entry");
241 return (-1);
242 }
243 if (stat(pw->pw_shell, &sbuf) < 0) {
244 if (errno == ENOENT)
245 warnx("WARNING: shell '%s' does not exist",
246 pw->pw_shell);
247 else
248 warn("WARNING: can't stat shell '%s'", pw->pw_shell);
249 return (0);
250 }
251 if (!S_ISREG(sbuf.st_mode)) {
252 warnx("WARNING: shell '%s' is not a regular file",
253 pw->pw_shell);
254 return (0);
255 }
256 if ((sbuf.st_mode & (S_IXOTH | S_IXGRP | S_IXUSR)) == 0) {
257 warnx("WARNING: shell '%s' is not executable", pw->pw_shell);
258 return (0);
259 }
260 return (0);
261 }