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