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