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