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 */
27
28#ifndef lint
29static const char rcsid[] =
30  "$FreeBSD$";
31#endif /* not lint */
32
33#include <pwd.h>
34#include <grp.h>
35#include <libutil.h>
36#define _WITH_GETLINE
37#include <stdio.h>
38#include <string.h>
39#include <stdlib.h>
40#include <sys/param.h>
41
42#include "pwupd.h"
43
44static FILE * pwd_fp = NULL;
45
46void
47vendpwent(void)
48{
49	if (pwd_fp != NULL) {
50		fclose(pwd_fp);
51		pwd_fp = NULL;
52	}
53}
54
55void
56vsetpwent(void)
57{
58	vendpwent();
59}
60
61static struct passwd *
62vnextpwent(char const *nam, uid_t uid, int doclose)
63{
64	struct passwd *pw;
65	char *line;
66	size_t linecap;
67	ssize_t linelen;
68
69	pw = NULL;
70	line = NULL;
71	linecap = 0;
72	linelen = 0;
73
74	if (pwd_fp != NULL || (pwd_fp = fopen(getpwpath(_MASTERPASSWD), "r")) != NULL) {
75		while ((linelen = getline(&line, &linecap, pwd_fp)) > 0) {
76			/* Skip comments and empty lines */
77			if (*line == '\n' || *line == '#')
78				continue;
79			/* trim latest \n */
80			if (line[linelen - 1 ] == '\n')
81				line[linelen - 1] = '\0';
82			pw = pw_scan(line, PWSCAN_MASTER);
83			if (uid != (uid_t)-1) {
84				if (uid == pw->pw_uid)
85					break;
86			} else if (nam != NULL) {
87				if (strcmp(nam, pw->pw_name) == 0)
88					break;
89			} else
90				break;
91			free(pw);
92			pw = NULL;
93		}
94		if (doclose)
95			vendpwent();
96	}
97	free(line);
98
99	return (pw);
100}
101
102struct passwd *
103vgetpwent(void)
104{
105  return vnextpwent(NULL, -1, 0);
106}
107
108struct passwd *
109vgetpwuid(uid_t uid)
110{
111  return vnextpwent(NULL, uid, 1);
112}
113
114struct passwd *
115vgetpwnam(const char * nam)
116{
117  return vnextpwent(nam, -1, 1);
118}
119
120
121static FILE * grp_fp = NULL;
122
123void
124vendgrent(void)
125{
126	if (grp_fp != NULL) {
127		fclose(grp_fp);
128		grp_fp = NULL;
129	}
130}
131
132RET_SETGRENT
133vsetgrent(void)
134{
135	vendgrent();
136#if defined(__FreeBSD__)
137	return 0;
138#endif
139}
140
141static struct group *
142vnextgrent(char const *nam, gid_t gid, int doclose)
143{
144	struct group *gr;
145	char *line;
146	size_t linecap;
147	ssize_t linelen;
148
149	gr = NULL;
150	line = NULL;
151	linecap = 0;
152	linelen = 0;
153
154	if (grp_fp != NULL || (grp_fp = fopen(getgrpath(_GROUP), "r")) != NULL) {
155		while ((linelen = getline(&line, &linecap, grp_fp)) > 0) {
156			/* Skip comments and empty lines */
157			if (*line == '\n' || *line == '#')
158				continue;
159			/* trim latest \n */
160			if (line[linelen - 1 ] == '\n')
161				line[linelen - 1] = '\0';
162			gr = gr_scan(line);
163			if (gid != (gid_t)-1) {
164				if (gid == gr->gr_gid)
165					break;
166			} else if (nam != NULL) {
167				if (strcmp(nam, gr->gr_name) == 0)
168					break;
169			} else
170				break;
171			free(gr);
172			gr = NULL;
173		}
174		if (doclose)
175			vendgrent();
176	}
177	free(line);
178
179	return (gr);
180}
181
182struct group *
183vgetgrent(void)
184{
185  return vnextgrent(NULL, -1, 0);
186}
187
188
189struct group *
190vgetgrgid(gid_t gid)
191{
192  return vnextgrent(NULL, gid, 1);
193}
194
195struct group *
196vgetgrnam(const char * nam)
197{
198  return vnextgrent(nam, -1, 1);
199}
200
201