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