pw_vpw.c revision 330449
1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (C) 1996 5 * David L. Nugent. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY DAVID L. NUGENT AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL DAVID L. NUGENT OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 */ 29 30#ifndef lint 31static const char rcsid[] = 32 "$FreeBSD: stable/11/usr.sbin/pw/pw_vpw.c 330449 2018-03-05 07:26:05Z eadler $"; 33#endif /* not lint */ 34 35#include <pwd.h> 36#include <grp.h> 37#include <libutil.h> 38#define _WITH_GETLINE 39#include <stdio.h> 40#include <string.h> 41#include <stdlib.h> 42#include <err.h> 43 44#include "pwupd.h" 45 46static FILE * pwd_fp = NULL; 47 48void 49vendpwent(void) 50{ 51 if (pwd_fp != NULL) { 52 fclose(pwd_fp); 53 pwd_fp = NULL; 54 } 55} 56 57void 58vsetpwent(void) 59{ 60 vendpwent(); 61} 62 63static struct passwd * 64vnextpwent(char const *nam, uid_t uid, int doclose) 65{ 66 struct passwd *pw; 67 char *line; 68 size_t linecap; 69 ssize_t linelen; 70 71 pw = NULL; 72 line = NULL; 73 linecap = 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 157 if (grp_fp != NULL || (grp_fp = fopen(getgrpath(_GROUP), "r")) != NULL) { 158 while ((linelen = getline(&line, &linecap, grp_fp)) > 0) { 159 /* Skip comments and empty lines */ 160 if (*line == '\n' || *line == '#') 161 continue; 162 /* trim latest \n */ 163 if (line[linelen - 1 ] == '\n') 164 line[linelen - 1] = '\0'; 165 gr = gr_scan(line); 166 if (gr == NULL) 167 errx(EXIT_FAILURE, "Invalid group entry in '%s':" 168 " '%s'", getgrpath(_GROUP), line); 169 if (gid != (gid_t)-1) { 170 if (gid == gr->gr_gid) 171 break; 172 } else if (nam != NULL) { 173 if (strcmp(nam, gr->gr_name) == 0) 174 break; 175 } else 176 break; 177 free(gr); 178 gr = NULL; 179 } 180 if (doclose) 181 vendgrent(); 182 } 183 free(line); 184 185 return (gr); 186} 187 188struct group * 189vgetgrent(void) 190{ 191 return vnextgrent(NULL, -1, 0); 192} 193 194 195struct group * 196vgetgrgid(gid_t gid) 197{ 198 return vnextgrent(NULL, gid, 1); 199} 200 201struct group * 202vgetgrnam(const char * nam) 203{ 204 return vnextgrent(nam, -1, 1); 205} 206 207