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 *
cache_alloc(char * fname,int len,size_t struct_size)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 *
cgrnam(char * nam)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 *
cpwnam(char * nam)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
uid_hash(void * datap,int datalen,int hsz)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
uid_comp(void * datap1,void * datap2,int datalen)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 *
cgrgid(gid_t gid)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 *
cpwuid(uid_t uid)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
dup_gr_ent(struct group * grp)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
dup_pw_ent(struct passwd * pwd)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 *
clgrnam(char * nam)5935c51f124SMoriah Waterland clgrnam(char *nam)
5945c51f124SMoriah Waterland {
5955c51f124SMoriah Waterland struct group *gr;
5965c51f124SMoriah Waterland char *instroot, *buf;
5975c51f124SMoriah Waterland FILE *gr_ptr;
5984656d474SGarrett D'Amore size_t bufsz;
5995c51f124SMoriah Waterland
6005c51f124SMoriah Waterland if ((instroot = get_install_root()) != NULL) {
6014656d474SGarrett D'Amore bufsz = strlen(instroot) + strlen(GROUP) + 1;
6024656d474SGarrett D'Amore if ((buf = (char *)malloc(bufsz)) == NULL) {
6035c51f124SMoriah Waterland (void) fprintf(stderr,
6044656d474SGarrett D'Amore pkg_gt(ERR_MALLOC), "clgrnam()",
6054656d474SGarrett D'Amore strlen(instroot) + strlen(GROUP), "buf");
6065c51f124SMoriah Waterland }
6074656d474SGarrett 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 *
clpwnam(char * nam)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) {
6404656d474SGarrett D'Amore if (asprintf(&buf, "%s%s", instroot, PASSWD) < 0) {
6415c51f124SMoriah Waterland (void) fprintf(stderr,
6424656d474SGarrett D'Amore pkg_gt(ERR_MALLOC), "clpwnam()",
6434656d474SGarrett D'Amore strlen(instroot) + strlen(PASSWD), "buf");
6444656d474SGarrett 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 *
clgrgid(gid_t gid)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) {
6784656d474SGarrett D'Amore if (asprintf(&buf, "%s%s", instroot, GROUP) < 0) {
6795c51f124SMoriah Waterland (void) fprintf(stderr,
6804656d474SGarrett D'Amore pkg_gt(ERR_MALLOC), "clgrgid()",
6814656d474SGarrett D'Amore strlen(instroot) + strlen(GROUP), "buf");
6824656d474SGarrett D'Amore return (NULL);
6835c51f124SMoriah Waterland }
684*55fea89dSDan Cross
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 *
clpwuid(uid_t uid)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) {
7174656d474SGarrett D'Amore if (asprintf(&buf, "%s%s", instroot, PASSWD) < 0) {
7184656d474SGarrett D'Amore (void) fprintf(stderr, pkg_gt(ERR_MALLOC), "clpwuid()",
7194656d474SGarrett D'Amore strlen(instroot) + strlen(PASSWD), "buf");
7204656d474SGarrett 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