xref: /titanic_52/usr/src/lib/libpkg/common/ncgrpw.c (revision 5c51f1241dbbdf2656d0e10011981411ed0c9673)
1*5c51f124SMoriah Waterland /*
2*5c51f124SMoriah Waterland  * CDDL HEADER START
3*5c51f124SMoriah Waterland  *
4*5c51f124SMoriah Waterland  * The contents of this file are subject to the terms of the
5*5c51f124SMoriah Waterland  * Common Development and Distribution License (the "License").
6*5c51f124SMoriah Waterland  * You may not use this file except in compliance with the License.
7*5c51f124SMoriah Waterland  *
8*5c51f124SMoriah Waterland  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*5c51f124SMoriah Waterland  * or http://www.opensolaris.org/os/licensing.
10*5c51f124SMoriah Waterland  * See the License for the specific language governing permissions
11*5c51f124SMoriah Waterland  * and limitations under the License.
12*5c51f124SMoriah Waterland  *
13*5c51f124SMoriah Waterland  * When distributing Covered Code, include this CDDL HEADER in each
14*5c51f124SMoriah Waterland  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*5c51f124SMoriah Waterland  * If applicable, add the following below this CDDL HEADER, with the
16*5c51f124SMoriah Waterland  * fields enclosed by brackets "[]" replaced with your own identifying
17*5c51f124SMoriah Waterland  * information: Portions Copyright [yyyy] [name of copyright owner]
18*5c51f124SMoriah Waterland  *
19*5c51f124SMoriah Waterland  * CDDL HEADER END
20*5c51f124SMoriah Waterland  */
21*5c51f124SMoriah Waterland 
22*5c51f124SMoriah Waterland /*
23*5c51f124SMoriah Waterland  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*5c51f124SMoriah Waterland  * Use is subject to license terms.
25*5c51f124SMoriah Waterland  */
26*5c51f124SMoriah Waterland 
27*5c51f124SMoriah Waterland 
28*5c51f124SMoriah Waterland /*
29*5c51f124SMoriah Waterland  * This module fetches group and passwd structs for the caller. It
30*5c51f124SMoriah Waterland  * uses a hash table to speed up retrieval of repeated entries. If
31*5c51f124SMoriah Waterland  * the attempts to initialize the hash tables fail, this just
32*5c51f124SMoriah Waterland  * continues the slow way.
33*5c51f124SMoriah Waterland  */
34*5c51f124SMoriah Waterland 
35*5c51f124SMoriah Waterland #include <pwd.h>
36*5c51f124SMoriah Waterland #include <grp.h>
37*5c51f124SMoriah Waterland #include <string.h>
38*5c51f124SMoriah Waterland #include <stdio.h>
39*5c51f124SMoriah Waterland #include <stdlib.h>
40*5c51f124SMoriah Waterland #include <unistd.h>
41*5c51f124SMoriah Waterland #include "pkglib.h"
42*5c51f124SMoriah Waterland #include "pkglocale.h"
43*5c51f124SMoriah Waterland #include "nhash.h"
44*5c51f124SMoriah Waterland 
45*5c51f124SMoriah Waterland #define	HASHSIZE	151
46*5c51f124SMoriah Waterland #define	BSZ		4
47*5c51f124SMoriah Waterland 
48*5c51f124SMoriah Waterland #define	ERR_DUPFAIL	"%s: strdup(%s) failed.\n"
49*5c51f124SMoriah Waterland #define	ERR_ADDFAIL	"%s: add_cache() failed.\n"
50*5c51f124SMoriah Waterland #define	ERR_BADMEMB	"%s: %s in \"%s\" %s structure is invalid.\n"
51*5c51f124SMoriah Waterland #define	ERR_NOGRP	"dup_gr_ent(): no group entry provided.\n"
52*5c51f124SMoriah Waterland #define	ERR_NOPWD	"dup_pw_ent(): no passwd entry provided.\n"
53*5c51f124SMoriah Waterland #define	ERR_NOINIT	"%s: init_cache() failed.\n"
54*5c51f124SMoriah Waterland #define	ERR_MALLOC	"%s: malloc(%d) failed for %s.\n"
55*5c51f124SMoriah Waterland 
56*5c51f124SMoriah Waterland static Cache *pwnam_cache = (Cache *) NULL;
57*5c51f124SMoriah Waterland static Cache *grnam_cache = (Cache *) NULL;
58*5c51f124SMoriah Waterland static Cache *pwuid_cache = (Cache *) NULL;
59*5c51f124SMoriah Waterland static Cache *grgid_cache = (Cache *) NULL;
60*5c51f124SMoriah Waterland 
61*5c51f124SMoriah Waterland static int dup_gr_ent(struct group *grp);
62*5c51f124SMoriah Waterland static int dup_pw_ent(struct passwd *pwp);
63*5c51f124SMoriah Waterland 
64*5c51f124SMoriah Waterland /*
65*5c51f124SMoriah Waterland  * These indicate whether the hash table has been initialized for the four
66*5c51f124SMoriah Waterland  * categories.
67*5c51f124SMoriah Waterland  */
68*5c51f124SMoriah Waterland static int is_a_pwnam_cache;
69*5c51f124SMoriah Waterland static int is_a_grnam_cache;
70*5c51f124SMoriah Waterland static int is_a_pwuid_cache;
71*5c51f124SMoriah Waterland static int is_a_grgid_cache;
72*5c51f124SMoriah Waterland 
73*5c51f124SMoriah Waterland extern char *get_install_root(void);
74*5c51f124SMoriah Waterland 
75*5c51f124SMoriah Waterland /*
76*5c51f124SMoriah Waterland  * If there's a grnam cache, then update it with this new
77*5c51f124SMoriah Waterland  * group, otherwise, skip it.
78*5c51f124SMoriah Waterland  */
79*5c51f124SMoriah Waterland static Item *
80*5c51f124SMoriah Waterland cache_alloc(char *fname, int len, size_t struct_size)
81*5c51f124SMoriah Waterland {
82*5c51f124SMoriah Waterland 	Item *itemp;
83*5c51f124SMoriah Waterland 
84*5c51f124SMoriah Waterland 	/*
85*5c51f124SMoriah Waterland 	 * Allocate space for the Item pointer, key and data.
86*5c51f124SMoriah Waterland 	 */
87*5c51f124SMoriah Waterland 	if ((itemp = (Item *) malloc(sizeof (*itemp))) ==
88*5c51f124SMoriah Waterland 	    Null_Item) {
89*5c51f124SMoriah Waterland 		(void) fprintf(stderr,
90*5c51f124SMoriah Waterland 		    pkg_gt(ERR_MALLOC), fname,
91*5c51f124SMoriah Waterland 		    sizeof (*itemp), "itemp");
92*5c51f124SMoriah Waterland 	} else if ((itemp->key = (char *)malloc(len)) == NULL) {
93*5c51f124SMoriah Waterland 		(void) fprintf(stderr, pkg_gt(ERR_MALLOC), fname, len,
94*5c51f124SMoriah Waterland 		    "itemp->key");
95*5c51f124SMoriah Waterland 		free(itemp);
96*5c51f124SMoriah Waterland 	} else if ((itemp->data = malloc(struct_size)) == NULL) {
97*5c51f124SMoriah Waterland 		(void) fprintf(stderr, pkg_gt(ERR_MALLOC), fname,
98*5c51f124SMoriah Waterland 		    struct_size, "itemp->data");
99*5c51f124SMoriah Waterland 		free(itemp->key);
100*5c51f124SMoriah Waterland 		free(itemp);
101*5c51f124SMoriah Waterland 	} else {
102*5c51f124SMoriah Waterland 		/* Set length parameters. */
103*5c51f124SMoriah Waterland 		itemp->keyl = len;
104*5c51f124SMoriah Waterland 		itemp->datal = struct_size;
105*5c51f124SMoriah Waterland 
106*5c51f124SMoriah Waterland 		return (itemp);
107*5c51f124SMoriah Waterland 	}
108*5c51f124SMoriah Waterland 
109*5c51f124SMoriah Waterland 	return ((Item *) NULL);
110*5c51f124SMoriah Waterland }
111*5c51f124SMoriah Waterland 
112*5c51f124SMoriah Waterland /* Get the required group structure based upon the group name. */
113*5c51f124SMoriah Waterland struct group *
114*5c51f124SMoriah Waterland cgrnam(char *nam)
115*5c51f124SMoriah Waterland {
116*5c51f124SMoriah Waterland 	struct group *grp;
117*5c51f124SMoriah Waterland 	Item *itemp;
118*5c51f124SMoriah Waterland 	int len;
119*5c51f124SMoriah Waterland 	static int cache_failed;
120*5c51f124SMoriah Waterland 
121*5c51f124SMoriah Waterland 	/* Attempt to initialize the grname cache. */
122*5c51f124SMoriah Waterland 	if (!is_a_grnam_cache && !cache_failed) {
123*5c51f124SMoriah Waterland 		if (init_cache(&grnam_cache, HASHSIZE, BSZ,
124*5c51f124SMoriah Waterland 		    (int (*)())NULL, (int (*)())NULL) == -1) {
125*5c51f124SMoriah Waterland 			(void) fprintf(stderr, pkg_gt(ERR_NOINIT), "cgrnam()");
126*5c51f124SMoriah Waterland 			grnam_cache = (Cache *) NULL;
127*5c51f124SMoriah Waterland 			cache_failed = 1;
128*5c51f124SMoriah Waterland 		} else
129*5c51f124SMoriah Waterland 			is_a_grnam_cache = 1;
130*5c51f124SMoriah Waterland 	}
131*5c51f124SMoriah Waterland 
132*5c51f124SMoriah Waterland 	len = strlen(nam) + 1;
133*5c51f124SMoriah Waterland 
134*5c51f124SMoriah Waterland 	/* First look in the cache. Failing that, do it the hard way. */
135*5c51f124SMoriah Waterland 	if ((itemp = lookup_cache(grnam_cache, nam, len)) == Null_Item) {
136*5c51f124SMoriah Waterland 
137*5c51f124SMoriah Waterland 		/* Get the group by name. */
138*5c51f124SMoriah Waterland 		if ((grp = clgrnam(nam)) != NULL ||
139*5c51f124SMoriah Waterland 				(grp = getgrnam(nam)) != NULL) {
140*5c51f124SMoriah Waterland 			/* A group by that name exists on this machine. */
141*5c51f124SMoriah Waterland 			if (dup_gr_ent(grp))
142*5c51f124SMoriah Waterland 				/*
143*5c51f124SMoriah Waterland 				 * Effectively no such group since struct
144*5c51f124SMoriah Waterland 				 * couldn't be duplicated.
145*5c51f124SMoriah Waterland 				 */
146*5c51f124SMoriah Waterland 				grp = (struct group *)NULL;
147*5c51f124SMoriah Waterland 			/*
148*5c51f124SMoriah Waterland 			 * If there's a grnam cache, then update it with this
149*5c51f124SMoriah Waterland 			 * new group, otherwise, skip it.
150*5c51f124SMoriah Waterland 			 */
151*5c51f124SMoriah Waterland 			else if (is_a_grnam_cache) {
152*5c51f124SMoriah Waterland 				if ((itemp = cache_alloc("cgrnam()", len,
153*5c51f124SMoriah Waterland 				    sizeof (struct group))) != Null_Item) {
154*5c51f124SMoriah Waterland 					/*
155*5c51f124SMoriah Waterland 					 * With that allocated, insert the
156*5c51f124SMoriah Waterland 					 * group name as key and set the key
157*5c51f124SMoriah Waterland 					 * length.
158*5c51f124SMoriah Waterland 					 */
159*5c51f124SMoriah Waterland 					(void) memmove(itemp->key, nam, len);
160*5c51f124SMoriah Waterland 
161*5c51f124SMoriah Waterland 					/*
162*5c51f124SMoriah Waterland 					 * Insert the data associated with
163*5c51f124SMoriah Waterland 					 * the key and the data length.
164*5c51f124SMoriah Waterland 					 */
165*5c51f124SMoriah Waterland 					(void) memmove(itemp->data, grp,
166*5c51f124SMoriah Waterland 					    sizeof (struct group));
167*5c51f124SMoriah Waterland 
168*5c51f124SMoriah Waterland 					/* Insert the Item into the cache. */
169*5c51f124SMoriah Waterland 					if (add_cache(grnam_cache, itemp) == -1)
170*5c51f124SMoriah Waterland 						(void) fprintf(stderr,
171*5c51f124SMoriah Waterland 						    pkg_gt(ERR_ADDFAIL),
172*5c51f124SMoriah Waterland 						    "cgrnam()");
173*5c51f124SMoriah Waterland 				}
174*5c51f124SMoriah Waterland 			}
175*5c51f124SMoriah Waterland 		}
176*5c51f124SMoriah Waterland 		return (grp);
177*5c51f124SMoriah Waterland 	} else	/* Found it in the cache. */
178*5c51f124SMoriah Waterland 		return ((struct group *)itemp->data);
179*5c51f124SMoriah Waterland }
180*5c51f124SMoriah Waterland 
181*5c51f124SMoriah Waterland struct passwd *
182*5c51f124SMoriah Waterland cpwnam(char *nam)
183*5c51f124SMoriah Waterland {
184*5c51f124SMoriah Waterland 	struct passwd *pwd;
185*5c51f124SMoriah Waterland 	Item *itemp;
186*5c51f124SMoriah Waterland 	int len;
187*5c51f124SMoriah Waterland 	static int cache_failed;
188*5c51f124SMoriah Waterland 
189*5c51f124SMoriah Waterland 	if (!is_a_pwnam_cache && !cache_failed) {
190*5c51f124SMoriah Waterland 		if (init_cache(&pwnam_cache, HASHSIZE, BSZ,
191*5c51f124SMoriah Waterland 		    (int (*)())NULL, (int (*)())NULL) == -1) {
192*5c51f124SMoriah Waterland 			(void) fprintf(stderr, pkg_gt(ERR_NOINIT), "cpwnam()");
193*5c51f124SMoriah Waterland 			pwnam_cache = (Cache *) NULL;
194*5c51f124SMoriah Waterland 			cache_failed = 1;
195*5c51f124SMoriah Waterland 		} else
196*5c51f124SMoriah Waterland 			is_a_pwnam_cache = 1;
197*5c51f124SMoriah Waterland 	}
198*5c51f124SMoriah Waterland 
199*5c51f124SMoriah Waterland 	len = strlen(nam) + 1;
200*5c51f124SMoriah Waterland 
201*5c51f124SMoriah Waterland 	/* First look in the cache. Failing that, do it the hard way. */
202*5c51f124SMoriah Waterland 	if ((itemp = lookup_cache(pwnam_cache, nam, len)) == Null_Item) {
203*5c51f124SMoriah Waterland 
204*5c51f124SMoriah Waterland 		/* Get the passwd by name. */
205*5c51f124SMoriah Waterland 		if ((pwd = clpwnam(nam)) != NULL ||
206*5c51f124SMoriah Waterland 				(pwd = getpwnam(nam)) != NULL) {
207*5c51f124SMoriah Waterland 			/* A passwd by that name exists on this machine. */
208*5c51f124SMoriah Waterland 			if (dup_pw_ent(pwd))
209*5c51f124SMoriah Waterland 				/*
210*5c51f124SMoriah Waterland 				 * Effectively no such passwd since struct
211*5c51f124SMoriah Waterland 				 * couldn't be duplicated.
212*5c51f124SMoriah Waterland 				 */
213*5c51f124SMoriah Waterland 				pwd = (struct passwd *)NULL;
214*5c51f124SMoriah Waterland 			/*
215*5c51f124SMoriah Waterland 			 * If there's a pwnam cache, then update it with this
216*5c51f124SMoriah Waterland 			 * new passwd, otherwise, skip it.
217*5c51f124SMoriah Waterland 			 */
218*5c51f124SMoriah Waterland 			else if (is_a_pwnam_cache) {
219*5c51f124SMoriah Waterland 				/*
220*5c51f124SMoriah Waterland 				 * Allocate space for the Item pointer, key
221*5c51f124SMoriah Waterland 				 * and data.
222*5c51f124SMoriah Waterland 				 */
223*5c51f124SMoriah Waterland 				if ((itemp = cache_alloc("cpwnam()", len,
224*5c51f124SMoriah Waterland 				    sizeof (struct passwd))) != Null_Item) {
225*5c51f124SMoriah Waterland 					/*
226*5c51f124SMoriah Waterland 					 * With that allocated, insert the
227*5c51f124SMoriah Waterland 					 * group name as key and set the key
228*5c51f124SMoriah Waterland 					 * length.
229*5c51f124SMoriah Waterland 					 */
230*5c51f124SMoriah Waterland 					(void) memmove(itemp->key, nam, len);
231*5c51f124SMoriah Waterland 
232*5c51f124SMoriah Waterland 					/*
233*5c51f124SMoriah Waterland 					 * Insert the data associated with
234*5c51f124SMoriah Waterland 					 * the key and the data length.
235*5c51f124SMoriah Waterland 					 */
236*5c51f124SMoriah Waterland 					(void) memmove(itemp->data, pwd,
237*5c51f124SMoriah Waterland 					    sizeof (struct passwd));
238*5c51f124SMoriah Waterland 
239*5c51f124SMoriah Waterland 					if (add_cache(pwnam_cache, itemp) == -1)
240*5c51f124SMoriah Waterland 						(void) fprintf(stderr,
241*5c51f124SMoriah Waterland 						    pkg_gt(ERR_ADDFAIL),
242*5c51f124SMoriah Waterland 						    "cpwnam()");
243*5c51f124SMoriah Waterland 				}
244*5c51f124SMoriah Waterland 			}
245*5c51f124SMoriah Waterland 		}
246*5c51f124SMoriah Waterland 		return (pwd);
247*5c51f124SMoriah Waterland 	} else	/* Found it in the cache. */
248*5c51f124SMoriah Waterland 		return ((struct passwd *)itemp->data);
249*5c51f124SMoriah Waterland }
250*5c51f124SMoriah Waterland 
251*5c51f124SMoriah Waterland static int
252*5c51f124SMoriah Waterland uid_hash(void *datap, int datalen, int hsz)
253*5c51f124SMoriah Waterland {
254*5c51f124SMoriah Waterland #ifdef lint
255*5c51f124SMoriah Waterland 	int i = datalen;
256*5c51f124SMoriah Waterland 	datalen = i;
257*5c51f124SMoriah Waterland #endif	/* lint */
258*5c51f124SMoriah Waterland 
259*5c51f124SMoriah Waterland 	return (*((uid_t *)datap) % hsz);
260*5c51f124SMoriah Waterland }
261*5c51f124SMoriah Waterland 
262*5c51f124SMoriah Waterland static int
263*5c51f124SMoriah Waterland uid_comp(void *datap1, void *datap2, int datalen)
264*5c51f124SMoriah Waterland {
265*5c51f124SMoriah Waterland #ifdef lint
266*5c51f124SMoriah Waterland 	int i = datalen;
267*5c51f124SMoriah Waterland 	datalen = i;
268*5c51f124SMoriah Waterland #endif	/* lint */
269*5c51f124SMoriah Waterland 
270*5c51f124SMoriah Waterland 	return (*((uid_t *)datap1) - *((uid_t *)datap2));
271*5c51f124SMoriah Waterland }
272*5c51f124SMoriah Waterland 
273*5c51f124SMoriah Waterland struct group *
274*5c51f124SMoriah Waterland cgrgid(gid_t gid)
275*5c51f124SMoriah Waterland {
276*5c51f124SMoriah Waterland 	struct group *grp;
277*5c51f124SMoriah Waterland 	Item *itemp;
278*5c51f124SMoriah Waterland 	int len;
279*5c51f124SMoriah Waterland 	static int cache_failed;
280*5c51f124SMoriah Waterland 
281*5c51f124SMoriah Waterland 	if (!is_a_grgid_cache && !cache_failed) {
282*5c51f124SMoriah Waterland 		if (init_cache(&grgid_cache, HASHSIZE, BSZ,
283*5c51f124SMoriah Waterland 		    uid_hash, uid_comp) == -1) {
284*5c51f124SMoriah Waterland 			(void) fprintf(stderr, pkg_gt(ERR_NOINIT), "cgrgid()");
285*5c51f124SMoriah Waterland 			grgid_cache = (Cache *) NULL;
286*5c51f124SMoriah Waterland 			cache_failed = 1;
287*5c51f124SMoriah Waterland 		} else
288*5c51f124SMoriah Waterland 			is_a_grgid_cache = 1;
289*5c51f124SMoriah Waterland 	}
290*5c51f124SMoriah Waterland 
291*5c51f124SMoriah Waterland 	len = sizeof (uid_t);
292*5c51f124SMoriah Waterland 
293*5c51f124SMoriah Waterland 	/* First look in the cache. Failing that, do it the hard way. */
294*5c51f124SMoriah Waterland 	if ((itemp = lookup_cache(grgid_cache, &gid, len)) == Null_Item) {
295*5c51f124SMoriah Waterland 		if ((grp = clgrgid(gid)) != NULL ||
296*5c51f124SMoriah Waterland 				(grp = getgrgid(gid)) != NULL) {
297*5c51f124SMoriah Waterland 			/* A group by that number exists on this machine. */
298*5c51f124SMoriah Waterland 			if (dup_gr_ent(grp))
299*5c51f124SMoriah Waterland 				/*
300*5c51f124SMoriah Waterland 				 * Effectively no such group since struct
301*5c51f124SMoriah Waterland 				 * couldn't be duplicated.
302*5c51f124SMoriah Waterland 				 */
303*5c51f124SMoriah Waterland 				grp = (struct group *)NULL;
304*5c51f124SMoriah Waterland 			/*
305*5c51f124SMoriah Waterland 			 * If there's a grnam cache, then update it with this
306*5c51f124SMoriah Waterland 			 * new group, otherwise, skip it.
307*5c51f124SMoriah Waterland 			 */
308*5c51f124SMoriah Waterland 			else if (is_a_grgid_cache) {
309*5c51f124SMoriah Waterland 				if ((itemp = cache_alloc("cgrgid()", len,
310*5c51f124SMoriah Waterland 				    sizeof (struct group))) != Null_Item) {
311*5c51f124SMoriah Waterland 					/*
312*5c51f124SMoriah Waterland 					 * With that allocated, insert the
313*5c51f124SMoriah Waterland 					 * group name as key and set the key
314*5c51f124SMoriah Waterland 					 * length.
315*5c51f124SMoriah Waterland 					 */
316*5c51f124SMoriah Waterland 					(void) memmove(itemp->key, &gid, len);
317*5c51f124SMoriah Waterland 
318*5c51f124SMoriah Waterland 					/*
319*5c51f124SMoriah Waterland 					 * Insert the data associated with
320*5c51f124SMoriah Waterland 					 * the key and the data length.
321*5c51f124SMoriah Waterland 					 */
322*5c51f124SMoriah Waterland 					(void) memmove(itemp->data, grp,
323*5c51f124SMoriah Waterland 					    sizeof (struct group));
324*5c51f124SMoriah Waterland 
325*5c51f124SMoriah Waterland 					if (add_cache(grgid_cache, itemp) == -1)
326*5c51f124SMoriah Waterland 						(void) fprintf(stderr,
327*5c51f124SMoriah Waterland 						    pkg_gt(ERR_ADDFAIL),
328*5c51f124SMoriah Waterland 						    "cgrgid()");
329*5c51f124SMoriah Waterland 				}
330*5c51f124SMoriah Waterland 			}
331*5c51f124SMoriah Waterland 		}
332*5c51f124SMoriah Waterland 		return (grp);
333*5c51f124SMoriah Waterland 	} else	/* Found it in the cache. */
334*5c51f124SMoriah Waterland 		return ((struct group *)itemp->data);
335*5c51f124SMoriah Waterland }
336*5c51f124SMoriah Waterland 
337*5c51f124SMoriah Waterland struct passwd *
338*5c51f124SMoriah Waterland cpwuid(uid_t uid)
339*5c51f124SMoriah Waterland {
340*5c51f124SMoriah Waterland 	struct passwd *pwd;
341*5c51f124SMoriah Waterland 	Item *itemp;
342*5c51f124SMoriah Waterland 	int len;
343*5c51f124SMoriah Waterland 	static int cache_failed;
344*5c51f124SMoriah Waterland 
345*5c51f124SMoriah Waterland 	if (!is_a_pwuid_cache && !cache_failed) {
346*5c51f124SMoriah Waterland 		if (init_cache(&pwuid_cache, HASHSIZE, BSZ,
347*5c51f124SMoriah Waterland 		    uid_hash, uid_comp) == -1) {
348*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
349*5c51f124SMoriah Waterland 			    pkg_gt(ERR_NOINIT), "cpwuid()");
350*5c51f124SMoriah Waterland 			pwuid_cache = (Cache *) NULL;
351*5c51f124SMoriah Waterland 			cache_failed = 1;
352*5c51f124SMoriah Waterland 		} else
353*5c51f124SMoriah Waterland 			is_a_pwuid_cache = 1;
354*5c51f124SMoriah Waterland 	}
355*5c51f124SMoriah Waterland 
356*5c51f124SMoriah Waterland 	len = sizeof (uid_t);
357*5c51f124SMoriah Waterland 
358*5c51f124SMoriah Waterland 	/* First look in the cache. Failing that, do it the hard way. */
359*5c51f124SMoriah Waterland 	if ((itemp = lookup_cache(pwuid_cache, &uid, len)) == Null_Item) {
360*5c51f124SMoriah Waterland 
361*5c51f124SMoriah Waterland 		/* Get the passwd by number. */
362*5c51f124SMoriah Waterland 		if ((pwd = clpwuid(uid)) != NULL ||
363*5c51f124SMoriah Waterland 				(pwd = getpwuid(uid)) != NULL) {
364*5c51f124SMoriah Waterland 			/* A passwd by that user ID exists on this machine. */
365*5c51f124SMoriah Waterland 			if (dup_pw_ent(pwd))
366*5c51f124SMoriah Waterland 				/*
367*5c51f124SMoriah Waterland 				 * Effectively no such passwd since struct
368*5c51f124SMoriah Waterland 				 * couldn't be duplicated.
369*5c51f124SMoriah Waterland 				 */
370*5c51f124SMoriah Waterland 				pwd = (struct passwd *)NULL;
371*5c51f124SMoriah Waterland 			/*
372*5c51f124SMoriah Waterland 			 * If there's a pwuid cache, then update it with this
373*5c51f124SMoriah Waterland 			 * new passwd, otherwise, skip it.
374*5c51f124SMoriah Waterland 			 */
375*5c51f124SMoriah Waterland 			else if (is_a_pwuid_cache) {
376*5c51f124SMoriah Waterland 				if ((itemp = cache_alloc("cpwuid()", len,
377*5c51f124SMoriah Waterland 				    sizeof (struct passwd))) != Null_Item) {
378*5c51f124SMoriah Waterland 					/*
379*5c51f124SMoriah Waterland 					 * With that allocated, insert the
380*5c51f124SMoriah Waterland 					 * group name as key and set the key
381*5c51f124SMoriah Waterland 					 * length.
382*5c51f124SMoriah Waterland 					 */
383*5c51f124SMoriah Waterland 					(void) memmove(itemp->key, &uid, len);
384*5c51f124SMoriah Waterland 
385*5c51f124SMoriah Waterland 					/*
386*5c51f124SMoriah Waterland 					 * Insert the data associated with
387*5c51f124SMoriah Waterland 					 * the key and the data length.
388*5c51f124SMoriah Waterland 					 */
389*5c51f124SMoriah Waterland 					(void) memmove(itemp->data, pwd,
390*5c51f124SMoriah Waterland 					    sizeof (struct passwd));
391*5c51f124SMoriah Waterland 
392*5c51f124SMoriah Waterland 					if (add_cache(pwuid_cache, itemp) == -1)
393*5c51f124SMoriah Waterland 						(void) fprintf(stderr,
394*5c51f124SMoriah Waterland 						    pkg_gt(ERR_ADDFAIL),
395*5c51f124SMoriah Waterland 						    "cpwuid()");
396*5c51f124SMoriah Waterland 				}
397*5c51f124SMoriah Waterland 			}
398*5c51f124SMoriah Waterland 		}
399*5c51f124SMoriah Waterland 		return (pwd);
400*5c51f124SMoriah Waterland 	} else	/* Found it in the cache. */
401*5c51f124SMoriah Waterland 		return ((struct passwd *)itemp->data);
402*5c51f124SMoriah Waterland }
403*5c51f124SMoriah Waterland 
404*5c51f124SMoriah Waterland /*
405*5c51f124SMoriah Waterland  * This function duplicates the group structure provided from kernel static
406*5c51f124SMoriah Waterland  * memory. There is a lot of defensive coding here because there have been
407*5c51f124SMoriah Waterland  * problems with the getgr*() functions. They will sometimes provide NULL
408*5c51f124SMoriah Waterland  * values instead of pointers to NULL values. There has been no explanation
409*5c51f124SMoriah Waterland  * for the reason behind this; but, this function takes a NULL to be an
410*5c51f124SMoriah Waterland  * invalid (char *) and returns an error.
411*5c51f124SMoriah Waterland  */
412*5c51f124SMoriah Waterland static int
413*5c51f124SMoriah Waterland dup_gr_ent(struct group *grp)
414*5c51f124SMoriah Waterland {
415*5c51f124SMoriah Waterland 	char **tp = NULL;
416*5c51f124SMoriah Waterland 	char **memp = NULL;
417*5c51f124SMoriah Waterland 	int	nent = 0;	/* Number of entries in the member list. */
418*5c51f124SMoriah Waterland 
419*5c51f124SMoriah Waterland 	if (grp) {
420*5c51f124SMoriah Waterland 		if (grp->gr_name == NULL) {
421*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
422*5c51f124SMoriah Waterland 			    pkg_gt(ERR_BADMEMB), "dup_gr_ent()", "gr_name",
423*5c51f124SMoriah Waterland 			    "unknown", "group");
424*5c51f124SMoriah Waterland 			return (-1);
425*5c51f124SMoriah Waterland 		} else if ((grp->gr_name = strdup(grp->gr_name)) == NULL) {
426*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
427*5c51f124SMoriah Waterland 			    pkg_gt(ERR_DUPFAIL), "dup_gr_ent()", "gr_name");
428*5c51f124SMoriah Waterland 			return (-1);
429*5c51f124SMoriah Waterland 		}
430*5c51f124SMoriah Waterland 		if (grp->gr_passwd == NULL) {
431*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
432*5c51f124SMoriah Waterland 			    pkg_gt(ERR_BADMEMB), "dup_gr_ent()", "gr_passwd",
433*5c51f124SMoriah Waterland 			    grp->gr_name, "group");
434*5c51f124SMoriah Waterland 			return (-1);
435*5c51f124SMoriah Waterland 		} else if ((grp->gr_passwd = strdup(grp->gr_passwd)) == NULL) {
436*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
437*5c51f124SMoriah Waterland 			    pkg_gt(ERR_DUPFAIL), "dup_gr_ent()", "gr_passwd");
438*5c51f124SMoriah Waterland 			return (-1);
439*5c51f124SMoriah Waterland 		}
440*5c51f124SMoriah Waterland 		/*
441*5c51f124SMoriah Waterland 		 * Allocate space for the member list and move the members
442*5c51f124SMoriah Waterland 		 * into it.
443*5c51f124SMoriah Waterland 		 */
444*5c51f124SMoriah Waterland 		if (grp->gr_mem) {
445*5c51f124SMoriah Waterland 			/*
446*5c51f124SMoriah Waterland 			 * First count the members. The nent variable will be
447*5c51f124SMoriah Waterland 			 * the number of members + 1 for the terminator.
448*5c51f124SMoriah Waterland 			 */
449*5c51f124SMoriah Waterland 			for (tp = grp->gr_mem; *tp; nent++, tp++);
450*5c51f124SMoriah Waterland 
451*5c51f124SMoriah Waterland 			/* Now allocate room for the pointers. */
452*5c51f124SMoriah Waterland 			memp = malloc(sizeof (char **)* (nent+1));
453*5c51f124SMoriah Waterland 
454*5c51f124SMoriah Waterland 			if (memp == NULL) {
455*5c51f124SMoriah Waterland 				(void) fprintf(stderr,
456*5c51f124SMoriah Waterland 				    pkg_gt(ERR_MALLOC), "dup_gr_ent()",
457*5c51f124SMoriah Waterland 				    (sizeof (char **)* (nent+1)),
458*5c51f124SMoriah Waterland 				    "memp");
459*5c51f124SMoriah Waterland 				return (-1);
460*5c51f124SMoriah Waterland 			}
461*5c51f124SMoriah Waterland 
462*5c51f124SMoriah Waterland 			/*
463*5c51f124SMoriah Waterland 			 * Now copy over the pointers and entries. It should
464*5c51f124SMoriah Waterland 			 * be noted that if the structure is messed up here,
465*5c51f124SMoriah Waterland 			 * the resulting member list will be truncated at the
466*5c51f124SMoriah Waterland 			 * NULL entry.
467*5c51f124SMoriah Waterland 			 */
468*5c51f124SMoriah Waterland 			for (nent = 0, tp = grp->gr_mem; *tp; tp++) {
469*5c51f124SMoriah Waterland 				if ((memp[nent++] = strdup(*tp)) == NULL) {
470*5c51f124SMoriah Waterland 					(void) fprintf(stderr,
471*5c51f124SMoriah Waterland 					    pkg_gt(ERR_DUPFAIL), "dup_gr_ent()",
472*5c51f124SMoriah Waterland 					    "gr_mem");
473*5c51f124SMoriah Waterland 					return (-1);
474*5c51f124SMoriah Waterland 				}
475*5c51f124SMoriah Waterland 			}
476*5c51f124SMoriah Waterland 		} else {
477*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
478*5c51f124SMoriah Waterland 			    pkg_gt(ERR_BADMEMB), "dup_gr_ent()", "gr_mem",
479*5c51f124SMoriah Waterland 			    grp->gr_name, "group");
480*5c51f124SMoriah Waterland 			return (-1);
481*5c51f124SMoriah Waterland 		}
482*5c51f124SMoriah Waterland 	} else {
483*5c51f124SMoriah Waterland 		(void) fprintf(stderr, pkg_gt(ERR_NOGRP));
484*5c51f124SMoriah Waterland 		return (-1);
485*5c51f124SMoriah Waterland 	}
486*5c51f124SMoriah Waterland 	memp[nent++] = '\0';
487*5c51f124SMoriah Waterland 	return (0);
488*5c51f124SMoriah Waterland }
489*5c51f124SMoriah Waterland 
490*5c51f124SMoriah Waterland /*
491*5c51f124SMoriah Waterland  * This function duplicates the passwd structure provided from kernel static
492*5c51f124SMoriah Waterland  * memory. As in the above function, since there have been problems with the
493*5c51f124SMoriah Waterland  * getpw*() functions, the structure provided is rigorously scrubbed. This
494*5c51f124SMoriah Waterland  * function takes a NULL to be an invalid (char *) and returns an error if
495*5c51f124SMoriah Waterland  * one is detected.
496*5c51f124SMoriah Waterland  */
497*5c51f124SMoriah Waterland static int
498*5c51f124SMoriah Waterland dup_pw_ent(struct passwd *pwd)
499*5c51f124SMoriah Waterland {
500*5c51f124SMoriah Waterland 	if (pwd) {
501*5c51f124SMoriah Waterland 		if (pwd->pw_name == NULL) {
502*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
503*5c51f124SMoriah Waterland 			    pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_name",
504*5c51f124SMoriah Waterland 			    "unknown", "passwd");
505*5c51f124SMoriah Waterland 			return (-1);
506*5c51f124SMoriah Waterland 		} else if ((pwd->pw_name = strdup(pwd->pw_name)) == NULL) {
507*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
508*5c51f124SMoriah Waterland 			    pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_name");
509*5c51f124SMoriah Waterland 			return (-1);
510*5c51f124SMoriah Waterland 		}
511*5c51f124SMoriah Waterland 
512*5c51f124SMoriah Waterland 		if (pwd->pw_passwd == NULL) {
513*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
514*5c51f124SMoriah Waterland 			    pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_passwd",
515*5c51f124SMoriah Waterland 			    pwd->pw_name, "passwd");
516*5c51f124SMoriah Waterland 			return (-1);
517*5c51f124SMoriah Waterland 		} else if ((pwd->pw_passwd = strdup(pwd->pw_passwd)) == NULL) {
518*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
519*5c51f124SMoriah Waterland 			    pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_passwd");
520*5c51f124SMoriah Waterland 			return (-1);
521*5c51f124SMoriah Waterland 		}
522*5c51f124SMoriah Waterland 
523*5c51f124SMoriah Waterland 		if (pwd->pw_age == NULL) {
524*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
525*5c51f124SMoriah Waterland 			    pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_age",
526*5c51f124SMoriah Waterland 			    pwd->pw_name, "passwd");
527*5c51f124SMoriah Waterland 			return (-1);
528*5c51f124SMoriah Waterland 		} else if ((pwd->pw_age = strdup(pwd->pw_age)) == NULL) {
529*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
530*5c51f124SMoriah Waterland 			    pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_age");
531*5c51f124SMoriah Waterland 			return (-1);
532*5c51f124SMoriah Waterland 		}
533*5c51f124SMoriah Waterland 
534*5c51f124SMoriah Waterland 		if (pwd->pw_comment == NULL) {
535*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
536*5c51f124SMoriah Waterland 			    pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_comment",
537*5c51f124SMoriah Waterland 			    pwd->pw_name, "passwd");
538*5c51f124SMoriah Waterland 			return (-1);
539*5c51f124SMoriah Waterland 		} else if ((pwd->pw_comment = strdup(pwd->pw_comment)) ==
540*5c51f124SMoriah Waterland 		    NULL) {
541*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
542*5c51f124SMoriah Waterland 			    pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_comment");
543*5c51f124SMoriah Waterland 			return (-1);
544*5c51f124SMoriah Waterland 		}
545*5c51f124SMoriah Waterland 
546*5c51f124SMoriah Waterland 		if (pwd->pw_gecos == NULL) {
547*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
548*5c51f124SMoriah Waterland 			    pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_gecos",
549*5c51f124SMoriah Waterland 			    pwd->pw_name, "passwd");
550*5c51f124SMoriah Waterland 			return (-1);
551*5c51f124SMoriah Waterland 		} else if ((pwd->pw_gecos = strdup(pwd->pw_gecos)) == NULL) {
552*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
553*5c51f124SMoriah Waterland 			    pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_gecos");
554*5c51f124SMoriah Waterland 			return (-1);
555*5c51f124SMoriah Waterland 		}
556*5c51f124SMoriah Waterland 
557*5c51f124SMoriah Waterland 		if (pwd->pw_dir == NULL) {
558*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
559*5c51f124SMoriah Waterland 			    pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_dir",
560*5c51f124SMoriah Waterland 			    pwd->pw_name, "passwd");
561*5c51f124SMoriah Waterland 			return (-1);
562*5c51f124SMoriah Waterland 		} else if ((pwd->pw_dir = strdup(pwd->pw_dir)) == NULL) {
563*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
564*5c51f124SMoriah Waterland 			    pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_dir");
565*5c51f124SMoriah Waterland 			return (-1);
566*5c51f124SMoriah Waterland 		}
567*5c51f124SMoriah Waterland 
568*5c51f124SMoriah Waterland 		if (pwd->pw_shell == NULL) {
569*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
570*5c51f124SMoriah Waterland 			    pkg_gt(ERR_BADMEMB), "dup_pw_ent()", "pw_shell",
571*5c51f124SMoriah Waterland 			    pwd->pw_name, "passwd");
572*5c51f124SMoriah Waterland 			return (-1);
573*5c51f124SMoriah Waterland 		} else if ((pwd->pw_shell = strdup(pwd->pw_shell)) == NULL) {
574*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
575*5c51f124SMoriah Waterland 			    pkg_gt(ERR_DUPFAIL), "dup_pw_ent()", "pw_shell");
576*5c51f124SMoriah Waterland 			return (-1);
577*5c51f124SMoriah Waterland 		}
578*5c51f124SMoriah Waterland 	} else {
579*5c51f124SMoriah Waterland 		(void) fprintf(stderr, pkg_gt(ERR_NOPWD));
580*5c51f124SMoriah Waterland 		return (-1);
581*5c51f124SMoriah Waterland 	}
582*5c51f124SMoriah Waterland 
583*5c51f124SMoriah Waterland 	return (0);
584*5c51f124SMoriah Waterland }
585*5c51f124SMoriah Waterland 
586*5c51f124SMoriah Waterland /*
587*5c51f124SMoriah Waterland  * Check the client's etc/group file for the group name
588*5c51f124SMoriah Waterland  *
589*5c51f124SMoriah Waterland  * returns a pointer to the group structure if the group is found
590*5c51f124SMoriah Waterland  * returns NULL if not found
591*5c51f124SMoriah Waterland  */
592*5c51f124SMoriah Waterland struct group *
593*5c51f124SMoriah Waterland clgrnam(char *nam)
594*5c51f124SMoriah Waterland {
595*5c51f124SMoriah Waterland 	struct group *gr;
596*5c51f124SMoriah Waterland 	char *instroot, *buf;
597*5c51f124SMoriah Waterland 	FILE *gr_ptr;
598*5c51f124SMoriah Waterland 
599*5c51f124SMoriah Waterland 	if ((instroot = get_install_root()) != NULL) {
600*5c51f124SMoriah Waterland 		if ((buf = (char *)malloc(strlen(instroot) +
601*5c51f124SMoriah Waterland 			strlen(GROUP) + 1)) == NULL) {
602*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
603*5c51f124SMoriah Waterland 				pkg_gt(ERR_MALLOC), "clgrnam()",
604*5c51f124SMoriah Waterland 				strlen(instroot) + strlen(GROUP), "buf");
605*5c51f124SMoriah Waterland 		}
606*5c51f124SMoriah Waterland 		(void) sprintf(buf, "%s%s", instroot, GROUP);
607*5c51f124SMoriah Waterland 		if ((gr_ptr = fopen(buf, "r")) == NULL) {
608*5c51f124SMoriah Waterland 			free(buf);
609*5c51f124SMoriah Waterland 			return (NULL);
610*5c51f124SMoriah Waterland 		} else {
611*5c51f124SMoriah Waterland 			while ((gr = fgetgrent(gr_ptr)) != NULL) {
612*5c51f124SMoriah Waterland 				if (strcmp(gr->gr_name, nam) == 0) {
613*5c51f124SMoriah Waterland 					break;
614*5c51f124SMoriah Waterland 				}
615*5c51f124SMoriah Waterland 			}
616*5c51f124SMoriah Waterland 		}
617*5c51f124SMoriah Waterland 		free(buf);
618*5c51f124SMoriah Waterland 		(void) fclose(gr_ptr);
619*5c51f124SMoriah Waterland 		return (gr);
620*5c51f124SMoriah Waterland 	} else {
621*5c51f124SMoriah Waterland 		return (NULL);
622*5c51f124SMoriah Waterland 	}
623*5c51f124SMoriah Waterland }
624*5c51f124SMoriah Waterland 
625*5c51f124SMoriah Waterland /*
626*5c51f124SMoriah Waterland  * Check the client's etc/passwd file for the user name
627*5c51f124SMoriah Waterland  *
628*5c51f124SMoriah Waterland  * returns a pointer to the passwd structure if the passwd is found
629*5c51f124SMoriah Waterland  * returns NULL if not found
630*5c51f124SMoriah Waterland  */
631*5c51f124SMoriah Waterland struct passwd *
632*5c51f124SMoriah Waterland clpwnam(char *nam)
633*5c51f124SMoriah Waterland {
634*5c51f124SMoriah Waterland 	struct passwd *pw;
635*5c51f124SMoriah Waterland 	char *instroot, *buf;
636*5c51f124SMoriah Waterland 	FILE *pw_ptr;
637*5c51f124SMoriah Waterland 
638*5c51f124SMoriah Waterland 	if ((instroot = get_install_root()) != NULL) {
639*5c51f124SMoriah Waterland 		if ((buf = (char *)malloc(strlen(instroot) +
640*5c51f124SMoriah Waterland 			strlen(PASSWD) + 1)) == NULL) {
641*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
642*5c51f124SMoriah Waterland 				pkg_gt(ERR_MALLOC), "clpwnam()",
643*5c51f124SMoriah Waterland 				strlen(instroot) + strlen(PASSWD), "buf");
644*5c51f124SMoriah Waterland 		}
645*5c51f124SMoriah Waterland 		(void) sprintf(buf, "%s%s", instroot, PASSWD);
646*5c51f124SMoriah Waterland 		if ((pw_ptr = fopen(buf, "r")) == NULL) {
647*5c51f124SMoriah Waterland 			free(buf);
648*5c51f124SMoriah Waterland 			return (NULL);
649*5c51f124SMoriah Waterland 		} else {
650*5c51f124SMoriah Waterland 			while ((pw = fgetpwent(pw_ptr)) != NULL) {
651*5c51f124SMoriah Waterland 				if (strcmp(pw->pw_name, nam) == 0) {
652*5c51f124SMoriah Waterland 					break;
653*5c51f124SMoriah Waterland 				}
654*5c51f124SMoriah Waterland 			}
655*5c51f124SMoriah Waterland 		}
656*5c51f124SMoriah Waterland 		free(buf);
657*5c51f124SMoriah Waterland 		(void) fclose(pw_ptr);
658*5c51f124SMoriah Waterland 		return (pw);
659*5c51f124SMoriah Waterland 	} else {
660*5c51f124SMoriah Waterland 		return (NULL);
661*5c51f124SMoriah Waterland 	}
662*5c51f124SMoriah Waterland }
663*5c51f124SMoriah Waterland 
664*5c51f124SMoriah Waterland /*
665*5c51f124SMoriah Waterland  * Check the client's etc/group file for the group id
666*5c51f124SMoriah Waterland  *
667*5c51f124SMoriah Waterland  * returns a pointer to the group structure if the group id is found
668*5c51f124SMoriah Waterland  * returns NULL if not found
669*5c51f124SMoriah Waterland  */
670*5c51f124SMoriah Waterland struct group *
671*5c51f124SMoriah Waterland clgrgid(gid_t gid)
672*5c51f124SMoriah Waterland {
673*5c51f124SMoriah Waterland 	struct group *gr;
674*5c51f124SMoriah Waterland 	char *instroot, *buf;
675*5c51f124SMoriah Waterland 	FILE *gr_ptr;
676*5c51f124SMoriah Waterland 
677*5c51f124SMoriah Waterland 	if ((instroot = get_install_root()) != NULL) {
678*5c51f124SMoriah Waterland 		if ((buf = (char *)malloc(strlen(instroot) +
679*5c51f124SMoriah Waterland 			strlen(GROUP) + 1)) == NULL) {
680*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
681*5c51f124SMoriah Waterland 				pkg_gt(ERR_MALLOC), "clgrgid()",
682*5c51f124SMoriah Waterland 				strlen(instroot) + strlen(GROUP), "buf");
683*5c51f124SMoriah Waterland 		}
684*5c51f124SMoriah Waterland 		(void) sprintf(buf, "%s%s", instroot, GROUP);
685*5c51f124SMoriah Waterland 		if ((gr_ptr = fopen(buf, "r")) == NULL) {
686*5c51f124SMoriah Waterland 			free(buf);
687*5c51f124SMoriah Waterland 			return (NULL);
688*5c51f124SMoriah Waterland 		} else {
689*5c51f124SMoriah Waterland 			while ((gr = fgetgrent(gr_ptr)) != NULL) {
690*5c51f124SMoriah Waterland 				if (gr->gr_gid == gid) {
691*5c51f124SMoriah Waterland 					break;
692*5c51f124SMoriah Waterland 				}
693*5c51f124SMoriah Waterland 			}
694*5c51f124SMoriah Waterland 		}
695*5c51f124SMoriah Waterland 		free(buf);
696*5c51f124SMoriah Waterland 		(void) fclose(gr_ptr);
697*5c51f124SMoriah Waterland 		return (gr);
698*5c51f124SMoriah Waterland 	} else {
699*5c51f124SMoriah Waterland 		return (NULL);
700*5c51f124SMoriah Waterland 	}
701*5c51f124SMoriah Waterland }
702*5c51f124SMoriah Waterland 
703*5c51f124SMoriah Waterland /*
704*5c51f124SMoriah Waterland  * Check the client's etc/passwd file for the user id
705*5c51f124SMoriah Waterland  *
706*5c51f124SMoriah Waterland  * returns a pointer to the passwd structure if the user id is found
707*5c51f124SMoriah Waterland  * returns NULL if not found
708*5c51f124SMoriah Waterland  */
709*5c51f124SMoriah Waterland struct passwd *
710*5c51f124SMoriah Waterland clpwuid(uid_t uid)
711*5c51f124SMoriah Waterland {
712*5c51f124SMoriah Waterland 	struct passwd *pw;
713*5c51f124SMoriah Waterland 	char *instroot, *buf;
714*5c51f124SMoriah Waterland 	FILE *pw_ptr;
715*5c51f124SMoriah Waterland 
716*5c51f124SMoriah Waterland 	if ((instroot = get_install_root()) != NULL) {
717*5c51f124SMoriah Waterland 		if ((buf = (char *)malloc(strlen(instroot) +
718*5c51f124SMoriah Waterland 			strlen(PASSWD) + 1)) == NULL) {
719*5c51f124SMoriah Waterland 			(void) fprintf(stderr,
720*5c51f124SMoriah Waterland 				pkg_gt(ERR_MALLOC), "clpwuid()",
721*5c51f124SMoriah Waterland 				strlen(instroot) + strlen(PASSWD), "buf");
722*5c51f124SMoriah Waterland 		}
723*5c51f124SMoriah Waterland 		(void) sprintf(buf, "%s%s", instroot, PASSWD);
724*5c51f124SMoriah Waterland 		if ((pw_ptr = fopen(buf, "r")) == NULL) {
725*5c51f124SMoriah Waterland 			free(buf);
726*5c51f124SMoriah Waterland 			return (NULL);
727*5c51f124SMoriah Waterland 		} else {
728*5c51f124SMoriah Waterland 			while ((pw = fgetpwent(pw_ptr)) != NULL) {
729*5c51f124SMoriah Waterland 				if (pw->pw_uid == uid) {
730*5c51f124SMoriah Waterland 					break;
731*5c51f124SMoriah Waterland 				}
732*5c51f124SMoriah Waterland 			}
733*5c51f124SMoriah Waterland 		}
734*5c51f124SMoriah Waterland 		free(buf);
735*5c51f124SMoriah Waterland 		(void) fclose(pw_ptr);
736*5c51f124SMoriah Waterland 		return (pw);
737*5c51f124SMoriah Waterland 	} else {
738*5c51f124SMoriah Waterland 		return (NULL);
739*5c51f124SMoriah Waterland 	}
740*5c51f124SMoriah Waterland }
741