[BACK]Return to pwcache.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libc / gen

Annotation of src/lib/libc/gen/pwcache.c, Revision 1.27

1.27    ! sjg         1: /*     $NetBSD: pwcache.c,v 1.26 2004/04/23 02:58:27 simonb Exp $      */
1.4       cgd         2:
1.10      mycroft     3: /*-
1.25      agc         4:  * Copyright (c) 1992 Keith Muller.
1.10      mycroft     5:  * Copyright (c) 1992, 1993
1.4       cgd         6:  *     The Regents of the University of California.  All rights reserved.
1.1       cgd         7:  *
1.10      mycroft     8:  * This code is derived from software contributed to Berkeley by
                      9:  * Keith Muller of the University of California, San Diego.
                     10:  *
1.1       cgd        11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
1.24      agc        19:  * 3. Neither the name of the University nor the names of its contributors
                     20:  *    may be used to endorse or promote products derived from this software
                     21:  *    without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     24:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     25:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     26:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     27:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     28:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     29:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     31:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     32:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     33:  * SUCH DAMAGE.
                     34:  */
                     35:
                     36: /*-
1.17      lukem      37:  * Copyright (c) 2002 The NetBSD Foundation, Inc.
                     38:  * All rights reserved.
                     39:  *
                     40:  * Redistribution and use in source and binary forms, with or without
                     41:  * modification, are permitted provided that the following conditions
                     42:  * are met:
                     43:  * 1. Redistributions of source code must retain the above copyright
                     44:  *    notice, this list of conditions and the following disclaimer.
                     45:  * 2. Redistributions in binary form must reproduce the above copyright
                     46:  *    notice, this list of conditions and the following disclaimer in the
                     47:  *    documentation and/or other materials provided with the distribution.
                     48:  * 3. All advertising materials mentioning features or use of this software
                     49:  *    must display the following acknowledgement:
                     50:  *        This product includes software developed by the NetBSD
                     51:  *        Foundation, Inc. and its contributors.
                     52:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     53:  *    contributors may be used to endorse or promote products derived
                     54:  *    from this software without specific prior written permission.
                     55:  *
                     56:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     57:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     58:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     59:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     60:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     61:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     62:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     63:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     64:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     65:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     66:  * POSSIBILITY OF SUCH DAMAGE.
                     67:  */
                     68:
1.27    ! sjg        69: #if HAVE_NBTOOL_CONFIG_H
        !            70: #include "nbtool_config.h"
        !            71: #endif
        !            72:
1.7       christos   73: #include <sys/cdefs.h>
1.15      msaitoh    74: #if defined(LIBC_SCCS) && !defined(lint)
1.4       cgd        75: #if 0
1.10      mycroft    76: static char sccsid[] = "@(#)cache.c    8.1 (Berkeley) 5/31/93";
1.4       cgd        77: #else
1.27    ! sjg        78: __RCSID("$NetBSD: pwcache.c,v 1.26 2004/04/23 02:58:27 simonb Exp $");
1.4       cgd        79: #endif
1.15      msaitoh    80: #endif /* LIBC_SCCS and not lint */
1.1       cgd        81:
1.8       jtc        82: #include "namespace.h"
1.10      mycroft    83:
1.1       cgd        84: #include <sys/types.h>
1.6       sommerfe   85: #include <sys/param.h>
1.4       cgd        86:
1.13      lukem      87: #include <assert.h>
1.4       cgd        88: #include <grp.h>
1.1       cgd        89: #include <pwd.h>
                     90: #include <stdio.h>
1.10      mycroft    91: #include <stdlib.h>
1.5       jtc        92: #include <string.h>
1.10      mycroft    93: #include <unistd.h>
                     94:
1.8       jtc        95: #ifdef __weak_alias
1.14      mycroft    96: __weak_alias(user_from_uid,_user_from_uid)
                     97: __weak_alias(group_from_gid,_group_from_gid)
1.17      lukem      98: __weak_alias(pwcache_userdb,_pwcache_userdb)
                     99: __weak_alias(pwcache_groupdb,_pwcache_groupdb)
1.8       jtc       100: #endif
1.19      lukem     101:
                    102: #if !HAVE_PWCACHE_USERDB
                    103: #include "pwcache.h"
1.1       cgd       104:
1.10      mycroft   105: /*
                    106:  * routines that control user, group, uid and gid caches (for the archive
                    107:  * member print routine).
                    108:  * IMPORTANT:
                    109:  * these routines cache BOTH hits and misses, a major performance improvement
                    110:  */
                    111:
