xref: /original-bsd/usr.bin/chpass/field.c (revision 333da485)
1 /*
2  * Copyright (c) 1988, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)field.c	8.2 (Berkeley) 01/03/94";
10 #endif /* not lint */
11 
12 #include <sys/param.h>
13 #include <pwd.h>
14 #include <grp.h>
15 #include <string.h>
16 #include <stdio.h>
17 #include <errno.h>
18 #include <ctype.h>
19 #include "chpass.h"
20 #include "pathnames.h"
21 
22 /* ARGSUSED */
23 p_login(p, pw, ep)
24 	char *p;
25 	struct passwd *pw;
26 	ENTRY *ep;
27 {
28 	if (!*p) {
29 		(void)fprintf(stderr, "chpass: empty login field.\n");
30 		return(1);
31 	}
32 	if (*p == '-') {
33 		(void)fprintf(stderr,
34 		    "chpass: login names may not begin with a hyphen.\n");
35 		return(1);
36 	}
37 	if (!(pw->pw_name = strdup(p))) {
38 		(void)fprintf(stderr, "chpass: can't save entry.\n");
39 		return(1);
40 	}
41 	if (index(p, '.'))
42 		(void)fprintf(stderr,
43 		    "chpass: \'.\' is dangerous in a login name.\n");
44 	for (; *p; ++p)
45 		if (isupper(*p)) {
46 			(void)fprintf(stderr,
47 			    "chpass: upper-case letters are dangerous in a login name.\n");
48 			break;
49 		}
50 	return(0);
51 }
52 
53 /* ARGSUSED */
54 p_passwd(p, pw, ep)
55 	char *p;
56 	struct passwd *pw;
57 	ENTRY *ep;
58 {
59 	if (!*p)
60 		pw->pw_passwd = "";	/* "NOLOGIN"; */
61 	else if (!(pw->pw_passwd = strdup(p))) {
62 		(void)fprintf(stderr, "chpass: can't save password entry.\n");
63 		return(1);
64 	}
65 
66 	return(0);
67 }
68 
69 /* ARGSUSED */
70 p_uid(p, pw, ep)
71 	register char *p;
72 	struct passwd *pw;
73 	ENTRY *ep;
74 {
75 	uid_t id;
76 	char *np;
77 
78 	if (!*p) {
79 		(void)fprintf(stderr, "chpass: empty uid field.\n");
80 		return(1);
81 	}
82 	if (!isdigit(*p)) {
83 		(void)fprintf(stderr, "chpass: illegal uid.\n");
84 		return(1);
85 	}
86 	errno = 0;
87 	id = strtoul(p, &np, 10);
88 	if (*np || (id == ULONG_MAX && errno == ERANGE)) {
89 		(void)fprintf(stderr, "chpass: illegal uid.\n");
90 		return(1);
91 	}
92 	pw->pw_uid = id;
93 	return(0);
94 }
95 
96 /* ARGSUSED */
97 p_gid(p, pw, ep)
98 	register char *p;
99 	struct passwd *pw;
100 	ENTRY *ep;
101 {
102 	struct group *gr;
103 	gid_t id;
104 	char *np;
105 
106 	if (!*p) {
107 		(void)fprintf(stderr, "chpass: empty gid field.\n");
108 		return(1);
109 	}
110 	if (!isdigit(*p)) {
111 		if (!(gr = getgrnam(p))) {
112 			(void)fprintf(stderr,
113 			    "chpass: unknown group %s.\n", p);
114 			return(1);
115 		}
116 		pw->pw_gid = gr->gr_gid;
117 		return(0);
118 	}
119 	errno = 0;
120 	id = strtoul(p, &np, 10);
121 	if (*np || (id == ULONG_MAX && errno == ERANGE)) {
122 		(void)fprintf(stderr, "chpass: illegal gid.\n");
123 		return(1);
124 	}
125 	pw->pw_gid = id;
126 	return(0);
127 }
128 
129 /* ARGSUSED */
130 p_class(p, pw, ep)
131 	char *p;
132 	struct passwd *pw;
133 	ENTRY *ep;
134 {
135 	if (!*p)
136 		pw->pw_class = "";
137 	else if (!(pw->pw_class = strdup(p))) {
138 		(void)fprintf(stderr, "chpass: can't save entry.\n");
139 		return(1);
140 	}
141 
142 	return(0);
143 }
144 
145 /* ARGSUSED */
146 p_change(p, pw, ep)
147 	char *p;
148 	struct passwd *pw;
149 	ENTRY *ep;
150 {
151 	if (!atot(p, &pw->pw_change))
152 		return(0);
153 	(void)fprintf(stderr, "chpass: illegal date for change field.\n");
154 	return(1);
155 }
156 
157 /* ARGSUSED */
158 p_expire(p, pw, ep)
159 	char *p;
160 	struct passwd *pw;
161 	ENTRY *ep;
162 {
163 	if (!atot(p, &pw->pw_expire))
164 		return(0);
165 	(void)fprintf(stderr, "chpass: illegal date for expire field.\n");
166 	return(1);
167 }
168 
169 /* ARGSUSED */
170 p_gecos(p, pw, ep)
171 	char *p;
172 	struct passwd *pw;
173 	ENTRY *ep;
174 {
175 	if (!*p)
176 		ep->save = "";
177 	else if (!(ep->save = strdup(p))) {
178 		(void)fprintf(stderr, "chpass: can't save entry.\n");
179 		return(1);
180 	}
181 	return(0);
182 }
183 
184 /* ARGSUSED */
185 p_hdir(p, pw, ep)
186 	char *p;
187 	struct passwd *pw;
188 	ENTRY *ep;
189 {
190 	if (!*p) {
191 		(void)fprintf(stderr, "chpass: empty home directory field.\n");
192 		return(1);
193 	}
194 	if (!(pw->pw_dir = strdup(p))) {
195 		(void)fprintf(stderr, "chpass: can't save entry.\n");
196 		return(1);
197 	}
198 	return(0);
199 }
200 
201 /* ARGSUSED */
202 p_shell(p, pw, ep)
203 	register char *p;
204 	struct passwd *pw;
205 	ENTRY *ep;
206 {
207 	char *t, *ok_shell();
208 
209 	if (!*p) {
210 		pw->pw_shell = _PATH_BSHELL;
211 		return(0);
212 	}
213 	/* only admin can change from or to "restricted" shells */
214 	if (uid && pw->pw_shell && !ok_shell(pw->pw_shell)) {
215 		(void)fprintf(stderr,
216 		    "chpass: %s: current shell non-standard.\n", pw->pw_shell);
217 		return(1);
218 	}
219 	if (!(t = ok_shell(p))) {
220 		if (uid) {
221 			(void)fprintf(stderr,
222 			    "chpass: %s: non-standard shell.\n", p);
223 			return(1);
224 		}
225 	}
226 	else
227 		p = t;
228 	if (!(pw->pw_shell = strdup(p))) {
229 		(void)fprintf(stderr, "chpass: can't save entry.\n");
230 		return(1);
231 	}
232 	return(0);
233 }
234