Libinfo-330.10.tar.gz
[apple/libinfo.git] / nis.subproj / innetgr.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24 #if !defined(lint) && defined(SCCSIDS)
25 static char sccsid[] = "@(#)innetgr.c 1.2 90/07/20 4.1NFSSRC; from 1.17 88/02/08 SMI Copyr 1985 Sun Micro";
26 #endif
27
28 /*
29 * Copyright (c) 1990 by Sun Microsystems, Inc.
30 */
31
32 #include <stdio.h>
33 #include <ctype.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <rpcsvc/ypclnt.h>
37
38 /*
39 * innetgr: test whether I'm in /etc/netgroup
40 *
41 */
42
43
44 struct innetgrdata {
45 char *name;
46 char *machine;
47 char *domain;
48 char **list;
49 #define LISTSIZE 200 /* recursion limit */
50 char **listp; /* pointer into list */
51 char *thisdomain;
52 };
53
54 static int lookup(char *, char *, char *, char *, char *, int *);
55 static int doit(register struct innetgrdata *, char *);
56 static void makekey(char *, char *, char *);
57
58 int _old_innetgr(group, machine, name, domain)
59 char *group, *machine, *name, *domain;
60 {
61 int res;
62 register struct innetgrdata *d;
63 char *thisdomain;
64
65 (void) yp_get_default_domain(&thisdomain);
66 if (domain) {
67 if (name && !machine) {
68 if (lookup(thisdomain,
69 "netgroup.byuser",group,name,domain,&res)) {
70 return(res);
71 }
72 } else if (machine && !name) {
73 if (lookup(thisdomain,
74 "netgroup.byhost",group,machine,domain,&res)) {
75 return(res);
76 }
77 }
78 }
79 d = (struct innetgrdata *)malloc(sizeof (struct innetgrdata));
80 if (d == 0)
81 return (0);
82 d->machine = machine;
83 d->name = name;
84 d->domain = domain;
85 d->thisdomain = thisdomain;
86 d->list = (char **)calloc(LISTSIZE, sizeof (char *));
87 d->listp = d->list;
88 if (d->list == 0) {
89 free(d);
90 return (0);
91 }
92 res = doit(d, group);
93 free(d->list);
94 free(d);
95 return (res);
96 }
97
98 /*
99 * calls itself recursively
100 */
101 static int
102 doit(d, group)
103 register struct innetgrdata *d;
104 char *group;
105 {
106 char *key, *val;
107 int vallen,keylen;
108 char *r;
109 int match;
110 register char *p, *q;
111 register char **lp;
112 int err;
113
114 *d->listp++ = group;
115 if (d->listp > d->list + LISTSIZE) {
116 (void) fprintf(stderr, "innetgr: recursive overflow\r\n");
117 d->listp--;
118 return (0);
119 }
120 key = group;
121 keylen = strlen(group);
122 err = yp_match(d->thisdomain, "netgroup", key, keylen, &val, &vallen);
123 if (err) {
124 #ifdef DEBUG
125 if (err == YPERR_KEY)
126 (void) fprintf(stderr,
127 "innetgr: no such netgroup as %s\n", group);
128 else
129 (void) fprintf(stderr, "innetgr: yp_match, %s\n",yperr_string(err));
130 #endif
131 d->listp--;
132 return(0);
133 }
134 /*
135 * check for recursive loops
136 */
137 for (lp = d->list; lp < d->listp-1; lp++)
138 if (strcmp(*lp, group) == 0) {
139 (void) fprintf(stderr,
140 "innetgr: netgroup %s called recursively\r\n",
141 group);
142 d->listp--;
143 free(val);
144 return(0);
145 }
146
147 p = val;
148 p[vallen] = 0;
149 while (p != NULL) {
150 match = 0;
151 while (*p == ' ' || *p == '\t')
152 p++;
153 if (*p == 0 || *p == '#')
154 break;
155 if (*p == '(') {
156 p++;
157 while (*p == ' ' || *p == '\t')
158 p++;
159 r = q = index(p, ',');
160 if (q == NULL) {
161 (void) fprintf(stderr,
162 "innetgr: syntax error in /etc/netgroup\r\n");
163 d->listp--;
164 free(val);
165 return(0);
166 }
167 if (p == q || d->machine == NULL)
168 match++;
169 else {
170 while (*(q-1) == ' ' || *(q-1) == '\t')
171 q--;
172 if (strncmp(d->machine, p, q-p) == 0)
173 match++;
174 }
175 p = r+1;
176
177 while (*p == ' ' || *p == '\t')
178 p++;
179 r = q = index(p, ',');
180 if (q == NULL) {
181 (void) fprintf(stderr,
182 "innetgr: syntax error in /etc/netgroup\r\n");
183 d->listp--;
184 free(val);
185 return(0);
186 }
187 if (p == q || d->name == NULL)
188 match++;
189 else {
190 while (*(q-1) == ' ' || *(q-1) == '\t')
191 q--;
192 if (strncmp(d->name, p, q-p) == 0)
193 match++;
194 }
195 p = r+1;
196
197 while (*p == ' ' || *p == '\t')
198 p++;
199 r = q = index(p, ')');
200 if (q == NULL) {
201 (void) fprintf(stderr,
202 "innetgr: syntax error in /etc/netgroup\r\n");
203 d->listp--;
204 free(val);
205 return(0);
206 }
207 if (p == q || d->domain == NULL)
208 match++;
209 else {
210 while (*(q-1) == ' ' || *(q-1) == '\t')
211 q--;
212 if (strncmp(d->domain, p, q-p) == 0)
213 match++;
214 }
215 p = r+1;
216 if (match == 3) {
217 free(val);
218 d->listp--;
219 return 1;
220 }
221 }
222 else {
223 q = strpbrk(p, " \t\n#");
224 if (q && *q == '#')
225 break;
226 if (q)
227 *q = 0;
228 if (doit(d, p)) {
229 free(val);
230 d->listp--;
231 return 1;
232 }
233 if (q)
234 *q = ' ';
235 }
236 p = strpbrk(p, " \t");
237 }
238 free(val);
239 d->listp--;
240 return 0;
241 }
242
243 /*
244 * return 1 if "what" is in the comma-separated, newline-terminated "d->list"
245 */
246 static int
247 inlist(what,list)
248 char *what;
249 char *list;
250 {
251 # define TERMINATOR(c) (c == ',' || c == '\n')
252
253 register char *p;
254 int len;
255
256 len = strlen(what);
257 p = list;
258 do {
259 if (strncmp(what,p,len) == 0 && TERMINATOR(p[len])) {
260 return(1);
261 }
262 while (!TERMINATOR(*p)) {
263 p++;
264 }
265 p++;
266 } while (*p);
267 return(0);
268 }
269
270
271
272
273 /*
274 * Lookup a host or user name in a NIS map. Set result to 1 if group in the
275 * lookup list of groups. Return 1 if the map was found.
276 */
277 static int
278 lookup(thisdomain,map,group,name,domain,res)
279 char *thisdomain;
280 char *map;
281 char *group;
282 char *name;
283 char *domain;
284 int *res;
285 {
286 int err;
287 char *val;
288 int vallen;
289 char key[256];
290 char *wild = "*";
291 int i;
292
293 for (i = 0; i < 4; i++) {
294 switch (i) {
295 case 0: makekey(key,name,domain); break;
296 case 1: makekey(key,wild,domain); break;
297 case 2: makekey(key,name,wild); break;
298 case 3: makekey(key,wild,wild); break;
299 }
300 err = yp_match(thisdomain,map,key,strlen(key),&val,&vallen);
301 if (!err) {
302 *res = inlist(group,val);
303 free(val);
304 if (*res) {
305 return(1);
306 }
307 } else {
308 #ifdef DEBUG
309 (void) fprintf(stderr,
310 "yp_match(%s,%s) failed: %s.\n",map,key,yperr_string(err));
311 #endif
312 if (err != YPERR_KEY) {
313 return(0);
314 }
315 }
316 }
317 *res = 0;
318 return(1);
319 }
320
321
322
323 /*
324 * Generate a key for a netgroup.byXXXX NIS map
325 */
326 static void
327 makekey(key,name,domain)
328 register char *key;
329 register char *name;
330 register char *domain;
331 {
332 while ((*key++ = *name++))
333 ;
334 *(key-1) = '.';
335 while ((*key++ = *domain++))
336 ;
337 }