1.17      lukem     112: /*
                    113:  * function pointers to various name lookup routines.
                    114:  * these may be changed as necessary.
                    115:  */
                    116: static int             (*_pwcache_setgroupent)(int)            = setgroupent;
                    117: static void            (*_pwcache_endgrent)(void)              = endgrent;
                    118: static struct group *  (*_pwcache_getgrnam)(const char *)      = getgrnam;
                    119: static struct group *  (*_pwcache_getgrgid)(gid_t)             = getgrgid;
                    120: static int             (*_pwcache_setpassent)(int)             = setpassent;
                    121: static void            (*_pwcache_endpwent)(void)              = endpwent;
                    122: static struct passwd * (*_pwcache_getpwnam)(const char *)      = getpwnam;
                    123: static struct passwd * (*_pwcache_getpwuid)(uid_t)             = getpwuid;
                    124:
                    125: /*
                    126:  * internal state
                    127:  */
                    128: static int     pwopn;          /* is password file open */
                    129: static int     gropn;          /* is group file open */
                    130: static UIDC    **uidtb;        /* uid to name cache */
                    131: static GIDC    **gidtb;        /* gid to name cache */
                    132: static UIDC    **usrtb;        /* user name to uid cache */
                    133: static GIDC    **grptb;        /* group name to gid cache */
                    134:
                    135: static int     uidtb_fail;     /* uidtb_start() failed ? */
                    136: static int     gidtb_fail;     /* gidtb_start() failed ? */
                    137: static int     usrtb_fail;     /* usrtb_start() failed ? */
                    138: static int     grptb_fail;     /* grptb_start() failed ? */
                    139:
                    140:
                    141: static u_int   st_hash(const char *, size_t, int);
                    142: static int     uidtb_start(void);
                    143: static int     gidtb_start(void);
                    144: static int     usrtb_start(void);
                    145: static int     grptb_start(void);
                    146:
1.10      mycroft   147:
                    148: static u_int
1.16      lukem     149: st_hash(const char *name, size_t len, int tabsz)
1.10      mycroft   150: {
                    151:        u_int key = 0;
                    152:
1.13      lukem     153:        _DIAGASSERT(name != NULL);
                    154:
1.10      mycroft   155:        while (len--) {
                    156:                key += *name++;
                    157:                key = (key << 8) | (key >> 24);
                    158:        }
                    159:
                    160:        return (key % tabsz);
                    161: }
                    162:
                    163: /*
                    164:  * uidtb_start
                    165:  *     creates an an empty uidtb
                    166:  * Return:
                    167:  *     0 if ok, -1 otherwise
                    168:  */
                    169: static int
                    170: uidtb_start(void)
                    171: {
                    172:
                    173:        if (uidtb != NULL)
                    174:                return (0);
1.17      lukem     175:        if (uidtb_fail)
1.10      mycroft   176:                return (-1);
                    177:        if ((uidtb = (UIDC **)calloc(UID_SZ, sizeof(UIDC *))) == NULL) {
1.17      lukem     178:                ++uidtb_fail;
1.10      mycroft   179:                return (-1);
                    180:        }
                    181:        return (0);
                    182: }
                    183:
                    184: /*
                    185:  * gidtb_start
                    186:  *     creates an an empty gidtb
                    187:  * Return:
                    188:  *     0 if ok, -1 otherwise
                    189:  */
1.17      lukem     190: static int
1.10      mycroft   191: gidtb_start(void)
                    192: {
                    193:
                    194:        if (gidtb != NULL)
                    195:                return (0);
1.17      lukem     196:        if (gidtb_fail)
1.10      mycroft   197:                return (-1);
                    198:        if ((gidtb = (GIDC **)calloc(GID_SZ, sizeof(GIDC *))) == NULL) {
1.17      lukem     199:                ++gidtb_fail;
1.10      mycroft   200:                return (-1);
                    201:        }
                    202:        return (0);
                    203: }
                    204:
                    205: /*
                    206:  * usrtb_start
                    207:  *     creates an an empty usrtb
                    208:  * Return:
                    209:  *     0 if ok, -1 otherwise
                    210:  */
