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. All advertising materials mentioning features or use of this software
|
|
|
|
* must display the following acknowledgement:
|
|
|
|
* This product includes software developed by the University of
|
|
|
|
* California, Berkeley and its contributors.
|
|
|
|
* 4. Neither the name of the University nor the names of its contributors
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#if defined(LIBC_SCCS) && !defined(lint)
|
1997-03-11 11:52:33 +00:00
|
|
|
static char sccsid[] = "@(#)getnetgrent.c 8.2 (Berkeley) 4/27/95";
|
1994-05-27 05:00:24 +00:00
|
|
|
#endif /* LIBC_SCCS and not lint */
|
2002-02-01 01:08:48 +00:00
|
|
|
#include <sys/cdefs.h>
|
|
|
|
__FBSDID("$FreeBSD$");
|
1994-05-27 05:00:24 +00:00
|
|
|
|
2003-01-03 23:55:58 +00:00
|
|
|
#include <ctype.h>
|
1994-05-27 05:00:24 +00:00
|
|
|
#include <stdio.h>
|
1995-04-04 05:36:16 +00:00
|
|
|
#include <stdlib.h>
|
2002-04-25 18:14:39 +00:00
|
|
|
#include <string.h>
|
1995-04-04 05:36:16 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#ifdef YP
|
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).
|
|
|
|
*/
|
1997-10-11 00:03:25 +00:00
|
|
|
|
1995-04-04 05:36:16 +00:00
|
|
|
#include <rpc/rpc.h>
|
|
|
|
#include <rpcsvc/yp_prot.h>
|
|
|
|
#include <rpcsvc/ypclnt.h>
|
1995-08-07 03:42:14 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/errno.h>
|
|
|
|
static char *_netgr_yp_domain;
|
1995-09-02 04:08:55 +00:00
|
|
|
int _use_only_yp;
|
1995-04-04 05:36:16 +00:00
|
|
|
static int _netgr_yp_enabled;
|
1995-08-07 03:42:14 +00:00
|
|
|
static int _yp_innetgr;
|
1995-04-04 05:36:16 +00:00
|
|
|
#endif
|
1994-05-27 05:00:24 +00:00
|
|
|
|
1995-08-07 03:42:14 +00:00
|
|
|
#ifndef _PATH_NETGROUP
|
1994-05-27 05:00:24 +00:00
|
|
|
#define _PATH_NETGROUP "/etc/netgroup"
|
1995-08-07 03:42:14 +00:00
|
|
|
#endif
|
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 */
|
|
|
|
};
|
|
|
|
#define NG_HOST 0 /* Host name */
|
|
|
|
#define NG_USER 1 /* User name */
|
|
|
|
#define NG_DOM 2 /* and Domain name */
|
|
|
|
|
|
|
|
static struct linelist *linehead = (struct linelist *)0;
|
|
|
|
static struct netgrp *nextgrp = (struct netgrp *)0;
|
|
|
|
static struct {
|
|
|
|
struct netgrp *gr;
|
|
|
|
char *grname;
|
|
|
|
} grouphead = {
|
|
|
|
(struct netgrp *)0,
|
|
|
|
(char *)0,
|
|
|
|
};
|
|
|
|
static FILE *netf = (FILE *)0;
|
|
|
|
static int parse_netgrp();
|
|
|
|
static struct linelist *read_for_group();
|
|
|
|
void setnetgrent(), endnetgrent();
|
|
|
|
int getnetgrent(), innetgr();
|
|
|
|
|
|
|
|
#define LINSIZ 1024 /* Length of netgroup file line */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* setnetgrent()
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
setnetgrent(group)
|
|
|
|
char *group;
|
|
|
|
{
|
1995-08-07 03:42:14 +00:00
|
|
|
#ifdef YP
|
|
|
|
struct stat _yp_statp;
|
|
|
|
char _yp_plus;
|
|
|
|
#endif
|
|
|
|
|
1995-03-24 20:42:28 +00:00
|
|
|
/* Sanity check */
|
1995-03-23 22:21:16 +00:00
|
|
|
|
1995-03-24 20:42:28 +00:00
|
|
|
if (group == NULL || !strlen(group))
|
1995-03-23 22:21:16 +00:00
|
|
|
return;
|
1995-03-24 20:42:28 +00:00
|
|
|
|
1994-05-27 05:00:24 +00:00
|
|
|
if (grouphead.gr == (struct netgrp *)0 ||
|
|
|
|
strcmp(group, grouphead.grname)) {
|
|
|
|
endnetgrent();
|
1995-08-07 03:42:14 +00:00
|
|
|
#ifdef YP
|
1995-09-02 04:08:55 +00:00
|
|
|
/* Presumed guilty until proven innocent. */
|
|
|
|
_use_only_yp = 0;
|
1995-08-07 03:42:14 +00:00
|
|
|
/*
|
1996-04-15 16:17:04 +00:00
|
|
|
* If /etc/netgroup doesn't exist or is empty,
|
1995-08-07 03:42:14 +00:00
|
|
|
* use NIS exclusively.
|
|
|
|
*/
|
|
|
|
if (((stat(_PATH_NETGROUP, &_yp_statp) < 0) &&
|
|
|
|
errno == ENOENT) || _yp_statp.st_size == 0)
|
|
|
|
_use_only_yp = _netgr_yp_enabled = 1;
|
|
|
|
if ((netf = fopen(_PATH_NETGROUP,"r")) != NULL ||_use_only_yp){
|
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
1995-09-02 04:08:55 +00:00
|
|
|
if (_use_only_yp && _yp_innetgr) {
|
|
|
|
/* dohw! */
|
1995-12-02 21:54:59 +00:00
|
|
|
if (netf != NULL)
|
|
|
|
fclose(netf);
|
1995-08-07 03:42:14 +00:00
|
|
|
return;
|
1995-09-02 04:08:55 +00:00
|
|
|
}
|
1995-08-07 03:42:14 +00:00
|
|
|
#else
|
1994-05-27 05:00:24 +00:00
|
|
|
if (netf = fopen(_PATH_NETGROUP, "r")) {
|
1995-08-07 03:42:14 +00:00
|
|
|
#endif
|
1994-05-27 05:00:24 +00:00
|
|
|
if (parse_netgrp(group))
|
|
|
|
endnetgrent();
|
|
|
|
else {
|
|
|
|
grouphead.grname = (char *)
|
|
|
|
malloc(strlen(group) + 1);
|
|
|
|
strcpy(grouphead.grname, group);
|
|
|
|
}
|
1995-08-07 03:42:14 +00:00
|
|
|
if (netf)
|
|
|
|
fclose(netf);
|
1994-05-27 05:00:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
nextgrp = grouphead.gr;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the next netgroup off the list.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
getnetgrent(hostp, userp, domp)
|
|
|
|
char **hostp, **userp, **domp;
|
|
|
|
{
|
1995-08-07 03:42:14 +00:00
|
|
|
#ifdef YP
|
|
|
|
_yp_innetgr = 0;
|
|
|
|
#endif
|
1994-05-27 05:00:24 +00:00
|
|
|
|
|
|
|
if (nextgrp) {
|
|
|
|
*hostp = nextgrp->ng_str[NG_HOST];
|
|
|
|
*userp = nextgrp->ng_str[NG_USER];
|
|
|
|
*domp = nextgrp->ng_str[NG_DOM];
|
|
|
|
nextgrp = nextgrp->ng_next;
|
|
|
|
return (1);
|
|
|
|
}
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* endnetgrent() - cleanup
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
endnetgrent()
|
|
|
|
{
|
2002-02-01 01:08:48 +00:00
|
|
|
struct linelist *lp, *olp;
|
|
|
|
struct netgrp *gp, *ogp;
|
1994-05-27 05:00:24 +00:00
|
|
|
|
|
|
|
lp = linehead;
|
|
|
|
while (lp) {
|
|
|
|
olp = lp;
|
|
|
|
lp = lp->l_next;
|
|
|
|
free(olp->l_groupname);
|
|
|
|
free(olp->l_line);
|
|
|
|
free((char *)olp);
|
|
|
|
}
|
|
|
|
linehead = (struct linelist *)0;
|
|
|
|
if (grouphead.grname) {
|
|
|
|
free(grouphead.grname);
|
|
|
|
grouphead.grname = (char *)0;
|
|
|
|
}
|
|
|
|
gp = grouphead.gr;
|
|
|
|
while (gp) {
|
|
|
|
ogp = gp;
|
|
|
|
gp = gp->ng_next;
|
|
|
|
if (ogp->ng_str[NG_HOST])
|
|
|
|
free(ogp->ng_str[NG_HOST]);
|
|
|
|
if (ogp->ng_str[NG_USER])
|
|
|
|
free(ogp->ng_str[NG_USER]);
|
|
|
|
if (ogp->ng_str[NG_DOM])
|
|
|
|
free(ogp->ng_str[NG_DOM]);
|
|
|
|
free((char *)ogp);
|
|
|
|
}
|
|
|
|
grouphead.gr = (struct netgrp *)0;
|
1995-03-19 06:16:03 +00:00
|
|
|
#ifdef YP
|
1995-03-21 19:47:12 +00:00
|
|
|
_netgr_yp_enabled = 0;
|
1995-03-19 06:16:03 +00:00
|
|
|
#endif
|
1994-05-27 05:00:24 +00:00
|
|
|
}
|
|
|
|
|
1995-08-07 03:42:14 +00:00
|
|
|
#ifdef YP
|
1995-08-08 02:51:16 +00:00
|
|
|
static int _listmatch(list, group, len)
|
1997-11-16 03:02:39 +00:00
|
|
|
char *list, *group;
|
|
|
|
int len;
|
1995-08-07 03:42:14 +00:00
|
|
|
{
|
1997-11-16 03:02:39 +00:00
|
|
|
char *ptr = list, *cptr;
|
|
|
|
int glen = strlen(group);
|
1995-08-07 03:42:14 +00:00
|
|
|
|
1997-11-16 03:02:39 +00:00
|
|
|
/* skip possible leading whitespace */
|
1999-11-04 04:16:28 +00:00
|
|
|
while(isspace((unsigned char)*ptr))
|
1997-11-16 03:02:39 +00:00
|
|
|
ptr++;
|
1996-05-21 16:11:27 +00:00
|
|
|
|
1998-03-01 18:49:37 +00:00
|
|
|
while (ptr < list + len) {
|
|
|
|
cptr = ptr;
|
1999-11-04 04:16:28 +00:00
|
|
|
while(*ptr != ',' && *ptr != '\0' && !isspace((unsigned char)*ptr))
|
1998-03-01 18:49:37 +00:00
|
|
|
ptr++;
|
|
|
|
if (strncmp(cptr, group, glen) == 0 && glen == (ptr - cptr))
|
1996-05-21 16:11:27 +00:00
|
|
|
return(1);
|
1999-11-04 04:16:28 +00:00
|
|
|
while(*ptr == ',' || isspace((unsigned char)*ptr))
|
1998-03-01 18:49:37 +00:00
|
|
|
ptr++;
|
1996-05-21 16:11:27 +00:00
|
|
|
}
|
1996-04-15 16:17:04 +00:00
|
|
|
|
1995-08-07 03:42:14 +00:00
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int _buildkey(key, str, dom, rotation)
|
|
|
|
char *key, *str, *dom;
|
|
|
|
int *rotation;
|
|
|
|
{
|
|
|
|
(*rotation)++;
|
|
|
|
if (*rotation > 4)
|
|
|
|
return(0);
|
|
|
|
switch(*rotation) {
|
|
|
|
case(1): sprintf((char *)key, "%s.%s", str, dom ? dom : "*");
|
|
|
|
break;
|
|
|
|
case(2): sprintf((char *)key, "%s.*", str);
|
|
|
|
break;
|
|
|
|
case(3): sprintf((char *)key, "*.%s", dom ? dom : "*");
|
|
|
|
break;
|
|
|
|
case(4): sprintf((char *)key, "*.*");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return(1);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
1994-05-27 05:00:24 +00:00
|
|
|
/*
|
|
|
|
* Search for a match in a netgroup.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
innetgr(group, host, user, dom)
|
1996-07-12 18:57:58 +00:00
|
|
|
const char *group, *host, *user, *dom;
|
1994-05-27 05:00:24 +00:00
|
|
|
{
|
|
|
|
char *hst, *usr, *dm;
|
1995-08-07 03:42:14 +00:00
|
|
|
#ifdef YP
|
|
|
|
char *result;
|
|
|
|
int resultlen;
|
1996-04-15 16:17:04 +00:00
|
|
|
int rv;
|
1995-08-07 03:42:14 +00:00
|
|
|
#endif
|
1995-03-24 20:42:28 +00:00
|
|
|
/* Sanity check */
|
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
|
|
|
|
1995-03-24 20:42:28 +00:00
|
|
|
if (group == NULL || !strlen(group))
|
|
|
|
return (0);
|
|
|
|
|
1995-08-07 03:42:14 +00:00
|
|
|
#ifdef YP
|
|
|
|
_yp_innetgr = 1;
|
|
|
|
#endif
|
|
|
|
setnetgrent(group);
|
|
|
|
#ifdef YP
|
1996-04-15 16:17:04 +00:00
|
|
|
_yp_innetgr = 0;
|
1995-08-07 03:42:14 +00:00
|
|
|
/*
|
|
|
|
* If we're in NIS-only mode, do the search using
|
|
|
|
* NIS 'reverse netgroup' lookups.
|
|
|
|
*/
|
|
|
|
if (_use_only_yp) {
|
|
|
|
char _key[MAXHOSTNAMELEN];
|
1997-10-13 17:09:15 +00:00
|
|
|
int rot = 0, y = 0;
|
1995-08-07 03:42:14 +00:00
|
|
|
|
|
|
|
if(yp_get_default_domain(&_netgr_yp_domain))
|
|
|
|
return(0);
|
1996-12-05 18:22:00 +00:00
|
|
|
while(_buildkey(_key, user ? user : host, dom, &rot)) {
|
1997-10-13 17:09:15 +00:00
|
|
|
y = yp_match(_netgr_yp_domain, user? "netgroup.byuser":
|
1995-08-07 03:42:14 +00:00
|
|
|
"netgroup.byhost", _key, strlen(_key), &result,
|
1997-10-13 17:09:15 +00:00
|
|
|
&resultlen);
|
|
|
|
if (y) {
|
|
|
|
/*
|
|
|
|
* If we get an error other than 'no
|
|
|
|
* such key in map' then something is
|
|
|
|
* wrong and we should stop the search.
|
|
|
|
*/
|
|
|
|
if (y != YPERR_KEY)
|
|
|
|
break;
|
|
|
|
} else {
|
1996-04-15 16:17:04 +00:00
|
|
|
rv = _listmatch(result, group, resultlen);
|
|
|
|
free(result);
|
|
|
|
if (rv)
|
1995-08-07 03:42:14 +00:00
|
|
|
return(1);
|
1996-04-15 16:17:04 +00:00
|
|
|
else
|
|
|
|
return(0);
|
1995-08-07 03:42:14 +00:00
|
|
|
}
|
|
|
|
}
|
1997-10-13 17:09:15 +00:00
|
|
|
/*
|
|
|
|
* Couldn't match using NIS-exclusive mode. If the error
|
|
|
|
* was YPERR_MAP, then the failure happened because there
|
|
|
|
* was no netgroup.byhost or netgroup.byuser map. The odds
|
2002-12-30 21:18:15 +00:00
|
|
|
* are we are talking to a Sun NIS+ server in YP emulation
|
1997-10-13 17:09:15 +00:00
|
|
|
* mode; if this is the case, then we have to do the check
|
|
|
|
* the 'old-fashioned' way by grovelling through the netgroup
|
|
|
|
* map and resolving memberships on the fly.
|
|
|
|
*/
|
|
|
|
if (y != YPERR_MAP)
|
|
|
|
return(0);
|
1995-08-07 03:42:14 +00:00
|
|
|
}
|
1997-10-13 17:09:15 +00:00
|
|
|
|
1994-05-27 05:00:24 +00:00
|
|
|
setnetgrent(group);
|
1995-08-07 03:42:14 +00:00
|
|
|
#endif /* YP */
|
1997-10-13 17:09:15 +00:00
|
|
|
|
1994-05-27 05:00:24 +00:00
|
|
|
while (getnetgrent(&hst, &usr, &dm))
|
1995-08-07 03:42:14 +00:00
|
|
|
if ((host == NULL || hst == NULL || !strcmp(host, hst)) &&
|
|
|
|
(user == NULL || usr == NULL || !strcmp(user, usr)) &&
|
|
|
|
( dom == NULL || dm == NULL || !strcmp(dom, dm))) {
|
1994-05-27 05:00:24 +00:00
|
|
|
endnetgrent();
|
|
|
|
return (1);
|
|
|
|
}
|
|
|
|
endnetgrent();
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Parse the netgroup file setting up the linked lists.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
parse_netgrp(group)
|
|
|
|
char *group;
|
|
|
|
{
|
2002-02-01 01:08:48 +00:00
|
|
|
char *spos, *epos;
|
|
|
|
int 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
|
2002-02-01 01:08:48 +00:00
|
|
|
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
|
|
|
char *pos, *gpos;
|
|
|
|
struct netgrp *grp;
|
|
|
|
struct linelist *lp = linehead;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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 == (struct linelist *)0 &&
|
|
|
|
(lp = read_for_group(group)) == (struct linelist *)0)
|
|
|
|
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;
|
1995-03-19 06:16:03 +00:00
|
|
|
/* Watch for null pointer dereferences, dammit! */
|
|
|
|
while (pos != NULL && *pos != '\0') {
|
1994-05-27 05:00:24 +00:00
|
|
|
if (*pos == '(') {
|
|
|
|
grp = (struct netgrp *)malloc(sizeof (struct netgrp));
|
|
|
|
bzero((char *)grp, sizeof (struct netgrp));
|
|
|
|
grp->ng_next = grouphead.gr;
|
|
|
|
grouphead.gr = grp;
|
|
|
|
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++) {
|
1995-08-07 03:42:14 +00:00
|
|
|
if ((spos = strsep(&gpos, ","))) {
|
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++;
|
|
|
|
#endif
|
1994-05-27 05:00:24 +00:00
|
|
|
while (*spos == ' ' || *spos == '\t')
|
|
|
|
spos++;
|
1995-08-07 03:42:14 +00:00
|
|
|
if ((epos = strpbrk(spos, " \t"))) {
|
1994-05-27 05:00:24 +00:00
|
|
|
*epos = '\0';
|
|
|
|
len = epos - spos;
|
|
|
|
} else
|
|
|
|
len = strlen(spos);
|
|
|
|
if (len > 0) {
|
|
|
|
grp->ng_str[strpos] = (char *)
|
|
|
|
malloc(len + 1);
|
|
|
|
bcopy(spos, grp->ng_str[strpos],
|
|
|
|
len + 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
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* All other systems I've tested
|
|
|
|
* return NULL for empty netgroup
|
|
|
|
* fields. It's up to user programs
|
|
|
|
* to handle the NULLs appropriately.
|
|
|
|
*/
|
|
|
|
grp->ng_str[strpos] = NULL;
|
|
|
|
}
|
1994-05-27 05:00:24 +00:00
|
|
|
}
|
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",
|
|
|
|
grp->ng_str[NG_HOST] == NULL ? "" : grp->ng_str[NG_HOST],
|
|
|
|
grp->ng_str[NG_USER] == NULL ? "" : ",",
|
|
|
|
grp->ng_str[NG_USER] == NULL ? "" : grp->ng_str[NG_USER],
|
|
|
|
grp->ng_str[NG_DOM] == NULL ? "" : ",",
|
|
|
|
grp->ng_str[NG_DOM] == NULL ? "" : grp->ng_str[NG_DOM],
|
|
|
|
lp->l_groupname);
|
|
|
|
#endif
|
1994-05-27 05:00:24 +00:00
|
|
|
} else {
|
|
|
|
spos = strsep(&pos, ", \t");
|
|
|
|
if (parse_netgrp(spos))
|
1995-03-19 22:19:52 +00:00
|
|
|
continue;
|
1994-05-27 05:00:24 +00:00
|
|
|
}
|
1997-03-11 11:52:33 +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(group)
|
|
|
|
char *group;
|
|
|
|
{
|
2002-02-01 01:08:48 +00:00
|
|
|
char *pos, *spos, *linep, *olinep;
|
|
|
|
int len, olen;
|
1994-05-27 05:00:24 +00:00
|
|
|
int cont;
|
|
|
|
struct linelist *lp;
|
1996-12-27 19:28:46 +00:00
|
|
|
char line[LINSIZ + 2];
|
1995-03-19 06:16:03 +00:00
|
|
|
#ifdef YP
|
|
|
|
char *result;
|
|
|
|
int resultlen;
|
1994-05-27 05:00:24 +00:00
|
|
|
|
1995-03-19 06:16:03 +00:00
|
|
|
while (_netgr_yp_enabled || fgets(line, LINSIZ, netf) != NULL) {
|
|
|
|
if (_netgr_yp_enabled) {
|
|
|
|
if(!_netgr_yp_domain)
|
1995-03-21 19:47:12 +00:00
|
|
|
if(yp_get_default_domain(&_netgr_yp_domain))
|
1995-03-19 06:16:03 +00:00
|
|
|
continue;
|
1995-03-21 19:47:12 +00:00
|
|
|
if (yp_match(_netgr_yp_domain, "netgroup", group,
|
|
|
|
strlen(group), &result, &resultlen)) {
|
|
|
|
free(result);
|
1995-08-07 03:42:14 +00:00
|
|
|
if (_use_only_yp)
|
|
|
|
return ((struct linelist *)0);
|
|
|
|
else {
|
|
|
|
_netgr_yp_enabled = 0;
|
|
|
|
continue;
|
|
|
|
}
|
1995-03-19 06:16:03 +00:00
|
|
|
}
|
1996-12-27 19:28:46 +00:00
|
|
|
snprintf(line, LINSIZ, "%s %s", group, result);
|
1995-03-19 06:16:03 +00:00
|
|
|
free(result);
|
|
|
|
}
|
|
|
|
#else
|
1994-05-27 05:00:24 +00:00
|
|
|
while (fgets(line, LINSIZ, netf) != NULL) {
|
1995-03-19 06:16:03 +00:00
|
|
|
#endif
|
|
|
|
pos = (char *)&line;
|
|
|
|
#ifdef YP
|
|
|
|
if (*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 = (struct linelist *)malloc(sizeof (*lp));
|
|
|
|
lp->l_parsed = 0;
|
|
|
|
lp->l_groupname = (char *)malloc(len + 1);
|
|
|
|
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 = (char *)malloc(olen + len + 1);
|
|
|
|
if (olen > 0) {
|
|
|
|
bcopy(olinep, linep, olen);
|
|
|
|
free(olinep);
|
|
|
|
}
|
|
|
|
bcopy(pos, linep + olen, len);
|
|
|
|
olen += len;
|
|
|
|
*(linep + olen) = '\0';
|
|
|
|
olinep = linep;
|
|
|
|
}
|
|
|
|
if (cont) {
|
|
|
|
if (fgets(line, LINSIZ, netf)) {
|
|
|
|
pos = line;
|
|
|
|
len = strlen(pos);
|
|
|
|
} else
|
|
|
|
cont = 0;
|
|
|
|
}
|
|
|
|
} while (cont);
|
|
|
|
lp->l_line = linep;
|
|
|
|
lp->l_next = linehead;
|
|
|
|
linehead = lp;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If this is the one we wanted, we are done.
|
|
|
|
*/
|
|
|
|
if (!strcmp(lp->l_groupname, group))
|
|
|
|
return (lp);
|
|
|
|
}
|
|
|
|
}
|
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
|
1994-05-27 05:00:24 +00:00
|
|
|
return ((struct linelist *)0);
|
|
|
|
}
|