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