1.17      lukem     211: static int
1.10      mycroft   212: usrtb_start(void)
                    213: {
                    214:
                    215:        if (usrtb != NULL)
                    216:                return (0);
1.17      lukem     217:        if (usrtb_fail)
1.10      mycroft   218:                return (-1);
                    219:        if ((usrtb = (UIDC **)calloc(UNM_SZ, sizeof(UIDC *))) == NULL) {
1.17      lukem     220:                ++usrtb_fail;
1.10      mycroft   221:                return (-1);
                    222:        }
                    223:        return (0);
                    224: }
                    225:
                    226: /*
                    227:  * grptb_start
                    228:  *     creates an an empty grptb
                    229:  * Return:
                    230:  *     0 if ok, -1 otherwise
                    231:  */
1.17      lukem     232: static int
1.10      mycroft   233: grptb_start(void)
                    234: {
                    235:
                    236:        if (grptb != NULL)
                    237:                return (0);
1.17      lukem     238:        if (grptb_fail)
1.10      mycroft   239:                return (-1);
                    240:        if ((grptb = (GIDC **)calloc(GNM_SZ, sizeof(GIDC *))) == NULL) {
1.17      lukem     241:                ++grptb_fail;
1.10      mycroft   242:                return (-1);
                    243:        }
                    244:        return (0);
                    245: }
                    246:
                    247: /*
1.11      mycroft   248:  * user_from_uid()
1.16      lukem     249:  *     caches the name (if any) for the uid. If noname clear, we always
1.26      simonb    250:  *     return the stored name (if valid or invalid match).
1.16      lukem     251:  *     We use a simple hash table.
1.10      mycroft   252:  * Return
                    253:  *     Pointer to stored name (or a empty string)
                    254:  */
                    255: const char *
                    256: user_from_uid(uid_t uid, int noname)
1.1       cgd       257: {
1.9       perry     258:        struct passwd *pw;
1.10      mycroft   259:        UIDC *ptr, **pptr;
1.1       cgd       260:
1.10      mycroft   261:        if ((uidtb == NULL) && (uidtb_start() < 0))
                    262:                return (NULL);
                    263:
                    264:        /*
                    265:         * see if we have this uid cached
                    266:         */
                    267:        pptr = uidtb + (uid % UID_SZ);
                    268:        ptr = *pptr;
                    269:
                    270:        if ((ptr != NULL) && (ptr->valid > 0) && (ptr->uid == uid)) {
                    271:                /*
                    272:                 * have an entry for this uid
                    273:                 */
                    274:                if (!noname || (ptr->valid == VALID))
                    275:                        return (ptr->name);
                    276:                return (NULL);
                    277:        }
                    278:
                    279:        /*
                    280:         * No entry for this uid, we will add it
                    281:         */
                    282:        if (!pwopn) {
1.17      lukem     283:                if (_pwcache_setpassent != NULL)
                    284:                        (*_pwcache_setpassent)(1);
1.10      mycroft   285:                ++pwopn;
1.1       cgd       286:        }
1.10      mycroft   287:
                    288:        if (ptr == NULL)
1.12      mycroft   289:                *pptr = ptr = (UIDC *)malloc(sizeof(UIDC));
1.10      mycroft   290:
1.17      lukem     291:        if ((pw = (*_pwcache_getpwuid)(uid)) == NULL) {
1.10      mycroft   292:                /*
                    293:                 * no match for this uid in the local password file
1.23      grant     294:                 * a string that is the uid in numeric format
1.10      mycroft   295:                 */
                    296:                if (ptr == NULL)
                    297:                        return (NULL);
                    298:                ptr->uid = uid;
                    299:                (void)snprintf(ptr->name, UNMLEN, "%lu", (long) uid);
                    300:                ptr->valid = INVALID;
                    301:                if (noname)
                    302:                        return (NULL);
                    303:        } else {
                    304:                /*
                    305:                 * there is an entry for this uid in the password file
                    306:                 */
                    307:                if (ptr == NULL)
                    308:                        return (pw->pw_name);
                    309:                ptr->uid = uid;
1.17      lukem     310:                (void)strlcpy(ptr->name, pw->pw_name, UNMLEN);
1.10      mycroft   311:                ptr->valid = VALID;
                    312:        }
                    313:        return (ptr->name);
1.1       cgd       314: }
                    315:
