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