Annotation of embedaddon/sudo/plugins/group_file/getgrent.c, revision 1.1.1.2
1.1 misho 1: /*
2: * Copyright (c) 2005,2008,2010-2013 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 getgr{uid,nam}() routines.
19: */
20:
21: #include <config.h>
22:
23: #include <sys/types.h>
24: #include <stdio.h>
25: #ifdef STDC_HEADERS
26: # include <stdlib.h>
27: # include <stddef.h>
28: #else
29: # ifdef HAVE_STDLIB_H
30: # include <stdlib.h>
31: # endif
32: #endif /* STDC_HEADERS */
33: #ifdef HAVE_STRING_H
34: # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
35: # include <memory.h>
36: # endif
37: # include <string.h>
38: #endif /* HAVE_STRING_H */
39: #ifdef HAVE_STRINGS_H
40: # include <strings.h>
41: #endif /* HAVE_STRINGS_H */
42: #include <fcntl.h>
43: #include <limits.h>
44: #include <pwd.h>
45: #include <grp.h>
46:
47: #include "missing.h"
1.1.1.2 ! misho 48: #include "sudo_util.h"
1.1 misho 49:
50: #ifndef LINE_MAX
51: # define LINE_MAX 2048
52: #endif
53:
54: #undef GRMEM_MAX
55: #define GRMEM_MAX 200
56:
57: static FILE *grf;
58: static const char *grfile = "/etc/group";
59: static int gr_stayopen;
60:
61: void mysetgrfile(const char *);
62: void mysetgrent(void);
63: void myendgrent(void);
64: struct group *mygetgrent(void);
65: struct group *mygetgrnam(const char *);
66: struct group *mygetgrgid(gid_t);
67:
68: void
69: mysetgrfile(const char *file)
70: {
71: grfile = file;
72: if (grf != NULL)
73: myendgrent();
74: }
75:
76: void
77: mysetgrent(void)
78: {
79: if (grf == NULL) {
80: grf = fopen(grfile, "r");
81: if (grf != NULL)
82: fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
83: } else {
84: rewind(grf);
85: }
86: gr_stayopen = 1;
87: }
88:
89: void
90: myendgrent(void)
91: {
92: if (grf != NULL) {
93: fclose(grf);
94: grf = NULL;
95: }
96: gr_stayopen = 0;
97: }
98:
99: struct group *
100: mygetgrent(void)
101: {
102: static struct group gr;
103: static char grbuf[LINE_MAX], *gr_mem[GRMEM_MAX+1];
104: size_t len;
1.1.1.2 ! misho 105: id_t id;
1.1 misho 106: char *cp, *colon;
1.1.1.2 ! misho 107: const char *errstr;
1.1 misho 108: int n;
109:
1.1.1.2 ! misho 110: next_entry:
1.1 misho 111: if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL)
112: return NULL;
113:
114: memset(&gr, 0, sizeof(gr));
115: if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2 ! misho 116: goto next_entry;
1.1 misho 117: *colon++ = '\0';
118: gr.gr_name = cp;
119: if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2 ! misho 120: goto next_entry;
1.1 misho 121: *colon++ = '\0';
122: gr.gr_passwd = cp;
123: if ((colon = strchr(cp = colon, ':')) == NULL)
1.1.1.2 ! misho 124: goto next_entry;
1.1 misho 125: *colon++ = '\0';
1.1.1.2 ! misho 126: id = atoid(cp, NULL, NULL, &errstr);
! 127: if (errstr != NULL)
! 128: goto next_entry;
! 129: gr.gr_gid = (gid_t)id;
1.1 misho 130: len = strlen(colon);
131: if (len > 0 && colon[len - 1] == '\n')
132: colon[len - 1] = '\0';
133: if (*colon != '\0') {
134: gr.gr_mem = gr_mem;
135: cp = strtok(colon, ",");
136: for (n = 0; cp != NULL && n < GRMEM_MAX; n++) {
137: gr.gr_mem[n] = cp;
138: cp = strtok(NULL, ",");
139: }
140: gr.gr_mem[n++] = NULL;
141: } else
142: gr.gr_mem = NULL;
143: return &gr;
144: }
145:
146: struct group *
147: mygetgrnam(const char *name)
148: {
149: struct group *gr;
150:
151: if (grf == NULL) {
152: if ((grf = fopen(grfile, "r")) == NULL)
153: return NULL;
154: fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
155: } else {
156: rewind(grf);
157: }
158: while ((gr = mygetgrent()) != NULL) {
159: if (strcmp(gr->gr_name, name) == 0)
160: break;
161: }
162: if (!gr_stayopen) {
163: fclose(grf);
164: grf = NULL;
165: }
166: return gr;
167: }
168:
169: struct group *
170: mygetgrgid(gid_t gid)
171: {
172: struct group *gr;
173:
174: if (grf == NULL) {
175: if ((grf = fopen(grfile, "r")) == NULL)
176: return NULL;
177: fcntl(fileno(grf), F_SETFD, FD_CLOEXEC);
178: } else {
179: rewind(grf);
180: }
181: while ((gr = mygetgrent()) != NULL) {
182: if (gr->gr_gid == gid)
183: break;
184: }
185: if (!gr_stayopen) {
186: fclose(grf);
187: grf = NULL;
188: }
189: return gr;
190: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>