pw_vpw.c revision 292965
11638Srgrimes/*-
21638Srgrimes * Copyright (C) 1996
31638Srgrimes *	David L. Nugent.  All rights reserved.
41638Srgrimes *
51638Srgrimes * Redistribution and use in source and binary forms, with or without
61638Srgrimes * modification, are permitted provided that the following conditions
71638Srgrimes * are met:
81638Srgrimes * 1. Redistributions of source code must retain the above copyright
91638Srgrimes *    notice, this list of conditions and the following disclaimer.
101638Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111638Srgrimes *    notice, this list of conditions and the following disclaimer in the
121638Srgrimes *    documentation and/or other materials provided with the distribution.
131638Srgrimes *
141638Srgrimes * THIS SOFTWARE IS PROVIDED BY DAVID L. NUGENT AND CONTRIBUTORS ``AS IS'' AND
151638Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
161638Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
171638Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL DAVID L. NUGENT OR CONTRIBUTORS BE LIABLE
181638Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
191638Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
201638Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
211638Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
221638Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
231638Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
241638Srgrimes * SUCH DAMAGE.
251638Srgrimes *
261638Srgrimes */
271638Srgrimes
281638Srgrimes#ifndef lint
291638Srgrimesstatic const char rcsid[] =
301638Srgrimes  "$FreeBSD: stable/10/usr.sbin/pw/pw_vpw.c 292965 2015-12-30 23:25:45Z bapt $";
311638Srgrimes#endif /* not lint */
321638Srgrimes
3350476Speter#include <pwd.h>
341638Srgrimes#include <grp.h>
35230577Sglebius#include <libutil.h>
361638Srgrimes#define _WITH_GETLINE
3779538Sru#include <stdio.h>
381638Srgrimes#include <string.h>
391638Srgrimes#include <stdlib.h>
401638Srgrimes#include <sys/param.h>
411638Srgrimes#include <err.h>
4284306Sru
4384306Sru#include "pwupd.h"
4484306Sru
4584306Srustatic FILE * pwd_fp = NULL;
4684306Sru
471638Srgrimesvoid
481638Srgrimesvendpwent(void)
491638Srgrimes{
501638Srgrimes	if (pwd_fp != NULL) {
511638Srgrimes		fclose(pwd_fp);
521638Srgrimes		pwd_fp = NULL;
531638Srgrimes	}
541638Srgrimes}
551638Srgrimes
561638Srgrimesvoid
571638Srgrimesvsetpwent(void)
581638Srgrimes{
591638Srgrimes	vendpwent();
601638Srgrimes}
611638Srgrimes
62117011Srustatic struct passwd *
63117011Sruvnextpwent(char const *nam, uid_t uid, int doclose)
6479727Sschweikh{
65117011Sru	struct passwd *pw;
66117011Sru	char *line;
671638Srgrimes	size_t linecap;
68117011Sru	ssize_t linelen;
69117011Sru
701638Srgrimes	pw = NULL;
71117011Sru	line = NULL;
72117011Sru	linecap = 0;
73117011Sru
7479727Sschweikh	if (pwd_fp != NULL || (pwd_fp = fopen(getpwpath(_MASTERPASSWD), "r")) != NULL) {
751638Srgrimes		while ((linelen = getline(&line, &linecap, pwd_fp)) > 0) {
761638Srgrimes			/* Skip comments and empty lines */
771638Srgrimes			if (*line == '\n' || *line == '#')
781638Srgrimes				continue;
791638Srgrimes			/* trim latest \n */
801638Srgrimes			if (line[linelen - 1 ] == '\n')
811638Srgrimes				line[linelen - 1] = '\0';
821638Srgrimes			pw = pw_scan(line, PWSCAN_MASTER);
831638Srgrimes			if (pw == NULL)
841638Srgrimes				errx(EXIT_FAILURE, "Invalid user entry in '%s':"
85117011Sru				    " '%s'", getpwpath(_MASTERPASSWD), line);
86117011Sru			if (uid != (uid_t)-1) {
871638Srgrimes				if (uid == pw->pw_uid)
881638Srgrimes					break;
89117011Sru			} else if (nam != NULL) {
90117011Sru				if (strcmp(nam, pw->pw_name) == 0)
911638Srgrimes					break;
921638Srgrimes			} else
931638Srgrimes				break;
941638Srgrimes			free(pw);
951638Srgrimes			pw = NULL;
961638Srgrimes		}
971638Srgrimes		if (doclose)
98117011Sru			vendpwent();
99117011Sru	}
1001638Srgrimes	free(line);
1011638Srgrimes
1021638Srgrimes	return (pw);
1031638Srgrimes}
1041638Srgrimes
1051638Srgrimesstruct passwd *
1061638Srgrimesvgetpwent(void)
1071638Srgrimes{
1081638Srgrimes  return vnextpwent(NULL, -1, 0);
1091638Srgrimes}
1101638Srgrimes
1111638Srgrimesstruct passwd *
1121638Srgrimesvgetpwuid(uid_t uid)
1131638Srgrimes{
1141638Srgrimes  return vnextpwent(NULL, uid, 1);
1151638Srgrimes}
1161638Srgrimes
1171638Srgrimesstruct passwd *
1181638Srgrimesvgetpwnam(const char * nam)
1191638Srgrimes{
1201638Srgrimes  return vnextpwent(nam, -1, 1);
1211638Srgrimes}
1221638Srgrimes
1231638Srgrimes
1241638Srgrimesstatic FILE * grp_fp = NULL;
1251638Srgrimes
1261638Srgrimesvoid
1271638Srgrimesvendgrent(void)
1281638Srgrimes{
1291638Srgrimes	if (grp_fp != NULL) {
1301638Srgrimes		fclose(grp_fp);
131117011Sru		grp_fp = NULL;
132117011Sru	}
13357676Ssheldonh}
13457676Ssheldonh
1351638SrgrimesRET_SETGRENT
1361638Srgrimesvsetgrent(void)
1371638Srgrimes{
1381638Srgrimes	vendgrent();
13989672Sschweikh#if defined(__FreeBSD__)
14089672Sschweikh	return 0;
14189672Sschweikh#endif
14289672Sschweikh}
1431638Srgrimes
1441638Srgrimesstatic struct group *
1451638Srgrimesvnextgrent(char const *nam, gid_t gid, int doclose)
1461638Srgrimes{
14779216Sru	struct group *gr;
14885064Stom	char *line;
1491638Srgrimes	size_t linecap;
1501638Srgrimes	ssize_t linelen;
15179216Sru
1521638Srgrimes	gr = NULL;
1531638Srgrimes	line = NULL;
1541638Srgrimes	linecap = 0;
1551638Srgrimes
1561638Srgrimes	if (grp_fp != NULL || (grp_fp = fopen(getgrpath(_GROUP), "r")) != NULL) {
1571638Srgrimes		while ((linelen = getline(&line, &linecap, grp_fp)) > 0) {
1581638Srgrimes			/* Skip comments and empty lines */
1591638Srgrimes			if (*line == '\n' || *line == '#')
1601638Srgrimes				continue;
1611638Srgrimes			/* trim latest \n */
1621638Srgrimes			if (line[linelen - 1 ] == '\n')
16392577Sru				line[linelen - 1] = '\0';
1641638Srgrimes			gr = gr_scan(line);
1651638Srgrimes			if (gr == NULL)
1661638Srgrimes				errx(EXIT_FAILURE, "Invalid group entry in '%s':"
1671638Srgrimes				    " '%s'", getgrpath(_GROUP), line);
1681638Srgrimes			if (gid != (gid_t)-1) {
1691638Srgrimes				if (gid == gr->gr_gid)
1701638Srgrimes					break;
1711638Srgrimes			} else if (nam != NULL) {
1721638Srgrimes				if (strcmp(nam, gr->gr_name) == 0)
1731638Srgrimes					break;
1741638Srgrimes			} else
1751638Srgrimes				break;
1761638Srgrimes			free(gr);
1771638Srgrimes			gr = NULL;
1781638Srgrimes		}
1791638Srgrimes		if (doclose)
180117011Sru			vendgrent();
181117011Sru	}
1821638Srgrimes	free(line);
1831638Srgrimes
1841638Srgrimes	return (gr);
1851638Srgrimes}
18679727Sschweikh
18715135Smppstruct group *
1881638Srgrimesvgetgrent(void)
1891638Srgrimes{
19015135Smpp  return vnextgrent(NULL, -1, 0);
1911638Srgrimes}
1921638Srgrimes
1931638Srgrimes
19479727Sschweikhstruct group *
1951638Srgrimesvgetgrgid(gid_t gid)
19679216Sru{
197117011Sru  return vnextgrent(NULL, gid, 1);
198117011Sru}
1991638Srgrimes
2001638Srgrimesstruct group *
2011638Srgrimesvgetgrnam(const char * nam)
20211692Storstenb{
2031638Srgrimes  return vnextgrent(nam, -1, 1);
2041638Srgrimes}
2051638Srgrimes
2061638Srgrimes