14b88c807SRodney W. Grimes /*- 24b88c807SRodney W. Grimes * Copyright (c) 1992 Keith Muller. 34b88c807SRodney W. Grimes * Copyright (c) 1992, 1993 44b88c807SRodney W. Grimes * The Regents of the University of California. All rights reserved. 54b88c807SRodney W. Grimes * 64b88c807SRodney W. Grimes * This code is derived from software contributed to Berkeley by 74b88c807SRodney W. Grimes * Keith Muller of the University of California, San Diego. 84b88c807SRodney W. Grimes * 94b88c807SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 104b88c807SRodney W. Grimes * modification, are permitted provided that the following conditions 114b88c807SRodney W. Grimes * are met: 124b88c807SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 134b88c807SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 144b88c807SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 154b88c807SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 164b88c807SRodney W. Grimes * documentation and/or other materials provided with the distribution. 174b88c807SRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 184b88c807SRodney W. Grimes * must display the following acknowledgement: 194b88c807SRodney W. Grimes * This product includes software developed by the University of 204b88c807SRodney W. Grimes * California, Berkeley and its contributors. 214b88c807SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 224b88c807SRodney W. Grimes * may be used to endorse or promote products derived from this software 234b88c807SRodney W. Grimes * without specific prior written permission. 244b88c807SRodney W. Grimes * 254b88c807SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 264b88c807SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 274b88c807SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 284b88c807SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 294b88c807SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 304b88c807SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 314b88c807SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 324b88c807SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 334b88c807SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 344b88c807SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 354b88c807SRodney W. Grimes * SUCH DAMAGE. 364b88c807SRodney W. Grimes */ 374b88c807SRodney W. Grimes 384b88c807SRodney W. Grimes #ifndef lint 39c9a8d1f4SPhilippe Charnier #if 0 40c9a8d1f4SPhilippe Charnier static char sccsid[] = "@(#)cache.c 8.1 (Berkeley) 5/31/93"; 41c9a8d1f4SPhilippe Charnier #endif 424b88c807SRodney W. Grimes #endif /* not lint */ 432749b141SDavid E. O'Brien #include <sys/cdefs.h> 442749b141SDavid E. O'Brien __FBSDID("$FreeBSD$"); 454b88c807SRodney W. Grimes 464b88c807SRodney W. Grimes #include <sys/types.h> 474b88c807SRodney W. Grimes #include <sys/stat.h> 484b88c807SRodney W. Grimes #include <string.h> 494b88c807SRodney W. Grimes #include <stdio.h> 504b88c807SRodney W. Grimes #include <pwd.h> 514b88c807SRodney W. Grimes #include <grp.h> 524b88c807SRodney W. Grimes #include <unistd.h> 534b88c807SRodney W. Grimes #include <stdlib.h> 544b88c807SRodney W. Grimes #include "pax.h" 554b88c807SRodney W. Grimes #include "cache.h" 564b88c807SRodney W. Grimes #include "extern.h" 574b88c807SRodney W. Grimes 584b88c807SRodney W. Grimes /* 594b88c807SRodney W. Grimes * routines that control user, group, uid and gid caches (for the archive 604b88c807SRodney W. Grimes * member print routine). 614b88c807SRodney W. Grimes * IMPORTANT: 624b88c807SRodney W. Grimes * these routines cache BOTH hits and misses, a major performance improvement 634b88c807SRodney W. Grimes */ 644b88c807SRodney W. Grimes 654b88c807SRodney W. Grimes static int pwopn = 0; /* is password file open */ 664b88c807SRodney W. Grimes static int gropn = 0; /* is group file open */ 674b88c807SRodney W. Grimes static UIDC **uidtb = NULL; /* uid to name cache */ 684b88c807SRodney W. Grimes static GIDC **gidtb = NULL; /* gid to name cache */ 694b88c807SRodney W. Grimes static UIDC **usrtb = NULL; /* user name to uid cache */ 704b88c807SRodney W. Grimes static GIDC **grptb = NULL; /* group name to gid cache */ 714b88c807SRodney W. Grimes 724b88c807SRodney W. Grimes /* 734b88c807SRodney W. Grimes * uidtb_start 744b88c807SRodney W. Grimes * creates an an empty uidtb 754b88c807SRodney W. Grimes * Return: 764b88c807SRodney W. Grimes * 0 if ok, -1 otherwise 774b88c807SRodney W. Grimes */ 784b88c807SRodney W. Grimes 794b88c807SRodney W. Grimes int 804b88c807SRodney W. Grimes uidtb_start(void) 814b88c807SRodney W. Grimes { 824b88c807SRodney W. Grimes static int fail = 0; 834b88c807SRodney W. Grimes 844b88c807SRodney W. Grimes if (uidtb != NULL) 854b88c807SRodney W. Grimes return(0); 864b88c807SRodney W. Grimes if (fail) 874b88c807SRodney W. Grimes return(-1); 884b88c807SRodney W. Grimes if ((uidtb = (UIDC **)calloc(UID_SZ, sizeof(UIDC *))) == NULL) { 894b88c807SRodney W. Grimes ++fail; 90778766feSKris Kennaway paxwarn(1, "Unable to allocate memory for user id cache table"); 914b88c807SRodney W. Grimes return(-1); 924b88c807SRodney W. Grimes } 934b88c807SRodney W. Grimes return(0); 944b88c807SRodney W. Grimes } 954b88c807SRodney W. Grimes 964b88c807SRodney W. Grimes /* 974b88c807SRodney W. Grimes * gidtb_start 984b88c807SRodney W. Grimes * creates an an empty gidtb 994b88c807SRodney W. Grimes * Return: 1004b88c807SRodney W. Grimes * 0 if ok, -1 otherwise 1014b88c807SRodney W. Grimes */ 1024b88c807SRodney W. Grimes 1034b88c807SRodney W. Grimes int 1044b88c807SRodney W. Grimes gidtb_start(void) 1054b88c807SRodney W. Grimes { 1064b88c807SRodney W. Grimes static int fail = 0; 1074b88c807SRodney W. Grimes 1084b88c807SRodney W. Grimes if (gidtb != NULL) 1094b88c807SRodney W. Grimes return(0); 1104b88c807SRodney W. Grimes if (fail) 1114b88c807SRodney W. Grimes return(-1); 1124b88c807SRodney W. Grimes if ((gidtb = (GIDC **)calloc(GID_SZ, sizeof(GIDC *))) == NULL) { 1134b88c807SRodney W. Grimes ++fail; 114778766feSKris Kennaway paxwarn(1, "Unable to allocate memory for group id cache table"); 1154b88c807SRodney W. Grimes return(-1); 1164b88c807SRodney W. Grimes } 1174b88c807SRodney W. Grimes return(0); 1184b88c807SRodney W. Grimes } 1194b88c807SRodney W. Grimes 1204b88c807SRodney W. Grimes /* 1214b88c807SRodney W. Grimes * usrtb_start 1224b88c807SRodney W. Grimes * creates an an empty usrtb 1234b88c807SRodney W. Grimes * Return: 1244b88c807SRodney W. Grimes * 0 if ok, -1 otherwise 1254b88c807SRodney W. Grimes */ 1264b88c807SRodney W. Grimes 1274b88c807SRodney W. Grimes int 1284b88c807SRodney W. Grimes usrtb_start(void) 1294b88c807SRodney W. Grimes { 1304b88c807SRodney W. Grimes static int fail = 0; 1314b88c807SRodney W. Grimes 1324b88c807SRodney W. Grimes if (usrtb != NULL) 1334b88c807SRodney W. Grimes return(0); 1344b88c807SRodney W. Grimes if (fail) 1354b88c807SRodney W. Grimes return(-1); 1364b88c807SRodney W. Grimes if ((usrtb = (UIDC **)calloc(UNM_SZ, sizeof(UIDC *))) == NULL) { 1374b88c807SRodney W. Grimes ++fail; 138778766feSKris Kennaway paxwarn(1, "Unable to allocate memory for user name cache table"); 1394b88c807SRodney W. Grimes return(-1); 1404b88c807SRodney W. Grimes } 1414b88c807SRodney W. Grimes return(0); 1424b88c807SRodney W. Grimes } 1434b88c807SRodney W. Grimes 1444b88c807SRodney W. Grimes /* 1454b88c807SRodney W. Grimes * grptb_start 1464b88c807SRodney W. Grimes * creates an an empty grptb 1474b88c807SRodney W. Grimes * Return: 1484b88c807SRodney W. Grimes * 0 if ok, -1 otherwise 1494b88c807SRodney W. Grimes */ 1504b88c807SRodney W. Grimes 1514b88c807SRodney W. Grimes int 1524b88c807SRodney W. Grimes grptb_start(void) 1534b88c807SRodney W. Grimes { 1544b88c807SRodney W. Grimes static int fail = 0; 1554b88c807SRodney W. Grimes 1564b88c807SRodney W. Grimes if (grptb != NULL) 1574b88c807SRodney W. Grimes return(0); 1584b88c807SRodney W. Grimes if (fail) 1594b88c807SRodney W. Grimes return(-1); 1604b88c807SRodney W. Grimes if ((grptb = (GIDC **)calloc(GNM_SZ, sizeof(GIDC *))) == NULL) { 1614b88c807SRodney W. Grimes ++fail; 162778766feSKris Kennaway paxwarn(1,"Unable to allocate memory for group name cache table"); 1634b88c807SRodney W. Grimes return(-1); 1644b88c807SRodney W. Grimes } 1654b88c807SRodney W. Grimes return(0); 1664b88c807SRodney W. Grimes } 1674b88c807SRodney W. Grimes 1684b88c807SRodney W. Grimes /* 1694b88c807SRodney W. Grimes * name_uid() 1704b88c807SRodney W. Grimes * caches the name (if any) for the uid. If frc set, we always return the 1714b88c807SRodney W. Grimes * the stored name (if valid or invalid match). We use a simple hash table. 1724b88c807SRodney W. Grimes * Return 1739d5abbddSJens Schweikhardt * Pointer to stored name (or an empty string). 1744b88c807SRodney W. Grimes */ 1754b88c807SRodney W. Grimes 17640feca3aSMark Murray const char * 1774b88c807SRodney W. Grimes name_uid(uid_t uid, int frc) 1784b88c807SRodney W. Grimes { 179f789b261SWarner Losh struct passwd *pw; 180f789b261SWarner Losh UIDC *ptr; 1814b88c807SRodney W. Grimes 1824b88c807SRodney W. Grimes if ((uidtb == NULL) && (uidtb_start() < 0)) 1834b88c807SRodney W. Grimes return(""); 1844b88c807SRodney W. Grimes 1854b88c807SRodney W. Grimes /* 1864b88c807SRodney W. Grimes * see if we have this uid cached 1874b88c807SRodney W. Grimes */ 1884b88c807SRodney W. Grimes ptr = uidtb[uid % UID_SZ]; 1894b88c807SRodney W. Grimes if ((ptr != NULL) && (ptr->valid > 0) && (ptr->uid == uid)) { 1904b88c807SRodney W. Grimes /* 1914b88c807SRodney W. Grimes * have an entry for this uid 1924b88c807SRodney W. Grimes */ 1934b88c807SRodney W. Grimes if (frc || (ptr->valid == VALID)) 1944b88c807SRodney W. Grimes return(ptr->name); 1954b88c807SRodney W. Grimes return(""); 1964b88c807SRodney W. Grimes } 1974b88c807SRodney W. Grimes 1984b88c807SRodney W. Grimes /* 1994b88c807SRodney W. Grimes * No entry for this uid, we will add it 2004b88c807SRodney W. Grimes */ 2014b88c807SRodney W. Grimes if (!pwopn) { 2024b88c807SRodney W. Grimes setpassent(1); 2034b88c807SRodney W. Grimes ++pwopn; 2044b88c807SRodney W. Grimes } 2054b88c807SRodney W. Grimes if (ptr == NULL) 2064b88c807SRodney W. Grimes ptr = (UIDC *)malloc(sizeof(UIDC)); 2074b88c807SRodney W. Grimes 2084b88c807SRodney W. Grimes if ((pw = getpwuid(uid)) == NULL) { 2094b88c807SRodney W. Grimes /* 2104b88c807SRodney W. Grimes * no match for this uid in the local password file 21146be34b9SKris Kennaway * a string that is the uid in numeric format 2124b88c807SRodney W. Grimes */ 2134b88c807SRodney W. Grimes if (ptr == NULL) 2144b88c807SRodney W. Grimes return(""); 2154b88c807SRodney W. Grimes ptr->uid = uid; 2164b88c807SRodney W. Grimes ptr->valid = INVALID; 2174b88c807SRodney W. Grimes # ifdef NET2_STAT 218778766feSKris Kennaway (void)snprintf(ptr->name, sizeof(ptr->name), "%u", uid); 2194b88c807SRodney W. Grimes # else 220778766feSKris Kennaway (void)snprintf(ptr->name, sizeof(ptr->name), "%lu", 221778766feSKris Kennaway (unsigned long)uid); 2224b88c807SRodney W. Grimes # endif 2234b88c807SRodney W. Grimes if (frc == 0) 2244b88c807SRodney W. Grimes return(""); 2254b88c807SRodney W. Grimes } else { 2264b88c807SRodney W. Grimes /* 2274b88c807SRodney W. Grimes * there is an entry for this uid in the password file 2284b88c807SRodney W. Grimes */ 2294b88c807SRodney W. Grimes if (ptr == NULL) 2304b88c807SRodney W. Grimes return(pw->pw_name); 2314b88c807SRodney W. Grimes ptr->uid = uid; 232877155d0SPhilippe Charnier (void)strncpy(ptr->name, pw->pw_name, UNMLEN - 1); 2334b88c807SRodney W. Grimes ptr->name[UNMLEN-1] = '\0'; 2344b88c807SRodney W. Grimes ptr->valid = VALID; 2354b88c807SRodney W. Grimes } 2364b88c807SRodney W. Grimes return(ptr->name); 2374b88c807SRodney W. Grimes } 2384b88c807SRodney W. Grimes 2394b88c807SRodney W. Grimes /* 2404b88c807SRodney W. Grimes * name_gid() 2414b88c807SRodney W. Grimes * caches the name (if any) for the gid. If frc set, we always return the 2424b88c807SRodney W. Grimes * the stored name (if valid or invalid match). We use a simple hash table. 2434b88c807SRodney W. Grimes * Return 2449d5abbddSJens Schweikhardt * Pointer to stored name (or an empty string). 2454b88c807SRodney W. Grimes */ 2464b88c807SRodney W. Grimes 24740feca3aSMark Murray const char * 2484b88c807SRodney W. Grimes name_gid(gid_t gid, int frc) 2494b88c807SRodney W. Grimes { 250f789b261SWarner Losh struct group *gr; 251f789b261SWarner Losh GIDC *ptr; 2524b88c807SRodney W. Grimes 2534b88c807SRodney W. Grimes if ((gidtb == NULL) && (gidtb_start() < 0)) 2544b88c807SRodney W. Grimes return(""); 2554b88c807SRodney W. Grimes 2564b88c807SRodney W. Grimes /* 2574b88c807SRodney W. Grimes * see if we have this gid cached 2584b88c807SRodney W. Grimes */ 2594b88c807SRodney W. Grimes ptr = gidtb[gid % GID_SZ]; 2604b88c807SRodney W. Grimes if ((ptr != NULL) && (ptr->valid > 0) && (ptr->gid == gid)) { 2614b88c807SRodney W. Grimes /* 2624b88c807SRodney W. Grimes * have an entry for this gid 2634b88c807SRodney W. Grimes */ 2644b88c807SRodney W. Grimes if (frc || (ptr->valid == VALID)) 2654b88c807SRodney W. Grimes return(ptr->name); 2664b88c807SRodney W. Grimes return(""); 2674b88c807SRodney W. Grimes } 2684b88c807SRodney W. Grimes 2694b88c807SRodney W. Grimes /* 2704b88c807SRodney W. Grimes * No entry for this gid, we will add it 2714b88c807SRodney W. Grimes */ 2724b88c807SRodney W. Grimes if (!gropn) { 2734b88c807SRodney W. Grimes setgroupent(1); 2744b88c807SRodney W. Grimes ++gropn; 2754b88c807SRodney W. Grimes } 2764b88c807SRodney W. Grimes if (ptr == NULL) 2774b88c807SRodney W. Grimes ptr = (GIDC *)malloc(sizeof(GIDC)); 2784b88c807SRodney W. Grimes 2794b88c807SRodney W. Grimes if ((gr = getgrgid(gid)) == NULL) { 2804b88c807SRodney W. Grimes /* 2814b88c807SRodney W. Grimes * no match for this gid in the local group file, put in 28246be34b9SKris Kennaway * a string that is the gid in numeric format 2834b88c807SRodney W. Grimes */ 2844b88c807SRodney W. Grimes if (ptr == NULL) 2854b88c807SRodney W. Grimes return(""); 2864b88c807SRodney W. Grimes ptr->gid = gid; 2874b88c807SRodney W. Grimes ptr->valid = INVALID; 2884b88c807SRodney W. Grimes # ifdef NET2_STAT 289778766feSKris Kennaway (void)snprintf(ptr->name, sizeof(ptr->name), "%u", gid); 2904b88c807SRodney W. Grimes # else 291778766feSKris Kennaway (void)snprintf(ptr->name, sizeof(ptr->name), "%lu", 292778766feSKris Kennaway (unsigned long)gid); 2934b88c807SRodney W. Grimes # endif 2944b88c807SRodney W. Grimes if (frc == 0) 2954b88c807SRodney W. Grimes return(""); 2964b88c807SRodney W. Grimes } else { 2974b88c807SRodney W. Grimes /* 2984b88c807SRodney W. Grimes * there is an entry for this group in the group file 2994b88c807SRodney W. Grimes */ 3004b88c807SRodney W. Grimes if (ptr == NULL) 3014b88c807SRodney W. Grimes return(gr->gr_name); 3024b88c807SRodney W. Grimes ptr->gid = gid; 303877155d0SPhilippe Charnier (void)strncpy(ptr->name, gr->gr_name, GNMLEN - 1); 3044b88c807SRodney W. Grimes ptr->name[GNMLEN-1] = '\0'; 3054b88c807SRodney W. Grimes ptr->valid = VALID; 3064b88c807SRodney W. Grimes } 3074b88c807SRodney W. Grimes return(ptr->name); 3084b88c807SRodney W. Grimes } 3094b88c807SRodney W. Grimes 3104b88c807SRodney W. Grimes /* 3114b88c807SRodney W. Grimes * uid_name() 3124b88c807SRodney W. Grimes * caches the uid for a given user name. We use a simple hash table. 3134b88c807SRodney W. Grimes * Return 3144b88c807SRodney W. Grimes * the uid (if any) for a user name, or a -1 if no match can be found 3154b88c807SRodney W. Grimes */ 3164b88c807SRodney W. Grimes 3174b88c807SRodney W. Grimes int 3184b88c807SRodney W. Grimes uid_name(char *name, uid_t *uid) 3194b88c807SRodney W. Grimes { 320f789b261SWarner Losh struct passwd *pw; 321f789b261SWarner Losh UIDC *ptr; 322f789b261SWarner Losh int namelen; 3234b88c807SRodney W. Grimes 3244b88c807SRodney W. Grimes /* 3254b88c807SRodney W. Grimes * return -1 for mangled names 3264b88c807SRodney W. Grimes */ 3274b88c807SRodney W. Grimes if (((namelen = strlen(name)) == 0) || (name[0] == '\0')) 3284b88c807SRodney W. Grimes return(-1); 3294b88c807SRodney W. Grimes if ((usrtb == NULL) && (usrtb_start() < 0)) 3304b88c807SRodney W. Grimes return(-1); 3314b88c807SRodney W. Grimes 3324b88c807SRodney W. Grimes /* 3334b88c807SRodney W. Grimes * look up in hash table, if found and valid return the uid, 3344b88c807SRodney W. Grimes * if found and invalid, return a -1 3354b88c807SRodney W. Grimes */ 3364b88c807SRodney W. Grimes ptr = usrtb[st_hash(name, namelen, UNM_SZ)]; 3374b88c807SRodney W. Grimes if ((ptr != NULL) && (ptr->valid > 0) && !strcmp(name, ptr->name)) { 3384b88c807SRodney W. Grimes if (ptr->valid == INVALID) 3394b88c807SRodney W. Grimes return(-1); 3404b88c807SRodney W. Grimes *uid = ptr->uid; 3414b88c807SRodney W. Grimes return(0); 3424b88c807SRodney W. Grimes } 3434b88c807SRodney W. Grimes 3444b88c807SRodney W. Grimes if (!pwopn) { 3454b88c807SRodney W. Grimes setpassent(1); 3464b88c807SRodney W. Grimes ++pwopn; 3474b88c807SRodney W. Grimes } 3484b88c807SRodney W. Grimes 3494b88c807SRodney W. Grimes if (ptr == NULL) 350b1787decSKris Kennaway ptr = usrtb[st_hash(name, namelen, UNM_SZ)] = 351b1787decSKris Kennaway (UIDC *)malloc(sizeof(UIDC)); 3524b88c807SRodney W. Grimes 3534b88c807SRodney W. Grimes /* 3544b88c807SRodney W. Grimes * no match, look it up, if no match store it as an invalid entry, 3554b88c807SRodney W. Grimes * or store the matching uid 3564b88c807SRodney W. Grimes */ 3574b88c807SRodney W. Grimes if (ptr == NULL) { 3584b88c807SRodney W. Grimes if ((pw = getpwnam(name)) == NULL) 3594b88c807SRodney W. Grimes return(-1); 3604b88c807SRodney W. Grimes *uid = pw->pw_uid; 3614b88c807SRodney W. Grimes return(0); 3624b88c807SRodney W. Grimes } 363877155d0SPhilippe Charnier (void)strncpy(ptr->name, name, UNMLEN - 1); 3644b88c807SRodney W. Grimes ptr->name[UNMLEN-1] = '\0'; 3654b88c807SRodney W. Grimes if ((pw = getpwnam(name)) == NULL) { 3664b88c807SRodney W. Grimes ptr->valid = INVALID; 3674b88c807SRodney W. Grimes return(-1); 3684b88c807SRodney W. Grimes } 3694b88c807SRodney W. Grimes ptr->valid = VALID; 3704b88c807SRodney W. Grimes *uid = ptr->uid = pw->pw_uid; 3714b88c807SRodney W. Grimes return(0); 3724b88c807SRodney W. Grimes } 3734b88c807SRodney W. Grimes 3744b88c807SRodney W. Grimes /* 3754b88c807SRodney W. Grimes * gid_name() 3764b88c807SRodney W. Grimes * caches the gid for a given group name. We use a simple hash table. 3774b88c807SRodney W. Grimes * Return 3784b88c807SRodney W. Grimes * the gid (if any) for a group name, or a -1 if no match can be found 3794b88c807SRodney W. Grimes */ 3804b88c807SRodney W. Grimes 3814b88c807SRodney W. Grimes int 3824b88c807SRodney W. Grimes gid_name(char *name, gid_t *gid) 3834b88c807SRodney W. Grimes { 384f789b261SWarner Losh struct group *gr; 385f789b261SWarner Losh GIDC *ptr; 386f789b261SWarner Losh int namelen; 3874b88c807SRodney W. Grimes 3884b88c807SRodney W. Grimes /* 3894b88c807SRodney W. Grimes * return -1 for mangled names 3904b88c807SRodney W. Grimes */ 3914b88c807SRodney W. Grimes if (((namelen = strlen(name)) == 0) || (name[0] == '\0')) 3924b88c807SRodney W. Grimes return(-1); 3934b88c807SRodney W. Grimes if ((grptb == NULL) && (grptb_start() < 0)) 3944b88c807SRodney W. Grimes return(-1); 3954b88c807SRodney W. Grimes 3964b88c807SRodney W. Grimes /* 3974b88c807SRodney W. Grimes * look up in hash table, if found and valid return the uid, 3984b88c807SRodney W. Grimes * if found and invalid, return a -1 3994b88c807SRodney W. Grimes */ 4004b88c807SRodney W. Grimes ptr = grptb[st_hash(name, namelen, GID_SZ)]; 4014b88c807SRodney W. Grimes if ((ptr != NULL) && (ptr->valid > 0) && !strcmp(name, ptr->name)) { 4024b88c807SRodney W. Grimes if (ptr->valid == INVALID) 4034b88c807SRodney W. Grimes return(-1); 4044b88c807SRodney W. Grimes *gid = ptr->gid; 4054b88c807SRodney W. Grimes return(0); 4064b88c807SRodney W. Grimes } 4074b88c807SRodney W. Grimes 4084b88c807SRodney W. Grimes if (!gropn) { 4094b88c807SRodney W. Grimes setgroupent(1); 4104b88c807SRodney W. Grimes ++gropn; 4114b88c807SRodney W. Grimes } 4124b88c807SRodney W. Grimes if (ptr == NULL) 413b1787decSKris Kennaway ptr = grptb[st_hash(name, namelen, GID_SZ)] = 414b1787decSKris Kennaway (GIDC *)malloc(sizeof(GIDC)); 4154b88c807SRodney W. Grimes 4164b88c807SRodney W. Grimes /* 4174b88c807SRodney W. Grimes * no match, look it up, if no match store it as an invalid entry, 4184b88c807SRodney W. Grimes * or store the matching gid 4194b88c807SRodney W. Grimes */ 4204b88c807SRodney W. Grimes if (ptr == NULL) { 4214b88c807SRodney W. Grimes if ((gr = getgrnam(name)) == NULL) 4224b88c807SRodney W. Grimes return(-1); 4234b88c807SRodney W. Grimes *gid = gr->gr_gid; 4244b88c807SRodney W. Grimes return(0); 4254b88c807SRodney W. Grimes } 4264b88c807SRodney W. Grimes 427877155d0SPhilippe Charnier (void)strncpy(ptr->name, name, GNMLEN - 1); 4284b88c807SRodney W. Grimes ptr->name[GNMLEN-1] = '\0'; 4294b88c807SRodney W. Grimes if ((gr = getgrnam(name)) == NULL) { 4304b88c807SRodney W. Grimes ptr->valid = INVALID; 4314b88c807SRodney W. Grimes return(-1); 4324b88c807SRodney W. Grimes } 4334b88c807SRodney W. Grimes ptr->valid = VALID; 4344b88c807SRodney W. Grimes *gid = ptr->gid = gr->gr_gid; 4354b88c807SRodney W. Grimes return(0); 4364b88c807SRodney W. Grimes } 437