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