1 /* $NetBSD: field.c,v 1.4 1997/10/18 12:49:00 lukem 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 #include <sys/cdefs.h> 37 #ifndef lint 38 #if 0 39 static char sccsid[] = "@(#)field.c 8.4 (Berkeley) 4/2/94"; 40 #else 41 __RCSID("$NetBSD: field.c,v 1.4 1997/10/18 12:49:00 lukem Exp $"); 42 #endif 43 #endif /* not lint */ 44 45 #include <sys/param.h> 46 47 #include <ctype.h> 48 #include <err.h> 49 #include <errno.h> 50 #include <grp.h> 51 #include <pwd.h> 52 #include <stdio.h> 53 #include <stdlib.h> 54 #include <string.h> 55 #include <unistd.h> 56 57 #include "chpass.h" 58 #include "pathnames.h" 59 60 /* ARGSUSED */ 61 int 62 p_login(p, pw, ep) 63 char *p; 64 struct passwd *pw; 65 ENTRY *ep; 66 { 67 if (!*p) { 68 warnx("empty login field"); 69 return (1); 70 } 71 if (*p == '-') { 72 warnx("login names may not begin with a hyphen"); 73 return (1); 74 } 75 if (!(pw->pw_name = strdup(p))) { 76 warnx("can't save entry"); 77 return (1); 78 } 79 if (strchr(p, '.')) 80 warnx("\'.\' is dangerous in a login name"); 81 for (; *p; ++p) 82 if (isupper(*p)) { 83 warnx("upper-case letters are dangerous in a login name"); 84 break; 85 } 86 return (0); 87 } 88 89 /* ARGSUSED */ 90 int 91 p_passwd(p, pw, ep) 92 char *p; 93 struct passwd *pw; 94 ENTRY *ep; 95 { 96 if (!*p) 97 pw->pw_passwd = ""; /* "NOLOGIN"; */ 98 else if (!(pw->pw_passwd = strdup(p))) { 99 warnx("can't save password entry"); 100 return (1); 101 } 102 103 return (0); 104 } 105 106 /* ARGSUSED */ 107 int 108 p_uid(p, pw, ep) 109 char *p; 110 struct passwd *pw; 111 ENTRY *ep; 112 { 113 uid_t id; 114 char *np; 115 116 if (!*p) { 117 warnx("empty uid field"); 118 return (1); 119 } 120 if (!isdigit(*p)) { 121 warnx("illegal uid"); 122 return (1); 123 } 124 errno = 0; 125 id = strtoul(p, &np, 10); 126 if (*np || (id == ULONG_MAX && errno == ERANGE)) { 127 warnx("illegal uid"); 128 return (1); 129 } 130 pw->pw_uid = id; 131 return (0); 132 } 133 134 /* ARGSUSED */ 135 int 136 p_gid(p, pw, ep) 137 char *p; 138 struct passwd *pw; 139 ENTRY *ep; 140 { 141 struct group *gr; 142 gid_t id; 143 char *np; 144 145 if (!*p) { 146 warnx("empty gid field"); 147 return (1); 148 } 149 if (!isdigit(*p)) { 150 if (!(gr = getgrnam(p))) { 151 warnx("unknown group %s", p); 152 return (1); 153 } 154 pw->pw_gid = gr->gr_gid; 155 return (0); 156 } 157 errno = 0; 158 id = strtoul(p, &np, 10); 159 if (*np || (id == ULONG_MAX && errno == ERANGE)) { 160 warnx("illegal gid"); 161 return (1); 162 } 163 pw->pw_gid = id; 164 return (0); 165 } 166 167 /* ARGSUSED */ 168 int 169 p_class(p, pw, ep) 170 char *p; 171 struct passwd *pw; 172 ENTRY *ep; 173 { 174 if (!*p) 175 pw->pw_class = ""; 176 else if (!(pw->pw_class = strdup(p))) { 177 warnx("can't save entry"); 178 return (1); 179 } 180 181 return (0); 182 } 183 184 /* ARGSUSED */ 185 int 186 p_change(p, pw, ep) 187 char *p; 188 struct passwd *pw; 189 ENTRY *ep; 190 { 191 if (!atot(p, &pw->pw_change)) 192 return (0); 193 warnx("illegal date for change field"); 194 return (1); 195 } 196 197 /* ARGSUSED */ 198 int 199 p_expire(p, pw, ep) 200 char *p; 201 struct passwd *pw; 202 ENTRY *ep; 203 { 204 if (!atot(p, &pw->pw_expire)) 205 return (0); 206 warnx("illegal date for expire field"); 207 return (1); 208 } 209 210 /* ARGSUSED */ 211 int 212 p_gecos(p, pw, ep) 213 char *p; 214 struct passwd *pw; 215 ENTRY *ep; 216 { 217 if (!*p) 218 ep->save = ""; 219 else if (!(ep->save = strdup(p))) { 220 warnx("can't save entry"); 221 return (1); 222 } 223 return (0); 224 } 225 226 /* ARGSUSED */ 227 int 228 p_hdir(p, pw, ep) 229 char *p; 230 struct passwd *pw; 231 ENTRY *ep; 232 { 233 if (!*p) { 234 warnx("empty home directory field"); 235 return (1); 236 } 237 if (!(pw->pw_dir = strdup(p))) { 238 warnx("can't save entry"); 239 return (1); 240 } 241 return (0); 242 } 243 244 /* ARGSUSED */ 245 int 246 p_shell(p, pw, ep) 247 char *p; 248 struct passwd *pw; 249 ENTRY *ep; 250 { 251 char *t; 252 253 if (!*p) { 254 pw->pw_shell = _PATH_BSHELL; 255 return (0); 256 } 257 /* only admin can change from or to "restricted" shells */ 258 if (uid && pw->pw_shell && !ok_shell(pw->pw_shell)) { 259 warnx("%s: current shell non-standard", pw->pw_shell); 260 return (1); 261 } 262 if (!(t = ok_shell(p))) { 263 if (uid) { 264 warnx("%s: non-standard shell", p); 265 return (1); 266 } 267 } 268 else 269 p = t; 270 if (!(pw->pw_shell = strdup(p))) { 271 warnx("can't save entry"); 272 return (1); 273 } 274 return (0); 275 } 276