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