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