pull nsswitch up to main branch
This commit is contained in:
parent
34410d5d0c
commit
0eb8645e3a
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue