version 1.9.2.1, 1996/09/16 18:40:26 |
version 1.41, 2009/10/21 01:07:45 |
|
|
* 2. Redistributions in binary form must reproduce the above copyright |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 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 Christos Zoulas. |
|
* 4. The name of the author may not be used to endorse or promote products |
|
* derived from this software without specific prior written permission. |
|
* |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS |
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
|
* SUCH DAMAGE. |
* SUCH DAMAGE. |
*/ |
*/ |
|
|
|
#include <sys/cdefs.h> |
#if defined(LIBC_SCCS) && !defined(lint) |
#if defined(LIBC_SCCS) && !defined(lint) |
static char *rcsid = "$NetBSD$"; |
__RCSID("$NetBSD$"); |
#endif /* LIBC_SCCS and not lint */ |
#endif /* LIBC_SCCS and not lint */ |
|
|
#include "namespace.h" |
#include "namespace.h" |
#include <sys/types.h> |
#include <sys/types.h> |
#include <stdio.h> |
|
|
#include <assert.h> |
|
#include <ctype.h> |
|
#include <db.h> |
|
#include <err.h> |
|
#include <fcntl.h> |
#define _NETGROUP_PRIVATE |
#define _NETGROUP_PRIVATE |
|
#include <stringlist.h> |
#include <netgroup.h> |
#include <netgroup.h> |
#include <string.h> |
#include <nsswitch.h> |
#include <fcntl.h> |
#include <stdarg.h> |
#include <err.h> |
#include <stdio.h> |
#include <ctype.h> |
|
#include <stdlib.h> |
#include <stdlib.h> |
#include <db.h> |
#include <string.h> |
|
|
|
#ifdef YP |
|
#include <rpc/rpc.h> |
|
#include <rpcsvc/ypclnt.h> |
|
#include <rpcsvc/yp_prot.h> |
|
#endif |
|
|
|
#ifdef __weak_alias |
|
__weak_alias(endnetgrent,_endnetgrent) |
|
__weak_alias(getnetgrent,_getnetgrent) |
|
__weak_alias(innetgr,_innetgr) |
|
__weak_alias(setnetgrent,_setnetgrent) |
|
#endif |
|
|
#define _NG_STAR(s) (((s) == NULL || *(s) == '\0') ? _ngstar : s) |
#define _NG_STAR(s) (((s) == NULL || *(s) == '\0') ? _ngstar : s) |
#define _NG_EMPTY(s) ((s) == NULL ? "" : s) |
#define _NG_EMPTY(s) ((s) == NULL ? "" : s) |
#define _NG_ISSPACE(p) (isspace((unsigned char) (p)) || (p) == '\n') |
#define _NG_ISSPACE(p) (isspace((unsigned char) (p)) || (p) == '\n') |
|
|
static const char _ngstar[] = "*"; |
static const char _ngstar[] = "*"; |
static const char _ngoomem[] = "netgroup: %m"; |
static struct netgroup *_nghead = NULL; |
static struct netgroup *_nghead = (struct netgroup *)NULL; |
static struct netgroup *_nglist = NULL; |
static struct netgroup *_nglist = (struct netgroup *)NULL; |
|
static DB *_ng_db; |
static DB *_ng_db; |
|
|
/* |
static int getstring(char **, int, __aconst char **); |
* Simple string list |
static struct netgroup *getnetgroup(char **); |
*/ |
static int lookup(char *, char **, int); |
struct stringlist { |
static int addgroup(StringList *, char *); |
char **sl_str; |
static int in_check(const char *, const char *, const char *, |
size_t sl_max; |
struct netgroup *); |
size_t sl_cur; |
static int in_find(StringList *, char *, const char *, const char *, |
|
const char *); |
|
static char *in_lookup1(const char *, const char *, int); |
|
static int in_lookup(const char *, const char *, const char *, int); |
|
|
|
#ifdef NSSRC_FILES |
|
static const ns_src default_files_nis[] = { |
|
{ NSSRC_FILES, NS_SUCCESS | NS_NOTFOUND }, |
|
#ifdef YP |
|
{ NSSRC_NIS, NS_SUCCESS }, |
|
#endif |
|
{ 0, 0 }, |
}; |
}; |
|
#endif |
static int getstring __P((char **, int, char **)); |
|
static struct netgroup *getnetgroup __P((char **)); |
|
static int lookup __P((const char *, char *, char **, int)); |
|
static void addgroup __P((char *, struct stringlist *, char *)); |
|
static int in_check __P((const char *, const char *, |
|
const char *, struct netgroup *)); |
|
static int in_find __P((char *, struct stringlist *, |
|
char *, const char *, |
|
const char *, const char *)); |
|
static char *in_lookup1 __P((const char *, const char *, |
|
const char *, int)); |
|
static int in_lookup __P((const char *, const char *, |
|
const char *, const char *, int)); |
|
|
|
/* |
|
* _ng_sl_init(): Initialize a string list |
|
*/ |
|
struct stringlist * |
|
_ng_sl_init() |
|
{ |
|
struct stringlist *sl = malloc(sizeof(struct stringlist)); |
|
if (sl == NULL) |
|
_err(1, _ngoomem); |
|
|
|
sl->sl_cur = 0; |
|
sl->sl_max = 20; |
|
sl->sl_str = malloc(sl->sl_max * sizeof(char *)); |
|
if (sl->sl_str == NULL) |
|
_err(1, _ngoomem); |
|
return sl; |
|
} |
|
|
|
|
|
/* |
|
* _ng_sl_add(): Add an item to the string list |
|
*/ |
|
void |
|
_ng_sl_add(sl, name) |
|
struct stringlist *sl; |
|
char *name; |
|
{ |
|
if (sl->sl_cur == sl->sl_max - 1) { |
|
sl->sl_max += 20; |
|
sl->sl_str = realloc(sl->sl_str, sl->sl_max * sizeof(char *)); |
|
if (sl->sl_str == NULL) |
|
_err(1, _ngoomem); |
|
} |
|
sl->sl_str[sl->sl_cur++] = name; |
|
} |
|
|
|
|
|
/* |
|
* _ng_sl_free(): Free a stringlist |
|
*/ |
|
void |
|
_ng_sl_free(sl, all) |
|
struct stringlist *sl; |
|
int all; |
|
{ |
|
size_t i; |
|
|
|
if (all) |
|
for (i = 0; i < sl->sl_cur; i++) |
|
free(sl->sl_str[i]); |
|
free(sl->sl_str); |
|
free(sl); |
|
} |
|
|
|
|
|
/* |
|
* sl_find(): Find a name in the string list |
|
*/ |
|
char * |
|
_ng_sl_find(sl, name) |
|
struct stringlist *sl; |
|
char *name; |
|
{ |
|
size_t i; |
|
|
|
for (i = 0; i < sl->sl_cur; i++) |
|
if (strcmp(sl->sl_str[i], name) == 0) |
|
return sl->sl_str[i]; |
|
|
|
return NULL; |
|
} |
|
|
|
|
|
/* |
/* |
* getstring(): Get a string delimited by the character, skipping leading and |
* getstring(): Get a string delimited by the character, skipping leading and |
* trailing blanks and advancing the pointer |
* trailing blanks and advancing the pointer |
*/ |
*/ |
static int |
static int |
getstring(pp, del, str) |
getstring(char **pp, int del, char __aconst **str) |
char **pp; |
|
int del; |
|
char **str; |
|
{ |
{ |
|
size_t len; |
char *sp, *ep, *dp; |
char *sp, *ep, *dp; |
|
|
|
_DIAGASSERT(pp != NULL); |
|
_DIAGASSERT(str != NULL); |
|
|
/* skip leading blanks */ |
/* skip leading blanks */ |
for (sp = *pp; *sp && _NG_ISSPACE(*sp); sp++) |
for (sp = *pp; *sp && _NG_ISSPACE(*sp); sp++) |
continue; |
continue; |
Line 184 getstring(pp, del, str) |
|
Line 123 getstring(pp, del, str) |
|
|
|
*pp = ++dp; |
*pp = ++dp; |
|
|
del = (ep - sp) + 1; |
len = (ep - sp) + 1; |
if (del > 1) { |
if (len > 1) { |
dp = malloc(del); |
dp = malloc(len); |
if (dp == NULL) |
if (dp == NULL) |
_err(1, _ngoomem); |
return 0; |
memcpy(dp, sp, del); |
(void)memcpy(dp, sp, len); |
dp[del - 1] = '\0'; |
dp[len - 1] = '\0'; |
} else |
} else |
dp = NULL; |
dp = NULL; |
|
|
Line 206 static struct netgroup * |
|
Line 145 static struct netgroup * |
|
getnetgroup(pp) |
getnetgroup(pp) |
char **pp; |
char **pp; |
{ |
{ |
struct netgroup *ng = malloc(sizeof(struct netgroup)); |
struct netgroup *ng; |
|
|
|
_DIAGASSERT(pp != NULL); |
|
_DIAGASSERT(*pp != NULL); |
|
|
|
ng = malloc(sizeof(struct netgroup)); |
if (ng == NULL) |
if (ng == NULL) |
_err(1, _ngoomem); |
return NULL; |
|
|
(*pp)++; /* skip '(' */ |
(*pp)++; /* skip '(' */ |
if (!getstring(pp, ',', &ng->ng_host)) |
if (!getstring(pp, ',', &ng->ng_host)) |
|
|
return NULL; |
return NULL; |
} |
} |
|
|
|
void |
/* |
_ng_cycle(const char *grp, const StringList *sl) |
* lookup(): Find the given key in the database or yp, and return its value |
|
* in *line; returns 1 if key was found, 0 otherwise |
|
*/ |
|
static int |
|
lookup(ypdom, name, line, bywhat) |
|
const char *ypdom; |
|
char *name; |
|
char **line; |
|
int bywhat; |
|
{ |
{ |
#ifdef YP |
size_t i; |
int i; |
warnx("netgroup: Cycle in group `%s'", grp); |
char *map = NULL; |
(void)fprintf(stderr, "groups: "); |
#endif |
for (i = 0; i < sl->sl_cur; i++) |
|
(void)fprintf(stderr, "%s ", sl->sl_str[i]); |
|
(void)fprintf(stderr, "\n"); |
|
} |
|
|
if (_ng_db) { |
static int _local_lookup(void *, void *, va_list); |
DBT key, data; |
|
size_t len = strlen(name) + 2; |
|
char *ks = malloc(len); |
|
|
|
ks[0] = bywhat; |
/*ARGSUSED*/ |
memcpy(&ks[1], name, len - 1); |
static int |
|
_local_lookup(void *rv, void *cb_data, va_list ap) |
|
{ |
|
char *name = va_arg(ap, char *); |
|
char **line = va_arg(ap, char **); |
|
int bywhat = va_arg(ap, int); |
|
|
key.data = (u_char *) ks; |
DBT key, data; |
key.size = len; |
size_t len; |
|
char *ks; |
|
int r; |
|
|
switch ((_ng_db->get) (_ng_db, &key, &data, 0)) { |
if (_ng_db == NULL) |
case 0: |
return NS_UNAVAIL; |
free(ks); |
|
*line = strdup(data.data); |
|
if (*line == NULL) |
|
_err(1, _ngoomem); |
|
return 1; |
|
|
|
case 1: |
len = strlen(name) + 2; |
break; |
ks = malloc(len); |
|
if (ks == NULL) |
|
return NS_UNAVAIL; |
|
|
|
ks[0] = bywhat; |
|
(void)memcpy(&ks[1], name, len - 1); |
|
|
|
key.data = (u_char *)ks; |
|
key.size = len; |
|
|
|
r = (*_ng_db->get)(_ng_db, &key, &data, 0); |
|
free(ks); |
|
switch (r) { |
|
case 0: |
|
break; |
|
case 1: |
|
return NS_NOTFOUND; |
|
case -1: |
|
/* XXX: call endnetgrent() here ? */ |
|
return NS_UNAVAIL; |
|
} |
|
|
|
*line = strdup(data.data); |
|
if (*line == NULL) |
|
return NS_UNAVAIL; |
|
return NS_SUCCESS; |
|
} |
|
|
case -1: |
|
_warn("netgroup: db get"); |
|
break; |
|
} |
|
free(ks); |
|
} |
|
#ifdef YP |
#ifdef YP |
if (ypdom) { |
static int _nis_lookup(void *, void *, va_list); |
switch (bywhat) { |
|
case _NG_KEYBYNAME: |
|
map = "netgroup"; |
|
break; |
|
|
|
case _NG_KEYBYUSER: |
/*ARGSUSED*/ |
map = "netgroup.byuser"; |
static int |
break; |
_nis_lookup(void *rv, void *cb_data, va_list ap) |
|
{ |
|
char *name = va_arg(ap, char *); |
|
char **line = va_arg(ap, char **); |
|
int bywhat = va_arg(ap, int); |
|
|
|
static char *__ypdomain; |
|
int i; |
|
const char *map = NULL; |
|
|
case _NG_KEYBYHOST: |
if(__ypdomain == NULL) { |
map = "netgroup.byhost"; |
switch (yp_get_default_domain(&__ypdomain)) { |
|
case 0: |
break; |
break; |
|
case YPERR_RESRC: |
|
return NS_TRYAGAIN; |
default: |
default: |
abort(); |
return NS_UNAVAIL; |
break; |
|
} |
} |
|
} |
|
|
|
switch (bywhat) { |
if (yp_match(ypdom, map, name, strlen(name), line, &i) == 0) |
case _NG_KEYBYNAME: |
return 1; |
map = "netgroup"; |
|
break; |
|
|
|
case _NG_KEYBYUSER: |
|
map = "netgroup.byuser"; |
|
break; |
|
|
|
case _NG_KEYBYHOST: |
|
map = "netgroup.byhost"; |
|
break; |
|
|
|
default: |
|
abort(); |
|
} |
|
|
|
*line = NULL; |
|
switch (yp_match(__ypdomain, map, name, (int)strlen(name), line, &i)) { |
|
case 0: |
|
return NS_SUCCESS; |
|
case YPERR_KEY: |
|
if (*line) |
|
free(*line); |
|
return NS_NOTFOUND; |
|
default: |
|
if (*line) |
|
free(*line); |
|
return NS_UNAVAIL; |
} |
} |
|
/* NOTREACHED */ |
|
} |
#endif |
#endif |
|
|
return 0; |
#ifdef NSSRC_FILES |
|
/* |
|
* lookup(): Find the given key in the database or yp, and return its value |
|
* in *line; returns 1 if key was found, 0 otherwise |
|
*/ |
|
static int |
|
lookup(char *name, char **line, int bywhat) |
|
{ |
|
int r; |
|
static const ns_dtab dtab[] = { |
|
NS_FILES_CB(_local_lookup, NULL) |
|
NS_NIS_CB(_nis_lookup, NULL) |
|
NS_NULL_CB |
|
}; |
|
|
|
_DIAGASSERT(name != NULL); |
|
_DIAGASSERT(line != NULL); |
|
|
|
r = nsdispatch(NULL, dtab, NSDB_NETGROUP, "lookup", default_files_nis, |
|
name, line, bywhat); |
|
return (r == NS_SUCCESS) ? 1 : 0; |
|
} |
|
#else |
|
static int |
|
_local_lookupv(int *rv, void *cbdata, ...) |
|
{ |
|
int e; |
|
va_list ap; |
|
va_start(ap, cbdata); |
|
e = _local_lookup(rv, cbdata, ap); |
|
va_end(ap); |
|
return e; |
} |
} |
|
|
|
static int |
|
lookup(name, line, bywhat) |
|
char *name; |
|
char **line; |
|
int bywhat; |
|
{ |
|
return _local_lookupv(NULL, NULL, name, line, bywhat) == NS_SUCCESS; |
|
} |
|
#endif |
|
|
/* |
/* |
* _ng_parse(): Parse a line and return: _NG_ERROR: Syntax Error _NG_NONE: |
* _ng_parse(): Parse a line and return: _NG_ERROR: Syntax Error _NG_NONE: |
Line 324 lookup(ypdom, name, line, bywhat) |
|
Line 354 lookup(ypdom, name, line, bywhat) |
|
* Public since used by netgroup_mkdb |
* Public since used by netgroup_mkdb |
*/ |
*/ |
int |
int |
_ng_parse(p, name, ng) |
_ng_parse(char **p, char **name, struct netgroup **ng) |
char **p; |
|
char **name; |
|
struct netgroup **ng; |
|
{ |
{ |
|
|
|
_DIAGASSERT(p != NULL); |
|
_DIAGASSERT(*p != NULL); |
|
_DIAGASSERT(name != NULL); |
|
_DIAGASSERT(ng != NULL); |
|
|
while (**p) { |
while (**p) { |
if (**p == '#') |
if (**p == '#') |
/* comment */ |
/* comment */ |
Line 339 _ng_parse(p, name, ng) |
|
Line 372 _ng_parse(p, name, ng) |
|
(*p)++; |
(*p)++; |
|
|
if (**p == '(') { |
if (**p == '(') { |
if ((*ng = getnetgroup(p)) == NULL) { |
if ((*ng = getnetgroup(p)) == NULL) |
_warnx("netgroup: Syntax error `%s'", *p); |
|
return _NG_ERROR; |
return _NG_ERROR; |
} |
|
return _NG_GROUP; |
return _NG_GROUP; |
} else { |
} else { |
char *np; |
char *np; |
int i; |
size_t i; |
|
|
for (np = *p; **p && !_NG_ISSPACE(**p); (*p)++) |
for (np = *p; **p && !_NG_ISSPACE(**p); (*p)++) |
continue; |
continue; |
Line 354 _ng_parse(p, name, ng) |
|
Line 385 _ng_parse(p, name, ng) |
|
i = (*p - np) + 1; |
i = (*p - np) + 1; |
*name = malloc(i); |
*name = malloc(i); |
if (*name == NULL) |
if (*name == NULL) |
_err(1, _ngoomem); |
return _NG_ERROR; |
memcpy(*name, np, i); |
(void)memcpy(*name, np, i); |
(*name)[i - 1] = '\0'; |
(*name)[i - 1] = '\0'; |
return _NG_NAME; |
return _NG_NAME; |
} |
} |
Line 366 _ng_parse(p, name, ng) |
|
Line 397 _ng_parse(p, name, ng) |
|
|
|
|
|
/* |
/* |
* addgroup(): Recursively add all the members of the netgroup to this group |
* addgroup(): Recursively add all the members of the netgroup to this group. |
|
* returns 0 upon failure, nonzero upon success. |
|
* grp is not a valid pointer after return (either free(3)ed or allocated |
|
* to a stringlist). in either case, it shouldn't be used again. |
*/ |
*/ |
static void |
static int |
addgroup(ypdom, sl, grp) |
addgroup(StringList *sl, char *grp) |
char *ypdom; |
|
struct stringlist *sl; |
|
char *grp; |
|
{ |
{ |
char *line, *p; |
char *line, *p; |
struct netgroup *ng; |
struct netgroup *ng; |
char *name; |
char *name; |
|
|
|
_DIAGASSERT(sl != NULL); |
|
_DIAGASSERT(grp != NULL); |
|
|
#ifdef DEBUG_NG |
#ifdef DEBUG_NG |
(void) fprintf(stderr, "addgroup(%s)\n", grp); |
(void)fprintf(stderr, "addgroup(%s)\n", grp); |
#endif |
#endif |
/* check for cycles */ |
/* check for cycles */ |
if (_ng_sl_find(sl, grp) != NULL) { |
if (sl_find(sl, grp) != NULL) { |
|
_ng_cycle(grp, sl); |
free(grp); |
free(grp); |
_warnx("netgroup: Cycle in group `%s'", grp); |
return 0; |
return; |
} |
|
if (sl_add(sl, grp) == -1) { |
|
free(grp); |
|
return 0; |
} |
} |
_ng_sl_add(sl, grp); |
|
|
|
/* Lookup this netgroup */ |
/* Lookup this netgroup */ |
if (!lookup(ypdom, grp, &line, _NG_KEYBYNAME)) |
line = NULL; |
return; |
if (!lookup(grp, &line, _NG_KEYBYNAME)) { |
|
if (line) |
|
free(line); |
|
return 0; |
|
} |
|
|
p = line; |
p = line; |
|
|
Line 400 addgroup(ypdom, sl, grp) |
|
Line 441 addgroup(ypdom, sl, grp) |
|
case _NG_NONE: |
case _NG_NONE: |
/* Done with the line */ |
/* Done with the line */ |
free(line); |
free(line); |
return; |
return 1; |
|
|
case _NG_GROUP: |
case _NG_GROUP: |
/* new netgroup */ |
/* new netgroup */ |
Line 411 addgroup(ypdom, sl, grp) |
|
Line 452 addgroup(ypdom, sl, grp) |
|
|
|
case _NG_NAME: |
case _NG_NAME: |
/* netgroup name */ |
/* netgroup name */ |
addgroup(ypdom, sl, name); |
if (!addgroup(sl, name)) |
|
return 0; |
break; |
break; |
|
|
case _NG_ERROR: |
case _NG_ERROR: |
return; |
return 0; |
|
|
default: |
default: |
abort(); |
abort(); |
return; |
|
} |
} |
} |
} |
} |
} |
Line 429 addgroup(ypdom, sl, grp) |
|
Line 470 addgroup(ypdom, sl, grp) |
|
* in_check(): Compare the spec with the netgroup |
* in_check(): Compare the spec with the netgroup |
*/ |
*/ |
static int |
static int |
in_check(host, user, domain, ng) |
in_check(const char *host, const char *user, const char *domain, |
const char *host; |
struct netgroup *ng) |
const char *user; |
|
const char *domain; |
|
struct netgroup *ng; |
|
{ |
{ |
|
|
|
/* host may be NULL */ |
|
/* user may be NULL */ |
|
/* domain may be NULL */ |
|
_DIAGASSERT(ng != NULL); |
|
|
if ((host != NULL) && (ng->ng_host != NULL) |
if ((host != NULL) && (ng->ng_host != NULL) |
&& strcmp(ng->ng_host, host) != 0) |
&& strcmp(ng->ng_host, host) != 0) |
return 0; |
return 0; |
Line 452 in_check(host, user, domain, ng) |
|
Line 496 in_check(host, user, domain, ng) |
|
|
|
|
|
/* |
/* |
* in_find(): Find a match for the host, user, domain spec |
* in_find(): Find a match for the host, user, domain spec. |
|
* grp is not a valid pointer after return (either free(3)ed or allocated |
|
* to a stringlist). in either case, it shouldn't be used again. |
*/ |
*/ |
static int |
static int |
in_find(ypdom, sl, grp, host, user, domain) |
in_find(StringList *sl, char *grp, const char *host, const char *user, |
char *ypdom; |
const char *domain) |
struct stringlist *sl; |
|
char *grp; |
|
const char *host; |
|
const char *user; |
|
const char *domain; |
|
{ |
{ |
char *line, *p; |
char *line, *p; |
int i; |
int i; |
struct netgroup *ng; |
struct netgroup *ng; |
char *name; |
char *name; |
|
|
|
_DIAGASSERT(sl != NULL); |
|
_DIAGASSERT(grp != NULL); |
|
/* host may be NULL */ |
|
/* user may be NULL */ |
|
/* domain may be NULL */ |
|
|
#ifdef DEBUG_NG |
#ifdef DEBUG_NG |
(void) fprintf(stderr, "in_find(%s)\n", grp); |
(void)fprintf(stderr, "in_find(%s)\n", grp); |
#endif |
#endif |
/* check for cycles */ |
/* check for cycles */ |
if (_ng_sl_find(sl, grp) != NULL) { |
if (sl_find(sl, grp) != NULL) { |
|
_ng_cycle(grp, sl); |
|
free(grp); |
|
return 0; |
|
} |
|
if (sl_add(sl, grp) == -1) { |
free(grp); |
free(grp); |
_warnx("netgroup: Cycle in group `%s'", grp); |
|
return 0; |
return 0; |
} |
} |
_ng_sl_add(sl, grp); |
|
|
|
/* Lookup this netgroup */ |
/* Lookup this netgroup */ |
if (!lookup(ypdom, grp, &line, _NG_KEYBYNAME)) |
line = NULL; |
|
if (!lookup(grp, &line, _NG_KEYBYNAME)) { |
|
if (line) |
|
free(line); |
return 0; |
return 0; |
|
} |
|
|
p = line; |
p = line; |
|
|
Line 510 in_find(ypdom, sl, grp, host, user, doma |
|
Line 564 in_find(ypdom, sl, grp, host, user, doma |
|
|
|
case _NG_NAME: |
case _NG_NAME: |
/* netgroup name */ |
/* netgroup name */ |
if (in_find(ypdom, sl, name, host, user, domain)) { |
if (in_find(sl, name, host, user, domain)) { |
free(line); |
free(line); |
return 1; |
return 1; |
} |
} |
Line 522 in_find(ypdom, sl, grp, host, user, doma |
|
Line 576 in_find(ypdom, sl, grp, host, user, doma |
|
|
|
default: |
default: |
abort(); |
abort(); |
return 0; |
|
} |
} |
} |
} |
} |
} |
|
|
|
|
/* |
/* |
* _ng_makekey(): Make a key from the two names given. The key is of the form |
* _ng_makekey(): Make a key from the two names given. The key is of the form |
* <name1>.<name2> Names strings are replaced with * if they are empty; |
* <name1>.<name2> Names strings are replaced with * if they are empty; |
|
* Returns NULL if there's a problem. |
*/ |
*/ |
char * |
char * |
_ng_makekey(s1, s2, len) |
_ng_makekey(const char *s1, const char *s2, size_t len) |
const char *s1, *s2; |
{ |
size_t len; |
char *buf; |
{ |
|
char *buf = malloc(len); |
/* s1 may be NULL */ |
if (buf == NULL) |
/* s2 may be NULL */ |
_err(1, _ngoomem); |
|
(void) snprintf(buf, len, "%s.%s", _NG_STAR(s1), _NG_STAR(s2)); |
buf = malloc(len); |
|
if (buf != NULL) |
|
(void)snprintf(buf, len, "%s.%s", _NG_STAR(s1), _NG_STAR(s2)); |
return buf; |
return buf; |
} |
} |
|
|
void |
void |
_ng_print(buf, len, ng) |
_ng_print(char *buf, size_t len, const struct netgroup *ng) |
char *buf; |
|
size_t len; |
|
const struct netgroup *ng; |
|
{ |
{ |
(void) snprintf(buf, len, "(%s,%s,%s)", _NG_EMPTY(ng->ng_host), |
_DIAGASSERT(buf != NULL); |
|
_DIAGASSERT(ng != NULL); |
|
|
|
(void)snprintf(buf, len, "(%s,%s,%s)", _NG_EMPTY(ng->ng_host), |
_NG_EMPTY(ng->ng_user), _NG_EMPTY(ng->ng_domain)); |
_NG_EMPTY(ng->ng_user), _NG_EMPTY(ng->ng_domain)); |
} |
} |
|
|
Line 559 _ng_print(buf, len, ng) |
|
Line 614 _ng_print(buf, len, ng) |
|
* in_lookup1(): Fast lookup for a key in the appropriate map |
* in_lookup1(): Fast lookup for a key in the appropriate map |
*/ |
*/ |
static char * |
static char * |
in_lookup1(ypdom, key, domain, map) |
in_lookup1(const char *key, const char *domain, int map) |
const char *ypdom; |
|
const char *key; |
|
const char *domain; |
|
int map; |
|
{ |
{ |
char *line; |
char *line; |
size_t len; |
size_t len; |
char *ptr; |
char *ptr; |
int res; |
int res; |
|
|
|
/* key may be NULL */ |
|
/* domain may be NULL */ |
|
|
len = (key ? strlen(key) : 1) + (domain ? strlen(domain) : 1) + 2; |
len = (key ? strlen(key) : 1) + (domain ? strlen(domain) : 1) + 2; |
ptr = _ng_makekey(key, domain, len); |
ptr = _ng_makekey(key, domain, len); |
res = lookup(ypdom, ptr, &line, map); |
if (ptr == NULL) |
|
return NULL; |
|
res = lookup(ptr, &line, map); |
free(ptr); |
free(ptr); |
return res ? line : NULL; |
return res ? line : NULL; |
} |
} |
Line 582 in_lookup1(ypdom, key, domain, map) |
|
Line 638 in_lookup1(ypdom, key, domain, map) |
|
* in_lookup(): Fast lookup for a key in the appropriate map |
* in_lookup(): Fast lookup for a key in the appropriate map |
*/ |
*/ |
static int |
static int |
in_lookup(ypdom, group, key, domain, map) |
in_lookup(const char *group, const char *key, const char *domain, int map) |
const char *ypdom; |
|
const char *group; |
|
const char *key; |
|
const char *domain; |
|
int map; |
|
{ |
{ |
size_t len; |
size_t len; |
char *ptr, *line; |
char *ptr, *line; |
|
|
|
_DIAGASSERT(group != NULL); |
|
/* key may be NULL */ |
|
/* domain may be NULL */ |
|
|
if (domain != NULL) { |
if (domain != NULL) { |
/* Domain specified; look in "group.domain" and "*.domain" */ |
/* Domain specified; look in "group.domain" and "*.domain" */ |
if ((line = in_lookup1(ypdom, key, domain, map)) == NULL) |
if ((line = in_lookup1(key, domain, map)) == NULL) |
line = in_lookup1(ypdom, NULL, domain, map); |
line = in_lookup1(NULL, domain, map); |
} |
} else |
else |
|
line = NULL; |
line = NULL; |
|
|
if (line == NULL) { |
if (line == NULL) { |
/* |
/* |
* domain not specified or domain lookup failed; look in |
* domain not specified or domain lookup failed; look in |
* "group.*" and "*.*" |
* "group.*" and "*.*" |
*/ |
*/ |
if (((line = in_lookup1(ypdom, key, NULL, map)) == NULL) && |
if (((line = in_lookup1(key, NULL, map)) == NULL) && |
((line = in_lookup1(ypdom, NULL, NULL, map)) == NULL)) |
((line = in_lookup1(NULL, NULL, map)) == NULL)) |
return 0; |
return 0; |
} |
} |
|
|
Line 626 in_lookup(ypdom, group, key, domain, map |
|
Line 680 in_lookup(ypdom, group, key, domain, map |
|
return 0; |
return 0; |
} |
} |
|
|
|
/*ARGSUSED*/ |
void |
static int |
endnetgrent() |
_local_endnetgrent(void *rv, void *cb_data, va_list ap) |
{ |
{ |
for (_nglist = _nghead; _nglist != NULL; _nglist = _nghead) { |
for (_nglist = _nghead; _nglist != NULL; _nglist = _nghead) { |
_nghead = _nglist->ng_next; |
_nghead = _nglist->ng_next; |
|
|
} |
} |
|
|
if (_ng_db) { |
if (_ng_db) { |
(void) (_ng_db->close) (_ng_db); |
(void)(*_ng_db->close)(_ng_db); |
_ng_db = NULL; |
_ng_db = NULL; |
} |
} |
} |
|
|
|
|
return NS_SUCCESS; |
|
} |
|
|
void |
/*ARGSUSED*/ |
setnetgrent(ng) |
static int |
const char *ng; |
_local_setnetgrent(void *rv, void *cb_data, va_list ap) |
{ |
{ |
struct stringlist *sl = _ng_sl_init(); |
const char *ng = va_arg(ap, const char *); |
#ifdef YP |
StringList *sl; |
char *line; |
char *ng_copy; |
#endif |
|
char *ng_copy, *ypdom = NULL; |
_DIAGASSERT(ng != NULL); |
|
|
|
sl = sl_init(); |
|
if (sl == NULL) |
|
return NS_TRYAGAIN; |
|
|
/* Cleanup any previous storage */ |
/* Cleanup any previous storage */ |
if (_nghead != NULL) |
if (_nghead != NULL) |
|
|
if (_ng_db == NULL) |
if (_ng_db == NULL) |
_ng_db = dbopen(_PATH_NETGROUP_DB, O_RDONLY, 0, DB_HASH, NULL); |
_ng_db = dbopen(_PATH_NETGROUP_DB, O_RDONLY, 0, DB_HASH, NULL); |
|
|
#ifdef YP |
|
/* |
|
* We use yp if there is a "+" in the netgroup file, or if there is |
|
* no netgroup file at all |
|
*/ |
|
if (_ng_db == NULL || lookup(NULL, "+", &line, _NG_KEYBYNAME) == 0) |
|
yp_get_default_domain(&ypdom); |
|
else |
|
free(line); |
|
#endif |
|
ng_copy = strdup(ng); |
ng_copy = strdup(ng); |
if (ng_copy == NULL) |
if (ng_copy != NULL) |
_err(1, _ngoomem); |
addgroup(sl, ng_copy); |
addgroup(ypdom, sl, ng_copy); |
|
_nghead = _nglist; |
_nghead = _nglist; |
_ng_sl_free(sl, 1); |
sl_free(sl, 1); |
} |
|
|
|
|
return NS_SUCCESS; |
|
} |
|
|
int |
/*ARGSUSED*/ |
getnetgrent(host, user, domain) |
static int |
const char **host; |
_local_getnetgrent(void *rv, void *cb_data, va_list ap) |
const char **user; |
|
const char **domain; |
|
{ |
{ |
|
int *retval = va_arg(ap, int *); |
|
const char **host = va_arg(ap, const char **); |
|
const char **user = va_arg(ap, const char **); |
|
const char **domain = va_arg(ap, const char **); |
|
|
|
_DIAGASSERT(host != NULL); |
|
_DIAGASSERT(user != NULL); |
|
_DIAGASSERT(domain != NULL); |
|
|
|
*retval = 0; |
|
|
if (_nglist == NULL) |
if (_nglist == NULL) |
return 0; |
return NS_TRYAGAIN; |
|
|
*host = _nglist->ng_host; |
*host = _nglist->ng_host; |
*user = _nglist->ng_user; |
*user = _nglist->ng_user; |
Line 699 getnetgrent(host, user, domain) |
|
Line 757 getnetgrent(host, user, domain) |
|
|
|
_nglist = _nglist->ng_next; |
_nglist = _nglist->ng_next; |
|
|
return 1; |
*retval = 1; |
} |
|
|
|
|
return NS_SUCCESS; |
|
} |
|
|
int |
/*ARGSUSED*/ |
innetgr(grp, host, user, domain) |
static int |
const char *grp, *host, *user, *domain; |
_local_innetgr(void *rv, void *cb_data, va_list ap) |
{ |
{ |
char *ypdom = NULL; |
int *retval = va_arg(ap, int *); |
#ifdef YP |
const char *grp = va_arg(ap, const char *); |
char *line; |
const char *host = va_arg(ap, const char *); |
#endif |
const char *user = va_arg(ap, const char *); |
|
const char *domain = va_arg(ap, const char *); |
|
|
int found; |
int found; |
struct stringlist *sl; |
StringList *sl; |
|
char *grcpy; |
|
|
if (_ng_db == NULL) |
_DIAGASSERT(grp != NULL); |
_ng_db = dbopen(_PATH_NETGROUP_DB, O_RDONLY, 0, DB_HASH, NULL); |
/* host may be NULL */ |
|
/* user may be NULL */ |
|
/* domain may be NULL */ |
|
|
#ifdef YP |
|
/* |
|
* We use yp if there is a "+" in the netgroup file, or if there is |
|
* no netgroup file at all |
|
*/ |
|
if (_ng_db == NULL) |
if (_ng_db == NULL) |
yp_get_default_domain(&ypdom); |
_ng_db = dbopen(_PATH_NETGROUP_DB, O_RDONLY, 0, DB_HASH, NULL); |
else if (lookup(NULL, "+", &line, _NG_KEYBYNAME) == 0) { |
|
yp_get_default_domain(&ypdom); |
|
free(line); |
|
} |
|
#endif |
|
|
|
/* Try the fast lookup first */ |
/* Try the fast lookup first */ |
if (host != NULL && user == NULL) { |
if (host != NULL && user == NULL) { |
if (in_lookup(ypdom, grp, host, domain, _NG_KEYBYHOST)) |
if (in_lookup(grp, host, domain, _NG_KEYBYHOST)) { |
return 1; |
*retval = 1; |
|
return NS_SUCCESS; |
|
} |
} else if (host == NULL && user != NULL) { |
} else if (host == NULL && user != NULL) { |
if (in_lookup(ypdom, grp, user, domain, _NG_KEYBYUSER)) |
if (in_lookup(grp, user, domain, _NG_KEYBYUSER)) { |
return 1; |
*retval = 1; |
|
return NS_SUCCESS; |
|
} |
} |
} |
/* If a domainname is given, we would have found a match */ |
/* If a domainname is given, we would have found a match */ |
if (domain != NULL) |
if (domain != NULL) { |
return 0; |
*retval = 0; |
|
return NS_SUCCESS; |
|
} |
|
|
/* Too bad need the slow recursive way */ |
/* Too bad need the slow recursive way */ |
sl = _ng_sl_init(); |
sl = sl_init(); |
found = in_find(ypdom, sl, strdup(grp), host, user, domain); |
if (sl == NULL) { |
_ng_sl_free(sl, 1); |
*retval = 0; |
|
return NS_SUCCESS; |
|
} |
|
if ((grcpy = strdup(grp)) == NULL) { |
|
sl_free(sl, 1); |
|
*retval = 0; |
|
return NS_SUCCESS; |
|
} |
|
found = in_find(sl, grcpy, host, user, domain); |
|
sl_free(sl, 1); |
|
|
|
*retval = found; |
|
return NS_SUCCESS; |
|
} |
|
|
|
#ifdef YP |
|
|
|
/*ARGSUSED*/ |
|
static int |
|
_nis_endnetgrent(void *rv, void *cb_data, va_list ap) |
|
{ |
|
return _local_endnetgrent(rv, cb_data, ap); |
|
} |
|
|
|
/*ARGSUSED*/ |
|
static int |
|
_nis_setnetgrent(void *rv, void *cb_data, va_list ap) |
|
{ |
|
return _local_setnetgrent(rv, cb_data, ap); |
|
} |
|
|
|
/*ARGSUSED*/ |
|
static int |
|
_nis_getnetgrent(void *rv, void *cb_data, va_list ap) |
|
{ |
|
return _local_getnetgrent(rv, cb_data, ap); |
|
} |
|
|
|
/*ARGSUSED*/ |
|
static int |
|
_nis_innetgr(void *rv, void *cb_data, va_list ap) |
|
{ |
|
return _local_innetgr(rv, cb_data, ap); |
|
} |
|
|
|
#endif |
|
|
|
|
|
#ifdef NSSRC_FILES |
|
void |
|
endnetgrent(void) |
|
{ |
|
static const ns_dtab dtab[] = { |
|
NS_FILES_CB(_local_endnetgrent, NULL) |
|
NS_NIS_CB(_nis_endnetgrent, NULL) |
|
NS_NULL_CB |
|
}; |
|
|
|
(void) nsdispatch(NULL, dtab, NSDB_NETGROUP, "endnetgrent", |
|
__nsdefaultcompat); |
|
} |
|
#else |
|
static int |
|
_local_endnetgrentv(int *rv, void *cbdata, ...) |
|
{ |
|
int e; |
|
va_list ap; |
|
va_start(ap, cbdata); |
|
e = _local_endnetgrent(rv, cbdata, ap); |
|
va_end(ap); |
|
return e; |
|
} |
|
|
|
void |
|
endnetgrent(void) |
|
{ |
|
(void)_local_endnetgrentv(NULL, NULL, NULL); |
|
} |
|
#endif |
|
|
|
#ifdef NSSRC_FILES |
|
void |
|
setnetgrent(const char *ng) |
|
{ |
|
static const ns_dtab dtab[] = { |
|
NS_FILES_CB(_local_setnetgrent, NULL) |
|
NS_NIS_CB(_nis_setnetgrent, NULL) |
|
NS_NULL_CB |
|
}; |
|
|
|
(void) nsdispatch(NULL, dtab, NSDB_NETGROUP, "setnetgrent", |
|
__nsdefaultnis, ng); |
|
} |
|
#else |
|
static int |
|
_local_setnetgrentv(int *rv, void *cbdata, ...) |
|
{ |
|
int e; |
|
va_list ap; |
|
va_start(ap, cbdata); |
|
e = _local_setnetgrent(rv, cbdata, ap); |
|
va_end(ap); |
|
return e; |
|
} |
|
|
return found; |
void |
|
setnetgrent(const char *ng) |
|
{ |
|
(void) _local_setnetgrentv(NULL, NULL,ng); |
} |
} |
|
|
|
#endif |
|
|
|
#ifdef NSSRC_FILES |
|
int |
|
getnetgrent(const char **host, const char **user, const char **domain) |
|
{ |
|
int r, retval; |
|
static const ns_dtab dtab[] = { |
|
NS_FILES_CB(_local_getnetgrent, NULL) |
|
NS_NIS_CB(_nis_getnetgrent, NULL) |
|
NS_NULL_CB |
|
}; |
|
|
|
r = nsdispatch(NULL, dtab, NSDB_NETGROUP, "getnetgrent", |
|
__nsdefaultnis, &retval, host, user, domain); |
|
|
|
return (r == NS_SUCCESS) ? retval : 0; |
|
} |
|
#else |
|
static int |
|
_local_getnetgrentv(int *rv, void *cbdata, ...) |
|
{ |
|
int e; |
|
va_list ap; |
|
va_start(ap, cbdata); |
|
e = _local_getnetgrent(rv, cbdata, ap); |
|
va_end(ap); |
|
return e; |
|
} |
|
|
|
int |
|
getnetgrent(const char **host, const char **user, const char **domain) |
|
{ |
|
return _local_getnetgrentv(NULL, NULL, host, user, domain) == NS_SUCCESS; |
|
} |
|
#endif |
|
|
|
#ifdef NSSRC_FILES |
|
int |
|
innetgr(const char *grp, const char *host, const char *user, |
|
const char *domain) |
|
{ |
|
int r, retval; |
|
static const ns_dtab dtab[] = { |
|
NS_FILES_CB(_local_innetgr, NULL) |
|
NS_NIS_CB(_nis_innetgr, NULL) |
|
NS_NULL_CB |
|
}; |
|
|
|
r = nsdispatch(NULL, dtab, NSDB_NETGROUP, "innetgr", |
|
__nsdefaultnis, &retval, grp, host, user, domain); |
|
|
|
return (r == NS_SUCCESS) ? retval : 0; |
|
} |
|
#else |
|
static int |
|
_local_innetgrv(int *rv, void *cbdata, ...) |
|
{ |
|
int e; |
|
va_list ap; |
|
va_start(ap, cbdata); |
|
e = _local_innetgr(rv, cbdata, ap); |
|
va_end(ap); |
|
return e; |
|
} |
|
|
|
int |
|
innetgr(const char *grp, const char *host, const char *user, |
|
const char *domain) |
|
{ |
|
return _local_innetgrv(NULL, NULL, grp, host, user, domain) == NS_SUCCESS; |
|
} |
|
#endif |