15c51f124SMoriah Waterland /* 25c51f124SMoriah Waterland * CDDL HEADER START 35c51f124SMoriah Waterland * 45c51f124SMoriah Waterland * The contents of this file are subject to the terms of the 55c51f124SMoriah Waterland * Common Development and Distribution License (the "License"). 65c51f124SMoriah Waterland * You may not use this file except in compliance with the License. 75c51f124SMoriah Waterland * 85c51f124SMoriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95c51f124SMoriah Waterland * or http://www.opensolaris.org/os/licensing. 105c51f124SMoriah Waterland * See the License for the specific language governing permissions 115c51f124SMoriah Waterland * and limitations under the License. 125c51f124SMoriah Waterland * 135c51f124SMoriah Waterland * When distributing Covered Code, include this CDDL HEADER in each 145c51f124SMoriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155c51f124SMoriah Waterland * If applicable, add the following below this CDDL HEADER, with the 165c51f124SMoriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying 175c51f124SMoriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner] 185c51f124SMoriah Waterland * 195c51f124SMoriah Waterland * CDDL HEADER END 205c51f124SMoriah Waterland */ 215c51f124SMoriah Waterland 225c51f124SMoriah Waterland /* 235c51f124SMoriah Waterland * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 245c51f124SMoriah Waterland * Use is subject to license terms. 255c51f124SMoriah Waterland */ 265c51f124SMoriah Waterland 275c51f124SMoriah Waterland 285c51f124SMoriah Waterland /* 295c51f124SMoriah Waterland * This module fetches group and passwd structs for the caller. It 305c51f124SMoriah Waterland * uses a hash table to speed up retrieval of repeated entries. If 315c51f124SMoriah Waterland * the attempts to initialize the hash tables fail, this just 325c51f124SMoriah Waterland * continues the slow way. 335c51f124SMoriah Waterland */ 345c51f124SMoriah Waterland 355c51f124SMoriah Waterland #include <pwd.h> 365c51f124SMoriah Waterland #include <grp.h> 375c51f124SMoriah Waterland #include <string.h> 385c51f124SMoriah Waterland #include <stdio.h> 395c51f124SMoriah Waterland #include <stdlib.h> 405c51f124SMoriah Waterland #include <unistd.h> 415c51f124SMoriah Waterland #include "pkglib.h" 425c51f124SMoriah Waterland #include "pkglocale.h" 435c51f124SMoriah Waterland #include "nhash.h" 445c51f124SMoriah Waterland 455c51f124SMoriah Waterland #define HASHSIZE 151 465c51f124SMoriah Waterland #define BSZ 4 475c51f124SMoriah Waterland 485c51f124SMoriah Waterland #define ERR_DUPFAIL "%s: strdup(%s) failed.\n" 495c51f124SMoriah Waterland #define ERR_ADDFAIL "%s: add_cache() failed.\n" 505c51f124SMoriah Waterland #define ERR_BADMEMB "%s: %s in \"%s\" %s structure is invalid.\n" 515c51f124SMoriah Waterland #define ERR_NOGRP "dup_gr_ent(): no group entry provided.\n" 525c51f124SMoriah Waterland #define ERR_NOPWD "dup_pw_ent(): no passwd entry provided.\n" 535c51f124SMoriah Waterland #define ERR_NOINIT "%s: init_cache() failed.\n" 545c51f124SMoriah Waterland #define ERR_MALLOC "%s: malloc(%d) failed for %s.\n" 555c51f124SMoriah Waterland 565c51f124SMoriah Waterland static Cache *pwnam_cache = (Cache *) NULL; 575c51f124SMoriah Waterland static Cache *grnam_cache = (Cache *) NULL; 585c51f124SMoriah Waterland static Cache *pwuid_cache = (Cache *) NULL; 595c51f124SMoriah Waterland static Cache *grgid_cache = (Cache *) NULL; 605c51f124SMoriah Waterland 615c51f124SMoriah Waterland static int dup_gr_ent(struct group *grp); 625c51f124SMoriah Waterland static int dup_pw_ent(struct passwd *pwp); 635c51f124SMoriah Waterland 645c51f124SMoriah Waterland /* 655c51f124SMoriah Waterland * These indicate whether the hash table has been initialized for the four 665c51f124SMoriah Waterland * categories. 675c51f124SMoriah Waterland */ 685c51f124SMoriah Waterland static int is_a_pwnam_cache; 695c51f124SMoriah Waterland static int is_a_grnam_cache; 705c51f124SMoriah Waterland static int is_a_pwuid_cache; 715c51f124SMoriah Waterland static int is_a_grgid_cache; 725c51f124SMoriah Waterland 735c51f124SMoriah Waterland extern char *get_install_root(void); 745c51f124SMoriah Waterland 755c51f124SMoriah Waterland /* 765c51f124SMoriah Waterland * If there's a grnam cache, then update it with this new 775c51f124SMoriah Waterland * group, otherwise, skip it. 785c51f124SMoriah Waterland */ 795c51f124SMoriah Waterland static Item * 805c51f124SMoriah Waterland cache_alloc(char *fname, int len, size_t struct_size) 815c51f124SMoriah Waterland { 825c51f124SMoriah Waterland Item *itemp; 835c51f124SMoriah Waterland 845c51f124SMoriah Waterland /* 855c51f124SMoriah Waterland * Allocate space for the Item pointer, key and data. 865c51f124SMoriah Waterland */ 875c51f124SMoriah Waterland if ((itemp = (Item *) malloc(sizeof (*itemp))) == 885c51f124SMoriah Waterland Null_Item) { 895c51f124SMoriah Waterland (void) fprintf(stderr, 905c51f124SMoriah Waterland pkg_gt(ERR_MALLOC), fname, 915c51f124SMoriah Waterland sizeof (*itemp), "itemp"); 925c51f124SMoriah Waterland } else if ((itemp->key = (char *)malloc(len)) == NULL) { 935c51f124SMoriah Waterland (void) fprintf(stderr, pkg_gt(ERR_MALLOC), fname, len, 945c51f124SMoriah Waterland "itemp->key"); 955c51f124SMoriah Waterland free(itemp); 965c51f124SMoriah Waterland } else if ((itemp->data = malloc(struct_size)) == NULL) { 975c51f124SMoriah Waterland (void) fprintf(stderr, pkg_gt(ERR_MALLOC), fname, 985c51f124SMoriah Waterland struct_size, "itemp->data"); 995c51f124SMoriah Waterland free(itemp->key); 1005c51f124SMoriah Waterland free(itemp); 1015c51f124SMoriah Waterland } else { 1025c51f124SMoriah Waterland /* Set length parameters. */ 1035c51f124SMoriah Waterland itemp->keyl = len; 1045c51f124SMoriah Waterland itemp->datal = struct_size; 1055c51f124SMoriah Waterland 1065c51f124SMoriah Waterland return (itemp); 1075c51f124SMoriah Waterland } 1085c51f124SMoriah Waterland 1095c51f124SMoriah Waterland return ((Item *) NULL); 1105c51f124SMoriah Waterland } 1115c51f124SMoriah Waterland 1125c51f124SMoriah Waterland /* Get the required group structure based upon the group name. */ 1135c51f124SMoriah Waterland struct group * 1145c51f124SMoriah Waterland cgrnam(char *nam) 1155c51f124SMoriah Waterland { 1165c51f124SMoriah Waterland struct group *grp; 1175c51f124SMoriah Waterland Item *itemp; 1185c51f124SMoriah Waterland int len; 1195c51f124SMoriah Waterland static int cache_failed; 1205c51f124SMoriah Waterland 1215c51f124SMoriah Waterland /* Attempt to initialize the grname cache. */ 1225c51f124SMoriah Waterland if (!is_a_grnam_cache && !cache_failed) { 1235c51f124SMoriah Waterland if (init_cache(&grnam_cache, HASHSIZE, BSZ, 1245c51f124SMoriah Waterland (int (*)())NULL, (int (*)())NULL) == -1) { 1255c51f124SMoriah Waterland (void) fprintf(stderr, pkg_gt(ERR_NOINIT), "cgrnam()"); 1265c51f124SMoriah Waterland grnam_cache = (Cache *) NULL; 1275c51f124SMoriah Waterland cache_failed = 1; 1285c51f124SMoriah Waterland } else 1295c51f124SMoriah Waterland is_a_grnam_cache = 1; 1305c51f124SMoriah Waterland } 1315c51f124SMoriah Waterland 1325c51f124SMoriah Waterland len = strlen(nam) + 1; 1335c51f124SMoriah Waterland 1345c51f124SMoriah Waterland /* First look in the cache. Failing that, do it the hard way. */ 1355c51f124SMoriah Waterland if ((itemp = lookup_cache(grnam_cache, nam, len)) == Null_Item) { 1365c51f124SMoriah Waterland 1375c51f124SMoriah Waterland /* Get the group by name. */ 1385c51f124SMoriah Waterland if ((grp = clgrnam(nam)) != NULL || 1395c51f124SMoriah Waterland (grp = getgrnam(nam)) != NULL) { 1405c51f124SMoriah Waterland /* A group by that name exists on this machine. */ 1415c51f124SMoriah Waterland if (dup_gr_ent(grp)) 1425c51f124SMoriah Waterland /* 1435c51f124SMoriah Waterland * Effectively no such group since struct 1445c51f124SMoriah Waterland * couldn't be duplicated. 1455c51f124SMoriah Waterland */ 1465c51f124SMoriah Waterland grp = (struct group *)NULL; 1475c51f124SMoriah Waterland /* 1485c51f124SMoriah Waterland * If there's a grnam cache, then update it with this 1495c51f124SMoriah Waterland * new group, otherwise, skip it. 1505c51f124SMoriah Waterland */ 1515c51f124SMoriah Waterland else if (is_a_grnam_cache) { 1525c51f124SMoriah Waterland if ((itemp = cache_alloc("cgrnam()", len, 1535c51f124SMoriah Waterland sizeof (struct group))) != Null_Item) { 1545c51f124SMoriah Waterland /* 1555c51f124SMoriah Waterland * With that allocated, insert the 1565c51f124SMoriah Waterland * group name as key and set the key 1575c51f124SMoriah Waterland * length. 1585c51f124SMoriah Waterland */ 1595c51f124SMoriah Waterland (void) memmove(itemp->key, nam, len); 1605c51f124SMoriah Waterland 1615c51f124SMoriah Waterland /* 1625c51f124SMoriah Waterland * Insert the data associated with 1635c51f124SMoriah Waterland * the key and the data length. 1645c51f124SMoriah Waterland */ 1655c51f124SMoriah Waterland (void) memmove(itemp->data, grp, 1665c51f124SMoriah Waterland sizeof (struct group)); 1675c51f124SMoriah Waterland 1685c51f124SMoriah Waterland /* Insert the Item into the cache. */ 1695c51f124SMoriah Waterland if (add_cache(grnam_cache, itemp) == -1) 1705c51f124SMoriah Waterland (void) fprintf(stderr, 1715c51f124SMoriah Waterland pkg_gt(ERR_ADDFAIL), 1725c51f124SMoriah Waterland "cgrnam()"); 1735c51f124SMoriah Waterland } 1745c51f124SMoriah Waterland } 1755c51f124SMoriah Waterland } 1765c51f124SMoriah Waterland return (grp); 1775c51f124SMoriah Waterland } else /* Found it in the cache. */ 1785c51f124SMoriah Waterland return ((struct group *)itemp->data); 1795c51f124SMoriah Waterland } 1805c51f124SMoriah Waterland 1815c51f124SMoriah Waterland struct passwd * 1825c51f124SMoriah Waterland cpwnam(char *nam) 1835c51f124SMoriah Waterland { 1845c51f124SMoriah Waterland struct passwd *pwd; 1855c51f124SMoriah Waterland Item *itemp; 1865c51f124SMoriah Waterland int len; 1875c51f124SMoriah Waterland static int cache_failed; 1885c51f124SMoriah Waterland 1895c51f124SMoriah Waterland if (!is_a_pwnam_cache && !cache_failed) { 1905c51f124SMoriah Waterland if (init_cache(&pwnam_cache, HASHSIZE, BSZ, 1915c51f124SMoriah Waterland (int (*)())NULL, (int (*)())NULL) == -1) { 1925c51f124SMoriah Waterland (void) fprintf(stderr, pkg_gt(ERR_NOINIT), "cpwnam()"); 1935c51f124SMoriah Waterland pwnam_cache = (Cache *) NULL; 1945c51f124SMoriah Waterland cache_failed = 1; 1955c51f124SMoriah Waterland } else 1965c51f124SMoriah Waterland is_a_pwnam_cache = 1; 1975c51f124SMoriah Waterland } 1985c51f124SMoriah Waterland 1995c51f124SMoriah Waterland len = strlen(nam) + 1; 2005c51f124SMoriah Waterland 2015c51f124SMoriah Waterland /* First look in the cache. Failing that, do it the hard way. */ 2025c51f124SMoriah Waterland if ((itemp = lookup_cache(pwnam_cache, nam, len)) == Null_Item) { 2035c51f124SMoriah Waterland 2045c51f124SMoriah Waterland /* Get the passwd by name. */ 2055c51f124SMoriah Waterland if ((pwd = clpwnam(nam)) != NULL || 2065c51f124SMoriah Waterland (pwd = getpwnam(nam)) != NULL) { 2075c51f124SMoriah Waterland /* A passwd by that name exists on this machine. */ 2085c51f124SMoriah Waterland if (dup_pw_ent(pwd)) 2095c51f124SMoriah Waterland /* 2105c51f124SMoriah Waterland * Effectively no such passwd since struct 2115c51f124SMoriah Waterland * couldn't be duplicated. 2125c51f124SMoriah Waterland */ 2135c51f124SMoriah Waterland pwd = (struct passwd *)NULL; 2145c51f124SMoriah Waterland /* 2155c51f124SMoriah Waterland * If there's a pwnam cache, then update it with this 2165c51f124SMoriah Waterland * new passwd, otherwise, skip it. 2175c51f124SMoriah Waterland */ 2185c51f124SMoriah Waterland else if (is_a_pwnam_cache) { 2195c51f124SMoriah Waterland /* 2205c51f124SMoriah Waterland * Allocate space for the Item pointer, key 2215c51f124SMoriah Waterland * and data. 2225c51f124SMoriah Waterland */ 2235c51f124SMoriah Waterland if ((itemp = cache_alloc("cpwnam()", len, 2245c51f124SMoriah Waterland sizeof (struct passwd))) != Null_Item) { 2255c51f124SMoriah Waterland /* 2265c51f124SMoriah Waterland * With that allocated, insert the 2275c51f124SMoriah Waterland * group name as key and set the key 2285c51f124SMoriah Waterland * length. 2295c51f124SMoriah Waterland */ 2305c51f124SMoriah Waterland (void) memmove(itemp->key, nam, len); 2315c51f124SMoriah Waterland 2325c51f124SMoriah Waterland /* 2335c51f124SMoriah Waterland * Insert the data associated with 2345c51f124SMoriah Waterland * the key and the data length. 2355c51f124SMoriah Waterland */ 2365c51f124SMoriah Waterland (void) memmove(itemp->data, pwd, 2375c51f124SMoriah Waterland sizeof (struct passwd)); 2385c51f124SMoriah Waterland 2395c51f124SMoriah Waterland if (add_cache(pwnam_cache, itemp) == -1) 2405c51f124SMoriah Waterland (void) fprintf(stderr, 2415c51f124SMoriah Waterland pkg_gt(ERR_ADDFAIL), 2425c51f124SMoriah Waterland "cpwnam()"); 2435c51f124SMoriah Waterland } 2445c51f124SMoriah Waterland } 2455c51f124SMoriah Waterland } 2465c51f124SMoriah Waterland return (pwd); 2475c51f124SMoriah Waterland } else /* Found it in the cache. */ 2485c51f124SMoriah Waterland return ((struct passwd *)itemp->data); 2495c51f124SMoriah Waterland } 2505c51f124SMoriah Waterland 2515c51f124SMoriah Waterland static int 2525c51f124SMoriah Waterland uid_hash(void *datap, int datalen, int hsz) 2535c51f124SMoriah Waterland { 2545c51f124SMoriah Waterland #ifdef lint 2555c51f124SMoriah Waterland int i = datalen; 2565c51f124SMoriah Waterland datalen = i; 2575c51f124SMoriah Waterland #endif /* lint */ 2585c51f124SMoriah Waterland 2595c51f124SMoriah Waterland return (*((uid_t *)datap) % hsz); 2605c51f124SMoriah Waterland } 2615c51f124SMoriah Waterland 2625c51f124SMoriah Waterland static int 2635c51f124SMoriah Waterland uid_comp(void *datap1, void *datap2, int datalen) 2645c51f124SMoriah Waterland { 2655c51f124SMoriah Waterland #ifdef lint 2665c51f124SMoriah Waterland int i = datalen; 2675c51f124SMoriah Waterland datalen = i; 2685c51f124SMoriah Waterland #endif /* lint */ 2695c51f124SMoriah Waterland 2705c51f124SMoriah Waterland return (*((uid_t *)datap1) - *((uid_t *)datap2)); 2715c51f124SMoriah Waterland } 2725c51f124SMoriah Waterland 2735c51f124SMoriah Waterland struct group * 2745c51f124SMoriah Waterland cgrgid(gid_t gid) 2755c51f124SMoriah Waterland { 2765c51f124SMoriah Waterland struct group *grp; 2775c51f124SMoriah Waterland Item *itemp; 2785c51f124SMoriah Waterland int len; 2795c51f124SMoriah Waterland static int cache_failed; 2805c51f124SMoriah Waterland 2815c51f124SMoriah Waterland if (!is_a_grgid_cache && !cache_failed) { 2825c51f124SMoriah Waterland if (init_cache(&grgid_cache, HASHSIZE, BSZ, 2835c51f124SMoriah Waterland uid_hash, uid_comp) == -1) { 2845c51f124SMoriah Waterland (void) fprintf(stderr, pkg_gt(ERR_NOINIT), "cgrgid()"); 2855c51f124SMoriah Waterland grgid_cache = (Cache *) NULL; 2865c51f124SMoriah Waterland cache_failed = 1; 2875c51f124SMoriah Waterland } else 2885c51f124SMoriah Waterland is_a_grgid_cache = 1; 2895c51f124SMoriah Waterland } 2905c51f124SMoriah Waterland 2915c51f124SMoriah Waterland len = sizeof (uid_t); 2925c51f124SMoriah Waterland 2935c51f124SMoriah Waterland /* First look in the cache. Failing that, do it the hard way. */ 2945c51f124SMoriah Waterland if ((itemp = lookup_cache(grgid_cache, &gid, len)) == Null_Item) { 2955c51f124SMoriah Waterland if ((grp = clgrgid(gid)) != NULL || 2965c51f124SMoriah Waterland (grp = getgrgid(gid)) != NULL) { 2975c51f124SMoriah Waterland /* A group by that number exists on this machine. */ 2985c51f124SMoriah Waterland if (dup_gr_ent(grp)) 2995c51f124SMoriah Waterland /* 3005c51f124SMoriah Waterland * Effectively no such group since struct 3015c51f124SMoriah Waterland * couldn't be duplicated. 3025c51f124SMoriah Waterland */ 3035c51f124SMoriah Waterland grp = (struct group *)NULL; 3045c51f124SMoriah Waterland /* 3055c51f124SMoriah Waterland * If there's a grnam cache, then update it with this 3065c51f124SMoriah Waterland * new group, otherwise, skip it. 3075c51f124SMoriah Waterland */ 3085c51f124SMoriah Waterland else if (is_a_grgid_cache) { 3095c51f124SMoriah Waterland if ((itemp = cache_alloc("cgrgid()", len, 3105c51f124SMoriah Waterland sizeof (struct group))) != Null_Item) { 3115c51f124SMoriah Waterland /* 3125c51f124SMoriah Waterland * With that allocated, insert the 3135c51f124SMoriah Waterland * group name as key and set the key 3145c51f124SMoriah Waterland * length. 3155c51f124SMoriah Waterland */ 3165c51f124SMoriah Waterland (void) memmove(itemp->key, &gid, len); 3175c51f124SMoriah Waterland 3185c51f124SMoriah Waterland /* 3195c51f124SMoriah Waterland * Insert the data associated with 3205c51f124SMoriah Waterland * the key and the data length. 3215c51f124SMoriah Waterland */ 3225c51f124SMoriah Waterland (void) memmove(itemp->data, grp, 3235c51f124SMoriah Waterland sizeof (struct group)); 3245c51f124SMoriah Waterland 3255c51f124SMoriah Waterland if (add_cache(grgid_cache, itemp) == -1) 3265c51f124SMoriah Waterland (void) fprintf(stderr, 3275c51f124SMoriah Waterland pkg_gt(ERR_ADDFAIL), 3285c51f124SMoriah Waterland "cgrgid()"); 3295c51f124SMoriah Waterland } 3305c51f124SMoriah Waterland } 3315c51f124SMoriah Waterland } 3325c51f124SMoriah Waterland return (grp); 3335c51f124SMoriah Waterland } else /* Found it in the cache. */ 3345c51f124SMoriah Waterland return ((struct group *)itemp->data); 3355c51f124SMoriah Waterland } 3365c51f124SMoriah Waterland 3375c51f124SMoriah Waterland struct passwd * 3385c51f124SMoriah Waterland cpwuid(uid_t uid) 3395c51f124SMoriah Waterland { 3405c51f124SMoriah Waterland struct passwd *pwd; 3415c51f124SMoriah Waterland Item *itemp; 3425c51f124SMoriah Waterland int len; 3435c51f124SMoriah Waterland static int cache_failed; 3445c51f124SMoriah Waterland 3455c51f124SMoriah Waterland if (!is_a_pwuid_cache && !cache_failed) { 3465c51f124SMoriah Waterland if (init_cache(&pwuid_cache, HASHSIZE, BSZ, 3475c51f124SMoriah Waterland uid_hash, uid_comp) == -1) { 3485c51f124SMoriah Waterland (void) fprintf(stderr, 3495c51f124SMoriah Waterland pkg_gt(ERR_NOINIT), "cpwuid()"); 3505c51f124SMoriah Waterland pwuid_cache = (Cache *) NULL; 3515c51f124SMoriah Waterland cache_failed = 1; 3525c51f124SMoriah Waterland } else 3535c51f124SMoriah Waterland is_a_pwuid_cache = 1; 3545c51f124SMoriah Waterland } 3555c51f124SMoriah Waterland 3565c51f124SMoriah Waterland len = sizeof (uid_t); 3575c51f124SMoriah Waterland 3585c51f124SMoriah Waterland /* First look in the cache. Failing that, do it the hard way. */ 3595c51f124SMoriah Waterland if ((itemp = lookup_cache(pwuid_cache, &uid, len)) == Null_Item) { 3605c51f124SMoriah Waterland 3615c51f124SMoriah Waterland /* Get the passwd by number. */ 3625c51f124SMoriah Waterland if ((pwd = clpwuid(uid)) != NULL || 3635c51f124SMoriah Waterland (pwd = getpwuid(uid)) != NULL) { 3645c51f124SMoriah Waterland /* A passwd by that user ID exists on this machine. */ 3655c51f124SMoriah Waterland if (dup_pw_ent(pwd)) 3665c51f124SMoriah Waterland /* 3675c51f124SMoriah Waterland * Effectively no such passwd since struct 3685c51f124SMoriah Waterland * couldn't be duplicated. 3695c51f124SMoriah Waterland */ 3705c51f124SMoriah Waterland pwd = (struct passwd *)NULL; 3715c51f124SMoriah Waterland /* 3725c51f124SMoriah Waterland * If there's a pwuid cache, then update it with this 3735c51f124SMoriah Waterland * new passwd, otherwise, skip it. 3745c51f124SMoriah Waterland */ 3755c51f124SMoriah Waterland else if (is_a_pwuid_cache) { 3765c51f124SMoriah Waterland if ((itemp = cache_alloc("cpwuid()", len, 3775c51f124SMoriah Waterland sizeof (struct passwd))) != Null_Item) { 3785c51f124SMoriah Waterland /* 3795c51f124SMoriah Waterland * With that allocated, insert the 3805c51f124SMoriah Waterland * group name as key and set the key 3815c51f124SMoriah Waterland * length. 3825c51f124SMoriah Waterland */ 3835c51f124SMoriah Waterland (void) memmove(itemp->key, &uid, len); 3845c51f124SMoriah Waterland 3855c51f124SMoriah Waterland /* 3865c51f124SMoriah Waterland * Insert the data associated with 3875c51f124SMoriah Waterland * the key and the data length. 3885c51f124SMoriah Waterland */ 3895c51f124SMoriah Waterland (void) memmove(itemp->data, pwd, 3905c51f124SMoriah Waterland sizeof (struct passwd)); 3915c51f124SMoriah Waterland 3925c51f124SMoriah Waterland if (add_cache(pwuid_cache, itemp) == -1) 3935c51f124SMoriah Waterland (void) fprintf(stderr, 3945c51f124SMoriah Waterland pkg_gt(ERR_ADDFAIL), 3955c51f124SMoriah Waterland "cpwuid()"); 3965c51f124SMoriah Waterland } 3975c51f124SMoriah Waterland } 3985c51f124SMoriah Waterland } 3995c51f124SMoriah Waterland return (pwd); 4005c51f124SMoriah Waterland } else /* Found it in the cache. */ 4015c51f124SMoriah Waterland return ((struct passwd *)itemp->data); 4025c51f124SMoriah Waterland } 4035c51f124SMoriah Waterland 4045c51f124SMoriah Waterland /* 4055c51f124SMoriah Waterland * This function duplicates the group structure provided from kernel static 4065c51f124SMoriah Waterland * memory. There is a lot of defensive coding here because there have been 4075c51f124SMoriah Waterland * problems with the getgr*() functions. They will sometimes provide NULL 4085c51f124SMoriah Waterland * values instead of pointers to NULL values. There has been no explanation 4095c51f124SMoriah Waterland * for the reason behind this; but, this function takes a NULL to be an 4105c51f124SMoriah Waterland * invalid (char *) and returns an error. 4115c51f124SMoriah Waterland */ 4125c51f124SMoriah Waterland static int 4135c51f124SMoriah Waterland dup_gr_ent(struct group *grp) 4145c51f124SMoriah Waterland { 4155c51f124SMoriah Waterland char **tp = NULL; 4165c51f124SMoriah Waterland char **memp = NULL; 4175c51f124SMoriah Waterland int nent = 0; /* Number of entries in the member list. */ 4185c51f124SMoriah Waterland 4195c51f124SMoriah Waterland if (grp) { 4205c51f124SMoriah Waterland if (grp->gr_name == NULL) { 4215c51f124SMoriah Waterland (void) fprintf(stderr, 4225c51f124SMoriah Waterland pkg_gt(ERR_BADMEMB), "dup_gr_ent()", "gr_name", 4235c51f124SMoriah Waterland "unknown", "group"); 4245c51f124SMoriah Waterland return (-1); 4255c51f124SMoriah Waterland } else if ((grp->gr_name = strdup(grp->gr_name)) == NULL) { 4265c51f124SMoriah Waterland (void) fprintf(stderr, 4275c51f124SMoriah Waterland pkg_gt(ERR_DUPFAIL), "dup_gr_ent()", "gr_name"); 4285c51f124SMoriah Waterland return (-1); 4295c51f124SMoriah Waterland } 4305c51f124SMoriah Waterland if (grp->gr_passwd == NULL) { 4315c51f124SMoriah Waterland (void) fprintf(stderr, 4325c51f124SMoriah Waterland pkg_gt(ERR_BADMEMB), "dup_gr_ent()", "gr_passwd", 4335c51f124SMoriah Waterland grp->gr_name, "group"); 4345c51f124SMoriah Waterland return (-1); 4355c51f124SMoriah Waterland } else if ((grp->gr_passwd = strdup(grp->gr_passwd)) == NULL) { 4365c51f124SMoriah Waterland (void) fprintf(stderr, 4375c51f124SMoriah Waterland pkg_gt(ERR_DUPFAIL), "dup_gr_ent()", "gr_passwd"); 4385c51f124SMoriah Waterland return (-1); 4395c51f124SMoriah Waterland } 4405c51f124SMoriah Waterland /* 4415c51f124SMoriah Waterland * Allocate space for the member list and move the members 4425c51f124SMoriah Waterland * into it. 4435c51f124SMoriah Waterland */ 4445c51f124SMoriah Waterland if (grp->gr_mem) { 4455c51f124SMoriah Waterland /* 4465c51f124SMoriah Waterland * First count the members. The nent variable will be 4475c51f124SMoriah Waterland * the number of members + 1 for the terminator. 4485c51f124SMoriah Waterland */ 4495c51f124SMoriah Waterland for (tp = grp->gr_mem; *tp; nent++, tp++); 4505c51f124SMoriah Waterland 4515c51f124SMoriah Waterland /* Now allocate room for the pointers. */ 4525c51f124SMoriah Waterland memp = malloc(sizeof (char **)* (nent+1)); 4535c51f124SMoriah Waterland 4545c51f124SMoriah Waterland if (memp == NULL) { 4555c51f124SMoriah Waterland (void) fprintf(stderr, 4565c51f124SMoriah Waterland pkg_gt(ERR_MALLOC), "dup_gr_ent()", 4575c51f124SMoriah Waterland (sizeof (char **)* (nent+1)), 4585c51f124SMoriah Waterland "memp"); 4595c51f124SMoriah Waterland return (-1); 4605c51f124SMoriah Waterland } 4615c51f124SMoriah Waterland 4625c51f124SMoriah Waterland /* 4635c51f124SMoriah Waterland * Now copy over the pointers and entries. It should 4645c51f124SMoriah Waterland * be noted that if the structure is messed up here, 4655c51f124SMoriah Waterland * the resulting member list will be truncated at the 4665c51f124SMoriah Waterland * NULL entry. 4675c51f124SMoriah Waterland */ 4685c51f124SMoriah Waterland for (nent = 0, tp = grp->gr_mem; *tp; tp++) { 4695c51f124SMoriah Waterland if ((memp[nent++] = strdup(*tp)) == NULL) { 4705c51f124SMoriah Waterland (void) fprintf(stderr, 4715c51f124SMoriah Waterland pkg_gt(ERR_DUPFAIL), "dup_gr_ent()", 4725c51f124SMoriah Waterland "gr_mem"); 4735c51f124SMoriah Waterland return (-1); 4745c51f124SMoriah Waterland } 4755c51f124SMoriah Waterland } 4765c51f124SMoriah Waterland } else { 4775c51f124SMoriah Waterland (void) fprintf(stderr, 4785c51f124SMoriah Waterland pkg_gt(ERR_BADMEMB), "dup_gr_ent()", "gr_mem", 4795c51f124SMoriah Waterland grp->gr_name, "group"); 4805c51f124SMoriah Waterland return (-1); 4815c51f124SMoriah Waterland } 4825c51f124SMoriah Waterland } else { 4835c51f124SMoriah Waterland (void) fprintf(stderr, pkg_gt(ERR_NOGRP)); 4845c51f124SMoriah Waterland return (-1); 4855c51f124SMoriah Waterland } 4865c51f124SMoriah Waterland memp[nent++] = '\0'; 4875c51f124SMoriah Waterland return (0); 4885c51f124SMoriah Waterland } 4895c51f124SMoriah Waterland 4905c51f124SMoriah Waterland /* 4915c51f124SMoriah Waterland * This function duplicates the passwd structure provided from kernel static 4925c51f124SMoriah Waterland * memory. As in the above function, since there have been problems with the 4935c51f124SMoriah Waterland * getpw*() functions, the structure provided is rigorously scrubbed. This 4945c51f124SMoriah Waterland * function takes a NULL to be an invalid (char *) and returns an error if 4955c51f124SMoriah Waterland * one is detected. 4965c51f124SMoriah Waterland */ 4975c51f124SMoriah Waterland static int 4985c51f124SMoriah Waterland dup_pw_ent(struct passwd *pwd) 4995c51f124SMoriah Waterland { 5005c51f124SMoriah Waterland if (pwd) { 5015c51f124SMoriah Waterland if (pwd->pw_name == NULL) { 5025c51f124SMoriah Waterland (void) fprintf(stderr, 5035c51f124SMoriah Waterland pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_name", 5045c51f124SMoriah Waterland "unknown", "passwd"); 5055c51f124SMoriah Waterland return (-1); 5065c51f124SMoriah Waterland } else if ((pwd->pw_name = strdup(pwd->pw_name)) == NULL) { 5075c51f124SMoriah Waterland (void) fprintf(stderr, 5085c51f124SMoriah Waterland pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_name"); 5095c51f124SMoriah Waterland return (-1); 5105c51f124SMoriah Waterland } 5115c51f124SMoriah Waterland 5125c51f124SMoriah Waterland if (pwd->pw_passwd == NULL) { 5135c51f124SMoriah Waterland (void) fprintf(stderr, 5145c51f124SMoriah Waterland pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_passwd", 5155c51f124SMoriah Waterland pwd->pw_name, "passwd"); 5165c51f124SMoriah Waterland return (-1); 5175c51f124SMoriah Waterland } else if ((pwd->pw_passwd = strdup(pwd->pw_passwd)) == NULL) { 5185c51f124SMoriah Waterland (void) fprintf(stderr, 5195c51f124SMoriah Waterland pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_passwd"); 5205c51f124SMoriah Waterland return (-1); 5215c51f124SMoriah Waterland } 5225c51f124SMoriah Waterland 5235c51f124SMoriah Waterland if (pwd->pw_age == NULL) { 5245c51f124SMoriah Waterland (void) fprintf(stderr, 5255c51f124SMoriah Waterland pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_age", 5265c51f124SMoriah Waterland pwd->pw_name, "passwd"); 5275c51f124SMoriah Waterland return (-1); 5285c51f124SMoriah Waterland } else if ((pwd->pw_age = strdup(pwd->pw_age)) == NULL) { 5295c51f124SMoriah Waterland (void) fprintf(stderr, 5305c51f124SMoriah Waterland pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_age"); 5315c51f124SMoriah Waterland return (-1); 5325c51f124SMoriah Waterland } 5335c51f124SMoriah Waterland 5345c51f124SMoriah Waterland if (pwd->pw_comment == NULL) { 5355c51f124SMoriah Waterland (void) fprintf(stderr, 5365c51f124SMoriah Waterland pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_comment", 5375c51f124SMoriah Waterland pwd->pw_name, "passwd"); 5385c51f124SMoriah Waterland return (-1); 5395c51f124SMoriah Waterland } else if ((pwd->pw_comment = strdup(pwd->pw_comment)) == 5405c51f124SMoriah Waterland NULL) { 5415c51f124SMoriah Waterland (void) fprintf(stderr, 5425c51f124SMoriah Waterland pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_comment"); 5435c51f124SMoriah Waterland return (-1); 5445c51f124SMoriah Waterland } 5455c51f124SMoriah Waterland 5465c51f124SMoriah Waterland if (pwd->pw_gecos == NULL) { 5475c51f124SMoriah Waterland (void) fprintf(stderr, 5485c51f124SMoriah Waterland pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_gecos", 5495c51f124SMoriah Waterland pwd->pw_name, "passwd"); 5505c51f124SMoriah Waterland return (-1); 5515c51f124SMoriah Waterland } else if ((pwd->pw_gecos = strdup(pwd->pw_gecos)) == NULL) { 5525c51f124SMoriah Waterland (void) fprintf(stderr, 5535c51f124SMoriah Waterland pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_gecos"); 5545c51f124SMoriah Waterland return (-1); 5555c51f124SMoriah Waterland } 5565c51f124SMoriah Waterland 5575c51f124SMoriah Waterland if (pwd->pw_dir == NULL) { 5585c51f124SMoriah Waterland (void) fprintf(stderr, 5595c51f124SMoriah Waterland pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_dir", 5605c51f124SMoriah Waterland pwd->pw_name, "passwd"); 5615c51f124SMoriah Waterland return (-1); 5625c51f124SMoriah Waterland } else if ((pwd->pw_dir = strdup(pwd->pw_dir)) == NULL) { 5635c51f124SMoriah Waterland (void) fprintf(stderr, 5645c51f124SMoriah Waterland pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_dir"); 5655c51f124SMoriah Waterland return (-1); 5665c51f124SMoriah Waterland } 5675c51f124SMoriah Waterland 5685c51f124SMoriah Waterland if (pwd->pw_shell == NULL) { 5695c51f124SMoriah Waterland (void) fprintf(stderr, 5705c51f124SMoriah Waterland pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_shell", 5715c51f124SMoriah Waterland pwd->pw_name, "passwd"); 5725c51f124SMoriah Waterland return (-1); 5735c51f124SMoriah Waterland } else if ((pwd->pw_shell = strdup(pwd->pw_shell)) == NULL) { 5745c51f124SMoriah Waterland (void) fprintf(stderr, 5755c51f124SMoriah Waterland pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_shell"); 5765c51f124SMoriah Waterland return (-1); 5775c51f124SMoriah Waterland } 5785c51f124SMoriah Waterland } else { 5795c51f124SMoriah Waterland (void) fprintf(stderr, pkg_gt(ERR_NOPWD)); 5805c51f124SMoriah Waterland return (-1); 5815c51f124SMoriah Waterland } 5825c51f124SMoriah Waterland 5835c51f124SMoriah Waterland return (0); 5845c51f124SMoriah Waterland } 5855c51f124SMoriah Waterland 5865c51f124SMoriah Waterland /* 5875c51f124SMoriah Waterland * Check the client's etc/group file for the group name 5885c51f124SMoriah Waterland * 5895c51f124SMoriah Waterland * returns a pointer to the group structure if the group is found 5905c51f124SMoriah Waterland * returns NULL if not found 5915c51f124SMoriah Waterland */ 5925c51f124SMoriah Waterland struct group * 5935c51f124SMoriah Waterland clgrnam(char *nam) 5945c51f124SMoriah Waterland { 5955c51f124SMoriah Waterland struct group *gr; 5965c51f124SMoriah Waterland char *instroot, *buf; 5975c51f124SMoriah Waterland FILE *gr_ptr; 598*4656d474SGarrett D'Amore size_t bufsz; 5995c51f124SMoriah Waterland 6005c51f124SMoriah Waterland if ((instroot = get_install_root()) != NULL) { 601*4656d474SGarrett D'Amore bufsz = strlen(instroot) + strlen(GROUP) + 1; 602*4656d474SGarrett D'Amore if ((buf = (char *)malloc(bufsz)) == NULL) { 6035c51f124SMoriah Waterland (void) fprintf(stderr, 6045c51f124SMoriah Waterland pkg_gt(ERR_MALLOC), "clgrnam()", 6055c51f124SMoriah Waterland strlen(instroot) + strlen(GROUP), "buf"); 6065c51f124SMoriah Waterland } 607*4656d474SGarrett D'Amore (void) snprintf(buf, bufsz, "%s%s", instroot, GROUP); 6085c51f124SMoriah Waterland if ((gr_ptr = fopen(buf, "r")) == NULL) { 6095c51f124SMoriah Waterland free(buf); 6105c51f124SMoriah Waterland return (NULL); 6115c51f124SMoriah Waterland } else { 6125c51f124SMoriah Waterland while ((gr = fgetgrent(gr_ptr)) != NULL) { 6135c51f124SMoriah Waterland if (strcmp(gr->gr_name, nam) == 0) { 6145c51f124SMoriah Waterland break; 6155c51f124SMoriah Waterland } 6165c51f124SMoriah Waterland } 6175c51f124SMoriah Waterland } 6185c51f124SMoriah Waterland free(buf); 6195c51f124SMoriah Waterland (void) fclose(gr_ptr); 6205c51f124SMoriah Waterland return (gr); 6215c51f124SMoriah Waterland } else { 6225c51f124SMoriah Waterland return (NULL); 6235c51f124SMoriah Waterland } 6245c51f124SMoriah Waterland } 6255c51f124SMoriah Waterland 6265c51f124SMoriah Waterland /* 6275c51f124SMoriah Waterland * Check the client's etc/passwd file for the user name 6285c51f124SMoriah Waterland * 6295c51f124SMoriah Waterland * returns a pointer to the passwd structure if the passwd is found 6305c51f124SMoriah Waterland * returns NULL if not found 6315c51f124SMoriah Waterland */ 6325c51f124SMoriah Waterland struct passwd * 6335c51f124SMoriah Waterland clpwnam(char *nam) 6345c51f124SMoriah Waterland { 6355c51f124SMoriah Waterland struct passwd *pw; 6365c51f124SMoriah Waterland char *instroot, *buf; 6375c51f124SMoriah Waterland FILE *pw_ptr; 6385c51f124SMoriah Waterland 6395c51f124SMoriah Waterland if ((instroot = get_install_root()) != NULL) { 640*4656d474SGarrett D'Amore if (asprintf(&buf, "%s%s", instroot, PASSWD) < 0) { 6415c51f124SMoriah Waterland (void) fprintf(stderr, 6425c51f124SMoriah Waterland pkg_gt(ERR_MALLOC), "clpwnam()", 6435c51f124SMoriah Waterland strlen(instroot) + strlen(PASSWD), "buf"); 644*4656d474SGarrett D'Amore return (NULL); 6455c51f124SMoriah Waterland } 6465c51f124SMoriah Waterland if ((pw_ptr = fopen(buf, "r")) == NULL) { 6475c51f124SMoriah Waterland free(buf); 6485c51f124SMoriah Waterland return (NULL); 6495c51f124SMoriah Waterland } else { 6505c51f124SMoriah Waterland while ((pw = fgetpwent(pw_ptr)) != NULL) { 6515c51f124SMoriah Waterland if (strcmp(pw->pw_name, nam) == 0) { 6525c51f124SMoriah Waterland break; 6535c51f124SMoriah Waterland } 6545c51f124SMoriah Waterland } 6555c51f124SMoriah Waterland } 6565c51f124SMoriah Waterland free(buf); 6575c51f124SMoriah Waterland (void) fclose(pw_ptr); 6585c51f124SMoriah Waterland return (pw); 6595c51f124SMoriah Waterland } else { 6605c51f124SMoriah Waterland return (NULL); 6615c51f124SMoriah Waterland } 6625c51f124SMoriah Waterland } 6635c51f124SMoriah Waterland 6645c51f124SMoriah Waterland /* 6655c51f124SMoriah Waterland * Check the client's etc/group file for the group id 6665c51f124SMoriah Waterland * 6675c51f124SMoriah Waterland * returns a pointer to the group structure if the group id is found 6685c51f124SMoriah Waterland * returns NULL if not found 6695c51f124SMoriah Waterland */ 6705c51f124SMoriah Waterland struct group * 6715c51f124SMoriah Waterland clgrgid(gid_t gid) 6725c51f124SMoriah Waterland { 6735c51f124SMoriah Waterland struct group *gr; 6745c51f124SMoriah Waterland char *instroot, *buf; 6755c51f124SMoriah Waterland FILE *gr_ptr; 6765c51f124SMoriah Waterland 6775c51f124SMoriah Waterland if ((instroot = get_install_root()) != NULL) { 678*4656d474SGarrett D'Amore if (asprintf(&buf, "%s%s", instroot, GROUP) < 0) { 6795c51f124SMoriah Waterland (void) fprintf(stderr, 6805c51f124SMoriah Waterland pkg_gt(ERR_MALLOC), "clgrgid()", 6815c51f124SMoriah Waterland strlen(instroot) + strlen(GROUP), "buf"); 682*4656d474SGarrett D'Amore return (NULL); 6835c51f124SMoriah Waterland } 684*4656d474SGarrett D'Amore 6855c51f124SMoriah Waterland if ((gr_ptr = fopen(buf, "r")) == NULL) { 6865c51f124SMoriah Waterland free(buf); 6875c51f124SMoriah Waterland return (NULL); 6885c51f124SMoriah Waterland } else { 6895c51f124SMoriah Waterland while ((gr = fgetgrent(gr_ptr)) != NULL) { 6905c51f124SMoriah Waterland if (gr->gr_gid == gid) { 6915c51f124SMoriah Waterland break; 6925c51f124SMoriah Waterland } 6935c51f124SMoriah Waterland } 6945c51f124SMoriah Waterland } 6955c51f124SMoriah Waterland free(buf); 6965c51f124SMoriah Waterland (void) fclose(gr_ptr); 6975c51f124SMoriah Waterland return (gr); 6985c51f124SMoriah Waterland } else { 6995c51f124SMoriah Waterland return (NULL); 7005c51f124SMoriah Waterland } 7015c51f124SMoriah Waterland } 7025c51f124SMoriah Waterland 7035c51f124SMoriah Waterland /* 7045c51f124SMoriah Waterland * Check the client's etc/passwd file for the user id 7055c51f124SMoriah Waterland * 7065c51f124SMoriah Waterland * returns a pointer to the passwd structure if the user id is found 7075c51f124SMoriah Waterland * returns NULL if not found 7085c51f124SMoriah Waterland */ 7095c51f124SMoriah Waterland struct passwd * 7105c51f124SMoriah Waterland clpwuid(uid_t uid) 7115c51f124SMoriah Waterland { 7125c51f124SMoriah Waterland struct passwd *pw; 7135c51f124SMoriah Waterland char *instroot, *buf; 7145c51f124SMoriah Waterland FILE *pw_ptr; 7155c51f124SMoriah Waterland 7165c51f124SMoriah Waterland if ((instroot = get_install_root()) != NULL) { 717*4656d474SGarrett D'Amore if (asprintf(&buf, "%s%s", instroot, PASSWD) < 0) { 718*4656d474SGarrett D'Amore (void) fprintf(stderr, pkg_gt(ERR_MALLOC), "clpwuid()", 7195c51f124SMoriah Waterland strlen(instroot) + strlen(PASSWD), "buf"); 720*4656d474SGarrett D'Amore return (NULL); 7215c51f124SMoriah Waterland } 7225c51f124SMoriah Waterland if ((pw_ptr = fopen(buf, "r")) == NULL) { 7235c51f124SMoriah Waterland free(buf); 7245c51f124SMoriah Waterland return (NULL); 7255c51f124SMoriah Waterland } else { 7265c51f124SMoriah Waterland while ((pw = fgetpwent(pw_ptr)) != NULL) { 7275c51f124SMoriah Waterland if (pw->pw_uid == uid) { 7285c51f124SMoriah Waterland break; 7295c51f124SMoriah Waterland } 7305c51f124SMoriah Waterland } 7315c51f124SMoriah Waterland } 7325c51f124SMoriah Waterland free(buf); 7335c51f124SMoriah Waterland (void) fclose(pw_ptr); 7345c51f124SMoriah Waterland return (pw); 7355c51f124SMoriah Waterland } else { 7365c51f124SMoriah Waterland return (NULL); 7375c51f124SMoriah Waterland } 7385c51f124SMoriah Waterland } 739