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