1 /*- 2 * Copyright (C) 1996 3 * David L. Nugent. 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 * 14 * THIS SOFTWARE IS PROVIDED BY DAVID L. NUGENT AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL DAVID L. NUGENT OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27 28 #ifndef lint 29 static const char rcsid[] = 30 "$FreeBSD$"; 31 #endif /* not lint */ 32 33 #include <stdio.h> 34 #include <string.h> 35 #include <stdlib.h> 36 #include <sys/param.h> 37 38 #include "pwupd.h" 39 40 static FILE * pwd_fp = NULL; 41 42 void 43 vendpwent(void) 44 { 45 if (pwd_fp != NULL) { 46 fclose(pwd_fp); 47 pwd_fp = NULL; 48 } 49 } 50 51 void 52 vsetpwent(void) 53 { 54 vendpwent(); 55 } 56 57 static struct passwd * 58 vnextpwent(char const * nam, uid_t uid, int doclose) 59 { 60 struct passwd * pw = NULL; 61 static char pwtmp[1024]; 62 63 strncpy(pwtmp, getpwpath(_MASTERPASSWD), sizeof pwtmp); 64 pwtmp[sizeof pwtmp - 1] = '\0'; 65 66 if (pwd_fp != NULL || (pwd_fp = fopen(pwtmp, "r")) != NULL) { 67 int done = 0; 68 69 static struct passwd pwd; 70 71 while (!done && fgets(pwtmp, sizeof pwtmp, pwd_fp) != NULL) 72 { 73 int i, quickout = 0; 74 char * q; 75 char * p = strchr(pwtmp, '\n'); 76 77 if (p == NULL) { 78 while (fgets(pwtmp, sizeof pwtmp, pwd_fp) != NULL && strchr(pwtmp, '\n')==NULL) 79 ; /* Skip long lines */ 80 continue; 81 } 82 83 /* skip comments & empty lines */ 84 if (*pwtmp =='\n' || *pwtmp == '#') 85 continue; 86 87 i = 0; 88 q = p = pwtmp; 89 bzero(&pwd, sizeof pwd); 90 while (!quickout && (p = strsep(&q, ":\n")) != NULL) { 91 switch (i++) 92 { 93 case 0: /* username */ 94 pwd.pw_name = p; 95 if (nam) { 96 if (strcmp(nam, p) == 0) 97 done = 1; 98 else 99 quickout = 1; 100 } 101 break; 102 case 1: /* password */ 103 pwd.pw_passwd = p; 104 break; 105 case 2: /* uid */ 106 pwd.pw_uid = atoi(p); 107 if (uid != (uid_t)-1) { 108 if (uid == pwd.pw_uid) 109 done = 1; 110 else 111 quickout = 1; 112 } 113 break; 114 case 3: /* gid */ 115 pwd.pw_gid = atoi(p); 116 break; 117 case 4: /* class */ 118 if (nam == NULL && uid == (uid_t)-1) 119 done = 1; 120 pwd.pw_class = p; 121 break; 122 case 5: /* change */ 123 pwd.pw_change = (time_t)atol(p); 124 break; 125 case 6: /* expire */ 126 pwd.pw_expire = (time_t)atol(p); 127 break; 128 case 7: /* gecos */ 129 pwd.pw_gecos = p; 130 break; 131 case 8: /* directory */ 132 pwd.pw_dir = p; 133 break; 134 case 9: /* shell */ 135 pwd.pw_shell = p; 136 break; 137 } 138 } 139 } 140 if (doclose) 141 vendpwent(); 142 if (done && pwd.pw_name) { 143 pw = &pwd; 144 145 #define CKNULL(s) s = s ? s : "" 146 CKNULL(pwd.pw_passwd); 147 CKNULL(pwd.pw_class); 148 CKNULL(pwd.pw_gecos); 149 CKNULL(pwd.pw_dir); 150 CKNULL(pwd.pw_shell); 151 } 152 } 153 return pw; 154 } 155 156 struct passwd * 157 vgetpwent(void) 158 { 159 return vnextpwent(NULL, -1, 0); 160 } 161 162 struct passwd * 163 vgetpwuid(uid_t uid) 164 { 165 return vnextpwent(NULL, uid, 1); 166 } 167 168 struct passwd * 169 vgetpwnam(const char * nam) 170 { 171 return vnextpwent(nam, -1, 1); 172 } 173 174 int vpwdb(char *arg, ...) 175 { 176 arg=arg; 177 return 0; 178 } 179 180 181 182 static FILE * grp_fp = NULL; 183 184 void 185 vendgrent(void) 186 { 187 if (grp_fp != NULL) { 188 fclose(grp_fp); 189 grp_fp = NULL; 190 } 191 } 192 193 RET_SETGRENT 194 vsetgrent(void) 195 { 196 vendgrent(); 197 #if defined(__FreeBSD__) 198 return 0; 199 #endif 200 } 201 202 static struct group * 203 vnextgrent(char const * nam, gid_t gid, int doclose) 204 { 205 struct group * gr = NULL; 206 207 static char * grtmp = NULL; 208 static int grlen = 0; 209 static char ** mems = NULL; 210 static int memlen = 0; 211 212 extendline(&grtmp, &grlen, MAXPATHLEN); 213 strncpy(grtmp, getgrpath(_GROUP), MAXPATHLEN); 214 grtmp[MAXPATHLEN - 1] = '\0'; 215 216 if (grp_fp != NULL || (grp_fp = fopen(grtmp, "r")) != NULL) { 217 int done = 0; 218 219 static struct group grp; 220 221 while (!done && fgets(grtmp, grlen, grp_fp) != NULL) 222 { 223 int i, quickout = 0; 224 int mno = 0; 225 char * q, * p; 226 char * sep = ":\n"; 227 228 if ((p = strchr(grtmp, '\n')) == NULL) { 229 int l; 230 extendline(&grtmp, &grlen, grlen + PWBUFSZ); 231 l = strlen(grtmp); 232 if (fgets(grtmp + l, grlen - l, grp_fp) == NULL) 233 break; /* No newline terminator on last line */ 234 } 235 /* Skip comments and empty lines */ 236 if (*grtmp == '\n' || *grtmp == '#') 237 continue; 238 i = 0; 239 q = p = grtmp; 240 bzero(&grp, sizeof grp); 241 extendarray(&mems, &memlen, 200); 242 while (!quickout && (p = strsep(&q, sep)) != NULL) { 243 switch (i++) 244 { 245 case 0: /* groupname */ 246 grp.gr_name = p; 247 if (nam) { 248 if (strcmp(nam, p) == 0) 249 done = 1; 250 else 251 quickout = 1; 252 } 253 break; 254 case 1: /* password */ 255 grp.gr_passwd = p; 256 break; 257 case 2: /* gid */ 258 grp.gr_gid = atoi(p); 259 if (gid != (gid_t)-1) { 260 if (gid == (gid_t)grp.gr_gid) 261 done = 1; 262 else 263 quickout = 1; 264 } else if (nam == NULL) 265 done = 1; 266 break; 267 case 3: 268 q = p; 269 sep = ",\n"; 270 break; 271 default: 272 if (*p) { 273 extendarray(&mems, &memlen, mno + 2); 274 mems[mno++] = p; 275 } 276 break; 277 } 278 } 279 grp.gr_mem = mems; 280 mems[mno] = NULL; 281 } 282 if (doclose) 283 vendgrent(); 284 if (done && grp.gr_name) { 285 gr = &grp; 286 287 CKNULL(grp.gr_passwd); 288 } 289 } 290 return gr; 291 } 292 293 struct group * 294 vgetgrent(void) 295 { 296 return vnextgrent(NULL, -1, 0); 297 } 298 299 300 struct group * 301 vgetgrgid(gid_t gid) 302 { 303 return vnextgrent(NULL, gid, 1); 304 } 305 306 struct group * 307 vgetgrnam(const char * nam) 308 { 309 return vnextgrent(nam, -1, 1); 310 } 311 312 int 313 vgrdb(char *arg, ...) 314 { 315 arg=arg; 316 return 0; 317 } 318 319