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