freebsd-dev/lib/libc/gen/getnetgrent.c

1017 lines
25 KiB
C
Raw Normal View History

/*-
* SPDX-License-Identifier: BSD-3-Clause
*
1994-05-27 05:00:24 +00:00
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Rick Macklem at The University of Guelph.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
1994-05-27 05:00:24 +00:00
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__SCCSID("@(#)getnetgrent.c 8.2 (Berkeley) 4/27/95");
__FBSDID("$FreeBSD$");
1994-05-27 05:00:24 +00:00
#include "namespace.h"
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <nsswitch.h>
#include <pthread.h>
#include <pthread_np.h>
1994-05-27 05:00:24 +00:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "nss_tls.h"
#ifdef YP
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
/*
* Notes:
* We want to be able to use NIS netgroups properly while retaining
* the ability to use a local /etc/netgroup file. Unfortunately, you
* can't really do both at the same time - at least, not efficiently.
* NetBSD deals with this problem by creating a netgroup database
* using Berkeley DB (just like the password database) that allows
* for lookups using netgroup, netgroup.byuser or netgroup.byhost
* searches. This is a neat idea, but I don't have time to implement
* something like that now. (I think ultimately it would be nice
* if we DB-fied the group and netgroup stuff all in one shot, but
* for now I'm satisfied just to have something that works well
* without requiring massive code changes.)
*
* Therefore, to still permit the use of the local file and maintain
* optimum NIS performance, we allow for the following conditions:
*
* - If /etc/netgroup does not exist and NIS is turned on, we use
* NIS netgroups only.
*
* - If /etc/netgroup exists but is empty, we use NIS netgroups
* only.
*
* - If /etc/netgroup exists and contains _only_ a '+', we use
* NIS netgroups only.
*
* - If /etc/netgroup exists, contains locally defined netgroups
* and a '+', we use a mixture of NIS and the local entries.
* This method should return the same NIS data as just using
* NIS alone, but it will be slower if the NIS netgroup database
* is large (innetgr() in particular will suffer since extra
* processing has to be done in order to determine memberships
* using just the raw netgroup data).
*
* - If /etc/netgroup exists and contains only locally defined
* netgroup entries, we use just those local entries and ignore
* NIS (this is the original, pre-NIS behavior).
*/
#include <rpc/rpc.h>
#include <rpcsvc/yp_prot.h>
#include <rpcsvc/ypclnt.h>
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
#include <sys/param.h>
#include <sys/stat.h>
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
#include <sys/errno.h>
static char *_netgr_yp_domain;
int _use_only_yp;
static int _netgr_yp_enabled;
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
static int _yp_innetgr;
#endif
1994-05-27 05:00:24 +00:00
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
#ifndef _PATH_NETGROUP
1994-05-27 05:00:24 +00:00
#define _PATH_NETGROUP "/etc/netgroup"
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
#endif
1994-05-27 05:00:24 +00:00
enum constants {
NGRP_STORAGE_INITIAL = 1 << 10, /* 1 KByte */
NGRP_STORAGE_MAX = 1 << 20, /* 1 MByte */
};
static const ns_src defaultsrc[] = {
{ NSSRC_COMPAT, NS_SUCCESS },
{ NULL, 0 },
};
1994-05-27 05:00:24 +00:00
/*
* Static Variables and functions used by setnetgrent(), getnetgrent() and
* endnetgrent().
* There are two linked lists:
* - linelist is just used by setnetgrent() to parse the net group file via.
* parse_netgrp()
* - netgrp is the list of entries for the current netgroup
*/
struct linelist {
struct linelist *l_next; /* Chain ptr. */
int l_parsed; /* Flag for cycles */
char *l_groupname; /* Name of netgroup */
char *l_line; /* Netgroup entrie(s) to be parsed */
};
struct netgrp {
struct netgrp *ng_next; /* Chain ptr */
char *ng_str[3]; /* Field pointers, see below */
};
struct netgr_state {
FILE *st_netf;
struct linelist *st_linehead;
struct netgrp *st_nextgrp;
struct netgrp *st_gr;
char *st_grname;
};
1994-05-27 05:00:24 +00:00
#define NG_HOST 0 /* Host name */
#define NG_USER 1 /* User name */
#define NG_DOM 2 /* and Domain name */
static void netgr_endstate(void *);
NSS_TLS_HANDLING(netgr);
static int files_endnetgrent(void *, void *, va_list);
static int files_getnetgrent_r(void *, void *, va_list);
static int files_setnetgrent(void *, void *, va_list);
static int compat_endnetgrent(void *, void *, va_list);
static int compat_innetgr(void *, void *, va_list);
static int compat_getnetgrent_r(void *, void *, va_list);
static int compat_setnetgrent(void *, void *, va_list);
static void _compat_clearstate(void);
static int _getnetgrent_r(char **, char **, char **, char *, size_t, int *,
struct netgr_state *);
static int _innetgr_fallback(void *, void *, const char *, const char *,
const char *, const char *);
static int innetgr_fallback(void *, void *, va_list);
static int parse_netgrp(const char *, struct netgr_state *, int);
static struct linelist *read_for_group(const char *, struct netgr_state *, int);
1994-05-27 05:00:24 +00:00
#define LINSIZ 1024 /* Length of netgroup file line */
static const ns_dtab getnetgrent_dtab[] = {
NS_FILES_CB(files_getnetgrent_r, NULL)
NS_COMPAT_CB(compat_getnetgrent_r, NULL)
{ NULL, NULL, NULL },
};
static const ns_dtab setnetgrent_dtab[] = {
NS_FILES_CB(files_setnetgrent, NULL)
NS_COMPAT_CB(compat_setnetgrent, NULL)
{ NULL, NULL, NULL },
};
static const ns_dtab endnetgrent_dtab[] = {
NS_FILES_CB(files_endnetgrent, NULL)
NS_COMPAT_CB(compat_endnetgrent, NULL)
{ NULL, NULL, NULL },
};
static struct netgr_state compat_state;
static void
netgr_endstate(void *arg)
{
struct linelist *lp, *olp;
struct netgrp *gp, *ogp;
struct netgr_state *st;
st = (struct netgr_state *)arg;
lp = st->st_linehead;
while (lp != NULL) {
olp = lp;
lp = lp->l_next;
free(olp->l_groupname);
free(olp->l_line);
free(olp);
}
st->st_linehead = NULL;
if (st->st_grname != NULL) {
free(st->st_grname);
st->st_grname = NULL;
}
gp = st->st_gr;
while (gp != NULL) {
ogp = gp;
gp = gp->ng_next;
free(ogp->ng_str[NG_HOST]);
free(ogp->ng_str[NG_USER]);
free(ogp->ng_str[NG_DOM]);
free(ogp);
}
st->st_gr = NULL;
st->st_nextgrp = NULL;
}
static int
files_getnetgrent_r(void *retval, void *mdata, va_list ap)
{
struct netgr_state *st;
char **hostp, **userp, **domp, *buf;
size_t bufsize;
int *errnop;
hostp = va_arg(ap, char **);
userp = va_arg(ap, char **);
domp = va_arg(ap, char **);
buf = va_arg(ap, char *);
bufsize = va_arg(ap, size_t);
errnop = va_arg(ap, int *);
if (netgr_getstate(&st) != 0)
return (NS_UNAVAIL);
return (_getnetgrent_r(hostp, userp, domp, buf, bufsize, errnop, st));
}
static int
files_setnetgrent(void *retval, void *mdata, va_list ap)
{
const ns_src src[] = {
{ NSSRC_FILES, NS_SUCCESS },
{ NULL, 0 },
};
struct netgr_state *st;
const char *group;
int rv;
group = va_arg(ap, const char *);
if (group == NULL || group[0] == '\0')
return (NS_RETURN);
rv = netgr_getstate(&st);
if (rv != 0)
return (NS_UNAVAIL);
if (st->st_gr == NULL || strcmp(group, st->st_grname) != 0) {
(void)_nsdispatch(NULL, endnetgrent_dtab, NSDB_NETGROUP,
"endnetgrent", src);
if ((st->st_netf = fopen(_PATH_NETGROUP, "re")) != NULL) {
if (parse_netgrp(group, st, 0) != 0)
(void)_nsdispatch(NULL, endnetgrent_dtab,
NSDB_NETGROUP, "endnetgrent", src);
else
st->st_grname = strdup(group);
(void)fclose(st->st_netf);
st->st_netf = NULL;
}
}
st->st_nextgrp = st->st_gr;
return (st->st_grname != NULL ? NS_SUCCESS : NS_NOTFOUND);
}
static int
files_endnetgrent(void *retval, void *mdata, va_list ap)
{
struct netgr_state *st;
if (netgr_getstate(&st) != 0)
return (NS_UNAVAIL);
netgr_endstate(st);
return (NS_SUCCESS);
}
static int
compat_getnetgrent_r(void *retval, void *mdata, va_list ap)
{
char **hostp, **userp, **domp, *buf;
size_t bufsize;
int *errnop;
#ifdef YP
_yp_innetgr = 0;
#endif
hostp = va_arg(ap, char **);
userp = va_arg(ap, char **);
domp = va_arg(ap, char **);
buf = va_arg(ap, char *);
bufsize = va_arg(ap, size_t);
errnop = va_arg(ap, int *);
return (_getnetgrent_r(hostp, userp, domp, buf, bufsize, errnop,
&compat_state));
}
1994-05-27 05:00:24 +00:00
/*
* compat_setnetgrent()
1994-05-27 05:00:24 +00:00
* Parse the netgroup file looking for the netgroup and build the list
* of netgrp structures. Let parse_netgrp() and read_for_group() do
* most of the work.
*/
static int
compat_setnetgrent(void *retval, void *mdata, va_list ap)
1994-05-27 05:00:24 +00:00
{
FILE *netf;
const char *group;
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
#ifdef YP
struct stat _yp_statp;
char _yp_plus;
#endif
group = va_arg(ap, const char *);
/* Sanity check */
if (group == NULL || !strlen(group))
return (NS_RETURN);
if (compat_state.st_gr == NULL ||
strcmp(group, compat_state.st_grname) != 0) {
_compat_clearstate();
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
#ifdef YP
/* Presumed guilty until proven innocent. */
_use_only_yp = 0;
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
/*
* If /etc/netgroup doesn't exist or is empty,
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
* use NIS exclusively.
*/
if (((stat(_PATH_NETGROUP, &_yp_statp) < 0) &&
2012-06-16 13:11:10 +00:00
errno == ENOENT) || _yp_statp.st_size == 0)
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
_use_only_yp = _netgr_yp_enabled = 1;
if ((netf = fopen(_PATH_NETGROUP,"re")) != NULL ||_use_only_yp){
compat_state.st_netf = netf;
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
/*
* Icky: grab the first character of the netgroup file
* and turn on NIS if it's a '+'. rewind the stream
* afterwards so we don't goof up read_for_group() later.
*/
if (netf) {
fscanf(netf, "%c", &_yp_plus);
rewind(netf);
if (_yp_plus == '+')
_use_only_yp = _netgr_yp_enabled = 1;
}
/*
* If we were called specifically for an innetgr()
* lookup and we're in NIS-only mode, short-circuit
* parse_netgroup() and cut directly to the chase.
*/
if (_use_only_yp && _yp_innetgr) {
/* dohw! */
if (netf != NULL)
fclose(netf);
return (NS_RETURN);
}
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
#else
if ((netf = fopen(_PATH_NETGROUP, "re"))) {
compat_state.st_netf = netf;
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
#endif
if (parse_netgrp(group, &compat_state, 1)) {
_compat_clearstate();
} else {
compat_state.st_grname = strdup(group);
1994-05-27 05:00:24 +00:00
}
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
if (netf)
fclose(netf);
1994-05-27 05:00:24 +00:00
}
}
compat_state.st_nextgrp = compat_state.st_gr;
return (NS_SUCCESS);
1994-05-27 05:00:24 +00:00
}
static void
_compat_clearstate(void)
1994-05-27 05:00:24 +00:00
{
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
#ifdef YP
_netgr_yp_enabled = 0;
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
#endif
netgr_endstate(&compat_state);
1994-05-27 05:00:24 +00:00
}
/*
* compat_endnetgrent() - cleanup
1994-05-27 05:00:24 +00:00
*/
static int
compat_endnetgrent(void *retval, void *mdata, va_list ap)
1994-05-27 05:00:24 +00:00
{
_compat_clearstate();
return (NS_SUCCESS);
}
int
_getnetgrent_r(char **hostp, char **userp, char **domp, char *buf,
size_t bufsize, int *errnop, struct netgr_state *st)
{
char *p, *src;
size_t len;
int rv;
#define COPY_NG_ELEM(dstp, i) do { \
src = st->st_nextgrp->ng_str[(i)]; \
if (src == NULL) \
src = ""; \
len = strlcpy(p, src, bufsize); \
if (len >= bufsize) { \
*errnop = ERANGE; \
return (NS_RETURN); \
} \
*(dstp) = p; \
p += len + 1; \
bufsize -= len + 1; \
} while (0)
p = buf;
if (st->st_nextgrp != NULL) {
COPY_NG_ELEM(hostp, NG_HOST);
COPY_NG_ELEM(userp, NG_USER);
COPY_NG_ELEM(domp, NG_DOM);
st->st_nextgrp = st->st_nextgrp->ng_next;
rv = NS_SUCCESS;
} else {
rv = NS_NOTFOUND;
1994-05-27 05:00:24 +00:00
}
#undef COPY_NG_ELEM
return (rv);
1994-05-27 05:00:24 +00:00
}
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
#ifdef YP
static int
_listmatch(const char *list, const char *group, int len)
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
{
const char *ptr = list;
const char *cptr;
int glen = strlen(group);
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
/* skip possible leading whitespace */
2012-06-16 13:11:10 +00:00
while (isspace((unsigned char)*ptr))
ptr++;
while (ptr < list + len) {
cptr = ptr;
1999-11-04 04:16:28 +00:00
while(*ptr != ',' && *ptr != '\0' && !isspace((unsigned char)*ptr))
ptr++;
if (strncmp(cptr, group, glen) == 0 && glen == (ptr - cptr))
return (1);
2012-06-16 13:11:10 +00:00
while (*ptr == ',' || isspace((unsigned char)*ptr))
ptr++;
}
return (0);
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
}
static int
_revnetgr_lookup(char* lookupdom, char* map, const char* str,
const char* dom, const char* group)
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
{
int y, rv, rot;
char key[MAXHOSTNAMELEN];
char *result;
int resultlen;
for (rot = 0; ; rot++) {
switch (rot) {
case 0:
snprintf(key, MAXHOSTNAMELEN, "%s.%s", str,
dom ? dom : lookupdom);
break;
case 1:
snprintf(key, MAXHOSTNAMELEN, "%s.*", str);
break;
case 2:
snprintf(key, MAXHOSTNAMELEN, "*.%s",
dom ? dom : lookupdom);
break;
case 3:
snprintf(key, MAXHOSTNAMELEN, "*.*");
break;
default:
return (0);
}
y = yp_match(lookupdom, map, key, strlen(key), &result,
&resultlen);
if (y == 0) {
rv = _listmatch(result, group, resultlen);
free(result);
if (rv)
return (1);
} else if (y != YPERR_KEY) {
/*
* If we get an error other than 'no
* such key in map' then something is
* wrong and we should stop the search.
*/
return (-1);
}
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
}
}
#endif
1994-05-27 05:00:24 +00:00
/*
* Search for a match in a netgroup.
*/
static int
compat_innetgr(void *retval, void *mdata, va_list ap)
1994-05-27 05:00:24 +00:00
{
#ifdef YP
const ns_src src[] = {
{ mdata, NS_SUCCESS },
{ NULL, 0 },
};
#endif
const char *group, *host, *user, *dom;
group = va_arg(ap, const char *);
host = va_arg(ap, const char *);
user = va_arg(ap, const char *);
dom = va_arg(ap, const char *);
if (group == NULL || !strlen(group))
return (NS_RETURN);
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
#ifdef YP
_yp_innetgr = 1;
(void)_nsdispatch(NULL, setnetgrent_dtab, NSDB_NETGROUP, "setnetgrent",
src, group);
_yp_innetgr = 0;
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
/*
* If we're in NIS-only mode, do the search using
* NIS 'reverse netgroup' lookups.
*
* What happens with 'reverse netgroup' lookups:
*
* 1) try 'reverse netgroup' lookup
* 1.a) if host is specified and user is null:
* look in netgroup.byhost
* (try host.domain, host.*, *.domain or *.*)
* if found, return yes
* 1.b) if user is specified and host is null:
* look in netgroup.byuser
* (try host.domain, host.*, *.domain or *.*)
* if found, return yes
* 1.c) if both host and user are specified,
* don't do 'reverse netgroup' lookup. It won't work.
* 1.d) if neither host ane user are specified (why?!?)
* don't do 'reverse netgroup' lookup either.
* 2) if domain is specified and 'reverse lookup' is done:
* 'reverse lookup' was authoritative. bye bye.
* 3) otherwise, too bad, try it the slow way.
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
*/
if (_use_only_yp && (host == NULL) != (user == NULL)) {
int ret;
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
if(yp_get_default_domain(&_netgr_yp_domain))
return (NS_NOTFOUND);
ret = _revnetgr_lookup(_netgr_yp_domain,
host?"netgroup.byhost":"netgroup.byuser",
host?host:user, dom, group);
if (ret == 1) {
*(int *)retval = 1;
return (NS_SUCCESS);
} else if (ret == 0 && dom != NULL) {
*(int *)retval = 0;
return (NS_SUCCESS);
}
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
}
#endif /* YP */
return (_innetgr_fallback(retval, mdata, group, host, user, dom));
}
static int
_innetgr_fallback(void *retval, void *mdata, const char *group, const char *host,
const char *user, const char *dom)
{
const ns_src src[] = {
{ mdata, NS_SUCCESS },
{ NULL, 0 },
};
char *h, *u, *d;
char *buf;
size_t bufsize;
int rv, ret_errno;
if (group == NULL || group[0] == '\0')
return (NS_RETURN);
bufsize = NGRP_STORAGE_INITIAL;
buf = malloc(bufsize);
if (buf == NULL)
return (NS_UNAVAIL);
*(int *)retval = 0;
(void)_nsdispatch(NULL, setnetgrent_dtab, NSDB_NETGROUP, "setnetgrent",
src, group);
for (;;) {
do {
ret_errno = 0;
rv = _nsdispatch(NULL, getnetgrent_dtab, NSDB_NETGROUP,
"getnetgrent_r", src, &h, &u, &d, buf, bufsize,
&ret_errno);
if (rv != NS_SUCCESS && ret_errno == ERANGE) {
bufsize *= 2;
if (bufsize > NGRP_STORAGE_MAX ||
(buf = reallocf(buf, bufsize)) == NULL)
goto out;
}
} while (rv != NS_SUCCESS && ret_errno == ERANGE);
if (rv != NS_SUCCESS) {
if (rv == NS_NOTFOUND && ret_errno == 0)
rv = NS_SUCCESS;
break;
1994-05-27 05:00:24 +00:00
}
if ((host == NULL || h == NULL || strcmp(host, h) == 0) &&
(user == NULL || u == NULL || strcmp(user, u) == 0) &&
(dom == NULL || d == NULL || strcmp(dom, d) == 0)) {
*(int *)retval = 1;
break;
}
}
out:
free(buf);
(void)_nsdispatch(NULL, endnetgrent_dtab, NSDB_NETGROUP, "endnetgrent",
src);
return (rv);
}
static int
innetgr_fallback(void *retval, void *mdata, va_list ap)
{
const char *group, *host, *user, *dom;
group = va_arg(ap, const char *);
host = va_arg(ap, const char *);
user = va_arg(ap, const char *);
dom = va_arg(ap, const char *);
return (_innetgr_fallback(retval, mdata, group, host, user, dom));
1994-05-27 05:00:24 +00:00
}
/*
* Parse the netgroup file setting up the linked lists.
*/
static int
parse_netgrp(const char *group, struct netgr_state *st, int niscompat)
1994-05-27 05:00:24 +00:00
{
struct netgrp *grp;
struct linelist *lp = st->st_linehead;
char **ng;
char *epos, *gpos, *pos, *spos;
int freepos, len, strpos;
Fixes for PR #508 and #509 ('botched 'Bad netgroup' error message' and 'cycle in netgroup check too greedy'). PR #508 is apparently due to an inconsistency in the way the 4.4BSD netgroup code deals with bad netgroups. When 4.4BSD code encounters a badly formed netgroup entry (e.g. (somehost,-somedomain), which, because of the missing comma between the '-' and 'somedomain,' has only 2 fields instead of 3), it generates an error message and then bails out without doing any more processing on the netgroup containing the bad entry. Conversely, every other *NIX in the world that usees netgroups just tries to parse the entry as best it can and then silently continues on its way. The result is that two bad things happen: 1) we ignore other valid entries within the netgroup containing the bogus entry, which prevents us from interoperating with other systems that don't behave this way, and 2) by printing an error to stderr from inside libc, we hose certain programs, in this case rlogind. In the problem report, Bill Fenner noted that the 'B' from 'Bad' was missing, and that rlogind exited immediately after generating the error. The missing 'B' is apparently not caused by any problem in getnetgrent.c; more likely it's getting swallowed up by rlogind somehow, and the error message itself causes rlogind to become confused. I was able to duplicate this problem and discovered that running a simple test program on my FreeBSD system resulted in a properly formatted (if confusing) error, whereas triggering the error by trying to rlogin to the machine yielded the missing 'B' problem. Anyway, the fixes for this are as follows: - The error message has been reformatted so that it prints out more useful information (e.g. Bad entry (somehost,-somedomain) in netgroup "foo"). We check for NULL entries so that we don't print '(null)' anymore too. :) - Rearranged things in parse_netgrp() so that we make a best guess at what bad entries are supposed to look like and then continue processing instead of bailing out. - Even though the error message has been cleaned up, it's wrapped inside a #ifdef DEBUG. This way we match the behavior of other systems. Since we now handle the error condition better anyway, this error message becomes less important. PR #507 is another case of inconsistency. The code that handles duplicate/circular netgroup entries isn't really 'too greedy; -- it's just too noisy. If you have a netgroup containing duplicate entries, the code actually does the right thing, but it also generates an error message. As with the 'Bad netgroup' message, spewing this out from inside libc can also hose certain programs (like rlogind). Again, no other system generates an error message in this case. The only change here is to hide the error message inside an #ifdef DEBUG. Like the other message, it's largely superfluous since the code handles the condition correctly. Note that PR #510 (+@netgroup host matching in /etc/hosts.equiv) is still being investigated. I haven't been able to duplicate it myself, and I strongly suspect it to be a configuration problem of some kind. However, I'm leaving all three PRs open until I get 510 resolved just for the sake of paranoia.
1995-06-23 14:47:54 +00:00
#ifdef DEBUG
int fields;
Fixes for PR #508 and #509 ('botched 'Bad netgroup' error message' and 'cycle in netgroup check too greedy'). PR #508 is apparently due to an inconsistency in the way the 4.4BSD netgroup code deals with bad netgroups. When 4.4BSD code encounters a badly formed netgroup entry (e.g. (somehost,-somedomain), which, because of the missing comma between the '-' and 'somedomain,' has only 2 fields instead of 3), it generates an error message and then bails out without doing any more processing on the netgroup containing the bad entry. Conversely, every other *NIX in the world that usees netgroups just tries to parse the entry as best it can and then silently continues on its way. The result is that two bad things happen: 1) we ignore other valid entries within the netgroup containing the bogus entry, which prevents us from interoperating with other systems that don't behave this way, and 2) by printing an error to stderr from inside libc, we hose certain programs, in this case rlogind. In the problem report, Bill Fenner noted that the 'B' from 'Bad' was missing, and that rlogind exited immediately after generating the error. The missing 'B' is apparently not caused by any problem in getnetgrent.c; more likely it's getting swallowed up by rlogind somehow, and the error message itself causes rlogind to become confused. I was able to duplicate this problem and discovered that running a simple test program on my FreeBSD system resulted in a properly formatted (if confusing) error, whereas triggering the error by trying to rlogin to the machine yielded the missing 'B' problem. Anyway, the fixes for this are as follows: - The error message has been reformatted so that it prints out more useful information (e.g. Bad entry (somehost,-somedomain) in netgroup "foo"). We check for NULL entries so that we don't print '(null)' anymore too. :) - Rearranged things in parse_netgrp() so that we make a best guess at what bad entries are supposed to look like and then continue processing instead of bailing out. - Even though the error message has been cleaned up, it's wrapped inside a #ifdef DEBUG. This way we match the behavior of other systems. Since we now handle the error condition better anyway, this error message becomes less important. PR #507 is another case of inconsistency. The code that handles duplicate/circular netgroup entries isn't really 'too greedy; -- it's just too noisy. If you have a netgroup containing duplicate entries, the code actually does the right thing, but it also generates an error message. As with the 'Bad netgroup' message, spewing this out from inside libc can also hose certain programs (like rlogind). Again, no other system generates an error message in this case. The only change here is to hide the error message inside an #ifdef DEBUG. Like the other message, it's largely superfluous since the code handles the condition correctly. Note that PR #510 (+@netgroup host matching in /etc/hosts.equiv) is still being investigated. I haven't been able to duplicate it myself, and I strongly suspect it to be a configuration problem of some kind. However, I'm leaving all three PRs open until I get 510 resolved just for the sake of paranoia.
1995-06-23 14:47:54 +00:00
#endif
1994-05-27 05:00:24 +00:00
/*
* First, see if the line has already been read in.
*/
while (lp) {
if (!strcmp(group, lp->l_groupname))
break;
lp = lp->l_next;
}
if (lp == NULL && (lp = read_for_group(group, st, niscompat)) == NULL)
1994-05-27 05:00:24 +00:00
return (1);
if (lp->l_parsed) {
Fixes for PR #508 and #509 ('botched 'Bad netgroup' error message' and 'cycle in netgroup check too greedy'). PR #508 is apparently due to an inconsistency in the way the 4.4BSD netgroup code deals with bad netgroups. When 4.4BSD code encounters a badly formed netgroup entry (e.g. (somehost,-somedomain), which, because of the missing comma between the '-' and 'somedomain,' has only 2 fields instead of 3), it generates an error message and then bails out without doing any more processing on the netgroup containing the bad entry. Conversely, every other *NIX in the world that usees netgroups just tries to parse the entry as best it can and then silently continues on its way. The result is that two bad things happen: 1) we ignore other valid entries within the netgroup containing the bogus entry, which prevents us from interoperating with other systems that don't behave this way, and 2) by printing an error to stderr from inside libc, we hose certain programs, in this case rlogind. In the problem report, Bill Fenner noted that the 'B' from 'Bad' was missing, and that rlogind exited immediately after generating the error. The missing 'B' is apparently not caused by any problem in getnetgrent.c; more likely it's getting swallowed up by rlogind somehow, and the error message itself causes rlogind to become confused. I was able to duplicate this problem and discovered that running a simple test program on my FreeBSD system resulted in a properly formatted (if confusing) error, whereas triggering the error by trying to rlogin to the machine yielded the missing 'B' problem. Anyway, the fixes for this are as follows: - The error message has been reformatted so that it prints out more useful information (e.g. Bad entry (somehost,-somedomain) in netgroup "foo"). We check for NULL entries so that we don't print '(null)' anymore too. :) - Rearranged things in parse_netgrp() so that we make a best guess at what bad entries are supposed to look like and then continue processing instead of bailing out. - Even though the error message has been cleaned up, it's wrapped inside a #ifdef DEBUG. This way we match the behavior of other systems. Since we now handle the error condition better anyway, this error message becomes less important. PR #507 is another case of inconsistency. The code that handles duplicate/circular netgroup entries isn't really 'too greedy; -- it's just too noisy. If you have a netgroup containing duplicate entries, the code actually does the right thing, but it also generates an error message. As with the 'Bad netgroup' message, spewing this out from inside libc can also hose certain programs (like rlogind). Again, no other system generates an error message in this case. The only change here is to hide the error message inside an #ifdef DEBUG. Like the other message, it's largely superfluous since the code handles the condition correctly. Note that PR #510 (+@netgroup host matching in /etc/hosts.equiv) is still being investigated. I haven't been able to duplicate it myself, and I strongly suspect it to be a configuration problem of some kind. However, I'm leaving all three PRs open until I get 510 resolved just for the sake of paranoia.
1995-06-23 14:47:54 +00:00
#ifdef DEBUG
/*
* This error message is largely superflous since the
* code handles the error condition sucessfully, and
* spewing it out from inside libc can actually hose
* certain programs.
*/
1994-05-27 05:00:24 +00:00
fprintf(stderr, "Cycle in netgroup %s\n", lp->l_groupname);
Fixes for PR #508 and #509 ('botched 'Bad netgroup' error message' and 'cycle in netgroup check too greedy'). PR #508 is apparently due to an inconsistency in the way the 4.4BSD netgroup code deals with bad netgroups. When 4.4BSD code encounters a badly formed netgroup entry (e.g. (somehost,-somedomain), which, because of the missing comma between the '-' and 'somedomain,' has only 2 fields instead of 3), it generates an error message and then bails out without doing any more processing on the netgroup containing the bad entry. Conversely, every other *NIX in the world that usees netgroups just tries to parse the entry as best it can and then silently continues on its way. The result is that two bad things happen: 1) we ignore other valid entries within the netgroup containing the bogus entry, which prevents us from interoperating with other systems that don't behave this way, and 2) by printing an error to stderr from inside libc, we hose certain programs, in this case rlogind. In the problem report, Bill Fenner noted that the 'B' from 'Bad' was missing, and that rlogind exited immediately after generating the error. The missing 'B' is apparently not caused by any problem in getnetgrent.c; more likely it's getting swallowed up by rlogind somehow, and the error message itself causes rlogind to become confused. I was able to duplicate this problem and discovered that running a simple test program on my FreeBSD system resulted in a properly formatted (if confusing) error, whereas triggering the error by trying to rlogin to the machine yielded the missing 'B' problem. Anyway, the fixes for this are as follows: - The error message has been reformatted so that it prints out more useful information (e.g. Bad entry (somehost,-somedomain) in netgroup "foo"). We check for NULL entries so that we don't print '(null)' anymore too. :) - Rearranged things in parse_netgrp() so that we make a best guess at what bad entries are supposed to look like and then continue processing instead of bailing out. - Even though the error message has been cleaned up, it's wrapped inside a #ifdef DEBUG. This way we match the behavior of other systems. Since we now handle the error condition better anyway, this error message becomes less important. PR #507 is another case of inconsistency. The code that handles duplicate/circular netgroup entries isn't really 'too greedy; -- it's just too noisy. If you have a netgroup containing duplicate entries, the code actually does the right thing, but it also generates an error message. As with the 'Bad netgroup' message, spewing this out from inside libc can also hose certain programs (like rlogind). Again, no other system generates an error message in this case. The only change here is to hide the error message inside an #ifdef DEBUG. Like the other message, it's largely superfluous since the code handles the condition correctly. Note that PR #510 (+@netgroup host matching in /etc/hosts.equiv) is still being investigated. I haven't been able to duplicate it myself, and I strongly suspect it to be a configuration problem of some kind. However, I'm leaving all three PRs open until I get 510 resolved just for the sake of paranoia.
1995-06-23 14:47:54 +00:00
#endif
1994-05-27 05:00:24 +00:00
return (1);
} else
lp->l_parsed = 1;
pos = lp->l_line;
/* Watch for null pointer dereferences, dammit! */
while (pos != NULL && *pos != '\0') {
1994-05-27 05:00:24 +00:00
if (*pos == '(') {
grp = malloc(sizeof(*grp));
if (grp == NULL)
return (1);
ng = grp->ng_str;
bzero(grp, sizeof(*grp));
1994-05-27 05:00:24 +00:00
pos++;
gpos = strsep(&pos, ")");
Fixes for PR #508 and #509 ('botched 'Bad netgroup' error message' and 'cycle in netgroup check too greedy'). PR #508 is apparently due to an inconsistency in the way the 4.4BSD netgroup code deals with bad netgroups. When 4.4BSD code encounters a badly formed netgroup entry (e.g. (somehost,-somedomain), which, because of the missing comma between the '-' and 'somedomain,' has only 2 fields instead of 3), it generates an error message and then bails out without doing any more processing on the netgroup containing the bad entry. Conversely, every other *NIX in the world that usees netgroups just tries to parse the entry as best it can and then silently continues on its way. The result is that two bad things happen: 1) we ignore other valid entries within the netgroup containing the bogus entry, which prevents us from interoperating with other systems that don't behave this way, and 2) by printing an error to stderr from inside libc, we hose certain programs, in this case rlogind. In the problem report, Bill Fenner noted that the 'B' from 'Bad' was missing, and that rlogind exited immediately after generating the error. The missing 'B' is apparently not caused by any problem in getnetgrent.c; more likely it's getting swallowed up by rlogind somehow, and the error message itself causes rlogind to become confused. I was able to duplicate this problem and discovered that running a simple test program on my FreeBSD system resulted in a properly formatted (if confusing) error, whereas triggering the error by trying to rlogin to the machine yielded the missing 'B' problem. Anyway, the fixes for this are as follows: - The error message has been reformatted so that it prints out more useful information (e.g. Bad entry (somehost,-somedomain) in netgroup "foo"). We check for NULL entries so that we don't print '(null)' anymore too. :) - Rearranged things in parse_netgrp() so that we make a best guess at what bad entries are supposed to look like and then continue processing instead of bailing out. - Even though the error message has been cleaned up, it's wrapped inside a #ifdef DEBUG. This way we match the behavior of other systems. Since we now handle the error condition better anyway, this error message becomes less important. PR #507 is another case of inconsistency. The code that handles duplicate/circular netgroup entries isn't really 'too greedy; -- it's just too noisy. If you have a netgroup containing duplicate entries, the code actually does the right thing, but it also generates an error message. As with the 'Bad netgroup' message, spewing this out from inside libc can also hose certain programs (like rlogind). Again, no other system generates an error message in this case. The only change here is to hide the error message inside an #ifdef DEBUG. Like the other message, it's largely superfluous since the code handles the condition correctly. Note that PR #510 (+@netgroup host matching in /etc/hosts.equiv) is still being investigated. I haven't been able to duplicate it myself, and I strongly suspect it to be a configuration problem of some kind. However, I'm leaving all three PRs open until I get 510 resolved just for the sake of paranoia.
1995-06-23 14:47:54 +00:00
#ifdef DEBUG
fields = 0;
#endif
1994-05-27 05:00:24 +00:00
for (strpos = 0; strpos < 3; strpos++) {
if ((spos = strsep(&gpos, ",")) == NULL) {
Fixes for PR #508 and #509 ('botched 'Bad netgroup' error message' and 'cycle in netgroup check too greedy'). PR #508 is apparently due to an inconsistency in the way the 4.4BSD netgroup code deals with bad netgroups. When 4.4BSD code encounters a badly formed netgroup entry (e.g. (somehost,-somedomain), which, because of the missing comma between the '-' and 'somedomain,' has only 2 fields instead of 3), it generates an error message and then bails out without doing any more processing on the netgroup containing the bad entry. Conversely, every other *NIX in the world that usees netgroups just tries to parse the entry as best it can and then silently continues on its way. The result is that two bad things happen: 1) we ignore other valid entries within the netgroup containing the bogus entry, which prevents us from interoperating with other systems that don't behave this way, and 2) by printing an error to stderr from inside libc, we hose certain programs, in this case rlogind. In the problem report, Bill Fenner noted that the 'B' from 'Bad' was missing, and that rlogind exited immediately after generating the error. The missing 'B' is apparently not caused by any problem in getnetgrent.c; more likely it's getting swallowed up by rlogind somehow, and the error message itself causes rlogind to become confused. I was able to duplicate this problem and discovered that running a simple test program on my FreeBSD system resulted in a properly formatted (if confusing) error, whereas triggering the error by trying to rlogin to the machine yielded the missing 'B' problem. Anyway, the fixes for this are as follows: - The error message has been reformatted so that it prints out more useful information (e.g. Bad entry (somehost,-somedomain) in netgroup "foo"). We check for NULL entries so that we don't print '(null)' anymore too. :) - Rearranged things in parse_netgrp() so that we make a best guess at what bad entries are supposed to look like and then continue processing instead of bailing out. - Even though the error message has been cleaned up, it's wrapped inside a #ifdef DEBUG. This way we match the behavior of other systems. Since we now handle the error condition better anyway, this error message becomes less important. PR #507 is another case of inconsistency. The code that handles duplicate/circular netgroup entries isn't really 'too greedy; -- it's just too noisy. If you have a netgroup containing duplicate entries, the code actually does the right thing, but it also generates an error message. As with the 'Bad netgroup' message, spewing this out from inside libc can also hose certain programs (like rlogind). Again, no other system generates an error message in this case. The only change here is to hide the error message inside an #ifdef DEBUG. Like the other message, it's largely superfluous since the code handles the condition correctly. Note that PR #510 (+@netgroup host matching in /etc/hosts.equiv) is still being investigated. I haven't been able to duplicate it myself, and I strongly suspect it to be a configuration problem of some kind. However, I'm leaving all three PRs open until I get 510 resolved just for the sake of paranoia.
1995-06-23 14:47:54 +00:00
/*
* All other systems I've tested
* return NULL for empty netgroup
* fields. It's up to user programs
* to handle the NULLs appropriately.
*/
ng[strpos] = NULL;
continue;
}
#ifdef DEBUG
fields++;
#endif
while (*spos == ' ' || *spos == '\t')
spos++;
if ((epos = strpbrk(spos, " \t"))) {
*epos = '\0';
len = epos - spos;
} else
len = strlen(spos);
if (len <= 0)
continue;
ng[strpos] = malloc(len + 1);
if (ng[strpos] == NULL) {
for (freepos = 0; freepos < strpos;
freepos++)
free(ng[freepos]);
free(grp);
return (1);
Fixes for PR #508 and #509 ('botched 'Bad netgroup' error message' and 'cycle in netgroup check too greedy'). PR #508 is apparently due to an inconsistency in the way the 4.4BSD netgroup code deals with bad netgroups. When 4.4BSD code encounters a badly formed netgroup entry (e.g. (somehost,-somedomain), which, because of the missing comma between the '-' and 'somedomain,' has only 2 fields instead of 3), it generates an error message and then bails out without doing any more processing on the netgroup containing the bad entry. Conversely, every other *NIX in the world that usees netgroups just tries to parse the entry as best it can and then silently continues on its way. The result is that two bad things happen: 1) we ignore other valid entries within the netgroup containing the bogus entry, which prevents us from interoperating with other systems that don't behave this way, and 2) by printing an error to stderr from inside libc, we hose certain programs, in this case rlogind. In the problem report, Bill Fenner noted that the 'B' from 'Bad' was missing, and that rlogind exited immediately after generating the error. The missing 'B' is apparently not caused by any problem in getnetgrent.c; more likely it's getting swallowed up by rlogind somehow, and the error message itself causes rlogind to become confused. I was able to duplicate this problem and discovered that running a simple test program on my FreeBSD system resulted in a properly formatted (if confusing) error, whereas triggering the error by trying to rlogin to the machine yielded the missing 'B' problem. Anyway, the fixes for this are as follows: - The error message has been reformatted so that it prints out more useful information (e.g. Bad entry (somehost,-somedomain) in netgroup "foo"). We check for NULL entries so that we don't print '(null)' anymore too. :) - Rearranged things in parse_netgrp() so that we make a best guess at what bad entries are supposed to look like and then continue processing instead of bailing out. - Even though the error message has been cleaned up, it's wrapped inside a #ifdef DEBUG. This way we match the behavior of other systems. Since we now handle the error condition better anyway, this error message becomes less important. PR #507 is another case of inconsistency. The code that handles duplicate/circular netgroup entries isn't really 'too greedy; -- it's just too noisy. If you have a netgroup containing duplicate entries, the code actually does the right thing, but it also generates an error message. As with the 'Bad netgroup' message, spewing this out from inside libc can also hose certain programs (like rlogind). Again, no other system generates an error message in this case. The only change here is to hide the error message inside an #ifdef DEBUG. Like the other message, it's largely superfluous since the code handles the condition correctly. Note that PR #510 (+@netgroup host matching in /etc/hosts.equiv) is still being investigated. I haven't been able to duplicate it myself, and I strongly suspect it to be a configuration problem of some kind. However, I'm leaving all three PRs open until I get 510 resolved just for the sake of paranoia.
1995-06-23 14:47:54 +00:00
}
bcopy(spos, ng[strpos], len + 1);
1994-05-27 05:00:24 +00:00
}
grp->ng_next = st->st_gr;
st->st_gr = grp;
Fixes for PR #508 and #509 ('botched 'Bad netgroup' error message' and 'cycle in netgroup check too greedy'). PR #508 is apparently due to an inconsistency in the way the 4.4BSD netgroup code deals with bad netgroups. When 4.4BSD code encounters a badly formed netgroup entry (e.g. (somehost,-somedomain), which, because of the missing comma between the '-' and 'somedomain,' has only 2 fields instead of 3), it generates an error message and then bails out without doing any more processing on the netgroup containing the bad entry. Conversely, every other *NIX in the world that usees netgroups just tries to parse the entry as best it can and then silently continues on its way. The result is that two bad things happen: 1) we ignore other valid entries within the netgroup containing the bogus entry, which prevents us from interoperating with other systems that don't behave this way, and 2) by printing an error to stderr from inside libc, we hose certain programs, in this case rlogind. In the problem report, Bill Fenner noted that the 'B' from 'Bad' was missing, and that rlogind exited immediately after generating the error. The missing 'B' is apparently not caused by any problem in getnetgrent.c; more likely it's getting swallowed up by rlogind somehow, and the error message itself causes rlogind to become confused. I was able to duplicate this problem and discovered that running a simple test program on my FreeBSD system resulted in a properly formatted (if confusing) error, whereas triggering the error by trying to rlogin to the machine yielded the missing 'B' problem. Anyway, the fixes for this are as follows: - The error message has been reformatted so that it prints out more useful information (e.g. Bad entry (somehost,-somedomain) in netgroup "foo"). We check for NULL entries so that we don't print '(null)' anymore too. :) - Rearranged things in parse_netgrp() so that we make a best guess at what bad entries are supposed to look like and then continue processing instead of bailing out. - Even though the error message has been cleaned up, it's wrapped inside a #ifdef DEBUG. This way we match the behavior of other systems. Since we now handle the error condition better anyway, this error message becomes less important. PR #507 is another case of inconsistency. The code that handles duplicate/circular netgroup entries isn't really 'too greedy; -- it's just too noisy. If you have a netgroup containing duplicate entries, the code actually does the right thing, but it also generates an error message. As with the 'Bad netgroup' message, spewing this out from inside libc can also hose certain programs (like rlogind). Again, no other system generates an error message in this case. The only change here is to hide the error message inside an #ifdef DEBUG. Like the other message, it's largely superfluous since the code handles the condition correctly. Note that PR #510 (+@netgroup host matching in /etc/hosts.equiv) is still being investigated. I haven't been able to duplicate it myself, and I strongly suspect it to be a configuration problem of some kind. However, I'm leaving all three PRs open until I get 510 resolved just for the sake of paranoia.
1995-06-23 14:47:54 +00:00
#ifdef DEBUG
/*
* Note: on other platforms, malformed netgroup
* entries are not normally flagged. While we
* can catch bad entries and report them, we should
* stay silent by default for compatibility's sake.
*/
if (fields < 3) {
fprintf(stderr,
"Bad entry (%s%s%s%s%s) in netgroup \"%s\"\n",
ng[NG_HOST] == NULL ? "" : ng[NG_HOST],
ng[NG_USER] == NULL ? "" : ",",
ng[NG_USER] == NULL ? "" : ng[NG_USER],
ng[NG_DOM] == NULL ? "" : ",",
ng[NG_DOM] == NULL ? "" : ng[NG_DOM],
lp->l_groupname);
}
Fixes for PR #508 and #509 ('botched 'Bad netgroup' error message' and 'cycle in netgroup check too greedy'). PR #508 is apparently due to an inconsistency in the way the 4.4BSD netgroup code deals with bad netgroups. When 4.4BSD code encounters a badly formed netgroup entry (e.g. (somehost,-somedomain), which, because of the missing comma between the '-' and 'somedomain,' has only 2 fields instead of 3), it generates an error message and then bails out without doing any more processing on the netgroup containing the bad entry. Conversely, every other *NIX in the world that usees netgroups just tries to parse the entry as best it can and then silently continues on its way. The result is that two bad things happen: 1) we ignore other valid entries within the netgroup containing the bogus entry, which prevents us from interoperating with other systems that don't behave this way, and 2) by printing an error to stderr from inside libc, we hose certain programs, in this case rlogind. In the problem report, Bill Fenner noted that the 'B' from 'Bad' was missing, and that rlogind exited immediately after generating the error. The missing 'B' is apparently not caused by any problem in getnetgrent.c; more likely it's getting swallowed up by rlogind somehow, and the error message itself causes rlogind to become confused. I was able to duplicate this problem and discovered that running a simple test program on my FreeBSD system resulted in a properly formatted (if confusing) error, whereas triggering the error by trying to rlogin to the machine yielded the missing 'B' problem. Anyway, the fixes for this are as follows: - The error message has been reformatted so that it prints out more useful information (e.g. Bad entry (somehost,-somedomain) in netgroup "foo"). We check for NULL entries so that we don't print '(null)' anymore too. :) - Rearranged things in parse_netgrp() so that we make a best guess at what bad entries are supposed to look like and then continue processing instead of bailing out. - Even though the error message has been cleaned up, it's wrapped inside a #ifdef DEBUG. This way we match the behavior of other systems. Since we now handle the error condition better anyway, this error message becomes less important. PR #507 is another case of inconsistency. The code that handles duplicate/circular netgroup entries isn't really 'too greedy; -- it's just too noisy. If you have a netgroup containing duplicate entries, the code actually does the right thing, but it also generates an error message. As with the 'Bad netgroup' message, spewing this out from inside libc can also hose certain programs (like rlogind). Again, no other system generates an error message in this case. The only change here is to hide the error message inside an #ifdef DEBUG. Like the other message, it's largely superfluous since the code handles the condition correctly. Note that PR #510 (+@netgroup host matching in /etc/hosts.equiv) is still being investigated. I haven't been able to duplicate it myself, and I strongly suspect it to be a configuration problem of some kind. However, I'm leaving all three PRs open until I get 510 resolved just for the sake of paranoia.
1995-06-23 14:47:54 +00:00
#endif
1994-05-27 05:00:24 +00:00
} else {
spos = strsep(&pos, ", \t");
if (parse_netgrp(spos, st, niscompat))
continue;
1994-05-27 05:00:24 +00:00
}
if (pos == NULL)
break;
while (*pos == ' ' || *pos == ',' || *pos == '\t')
pos++;
1994-05-27 05:00:24 +00:00
}
return (0);
}
/*
* Read the netgroup file and save lines until the line for the netgroup
* is found. Return 1 if eof is encountered.
*/
static struct linelist *
read_for_group(const char *group, struct netgr_state *st, int niscompat)
1994-05-27 05:00:24 +00:00
{
char *linep, *olinep, *pos, *spos;
int len, olen;
1994-05-27 05:00:24 +00:00
int cont;
struct linelist *lp;
char line[LINSIZ + 2];
FILE *netf;
#ifdef YP
char *result;
int resultlen;
linep = NULL;
1994-05-27 05:00:24 +00:00
netf = st->st_netf;
while ((_netgr_yp_enabled && niscompat) ||
fgets(line, LINSIZ, netf) != NULL) {
if (_netgr_yp_enabled) {
if(!_netgr_yp_domain)
if(yp_get_default_domain(&_netgr_yp_domain))
continue;
if (yp_match(_netgr_yp_domain, "netgroup", group,
strlen(group), &result, &resultlen)) {
free(result);
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
if (_use_only_yp)
return ((struct linelist *)0);
else {
_netgr_yp_enabled = 0;
continue;
}
}
if (strlen(result) == 0) {
free(result);
return (NULL);
}
snprintf(line, LINSIZ, "%s %s", group, result);
free(result);
}
#else
linep = NULL;
1994-05-27 05:00:24 +00:00
while (fgets(line, LINSIZ, netf) != NULL) {
#endif
pos = (char *)&line;
#ifdef YP
if (niscompat && *pos == '+') {
_netgr_yp_enabled = 1;
continue;
}
#endif
1994-05-27 05:00:24 +00:00
if (*pos == '#')
continue;
while (*pos == ' ' || *pos == '\t')
pos++;
spos = pos;
while (*pos != ' ' && *pos != '\t' && *pos != '\n' &&
*pos != '\0')
pos++;
len = pos - spos;
while (*pos == ' ' || *pos == '\t')
pos++;
if (*pos != '\n' && *pos != '\0') {
lp = malloc(sizeof (*lp));
if (lp == NULL)
return (NULL);
1994-05-27 05:00:24 +00:00
lp->l_parsed = 0;
lp->l_groupname = malloc(len + 1);
if (lp->l_groupname == NULL) {
free(lp);
return (NULL);
}
1994-05-27 05:00:24 +00:00
bcopy(spos, lp->l_groupname, len);
*(lp->l_groupname + len) = '\0';
len = strlen(pos);
olen = 0;
/*
* Loop around handling line continuations.
*/
do {
if (*(pos + len - 1) == '\n')
len--;
if (*(pos + len - 1) == '\\') {
len--;
cont = 1;
} else
cont = 0;
if (len > 0) {
linep = malloc(olen + len + 1);
if (linep == NULL) {
free(lp->l_groupname);
free(lp);
if (olen > 0)
free(olinep);
return (NULL);
1994-05-27 05:00:24 +00:00
}
if (olen > 0) {
bcopy(olinep, linep, olen);
free(olinep);
}
1994-05-27 05:00:24 +00:00
bcopy(pos, linep + olen, len);
olen += len;
*(linep + olen) = '\0';
olinep = linep;
1994-05-27 05:00:24 +00:00
}
if (cont) {
if (fgets(line, LINSIZ, netf)) {
pos = line;
len = strlen(pos);
} else
cont = 0;
}
} while (cont);
lp->l_line = linep;
lp->l_next = st->st_linehead;
st->st_linehead = lp;
1994-05-27 05:00:24 +00:00
/*
* If this is the one we wanted, we are done.
*/
if (!strcmp(lp->l_groupname, group))
return (lp);
}
}
Just when you thought it was safe... - getnetgrent.c: address some NIS compatibility problems. We really need to use the netgroup.byuser and netgroup.byhost maps to speed up innetgr() when using NIS. Also, change the NIS interaction in the following way: If /etc/netgroup does not exist or is empty (or contains only the NIS '+' token), we now use NIS exclusively. This lets us use the 'reverse netgroup' maps and is more or less the behavior of other platforms. If /etc/netgroup exists and contains local netgroup data (but no '+'). we use only lthe local stuff and ignore NIS. If /etc/netgroup exists and contains both local data and the '+', we use the local data nd the netgroup map as a single combined database (which, unfortunately, can be slow when the netgroup database is large). This is what we have been doing up until now. Head off a potential NULL pointer dereference in the old innetgr() matching code. Also fix the way the NIS netgroup map is incorporated into things: adding the '+' is supposed to make it seem as though the netgroup database is 'inserted' wherever the '+' is placed. We didn't quite do it that way before. (The NetBSD people apparently use a real, honest-to-gosh, netgroup.db database that works just like the password database. This is actually a neat idea since netgroups is the sort of thing that can really benefit from having multi-key search capability, particularly since reverse lookups require more than a trivial amount of processing. Should we do something like this too?) - netgroup.5: document all this stuff. - rcmd.c: some sleuthing with some test programs linked with my own version of innetgr() has revealed that SunOS always passes the NIS domain name to innetgr() in the 'domain' argument. We might as well do the same (if YP is defined). - ether_addr.c: also fix the NIS interaction so that placing the '+' token in the /etc/ethers file makes it seem like the NIS ethers data is 'inserted' at that point. (Chances are nobody will notice the effect of this change, which is just te way I like it. :)
1995-08-07 03:42:14 +00:00
#ifdef YP
/*
* Yucky. The recursive nature of this whole mess might require
* us to make more than one pass through the netgroup file.
* This might be best left outside the #ifdef YP, but YP is
* defined by default anyway, so I'll leave it like this
* until I know better.
*/
rewind(netf);
#endif
return (NULL);
1994-05-27 05:00:24 +00:00
}
int
getnetgrent_r(char **hostp, char **userp, char **domp, char *buf, size_t bufsize)
{
int rv, ret_errno;
ret_errno = 0;
rv = _nsdispatch(NULL, getnetgrent_dtab, NSDB_NETGROUP, "getnetgrent_r",
defaultsrc, hostp, userp, domp, buf, bufsize, &ret_errno);
if (rv == NS_SUCCESS) {
return (1);
} else {
errno = ret_errno;
return (0);
}
}
int
getnetgrent(char **hostp, char **userp, char **domp)
{
static char *ngrp_storage;
static size_t ngrp_storage_size;
int ret_errno, rv;
if (ngrp_storage == NULL) {
ngrp_storage_size = NGRP_STORAGE_INITIAL;
ngrp_storage = malloc(ngrp_storage_size);
if (ngrp_storage == NULL)
return (0);
}
do {
ret_errno = 0;
rv = _nsdispatch(NULL, getnetgrent_dtab, NSDB_NETGROUP,
"getnetgrent_r", defaultsrc, hostp, userp, domp,
ngrp_storage, ngrp_storage_size, &ret_errno);
if (rv != NS_SUCCESS && ret_errno == ERANGE) {
ngrp_storage_size *= 2;
if (ngrp_storage_size > NGRP_STORAGE_MAX) {
free(ngrp_storage);
ngrp_storage = NULL;
errno = ERANGE;
return (0);
}
ngrp_storage = reallocf(ngrp_storage,
ngrp_storage_size);
if (ngrp_storage == NULL)
return (0);
}
} while (rv != NS_SUCCESS && ret_errno == ERANGE);
if (rv == NS_SUCCESS) {
return (1);
} else {
errno = ret_errno;
return (0);
}
}
void
setnetgrent(const char *netgroup)
{
(void)_nsdispatch(NULL, setnetgrent_dtab, NSDB_NETGROUP, "setnetgrent",
defaultsrc, netgroup);
}
void
endnetgrent(void)
{
(void)_nsdispatch(NULL, endnetgrent_dtab, NSDB_NETGROUP, "endnetgrent",
defaultsrc);
}
int
innetgr(const char *netgroup, const char *host, const char *user,
const char *domain)
{
static const ns_dtab dtab[] = {
NS_COMPAT_CB(compat_innetgr, NULL)
NS_FALLBACK_CB(innetgr_fallback)
{ NULL, NULL, NULL },
};
int result, rv;
rv = _nsdispatch(&result, dtab, NSDB_NETGROUP, "innetgr", defaultsrc,
netgroup, host, user, domain);
return (rv == NS_SUCCESS ? result : 0);
}