1.10      mycroft   316: /*
                    317:  * group_from_gid()
1.16      lukem     318:  *     caches the name (if any) for the gid. If noname clear, we always
1.26      simonb    319:  *     return the stored name (if valid or invalid match).
1.16      lukem     320:  *     We use a simple hash table.
1.10      mycroft   321:  * Return
                    322:  *     Pointer to stored name (or a empty string)
                    323:  */
                    324: const char *
                    325: group_from_gid(gid_t gid, int noname)
                    326: {
                    327:        struct group *gr;
                    328:        GIDC *ptr, **pptr;
                    329:
                    330:        if ((gidtb == NULL) && (gidtb_start() < 0))
                    331:                return (NULL);
                    332:
                    333:        /*
                    334:         * see if we have this gid cached
                    335:         */
                    336:        pptr = gidtb + (gid % GID_SZ);
                    337:        ptr = *pptr;
                    338:
                    339:        if ((ptr != NULL) && (ptr->valid > 0) && (ptr->gid == gid)) {
                    340:                /*
                    341:                 * have an entry for this gid
                    342:                 */
                    343:                if (!noname || (ptr->valid == VALID))
                    344:                        return (ptr->name);
                    345:                return (NULL);
                    346:        }
                    347:
                    348:        /*
                    349:         * No entry for this gid, we will add it
                    350:         */
                    351:        if (!gropn) {
1.17      lukem     352:                if (_pwcache_setgroupent != NULL)
                    353:                        (*_pwcache_setgroupent)(1);
1.10      mycroft   354:                ++gropn;
                    355:        }
                    356:
                    357:        if (ptr == NULL)
1.12      mycroft   358:                *pptr = ptr = (GIDC *)malloc(sizeof(GIDC));
1.10      mycroft   359:
1.17      lukem     360:        if ((gr = (*_pwcache_getgrgid)(gid)) == NULL) {
1.10      mycroft   361:                /*
                    362:                 * no match for this gid in the local group file, put in
                    363:                 * a string that is the gid in numberic format
                    364:                 */
                    365:                if (ptr == NULL)
                    366:                        return (NULL);
                    367:                ptr->gid = gid;
                    368:                (void)snprintf(ptr->name, GNMLEN, "%lu", (long) gid);
                    369:                ptr->valid = INVALID;
                    370:                if (noname)
                    371:                        return (NULL);
                    372:        } else {
                    373:                /*
                    374:                 * there is an entry for this group in the group file
                    375:                 */
                    376:                if (ptr == NULL)
                    377:                        return (gr->gr_name);
                    378:                ptr->gid = gid;
1.17      lukem     379:                (void)strlcpy(ptr->name, gr->gr_name, GNMLEN);
1.10      mycroft   380:                ptr->valid = VALID;
                    381:        }
                    382:        return (ptr->name);
                    383: }
                    384:
                    385: /*
                    386:  * uid_from_user()
                    387:  *     caches the uid for a given user name. We use a simple hash table.
                    388:  * Return
                    389:  *     the uid (if any) for a user name, or a -1 if no match can be found
                    390:  */
                    391: int
                    392: uid_from_user(const char *name, uid_t *uid)
                    393: {
                    394:        struct passwd *pw;
                    395:        UIDC *ptr, **pptr;
                    396:        size_t namelen;
                    397:
                    398:        /*
                    399:         * return -1 for mangled names
                    400:         */
1.13      lukem     401:        if (name == NULL || ((namelen = strlen(name)) == 0))
1.10      mycroft   402:                return (-1);
                    403:        if ((usrtb == NULL) && (usrtb_start() < 0))
                    404:                return (-1);
                    405:
                    406:        /*
                    407:         * look up in hash table, if found and valid return the uid,
                    408:         * if found and invalid, return a -1
                    409:         */
                    410:        pptr = usrtb + st_hash(name, namelen, UNM_SZ);
                    411:        ptr = *pptr;
                    412:
                    413:        if ((ptr != NULL) && (ptr->valid > 0) && !strcmp(name, ptr->name)) {
                    414:                if (ptr->valid == INVALID)
                    415:                        return (-1);
                    416:                *uid = ptr->uid;
                    417:                return (0);
                    418:        }
                    419:
                    420:        if (!pwopn) {
1.17      lukem     421:                if (_pwcache_setpassent != NULL)
                    422:                        (*_pwcache_setpassent)(1);
1.10      mycroft   423:                ++pwopn;
                    424:        }
                    425:
                    426:        if (ptr == NULL)
1.12      mycroft   427:                *pptr = ptr = (UIDC *)malloc(sizeof(UIDC));
1.10      mycroft   428:
                    429:        /*
                    430:         * no match, look it up, if no match store it as an invalid entry,
                    431:         * or store the matching uid
                    432:         */
                    433:        if (ptr == NULL) {
1.17      lukem     434:                if ((pw = (*_pwcache_getpwnam)(name)) == NULL)
1.10      mycroft   435:                        return (-1);
                    436:                *uid = pw->pw_uid;
                    437:                return (0);
                    438:        }
1.17      lukem     439:        (void)strlcpy(ptr->name, name, UNMLEN);
                    440:        if ((pw = (*_pwcache_getpwnam)(name)) == NULL) {
1.10      mycroft   441:                ptr->valid = INVALID;
                    442:                return (-1);
                    443:        }
                    444:        ptr->valid = VALID;
                    445:        *uid = ptr->uid = pw->pw_uid;
                    446:        return (0);
                    447: }
                    448:
                    449: /*
                    450:  * gid_from_group()
                    451:  *     caches the gid for a given group name. We use a simple hash table.
                    452:  * Return
                    453:  *     the gid (if any) for a group name, or a -1 if no match can be found
                    454:  */
                    455: int
                    456: gid_from_group(const char *name, gid_t *gid)
