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 are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 static char sccsid[] = "@(#)field.c 5.11 (Berkeley) 05/15/90"; 20 #endif /* not lint */ 21 22 #include <sys/param.h> 23 #include <pwd.h> 24 #include <grp.h> 25 #include <string.h> 26 #include <stdio.h> 27 #include <ctype.h> 28 #include "chpass.h" 29 #include "pathnames.h" 30 31 /* ARGSUSED */ 32 p_login(p, pw, ep) 33 char *p; 34 struct passwd *pw; 35 struct entry *ep; 36 { 37 if (!*p) { 38 (void)fprintf(stderr, "chpass: empty login field.\n"); 39 return(1); 40 } 41 if (*p == '-') { 42 (void)fprintf(stderr, 43 "chpass: login names may not begin with a hyphen.\n"); 44 return(1); 45 } 46 if (!(pw->pw_name = strdup(p))) { 47 (void)fprintf(stderr, "chpass: can't save entry.\n"); 48 return(1); 49 } 50 if (index(p, '.')) 51 (void)fprintf(stderr, 52 "chpass: \'.\' is dangerous in a login name.\n"); 53 for (; *p; ++p) 54 if (isupper(*p)) { 55 (void)fprintf(stderr, 56 "chpass: upper-case letters are dangerous in a login name.\n"); 57 break; 58 } 59 return(0); 60 } 61 62 /* ARGSUSED */ 63 p_passwd(p, pw, ep) 64 char *p; 65 struct passwd *pw; 66 struct entry *ep; 67 { 68 if (!*p) 69 pw->pw_passwd = ""; /* "NOLOGIN"; */ 70 else if (!(pw->pw_passwd = strdup(p))) { 71 (void)fprintf(stderr, "chpass: can't save password entry.\n"); 72 return(1); 73 } 74 75 return(0); 76 } 77 78 /* ARGSUSED */ 79 p_uid(p, pw, ep) 80 register char *p; 81 struct passwd *pw; 82 struct entry *ep; 83 { 84 int id; 85 86 if (!*p) { 87 (void)fprintf(stderr, "chpass: empty uid field.\n"); 88 return(1); 89 } 90 if (!isdigit(*p)) { 91 (void)fprintf(stderr, "chpass: illegal uid.\n"); 92 return(1); 93 } 94 id = atoi(p); 95 if ((u_int)id > USHRT_MAX) { 96 (void)fprintf(stderr, "chpass: %d > max uid value (%d).\n", 97 id, USHRT_MAX); 98 return(1); 99 } 100 pw->pw_uid = id; 101 return(0); 102 } 103 104 /* ARGSUSED */ 105 p_gid(p, pw, ep) 106 register char *p; 107 struct passwd *pw; 108 struct entry *ep; 109 { 110 struct group *gr; 111 int id; 112 113 if (!*p) { 114 (void)fprintf(stderr, "chpass: empty gid field.\n"); 115 return(1); 116 } 117 if (!isdigit(*p)) { 118 if (!(gr = getgrnam(p))) { 119 (void)fprintf(stderr, 120 "chpass: unknown group %s.\n", p); 121 return(1); 122 } 123 pw->pw_gid = gr->gr_gid; 124 return(0); 125 } 126 id = atoi(p); 127 if ((u_int)id > USHRT_MAX) { 128 (void)fprintf(stderr, "chpass: %d > max gid value (%d).\n", 129 id, USHRT_MAX); 130 return(1); 131 } 132 pw->pw_gid = id; 133 return(0); 134 } 135 136 /* ARGSUSED */ 137 p_class(p, pw, ep) 138 char *p; 139 struct passwd *pw; 140 struct entry *ep; 141 { 142 if (!*p) 143 pw->pw_class = ""; 144 else if (!(pw->pw_class = strdup(p))) { 145 (void)fprintf(stderr, "chpass: can't save entry.\n"); 146 return(1); 147 } 148 149 return(0); 150 } 151 152 /* ARGSUSED */ 153 p_change(p, pw, ep) 154 char *p; 155 struct passwd *pw; 156 struct entry *ep; 157 { 158 if (!atot(p, &pw->pw_change)) 159 return(0); 160 (void)fprintf(stderr, "chpass: illegal date for change field.\n"); 161 return(1); 162 } 163 164 /* ARGSUSED */ 165 p_expire(p, pw, ep) 166 char *p; 167 struct passwd *pw; 168 struct entry *ep; 169 { 170 if (!atot(p, &pw->pw_expire)) 171 return(0); 172 (void)fprintf(stderr, "chpass: illegal date for expire field.\n"); 173 return(1); 174 } 175 176 /* ARGSUSED */ 177 p_gecos(p, pw, ep) 178 char *p; 179 struct passwd *pw; 180 struct entry *ep; 181 { 182 if (!*p) 183 ep->save = ""; 184 else if (!(ep->save = strdup(p))) { 185 (void)fprintf(stderr, "chpass: can't save entry.\n"); 186 return(1); 187 } 188 return(0); 189 } 190 191 /* ARGSUSED */ 192 p_hdir(p, pw, ep) 193 char *p; 194 struct passwd *pw; 195 struct entry *ep; 196 { 197 if (!*p) { 198 (void)fprintf(stderr, "chpass: empty home directory field.\n"); 199 return(1); 200 } 201 if (!(pw->pw_dir = 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_shell(p, pw, ep) 210 register char *p; 211 struct passwd *pw; 212 struct entry *ep; 213 { 214 char *t, *ok_shell(); 215 216 if (!*p) { 217 pw->pw_shell = _PATH_BSHELL; 218 return(0); 219 } 220 /* only admin can change from or to "restricted" shells */ 221 if (uid && pw->pw_shell && !ok_shell(pw->pw_shell)) { 222 (void)fprintf(stderr, 223 "chpass: %s: current shell non-standard.\n", pw->pw_shell); 224 return(1); 225 } 226 if (!(t = ok_shell(p))) { 227 if (uid) { 228 (void)fprintf(stderr, 229 "chpass: %s: non-standard shell.\n", p); 230 return(1); 231 } 232 } 233 else 234 p = t; 235 if (!(pw->pw_shell = strdup(p))) { 236 (void)fprintf(stderr, "chpass: can't save entry.\n"); 237 return(1); 238 } 239 return(0); 240 } 241