Annotation of embedaddon/sudo/plugins/sudoers/tsgetgrpw.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (c) 2005, 2008, 2010-2011 Todd C. Miller <Todd.Miller@courtesan.com>
3: *
4: * Permission to use, copy, modify, and distribute this software for any
5: * purpose with or without fee is hereby granted, provided that the above
6: * copyright notice and this permission notice appear in all copies.
7: *
8: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15: */
16:
17: /*
18: * Trivial replacements for the libc get{gr,pw}{uid,nam}() routines
19: * for use by testsudoers in the sudo test harness.
20: * We need our own since many platforms don't provide set{pw,gr}file().
21: */
22:
23: #include <config.h>
24:
25: #include <sys/types.h>
26: #include <sys/param.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 */
45: #include <fcntl.h>
46: #include <limits.h>
47:
48: #include "tsgetgrpw.h"
49: #include "sudoers.h"
50:
51: #ifndef LINE_MAX
52: # define LINE_MAX 2048
53: #endif
54:
55: #undef GRMEM_MAX
56: #define GRMEM_MAX 200
57:
58: static FILE *pwf;
59: static const char *pwfile = "/etc/passwd";
60: static int pw_stayopen;
61:
62: static FILE *grf;
63: static const char *grfile = "/etc/group";
64: static int gr_stayopen;
65:
66: void setgrfile(const char *);
67: void setgrent(void);
68: void endgrent(void);
69: struct group *getgrent(void);
70: struct group *getgrnam(const char *);
71: struct group *getgrgid(gid_t);
72:
73: void setpwfile(const char *);
74: void setpwent(void);
75: void endpwent(void);
76: struct passwd *getpwent(void);
77: struct passwd *getpwnam(const char *);
78: struct passwd *getpwuid(uid_t);
79:
80: void
81: setpwfile(const char *file)
82: {
83: pwfile = file;
84: if (pwf != NULL)
85: endpwent();
86: }
87:
88: void
89: setpwent(void)
90: {
91: if (pwf == NULL) {
92: pwf = fopen(pwfile, "r");
93: if (pwf != NULL)
94: fcntl(fileno(pwf), F_SETFD, FD_CLOEXEC);
95: } else {
96: rewind(pwf);
97: }
98: pw_stayopen = 1;
99: }
100:
101: void
102: endpwent(void)
103: {
104: if (pwf != NULL) {
105: fclose(pwf);
106: pwf = NULL;
107: }
108: pw_stayopen = 0;
109: }
110:
111: struct passwd *
112: getpwent(void)
113: {
114: static struct passwd pw;
115: static char pwbuf[LINE_MAX];
116: size_t len;
117: char *cp, *colon;
118:
119: if ((colon = fgets(pwbuf, sizeof(pwbuf), pwf)) == NULL)
120: return NULL;
121:
122: zero_bytes(&pw, sizeof(pw));
123: if ((colon = strchr(cp = colon, ':')) == NULL)
124: return NULL;
125: *colon++ = '\0';
126: pw.pw_name = cp;
127: if ((colon = strchr(cp = colon, ':')) == NULL)
128: return NULL;
129: *colon++ = '\0';
130: pw.pw_passwd = cp;
131: if ((colon = strchr(cp = colon, ':')) == NULL)
132: return NULL;
133: *colon++ = '\0';
134: pw.pw_uid = atoi(cp);
135: if ((colon = strchr(cp = colon, ':')) == NULL)
136: return NULL;
137: *colon++ = '\0';
138: pw.pw_gid = atoi(cp);
139: if ((colon = strchr(cp = colon, ':')) == NULL)
140: return NULL;
141: *colon++ = '\0';
142: pw.pw_gecos = cp;
143: if ((colon = strchr(cp = colon, ':')) == NULL)
144: return NULL;
145: *colon++ = '\0';
146: pw.pw_dir = cp;
147: pw.pw_shell = colon;
148: len = strlen(colon);
149: if (len > 0 && colon[len - 1] == '\n')
150: colon[len - 1] = '\0';
151: return &pw;
152: }
153:
154: struct passwd *
155: getpwnam(const char *name)
156: {
157: struct passwd *pw;
158:
159: if (pwf == NULL) {
160: if ((pwf = fopen(pwfile, "r")) == NULL)
161: return NULL;
162: fcntl(fileno(pwf), F_SETFD, FD_CLOEXEC);
163: } else {
164: rewind(pwf);
165: }
166: while ((pw = getpwent()) != NULL) {
167: if (strcmp(pw->pw_name, name) == 0)
168: break;
169: }
170: if (!pw_stayopen) {
171: fclose(pwf);
172: pwf = NULL;
173: }
174: return pw;
175: }
176:
177: struct passwd *
178: getpwuid(uid_t uid)
179: {
180: struct passwd *pw;
181:
182: if (pwf == NULL) {
183: if ((pwf = fopen(pwfile, "r")) == NULL)
184: return NULL;
185: fcntl(fileno(pwf), F_SETFD, FD_CLOEXEC);
186: } else {
187: rewind(pwf);
188: }
189: while ((pw = getpwent()) != NULL) {
190: if (pw->pw_uid == uid)
191: break;
192: }
193: if (!pw_stayopen) {
194: fclose(pwf);
195: pwf = NULL;
196: }
197: return pw;
198: }
199:
200: void
201: setgrfile(const char *file)
202: {
203: grfile = file;
204: if (grf != NULL)
205: endgrent();
206: }
207:
208: void
209: setgrent(void)
210: {
211: if (grf == NULL) {
212: grf = fopen(grfile, "r");
213: if (grf != NULL)
214: fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
215: } else {
216: rewind(grf);
217: }
218: gr_stayopen = 1;
219: }
220:
221: void
222: endgrent(void)
223: {
224: if (grf != NULL) {
225: fclose(grf);
226: grf = NULL;
227: }
228: gr_stayopen = 0;
229: }
230:
231: struct group *
232: getgrent(void)
233: {
234: static struct group gr;
235: static char grbuf[LINE_MAX], *gr_mem[GRMEM_MAX+1];
236: size_t len;
237: char *cp, *colon;
238: int n;
239:
240: if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL)
241: return NULL;
242:
243: zero_bytes(&gr, sizeof(gr));
244: if ((colon = strchr(cp = colon, ':')) == NULL)
245: return NULL;
246: *colon++ = '\0';
247: gr.gr_name = cp;
248: if ((colon = strchr(cp = colon, ':')) == NULL)
249: return NULL;
250: *colon++ = '\0';
251: gr.gr_passwd = cp;
252: if ((colon = strchr(cp = colon, ':')) == NULL)
253: return NULL;
254: *colon++ = '\0';
255: gr.gr_gid = atoi(cp);
256: len = strlen(colon);
257: if (len > 0 && colon[len - 1] == '\n')
258: colon[len - 1] = '\0';
259: if (*colon != '\0') {
260: gr.gr_mem = gr_mem;
261: cp = strtok(colon, ",");
262: for (n = 0; cp != NULL && n < GRMEM_MAX; n++) {
263: gr.gr_mem[n] = cp;
264: cp = strtok(NULL, ",");
265: }
266: gr.gr_mem[n++] = NULL;
267: } else
268: gr.gr_mem = NULL;
269: return &gr;
270: }
271:
272: struct group *
273: getgrnam(const char *name)
274: {
275: struct group *gr;
276:
277: if (grf == NULL) {
278: if ((grf = fopen(grfile, "r")) == NULL)
279: return NULL;
280: fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
281: } else {
282: rewind(grf);
283: }
284: while ((gr = getgrent()) != NULL) {
285: if (strcmp(gr->gr_name, name) == 0)
286: break;
287: }
288: if (!gr_stayopen) {
289: fclose(grf);
290: grf = NULL;
291: }
292: return gr;
293: }
294:
295: struct group *
296: getgrgid(gid_t gid)
297: {
298: struct group *gr;
299:
300: if (grf == NULL) {
301: if ((grf = fopen(grfile, "r")) == NULL)
302: return NULL;
303: fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
304: } else {
305: rewind(grf);
306: }
307: while ((gr = getgrent()) != NULL) {
308: if (gr->gr_gid == gid)
309: break;
310: }
311: if (!gr_stayopen) {
312: fclose(grf);
313: grf = NULL;
314: }
315: return gr;
316: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>