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
33244743Sbapt#include <pwd.h>
34244743Sbapt#include <grp.h>
35244743Sbapt#include <libutil.h>
36244743Sbapt#define _WITH_GETLINE
3744229Sdavidn#include <stdio.h>
3844229Sdavidn#include <string.h>
3944229Sdavidn#include <stdlib.h>
4044229Sdavidn#include <sys/param.h>
4144229Sdavidn
4244229Sdavidn#include "pwupd.h"
4344229Sdavidn
4444229Sdavidnstatic FILE * pwd_fp = NULL;
4544229Sdavidn
4644229Sdavidnvoid
4744229Sdavidnvendpwent(void)
4844229Sdavidn{
4944229Sdavidn	if (pwd_fp != NULL) {
5044229Sdavidn		fclose(pwd_fp);
5144229Sdavidn		pwd_fp = NULL;
5244229Sdavidn	}
5344229Sdavidn}
5444229Sdavidn
5544229Sdavidnvoid
5644229Sdavidnvsetpwent(void)
5744229Sdavidn{
5844229Sdavidn	vendpwent();
5944229Sdavidn}
6044229Sdavidn
6144229Sdavidnstatic struct passwd *
62244743Sbaptvnextpwent(char const *nam, uid_t uid, int doclose)
6344229Sdavidn{
64244743Sbapt	struct passwd *pw;
65244743Sbapt	char *line;
66244743Sbapt	size_t linecap;
67244743Sbapt	ssize_t linelen;
6844229Sdavidn
69244743Sbapt	pw = NULL;
70244743Sbapt	line = NULL;
71244743Sbapt	linecap = 0;
72244743Sbapt	linelen = 0;
7344229Sdavidn
74244743Sbapt	if (pwd_fp != NULL || (pwd_fp = fopen(getpwpath(_MASTERPASSWD), "r")) != NULL) {
75244743Sbapt		while ((linelen = getline(&line, &linecap, pwd_fp)) > 0) {
76244743Sbapt			/* Skip comments and empty lines */
77244743Sbapt			if (*line == '\n' || *line == '#')
7844229Sdavidn				continue;
79244743Sbapt			/* trim latest \n */
80244743Sbapt			if (line[linelen - 1 ] == '\n')
81244743Sbapt				line[linelen - 1] = '\0';
82244743Sbapt			pw = pw_scan(line, PWSCAN_MASTER);
83244743Sbapt			if (uid != (uid_t)-1) {
84244743Sbapt				if (uid == pw->pw_uid)
85244743Sbapt					break;
86244743Sbapt			} else if (nam != NULL) {
87244743Sbapt				if (strcmp(nam, pw->pw_name) == 0)
88244743Sbapt					break;
89244743Sbapt			} else
90244743Sbapt				break;
91244743Sbapt			free(pw);
92244743Sbapt			pw = NULL;
93244743Sbapt		}
9444229Sdavidn		if (doclose)
9544229Sdavidn			vendpwent();
96244743Sbapt	}
97244743Sbapt	free(line);
9844229Sdavidn
99244743Sbapt	return (pw);
10044229Sdavidn}
10144229Sdavidn
10244229Sdavidnstruct passwd *
10344229Sdavidnvgetpwent(void)
10444229Sdavidn{
10544229Sdavidn  return vnextpwent(NULL, -1, 0);
10644229Sdavidn}
10744229Sdavidn
10844229Sdavidnstruct passwd *
10944229Sdavidnvgetpwuid(uid_t uid)
11044229Sdavidn{
11144229Sdavidn  return vnextpwent(NULL, uid, 1);
11244229Sdavidn}
11344229Sdavidn
11444229Sdavidnstruct passwd *
11544229Sdavidnvgetpwnam(const char * nam)
11644229Sdavidn{
11744229Sdavidn  return vnextpwent(nam, -1, 1);
11844229Sdavidn}
11944229Sdavidn
12044229Sdavidn
12144229Sdavidnstatic FILE * grp_fp = NULL;
12244229Sdavidn
12344229Sdavidnvoid
12444229Sdavidnvendgrent(void)
12544229Sdavidn{
12644229Sdavidn	if (grp_fp != NULL) {
12744229Sdavidn		fclose(grp_fp);
12844229Sdavidn		grp_fp = NULL;
12944229Sdavidn	}
13044229Sdavidn}
13144229Sdavidn
13256000SdavidnRET_SETGRENT
13344229Sdavidnvsetgrent(void)
13444229Sdavidn{
13544229Sdavidn	vendgrent();
13656000Sdavidn#if defined(__FreeBSD__)
13744229Sdavidn	return 0;
13856000Sdavidn#endif
13944229Sdavidn}
14044229Sdavidn
14144229Sdavidnstatic struct group *
142244743Sbaptvnextgrent(char const *nam, gid_t gid, int doclose)
14344229Sdavidn{
144244743Sbapt	struct group *gr;
145244743Sbapt	char *line;
146244743Sbapt	size_t linecap;
147244743Sbapt	ssize_t linelen;
14844229Sdavidn
149244743Sbapt	gr = NULL;
150244743Sbapt	line = NULL;
151244743Sbapt	linecap = 0;
152244743Sbapt	linelen = 0;
15344229Sdavidn
154244743Sbapt	if (grp_fp != NULL || (grp_fp = fopen(getgrpath(_GROUP), "r")) != NULL) {
155244743Sbapt		while ((linelen = getline(&line, &linecap, grp_fp)) > 0) {
15644229Sdavidn			/* Skip comments and empty lines */
157244743Sbapt			if (*line == '\n' || *line == '#')
15844229Sdavidn				continue;
159244743Sbapt			/* trim latest \n */
160244743Sbapt			if (line[linelen - 1 ] == '\n')
161244743Sbapt				line[linelen - 1] = '\0';
162244743Sbapt			gr = gr_scan(line);
163244743Sbapt			if (gid != (gid_t)-1) {
164244743Sbapt				if (gid == gr->gr_gid)
16544229Sdavidn					break;
166244743Sbapt			} else if (nam != NULL) {
167244743Sbapt				if (strcmp(nam, gr->gr_name) == 0)
16844229Sdavidn					break;
169244743Sbapt			} else
170244743Sbapt				break;
171244743Sbapt			free(gr);
172244743Sbapt			gr = NULL;
173244743Sbapt		}
17444229Sdavidn		if (doclose)
17544229Sdavidn			vendgrent();
176244743Sbapt	}
177244743Sbapt	free(line);
17844229Sdavidn
179244743Sbapt	return (gr);
18044229Sdavidn}
18144229Sdavidn
18244229Sdavidnstruct group *
18344229Sdavidnvgetgrent(void)
18444229Sdavidn{
18544229Sdavidn  return vnextgrent(NULL, -1, 0);
18644229Sdavidn}
18744229Sdavidn
18844229Sdavidn
18944229Sdavidnstruct group *
19044229Sdavidnvgetgrgid(gid_t gid)
19144229Sdavidn{
19244229Sdavidn  return vnextgrent(NULL, gid, 1);
19344229Sdavidn}
19444229Sdavidn
19544229Sdavidnstruct group *
19644229Sdavidnvgetgrnam(const char * nam)
19744229Sdavidn{
19844229Sdavidn  return vnextgrent(nam, -1, 1);
19944229Sdavidn}
20044229Sdavidn
201