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