1.1       cgd       457: {
1.4       cgd       458:        struct group *gr;
1.10      mycroft   459:        GIDC *ptr, **pptr;
                    460:        size_t namelen;
                    461:
                    462:        /*
                    463:         * return -1 for mangled names
                    464:         */
1.13      lukem     465:        if (name == NULL || ((namelen = strlen(name)) == 0))
1.10      mycroft   466:                return (-1);
                    467:        if ((grptb == NULL) && (grptb_start() < 0))
                    468:                return (-1);
                    469:
                    470:        /*
                    471:         * look up in hash table, if found and valid return the uid,
                    472:         * if found and invalid, return a -1
                    473:         */
                    474:        pptr = grptb + st_hash(name, namelen, GID_SZ);
                    475:        ptr = *pptr;
                    476:
                    477:        if ((ptr != NULL) && (ptr->valid > 0) && !strcmp(name, ptr->name)) {
                    478:                if (ptr->valid == INVALID)
                    479:                        return (-1);
                    480:                *gid = ptr->gid;
                    481:                return (0);
                    482:        }
                    483:
                    484:        if (!gropn) {
1.17      lukem     485:                if (_pwcache_setgroupent != NULL)
                    486:                        (*_pwcache_setgroupent)(1);
1.10      mycroft   487:                ++gropn;
                    488:        }
                    489:
                    490:        if (ptr == NULL)
1.12      mycroft   491:                *pptr = ptr = (GIDC *)malloc(sizeof(GIDC));
1.10      mycroft   492:
                    493:        /*
                    494:         * no match, look it up, if no match store it as an invalid entry,
                    495:         * or store the matching gid
                    496:         */
                    497:        if (ptr == NULL) {
1.17      lukem     498:                if ((gr = (*_pwcache_getgrnam)(name)) == NULL)
1.10      mycroft   499:                        return (-1);
                    500:                *gid = gr->gr_gid;
                    501:                return (0);
                    502:        }
1.1       cgd       503:
1.17      lukem     504:        (void)strlcpy(ptr->name, name, GNMLEN);
                    505:        if ((gr = (*_pwcache_getgrnam)(name)) == NULL) {
1.10      mycroft   506:                ptr->valid = INVALID;
                    507:                return (-1);
1.1       cgd       508:        }
1.10      mycroft   509:        ptr->valid = VALID;
                    510:        *gid = ptr->gid = gr->gr_gid;
                    511:        return (0);
1.1       cgd       512: }
1.17      lukem     513:
                    514: #define FLUSHTB(arr, len, fail)                                \
                    515:        do {                                            \
                    516:                if (arr != NULL) {                      \
                    517:                        for (i = 0; i < len; i++)       \
                    518:                                if (arr[i] != NULL)     \
                    519:                                        free(arr[i]);   \
                    520:                        arr = NULL;                     \
                    521:                }                                       \
                    522:                fail = 0;                               \
                    523:        } while (/* CONSTCOND */0);
                    524:
                    525: int
                    526: pwcache_userdb(
                    527:        int             (*a_setpassent)(int),
                    528:        void            (*a_endpwent)(void),
                    529:        struct passwd * (*a_getpwnam)(const char *),
                    530:        struct passwd * (*a_getpwuid)(uid_t))
                    531: {
                    532:        int i;
                    533:
                    534:                /* a_setpassent and a_endpwent may be NULL */
                    535:        if (a_getpwnam == NULL || a_getpwuid == NULL)
                    536:                return (-1);
                    537:
                    538:        if (_pwcache_endpwent != NULL)
                    539:                (*_pwcache_endpwent)();
                    540:        FLUSHTB(uidtb, UID_SZ, uidtb_fail);
                    541:        FLUSHTB(usrtb, UNM_SZ, usrtb_fail);
                    542:        pwopn = 0;
                    543:        _pwcache_setpassent = a_setpassent;
                    544:        _pwcache_endpwent = a_endpwent;
                    545:        _pwcache_getpwnam = a_getpwnam;
                    546:        _pwcache_getpwuid = a_getpwuid;
                    547:
                    548:        return (0);
                    549: }
                    550:
                    551: int
                    552: pwcache_groupdb(
                    553:        int             (*a_setgroupent)(int),
                    554:        void            (*a_endgrent)(void),
                    555:        struct group *  (*a_getgrnam)(const char *),
                    556:        struct group *  (*a_getgrgid)(gid_t))
                    557: {
                    558:        int i;
                    559:
                    560:                /* a_setgroupent and a_endgrent may be NULL */
                    561:        if (a_getgrnam == NULL || a_getgrgid == NULL)
                    562:                return (-1);
                    563:
                    564:        if (_pwcache_endgrent != NULL)
                    565:                (*_pwcache_endgrent)();
                    566:        FLUSHTB(gidtb, GID_SZ, gidtb_fail);
                    567:        FLUSHTB(grptb, GNM_SZ, grptb_fail);
                    568:        gropn = 0;
                    569:        _pwcache_setgroupent = a_setgroupent;
                    570:        _pwcache_endgrent = a_endgrent;
                    571:        _pwcache_getgrnam = a_getgrnam;
                    572:        _pwcache_getgrgid = a_getgrgid;
                    573:
                    574:        return (0);
                    575: }
                    576:
                    577:
                    578: #ifdef TEST_PWCACHE
                    579:
                    580: struct passwd *
                    581: test_getpwnam(const char *name)
                    582: {
                    583:        static struct passwd foo;
                    584:
                    585:        memset(&foo, 0, sizeof(foo));
                    586:        if (strcmp(name, "toor") == 0) {
                    587:                foo.pw_uid = 666;
                    588:                return &foo;
                    589:        }
                    590:        return (getpwnam(name));
                    591: }
                    592:
                    593: int
                    594: main(int argc, char *argv[])
                    595: {
                    596:        uid_t   u;
                    597:        int     r, i;
                    598:
                    599:        printf("pass 1 (default userdb)\n");
                    600:        for (i = 1; i < argc; i++) {
                    601:                printf("i: %d, pwopn %d usrtb_fail %d usrtb %p\n",
                    602:                    i, pwopn, usrtb_fail, usrtb);
                    603:                r = uid_from_user(argv[i], &u);
                    604:                if (r == -1)
                    605:                        printf("  uid_from_user %s: failed\n", argv[i]);
                    606:                else
                    607:                        printf("  uid_from_user %s: %d\n", argv[i], u);
                    608:        }
                    609:        printf("pass 1 finish: pwopn %d usrtb_fail %d usrtb %p\n",
                    610:                    pwopn, usrtb_fail, usrtb);
                    611:
                    612:        puts("");
                    613:        printf("pass 2 (replacement userdb)\n");
                    614:        printf("pwcache_userdb returned %d\n",
                    615:            pwcache_userdb(setpassent, test_getpwnam, getpwuid));
                    616:        printf("pwopn %d usrtb_fail %d usrtb %p\n", pwopn, usrtb_fail, usrtb);
                    617:
                    618:        for (i = 1; i < argc; i++) {
                    619:                printf("i: %d, pwopn %d usrtb_fail %d usrtb %p\n",
                    620:                    i, pwopn, usrtb_fail, usrtb);
                    621:                u = -1;
                    622:                r = uid_from_user(argv[i], &u);
                    623:                if (r == -1)
                    624:                        printf("  uid_from_user %s: failed\n", argv[i]);
                    625:                else
                    626:                        printf("  uid_from_user %s: %d\n", argv[i], u);
                    627:        }
                    628:        printf("pass 2 finish: pwopn %d usrtb_fail %d usrtb %p\n",
                    629:                    pwopn, usrtb_fail, usrtb);
                    630:
                    631:        puts("");
                    632:        printf("pass 3 (null pointers)\n");
                    633:        printf("pwcache_userdb returned %d\n",
                    634:            pwcache_userdb(NULL, NULL, NULL));
                    635:
                    636:        return (0);
                    637: }
                    638: #endif /* TEST_PWCACHE */
1.18      lukem     639: #endif /* !HAVE_PWCACHE_USERDB */

CVSweb <webmaster@jp.NetBSD.org>