xref: /illumos-gate/usr/src/lib/libpkg/common/ncgrpw.c (revision 4656d474)
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,
604*4656d474SGarrett D'Amore 			    pkg_gt(ERR_MALLOC), "clgrnam()",
605*4656d474SGarrett D'Amore 			    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,
642*4656d474SGarrett D'Amore 			    pkg_gt(ERR_MALLOC), "clpwnam()",
643*4656d474SGarrett D'Amore 			    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,
680*4656d474SGarrett D'Amore 			    pkg_gt(ERR_MALLOC), "clgrgid()",
681*4656d474SGarrett D'Amore 			    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()",
719*4656d474SGarrett D'Amore 			    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