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