Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libc/gen change getpwent() backends so that a flag (per ...
details: https://anonhg.NetBSD.org/src/rev/949a09d89e9f
branches: trunk
changeset: 472213:949a09d89e9f
user: lukem <lukem%NetBSD.org@localhost>
date: Sun Apr 25 07:54:01 1999 +0000
description:
change getpwent() backends so that a flag (per source) is set once the
source has been exhausted. this allows getpwent() across multiple
sources (e.g, ``passwd: files nis'') to work correctly. the flags are
reset in setpassent()/endpwent().
this fixes a bug noted in [lib/7449] by thorpej, and tracked down to
getpwent() as being the culprit by simonb.
diffstat:
lib/libc/gen/getpwent.c | 104 +++++++++++++++++++++++------------------------
1 files changed, 51 insertions(+), 53 deletions(-)
diffs (truncated from 306 to 300 lines):
diff -r a22ebbb046cb -r 949a09d89e9f lib/libc/gen/getpwent.c
--- a/lib/libc/gen/getpwent.c Sun Apr 25 06:28:10 1999 +0000
+++ b/lib/libc/gen/getpwent.c Sun Apr 25 07:54:01 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: getpwent.c,v 1.41 1999/04/18 02:04:05 lukem Exp $ */
+/* $NetBSD: getpwent.c,v 1.42 1999/04/25 07:54:01 lukem Exp $ */
/*
* Copyright (c) 1988, 1993
@@ -39,7 +39,7 @@
#if 0
static char sccsid[] = "@(#)getpwent.c 8.2 (Berkeley) 4/27/95";
#else
-__RCSID("$NetBSD: getpwent.c,v 1.41 1999/04/18 02:04:05 lukem Exp $");
+__RCSID("$NetBSD: getpwent.c,v 1.42 1999/04/25 07:54:01 lukem Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -97,10 +97,9 @@
static struct passwd _pw_passwd; /* password structure */
static DB *_pw_db; /* password database */
-static int _pw_keynum; /* key counter */
+static int _pw_keynum; /* key counter. no more records if -1 */
static int _pw_stayopen; /* keep fd's open */
static int _pw_flags; /* password flags */
-static int _pw_none; /* true if getpwent got EOF */
static int __hashpw __P((DBT *));
static int __initdb __P((void));
@@ -114,10 +113,11 @@
#ifdef YP
static char *__ypcurrent, *__ypdomain;
static int __ypcurrentlen;
+static int _pw_ypdone; /* non-zero if no more yp records */
#endif
#ifdef HESIOD
-static int _pw_hesnum;
+static int _pw_hesnum; /* hes counter. no more records if -1 */
#endif
#ifdef _PASSWD_COMPAT
@@ -324,7 +324,8 @@
}
/*
- * parse an old-style passwd file line (from NIS or HESIOD)
+ * parse a passwd file line (from NIS or HESIOD).
+ * assumed to be `old-style' if maptype != YPMAP_MASTER.
*/
static int
__pwparse(pw, s)
@@ -405,6 +406,8 @@
bf[0] = search;
switch (search) {
case _PW_KEYBYNUM:
+ if (_pw_keynum == -1)
+ return NS_NOTFOUND; /* no more local records */
++_pw_keynum;
memmove(bf + 1, &_pw_keynum, sizeof(_pw_keynum));
key.size = sizeof(_pw_keynum) + 1;
@@ -426,10 +429,8 @@
key.data = (u_char *)bf;
rval = __hashpw(&key);
- if (rval == NS_NOTFOUND && search == _PW_KEYBYNUM) {
- _pw_none = 1;
- rval = NS_SUCCESS;
- }
+ if (rval == NS_NOTFOUND && search == _PW_KEYBYNUM)
+ _pw_keynum = -1; /* flag `no more local records' */
if (!_pw_stayopen && (search != _PW_KEYBYNUM)) {
(void)(_pw_db->close)(_pw_db);
@@ -456,7 +457,7 @@
uid_t uid;
int search;
- char *map;
+ const char *map;
char **hp;
void *context;
int r;
@@ -464,6 +465,8 @@
search = va_arg(ap, int);
switch (search) {
case _PW_KEYBYNUM:
+ if (_pw_hesnum == -1)
+ return NS_NOTFOUND; /* no more hesiod records */
snprintf(line, sizeof(line) - 1, "passwd-%u", _pw_hesnum);
_pw_hesnum++;
map = "passwd";
@@ -490,12 +493,10 @@
hp = hesiod_resolve(context, line, map);
if (hp == NULL) {
if (errno == ENOENT) {
- if (search == _PW_KEYBYNUM) {
- _pw_hesnum = 0;
- _pw_none = 1;
- r = NS_SUCCESS;
- } else
- r = NS_NOTFOUND;
+ /* flag `no more hesiod records' */
+ if (search == _PW_KEYBYNUM)
+ _pw_hesnum = -1;
+ r = NS_NOTFOUND;
}
goto cleanup_dns_getpw;
}
@@ -531,14 +532,15 @@
uid_t uid;
int search;
char *key, *data;
- char *map = PASSWD_BYNAME;
- int keylen, datalen, r;
+ const char *map;
+ int keylen, datalen, r, rval;
if(__ypdomain == NULL) {
if(_yp_check(&__ypdomain) == 0)
return NS_UNAVAIL;
}
+ map = PASSWD_BYNAME;
search = va_arg(ap, int);
switch (search) {
case _PW_KEYBYNUM:
@@ -556,24 +558,17 @@
abort();
}
line[sizeof(line) - 1] = '\0';
+ rval = NS_UNAVAIL;
if (search != _PW_KEYBYNUM) {
data = NULL;
r = yp_match(__ypdomain, map, line, (int)strlen(line),
&data, &datalen);
- switch (r) {
- case 0:
- break;
- case YPERR_KEY:
- r = NS_NOTFOUND;
- break;
- default:
- r = NS_UNAVAIL;
- break;
- }
+ if (r == YPERR_KEY)
+ rval = NS_NOTFOUND;
if (r != 0) {
if (data)
free(data);
- return r;
+ return (rval);
}
data[datalen] = '\0'; /* clear trailing \n */
strncpy(line, data, sizeof(line));
@@ -584,6 +579,8 @@
return NS_SUCCESS;
}
+ if (_pw_ypdone)
+ return NS_NOTFOUND;
for (;;) {
data = key = NULL;
if (__ypcurrent) {
@@ -598,26 +595,20 @@
break;
case YPERR_NOMORE:
__ypcurrent = NULL;
- _pw_none = 1;
- if (key)
- free(key);
- return NS_SUCCESS;
- default:
- r = NS_UNAVAIL;
- break;
+ /* flag `no more yp records' */
+ _pw_ypdone = 1;
+ rval = NS_NOTFOUND;
}
} else {
- r = 0;
- if (yp_first(__ypdomain, map, &__ypcurrent,
- &__ypcurrentlen, &data, &datalen))
- r = NS_UNAVAIL;
+ r = yp_first(__ypdomain, map, &__ypcurrent,
+ &__ypcurrentlen, &data, &datalen);
}
if (r != 0) {
if (key)
free(key);
if (data)
free(data);
- return r;
+ return (rval);
}
data[datalen] = '\0'; /* clear trailing \n */
strncpy(line, data, sizeof(line));
@@ -744,7 +735,7 @@
#ifdef _PASSWD_COMPAT
static char *name = NULL;
const char *user, *host, *dom;
- int has_compatpw;
+ int has_compatpw, rval;
#endif
if (!_pw_db && !__initdb())
@@ -798,12 +789,17 @@
}
#endif
+ if (_pw_keynum == -1)
+ return NS_NOTFOUND; /* no more local records */
++_pw_keynum;
bf[0] = _PW_KEYBYNUM;
memmove(bf + 1, &_pw_keynum, sizeof(_pw_keynum));
key.data = (u_char *)bf;
key.size = sizeof(_pw_keynum) + 1;
- if(__hashpw(&key) == NS_SUCCESS) {
+ rval = __hashpw(&key);
+ if (rval == NS_NOTFOUND)
+ _pw_keynum = -1; /* flag `no more local records' */
+ else if (rval == NS_SUCCESS) {
#ifdef _PASSWD_COMPAT
/* if we don't have YP at all, don't bother. */
if (has_compatpw) {
@@ -847,9 +843,8 @@
}
}
#endif
- return NS_SUCCESS;
}
- return NS_NOTFOUND;
+ return (rval);
}
/*
@@ -866,9 +861,9 @@
{
#ifdef _PASSWD_COMPAT
DBT key;
- int search, rval, r, s;
+ int search, rval, r, s, keynum;
uid_t uid;
- char bf[MAXLOGNAME + 1];
+ char bf[sizeof(keynum) + 1];
const char *name, *host, *user, *dom;
#endif
@@ -899,11 +894,11 @@
abort();
}
- for(s = -1, _pw_keynum=1; _pw_keynum; _pw_keynum++) {
+ for (s = -1, keynum = 1 ; ; keynum++) {
bf[0] = _PW_KEYBYNUM;
- memmove(bf + 1, &_pw_keynum, sizeof(_pw_keynum));
+ memmove(bf + 1, &keynum, sizeof(keynum));
key.data = (u_char *)bf;
- key.size = sizeof(_pw_keynum) + 1;
+ key.size = sizeof(keynum) + 1;
if(__hashpw(&key) != NS_SUCCESS)
break;
switch(_pw_passwd.pw_name[0]) {
@@ -919,10 +914,12 @@
break;
case '@':
pwnam_netgrp:
+#if 0 /* XXX: is this a hangover from pre-nsswitch? */
if(__ypcurrent) {
free(__ypcurrent);
__ypcurrent = NULL;
}
+#endif
if (s == -1) /* first time */
setnetgrent(_pw_passwd.pw_name + 2);
s = getnetgrent(&host, &user, &dom);
@@ -1017,10 +1014,9 @@
{ 0 }
};
- _pw_none = 0;
r = nsdispatch(NULL, dtab, NSDB_PASSWD, "getpwent", compatsrc,
_PW_KEYBYNUM);
- if (_pw_none || r != NS_SUCCESS)
+ if (r != NS_SUCCESS)
return (struct passwd *)NULL;
return &_pw_passwd;
}
@@ -1075,6 +1071,7 @@
if(__ypcurrent)
free(__ypcurrent);
__ypcurrent = NULL;
+ _pw_ypdone = 0;
#endif
#ifdef HESIOD
_pw_hesnum = 0;
@@ -1110,6 +1107,7 @@
if(__ypcurrent)
Home |
Main Index |
Thread Index |
Old Index