Annotation of embedaddon/sudo/plugins/sudoers/tsgetgrpw.c, revision 1.1.1.2
1.1 misho 1: /*
1.1.1.2 ! misho 2: * Copyright (c) 2005, 2008, 2010-2013
! 3: * Todd C. Miller <Todd.Miller@courtesan.com>
1.1 misho 4: *
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.
8: *
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.
16: */
17:
18: /*
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().
22: */
23:
24: #include <config.h>
25:
26: #include <sys/types.h>
27: #include <stdio.h>
28: #ifdef STDC_HEADERS
29: # include <stdlib.h>
30: # include <stddef.h>
31: #else
32: # ifdef HAVE_STDLIB_H
33: # include <stdlib.h>
34: # endif
35: #endif /* STDC_HEADERS */
36: #ifdef HAVE_STRING_H
37: # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
38: # include <memory.h>
39: # endif
40: # include <string.h>
41: #endif /* HAVE_STRING_H */
42: #ifdef HAVE_STRINGS_H
43: # include <strings.h>
44: #endif /* HAVE_STRINGS_H */
1.1.1.2 ! misho 45: #include <errno.h>
1.1 misho 46: #include <fcntl.h>
47: #include <limits.h>
48:
49: #include "tsgetgrpw.h"
50: #include "sudoers.h"
51:
52: #ifndef LINE_MAX
53: # define LINE_MAX 2048
54: #endif
55:
56: #undef GRMEM_MAX
57: #define GRMEM_MAX 200
58:
1.1.1.2 ! misho 59: #ifndef UID_MAX
! 60: # define UID_MAX 0xffffffffU
! 61: #endif
! 62:
! 63: #ifndef GID_MAX
! 64: # define GID_MAX UID_MAX
! 65: #endif
! 66:
1.1 misho 67: static FILE *pwf;
68: static const char *pwfile = "/etc/passwd";
69: static int pw_stayopen;
70:
71: static FILE *grf;
72: static const char *grfile = "/etc/group";
73: static int gr_stayopen;
74:
75: void setgrfile(const char *);
76: void setgrent(void);
77: void endgrent(void);
78: struct group *getgrent(void);
79: struct group *getgrnam(const char *);
80: struct group *getgrgid(gid_t);
81:
82: void setpwfile(const char *);
83: void setpwent(void);
84: void endpwent(void);
85: struct passwd *getpwent(void);
86: struct passwd *getpwnam(const char *);
87: struct passwd *getpwuid(uid_t);
88:
89: void
90: setpwfile(const char *file)
91: {
92: pwfile = file;
93: if (pwf != NULL)
94: endpwent();
95: }
96:
97: void
98: setpwent(void)
99: {
100: if (pwf == NULL) {
101: pwf = fopen(pwfile, "r");
102: if (pwf != NULL)
103: fcntl(fileno(pwf), F_SETFD, FD_CLOEXEC);
104: } else {
105: rewind(pwf);
106: }
107: pw_stayopen = 1;
108: }
109:
110: void
111: endpwent(void)
112: {
113: if (pwf != NULL) {
114: fclose(pwf);
115: pwf = NULL;
116: }
117: pw_stayopen = 0;
118: }
119:
120: struct passwd *
121: getpwent(void)
122: {
123: static struct passwd pw;
124: static char pwbuf[LINE_MAX];
125: size_t len;
1.1.1.2 ! misho 126: unsigned long id;
! 127: char *cp, *colon, *ep;
1.1 misho 128:
1.1.1.2 ! misho 129: next_entry:
1.1 misho 130: if ((colon = fgets(pwbuf, sizeof(pwbuf), pwf)) == NULL)
131: return NULL;
132:
133: zero_bytes(&pw, sizeof(pw));
134: if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2 ! misho 135: goto next_entry;
1.1 misho 136: *colon++ = '\0';
137: pw.pw_name = cp;
138: if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2 ! misho 139: goto next_entry;
1.1 misho 140: *colon++ = '\0';
141: pw.pw_passwd = cp;
142: if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2 ! misho 143: goto next_entry;
1.1 misho 144: *colon++ = '\0';
1.1.1.2 ! misho 145: id = strtoul(cp, &ep, 10);
! 146: if (*cp == '\0' || *ep != '\0')
! 147: goto next_entry;
! 148: if (id > UID_MAX || (id == ULONG_MAX && errno == ERANGE))
! 149: goto next_entry;
! 150: pw.pw_uid = (uid_t)id;
1.1 misho 151: if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2 ! misho 152: goto next_entry;
1.1 misho 153: *colon++ = '\0';
1.1.1.2 ! misho 154: id = strtoul(cp, &ep, 10);
! 155: if (*cp == '\0' || *ep != '\0')
! 156: goto next_entry;
! 157: if (id > GID_MAX || (id == ULONG_MAX && errno == ERANGE))
! 158: goto next_entry;
! 159: pw.pw_gid = (gid_t)id;
1.1 misho 160: if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2 ! misho 161: goto next_entry;
1.1 misho 162: *colon++ = '\0';
163: pw.pw_gecos = cp;
164: if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2 ! misho 165: goto next_entry;
1.1 misho 166: *colon++ = '\0';
167: pw.pw_dir = cp;
168: pw.pw_shell = colon;
169: len = strlen(colon);
170: if (len > 0 && colon[len - 1] == '\n')
171: colon[len - 1] = '\0';
172: return &pw;
173: }
174:
175: struct passwd *
176: getpwnam(const char *name)
177: {
178: struct passwd *pw;
179:
180: if (pwf == NULL) {
181: if ((pwf = fopen(pwfile, "r")) == NULL)
182: return NULL;
183: fcntl(fileno(pwf), F_SETFD, FD_CLOEXEC);
184: } else {
185: rewind(pwf);
186: }
187: while ((pw = getpwent()) != NULL) {
188: if (strcmp(pw->pw_name, name) == 0)
189: break;
190: }
191: if (!pw_stayopen) {
192: fclose(pwf);
193: pwf = NULL;
194: }
195: return pw;
196: }
197:
198: struct passwd *
199: getpwuid(uid_t uid)
200: {
201: struct passwd *pw;
202:
203: if (pwf == NULL) {
204: if ((pwf = fopen(pwfile, "r")) == NULL)
205: return NULL;
206: fcntl(fileno(pwf), F_SETFD, FD_CLOEXEC);
207: } else {
208: rewind(pwf);
209: }
210: while ((pw = getpwent()) != NULL) {
211: if (pw->pw_uid == uid)
212: break;
213: }
214: if (!pw_stayopen) {
215: fclose(pwf);
216: pwf = NULL;
217: }
218: return pw;
219: }
220:
221: void
222: setgrfile(const char *file)
223: {
224: grfile = file;
225: if (grf != NULL)
226: endgrent();
227: }
228:
229: void
230: setgrent(void)
231: {
232: if (grf == NULL) {
233: grf = fopen(grfile, "r");
234: if (grf != NULL)
235: fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
236: } else {
237: rewind(grf);
238: }
239: gr_stayopen = 1;
240: }
241:
242: void
243: endgrent(void)
244: {
245: if (grf != NULL) {
246: fclose(grf);
247: grf = NULL;
248: }
249: gr_stayopen = 0;
250: }
251:
252: struct group *
253: getgrent(void)
254: {
255: static struct group gr;
256: static char grbuf[LINE_MAX], *gr_mem[GRMEM_MAX+1];
257: size_t len;
1.1.1.2 ! misho 258: unsigned long id;
! 259: char *cp, *colon, *ep;
1.1 misho 260: int n;
261:
1.1.1.2 ! misho 262: next_entry:
1.1 misho 263: if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL)
264: return NULL;
265:
266: zero_bytes(&gr, sizeof(gr));
267: if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2 ! misho 268: goto next_entry;
1.1 misho 269: *colon++ = '\0';
270: gr.gr_name = cp;
271: if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2 ! misho 272: goto next_entry;
1.1 misho 273: *colon++ = '\0';
274: gr.gr_passwd = cp;
275: if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2 ! misho 276: goto next_entry;
1.1 misho 277: *colon++ = '\0';
1.1.1.2 ! misho 278: id = strtoul(cp, &ep, 10);
! 279: if (*cp == '\0' || *ep != '\0')
! 280: goto next_entry;
! 281: if (id > GID_MAX || (id == ULONG_MAX && errno == ERANGE))
! 282: goto next_entry;
! 283: gr.gr_gid = (gid_t)id;
1.1 misho 284: len = strlen(colon);
285: if (len > 0 && colon[len - 1] == '\n')
286: colon[len - 1] = '\0';
287: if (*colon != '\0') {
288: gr.gr_mem = gr_mem;
289: cp = strtok(colon, ",");
290: for (n = 0; cp != NULL && n < GRMEM_MAX; n++) {
291: gr.gr_mem[n] = cp;
292: cp = strtok(NULL, ",");
293: }
294: gr.gr_mem[n++] = NULL;
295: } else
296: gr.gr_mem = NULL;
297: return &gr;
298: }
299:
300: struct group *
301: getgrnam(const char *name)
302: {
303: struct group *gr;
304:
305: if (grf == NULL) {
306: if ((grf = fopen(grfile, "r")) == NULL)
307: return NULL;
308: fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
309: } else {
310: rewind(grf);
311: }
312: while ((gr = getgrent()) != NULL) {
313: if (strcmp(gr->gr_name, name) == 0)
314: break;
315: }
316: if (!gr_stayopen) {
317: fclose(grf);
318: grf = NULL;
319: }
320: return gr;
321: }
322:
323: struct group *
324: getgrgid(gid_t gid)
325: {
326: struct group *gr;
327:
328: if (grf == NULL) {
329: if ((grf = fopen(grfile, "r")) == NULL)
330: return NULL;
331: fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
332: } else {
333: rewind(grf);
334: }
335: while ((gr = getgrent()) != NULL) {
336: if (gr->gr_gid == gid)
337: break;
338: }
339: if (!gr_stayopen) {
340: fclose(grf);
341: grf = NULL;
342: }
343: return gr;
344: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>