pull nsswitch up to main branch

This commit is contained in:
lukem 1999-01-16 07:47:18 +00:00
parent 34410d5d0c
commit 0eb8645e3a
4 changed files with 1425 additions and 929 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: getgrent.c,v 1.26 1998/08/26 00:38:40 perry Exp $ */
/* $NetBSD: getgrent.c,v 1.27 1999/01/16 07:47:18 lukem Exp $ */
/*
* Copyright (c) 1989, 1993
@ -39,17 +39,22 @@
#if 0
static char sccsid[] = "@(#)getgrent.c 8.2 (Berkeley) 3/21/94";
#else
__RCSID("$NetBSD: getgrent.c,v 1.26 1998/08/26 00:38:40 perry Exp $");
__RCSID("$NetBSD: getgrent.c,v 1.27 1999/01/16 07:47:18 lukem Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
#include <sys/types.h>
#include <grp.h>
#include <limits.h>
#include <nsswitch.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <grp.h>
#include <syslog.h>
#ifdef HESIOD
#include <hesiod.h>
#endif
#ifdef YP
#include <rpc/rpc.h>
#include <rpcsvc/yp_prot.h>
@ -65,30 +70,39 @@ __weak_alias(setgrent,_setgrent);
__weak_alias(setgroupent,_setgroupent);
#endif
static FILE *_gr_fp;
static struct group _gr_group;
static int _gr_stayopen;
static int grscan __P((int, gid_t, const char *));
static int start_gr __P((void));
static FILE *_gr_fp;
static struct group _gr_group;
static int _gr_stayopen;
static int _gr_nomore;
static int grscan __P((int, gid_t, const char *));
static int matchline __P((int, gid_t, const char *));
static int start_gr __P((void));
#define MAXGRP 200
static __aconst char *members[MAXGRP];
#define MAXLINELENGTH 1024
static char line[MAXLINELENGTH];
static __aconst char *members[MAXGRP];
static char line[MAXLINELENGTH];
#ifdef YP
enum _ypmode { YPMODE_NONE, YPMODE_FULL, YPMODE_NAME };
static enum _ypmode __ypmode;
static char *__ypcurrent, *__ypdomain;
static int __ypcurrentlen;
enum _grmode { GRMODE_NONE, GRMODE_FULL, GRMODE_NAME };
static enum _grmode __grmode;
static char *__ypcurrent, *__ypdomain;
static int __ypcurrentlen;
#endif
#ifdef HESIOD
static int __gr_hesnum;
#endif
struct group *
getgrent()
{
if ((!_gr_fp && !start_gr()) || !grscan(0, 0, NULL))
return(NULL);
return(&_gr_group);
_gr_nomore = 0;
if ((!_gr_fp && !start_gr()) || !grscan(0, 0, NULL) || _gr_nomore)
return(NULL);
return &_gr_group;
}
struct group *
@ -98,45 +112,44 @@ getgrnam(name)
int rval;
if (!start_gr())
return(NULL);
return NULL;
rval = grscan(1, 0, name);
if (!_gr_stayopen)
endgrent();
return(rval ? &_gr_group : NULL);
return (rval) ? &_gr_group : NULL;
}
struct group *
#ifdef __STDC__
getgrgid(gid_t gid)
#else
getgrgid(gid)
gid_t gid;
#endif
{
int rval;
if (!start_gr())
return(NULL);
return NULL;
rval = grscan(1, gid, NULL);
if (!_gr_stayopen)
endgrent();
return(rval ? &_gr_group : NULL);
return (rval) ? &_gr_group : NULL;
}
static int
start_gr()
{
#ifdef YP
__grmode = GRMODE_NONE;
if (__ypcurrent)
free(__ypcurrent);
__ypcurrent = NULL;
#endif
#ifdef HESIOD
__gr_hesnum = 0;
#endif
if (_gr_fp) {
rewind(_gr_fp);
#ifdef YP
__ypmode = YPMODE_NONE;
if (__ypcurrent)
free(__ypcurrent);
__ypcurrent = NULL;
#endif
return(1);
return 1;
}
return((_gr_fp = fopen(_PATH_GROUP, "r")) ? 1 : 0);
return (_gr_fp = fopen(_PATH_GROUP, "r")) ? 1 : 0;
}
void
@ -150,122 +163,50 @@ setgroupent(stayopen)
int stayopen;
{
if (!start_gr())
return(0);
return 0;
_gr_stayopen = stayopen;
return(1);
return 1;
}
void
endgrent()
{
#ifdef YP
__grmode = GRMODE_NONE;
if (__ypcurrent)
free(__ypcurrent);
__ypcurrent = NULL;
#endif
#ifdef HESIOD
__gr_hesnum = 0;
#endif
if (_gr_fp) {
(void)fclose(_gr_fp);
_gr_fp = NULL;
#ifdef YP
__ypmode = YPMODE_NONE;
if (__ypcurrent)
free(__ypcurrent);
__ypcurrent = NULL;
#endif
}
}
static int _local_grscan __P((void *, void *, va_list));
static int
grscan(search, gid, name)
int search;
gid_t gid;
const char *name;
_local_grscan(rv, cb_data, ap)
void *rv;
void *cb_data;
va_list ap;
{
__aconst char **m;
char *cp, *bp, *ep;
unsigned long id;
#ifdef YP
char *key, *data;
int keylen, datalen;
int r;
char *grname = (char *)NULL;
#endif
int search = va_arg(ap, int);
gid_t gid = va_arg(ap, gid_t);
const char *name = va_arg(ap, const char *);
for (;;) {
#ifdef YP
if (__ypmode != YPMODE_NONE) {
if (!__ypdomain) {
if (yp_get_default_domain(&__ypdomain)) {
__ypmode = YPMODE_NONE;
if (grname != (char *)NULL) {
free(grname);
grname = (char *)NULL;
}
continue;
}
if (!fgets(line, sizeof(line), _gr_fp)) {
if (!search) {
_gr_nomore = 1;
return NS_SUCCESS;
}
switch(__ypmode) {
case YPMODE_FULL:
data = NULL;
if (__ypcurrent) {
key = NULL;
r = yp_next(__ypdomain, "group.byname",
__ypcurrent, __ypcurrentlen,
&key, &keylen, &data, &datalen);
free(__ypcurrent);
if (r != 0) {
__ypcurrent = NULL;
if (key)
free(key);
}
else {
__ypcurrent = key;
__ypcurrentlen = keylen;
}
} else {
r = yp_first(__ypdomain, "group.byname",
&__ypcurrent, &__ypcurrentlen,
&data, &datalen);
}
if (r != 0) {
__ypmode = YPMODE_NONE;
if (data)
free(data);
continue;
}
memmove(line, data, (size_t)datalen);
free(data);
break;
case YPMODE_NAME:
if (grname != (char *)NULL) {
data = NULL;
r = yp_match(__ypdomain, "group.byname",
grname, (int)strlen(grname),
&data, &datalen);
__ypmode = YPMODE_NONE;
free(grname);
grname = (char *)NULL;
if (r != 0) {
if (data)
free(data);
continue;
}
memmove(line, data, (size_t)datalen);
free(data);
} else {
/* YP not available? */
__ypmode = YPMODE_NONE;
continue;
}
break;
case YPMODE_NONE:
abort(); /* Cannot happen */
break;
}
line[datalen] = '\0';
bp = line;
goto parse;
return NS_NOTFOUND;
}
#endif /* YP */
if (!fgets(line, sizeof(line), _gr_fp))
return(0);
bp = line;
/* skip lines that are too big */
if (!strchr(line, '\n')) {
int ch;
@ -274,114 +215,377 @@ grscan(search, gid, name)
;
continue;
}
if (matchline(search, gid, name))
return NS_SUCCESS;
}
/* NOTREACHED */
}
#ifdef HESIOD
static int _dns_grscan __P((void *, void *, va_list));
static int
_dns_grscan(rv, cb_data, ap)
void *rv;
void *cb_data;
va_list ap;
{
int search = va_arg(ap, int);
gid_t gid = va_arg(ap, gid_t);
const char *name = va_arg(ap, const char *);
char **hp;
for (;;) {
if (search) {
if (name)
strncpy(line, name, sizeof(line));
else
snprintf(line, sizeof(line), "%u", gid);
} else {
snprintf(line, sizeof(line), "group-%u", __gr_hesnum);
__gr_hesnum++;
}
line[sizeof(line) - 1] = '\0';
hp = hes_resolve(line, "group");
if (hp == NULL) {
switch (hes_error()) {
case HES_ER_NOTFOUND:
if (!search) {
__gr_hesnum = 0;
_gr_nomore = 1;
return NS_SUCCESS;
}
return NS_NOTFOUND;
case HES_ER_OK:
abort();
default:
return NS_UNAVAIL;
}
}
/* only check first elem */
strncpy(line, hp[0], sizeof(line));
line[sizeof(line) - 1] = '\0';
hes_free(hp);
if (matchline(search, gid, name))
return NS_SUCCESS;
else if (search)
return NS_NOTFOUND;
}
}
#endif
#ifdef YP
static int _nis_grscan __P((void *, void *, va_list));
static int
_nis_grscan(rv, cb_data, ap)
void *rv;
void *cb_data;
va_list ap;
{
int search = va_arg(ap, int);
gid_t gid = va_arg(ap, gid_t);
const char *name = va_arg(ap, const char *);
char *key, *data;
int keylen, datalen;
int r;
if(__ypdomain == NULL) {
switch (yp_get_default_domain(&__ypdomain)) {
case 0:
break;
case YPERR_RESRC:
return NS_TRYAGAIN;
default:
return NS_UNAVAIL;
}
}
if (search) { /* specific group or gid */
if (name)
strncpy(line, name, sizeof(line));
else
snprintf(line, sizeof(line), "%u", gid);
line[sizeof(line) - 1] = '\0';
data = NULL;
r = yp_match(__ypdomain,
(name) ? "group.byname" : "group.bygid",
line, (int)strlen(line), &data, &datalen);
switch (r) {
case 0:
break;
case YPERR_KEY:
if (data)
free(data);
return NS_NOTFOUND;
default:
if (data)
free(data);
return NS_UNAVAIL;
}
data[datalen] = '\0'; /* clear trailing \n */
strncpy(line, data, sizeof(line));
line[sizeof(line) - 1] = '\0';
free(data);
if (matchline(search, gid, name))
return NS_SUCCESS;
else
return NS_NOTFOUND;
}
for (;;) { /* ! search */
data = NULL;
if(__ypcurrent) {
key = NULL;
r = yp_next(__ypdomain, "group.byname",
__ypcurrent, __ypcurrentlen,
&key, &keylen, &data, &datalen);
free(__ypcurrent);
switch (r) {
case 0:
break;
case YPERR_NOMORE:
__ypcurrent = NULL;
if (key)
free(key);
if (data)
free(data);
_gr_nomore = 1;
return NS_SUCCESS;
default:
if (key)
free(key);
if (data)
free(data);
return NS_UNAVAIL;
}
__ypcurrent = key;
__ypcurrentlen = keylen;
} else {
if (yp_first(__ypdomain, "group.byname",
&__ypcurrent, &__ypcurrentlen,
&data, &datalen)) {
if (data);
free(data);
return NS_UNAVAIL;
}
}
data[datalen] = '\0'; /* clear trailing \n */
strncpy(line, data, sizeof(line));
line[sizeof(line) - 1] = '\0';
free(data);
if (matchline(search, gid, name))
return NS_SUCCESS;
}
/* NOTREACHED */
}
#endif
#if defined(YP) || defined(HESIOD)
/*
* log an error if "files" or "compat" is specified in group_compat database
*/
static int _bad_grscan __P((void *, void *, va_list));
static int
_bad_grscan(rv, cb_data, ap)
void *rv;
void *cb_data;
va_list ap;
{
static int warned;
if (!warned) {
syslog(LOG_ERR,
"nsswitch.conf group_compat database can't use '%s'",
(char *)cb_data);
}
warned = 1;
return NS_UNAVAIL;
}
/*
* when a name lookup in compat mode is required, look it up in group_compat
* nsswitch database. only Hesiod and NIS is supported - it doesn't make
* sense to lookup compat names from 'files' or 'compat'
*/
static int __grscancompat __P((int, gid_t, const char *));
static int
__grscancompat(search, gid, name)
int search;
gid_t gid;
const char *name;
{
static ns_dtab dtab[] = {
NS_FILES_CB(_bad_grscan, "files"),
NS_DNS_CB(_dns_grscan, NULL),
NS_NIS_CB(_nis_grscan, NULL),
NS_COMPAT_CB(_bad_grscan, "compat"),
{ 0 }
};
return nsdispatch(NULL, dtab, NSDB_GROUP_COMPAT, search, gid, name);
}
static int _compat_grscan __P((void *, void *, va_list));
static int
_compat_grscan(rv, cb_data, ap)
void *rv;
void *cb_data;
va_list ap;
{
int search = va_arg(ap, int);
gid_t gid = va_arg(ap, gid_t);
const char *name = va_arg(ap, const char *);
static char *grname = NULL;
for (;;) {
if(__grmode != GRMODE_NONE) {
int r;
switch(__grmode) {
case GRMODE_FULL:
r = __grscancompat(search, gid, name);
if (r == NS_SUCCESS)
return r;
__grmode = GRMODE_NONE;
break;
case GRMODE_NAME:
if(grname == (char *)NULL) {
__grmode = GRMODE_NONE;
break;
}
r = __grscancompat(1, 0, grname);
free(grname);
grname = (char *)NULL;
if (r != NS_SUCCESS)
break;
if (!search)
return NS_SUCCESS;
if (name) {
if (! strcmp(_gr_group.gr_name, name))
return NS_SUCCESS;
} else {
if (_gr_group.gr_gid == gid)
return NS_SUCCESS;
}
break;
case GRMODE_NONE:
abort();
}
continue;
}
if (!fgets(line, sizeof(line), _gr_fp))
return NS_NOTFOUND;
/* skip lines that are too big */
if (!strchr(line, '\n')) {
int ch;
while ((ch = getc(_gr_fp)) != '\n' && ch != EOF)
;
continue;
}
if (line[0] == '+') {
char *tptr, *bp;
switch(line[1]) {
case ':':
case '\0':
case '\n':
if (_yp_check(NULL)) {
if (!search) {
__ypmode = YPMODE_FULL;
continue;
}
if (!__ypdomain &&
yp_get_default_domain(&__ypdomain))
continue;
data = NULL;
if (name) {
r = yp_match(__ypdomain,
"group.byname",
name,
(int)strlen(name),
&data, &datalen);
} else {
char buf[20];
snprintf(buf, sizeof(buf),
"%u", gid);
r = yp_match(__ypdomain,
"group.bygid",
buf,
(int)strlen(buf),
&data, &datalen);
}
if (r != 0) {
if (data)
free(data);
continue;
}
memmove(line, data, (size_t)datalen);
free(data);
line[datalen] = '\0';
bp = line;
_gr_group.gr_name = strsep(&bp, ":\n");
_gr_group.gr_passwd =
strsep(&bp, ":\n");
if (!(cp = strsep(&bp, ":\n")))
continue;
if (name) {
id = strtoul(cp, &ep, 10);
if (id > GID_MAX || *ep != '\0')
continue;
_gr_group.gr_gid = (gid_t)id;
} else
_gr_group.gr_gid = gid;
goto found_it;
}
__grmode = GRMODE_FULL;
break;
default:
if (_yp_check(NULL)) {
char *tptr;
tptr = strsep(&bp, ":\n");
if (search && name &&
strcmp(tptr, name))
continue;
__ypmode = YPMODE_NAME;
grname = strdup(tptr + 1);
continue;
}
__grmode = GRMODE_NAME;
bp = line;
tptr = strsep(&bp, ":\n");
grname = strdup(tptr + 1);
break;
}
continue;
}
parse:
#endif /* YP */
_gr_group.gr_name = strsep(&bp, ":\n");
if (search && name && strcmp(_gr_group.gr_name, name))
continue;
_gr_group.gr_passwd = strsep(&bp, ":\n");
if (!(cp = strsep(&bp, ":\n")))
continue;
id = strtoul(cp, &ep, 10);
if (id > GID_MAX || *ep != '\0')
continue;
_gr_group.gr_gid = (gid_t)id;
if (search && name == NULL && _gr_group.gr_gid != gid)
continue;
found_it:
cp = NULL;
if (bp == NULL)
continue;
for (_gr_group.gr_mem = m = members;; bp++) {
if (m == &members[MAXGRP - 1])
break;
if (*bp == ',') {
if (cp) {
*bp = '\0';
*m++ = cp;
cp = NULL;
}
} else if (*bp == '\0' || *bp == '\n' || *bp == ' ') {
if (cp) {
*bp = '\0';
*m++ = cp;
}
break;
} else if (cp == NULL)
cp = bp;
}
*m = NULL;
return(1);
if (matchline(search, gid, name))
return NS_SUCCESS;
}
/* NOTREACHED */
}
#endif /* YP || HESIOD */
static int
grscan(search, gid, name)
int search;
gid_t gid;
const char *name;
{
int r;
static ns_dtab dtab[] = {
NS_FILES_CB(_local_grscan, NULL),
NS_DNS_CB(_dns_grscan, NULL),
NS_NIS_CB(_nis_grscan, NULL),
NS_COMPAT_CB(_compat_grscan, NULL),
{ 0 }
};
r = nsdispatch(NULL, dtab, NSDB_GROUP, search, gid, name);
return (r == NS_SUCCESS) ? 1 : 0;
}
static int
matchline(search, gid, name)
int search;
gid_t gid;
const char *name;
{
unsigned long id;
__aconst char **m;
char *cp, *bp, *ep;
if (line[0] == '+')
return 0; /* sanity check to prevent recursion */
bp = line;
_gr_group.gr_name = strsep(&bp, ":\n");
if (search && name && strcmp(_gr_group.gr_name, name))
return 0;
_gr_group.gr_passwd = strsep(&bp, ":\n");
if (!(cp = strsep(&bp, ":\n")))
return 0;
id = strtoul(cp, &ep, 10);
if (id > GID_MAX || *ep != '\0')
return 0;
_gr_group.gr_gid = (gid_t)id;
if (search && name == NULL && _gr_group.gr_gid != gid)
return 0;
cp = NULL;
if (bp == NULL)
return 0;
for (_gr_group.gr_mem = m = members;; bp++) {
if (m == &members[MAXGRP - 1])
break;
if (*bp == ',') {
if (cp) {
*bp = '\0';
*m++ = cp;
cp = NULL;
}
} else if (*bp == '\0' || *bp == '\n' || *bp == ' ') {
if (cp) {
*bp = '\0';
*m++ = cp;
}
break;
} else if (cp == NULL)
cp = bp;
}
*m = NULL;
return 1;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: getnetgrent.c,v 1.16 1998/07/27 09:47:44 mycroft Exp $ */
/* $NetBSD: getnetgrent.c,v 1.17 1999/01/16 07:47:19 lukem Exp $ */
/*
* Copyright (c) 1994 Christos Zoulas
@ -33,7 +33,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: getnetgrent.c,v 1.16 1998/07/27 09:47:44 mycroft Exp $");
__RCSID("$NetBSD: getnetgrent.c,v 1.17 1999/01/16 07:47:19 lukem Exp $");
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
@ -45,13 +45,16 @@ __RCSID("$NetBSD: getnetgrent.c,v 1.16 1998/07/27 09:47:44 mycroft Exp $");
#include <fcntl.h>
#include <err.h>
#include <ctype.h>
#include <nsswitch.h>
#include <stdlib.h>
#include <stringlist.h>
#include <db.h>
#ifdef YP
#include <rpc/rpc.h>
#include <rpcsvc/ypclnt.h>
#include <rpcsvc/yp_prot.h>
#endif
#ifdef __weak_alias
__weak_alias(endnetgrent,_endnetgrent);
__weak_alias(getnetgrent,_getnetgrent);
@ -71,17 +74,15 @@ static DB *_ng_db;
static int getstring __P((char **, int, __aconst char **));
static struct netgroup *getnetgroup __P((char **));
static int lookup __P((const char *, char *, char **, int));
static void addgroup __P((char *, StringList *, char *));
static int lookup __P((char *, char **, int));
static void addgroup __P((StringList *, char *));
static int in_check __P((const char *, const char *,
const char *, struct netgroup *));
static int in_find __P((char *, StringList *,
char *, const char *,
static int in_find __P((StringList *, char *, const char *,
const char *, const char *));
static char *in_lookup1 __P((const char *, const char *,
const char *, int));
static char *in_lookup1 __P((const char *, const char *, int));
static int in_lookup __P((const char *, const char *,
const char *, const char *, int));
const char *, int));
/*
* getstring(): Get a string delimited by the character, skipping leading and
@ -173,80 +174,139 @@ badhost:
}
static int _local_lookup __P((void *, void *, va_list));
static int
_local_lookup(rv, cb_data, ap)
void *rv;
void *cb_data;
va_list ap;
{
char *name = va_arg(ap, char *);
char **line = va_arg(ap, char **);
int bywhat = va_arg(ap, int);
DBT key, data;
size_t len;
char *ks;
int r;
if (_ng_db == NULL)
return NS_UNAVAIL;
len = strlen(name) + 2;
ks = malloc(len);
if (ks == NULL)
err(1, _ngoomem);
ks[0] = bywhat;
memcpy(&ks[1], name, len - 1);
key.data = (u_char *) ks;
key.size = len;
r = (_ng_db->get) (_ng_db, &key, &data, 0);
free(ks);
switch (r) {
case 0:
break;
case 1:
return NS_NOTFOUND;
case -1:
return NS_UNAVAIL;
}
*line = strdup(data.data);
if (*line == NULL)
return NS_UNAVAIL;
return NS_SUCCESS;
}
#ifdef YP
static int _nis_lookup __P((void *, void *, va_list));
static int
_nis_lookup(rv, cb_data, ap)
void *rv;
void *cb_data;
va_list ap;
{
char *name = va_arg(ap, char *);
char **line = va_arg(ap, char **);
int bywhat = va_arg(ap, int);
static char *__ypdomain;
int i;
char *map = NULL;
if(__ypdomain == NULL) {
switch (yp_get_default_domain(&__ypdomain)) {
case 0:
break;
case YPERR_RESRC:
return NS_TRYAGAIN;
default:
return NS_UNAVAIL;
}
}
switch (bywhat) {
case _NG_KEYBYNAME:
map = "netgroup";
break;
case _NG_KEYBYUSER:
map = "netgroup.byuser";
break;
case _NG_KEYBYHOST:
map = "netgroup.byhost";
break;
default:
abort();
break;
}
*line = NULL;
switch (yp_match(__ypdomain, map, name, (int)strlen(name), line, &i)) {
case 0:
return NS_SUCCESS;
case YPERR_KEY:
if (*line)
free(*line);
return NS_NOTFOUND;
default:
if (*line)
free(*line);
return NS_UNAVAIL;
}
/* NOTREACHED */
}
#endif
/*
* lookup(): Find the given key in the database or yp, and return its value
* in *line; returns 1 if key was found, 0 otherwise
*/
static int
lookup(ypdom, name, line, bywhat)
const char *ypdom;
char *name;
char **line;
int bywhat;
lookup(name, line, bywhat)
char *name;
char **line;
int bywhat;
{
#ifdef YP
int i;
char *map = NULL;
#endif
int r;
static ns_dtab dtab[] = {
NS_FILES_CB(_local_lookup, NULL),
NS_DNS_CB(_nis_lookup, NULL),
{ NULL, NULL, NULL }
};
if (_ng_db) {
DBT key, data;
size_t len = strlen(name) + 2;
char *ks = malloc(len);
ks[0] = bywhat;
memcpy(&ks[1], name, len - 1);
key.data = (u_char *) ks;
key.size = len;
switch ((_ng_db->get) (_ng_db, &key, &data, 0)) {
case 0:
free(ks);
*line = strdup(data.data);
if (*line == NULL)
err(1, _ngoomem);
return 1;
case 1:
break;
case -1:
warn("netgroup: db get");
break;
}
free(ks);
}
#ifdef YP
if (ypdom) {
switch (bywhat) {
case _NG_KEYBYNAME:
map = "netgroup";
break;
case _NG_KEYBYUSER:
map = "netgroup.byuser";
break;
case _NG_KEYBYHOST:
map = "netgroup.byhost";
break;
default:
abort();
break;
}
if (yp_match(ypdom, map, name, (int)strlen(name), line, &i) == 0)
return 1;
}
#endif
return 0;
r = nsdispatch(NULL, dtab, NSDB_NETGROUP, name, line, bywhat);
return (r == NS_SUCCESS) ? 1 : 0;
}
/*
* _ng_parse(): Parse a line and return: _NG_ERROR: Syntax Error _NG_NONE:
* line was empty or a comment _NG_GROUP: line had a netgroup definition,
@ -276,8 +336,8 @@ _ng_parse(p, name, ng)
}
return _NG_GROUP;
} else {
char *np;
size_t i;
char *np;
size_t i;
for (np = *p; **p && !_NG_ISSPACE(**p); (*p)++)
continue;
@ -300,8 +360,7 @@ _ng_parse(p, name, ng)
* addgroup(): Recursively add all the members of the netgroup to this group
*/
static void
addgroup(ypdom, sl, grp)
char *ypdom;
addgroup(sl, grp)
StringList *sl;
char *grp;
{
@ -321,8 +380,12 @@ addgroup(ypdom, sl, grp)
sl_add(sl, grp);
/* Lookup this netgroup */
if (!lookup(ypdom, grp, &line, _NG_KEYBYNAME))
line = NULL;
if (!lookup(grp, &line, _NG_KEYBYNAME)) {
if (line != NULL)
free(line);
return;
}
p = line;
@ -342,7 +405,7 @@ addgroup(ypdom, sl, grp)
case _NG_NAME:
/* netgroup name */
addgroup(ypdom, sl, name);
addgroup(sl, name);
break;
case _NG_ERROR:
@ -386,8 +449,7 @@ in_check(host, user, domain, ng)
* in_find(): Find a match for the host, user, domain spec
*/
static int
in_find(ypdom, sl, grp, host, user, domain)
char *ypdom;
in_find(sl, grp, host, user, domain)
StringList *sl;
char *grp;
const char *host;
@ -411,8 +473,12 @@ in_find(ypdom, sl, grp, host, user, domain)
sl_add(sl, grp);
/* Lookup this netgroup */
if (!lookup(ypdom, grp, &line, _NG_KEYBYNAME))
line = NULL;
if (!lookup(grp, &line, _NG_KEYBYNAME)) {
if (line)
free(line);
return 0;
}
p = line;
@ -441,7 +507,7 @@ in_find(ypdom, sl, grp, host, user, domain)
case _NG_NAME:
/* netgroup name */
if (in_find(ypdom, sl, name, host, user, domain)) {
if (in_find(sl, name, host, user, domain)) {
free(line);
return 1;
}
@ -490,8 +556,7 @@ _ng_print(buf, len, ng)
* in_lookup1(): Fast lookup for a key in the appropriate map
*/
static char *
in_lookup1(ypdom, key, domain, map)
const char *ypdom;
in_lookup1(key, domain, map)
const char *key;
const char *domain;
int map;
@ -503,7 +568,7 @@ in_lookup1(ypdom, key, domain, map)
len = (key ? strlen(key) : 1) + (domain ? strlen(domain) : 1) + 2;
ptr = _ng_makekey(key, domain, len);
res = lookup(ypdom, ptr, &line, map);
res = lookup(ptr, &line, map);
free(ptr);
return res ? line : NULL;
}
@ -513,8 +578,7 @@ in_lookup1(ypdom, key, domain, map)
* in_lookup(): Fast lookup for a key in the appropriate map
*/
static int
in_lookup(ypdom, group, key, domain, map)
const char *ypdom;
in_lookup(group, key, domain, map)
const char *group;
const char *key;
const char *domain;
@ -525,8 +589,8 @@ in_lookup(ypdom, group, key, domain, map)
if (domain != NULL) {
/* Domain specified; look in "group.domain" and "*.domain" */
if ((line = in_lookup1(ypdom, key, domain, map)) == NULL)
line = in_lookup1(ypdom, NULL, domain, map);
if ((line = in_lookup1(key, domain, map)) == NULL)
line = in_lookup1(NULL, domain, map);
}
else
line = NULL;
@ -536,8 +600,8 @@ in_lookup(ypdom, group, key, domain, map)
* domain not specified or domain lookup failed; look in
* "group.*" and "*.*"
*/
if (((line = in_lookup1(ypdom, key, NULL, map)) == NULL) &&
((line = in_lookup1(ypdom, NULL, NULL, map)) == NULL))
if (((line = in_lookup1(key, NULL, map)) == NULL) &&
((line = in_lookup1(NULL, NULL, map)) == NULL))
return 0;
}
@ -584,10 +648,7 @@ setnetgrent(ng)
const char *ng;
{
StringList *sl = sl_init();
#ifdef YP
char *line;
#endif
char *ng_copy, *ypdom = NULL;
char *ng_copy;
/* Cleanup any previous storage */
if (_nghead != NULL)
@ -596,20 +657,10 @@ setnetgrent(ng)
if (_ng_db == NULL)
_ng_db = dbopen(_PATH_NETGROUP_DB, O_RDONLY, 0, DB_HASH, NULL);
#ifdef YP
/*
* We use yp if there is a "+" in the netgroup file, or if there is
* no netgroup file at all
*/
if (_ng_db == NULL || lookup(NULL, "+", &line, _NG_KEYBYNAME) == 0)
yp_get_default_domain(&ypdom);
else
free(line);
#endif
ng_copy = strdup(ng);
if (ng_copy == NULL)
err(1, _ngoomem);
addgroup(ypdom, sl, ng_copy);
addgroup(sl, ng_copy);
_nghead = _nglist;
sl_free(sl, 1);
}
@ -638,35 +689,18 @@ int
innetgr(grp, host, user, domain)
const char *grp, *host, *user, *domain;
{
char *ypdom = NULL;
#ifdef YP
char *line;
#endif
int found;
StringList *sl;
if (_ng_db == NULL)
_ng_db = dbopen(_PATH_NETGROUP_DB, O_RDONLY, 0, DB_HASH, NULL);
#ifdef YP
/*
* We use yp if there is a "+" in the netgroup file, or if there is
* no netgroup file at all
*/
if (_ng_db == NULL)
yp_get_default_domain(&ypdom);
else if (lookup(NULL, "+", &line, _NG_KEYBYNAME) == 0) {
yp_get_default_domain(&ypdom);
free(line);
}
#endif
/* Try the fast lookup first */
if (host != NULL && user == NULL) {
if (in_lookup(ypdom, grp, host, domain, _NG_KEYBYHOST))
if (in_lookup(grp, host, domain, _NG_KEYBYHOST))
return 1;
} else if (host == NULL && user != NULL) {
if (in_lookup(ypdom, grp, user, domain, _NG_KEYBYUSER))
if (in_lookup(grp, user, domain, _NG_KEYBYUSER))
return 1;
}
/* If a domainname is given, we would have found a match */
@ -675,7 +709,7 @@ innetgr(grp, host, user, domain)
/* Too bad need the slow recursive way */
sl = sl_init();
found = in_find(ypdom, sl, strdup(grp), host, user, domain);
found = in_find(sl, strdup(grp), host, user, domain);
sl_free(sl, 1);
return found;

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: getusershell.c,v 1.12 1998/11/13 15:49:29 christos Exp $ */
/* $NetBSD: getusershell.c,v 1.13 1999/01/16 07:47:19 lukem Exp $ */
/*
* Copyright (c) 1985, 1993
@ -38,19 +38,29 @@
#if 0
static char sccsid[] = "@(#)getusershell.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: getusershell.c,v 1.12 1998/11/13 15:49:29 christos Exp $");
__RCSID("$NetBSD: getusershell.c,v 1.13 1999/01/16 07:47:19 lukem Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
#include <sys/param.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <stdio.h>
#include <ctype.h>
#include <nsswitch.h>
#include <stdlib.h>
#include <unistd.h>
#include <paths.h>
#include <string.h>
#include <stringlist.h>
#ifdef HESIOD
#include <hesiod.h>
#endif
#ifdef YP
#include <rpc/rpc.h>
#include <rpcsvc/ypclnt.h>
#include <rpcsvc/yp_prot.h>
#endif
#ifdef __weak_alias
__weak_alias(endusershell,_endusershell);
@ -64,12 +74,13 @@ __weak_alias(setusershell,_setusershell);
*/
static const char *const okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL };
static const char *const *curshell, **shells;
static char *strings;
static const char *const *curshell;
static StringList *sl;
static const char *const *initshells __P((void));
/*
* Get a list of shells from _PATH_SHELLS, if it exists.
* Get a list of shells from "shells" nsswitch database
*/
__aconst char *
getusershell()
@ -78,10 +89,7 @@ getusershell()
if (curshell == NULL)
curshell = initshells();
/* LINTED (auditing puproses only */
ret = (__aconst char *)*curshell;
if (ret != NULL)
curshell++;
return (ret);
@ -90,13 +98,9 @@ getusershell()
void
endusershell()
{
if (shells != NULL)
free(shells);
shells = NULL;
if (strings != NULL)
free(strings);
strings = NULL;
if (sl)
sl_free(sl, 1);
sl = NULL;
curshell = NULL;
}
@ -107,50 +111,170 @@ setusershell()
curshell = initshells();
}
static const char *const *
initshells()
{
const char **sp;
char *cp;
FILE *fp;
struct stat statb;
if (shells != NULL)
free(shells);
shells = NULL;
if (strings != NULL)
free(strings);
strings = NULL;
static int _local_initshells __P((void *, void *, va_list));
static int
_local_initshells(rv, cb_data, ap)
void *rv;
void *cb_data;
va_list ap;
{
char *sp, *cp;
FILE *fp;
char line[MAXPATHLEN + 2];
if (sl)
sl_free(sl, 1);
sl = sl_init();
if ((fp = fopen(_PATH_SHELLS, "r")) == NULL)
return (okshells);
if (fstat(fileno(fp), &statb) == -1) {
(void)fclose(fp);
return (okshells);
}
if ((cp = malloc((u_int)statb.st_size)) == NULL) {
(void)fclose(fp);
return (okshells);
}
sp = calloc((unsigned)statb.st_size / 3, sizeof (char *));
if (sp == NULL) {
(void)fclose(fp);
free(cp);
strings = NULL;
return (okshells);
}
shells = sp;
strings = cp;
return NS_UNAVAIL;
sp = cp = line;
while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
while (*cp != '#' && *cp != '/' && *cp != '\0')
cp++;
if (*cp == '#' || *cp == '\0')
continue;
*sp++ = cp;
sp = cp;
while (!isspace(*cp) && *cp != '#' && *cp != '\0')
cp++;
*cp++ = '\0';
sl_add(sl, strdup(sp));
}
*sp = NULL;
(void)fclose(fp);
return (shells);
return NS_SUCCESS;
}
#ifdef HESIOD
static int _dns_initshells __P((void *, void *, va_list));
static int
_dns_initshells(rv, cb_data, ap)
void *rv;
void *cb_data;
va_list ap;
{
char shellname[] = "shells-XXXXX";
int hsindex, hpi;
char **hp;
if (sl)
sl_free(sl, 1);
sl = sl_init();
for (hsindex = 0; ; hsindex++) {
snprintf(shellname, sizeof(shellname)-1, "shells-%d", hsindex);
hp = hes_resolve(shellname, "shells");
if (hp == NULL) {
switch(hes_error()) {
case HES_ER_OK:
break;
case HES_ER_NOTFOUND:
if (hsindex == 0)
return NS_NOTFOUND;
return NS_SUCCESS;
default:
return NS_UNAVAIL;
}
} else {
for (hpi = 0; hp[hpi]; hpi++)
sl_add(sl, hp[hpi]);
free(hp);
}
}
return NS_SUCCESS;
}
#endif /* HESIOD */
#ifdef YP
static int _nis_initshells __P((void *, void *, va_list));
static int
_nis_initshells(rv, cb_data, ap)
void *rv;
void *cb_data;
va_list ap;
{
static char *ypdomain;
if (sl)
sl_free(sl, 1);
sl = sl_init();
if (ypdomain == NULL) {
switch (yp_get_default_domain(&ypdomain)) {
case 0:
break;
case YPERR_RESRC:
return NS_TRYAGAIN;
default:
return NS_UNAVAIL;
}
}
for (;;) {
char *ypcur = NULL;
int ypcurlen;
char *key, *data;
int keylen, datalen;
int r;
key = data = NULL;
if (ypcur) {
r = yp_next(ypdomain, "shells", ypcur, ypcurlen,
&key, &keylen, &data, &datalen);
free(ypcur);
switch (r) {
case 0:
break;
case YPERR_NOMORE:
free(key);
free(data);
return NS_SUCCESS;
default:
free(key);
free(data);
return NS_UNAVAIL;
}
ypcur = key;
ypcurlen = keylen;
} else {
if (yp_first(ypdomain, "shells", &ypcur,
&ypcurlen, &data, &datalen)) {
free(data);
return NS_UNAVAIL;
}
}
data[datalen] = '\0'; /* clear trailing \n */
sl_add(sl, data);
}
return NS_SUCCESS;
}
#endif /* YP */
static const char *const *
initshells()
{
static ns_dtab dtab[] = {
NS_FILES_CB(_local_initshells, NULL),
NS_DNS_CB(_dns_initshells, NULL),
NS_NIS_CB(_nis_initshells, NULL),
{ NULL, NULL, NULL }
};
if (sl)
sl_free(sl, 1);
sl = sl_init();
if (nsdispatch(NULL, dtab, NSDB_SHELLS) != NS_SUCCESS) {
if (sl)
sl_free(sl, 1);
sl = NULL;
return (okshells);
}
sl_add(sl, NULL);
return (const char *const *)(sl->sl_str);
}