1*c6ec7d31SBrooks Davis /* $NetBSD: getid.c,v 1.7 2008/04/28 20:24:17 martin Exp $ */ 2*c6ec7d31SBrooks Davis /* from: NetBSD: getpwent.c,v 1.48 2000/10/03 03:22:26 enami Exp */ 3*c6ec7d31SBrooks Davis /* from: NetBSD: getgrent.c,v 1.41 2002/01/12 23:51:30 lukem Exp */ 4*c6ec7d31SBrooks Davis 5*c6ec7d31SBrooks Davis /* 6*c6ec7d31SBrooks Davis * Copyright (c) 1987, 1988, 1989, 1993, 1994, 1995 7*c6ec7d31SBrooks Davis * The Regents of the University of California. All rights reserved. 8*c6ec7d31SBrooks Davis * 9*c6ec7d31SBrooks Davis * Redistribution and use in source and binary forms, with or without 10*c6ec7d31SBrooks Davis * modification, are permitted provided that the following conditions 11*c6ec7d31SBrooks Davis * are met: 12*c6ec7d31SBrooks Davis * 1. Redistributions of source code must retain the above copyright 13*c6ec7d31SBrooks Davis * notice, this list of conditions and the following disclaimer. 14*c6ec7d31SBrooks Davis * 2. Redistributions in binary form must reproduce the above copyright 15*c6ec7d31SBrooks Davis * notice, this list of conditions and the following disclaimer in the 16*c6ec7d31SBrooks Davis * documentation and/or other materials provided with the distribution. 17*c6ec7d31SBrooks Davis * 3. Neither the name of the University nor the names of its contributors 18*c6ec7d31SBrooks Davis * may be used to endorse or promote products derived from this software 19*c6ec7d31SBrooks Davis * without specific prior written permission. 20*c6ec7d31SBrooks Davis * 21*c6ec7d31SBrooks Davis * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22*c6ec7d31SBrooks Davis * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23*c6ec7d31SBrooks Davis * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24*c6ec7d31SBrooks Davis * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25*c6ec7d31SBrooks Davis * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26*c6ec7d31SBrooks Davis * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27*c6ec7d31SBrooks Davis * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28*c6ec7d31SBrooks Davis * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29*c6ec7d31SBrooks Davis * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30*c6ec7d31SBrooks Davis * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31*c6ec7d31SBrooks Davis * SUCH DAMAGE. 32*c6ec7d31SBrooks Davis */ 33*c6ec7d31SBrooks Davis 34*c6ec7d31SBrooks Davis /*- 35*c6ec7d31SBrooks Davis * Copyright (c) 2002 The NetBSD Foundation, Inc. 36*c6ec7d31SBrooks Davis * All rights reserved. 37*c6ec7d31SBrooks Davis * 38*c6ec7d31SBrooks Davis * This code is derived from software contributed to The NetBSD Foundation 39*c6ec7d31SBrooks Davis * by Luke Mewburn of Wasabi Systems. 40*c6ec7d31SBrooks Davis * 41*c6ec7d31SBrooks Davis * Redistribution and use in source and binary forms, with or without 42*c6ec7d31SBrooks Davis * modification, are permitted provided that the following conditions 43*c6ec7d31SBrooks Davis * are met: 44*c6ec7d31SBrooks Davis * 1. Redistributions of source code must retain the above copyright 45*c6ec7d31SBrooks Davis * notice, this list of conditions and the following disclaimer. 46*c6ec7d31SBrooks Davis * 2. Redistributions in binary form must reproduce the above copyright 47*c6ec7d31SBrooks Davis * notice, this list of conditions and the following disclaimer in the 48*c6ec7d31SBrooks Davis * documentation and/or other materials provided with the distribution. 49*c6ec7d31SBrooks Davis * 50*c6ec7d31SBrooks Davis * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 51*c6ec7d31SBrooks Davis * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 52*c6ec7d31SBrooks Davis * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 53*c6ec7d31SBrooks Davis * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 54*c6ec7d31SBrooks Davis * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 55*c6ec7d31SBrooks Davis * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 56*c6ec7d31SBrooks Davis * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 57*c6ec7d31SBrooks Davis * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 58*c6ec7d31SBrooks Davis * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 59*c6ec7d31SBrooks Davis * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 60*c6ec7d31SBrooks Davis * POSSIBILITY OF SUCH DAMAGE. 61*c6ec7d31SBrooks Davis */ 62*c6ec7d31SBrooks Davis 63*c6ec7d31SBrooks Davis #if HAVE_NBTOOL_CONFIG_H 64*c6ec7d31SBrooks Davis #include "nbtool_config.h" 65*c6ec7d31SBrooks Davis #endif 66*c6ec7d31SBrooks Davis 67*c6ec7d31SBrooks Davis #include <sys/cdefs.h> 68*c6ec7d31SBrooks Davis __RCSID("$NetBSD: getid.c,v 1.7 2008/04/28 20:24:17 martin Exp $"); 69*c6ec7d31SBrooks Davis 70*c6ec7d31SBrooks Davis #include <sys/param.h> 71*c6ec7d31SBrooks Davis 72*c6ec7d31SBrooks Davis #include <grp.h> 73*c6ec7d31SBrooks Davis #include <limits.h> 74*c6ec7d31SBrooks Davis #include <pwd.h> 75*c6ec7d31SBrooks Davis #include <stdlib.h> 76*c6ec7d31SBrooks Davis #include <stdio.h> 77*c6ec7d31SBrooks Davis #include <string.h> 78*c6ec7d31SBrooks Davis #include <time.h> 79*c6ec7d31SBrooks Davis #include <unistd.h> 80*c6ec7d31SBrooks Davis 81*c6ec7d31SBrooks Davis #include "extern.h" 82*c6ec7d31SBrooks Davis 83*c6ec7d31SBrooks Davis static struct group * gi_getgrnam(const char *); 84*c6ec7d31SBrooks Davis static struct group * gi_getgrgid(gid_t); 85*c6ec7d31SBrooks Davis static int gi_setgroupent(int); 86*c6ec7d31SBrooks Davis static void gi_endgrent(void); 87*c6ec7d31SBrooks Davis static int grstart(void); 88*c6ec7d31SBrooks Davis static int grscan(int, gid_t, const char *); 89*c6ec7d31SBrooks Davis static int grmatchline(int, gid_t, const char *); 90*c6ec7d31SBrooks Davis 91*c6ec7d31SBrooks Davis static struct passwd * gi_getpwnam(const char *); 92*c6ec7d31SBrooks Davis static struct passwd * gi_getpwuid(uid_t); 93*c6ec7d31SBrooks Davis static int gi_setpassent(int); 94*c6ec7d31SBrooks Davis static void gi_endpwent(void); 95*c6ec7d31SBrooks Davis static int pwstart(void); 96*c6ec7d31SBrooks Davis static int pwscan(int, uid_t, const char *); 97*c6ec7d31SBrooks Davis static int pwmatchline(int, uid_t, const char *); 98*c6ec7d31SBrooks Davis 99*c6ec7d31SBrooks Davis #define MAXGRP 200 100*c6ec7d31SBrooks Davis #define MAXLINELENGTH 1024 101*c6ec7d31SBrooks Davis 102*c6ec7d31SBrooks Davis static FILE *_gr_fp; 103*c6ec7d31SBrooks Davis static struct group _gr_group; 104*c6ec7d31SBrooks Davis static int _gr_stayopen; 105*c6ec7d31SBrooks Davis static int _gr_filesdone; 106*c6ec7d31SBrooks Davis static FILE *_pw_fp; 107*c6ec7d31SBrooks Davis static struct passwd _pw_passwd; /* password structure */ 108*c6ec7d31SBrooks Davis static int _pw_stayopen; /* keep fd's open */ 109*c6ec7d31SBrooks Davis static int _pw_filesdone; 110*c6ec7d31SBrooks Davis 111*c6ec7d31SBrooks Davis static char grfile[MAXPATHLEN]; 112*c6ec7d31SBrooks Davis static char pwfile[MAXPATHLEN]; 113*c6ec7d31SBrooks Davis 114*c6ec7d31SBrooks Davis static char *members[MAXGRP]; 115*c6ec7d31SBrooks Davis static char grline[MAXLINELENGTH]; 116*c6ec7d31SBrooks Davis static char pwline[MAXLINELENGTH]; 117*c6ec7d31SBrooks Davis 118*c6ec7d31SBrooks Davis int 119*c6ec7d31SBrooks Davis setup_getid(const char *dir) 120*c6ec7d31SBrooks Davis { 121*c6ec7d31SBrooks Davis if (dir == NULL) 122*c6ec7d31SBrooks Davis return (0); 123*c6ec7d31SBrooks Davis 124*c6ec7d31SBrooks Davis /* close existing databases */ 125*c6ec7d31SBrooks Davis gi_endgrent(); 126*c6ec7d31SBrooks Davis gi_endpwent(); 127*c6ec7d31SBrooks Davis 128*c6ec7d31SBrooks Davis /* build paths to new databases */ 129*c6ec7d31SBrooks Davis snprintf(grfile, sizeof(grfile), "%s/group", dir); 130*c6ec7d31SBrooks Davis snprintf(pwfile, sizeof(pwfile), "%s/master.passwd", dir); 131*c6ec7d31SBrooks Davis 132*c6ec7d31SBrooks Davis /* try to open new databases */ 133*c6ec7d31SBrooks Davis if (!grstart() || !pwstart()) 134*c6ec7d31SBrooks Davis return (0); 135*c6ec7d31SBrooks Davis 136*c6ec7d31SBrooks Davis /* switch pwcache(3) lookup functions */ 137*c6ec7d31SBrooks Davis if (pwcache_groupdb(gi_setgroupent, gi_endgrent, 138*c6ec7d31SBrooks Davis gi_getgrnam, gi_getgrgid) == -1 139*c6ec7d31SBrooks Davis || pwcache_userdb(gi_setpassent, gi_endpwent, 140*c6ec7d31SBrooks Davis gi_getpwnam, gi_getpwuid) == -1) 141*c6ec7d31SBrooks Davis return (0); 142*c6ec7d31SBrooks Davis 143*c6ec7d31SBrooks Davis return (1); 144*c6ec7d31SBrooks Davis } 145*c6ec7d31SBrooks Davis 146*c6ec7d31SBrooks Davis 147*c6ec7d31SBrooks Davis /* 148*c6ec7d31SBrooks Davis * group lookup functions 149*c6ec7d31SBrooks Davis */ 150*c6ec7d31SBrooks Davis 151*c6ec7d31SBrooks Davis static struct group * 152*c6ec7d31SBrooks Davis gi_getgrnam(const char *name) 153*c6ec7d31SBrooks Davis { 154*c6ec7d31SBrooks Davis int rval; 155*c6ec7d31SBrooks Davis 156*c6ec7d31SBrooks Davis if (!grstart()) 157*c6ec7d31SBrooks Davis return NULL; 158*c6ec7d31SBrooks Davis rval = grscan(1, 0, name); 159*c6ec7d31SBrooks Davis if (!_gr_stayopen) 160*c6ec7d31SBrooks Davis endgrent(); 161*c6ec7d31SBrooks Davis return (rval) ? &_gr_group : NULL; 162*c6ec7d31SBrooks Davis } 163*c6ec7d31SBrooks Davis 164*c6ec7d31SBrooks Davis static struct group * 165*c6ec7d31SBrooks Davis gi_getgrgid(gid_t gid) 166*c6ec7d31SBrooks Davis { 167*c6ec7d31SBrooks Davis int rval; 168*c6ec7d31SBrooks Davis 169*c6ec7d31SBrooks Davis if (!grstart()) 170*c6ec7d31SBrooks Davis return NULL; 171*c6ec7d31SBrooks Davis rval = grscan(1, gid, NULL); 172*c6ec7d31SBrooks Davis if (!_gr_stayopen) 173*c6ec7d31SBrooks Davis endgrent(); 174*c6ec7d31SBrooks Davis return (rval) ? &_gr_group : NULL; 175*c6ec7d31SBrooks Davis } 176*c6ec7d31SBrooks Davis 177*c6ec7d31SBrooks Davis static int 178*c6ec7d31SBrooks Davis gi_setgroupent(int stayopen) 179*c6ec7d31SBrooks Davis { 180*c6ec7d31SBrooks Davis 181*c6ec7d31SBrooks Davis if (!grstart()) 182*c6ec7d31SBrooks Davis return 0; 183*c6ec7d31SBrooks Davis _gr_stayopen = stayopen; 184*c6ec7d31SBrooks Davis return 1; 185*c6ec7d31SBrooks Davis } 186*c6ec7d31SBrooks Davis 187*c6ec7d31SBrooks Davis static void 188*c6ec7d31SBrooks Davis gi_endgrent(void) 189*c6ec7d31SBrooks Davis { 190*c6ec7d31SBrooks Davis 191*c6ec7d31SBrooks Davis _gr_filesdone = 0; 192*c6ec7d31SBrooks Davis if (_gr_fp) { 193*c6ec7d31SBrooks Davis (void)fclose(_gr_fp); 194*c6ec7d31SBrooks Davis _gr_fp = NULL; 195*c6ec7d31SBrooks Davis } 196*c6ec7d31SBrooks Davis } 197*c6ec7d31SBrooks Davis 198*c6ec7d31SBrooks Davis static int 199*c6ec7d31SBrooks Davis grstart(void) 200*c6ec7d31SBrooks Davis { 201*c6ec7d31SBrooks Davis 202*c6ec7d31SBrooks Davis _gr_filesdone = 0; 203*c6ec7d31SBrooks Davis if (_gr_fp) { 204*c6ec7d31SBrooks Davis rewind(_gr_fp); 205*c6ec7d31SBrooks Davis return 1; 206*c6ec7d31SBrooks Davis } 207*c6ec7d31SBrooks Davis if (grfile[0] == '\0') /* sanity check */ 208*c6ec7d31SBrooks Davis return 0; 209*c6ec7d31SBrooks Davis return (_gr_fp = fopen(grfile, "r")) ? 1 : 0; 210*c6ec7d31SBrooks Davis } 211*c6ec7d31SBrooks Davis 212*c6ec7d31SBrooks Davis 213*c6ec7d31SBrooks Davis static int 214*c6ec7d31SBrooks Davis grscan(int search, gid_t gid, const char *name) 215*c6ec7d31SBrooks Davis { 216*c6ec7d31SBrooks Davis 217*c6ec7d31SBrooks Davis if (_gr_filesdone) 218*c6ec7d31SBrooks Davis return 0; 219*c6ec7d31SBrooks Davis for (;;) { 220*c6ec7d31SBrooks Davis if (!fgets(grline, sizeof(grline), _gr_fp)) { 221*c6ec7d31SBrooks Davis if (!search) 222*c6ec7d31SBrooks Davis _gr_filesdone = 1; 223*c6ec7d31SBrooks Davis return 0; 224*c6ec7d31SBrooks Davis } 225*c6ec7d31SBrooks Davis /* skip lines that are too big */ 226*c6ec7d31SBrooks Davis if (!strchr(grline, '\n')) { 227*c6ec7d31SBrooks Davis int ch; 228*c6ec7d31SBrooks Davis 229*c6ec7d31SBrooks Davis while ((ch = getc(_gr_fp)) != '\n' && ch != EOF) 230*c6ec7d31SBrooks Davis ; 231*c6ec7d31SBrooks Davis continue; 232*c6ec7d31SBrooks Davis } 233*c6ec7d31SBrooks Davis if (grmatchline(search, gid, name)) 234*c6ec7d31SBrooks Davis return 1; 235*c6ec7d31SBrooks Davis } 236*c6ec7d31SBrooks Davis /* NOTREACHED */ 237*c6ec7d31SBrooks Davis } 238*c6ec7d31SBrooks Davis 239*c6ec7d31SBrooks Davis static int 240*c6ec7d31SBrooks Davis grmatchline(int search, gid_t gid, const char *name) 241*c6ec7d31SBrooks Davis { 242*c6ec7d31SBrooks Davis unsigned long id; 243*c6ec7d31SBrooks Davis char **m; 244*c6ec7d31SBrooks Davis char *cp, *bp, *ep; 245*c6ec7d31SBrooks Davis 246*c6ec7d31SBrooks Davis /* name may be NULL if search is nonzero */ 247*c6ec7d31SBrooks Davis 248*c6ec7d31SBrooks Davis bp = grline; 249*c6ec7d31SBrooks Davis memset(&_gr_group, 0, sizeof(_gr_group)); 250*c6ec7d31SBrooks Davis _gr_group.gr_name = strsep(&bp, ":\n"); 251*c6ec7d31SBrooks Davis if (search && name && strcmp(_gr_group.gr_name, name)) 252*c6ec7d31SBrooks Davis return 0; 253*c6ec7d31SBrooks Davis _gr_group.gr_passwd = strsep(&bp, ":\n"); 254*c6ec7d31SBrooks Davis if (!(cp = strsep(&bp, ":\n"))) 255*c6ec7d31SBrooks Davis return 0; 256*c6ec7d31SBrooks Davis id = strtoul(cp, &ep, 10); 257*c6ec7d31SBrooks Davis if (id > GID_MAX || *ep != '\0') 258*c6ec7d31SBrooks Davis return 0; 259*c6ec7d31SBrooks Davis _gr_group.gr_gid = (gid_t)id; 260*c6ec7d31SBrooks Davis if (search && name == NULL && _gr_group.gr_gid != gid) 261*c6ec7d31SBrooks Davis return 0; 262*c6ec7d31SBrooks Davis cp = NULL; 263*c6ec7d31SBrooks Davis if (bp == NULL) 264*c6ec7d31SBrooks Davis return 0; 265*c6ec7d31SBrooks Davis for (_gr_group.gr_mem = m = members;; bp++) { 266*c6ec7d31SBrooks Davis if (m == &members[MAXGRP - 1]) 267*c6ec7d31SBrooks Davis break; 268*c6ec7d31SBrooks Davis if (*bp == ',') { 269*c6ec7d31SBrooks Davis if (cp) { 270*c6ec7d31SBrooks Davis *bp = '\0'; 271*c6ec7d31SBrooks Davis *m++ = cp; 272*c6ec7d31SBrooks Davis cp = NULL; 273*c6ec7d31SBrooks Davis } 274*c6ec7d31SBrooks Davis } else if (*bp == '\0' || *bp == '\n' || *bp == ' ') { 275*c6ec7d31SBrooks Davis if (cp) { 276*c6ec7d31SBrooks Davis *bp = '\0'; 277*c6ec7d31SBrooks Davis *m++ = cp; 278*c6ec7d31SBrooks Davis } 279*c6ec7d31SBrooks Davis break; 280*c6ec7d31SBrooks Davis } else if (cp == NULL) 281*c6ec7d31SBrooks Davis cp = bp; 282*c6ec7d31SBrooks Davis } 283*c6ec7d31SBrooks Davis *m = NULL; 284*c6ec7d31SBrooks Davis return 1; 285*c6ec7d31SBrooks Davis } 286*c6ec7d31SBrooks Davis 287*c6ec7d31SBrooks Davis 288*c6ec7d31SBrooks Davis /* 289*c6ec7d31SBrooks Davis * user lookup functions 290*c6ec7d31SBrooks Davis */ 291*c6ec7d31SBrooks Davis 292*c6ec7d31SBrooks Davis static struct passwd * 293*c6ec7d31SBrooks Davis gi_getpwnam(const char *name) 294*c6ec7d31SBrooks Davis { 295*c6ec7d31SBrooks Davis int rval; 296*c6ec7d31SBrooks Davis 297*c6ec7d31SBrooks Davis if (!pwstart()) 298*c6ec7d31SBrooks Davis return NULL; 299*c6ec7d31SBrooks Davis rval = pwscan(1, 0, name); 300*c6ec7d31SBrooks Davis if (!_pw_stayopen) 301*c6ec7d31SBrooks Davis endpwent(); 302*c6ec7d31SBrooks Davis return (rval) ? &_pw_passwd : NULL; 303*c6ec7d31SBrooks Davis } 304*c6ec7d31SBrooks Davis 305*c6ec7d31SBrooks Davis static struct passwd * 306*c6ec7d31SBrooks Davis gi_getpwuid(uid_t uid) 307*c6ec7d31SBrooks Davis { 308*c6ec7d31SBrooks Davis int rval; 309*c6ec7d31SBrooks Davis 310*c6ec7d31SBrooks Davis if (!pwstart()) 311*c6ec7d31SBrooks Davis return NULL; 312*c6ec7d31SBrooks Davis rval = pwscan(1, uid, NULL); 313*c6ec7d31SBrooks Davis if (!_pw_stayopen) 314*c6ec7d31SBrooks Davis endpwent(); 315*c6ec7d31SBrooks Davis return (rval) ? &_pw_passwd : NULL; 316*c6ec7d31SBrooks Davis } 317*c6ec7d31SBrooks Davis 318*c6ec7d31SBrooks Davis static int 319*c6ec7d31SBrooks Davis gi_setpassent(int stayopen) 320*c6ec7d31SBrooks Davis { 321*c6ec7d31SBrooks Davis 322*c6ec7d31SBrooks Davis if (!pwstart()) 323*c6ec7d31SBrooks Davis return 0; 324*c6ec7d31SBrooks Davis _pw_stayopen = stayopen; 325*c6ec7d31SBrooks Davis return 1; 326*c6ec7d31SBrooks Davis } 327*c6ec7d31SBrooks Davis 328*c6ec7d31SBrooks Davis static void 329*c6ec7d31SBrooks Davis gi_endpwent(void) 330*c6ec7d31SBrooks Davis { 331*c6ec7d31SBrooks Davis 332*c6ec7d31SBrooks Davis _pw_filesdone = 0; 333*c6ec7d31SBrooks Davis if (_pw_fp) { 334*c6ec7d31SBrooks Davis (void)fclose(_pw_fp); 335*c6ec7d31SBrooks Davis _pw_fp = NULL; 336*c6ec7d31SBrooks Davis } 337*c6ec7d31SBrooks Davis } 338*c6ec7d31SBrooks Davis 339*c6ec7d31SBrooks Davis static int 340*c6ec7d31SBrooks Davis pwstart(void) 341*c6ec7d31SBrooks Davis { 342*c6ec7d31SBrooks Davis 343*c6ec7d31SBrooks Davis _pw_filesdone = 0; 344*c6ec7d31SBrooks Davis if (_pw_fp) { 345*c6ec7d31SBrooks Davis rewind(_pw_fp); 346*c6ec7d31SBrooks Davis return 1; 347*c6ec7d31SBrooks Davis } 348*c6ec7d31SBrooks Davis if (pwfile[0] == '\0') /* sanity check */ 349*c6ec7d31SBrooks Davis return 0; 350*c6ec7d31SBrooks Davis return (_pw_fp = fopen(pwfile, "r")) ? 1 : 0; 351*c6ec7d31SBrooks Davis } 352*c6ec7d31SBrooks Davis 353*c6ec7d31SBrooks Davis 354*c6ec7d31SBrooks Davis static int 355*c6ec7d31SBrooks Davis pwscan(int search, uid_t uid, const char *name) 356*c6ec7d31SBrooks Davis { 357*c6ec7d31SBrooks Davis 358*c6ec7d31SBrooks Davis if (_pw_filesdone) 359*c6ec7d31SBrooks Davis return 0; 360*c6ec7d31SBrooks Davis for (;;) { 361*c6ec7d31SBrooks Davis if (!fgets(pwline, sizeof(pwline), _pw_fp)) { 362*c6ec7d31SBrooks Davis if (!search) 363*c6ec7d31SBrooks Davis _pw_filesdone = 1; 364*c6ec7d31SBrooks Davis return 0; 365*c6ec7d31SBrooks Davis } 366*c6ec7d31SBrooks Davis /* skip lines that are too big */ 367*c6ec7d31SBrooks Davis if (!strchr(pwline, '\n')) { 368*c6ec7d31SBrooks Davis int ch; 369*c6ec7d31SBrooks Davis 370*c6ec7d31SBrooks Davis while ((ch = getc(_pw_fp)) != '\n' && ch != EOF) 371*c6ec7d31SBrooks Davis ; 372*c6ec7d31SBrooks Davis continue; 373*c6ec7d31SBrooks Davis } 374*c6ec7d31SBrooks Davis if (pwmatchline(search, uid, name)) 375*c6ec7d31SBrooks Davis return 1; 376*c6ec7d31SBrooks Davis } 377*c6ec7d31SBrooks Davis /* NOTREACHED */ 378*c6ec7d31SBrooks Davis } 379*c6ec7d31SBrooks Davis 380*c6ec7d31SBrooks Davis static int 381*c6ec7d31SBrooks Davis pwmatchline(int search, uid_t uid, const char *name) 382*c6ec7d31SBrooks Davis { 383*c6ec7d31SBrooks Davis unsigned long id; 384*c6ec7d31SBrooks Davis char *cp, *bp, *ep; 385*c6ec7d31SBrooks Davis 386*c6ec7d31SBrooks Davis /* name may be NULL if search is nonzero */ 387*c6ec7d31SBrooks Davis 388*c6ec7d31SBrooks Davis bp = pwline; 389*c6ec7d31SBrooks Davis memset(&_pw_passwd, 0, sizeof(_pw_passwd)); 390*c6ec7d31SBrooks Davis _pw_passwd.pw_name = strsep(&bp, ":\n"); /* name */ 391*c6ec7d31SBrooks Davis if (search && name && strcmp(_pw_passwd.pw_name, name)) 392*c6ec7d31SBrooks Davis return 0; 393*c6ec7d31SBrooks Davis 394*c6ec7d31SBrooks Davis _pw_passwd.pw_passwd = strsep(&bp, ":\n"); /* passwd */ 395*c6ec7d31SBrooks Davis 396*c6ec7d31SBrooks Davis if (!(cp = strsep(&bp, ":\n"))) /* uid */ 397*c6ec7d31SBrooks Davis return 0; 398*c6ec7d31SBrooks Davis id = strtoul(cp, &ep, 10); 399*c6ec7d31SBrooks Davis if (id > UID_MAX || *ep != '\0') 400*c6ec7d31SBrooks Davis return 0; 401*c6ec7d31SBrooks Davis _pw_passwd.pw_uid = (uid_t)id; 402*c6ec7d31SBrooks Davis if (search && name == NULL && _pw_passwd.pw_uid != uid) 403*c6ec7d31SBrooks Davis return 0; 404*c6ec7d31SBrooks Davis 405*c6ec7d31SBrooks Davis if (!(cp = strsep(&bp, ":\n"))) /* gid */ 406*c6ec7d31SBrooks Davis return 0; 407*c6ec7d31SBrooks Davis id = strtoul(cp, &ep, 10); 408*c6ec7d31SBrooks Davis if (id > GID_MAX || *ep != '\0') 409*c6ec7d31SBrooks Davis return 0; 410*c6ec7d31SBrooks Davis _pw_passwd.pw_gid = (gid_t)id; 411*c6ec7d31SBrooks Davis 412*c6ec7d31SBrooks Davis if (!(ep = strsep(&bp, ":"))) /* class */ 413*c6ec7d31SBrooks Davis return 0; 414*c6ec7d31SBrooks Davis if (!(ep = strsep(&bp, ":"))) /* change */ 415*c6ec7d31SBrooks Davis return 0; 416*c6ec7d31SBrooks Davis if (!(ep = strsep(&bp, ":"))) /* expire */ 417*c6ec7d31SBrooks Davis return 0; 418*c6ec7d31SBrooks Davis 419*c6ec7d31SBrooks Davis if (!(_pw_passwd.pw_gecos = strsep(&bp, ":\n"))) /* gecos */ 420*c6ec7d31SBrooks Davis return 0; 421*c6ec7d31SBrooks Davis if (!(_pw_passwd.pw_dir = strsep(&bp, ":\n"))) /* directory */ 422*c6ec7d31SBrooks Davis return 0; 423*c6ec7d31SBrooks Davis if (!(_pw_passwd.pw_shell = strsep(&bp, ":\n"))) /* shell */ 424*c6ec7d31SBrooks Davis return 0; 425*c6ec7d31SBrooks Davis 426*c6ec7d31SBrooks Davis if (strchr(bp, ':') != NULL) 427*c6ec7d31SBrooks Davis return 0; 428*c6ec7d31SBrooks Davis 429*c6ec7d31SBrooks Davis return 1; 430*c6ec7d31SBrooks Davis } 431*c6ec7d31SBrooks Davis 432