Home | History | Annotate | Download | only in common
      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"
     28 
     29 #include <stdio.h>
     30 #include <grp.h>
     31 #include <grpadj.h>
     32 #include <rpcsvc/ypclnt.h>
     33 #include <string.h>
     34 #include <malloc.h>
     35 
     36 extern void rewind();
     37 extern long strtol();
     38 extern int fclose();
     39 
     40 void	setgraent(void);
     41 void	endgraent(void);
     42 
     43 static struct gradata {
     44 	char	*domain;
     45 	FILE	*grfa;
     46 	char	*yp;
     47 	int	yplen;
     48 	char	*oldyp;
     49 	int	oldyplen;
     50 	struct list {
     51 		char *name;
     52 		struct list *nxt;
     53 	} *minuslist;			/* list of - items */
     54 	struct	group_adjunct interpgra;
     55 	char	interpline[BUFSIZ+1];
     56 	struct	group_adjunct *sv;
     57 } *gradata, *_gradata(void);
     58 
     59 static char *GROUPADJ = "/etc/security/group.adjunct";
     60 
     61 static struct group_adjunct	*interpret(char *, int);
     62 static struct group_adjunct	*interpretwithsave(char *, int,
     63     struct group_adjunct *);
     64 static struct group_adjunct	*save(struct group_adjunct *);
     65 static struct group_adjunct	*getnamefromyellow(char *,
     66     struct group_adjunct *);
     67 static int	onminuslist(struct group_adjunct *);
     68 static int	matchname(char [], struct group_adjunct **, char *);
     69 static void	freeminuslist(void);
     70 static void	getnextfromyellow(void);
     71 static void	getfirstfromyellow(void);
     72 static void	addtominuslist(char *);
     73 
     74 
     75 static struct gradata *
     76 _gradata(void)
     77 {
     78 	struct gradata *g = gradata;
     79 
     80 	if (g == 0) {
     81 		g = (struct gradata *)calloc(1, sizeof (struct gradata));
     82 		gradata = g;
     83 	}
     84 	return (g);
     85 }
     86 
     87 struct group_adjunct *
     88 getgranam(char *name)
     89 {
     90 	struct gradata *g = _gradata();
     91 	struct group_adjunct *gra;
     92 	char line[BUFSIZ+1];
     93 
     94 	setgraent();
     95 	if (g == 0)
     96 		return (0);
     97 	if (!g->grfa)
     98 		return (NULL);
     99 	while (fgets(line, BUFSIZ, g->grfa) != NULL) {
    100 		if ((gra = interpret(line, strlen(line))) == NULL)
    101 			continue;
    102 		if (matchname(line, &gra, name)) {
    103 			endgraent();
    104 			return (gra);
    105 		}
    106 	}
    107 	endgraent();
    108 	return (NULL);
    109 }
    110 
    111 void
    112 setgraent(void)
    113 {
    114 	struct gradata *g = _gradata();
    115 
    116 	if (g == NULL)
    117 		return;
    118 	if (g->domain == NULL)
    119 		(void) yp_get_default_domain(&g->domain);
    120 	if (!g->grfa)
    121 		g->grfa = fopen(GROUPADJ, "r");
    122 	else
    123 		rewind(g->grfa);
    124 	if (g->yp)
    125 		free(g->yp);
    126 	g->yp = NULL;
    127 	freeminuslist();
    128 }
    129 
    130 void
    131 endgraent(void)
    132 {
    133 	struct gradata *g = _gradata();
    134 
    135 	if (g == 0)
    136 		return;
    137 	if (g->grfa) {
    138 		(void) fclose(g->grfa);
    139 		g->grfa = NULL;
    140 	}
    141 	if (g->yp)
    142 		free(g->yp);
    143 	g->yp = NULL;
    144 	freeminuslist();
    145 }
    146 
    147 struct group_adjunct *
    148 fgetgraent(FILE *f)
    149 {
    150 	char line1[BUFSIZ+1];
    151 
    152 	if(fgets(line1, BUFSIZ, f) == NULL)
    153 		return (NULL);
    154 	return (interpret(line1, strlen(line1)));
    155 }
    156 
    157 static char *
    158 grskip(char *p, int c)
    159 {
    160 	while(*p && *p != c && *p != '\n') ++p;
    161 	if (*p == '\n')
    162 		*p = '\0';
    163 	else if (*p != '\0')
    164 		*p++ = '\0';
    165 	return (p);
    166 }
    167 
    168 struct group_adjunct *
    169 getgraent(void)
    170 {
    171 	struct gradata *g = _gradata();
    172 	char line1[BUFSIZ+1];
    173 	static struct group_adjunct *savegra;
    174 	struct group_adjunct *gra;
    175 
    176 	if (g == 0)
    177 		return (0);
    178 	if (g->domain == NULL) {
    179 		(void) yp_get_default_domain(&g->domain);
    180 	}
    181 	if(!g->grfa && !(g->grfa = fopen(GROUPADJ, "r")))
    182 		return (NULL);
    183   again:
    184 	if (g->yp) {
    185 		gra = interpretwithsave(g->yp, g->yplen, savegra);
    186 		free(g->yp);
    187 		if (gra == NULL)
    188 			return (NULL);
    189 		getnextfromyellow();
    190 		if (onminuslist(gra))
    191 			goto again;
    192 		else
    193 			return (gra);
    194 	}
    195 	else if (fgets(line1, BUFSIZ, g->grfa) == NULL)
    196 		return (NULL);
    197 	if ((gra = interpret(line1, strlen(line1))) == NULL)
    198 		return (NULL);
    199 	switch(line1[0]) {
    200 		case '+':
    201 			if (strcmp(gra->gra_name, "+") == 0) {
    202 				getfirstfromyellow();
    203 				savegra = save(gra);
    204 				goto again;
    205 			}
    206 			/*
    207 			 * else look up this entry in NIS
    208 			 */
    209 			savegra = save(gra);
    210 			gra = getnamefromyellow(gra->gra_name+1, savegra);
    211 			if (gra == NULL)
    212 				goto again;
    213 			else if (onminuslist(gra))
    214 				goto again;
    215 			else
    216 				return (gra);
    217 			break;
    218 		case '-':
    219 			addtominuslist(gra->gra_name+1);
    220 			goto again;
    221 			break;
    222 		default:
    223 			if (onminuslist(gra))
    224 				goto again;
    225 			return (gra);
    226 			break;
    227 	}
    228 	/* NOTREACHED */
    229 }
    230 
    231 static struct group_adjunct *
    232 interpret(char *val, int len)
    233 {
    234 	struct gradata *g = _gradata();
    235 	char *p;
    236 
    237 	if (g == 0)
    238 		return (0);
    239 	strncpy(g->interpline, val, len);
    240 	p = g->interpline;
    241 	g->interpline[len] = '\n';
    242 	g->interpline[len+1] = 0;
    243 	g->interpgra.gra_name = p;
    244 	p = grskip(p,':');
    245         if (strcmp(g->interpgra.gra_name, "+") == 0) {
    246                 /* we are going to the NIS - fix the
    247                  * rest of the struct as much as is needed
    248                  */
    249                 g->interpgra.gra_passwd = "";
    250 		return (&g->interpgra);
    251         }
    252 	g->interpgra.gra_passwd = p;
    253         while(*p && *p != '\n') p++;
    254         *p = '\0';
    255 	return (&g->interpgra);
    256 }
    257 
    258 static void
    259 freeminuslist(void)
    260 {
    261 	struct gradata *g = _gradata();
    262 	struct list *ls;
    263 
    264 	if (g == 0)
    265 		return;
    266 	for (ls = g->minuslist; ls != NULL; ls = ls->nxt) {
    267 		free(ls->name);
    268 		free(ls);
    269 	}
    270 	g->minuslist = NULL;
    271 }
    272 
    273 static struct group_adjunct *
    274 interpretwithsave(char *val, int len, struct group_adjunct *savegra)
    275 {
    276 	struct gradata *g = _gradata();
    277 	struct group_adjunct *gra;
    278 
    279 	if (g == 0)
    280 		return (0);
    281 	if ((gra = interpret(val, len)) == NULL)
    282 		return (NULL);
    283 	if (savegra->gra_passwd && *savegra->gra_passwd)
    284 		gra->gra_passwd =  savegra->gra_passwd;
    285 	return (gra);
    286 }
    287 
    288 static int
    289 onminuslist(struct group_adjunct *gra)
    290 {
    291 	struct gradata *g = _gradata();
    292 	struct list *ls;
    293 	char *nm;
    294 
    295 	if (g == 0)
    296 		return (0);
    297 	nm = gra->gra_name;
    298 	for (ls = g->minuslist; ls != NULL; ls = ls->nxt)
    299 		if (strcmp(ls->name, nm) == 0)
    300 			return (1);
    301 	return (0);
    302 }
    303 
    304 static void
    305 getnextfromyellow(void)
    306 {
    307 	struct gradata *g = _gradata();
    308 	int reason;
    309 	char *key = NULL;
    310 	int keylen;
    311 
    312 	if (g == 0)
    313 		return;
    314 	if (reason = yp_next(g->domain, "group.adjunct.byname",
    315 	    g->oldyp, g->oldyplen, &key, &keylen,
    316 	    &g->yp, &g->yplen)) {
    317 #ifdef DEBUG
    318 fprintf(stderr, "reason yp_next failed is %d\n", reason);
    319 #endif
    320 		g->yp = NULL;
    321 	}
    322 	if (g->oldyp)
    323 		free(g->oldyp);
    324 	g->oldyp = key;
    325 	g->oldyplen = keylen;
    326 }
    327 
    328 static void
    329 getfirstfromyellow(void)
    330 {
    331 	struct gradata *g = _gradata();
    332 	int reason;
    333 	char *key = NULL;
    334 	int keylen;
    335 
    336 	if (g == 0)
    337 		return;
    338 	if (reason =  yp_first(g->domain, "group.adjunct.byname",
    339 	    &key, &keylen, &g->yp, &g->yplen)) {
    340 #ifdef DEBUG
    341 fprintf(stderr, "reason yp_first failed is %d\n", reason);
    342 #endif
    343 		g->yp = NULL;
    344 	}
    345 	if (g->oldyp)
    346 		free(g->oldyp);
    347 	g->oldyp = key;
    348 	g->oldyplen = keylen;
    349 }
    350 
    351 static struct group_adjunct *
    352 getnamefromyellow(char *name, struct group_adjunct *savegra)
    353 {
    354 	struct gradata *g = _gradata();
    355 	struct group_adjunct *gra;
    356 	int reason;
    357 	char *val;
    358 	int vallen;
    359 
    360 	if (g == 0)
    361 		return (NULL);
    362 	if (reason = yp_match(g->domain, "group.adjunct.byname",
    363 	    name, strlen(name), &val, &vallen)) {
    364 #ifdef DEBUG
    365 fprintf(stderr, "reason yp_next failed is %d\n", reason);
    366 #endif
    367 		return (NULL);
    368 	}
    369 	else {
    370 		gra = interpret(val, vallen);
    371 		free(val);
    372 		if (gra == NULL)
    373 			return (NULL);
    374 		if (savegra->gra_passwd && *savegra->gra_passwd)
    375 			gra->gra_passwd =  savegra->gra_passwd;
    376 		return (gra);
    377 	}
    378 }
    379 
    380 static void
    381 addtominuslist(char *name)
    382 {
    383 	struct gradata *g = _gradata();
    384 	struct list *ls;
    385 	char *buf;
    386 
    387 	if (g == 0)
    388 		return;
    389 	ls = (struct list *)malloc(sizeof(struct list));
    390 	buf = (char *)malloc(strlen(name) + 1);
    391 	(void) strcpy(buf, name);
    392 	ls->name = buf;
    393 	ls->nxt = g->minuslist;
    394 	g->minuslist = ls;
    395 }
    396 
    397 /*
    398  * save away psswd field, which is the only
    399  * one which can be specified in a local + entry to override the
    400  * value in the NIS
    401  */
    402 static struct group_adjunct *
    403 save(struct group_adjunct *gra)
    404 {
    405 	struct gradata *g = _gradata();
    406 
    407 	if (g == 0)
    408 		return (0);
    409 	/*
    410 	 * free up stuff from last time around
    411 	 */
    412 	if (g->sv) {
    413 		free(g->sv->gra_passwd);
    414 		free(g->sv);
    415 	}
    416 	g->sv = (struct group_adjunct *)calloc(1, sizeof(struct group_adjunct));
    417 	g->sv->gra_passwd = (char *)malloc(strlen(gra->gra_passwd) + 1);
    418 	(void) strcpy(g->sv->gra_passwd, gra->gra_passwd);
    419 	return (g->sv);
    420 }
    421 
    422 static int
    423 matchname(char line1[], struct group_adjunct **grap, char *name)
    424 {
    425 	struct group_adjunct *savegra;
    426 	struct group_adjunct *gra = *grap;
    427 
    428 	switch (line1[0]) {
    429 		case '+':
    430 			if (strcmp(gra->gra_name, "+") == 0) {
    431 				savegra = save(gra);
    432 				gra = getnamefromyellow(name, savegra);
    433 				if (gra) {
    434 					*grap = gra;
    435 					return (1);
    436 				}
    437 				else
    438 					return (0);
    439 			}
    440 			if (strcmp(gra->gra_name+1, name) == 0) {
    441 				savegra = save(gra);
    442 				gra = getnamefromyellow(gra->gra_name+1, savegra);
    443 				if (gra) {
    444 					*grap = gra;
    445 					return (1);
    446 				}
    447 				else
    448 					return (0);
    449 			}
    450 			break;
    451 		case '-':
    452 			if (strcmp(gra->gra_name+1, name) == 0) {
    453 				*grap = NULL;
    454 				return (1);
    455 			}
    456 			break;
    457 		default:
    458 			if (strcmp(gra->gra_name, name) == 0)
    459 				return (1);
    460 	}
    461 	return (0);
    462 }
    463