diff options
Diffstat (limited to 'usr/src/lib/libbc/libc/gen/common/getgraent.c')
-rw-r--r-- | usr/src/lib/libbc/libc/gen/common/getgraent.c | 483 |
1 files changed, 483 insertions, 0 deletions
diff --git a/usr/src/lib/libbc/libc/gen/common/getgraent.c b/usr/src/lib/libbc/libc/gen/common/getgraent.c new file mode 100644 index 0000000000..f8c3637c51 --- /dev/null +++ b/usr/src/lib/libbc/libc/gen/common/getgraent.c @@ -0,0 +1,483 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 1990 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" /* c2 secure */ + +#include <stdio.h> +#include <grp.h> +#include <grpadj.h> +#include <rpcsvc/ypclnt.h> + +extern void rewind(); +extern long strtol(); +extern int strlen(); +extern int strcmp(); +extern int fclose(); +extern char *strcpy(); +extern char *calloc(); +extern char *malloc(); + +void setgraent(), endgraent(); + +static struct gradata { + char *domain; + FILE *grfa; + char *yp; + int yplen; + char *oldyp; + int oldyplen; + struct list { + char *name; + struct list *nxt; + } *minuslist; /* list of - items */ + struct group_adjunct interpgra; + char interpline[BUFSIZ+1]; + struct group_adjunct *sv; +} *gradata, *_gradata(); + +static char *GROUPADJ = "/etc/security/group.adjunct"; +static struct group_adjunct *interpret(); +static struct group_adjunct *interpretwithsave(); +static struct group_adjunct *save(); +static struct group_adjunct *getnamefromyellow(); +static struct group_adjunct *getgidfromyellow(); + +static struct gradata * +_gradata() +{ + register struct gradata *g = gradata; + + if (g == 0) { + g = (struct gradata *)calloc(1, sizeof (struct gradata)); + gradata = g; + } + return (g); +} + +#ifdef NOT_DEFINED +struct group_adjunct * +getgragid(gid) +register gid; +{ + struct group *getgrgid(); + struct group *gr; + + if ((gr = getgrgid(gid)) == NULL) + return NULL; + return (getgranam(gr->gr_name)); +} +#endif NOT_DEFINED + +struct group_adjunct * +getgranam(name) +register char *name; +{ + register struct gradata *g = _gradata(); + struct group_adjunct *gra; + char line[BUFSIZ+1]; + + setgraent(); + if (g == 0) + return (0); + if (!g->grfa) + return NULL; + while (fgets(line, BUFSIZ, g->grfa) != NULL) { + if ((gra = interpret(line, strlen(line))) == NULL) + continue; + if (matchname(line, &gra, name)) { + endgraent(); + return (gra); + } + } + endgraent(); + return (NULL); +} + +void +setgraent() +{ + register struct gradata *g = _gradata(); + + if (g == NULL) + return; + if (g->domain == NULL) + (void) yp_get_default_domain(&g->domain); + if (!g->grfa) + g->grfa = fopen(GROUPADJ, "r"); + else + rewind(g->grfa); + if (g->yp) + free(g->yp); + g->yp = NULL; + freeminuslist(); +} + +void +endgraent() +{ + register struct gradata *g = _gradata(); + + if (g == 0) + return; + if (g->grfa) { + (void) fclose(g->grfa); + g->grfa = NULL; + } + if (g->yp) + free(g->yp); + g->yp = NULL; + freeminuslist(); +} + +struct group_adjunct * +fgetgraent(f) + FILE *f; +{ + char line1[BUFSIZ+1]; + + if(fgets(line1, BUFSIZ, f) == NULL) + return(NULL); + return (interpret(line1, strlen(line1))); +} + +static char * +grskip(p,c) + register char *p; + register c; +{ + while(*p && *p != c && *p != '\n') ++p; + if (*p == '\n') + *p = '\0'; + else if (*p != '\0') + *p++ = '\0'; + return(p); +} + +struct group_adjunct * +getgraent() +{ + register struct gradata *g = _gradata(); + char line1[BUFSIZ+1]; + static struct group_adjunct *savegra; + struct group_adjunct *gra; + + if (g == 0) + return (0); + if (g->domain == NULL) { + (void) yp_get_default_domain(&g->domain); + } + if(!g->grfa && !(g->grfa = fopen(GROUPADJ, "r"))) + return(NULL); + again: + if (g->yp) { + gra = interpretwithsave(g->yp, g->yplen, savegra); + free(g->yp); + if (gra == NULL) + return(NULL); + getnextfromyellow(); + if (onminuslist(gra)) + goto again; + else + return (gra); + } + else if (fgets(line1, BUFSIZ, g->grfa) == NULL) + return(NULL); + if ((gra = interpret(line1, strlen(line1))) == NULL) + return(NULL); + switch(line1[0]) { + case '+': + if (strcmp(gra->gra_name, "+") == 0) { + getfirstfromyellow(); + savegra = save(gra); + goto again; + } + /* + * else look up this entry in NIS + */ + savegra = save(gra); + gra = getnamefromyellow(gra->gra_name+1, savegra); + if (gra == NULL) + goto again; + else if (onminuslist(gra)) + goto again; + else + return (gra); + break; + case '-': + addtominuslist(gra->gra_name+1); + goto again; + break; + default: + if (onminuslist(gra)) + goto again; + return (gra); + break; + } + /*NOTREACHED*/ +} + +static struct group_adjunct * +interpret(val, len) + char *val; +{ + register struct gradata *g = _gradata(); + register char *p; + + if (g == 0) + return (0); + strncpy(g->interpline, val, len); + p = g->interpline; + g->interpline[len] = '\n'; + g->interpline[len+1] = 0; + g->interpgra.gra_name = p; + p = grskip(p,':'); + if (strcmp(g->interpgra.gra_name, "+") == 0) { + /* we are going to the NIS - fix the + * rest of the struct as much as is needed + */ + g->interpgra.gra_passwd = ""; + return (&g->interpgra); + } + g->interpgra.gra_passwd = p; + while(*p && *p != '\n') p++; + *p = '\0'; + return (&g->interpgra); +} + +static +freeminuslist() { + register struct gradata *g = _gradata(); + struct list *ls; + + if (g == 0) + return; + for (ls = g->minuslist; ls != NULL; ls = ls->nxt) { + free(ls->name); + free(ls); + } + g->minuslist = NULL; +} + +static struct group_adjunct * +interpretwithsave(val, len, savegra) + char *val; + struct group_adjunct *savegra; +{ + register struct gradata *g = _gradata(); + struct group_adjunct *gra; + + if (g == 0) + return (0); + if ((gra = interpret(val, len)) == NULL) + return (NULL); + if (savegra->gra_passwd && *savegra->gra_passwd) + gra->gra_passwd = savegra->gra_passwd; + return (gra); +} + +static +onminuslist(gra) + struct group_adjunct *gra; +{ + register struct gradata *g = _gradata(); + struct list *ls; + register char *nm; + + if (g == 0) + return 0; + nm = gra->gra_name; + for (ls = g->minuslist; ls != NULL; ls = ls->nxt) + if (strcmp(ls->name, nm) == 0) + return 1; + return 0; +} + +static +getnextfromyellow() +{ + register struct gradata *g = _gradata(); + int reason; + char *key = NULL; + int keylen; + + if (g == 0) + return; + if (reason = yp_next(g->domain, "group.adjunct.byname", + g->oldyp, g->oldyplen, &key, &keylen, + &g->yp, &g->yplen)) { +#ifdef DEBUG +fprintf(stderr, "reason yp_next failed is %d\n", reason); +#endif + g->yp = NULL; + } + if (g->oldyp) + free(g->oldyp); + g->oldyp = key; + g->oldyplen = keylen; +} + +static +getfirstfromyellow() +{ + register struct gradata *g = _gradata(); + int reason; + char *key = NULL; + int keylen; + + if (g == 0) + return; + if (reason = yp_first(g->domain, "group.adjunct.byname", + &key, &keylen, &g->yp, &g->yplen)) { +#ifdef DEBUG +fprintf(stderr, "reason yp_first failed is %d\n", reason); +#endif + g->yp = NULL; + } + if (g->oldyp) + free(g->oldyp); + g->oldyp = key; + g->oldyplen = keylen; +} + +static struct group_adjunct * +getnamefromyellow(name, savegra) + char *name; + struct group_adjunct *savegra; +{ + register struct gradata *g = _gradata(); + struct group_adjunct *gra; + int reason; + char *val; + int vallen; + + if (g == 0) + return (NULL); + if (reason = yp_match(g->domain, "group.adjunct.byname", + name, strlen(name), &val, &vallen)) { +#ifdef DEBUG +fprintf(stderr, "reason yp_next failed is %d\n", reason); +#endif + return NULL; + } + else { + gra = interpret(val, vallen); + free(val); + if (gra == NULL) + return NULL; + if (savegra->gra_passwd && *savegra->gra_passwd) + gra->gra_passwd = savegra->gra_passwd; + return gra; + } +} + +static +addtominuslist(name) + char *name; +{ + register struct gradata *g = _gradata(); + struct list *ls; + char *buf; + + if (g == 0) + return; + ls = (struct list *)malloc(sizeof(struct list)); + buf = (char *)malloc(strlen(name) + 1); + (void) strcpy(buf, name); + ls->name = buf; + ls->nxt = g->minuslist; + g->minuslist = ls; +} + +/* + * save away psswd field, which is the only + * one which can be specified in a local + entry to override the + * value in the NIS + */ +static struct group_adjunct * +save(gra) + struct group_adjunct *gra; +{ + register struct gradata *g = _gradata(); + + if (g == 0) + return 0; + /* + * free up stuff from last time around + */ + if (g->sv) { + free(g->sv->gra_passwd); + free(g->sv); + } + g->sv = (struct group_adjunct *)calloc(1, sizeof(struct group_adjunct)); + g->sv->gra_passwd = (char *)malloc(strlen(gra->gra_passwd) + 1); + (void) strcpy(g->sv->gra_passwd, gra->gra_passwd); + return g->sv; +} + +static +matchname(line1, grap, name) + char line1[]; + struct group_adjunct **grap; + char *name; +{ + struct group_adjunct *savegra; + struct group_adjunct *gra = *grap; + + switch(line1[0]) { + case '+': + if (strcmp(gra->gra_name, "+") == 0) { + savegra = save(gra); + gra = getnamefromyellow(name, savegra); + if (gra) { + *grap = gra; + return 1; + } + else + return 0; + } + if (strcmp(gra->gra_name+1, name) == 0) { + savegra = save(gra); + gra = getnamefromyellow(gra->gra_name+1, savegra); + if (gra) { + *grap = gra; + return 1; + } + else + return 0; + } + break; + case '-': + if (strcmp(gra->gra_name+1, name) == 0) { + *grap = NULL; + return 1; + } + break; + default: + if (strcmp(gra->gra_name, name) == 0) + return 1; + } + return 0; +} |