xref: /titanic_44/usr/src/lib/libbc/libc/gen/common/getgraent.c (revision 8eea8e29cc4374d1ee24c25a07f45af132db3499)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 1990 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"  /* c2 secure */
28 
29 #include <stdio.h>
30 #include <grp.h>
31 #include <grpadj.h>
32 #include <rpcsvc/ypclnt.h>
33 
34 extern void rewind();
35 extern long strtol();
36 extern int strlen();
37 extern int strcmp();
38 extern int fclose();
39 extern char *strcpy();
40 extern char *calloc();
41 extern char *malloc();
42 
43 void setgraent(), endgraent();
44 
45 static struct gradata {
46 	char	*domain;
47 	FILE	*grfa;
48 	char	*yp;
49 	int	yplen;
50 	char	*oldyp;
51 	int	oldyplen;
52 	struct list {
53 		char *name;
54 		struct list *nxt;
55 	} *minuslist;			/* list of - items */
56 	struct	group_adjunct interpgra;
57 	char	interpline[BUFSIZ+1];
58 	struct	group_adjunct *sv;
59 } *gradata, *_gradata();
60 
61 static char *GROUPADJ = "/etc/security/group.adjunct";
62 static	struct group_adjunct *interpret();
63 static	struct group_adjunct *interpretwithsave();
64 static	struct group_adjunct *save();
65 static	struct group_adjunct *getnamefromyellow();
66 static	struct group_adjunct *getgidfromyellow();
67 
68 static struct gradata *
69 _gradata()
70 {
71 	register struct gradata *g = gradata;
72 
73 	if (g == 0) {
74 		g = (struct gradata *)calloc(1, sizeof (struct gradata));
75 		gradata = g;
76 	}
77 	return (g);
78 }
79 
80 #ifdef	NOT_DEFINED
81 struct group_adjunct *
82 getgragid(gid)
83 register gid;
84 {
85 	struct group *getgrgid();
86 	struct group *gr;
87 
88 	if ((gr = getgrgid(gid)) == NULL)
89 		return NULL;
90 	return (getgranam(gr->gr_name));
91 }
92 #endif	NOT_DEFINED
93 
94 struct group_adjunct *
95 getgranam(name)
96 register char *name;
97 {
98 	register struct gradata *g = _gradata();
99 	struct group_adjunct *gra;
100 	char line[BUFSIZ+1];
101 
102 	setgraent();
103 	if (g == 0)
104 		return (0);
105 	if (!g->grfa)
106 		return NULL;
107 	while (fgets(line, BUFSIZ, g->grfa) != NULL) {
108 		if ((gra = interpret(line, strlen(line))) == NULL)
109 			continue;
110 		if (matchname(line, &gra, name)) {
111 			endgraent();
112 			return (gra);
113 		}
114 	}
115 	endgraent();
116 	return (NULL);
117 }
118 
119 void
120 setgraent()
121 {
122 	register struct gradata *g = _gradata();
123 
124 	if (g == NULL)
125 		return;
126 	if (g->domain == NULL)
127 		(void) yp_get_default_domain(&g->domain);
128 	if (!g->grfa)
129 		g->grfa = fopen(GROUPADJ, "r");
130 	else
131 		rewind(g->grfa);
132 	if (g->yp)
133 		free(g->yp);
134 	g->yp = NULL;
135 	freeminuslist();
136 }
137 
138 void
139 endgraent()
140 {
141 	register struct gradata *g = _gradata();
142 
143 	if (g == 0)
144 		return;
145 	if (g->grfa) {
146 		(void) fclose(g->grfa);
147 		g->grfa = NULL;
148 	}
149 	if (g->yp)
150 		free(g->yp);
151 	g->yp = NULL;
152 	freeminuslist();
153 }
154 
155 struct group_adjunct *
156 fgetgraent(f)
157 	FILE *f;
158 {
159 	char line1[BUFSIZ+1];
160 
161 	if(fgets(line1, BUFSIZ, f) == NULL)
162 		return(NULL);
163 	return (interpret(line1, strlen(line1)));
164 }
165 
166 static char *
167 grskip(p,c)
168 	register char *p;
169 	register c;
170 {
171 	while(*p && *p != c && *p != '\n') ++p;
172 	if (*p == '\n')
173 		*p = '\0';
174 	else if (*p != '\0')
175 		*p++ = '\0';
176 	return(p);
177 }
178 
179 struct group_adjunct *
180 getgraent()
181 {
182 	register struct gradata *g = _gradata();
183 	char line1[BUFSIZ+1];
184 	static struct group_adjunct *savegra;
185 	struct group_adjunct *gra;
186 
187 	if (g == 0)
188 		return (0);
189 	if (g->domain == NULL) {
190 		(void) yp_get_default_domain(&g->domain);
191 	}
192 	if(!g->grfa && !(g->grfa = fopen(GROUPADJ, "r")))
193 		return(NULL);
194   again:
195 	if (g->yp) {
196 		gra = interpretwithsave(g->yp, g->yplen, savegra);
197 		free(g->yp);
198 		if (gra == NULL)
199 			return(NULL);
200 		getnextfromyellow();
201 		if (onminuslist(gra))
202 			goto again;
203 		else
204 			return (gra);
205 	}
206 	else if (fgets(line1, BUFSIZ, g->grfa) == NULL)
207 		return(NULL);
208 	if ((gra = interpret(line1, strlen(line1))) == NULL)
209 		return(NULL);
210 	switch(line1[0]) {
211 		case '+':
212 			if (strcmp(gra->gra_name, "+") == 0) {
213 				getfirstfromyellow();
214 				savegra = save(gra);
215 				goto again;
216 			}
217 			/*
218 			 * else look up this entry in NIS
219 			 */
220 			savegra = save(gra);
221 			gra = getnamefromyellow(gra->gra_name+1, savegra);
222 			if (gra == NULL)
223 				goto again;
224 			else if (onminuslist(gra))
225 				goto again;
226 			else
227 				return (gra);
228 			break;
229 		case '-':
230 			addtominuslist(gra->gra_name+1);
231 			goto again;
232 			break;
233 		default:
234 			if (onminuslist(gra))
235 				goto again;
236 			return (gra);
237 			break;
238 	}
239 	/*NOTREACHED*/
240 }
241 
242 static struct group_adjunct *
243 interpret(val, len)
244 	char *val;
245 {
246 	register struct gradata *g = _gradata();
247 	register char *p;
248 
249 	if (g == 0)
250 		return (0);
251 	strncpy(g->interpline, val, len);
252 	p = g->interpline;
253 	g->interpline[len] = '\n';
254 	g->interpline[len+1] = 0;
255 	g->interpgra.gra_name = p;
256 	p = grskip(p,':');
257         if (strcmp(g->interpgra.gra_name, "+") == 0) {
258                 /* we are going to the NIS - fix the
259                  * rest of the struct as much as is needed
260                  */
261                 g->interpgra.gra_passwd = "";
262 		return (&g->interpgra);
263         }
264 	g->interpgra.gra_passwd = p;
265         while(*p && *p != '\n') p++;
266         *p = '\0';
267 	return (&g->interpgra);
268 }
269 
270 static
271 freeminuslist() {
272 	register struct gradata *g = _gradata();
273 	struct list *ls;
274 
275 	if (g == 0)
276 		return;
277 	for (ls = g->minuslist; ls != NULL; ls = ls->nxt) {
278 		free(ls->name);
279 		free(ls);
280 	}
281 	g->minuslist = NULL;
282 }
283 
284 static struct group_adjunct *
285 interpretwithsave(val, len, savegra)
286 	char *val;
287 	struct group_adjunct *savegra;
288 {
289 	register struct gradata *g = _gradata();
290 	struct group_adjunct *gra;
291 
292 	if (g == 0)
293 		return (0);
294 	if ((gra = interpret(val, len)) == NULL)
295 		return (NULL);
296 	if (savegra->gra_passwd && *savegra->gra_passwd)
297 		gra->gra_passwd =  savegra->gra_passwd;
298 	return (gra);
299 }
300 
301 static
302 onminuslist(gra)
303 	struct group_adjunct *gra;
304 {
305 	register struct gradata *g = _gradata();
306 	struct list *ls;
307 	register char *nm;
308 
309 	if (g == 0)
310 		return 0;
311 	nm = gra->gra_name;
312 	for (ls = g->minuslist; ls != NULL; ls = ls->nxt)
313 		if (strcmp(ls->name, nm) == 0)
314 			return 1;
315 	return 0;
316 }
317 
318 static
319 getnextfromyellow()
320 {
321 	register struct gradata *g = _gradata();
322 	int reason;
323 	char *key = NULL;
324 	int keylen;
325 
326 	if (g == 0)
327 		return;
328 	if (reason = yp_next(g->domain, "group.adjunct.byname",
329 	    g->oldyp, g->oldyplen, &key, &keylen,
330 	    &g->yp, &g->yplen)) {
331 #ifdef DEBUG
332 fprintf(stderr, "reason yp_next failed is %d\n", reason);
333 #endif
334 		g->yp = NULL;
335 	}
336 	if (g->oldyp)
337 		free(g->oldyp);
338 	g->oldyp = key;
339 	g->oldyplen = keylen;
340 }
341 
342 static
343 getfirstfromyellow()
344 {
345 	register struct gradata *g = _gradata();
346 	int reason;
347 	char *key = NULL;
348 	int keylen;
349 
350 	if (g == 0)
351 		return;
352 	if (reason =  yp_first(g->domain, "group.adjunct.byname",
353 	    &key, &keylen, &g->yp, &g->yplen)) {
354 #ifdef DEBUG
355 fprintf(stderr, "reason yp_first failed is %d\n", reason);
356 #endif
357 		g->yp = NULL;
358 	}
359 	if (g->oldyp)
360 		free(g->oldyp);
361 	g->oldyp = key;
362 	g->oldyplen = keylen;
363 }
364 
365 static struct group_adjunct *
366 getnamefromyellow(name, savegra)
367 	char *name;
368 	struct group_adjunct *savegra;
369 {
370 	register struct gradata *g = _gradata();
371 	struct group_adjunct *gra;
372 	int reason;
373 	char *val;
374 	int vallen;
375 
376 	if (g == 0)
377 		return (NULL);
378 	if (reason = yp_match(g->domain, "group.adjunct.byname",
379 	    name, strlen(name), &val, &vallen)) {
380 #ifdef DEBUG
381 fprintf(stderr, "reason yp_next failed is %d\n", reason);
382 #endif
383 		return NULL;
384 	}
385 	else {
386 		gra = interpret(val, vallen);
387 		free(val);
388 		if (gra == NULL)
389 			return NULL;
390 		if (savegra->gra_passwd && *savegra->gra_passwd)
391 			gra->gra_passwd =  savegra->gra_passwd;
392 		return gra;
393 	}
394 }
395 
396 static
397 addtominuslist(name)
398 	char *name;
399 {
400 	register struct gradata *g = _gradata();
401 	struct list *ls;
402 	char *buf;
403 
404 	if (g == 0)
405 		return;
406 	ls = (struct list *)malloc(sizeof(struct list));
407 	buf = (char *)malloc(strlen(name) + 1);
408 	(void) strcpy(buf, name);
409 	ls->name = buf;
410 	ls->nxt = g->minuslist;
411 	g->minuslist = ls;
412 }
413 
414 /*
415  * save away psswd field, which is the only
416  * one which can be specified in a local + entry to override the
417  * value in the NIS
418  */
419 static struct group_adjunct *
420 save(gra)
421 	struct group_adjunct *gra;
422 {
423 	register struct gradata *g = _gradata();
424 
425 	if (g == 0)
426 		return 0;
427 	/*
428 	 * free up stuff from last time around
429 	 */
430 	if (g->sv) {
431 		free(g->sv->gra_passwd);
432 		free(g->sv);
433 	}
434 	g->sv = (struct group_adjunct *)calloc(1, sizeof(struct group_adjunct));
435 	g->sv->gra_passwd = (char *)malloc(strlen(gra->gra_passwd) + 1);
436 	(void) strcpy(g->sv->gra_passwd, gra->gra_passwd);
437 	return g->sv;
438 }
439 
440 static
441 matchname(line1, grap, name)
442 	char line1[];
443 	struct group_adjunct **grap;
444 	char *name;
445 {
446 	struct group_adjunct *savegra;
447 	struct group_adjunct *gra = *grap;
448 
449 	switch(line1[0]) {
450 		case '+':
451 			if (strcmp(gra->gra_name, "+") == 0) {
452 				savegra = save(gra);
453 				gra = getnamefromyellow(name, savegra);
454 				if (gra) {
455 					*grap = gra;
456 					return 1;
457 				}
458 				else
459 					return 0;
460 			}
461 			if (strcmp(gra->gra_name+1, name) == 0) {
462 				savegra = save(gra);
463 				gra = getnamefromyellow(gra->gra_name+1, savegra);
464 				if (gra) {
465 					*grap = gra;
466 					return 1;
467 				}
468 				else
469 					return 0;
470 			}
471 			break;
472 		case '-':
473 			if (strcmp(gra->gra_name+1, name) == 0) {
474 				*grap = NULL;
475 				return 1;
476 			}
477 			break;
478 		default:
479 			if (strcmp(gra->gra_name, name) == 0)
480 				return 1;
481 	}
482 	return 0;
483 }
484