144229Sdavidn/*- 244229Sdavidn * Copyright (C) 1996 344229Sdavidn * David L. Nugent. All rights reserved. 444229Sdavidn * 544229Sdavidn * Redistribution and use in source and binary forms, with or without 644229Sdavidn * modification, are permitted provided that the following conditions 744229Sdavidn * are met: 844229Sdavidn * 1. Redistributions of source code must retain the above copyright 944229Sdavidn * notice, this list of conditions and the following disclaimer. 1044229Sdavidn * 2. Redistributions in binary form must reproduce the above copyright 1144229Sdavidn * notice, this list of conditions and the following disclaimer in the 1244229Sdavidn * documentation and/or other materials provided with the distribution. 1344229Sdavidn * 1444229Sdavidn * THIS SOFTWARE IS PROVIDED BY DAVID L. NUGENT AND CONTRIBUTORS ``AS IS'' AND 1544229Sdavidn * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1644229Sdavidn * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1744229Sdavidn * ARE DISCLAIMED. IN NO EVENT SHALL DAVID L. NUGENT OR CONTRIBUTORS BE LIABLE 1844229Sdavidn * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1944229Sdavidn * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2044229Sdavidn * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2144229Sdavidn * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2244229Sdavidn * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2344229Sdavidn * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2444229Sdavidn * SUCH DAMAGE. 2544229Sdavidn * 2644229Sdavidn */ 2744229Sdavidn 2844229Sdavidn#ifndef lint 2944229Sdavidnstatic const char rcsid[] = 3050479Speter "$FreeBSD$"; 3144229Sdavidn#endif /* not lint */ 3244229Sdavidn 3344229Sdavidn#include <stdio.h> 3444229Sdavidn#include <string.h> 3544229Sdavidn#include <stdlib.h> 3644229Sdavidn#include <sys/param.h> 3744229Sdavidn 3844229Sdavidn#include "pwupd.h" 3944229Sdavidn 4044229Sdavidnstatic FILE * pwd_fp = NULL; 4144229Sdavidn 4244229Sdavidnvoid 4344229Sdavidnvendpwent(void) 4444229Sdavidn{ 4544229Sdavidn if (pwd_fp != NULL) { 4644229Sdavidn fclose(pwd_fp); 4744229Sdavidn pwd_fp = NULL; 4844229Sdavidn } 4944229Sdavidn} 5044229Sdavidn 5144229Sdavidnvoid 5244229Sdavidnvsetpwent(void) 5344229Sdavidn{ 5444229Sdavidn vendpwent(); 5544229Sdavidn} 5644229Sdavidn 5744229Sdavidnstatic struct passwd * 5844229Sdavidnvnextpwent(char const * nam, uid_t uid, int doclose) 5944229Sdavidn{ 6044229Sdavidn struct passwd * pw = NULL; 6144229Sdavidn static char pwtmp[1024]; 6244229Sdavidn 63130633Srobert strlcpy(pwtmp, getpwpath(_MASTERPASSWD), sizeof(pwtmp)); 6444229Sdavidn 6544229Sdavidn if (pwd_fp != NULL || (pwd_fp = fopen(pwtmp, "r")) != NULL) { 6644229Sdavidn int done = 0; 6744229Sdavidn 6844229Sdavidn static struct passwd pwd; 6944229Sdavidn 7044229Sdavidn while (!done && fgets(pwtmp, sizeof pwtmp, pwd_fp) != NULL) 7144229Sdavidn { 7244229Sdavidn int i, quickout = 0; 7344229Sdavidn char * q; 7444229Sdavidn char * p = strchr(pwtmp, '\n'); 7544229Sdavidn 7644229Sdavidn if (p == NULL) { 7744229Sdavidn while (fgets(pwtmp, sizeof pwtmp, pwd_fp) != NULL && strchr(pwtmp, '\n')==NULL) 7844229Sdavidn ; /* Skip long lines */ 7944229Sdavidn continue; 8044229Sdavidn } 8144229Sdavidn 8244229Sdavidn /* skip comments & empty lines */ 8344229Sdavidn if (*pwtmp =='\n' || *pwtmp == '#') 8444229Sdavidn continue; 8544229Sdavidn 8644229Sdavidn i = 0; 8744229Sdavidn q = p = pwtmp; 8844229Sdavidn bzero(&pwd, sizeof pwd); 8944229Sdavidn while (!quickout && (p = strsep(&q, ":\n")) != NULL) { 9044229Sdavidn switch (i++) 9144229Sdavidn { 9244229Sdavidn case 0: /* username */ 9344229Sdavidn pwd.pw_name = p; 9444229Sdavidn if (nam) { 9544229Sdavidn if (strcmp(nam, p) == 0) 9644229Sdavidn done = 1; 9744229Sdavidn else 9844229Sdavidn quickout = 1; 9944229Sdavidn } 10044229Sdavidn break; 10144229Sdavidn case 1: /* password */ 10244229Sdavidn pwd.pw_passwd = p; 10344229Sdavidn break; 10444229Sdavidn case 2: /* uid */ 10544229Sdavidn pwd.pw_uid = atoi(p); 10644229Sdavidn if (uid != (uid_t)-1) { 10744229Sdavidn if (uid == pwd.pw_uid) 10844229Sdavidn done = 1; 10944229Sdavidn else 11044229Sdavidn quickout = 1; 11144229Sdavidn } 11244229Sdavidn break; 11344229Sdavidn case 3: /* gid */ 11444229Sdavidn pwd.pw_gid = atoi(p); 11544229Sdavidn break; 11644229Sdavidn case 4: /* class */ 11744229Sdavidn if (nam == NULL && uid == (uid_t)-1) 11844229Sdavidn done = 1; 11944229Sdavidn pwd.pw_class = p; 12044229Sdavidn break; 12144229Sdavidn case 5: /* change */ 12244229Sdavidn pwd.pw_change = (time_t)atol(p); 12344229Sdavidn break; 12444229Sdavidn case 6: /* expire */ 12544229Sdavidn pwd.pw_expire = (time_t)atol(p); 12644229Sdavidn break; 12744229Sdavidn case 7: /* gecos */ 12844229Sdavidn pwd.pw_gecos = p; 12944229Sdavidn break; 13044229Sdavidn case 8: /* directory */ 13144229Sdavidn pwd.pw_dir = p; 13244229Sdavidn break; 13344229Sdavidn case 9: /* shell */ 13444229Sdavidn pwd.pw_shell = p; 13544229Sdavidn break; 13644229Sdavidn } 13744229Sdavidn } 13844229Sdavidn } 13944229Sdavidn if (doclose) 14044229Sdavidn vendpwent(); 14144229Sdavidn if (done && pwd.pw_name) { 14244229Sdavidn pw = &pwd; 14344229Sdavidn 14444229Sdavidn #define CKNULL(s) s = s ? s : "" 14544229Sdavidn CKNULL(pwd.pw_passwd); 14644229Sdavidn CKNULL(pwd.pw_class); 14744229Sdavidn CKNULL(pwd.pw_gecos); 14844229Sdavidn CKNULL(pwd.pw_dir); 14944229Sdavidn CKNULL(pwd.pw_shell); 15044229Sdavidn } 15144229Sdavidn } 15244229Sdavidn return pw; 15344229Sdavidn} 15444229Sdavidn 15544229Sdavidnstruct passwd * 15644229Sdavidnvgetpwent(void) 15744229Sdavidn{ 15844229Sdavidn return vnextpwent(NULL, -1, 0); 15944229Sdavidn} 16044229Sdavidn 16144229Sdavidnstruct passwd * 16244229Sdavidnvgetpwuid(uid_t uid) 16344229Sdavidn{ 16444229Sdavidn return vnextpwent(NULL, uid, 1); 16544229Sdavidn} 16644229Sdavidn 16744229Sdavidnstruct passwd * 16844229Sdavidnvgetpwnam(const char * nam) 16944229Sdavidn{ 17044229Sdavidn return vnextpwent(nam, -1, 1); 17144229Sdavidn} 17244229Sdavidn 17344229Sdavidnint vpwdb(char *arg, ...) 17444229Sdavidn{ 17544229Sdavidn arg=arg; 17644229Sdavidn return 0; 17744229Sdavidn} 17844229Sdavidn 17944229Sdavidn 18044229Sdavidn 18144229Sdavidnstatic FILE * grp_fp = NULL; 18244229Sdavidn 18344229Sdavidnvoid 18444229Sdavidnvendgrent(void) 18544229Sdavidn{ 18644229Sdavidn if (grp_fp != NULL) { 18744229Sdavidn fclose(grp_fp); 18844229Sdavidn grp_fp = NULL; 18944229Sdavidn } 19044229Sdavidn} 19144229Sdavidn 19256000SdavidnRET_SETGRENT 19344229Sdavidnvsetgrent(void) 19444229Sdavidn{ 19544229Sdavidn vendgrent(); 19656000Sdavidn#if defined(__FreeBSD__) 19744229Sdavidn return 0; 19856000Sdavidn#endif 19944229Sdavidn} 20044229Sdavidn 20144229Sdavidnstatic struct group * 20244229Sdavidnvnextgrent(char const * nam, gid_t gid, int doclose) 20344229Sdavidn{ 20444229Sdavidn struct group * gr = NULL; 20544229Sdavidn 20644229Sdavidn static char * grtmp = NULL; 20744229Sdavidn static int grlen = 0; 20844229Sdavidn static char ** mems = NULL; 20944229Sdavidn static int memlen = 0; 21044229Sdavidn 21144229Sdavidn extendline(&grtmp, &grlen, MAXPATHLEN); 212130633Srobert strlcpy(grtmp, getgrpath(_GROUP), MAXPATHLEN); 21344229Sdavidn 21444229Sdavidn if (grp_fp != NULL || (grp_fp = fopen(grtmp, "r")) != NULL) { 21544229Sdavidn int done = 0; 21644229Sdavidn 21744229Sdavidn static struct group grp; 21844229Sdavidn 21944229Sdavidn while (!done && fgets(grtmp, grlen, grp_fp) != NULL) 22044229Sdavidn { 22144229Sdavidn int i, quickout = 0; 22244229Sdavidn int mno = 0; 22344229Sdavidn char * q, * p; 22444229Sdavidn char * sep = ":\n"; 22544229Sdavidn 22644229Sdavidn if ((p = strchr(grtmp, '\n')) == NULL) { 22744229Sdavidn int l; 22844229Sdavidn extendline(&grtmp, &grlen, grlen + PWBUFSZ); 22944229Sdavidn l = strlen(grtmp); 23044229Sdavidn if (fgets(grtmp + l, grlen - l, grp_fp) == NULL) 23144229Sdavidn break; /* No newline terminator on last line */ 23244229Sdavidn } 23344229Sdavidn /* Skip comments and empty lines */ 23444229Sdavidn if (*grtmp == '\n' || *grtmp == '#') 23544229Sdavidn continue; 23644229Sdavidn i = 0; 23744229Sdavidn q = p = grtmp; 23844229Sdavidn bzero(&grp, sizeof grp); 23944229Sdavidn extendarray(&mems, &memlen, 200); 24044229Sdavidn while (!quickout && (p = strsep(&q, sep)) != NULL) { 24144229Sdavidn switch (i++) 24244229Sdavidn { 24344229Sdavidn case 0: /* groupname */ 24444229Sdavidn grp.gr_name = p; 24544229Sdavidn if (nam) { 24644229Sdavidn if (strcmp(nam, p) == 0) 24744229Sdavidn done = 1; 24844229Sdavidn else 24944229Sdavidn quickout = 1; 25044229Sdavidn } 25144229Sdavidn break; 25244229Sdavidn case 1: /* password */ 25344229Sdavidn grp.gr_passwd = p; 25444229Sdavidn break; 25544229Sdavidn case 2: /* gid */ 25644229Sdavidn grp.gr_gid = atoi(p); 25744229Sdavidn if (gid != (gid_t)-1) { 25844229Sdavidn if (gid == (gid_t)grp.gr_gid) 25944229Sdavidn done = 1; 26044229Sdavidn else 26144229Sdavidn quickout = 1; 26244229Sdavidn } else if (nam == NULL) 26344229Sdavidn done = 1; 26444229Sdavidn break; 26544229Sdavidn case 3: 26644229Sdavidn q = p; 26744229Sdavidn sep = ",\n"; 26844229Sdavidn break; 26944229Sdavidn default: 27044229Sdavidn if (*p) { 27144229Sdavidn extendarray(&mems, &memlen, mno + 2); 27244229Sdavidn mems[mno++] = p; 27344229Sdavidn } 27444229Sdavidn break; 27544229Sdavidn } 27644229Sdavidn } 27744229Sdavidn grp.gr_mem = mems; 27844229Sdavidn mems[mno] = NULL; 27944229Sdavidn } 28044229Sdavidn if (doclose) 28144229Sdavidn vendgrent(); 28244229Sdavidn if (done && grp.gr_name) { 28344229Sdavidn gr = &grp; 28444229Sdavidn 28544229Sdavidn CKNULL(grp.gr_passwd); 28644229Sdavidn } 28744229Sdavidn } 28844229Sdavidn return gr; 28944229Sdavidn} 29044229Sdavidn 29144229Sdavidnstruct group * 29244229Sdavidnvgetgrent(void) 29344229Sdavidn{ 29444229Sdavidn return vnextgrent(NULL, -1, 0); 29544229Sdavidn} 29644229Sdavidn 29744229Sdavidn 29844229Sdavidnstruct group * 29944229Sdavidnvgetgrgid(gid_t gid) 30044229Sdavidn{ 30144229Sdavidn return vnextgrent(NULL, gid, 1); 30244229Sdavidn} 30344229Sdavidn 30444229Sdavidnstruct group * 30544229Sdavidnvgetgrnam(const char * nam) 30644229Sdavidn{ 30744229Sdavidn return vnextgrent(nam, -1, 1); 30844229Sdavidn} 30944229Sdavidn 31044229Sdavidnint 31144229Sdavidnvgrdb(char *arg, ...) 31244229Sdavidn{ 31344229Sdavidn arg=arg; 31444229Sdavidn return 0; 31544229Sdavidn} 31644229Sdavidn 317