xref: /original-bsd/usr.bin/chpass/field.c (revision 54e6d6c7)
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 are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 static char sccsid[] = "@(#)field.c	5.9 (Berkeley) 05/11/89";
20 #endif /* not lint */
21 
22 #include <sys/param.h>
23 #include <pwd.h>
24 #include <grp.h>
25 #include <strings.h>
26 #include <stdio.h>
27 #include <ctype.h>
28 #include "chpass.h"
29 #include "pathnames.h"
30 
31 /* ARGSUSED */
32 p_login(p, pw, ep)
33 	char *p;
34 	struct passwd *pw;
35 	struct entry *ep;
36 {
37 	if (!*p) {
38 		(void)fprintf(stderr, "chpass: empty login field.\n");
39 		return(1);
40 	}
41 	if (*p == '-') {
42 		(void)fprintf(stderr,
43 		    "chpass: login names may not begin with a hyphen.\n");
44 		return(1);
45 	}
46 	if (!(pw->pw_name = strdup(p))) {
47 		(void)fprintf(stderr, "chpass: can't save entry.\n");
48 		return(1);
49 	}
50 	if (index(p, '.'))
51 		(void)fprintf(stderr,
52 		    "chpass: \'.\' is dangerous in a login name.\n");
53 	for (; *p; ++p)
54 		if (isupper(*p)) {
55 			(void)fprintf(stderr,
56 			    "chpass: upper-case letters are dangerous in a login name.\n");
57 			break;
58 		}
59 	return(0);
60 }
61 
62 /* ARGSUSED */
63 p_passwd(p, pw, ep)
64 	char *p;
65 	struct passwd *pw;
66 	struct entry *ep;
67 {
68 	if (!*p)
69 		pw->pw_passwd = "";	/* "NOLOGIN"; */
70 	else if (!(pw->pw_passwd = strdup(p))) {
71 		(void)fprintf(stderr, "chpass: can't save password entry.\n");
72 		return(1);
73 	}
74 
75 	return(0);
76 }
77 
78 /* ARGSUSED */
79 p_uid(p, pw, ep)
80 	register char *p;
81 	struct passwd *pw;
82 	struct entry *ep;
83 {
84 	int id;
85 
86 	if (!*p) {
87 		(void)fprintf(stderr, "chpass: empty uid field.\n");
88 		return(1);
89 	}
90 	if (!isdigit(*p)) {
91 		(void)fprintf(stderr, "chpass: illegal uid.\n");
92 		return(1);
93 	}
94 	id = atoi(p);
95 	if ((u_int)id > USHRT_MAX) {
96 		(void)fprintf(stderr, "chpass: %d > max uid value (%d).\n",
97 		    id, USHRT_MAX);
98 		return(1);
99 	}
100 	pw->pw_uid = id;
101 	return(0);
102 }
103 
104 /* ARGSUSED */
105 p_gid(p, pw, ep)
106 	register char *p;
107 	struct passwd *pw;
108 	struct entry *ep;
109 {
110 	struct group *gr;
111 	int id;
112 
113 	if (!*p) {
114 		(void)fprintf(stderr, "chpass: empty gid field.\n");
115 		return(1);
116 	}
117 	if (!isdigit(*p)) {
118 		if (!(gr = getgrnam(p))) {
119 			(void)fprintf(stderr,
120 			    "chpass: unknown group %s.\n", p);
121 			return(1);
122 		}
123 		pw->pw_gid = gr->gr_gid;
124 		return(0);
125 	}
126 	id = atoi(p);
127 	if ((u_int)id > USHRT_MAX) {
128 		(void)fprintf(stderr, "chpass: %d > max gid value (%d).\n",
129 		    id, USHRT_MAX);
130 		return(1);
131 	}
132 	pw->pw_gid = id;
133 	return(0);
134 }
135 
136 /* ARGSUSED */
137 p_class(p, pw, ep)
138 	char *p;
139 	struct passwd *pw;
140 	struct entry *ep;
141 {
142 	if (!*p)
143 		pw->pw_class = "";
144 	else if (!(pw->pw_class = strdup(p))) {
145 		(void)fprintf(stderr, "chpass: can't save entry.\n");
146 		return(1);
147 	}
148 
149 	return(0);
150 }
151 
152 /* ARGSUSED */
153 p_change(p, pw, ep)
154 	char *p;
155 	struct passwd *pw;
156 	struct entry *ep;
157 {
158 	if (!atot(p, &pw->pw_change))
159 		return(0);
160 	(void)fprintf(stderr, "chpass: illegal date for change field.\n");
161 	return(1);
162 }
163 
164 /* ARGSUSED */
165 p_expire(p, pw, ep)
166 	char *p;
167 	struct passwd *pw;
168 	struct entry *ep;
169 {
170 	if (!atot(p, &pw->pw_expire))
171 		return(0);
172 	(void)fprintf(stderr, "chpass: illegal date for expire field.\n");
173 	return(1);
174 }
175 
176 /* ARGSUSED */
177 p_gecos(p, pw, ep)
178 	char *p;
179 	struct passwd *pw;
180 	struct entry *ep;
181 {
182 	if (!*p)
183 		ep->save = "";
184 	else if (!(ep->save = strdup(p))) {
185 		(void)fprintf(stderr, "chpass: can't save entry.\n");
186 		return(1);
187 	}
188 	return(0);
189 }
190 
191 /* ARGSUSED */
192 p_hdir(p, pw, ep)
193 	char *p;
194 	struct passwd *pw;
195 	struct entry *ep;
196 {
197 	if (!*p) {
198 		(void)fprintf(stderr, "chpass: empty home directory field.\n");
199 		return(1);
200 	}
201 	if (!(pw->pw_dir = strdup(p))) {
202 		(void)fprintf(stderr, "chpass: can't save entry.\n");
203 		return(1);
204 	}
205 	return(0);
206 }
207 
208 /* ARGSUSED */
209 p_shell(p, pw, ep)
210 	register char *p;
211 	struct passwd *pw;
212 	struct entry *ep;
213 {
214 	register char *sh, *t;
215 	char *getusershell();
216 
217 	if (!*p) {
218 		pw->pw_shell = _PATH_BSHELL;
219 		return(0);
220 	}
221 	setusershell();
222 	for (;;) {
223 		if (!(sh = getusershell())) {
224 			/* only admin can set "restricted" shells */
225 			if (!uid)
226 				break;
227 			(void)fprintf(stderr,
228 			    "chpass: %s: non-standard shell.\n", p);
229 			return(1);
230 		}
231 		if (!strcmp(p, sh))
232 			break;
233 		/* allow just shell name */
234 		if ((t = rindex(sh, '/')) && !strcmp(p, t)) {
235 			p = t;
236 			break;
237 		}
238 	}
239 	if (!(pw->pw_shell = strdup(p))) {
240 		(void)fprintf(stderr, "chpass: can't save entry.\n");
241 		return(1);
242 	}
243 	return(0);
244 }
245