2 * Copyright (c) 2005, 2008, 2010-2013
3 * Todd C. Miller <Todd.Miller@courtesan.com>
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 * Trivial replacements for the libc get{gr,pw}{uid,nam}() routines
20 * for use by testsudoers in the sudo test harness.
21 * We need our own since many platforms don't provide set{pw,gr}file().
26 #include <sys/types.h>
35 #endif /* STDC_HEADERS */
37 # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
41 #endif /* HAVE_STRING_H */
44 #endif /* HAVE_STRINGS_H */
49 #include "tsgetgrpw.h"
53 # define LINE_MAX 2048
60 # define UID_MAX 0xffffffffU
64 # define GID_MAX UID_MAX
68 static const char *pwfile = "/etc/passwd";
69 static int pw_stayopen;
72 static const char *grfile = "/etc/group";
73 static int gr_stayopen;
75 void setgrfile(const char *);
78 struct group *getgrent(void);
79 struct group *getgrnam(const char *);
80 struct group *getgrgid(gid_t);
82 void setpwfile(const char *);
85 struct passwd *getpwent(void);
86 struct passwd *getpwnam(const char *);
87 struct passwd *getpwuid(uid_t);
90 setpwfile(const char *file)
101 pwf = fopen(pwfile, "r");
103 fcntl(fileno(pwf), F_SETFD, FD_CLOEXEC);
123 static struct passwd pw;
124 static char pwbuf[LINE_MAX];
127 char *cp, *colon, *ep;
130 if ((colon = fgets(pwbuf, sizeof(pwbuf), pwf)) == NULL)
133 zero_bytes(&pw, sizeof(pw));
134 if ((colon = strchr(cp = colon, ':')) == NULL)
138 if ((colon = strchr(cp = colon, ':')) == NULL)
142 if ((colon = strchr(cp = colon, ':')) == NULL)
145 id = strtoul(cp, &ep, 10);
146 if (*cp == '\0' || *ep != '\0')
148 if (id > UID_MAX || (id == ULONG_MAX && errno == ERANGE))
150 pw.pw_uid = (uid_t)id;
151 if ((colon = strchr(cp = colon, ':')) == NULL)
154 id = strtoul(cp, &ep, 10);
155 if (*cp == '\0' || *ep != '\0')
157 if (id > GID_MAX || (id == ULONG_MAX && errno == ERANGE))
159 pw.pw_gid = (gid_t)id;
160 if ((colon = strchr(cp = colon, ':')) == NULL)
164 if ((colon = strchr(cp = colon, ':')) == NULL)
170 if (len > 0 && colon[len - 1] == '\n')
171 colon[len - 1] = '\0';
176 getpwnam(const char *name)
181 if ((pwf = fopen(pwfile, "r")) == NULL)
183 fcntl(fileno(pwf), F_SETFD, FD_CLOEXEC);
187 while ((pw = getpwent()) != NULL) {
188 if (strcmp(pw->pw_name, name) == 0)
204 if ((pwf = fopen(pwfile, "r")) == NULL)
206 fcntl(fileno(pwf), F_SETFD, FD_CLOEXEC);
210 while ((pw = getpwent()) != NULL) {
211 if (pw->pw_uid == uid)
222 setgrfile(const char *file)
233 grf = fopen(grfile, "r");
235 fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
255 static struct group gr;
256 static char grbuf[LINE_MAX], *gr_mem[GRMEM_MAX+1];
259 char *cp, *colon, *ep;
263 if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL)
266 zero_bytes(&gr, sizeof(gr));
267 if ((colon = strchr(cp = colon, ':')) == NULL)
271 if ((colon = strchr(cp = colon, ':')) == NULL)
275 if ((colon = strchr(cp = colon, ':')) == NULL)
278 id = strtoul(cp, &ep, 10);
279 if (*cp == '\0' || *ep != '\0')
281 if (id > GID_MAX || (id == ULONG_MAX && errno == ERANGE))
283 gr.gr_gid = (gid_t)id;
285 if (len > 0 && colon[len - 1] == '\n')
286 colon[len - 1] = '\0';
287 if (*colon != '\0') {
289 cp = strtok(colon, ",");
290 for (n = 0; cp != NULL && n < GRMEM_MAX; n++) {
292 cp = strtok(NULL, ",");
294 gr.gr_mem[n++] = NULL;
301 getgrnam(const char *name)
306 if ((grf = fopen(grfile, "r")) == NULL)
308 fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
312 while ((gr = getgrent()) != NULL) {
313 if (strcmp(gr->gr_name, name) == 0)
329 if ((grf = fopen(grfile, "r")) == NULL)
331 fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
335 while ((gr = getgrent()) != NULL) {
336 if (gr->gr_gid == gid)