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