getgraent.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* 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;
}