1*7369SJulian.Pullen@Sun.COM /*
2*7369SJulian.Pullen@Sun.COM  * CDDL HEADER START
3*7369SJulian.Pullen@Sun.COM  *
4*7369SJulian.Pullen@Sun.COM  * The contents of this file are subject to the terms of the
5*7369SJulian.Pullen@Sun.COM  * Common Development and Distribution License (the "License").
6*7369SJulian.Pullen@Sun.COM  * You may not use this file except in compliance with the License.
7*7369SJulian.Pullen@Sun.COM  *
8*7369SJulian.Pullen@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*7369SJulian.Pullen@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*7369SJulian.Pullen@Sun.COM  * See the License for the specific language governing permissions
11*7369SJulian.Pullen@Sun.COM  * and limitations under the License.
12*7369SJulian.Pullen@Sun.COM  *
13*7369SJulian.Pullen@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*7369SJulian.Pullen@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*7369SJulian.Pullen@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*7369SJulian.Pullen@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*7369SJulian.Pullen@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*7369SJulian.Pullen@Sun.COM  *
19*7369SJulian.Pullen@Sun.COM  * CDDL HEADER END
20*7369SJulian.Pullen@Sun.COM  */
21*7369SJulian.Pullen@Sun.COM 
22*7369SJulian.Pullen@Sun.COM /*
23*7369SJulian.Pullen@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24*7369SJulian.Pullen@Sun.COM  * Use is subject to license terms.
25*7369SJulian.Pullen@Sun.COM  */
26*7369SJulian.Pullen@Sun.COM 
27*7369SJulian.Pullen@Sun.COM /*
28*7369SJulian.Pullen@Sun.COM  * Windows to Solaris Identity Mapping
29*7369SJulian.Pullen@Sun.COM  * This module provides the libidmap idmap_cache.
30*7369SJulian.Pullen@Sun.COM  */
31*7369SJulian.Pullen@Sun.COM 
32*7369SJulian.Pullen@Sun.COM 
33*7369SJulian.Pullen@Sun.COM #include <sys/types.h>
34*7369SJulian.Pullen@Sun.COM #include <sys/avl.h>
35*7369SJulian.Pullen@Sun.COM #include <assert.h>
36*7369SJulian.Pullen@Sun.COM #include <pthread.h>
37*7369SJulian.Pullen@Sun.COM #include <strings.h>
38*7369SJulian.Pullen@Sun.COM #include <sys/idmap.h>
39*7369SJulian.Pullen@Sun.COM #include <stddef.h>
40*7369SJulian.Pullen@Sun.COM #include <stdlib.h>
41*7369SJulian.Pullen@Sun.COM #include "idmap_prot.h"
42*7369SJulian.Pullen@Sun.COM #include "idmap_cache.h"
43*7369SJulian.Pullen@Sun.COM 
44*7369SJulian.Pullen@Sun.COM 
45*7369SJulian.Pullen@Sun.COM /*
46*7369SJulian.Pullen@Sun.COM  * Internal definitions and functions
47*7369SJulian.Pullen@Sun.COM  */
48*7369SJulian.Pullen@Sun.COM 
49*7369SJulian.Pullen@Sun.COM #define	CACHE_UID_TRIGGER_SIZE	4096
50*7369SJulian.Pullen@Sun.COM #define	CACHE_GID_TRIGGER_SIZE	2048
51*7369SJulian.Pullen@Sun.COM #define	CACHE_UID_GID_TRIGGER_SIZE \
52*7369SJulian.Pullen@Sun.COM 	(CACHE_UID_TRIGGER_SIZE + CACHE_GID_TRIGGER_SIZE)
53*7369SJulian.Pullen@Sun.COM 
54*7369SJulian.Pullen@Sun.COM 
55*7369SJulian.Pullen@Sun.COM #define	UNDEF_UID	((uid_t)-1)
56*7369SJulian.Pullen@Sun.COM #define	UNDEF_GID	((gid_t)-1)
57*7369SJulian.Pullen@Sun.COM #define	UNDEF_ISUSER	(-1)
58*7369SJulian.Pullen@Sun.COM 
59*7369SJulian.Pullen@Sun.COM #define	CACHE_PURGE_INTERVAL	(60 * 3)
60*7369SJulian.Pullen@Sun.COM #define	CACHE_TTL		(60 * 10)
61*7369SJulian.Pullen@Sun.COM 
62*7369SJulian.Pullen@Sun.COM 
63*7369SJulian.Pullen@Sun.COM 
64*7369SJulian.Pullen@Sun.COM 
65*7369SJulian.Pullen@Sun.COM #define	list_insert(head, ele)\
66*7369SJulian.Pullen@Sun.COM 	do {\
67*7369SJulian.Pullen@Sun.COM 		(ele)->flink = (head)->flink;\
68*7369SJulian.Pullen@Sun.COM 		(head)->flink = (ele);\
69*7369SJulian.Pullen@Sun.COM 		(ele)->blink = (ele)->flink->blink;\
70*7369SJulian.Pullen@Sun.COM 		(ele)->flink->blink = (ele);\
71*7369SJulian.Pullen@Sun.COM 	} while (0)
72*7369SJulian.Pullen@Sun.COM 
73*7369SJulian.Pullen@Sun.COM 
74*7369SJulian.Pullen@Sun.COM 
75*7369SJulian.Pullen@Sun.COM #define	list_remove(ele)\
76*7369SJulian.Pullen@Sun.COM 	do {\
77*7369SJulian.Pullen@Sun.COM 		(ele)->flink->blink = (ele)->blink;\
78*7369SJulian.Pullen@Sun.COM 		(ele)->blink->flink = (ele)->flink;\
79*7369SJulian.Pullen@Sun.COM 	} while (0)
80*7369SJulian.Pullen@Sun.COM 
81*7369SJulian.Pullen@Sun.COM 
82*7369SJulian.Pullen@Sun.COM #define	list_move(head, ele) \
83*7369SJulian.Pullen@Sun.COM 	do {\
84*7369SJulian.Pullen@Sun.COM 		if ((head)->flink != (ele)) {\
85*7369SJulian.Pullen@Sun.COM 			list_remove(ele);\
86*7369SJulian.Pullen@Sun.COM 			list_insert(head, ele);\
87*7369SJulian.Pullen@Sun.COM 		}\
88*7369SJulian.Pullen@Sun.COM 	} while (0)
89*7369SJulian.Pullen@Sun.COM 
90*7369SJulian.Pullen@Sun.COM typedef struct sid2uid_gid {
91*7369SJulian.Pullen@Sun.COM 	avl_node_t		avl_link;
92*7369SJulian.Pullen@Sun.COM 	struct sid2uid_gid	*flink;
93*7369SJulian.Pullen@Sun.COM 	struct sid2uid_gid	*blink;
94*7369SJulian.Pullen@Sun.COM 	const char 		*sid_prefix;
95*7369SJulian.Pullen@Sun.COM 	idmap_rid_t		rid;
96*7369SJulian.Pullen@Sun.COM 	uid_t			uid;
97*7369SJulian.Pullen@Sun.COM 	time_t			uid_ttl;
98*7369SJulian.Pullen@Sun.COM 	gid_t			gid;
99*7369SJulian.Pullen@Sun.COM 	time_t			gid_ttl;
100*7369SJulian.Pullen@Sun.COM 	int			is_user;
101*7369SJulian.Pullen@Sun.COM } sid2uid_gid_t;
102*7369SJulian.Pullen@Sun.COM 
103*7369SJulian.Pullen@Sun.COM 
104*7369SJulian.Pullen@Sun.COM typedef struct pid2sid_winname {
105*7369SJulian.Pullen@Sun.COM 	avl_node_t		avl_link;
106*7369SJulian.Pullen@Sun.COM 	struct pid2sid_winname	*flink;
107*7369SJulian.Pullen@Sun.COM 	struct pid2sid_winname	*blink;
108*7369SJulian.Pullen@Sun.COM 	uid_t			pid;
109*7369SJulian.Pullen@Sun.COM 	const char		*sid_prefix;
110*7369SJulian.Pullen@Sun.COM 	idmap_rid_t		rid;
111*7369SJulian.Pullen@Sun.COM 	time_t			sid_ttl;
112*7369SJulian.Pullen@Sun.COM 	const char		*winname;
113*7369SJulian.Pullen@Sun.COM 	const char		*windomain;
114*7369SJulian.Pullen@Sun.COM 	time_t			winname_ttl;
115*7369SJulian.Pullen@Sun.COM } pid2sid_winname_t;
116*7369SJulian.Pullen@Sun.COM 
117*7369SJulian.Pullen@Sun.COM 
118*7369SJulian.Pullen@Sun.COM typedef struct winname2uid_gid {
119*7369SJulian.Pullen@Sun.COM 	avl_node_t		avl_link;
120*7369SJulian.Pullen@Sun.COM 	struct winname2uid_gid	*flink;
121*7369SJulian.Pullen@Sun.COM 	struct winname2uid_gid	*blink;
122*7369SJulian.Pullen@Sun.COM 	const char		*winname;
123*7369SJulian.Pullen@Sun.COM 	const char		*windomain;
124*7369SJulian.Pullen@Sun.COM 	uid_t			uid;
125*7369SJulian.Pullen@Sun.COM 	time_t			uid_ttl;
126*7369SJulian.Pullen@Sun.COM 	gid_t			gid;
127*7369SJulian.Pullen@Sun.COM 	time_t			gid_ttl;
128*7369SJulian.Pullen@Sun.COM } winname2uid_gid_t;
129*7369SJulian.Pullen@Sun.COM 
130*7369SJulian.Pullen@Sun.COM 
131*7369SJulian.Pullen@Sun.COM typedef struct sid2uid_gid_cache {
132*7369SJulian.Pullen@Sun.COM 	avl_tree_t		tree;
133*7369SJulian.Pullen@Sun.COM 	pthread_mutex_t		mutex;
134*7369SJulian.Pullen@Sun.COM 	sid2uid_gid_t		head;
135*7369SJulian.Pullen@Sun.COM 	sid2uid_gid_t		*prev;
136*7369SJulian.Pullen@Sun.COM 	time_t			purge_time;
137*7369SJulian.Pullen@Sun.COM 	int			uid_num;
138*7369SJulian.Pullen@Sun.COM 	int			gid_num;
139*7369SJulian.Pullen@Sun.COM 	int			pid_num;
140*7369SJulian.Pullen@Sun.COM } sid2uid_gid_cache_t;
141*7369SJulian.Pullen@Sun.COM 
142*7369SJulian.Pullen@Sun.COM 
143*7369SJulian.Pullen@Sun.COM typedef struct pid2sid_winname_cache {
144*7369SJulian.Pullen@Sun.COM 	avl_tree_t		tree;
145*7369SJulian.Pullen@Sun.COM 	pthread_mutex_t		mutex;
146*7369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	head;
147*7369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	*prev;
148*7369SJulian.Pullen@Sun.COM 	time_t			purge_time;
149*7369SJulian.Pullen@Sun.COM 	int			sid_num;
150*7369SJulian.Pullen@Sun.COM 	int			winname_num;
151*7369SJulian.Pullen@Sun.COM } pid2sid_winname_cache_t;
152*7369SJulian.Pullen@Sun.COM 
153*7369SJulian.Pullen@Sun.COM 
154*7369SJulian.Pullen@Sun.COM 
155*7369SJulian.Pullen@Sun.COM typedef struct winname2uid_gid_cache {
156*7369SJulian.Pullen@Sun.COM 	avl_tree_t		tree;
157*7369SJulian.Pullen@Sun.COM 	pthread_mutex_t		mutex;
158*7369SJulian.Pullen@Sun.COM 	winname2uid_gid_t	head;
159*7369SJulian.Pullen@Sun.COM 	winname2uid_gid_t	*prev;
160*7369SJulian.Pullen@Sun.COM 	time_t			purge_time;
161*7369SJulian.Pullen@Sun.COM 	int			uid_num;
162*7369SJulian.Pullen@Sun.COM 	int			gid_num;
163*7369SJulian.Pullen@Sun.COM } winname2uid_gid_cache_t;
164*7369SJulian.Pullen@Sun.COM 
165*7369SJulian.Pullen@Sun.COM 
166*7369SJulian.Pullen@Sun.COM typedef struct idmap_cache {
167*7369SJulian.Pullen@Sun.COM 	sid2uid_gid_cache_t	sid2uid_gid;
168*7369SJulian.Pullen@Sun.COM 	pid2sid_winname_cache_t	uid2sid_winname;
169*7369SJulian.Pullen@Sun.COM 	pid2sid_winname_cache_t	gid2sid_winname;
170*7369SJulian.Pullen@Sun.COM 	winname2uid_gid_cache_t	winname2uid_gid;
171*7369SJulian.Pullen@Sun.COM } idmap_cache_t;
172*7369SJulian.Pullen@Sun.COM 
173*7369SJulian.Pullen@Sun.COM 
174*7369SJulian.Pullen@Sun.COM 
175*7369SJulian.Pullen@Sun.COM typedef int (*avl_comp_fn)(const void*, const void*);
176*7369SJulian.Pullen@Sun.COM 
177*7369SJulian.Pullen@Sun.COM static void
178*7369SJulian.Pullen@Sun.COM idmap_purge_sid2uid_gid_cache(sid2uid_gid_cache_t *cache, size_t limit);
179*7369SJulian.Pullen@Sun.COM 
180*7369SJulian.Pullen@Sun.COM static void
181*7369SJulian.Pullen@Sun.COM idmap_purge_pid2sid_winname_cache(pid2sid_winname_cache_t *cache, size_t limit);
182*7369SJulian.Pullen@Sun.COM 
183*7369SJulian.Pullen@Sun.COM static void
184*7369SJulian.Pullen@Sun.COM idmap_purge_winname2uid_gid_cache(winname2uid_gid_cache_t *avl, size_t limit);
185*7369SJulian.Pullen@Sun.COM 
186*7369SJulian.Pullen@Sun.COM /*
187*7369SJulian.Pullen@Sun.COM  * Global structures
188*7369SJulian.Pullen@Sun.COM  */
189*7369SJulian.Pullen@Sun.COM 
190*7369SJulian.Pullen@Sun.COM static idmap_cache_t idmap_cache;
191*7369SJulian.Pullen@Sun.COM 
192*7369SJulian.Pullen@Sun.COM 
193*7369SJulian.Pullen@Sun.COM 
194*7369SJulian.Pullen@Sun.COM 
195*7369SJulian.Pullen@Sun.COM static int
196*7369SJulian.Pullen@Sun.COM idmap_compare_sid(const sid2uid_gid_t *entry1, const sid2uid_gid_t *entry2)
197*7369SJulian.Pullen@Sun.COM {
198*7369SJulian.Pullen@Sun.COM 	int64_t comp = ((int64_t)entry2->rid) - ((int64_t)entry1->rid);
199*7369SJulian.Pullen@Sun.COM 
200*7369SJulian.Pullen@Sun.COM 	if (comp == 0)
201*7369SJulian.Pullen@Sun.COM 		comp = strcmp(entry2->sid_prefix, entry1->sid_prefix);
202*7369SJulian.Pullen@Sun.COM 
203*7369SJulian.Pullen@Sun.COM 	if (comp < 0)
204*7369SJulian.Pullen@Sun.COM 		comp = -1;
205*7369SJulian.Pullen@Sun.COM 	else if (comp > 0)
206*7369SJulian.Pullen@Sun.COM 		comp = 1;
207*7369SJulian.Pullen@Sun.COM 
208*7369SJulian.Pullen@Sun.COM 	return ((int)comp);
209*7369SJulian.Pullen@Sun.COM }
210*7369SJulian.Pullen@Sun.COM 
211*7369SJulian.Pullen@Sun.COM 
212*7369SJulian.Pullen@Sun.COM static int
213*7369SJulian.Pullen@Sun.COM idmap_compare_pid(const pid2sid_winname_t *entry1,
214*7369SJulian.Pullen@Sun.COM 			const pid2sid_winname_t *entry2)
215*7369SJulian.Pullen@Sun.COM {
216*7369SJulian.Pullen@Sun.COM 	if (entry2->pid > entry1->pid)
217*7369SJulian.Pullen@Sun.COM 		return (1);
218*7369SJulian.Pullen@Sun.COM 	if (entry2->pid < entry1->pid)
219*7369SJulian.Pullen@Sun.COM 		return (-1);
220*7369SJulian.Pullen@Sun.COM 	return (0);
221*7369SJulian.Pullen@Sun.COM }
222*7369SJulian.Pullen@Sun.COM 
223*7369SJulian.Pullen@Sun.COM 
224*7369SJulian.Pullen@Sun.COM static int
225*7369SJulian.Pullen@Sun.COM idmap_compare_winname(const winname2uid_gid_t *entry1,
226*7369SJulian.Pullen@Sun.COM 			const winname2uid_gid_t *entry2)
227*7369SJulian.Pullen@Sun.COM {
228*7369SJulian.Pullen@Sun.COM 	int comp;
229*7369SJulian.Pullen@Sun.COM 
230*7369SJulian.Pullen@Sun.COM 	comp = strcasecmp(entry2->winname, entry1->winname);
231*7369SJulian.Pullen@Sun.COM 	if (comp == 0) {
232*7369SJulian.Pullen@Sun.COM 		if (entry2->windomain == NULL && entry1->windomain == NULL)
233*7369SJulian.Pullen@Sun.COM 			return (0);
234*7369SJulian.Pullen@Sun.COM 		if (entry1->windomain == NULL)
235*7369SJulian.Pullen@Sun.COM 			return (1);
236*7369SJulian.Pullen@Sun.COM 		if (entry2->windomain == NULL)
237*7369SJulian.Pullen@Sun.COM 			return (-1);
238*7369SJulian.Pullen@Sun.COM 
239*7369SJulian.Pullen@Sun.COM 		comp = strcasecmp(entry2->windomain, entry1->windomain);
240*7369SJulian.Pullen@Sun.COM 	}
241*7369SJulian.Pullen@Sun.COM 
242*7369SJulian.Pullen@Sun.COM 	if (comp < 0)
243*7369SJulian.Pullen@Sun.COM 		comp = -1;
244*7369SJulian.Pullen@Sun.COM 	else if (comp > 0)
245*7369SJulian.Pullen@Sun.COM 		comp = 1;
246*7369SJulian.Pullen@Sun.COM 
247*7369SJulian.Pullen@Sun.COM 	return (comp);
248*7369SJulian.Pullen@Sun.COM }
249*7369SJulian.Pullen@Sun.COM 
250*7369SJulian.Pullen@Sun.COM /*
251*7369SJulian.Pullen@Sun.COM  * Routine to update item
252*7369SJulian.Pullen@Sun.COM  *
253*7369SJulian.Pullen@Sun.COM  * Returns:	0 Success
254*7369SJulian.Pullen@Sun.COM  *		-1 Error
255*7369SJulian.Pullen@Sun.COM  */
256*7369SJulian.Pullen@Sun.COM static int
257*7369SJulian.Pullen@Sun.COM update_str(const char **item, const char *str)
258*7369SJulian.Pullen@Sun.COM {
259*7369SJulian.Pullen@Sun.COM 	char *tmp;
260*7369SJulian.Pullen@Sun.COM 
261*7369SJulian.Pullen@Sun.COM 	if (*item != NULL && str != NULL) {
262*7369SJulian.Pullen@Sun.COM 		if (strcmp(*item, str) != 0) {
263*7369SJulian.Pullen@Sun.COM 			if ((tmp = strdup(str)) == NULL)
264*7369SJulian.Pullen@Sun.COM 				return (-1);
265*7369SJulian.Pullen@Sun.COM 			free((char *)*item);
266*7369SJulian.Pullen@Sun.COM 			*item = tmp;
267*7369SJulian.Pullen@Sun.COM 		}
268*7369SJulian.Pullen@Sun.COM 	} else if (str != NULL) {
269*7369SJulian.Pullen@Sun.COM 		/* *item is NULL */
270*7369SJulian.Pullen@Sun.COM 		if ((*item = strdup(str)) == NULL)
271*7369SJulian.Pullen@Sun.COM 			return (-1);
272*7369SJulian.Pullen@Sun.COM 	} else if (*item != NULL) {
273*7369SJulian.Pullen@Sun.COM 		/* str is NULL */
274*7369SJulian.Pullen@Sun.COM 		free((char *)*item);
275*7369SJulian.Pullen@Sun.COM 		*item = NULL;
276*7369SJulian.Pullen@Sun.COM 	}
277*7369SJulian.Pullen@Sun.COM 
278*7369SJulian.Pullen@Sun.COM 	return (0);
279*7369SJulian.Pullen@Sun.COM }
280*7369SJulian.Pullen@Sun.COM 
281*7369SJulian.Pullen@Sun.COM /*
282*7369SJulian.Pullen@Sun.COM  * The Cache is initialized on loading libidmap.so
283*7369SJulian.Pullen@Sun.COM  */
284*7369SJulian.Pullen@Sun.COM #pragma	init(idmap_cache_create)
285*7369SJulian.Pullen@Sun.COM 
286*7369SJulian.Pullen@Sun.COM void
287*7369SJulian.Pullen@Sun.COM idmap_cache_create(void)
288*7369SJulian.Pullen@Sun.COM {
289*7369SJulian.Pullen@Sun.COM 	avl_create(&idmap_cache.sid2uid_gid.tree,
290*7369SJulian.Pullen@Sun.COM 	    (avl_comp_fn)idmap_compare_sid, sizeof (sid2uid_gid_t),
291*7369SJulian.Pullen@Sun.COM 	    offsetof(sid2uid_gid_t, avl_link));
292*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_init(&idmap_cache.sid2uid_gid.mutex, NULL);
293*7369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.head.flink = &idmap_cache.sid2uid_gid.head;
294*7369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.head.blink = &idmap_cache.sid2uid_gid.head;
295*7369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.prev = NULL;
296*7369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.purge_time = 0;
297*7369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.uid_num = 0;
298*7369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.gid_num = 0;
299*7369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.pid_num = 0;
300*7369SJulian.Pullen@Sun.COM 
301*7369SJulian.Pullen@Sun.COM 	avl_create(&idmap_cache.uid2sid_winname.tree,
302*7369SJulian.Pullen@Sun.COM 	    (avl_comp_fn)idmap_compare_pid, sizeof (pid2sid_winname_t),
303*7369SJulian.Pullen@Sun.COM 	    offsetof(pid2sid_winname_t, avl_link));
304*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_init(&idmap_cache.uid2sid_winname.mutex, NULL);
305*7369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.head.flink =
306*7369SJulian.Pullen@Sun.COM 	    &idmap_cache.uid2sid_winname.head;
307*7369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.head.blink =
308*7369SJulian.Pullen@Sun.COM 	    &idmap_cache.uid2sid_winname.head;
309*7369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.prev = NULL;
310*7369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.purge_time = 0;
311*7369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.sid_num = 0;
312*7369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.winname_num = 0;
313*7369SJulian.Pullen@Sun.COM 
314*7369SJulian.Pullen@Sun.COM 	avl_create(&idmap_cache.gid2sid_winname.tree,
315*7369SJulian.Pullen@Sun.COM 	    (avl_comp_fn)idmap_compare_pid, sizeof (pid2sid_winname_t),
316*7369SJulian.Pullen@Sun.COM 	    offsetof(pid2sid_winname_t, avl_link));
317*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_init(&idmap_cache.gid2sid_winname.mutex, NULL);
318*7369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.head.flink =
319*7369SJulian.Pullen@Sun.COM 	    &idmap_cache.gid2sid_winname.head;
320*7369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.head.blink =
321*7369SJulian.Pullen@Sun.COM 	    &idmap_cache.gid2sid_winname.head;
322*7369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.prev = NULL;
323*7369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.purge_time = 0;
324*7369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.sid_num = 0;
325*7369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.winname_num = 0;
326*7369SJulian.Pullen@Sun.COM 
327*7369SJulian.Pullen@Sun.COM 	avl_create(&idmap_cache.winname2uid_gid.tree,
328*7369SJulian.Pullen@Sun.COM 	    (avl_comp_fn)idmap_compare_winname, sizeof (winname2uid_gid_t),
329*7369SJulian.Pullen@Sun.COM 	    offsetof(winname2uid_gid_t, avl_link));
330*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_init(&idmap_cache.winname2uid_gid.mutex, NULL);
331*7369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.head.flink =
332*7369SJulian.Pullen@Sun.COM 	    &idmap_cache.winname2uid_gid.head;
333*7369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.head.blink =
334*7369SJulian.Pullen@Sun.COM 	    &idmap_cache.winname2uid_gid.head;
335*7369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.prev = NULL;
336*7369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.purge_time = 0;
337*7369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.uid_num = 0;
338*7369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.gid_num = 0;
339*7369SJulian.Pullen@Sun.COM }
340*7369SJulian.Pullen@Sun.COM 
341*7369SJulian.Pullen@Sun.COM 
342*7369SJulian.Pullen@Sun.COM void
343*7369SJulian.Pullen@Sun.COM idmap_cache_purge(void)
344*7369SJulian.Pullen@Sun.COM {
345*7369SJulian.Pullen@Sun.COM 	sid2uid_gid_t		*sid2uid_gid;
346*7369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	*uid2sid_winname;
347*7369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	*gid2sid_winname;
348*7369SJulian.Pullen@Sun.COM 	winname2uid_gid_t	*winname2uid_gid;
349*7369SJulian.Pullen@Sun.COM 	void			*cookie;
350*7369SJulian.Pullen@Sun.COM 
351*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
352*7369SJulian.Pullen@Sun.COM 	cookie = NULL;
353*7369SJulian.Pullen@Sun.COM 	while ((sid2uid_gid = avl_destroy_nodes(
354*7369SJulian.Pullen@Sun.COM 	    &idmap_cache.sid2uid_gid.tree, &cookie)) != NULL) {
355*7369SJulian.Pullen@Sun.COM 		free((char *)sid2uid_gid->sid_prefix);
356*7369SJulian.Pullen@Sun.COM 		free(sid2uid_gid);
357*7369SJulian.Pullen@Sun.COM 	}
358*7369SJulian.Pullen@Sun.COM 	avl_destroy(&idmap_cache.sid2uid_gid.tree);
359*7369SJulian.Pullen@Sun.COM 	avl_create(&idmap_cache.sid2uid_gid.tree,
360*7369SJulian.Pullen@Sun.COM 	    (avl_comp_fn)idmap_compare_sid, sizeof (sid2uid_gid_t),
361*7369SJulian.Pullen@Sun.COM 	    offsetof(sid2uid_gid_t, avl_link));
362*7369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.head.flink = &idmap_cache.sid2uid_gid.head;
363*7369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.head.blink = &idmap_cache.sid2uid_gid.head;
364*7369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.prev = NULL;
365*7369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.purge_time = 0;
366*7369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.uid_num = 0;
367*7369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.gid_num = 0;
368*7369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.pid_num = 0;
369*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
370*7369SJulian.Pullen@Sun.COM 
371*7369SJulian.Pullen@Sun.COM 
372*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
373*7369SJulian.Pullen@Sun.COM 	cookie = NULL;
374*7369SJulian.Pullen@Sun.COM 	while ((uid2sid_winname = avl_destroy_nodes(
375*7369SJulian.Pullen@Sun.COM 	    &idmap_cache.uid2sid_winname.tree, &cookie)) != NULL) {
376*7369SJulian.Pullen@Sun.COM 		free((char *)uid2sid_winname->sid_prefix);
377*7369SJulian.Pullen@Sun.COM 		free((char *)uid2sid_winname->winname);
378*7369SJulian.Pullen@Sun.COM 		if (uid2sid_winname->windomain != NULL)
379*7369SJulian.Pullen@Sun.COM 			free((char *)uid2sid_winname->windomain);
380*7369SJulian.Pullen@Sun.COM 		free(uid2sid_winname);
381*7369SJulian.Pullen@Sun.COM 	}
382*7369SJulian.Pullen@Sun.COM 	avl_destroy(&idmap_cache.uid2sid_winname.tree);
383*7369SJulian.Pullen@Sun.COM 	avl_create(&idmap_cache.uid2sid_winname.tree,
384*7369SJulian.Pullen@Sun.COM 	    (avl_comp_fn)idmap_compare_pid, sizeof (pid2sid_winname_t),
385*7369SJulian.Pullen@Sun.COM 	    offsetof(pid2sid_winname_t, avl_link));
386*7369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.head.flink =
387*7369SJulian.Pullen@Sun.COM 	    &idmap_cache.uid2sid_winname.head;
388*7369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.head.blink =
389*7369SJulian.Pullen@Sun.COM 	    &idmap_cache.uid2sid_winname.head;
390*7369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.prev = NULL;
391*7369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.purge_time = 0;
392*7369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.sid_num = 0;
393*7369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.winname_num = 0;
394*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
395*7369SJulian.Pullen@Sun.COM 
396*7369SJulian.Pullen@Sun.COM 
397*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
398*7369SJulian.Pullen@Sun.COM 	cookie = NULL;
399*7369SJulian.Pullen@Sun.COM 	while ((gid2sid_winname = avl_destroy_nodes(
400*7369SJulian.Pullen@Sun.COM 	    &idmap_cache.gid2sid_winname.tree, &cookie)) != NULL) {
401*7369SJulian.Pullen@Sun.COM 		free((char *)gid2sid_winname->sid_prefix);
402*7369SJulian.Pullen@Sun.COM 		free((char *)gid2sid_winname->winname);
403*7369SJulian.Pullen@Sun.COM 		if (gid2sid_winname->windomain != NULL)
404*7369SJulian.Pullen@Sun.COM 			free((char *)gid2sid_winname->windomain);
405*7369SJulian.Pullen@Sun.COM 		free(gid2sid_winname);
406*7369SJulian.Pullen@Sun.COM 	}
407*7369SJulian.Pullen@Sun.COM 	avl_destroy(&idmap_cache.gid2sid_winname.tree);
408*7369SJulian.Pullen@Sun.COM 	avl_create(&idmap_cache.gid2sid_winname.tree,
409*7369SJulian.Pullen@Sun.COM 	    (avl_comp_fn)idmap_compare_pid, sizeof (pid2sid_winname_t),
410*7369SJulian.Pullen@Sun.COM 	    offsetof(pid2sid_winname_t, avl_link));
411*7369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.head.flink =
412*7369SJulian.Pullen@Sun.COM 	    &idmap_cache.gid2sid_winname.head;
413*7369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.head.blink =
414*7369SJulian.Pullen@Sun.COM 	    &idmap_cache.gid2sid_winname.head;
415*7369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.prev = NULL;
416*7369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.purge_time = 0;
417*7369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.sid_num = 0;
418*7369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.winname_num = 0;
419*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
420*7369SJulian.Pullen@Sun.COM 
421*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
422*7369SJulian.Pullen@Sun.COM 	cookie = NULL;
423*7369SJulian.Pullen@Sun.COM 	while ((winname2uid_gid = avl_destroy_nodes(
424*7369SJulian.Pullen@Sun.COM 	    &idmap_cache.winname2uid_gid.tree, &cookie)) != NULL) {
425*7369SJulian.Pullen@Sun.COM 		free((char *)winname2uid_gid->winname);
426*7369SJulian.Pullen@Sun.COM 		if (winname2uid_gid->windomain)
427*7369SJulian.Pullen@Sun.COM 			free((char *)winname2uid_gid->windomain);
428*7369SJulian.Pullen@Sun.COM 		free(winname2uid_gid);
429*7369SJulian.Pullen@Sun.COM 	}
430*7369SJulian.Pullen@Sun.COM 	avl_destroy(&idmap_cache.winname2uid_gid.tree);
431*7369SJulian.Pullen@Sun.COM 	avl_create(&idmap_cache.winname2uid_gid.tree,
432*7369SJulian.Pullen@Sun.COM 	    (avl_comp_fn)idmap_compare_winname, sizeof (winname2uid_gid_t),
433*7369SJulian.Pullen@Sun.COM 	    offsetof(winname2uid_gid_t, avl_link));
434*7369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.head.flink =
435*7369SJulian.Pullen@Sun.COM 	    &idmap_cache.winname2uid_gid.head;
436*7369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.head.blink =
437*7369SJulian.Pullen@Sun.COM 	    &idmap_cache.winname2uid_gid.head;
438*7369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.prev = NULL;
439*7369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.purge_time = 0;
440*7369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.uid_num = 0;
441*7369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.gid_num = 0;
442*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
443*7369SJulian.Pullen@Sun.COM 
444*7369SJulian.Pullen@Sun.COM }
445*7369SJulian.Pullen@Sun.COM 
446*7369SJulian.Pullen@Sun.COM 
447*7369SJulian.Pullen@Sun.COM void
448*7369SJulian.Pullen@Sun.COM idmap_cache_get_data(size_t *uidbysid, size_t *gidbysid,
449*7369SJulian.Pullen@Sun.COM 	size_t *pidbysid, size_t *sidbyuid, size_t *sidbygid,
450*7369SJulian.Pullen@Sun.COM 	size_t *winnamebyuid, size_t *winnamebygid,
451*7369SJulian.Pullen@Sun.COM 	size_t *uidbywinname, size_t *gidbywinname)
452*7369SJulian.Pullen@Sun.COM {
453*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
454*7369SJulian.Pullen@Sun.COM 	*uidbysid = idmap_cache.sid2uid_gid.uid_num;
455*7369SJulian.Pullen@Sun.COM 	*gidbysid = idmap_cache.sid2uid_gid.gid_num;
456*7369SJulian.Pullen@Sun.COM 	*pidbysid = idmap_cache.sid2uid_gid.pid_num;
457*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
458*7369SJulian.Pullen@Sun.COM 
459*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
460*7369SJulian.Pullen@Sun.COM 	*sidbyuid = idmap_cache.uid2sid_winname.sid_num;
461*7369SJulian.Pullen@Sun.COM 	*winnamebyuid = idmap_cache.uid2sid_winname.winname_num;
462*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
463*7369SJulian.Pullen@Sun.COM 
464*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
465*7369SJulian.Pullen@Sun.COM 	*sidbygid = idmap_cache.gid2sid_winname.sid_num;
466*7369SJulian.Pullen@Sun.COM 	*winnamebygid = idmap_cache.gid2sid_winname.winname_num;
467*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
468*7369SJulian.Pullen@Sun.COM 
469*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
470*7369SJulian.Pullen@Sun.COM 	*uidbywinname = idmap_cache.winname2uid_gid.uid_num;
471*7369SJulian.Pullen@Sun.COM 	*gidbywinname = idmap_cache.winname2uid_gid.gid_num;
472*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
473*7369SJulian.Pullen@Sun.COM }
474*7369SJulian.Pullen@Sun.COM 
475*7369SJulian.Pullen@Sun.COM 
476*7369SJulian.Pullen@Sun.COM idmap_stat
477*7369SJulian.Pullen@Sun.COM idmap_cache_lookup_uidbysid(const char *sid_prefix,
478*7369SJulian.Pullen@Sun.COM 			idmap_rid_t rid, uid_t *uid)
479*7369SJulian.Pullen@Sun.COM {
480*7369SJulian.Pullen@Sun.COM 	sid2uid_gid_t	entry;
481*7369SJulian.Pullen@Sun.COM 	sid2uid_gid_t	*result;
482*7369SJulian.Pullen@Sun.COM 	avl_index_t	where;
483*7369SJulian.Pullen@Sun.COM 	int		status = IDMAP_ERR_NOMAPPING;
484*7369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
485*7369SJulian.Pullen@Sun.COM 
486*7369SJulian.Pullen@Sun.COM 	entry.sid_prefix = sid_prefix;
487*7369SJulian.Pullen@Sun.COM 	entry.rid = rid;
488*7369SJulian.Pullen@Sun.COM 
489*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
490*7369SJulian.Pullen@Sun.COM 
491*7369SJulian.Pullen@Sun.COM 	result = avl_find(&idmap_cache.sid2uid_gid.tree, &entry, &where);
492*7369SJulian.Pullen@Sun.COM 	if (result != NULL) {
493*7369SJulian.Pullen@Sun.COM 		list_move(&idmap_cache.sid2uid_gid.head, result);
494*7369SJulian.Pullen@Sun.COM 		if (result->uid != UNDEF_UID && result->uid_ttl > now) {
495*7369SJulian.Pullen@Sun.COM 			*uid = result->uid;
496*7369SJulian.Pullen@Sun.COM 			status = IDMAP_SUCCESS;
497*7369SJulian.Pullen@Sun.COM 		}
498*7369SJulian.Pullen@Sun.COM 	}
499*7369SJulian.Pullen@Sun.COM 
500*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
501*7369SJulian.Pullen@Sun.COM 
502*7369SJulian.Pullen@Sun.COM 	return (status);
503*7369SJulian.Pullen@Sun.COM }
504*7369SJulian.Pullen@Sun.COM 
505*7369SJulian.Pullen@Sun.COM 
506*7369SJulian.Pullen@Sun.COM 
507*7369SJulian.Pullen@Sun.COM idmap_stat
508*7369SJulian.Pullen@Sun.COM idmap_cache_lookup_gidbysid(const char *sid_prefix,
509*7369SJulian.Pullen@Sun.COM 			idmap_rid_t rid, gid_t *gid)
510*7369SJulian.Pullen@Sun.COM {
511*7369SJulian.Pullen@Sun.COM 	sid2uid_gid_t	entry;
512*7369SJulian.Pullen@Sun.COM 	sid2uid_gid_t	*result;
513*7369SJulian.Pullen@Sun.COM 	avl_index_t	where;
514*7369SJulian.Pullen@Sun.COM 	int		status = IDMAP_ERR_NOMAPPING;
515*7369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
516*7369SJulian.Pullen@Sun.COM 
517*7369SJulian.Pullen@Sun.COM 	entry.sid_prefix = sid_prefix;
518*7369SJulian.Pullen@Sun.COM 	entry.rid = rid;
519*7369SJulian.Pullen@Sun.COM 
520*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
521*7369SJulian.Pullen@Sun.COM 
522*7369SJulian.Pullen@Sun.COM 	result = avl_find(&idmap_cache.sid2uid_gid.tree, &entry, &where);
523*7369SJulian.Pullen@Sun.COM 	if (result != NULL) {
524*7369SJulian.Pullen@Sun.COM 		list_move(&idmap_cache.sid2uid_gid.head, result);
525*7369SJulian.Pullen@Sun.COM 		if (result->gid != UNDEF_GID && result->gid_ttl > now) {
526*7369SJulian.Pullen@Sun.COM 			*gid = result->gid;
527*7369SJulian.Pullen@Sun.COM 			status = IDMAP_SUCCESS;
528*7369SJulian.Pullen@Sun.COM 		}
529*7369SJulian.Pullen@Sun.COM 	}
530*7369SJulian.Pullen@Sun.COM 
531*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
532*7369SJulian.Pullen@Sun.COM 
533*7369SJulian.Pullen@Sun.COM 	return (status);
534*7369SJulian.Pullen@Sun.COM }
535*7369SJulian.Pullen@Sun.COM 
536*7369SJulian.Pullen@Sun.COM 
537*7369SJulian.Pullen@Sun.COM 
538*7369SJulian.Pullen@Sun.COM 
539*7369SJulian.Pullen@Sun.COM idmap_stat
540*7369SJulian.Pullen@Sun.COM idmap_cache_lookup_pidbysid(const char *sid_prefix,
541*7369SJulian.Pullen@Sun.COM 			idmap_rid_t rid, uid_t *pid, int *is_user)
542*7369SJulian.Pullen@Sun.COM {
543*7369SJulian.Pullen@Sun.COM 	sid2uid_gid_t	entry;
544*7369SJulian.Pullen@Sun.COM 	sid2uid_gid_t	*result;
545*7369SJulian.Pullen@Sun.COM 	avl_index_t	where;
546*7369SJulian.Pullen@Sun.COM 	int		status = IDMAP_ERR_NOMAPPING;
547*7369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
548*7369SJulian.Pullen@Sun.COM 
549*7369SJulian.Pullen@Sun.COM 	entry.sid_prefix = sid_prefix;
550*7369SJulian.Pullen@Sun.COM 	entry.rid = rid;
551*7369SJulian.Pullen@Sun.COM 
552*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
553*7369SJulian.Pullen@Sun.COM 
554*7369SJulian.Pullen@Sun.COM 	result = avl_find(&idmap_cache.sid2uid_gid.tree, &entry, &where);
555*7369SJulian.Pullen@Sun.COM 	if (result != NULL) {
556*7369SJulian.Pullen@Sun.COM 		list_move(&idmap_cache.sid2uid_gid.head, result);
557*7369SJulian.Pullen@Sun.COM 		if (result->is_user != UNDEF_ISUSER) {
558*7369SJulian.Pullen@Sun.COM 			*is_user = result->is_user;
559*7369SJulian.Pullen@Sun.COM 			if (result->is_user && result->uid_ttl > now) {
560*7369SJulian.Pullen@Sun.COM 				*pid = result->uid;
561*7369SJulian.Pullen@Sun.COM 				status = IDMAP_SUCCESS;
562*7369SJulian.Pullen@Sun.COM 			} else if (!result->is_user && result->gid_ttl > now) {
563*7369SJulian.Pullen@Sun.COM 				*pid = result->gid;
564*7369SJulian.Pullen@Sun.COM 				status = IDMAP_SUCCESS;
565*7369SJulian.Pullen@Sun.COM 			}
566*7369SJulian.Pullen@Sun.COM 		}
567*7369SJulian.Pullen@Sun.COM 	}
568*7369SJulian.Pullen@Sun.COM 
569*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
570*7369SJulian.Pullen@Sun.COM 
571*7369SJulian.Pullen@Sun.COM 	return (status);
572*7369SJulian.Pullen@Sun.COM }
573*7369SJulian.Pullen@Sun.COM 
574*7369SJulian.Pullen@Sun.COM 
575*7369SJulian.Pullen@Sun.COM 
576*7369SJulian.Pullen@Sun.COM idmap_stat
577*7369SJulian.Pullen@Sun.COM idmap_cache_lookup_sidbyuid(char **sid_prefix,
578*7369SJulian.Pullen@Sun.COM 			idmap_rid_t *rid, uid_t uid)
579*7369SJulian.Pullen@Sun.COM {
580*7369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	entry;
581*7369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	*result;
582*7369SJulian.Pullen@Sun.COM 	avl_index_t	where;
583*7369SJulian.Pullen@Sun.COM 	int		status = IDMAP_ERR_NOMAPPING;
584*7369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
585*7369SJulian.Pullen@Sun.COM 
586*7369SJulian.Pullen@Sun.COM 	entry.pid = uid;
587*7369SJulian.Pullen@Sun.COM 
588*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
589*7369SJulian.Pullen@Sun.COM 
590*7369SJulian.Pullen@Sun.COM 	result = avl_find(&idmap_cache.uid2sid_winname.tree, &entry, &where);
591*7369SJulian.Pullen@Sun.COM 	if (result != NULL) {
592*7369SJulian.Pullen@Sun.COM 		list_move(&idmap_cache.uid2sid_winname.head, result);
593*7369SJulian.Pullen@Sun.COM 		if (result->sid_ttl > now) {
594*7369SJulian.Pullen@Sun.COM 			*rid = result->rid;
595*7369SJulian.Pullen@Sun.COM 			*sid_prefix = strdup(result->sid_prefix);
596*7369SJulian.Pullen@Sun.COM 			if (*sid_prefix != NULL)
597*7369SJulian.Pullen@Sun.COM 				status = IDMAP_SUCCESS;
598*7369SJulian.Pullen@Sun.COM 			else
599*7369SJulian.Pullen@Sun.COM 				status = IDMAP_ERR_MEMORY;
600*7369SJulian.Pullen@Sun.COM 		}
601*7369SJulian.Pullen@Sun.COM 	}
602*7369SJulian.Pullen@Sun.COM 
603*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
604*7369SJulian.Pullen@Sun.COM 
605*7369SJulian.Pullen@Sun.COM 	return (status);
606*7369SJulian.Pullen@Sun.COM }
607*7369SJulian.Pullen@Sun.COM 
608*7369SJulian.Pullen@Sun.COM idmap_stat
609*7369SJulian.Pullen@Sun.COM idmap_cache_lookup_sidbygid(char **sid_prefix,
610*7369SJulian.Pullen@Sun.COM 			idmap_rid_t *rid, gid_t gid)
611*7369SJulian.Pullen@Sun.COM {
612*7369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	entry;
613*7369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	*result;
614*7369SJulian.Pullen@Sun.COM 	avl_index_t	where;
615*7369SJulian.Pullen@Sun.COM 	int		status = IDMAP_ERR_NOMAPPING;
616*7369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
617*7369SJulian.Pullen@Sun.COM 
618*7369SJulian.Pullen@Sun.COM 	entry.pid = gid;
619*7369SJulian.Pullen@Sun.COM 
620*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
621*7369SJulian.Pullen@Sun.COM 
622*7369SJulian.Pullen@Sun.COM 	result = avl_find(&idmap_cache.gid2sid_winname.tree, &entry, &where);
623*7369SJulian.Pullen@Sun.COM 	if (result != NULL) {
624*7369SJulian.Pullen@Sun.COM 		list_move(&idmap_cache.gid2sid_winname.head, result);
625*7369SJulian.Pullen@Sun.COM 		if (result->sid_ttl > now) {
626*7369SJulian.Pullen@Sun.COM 			*rid = result->rid;
627*7369SJulian.Pullen@Sun.COM 			*sid_prefix = strdup(result->sid_prefix);
628*7369SJulian.Pullen@Sun.COM 			if (*sid_prefix != NULL)
629*7369SJulian.Pullen@Sun.COM 				status = IDMAP_SUCCESS;
630*7369SJulian.Pullen@Sun.COM 			else
631*7369SJulian.Pullen@Sun.COM 				status = IDMAP_ERR_MEMORY;
632*7369SJulian.Pullen@Sun.COM 		}
633*7369SJulian.Pullen@Sun.COM 	}
634*7369SJulian.Pullen@Sun.COM 
635*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
636*7369SJulian.Pullen@Sun.COM 
637*7369SJulian.Pullen@Sun.COM 	return (status);
638*7369SJulian.Pullen@Sun.COM }
639*7369SJulian.Pullen@Sun.COM 
640*7369SJulian.Pullen@Sun.COM 
641*7369SJulian.Pullen@Sun.COM idmap_stat
642*7369SJulian.Pullen@Sun.COM idmap_cache_lookup_winnamebyuid(char **name, char **domain, uid_t uid)
643*7369SJulian.Pullen@Sun.COM {
644*7369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	entry;
645*7369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	*result;
646*7369SJulian.Pullen@Sun.COM 	avl_index_t	where;
647*7369SJulian.Pullen@Sun.COM 	int		status = IDMAP_ERR_NOMAPPING;
648*7369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
649*7369SJulian.Pullen@Sun.COM 
650*7369SJulian.Pullen@Sun.COM 	entry.pid = uid;
651*7369SJulian.Pullen@Sun.COM 
652*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
653*7369SJulian.Pullen@Sun.COM 
654*7369SJulian.Pullen@Sun.COM 	result = avl_find(&idmap_cache.uid2sid_winname.tree, &entry, &where);
655*7369SJulian.Pullen@Sun.COM 	if (result != NULL) {
656*7369SJulian.Pullen@Sun.COM 		list_move(&idmap_cache.uid2sid_winname.head, result);
657*7369SJulian.Pullen@Sun.COM 		if (result->winname_ttl > now) {
658*7369SJulian.Pullen@Sun.COM 			*name = strdup(result->winname);
659*7369SJulian.Pullen@Sun.COM 			if (*name != NULL) {
660*7369SJulian.Pullen@Sun.COM 				if (domain != NULL) {
661*7369SJulian.Pullen@Sun.COM 					if (result->windomain != NULL) {
662*7369SJulian.Pullen@Sun.COM 						*domain =
663*7369SJulian.Pullen@Sun.COM 						    strdup(result->windomain);
664*7369SJulian.Pullen@Sun.COM 						if (*domain != NULL)
665*7369SJulian.Pullen@Sun.COM 							status = IDMAP_SUCCESS;
666*7369SJulian.Pullen@Sun.COM 						else
667*7369SJulian.Pullen@Sun.COM 							status =
668*7369SJulian.Pullen@Sun.COM 							    IDMAP_ERR_MEMORY;
669*7369SJulian.Pullen@Sun.COM 					} else {
670*7369SJulian.Pullen@Sun.COM 						*domain = NULL;
671*7369SJulian.Pullen@Sun.COM 						status = IDMAP_SUCCESS;
672*7369SJulian.Pullen@Sun.COM 					}
673*7369SJulian.Pullen@Sun.COM 				} else
674*7369SJulian.Pullen@Sun.COM 					status = IDMAP_SUCCESS;
675*7369SJulian.Pullen@Sun.COM 			} else
676*7369SJulian.Pullen@Sun.COM 				status = IDMAP_ERR_MEMORY;
677*7369SJulian.Pullen@Sun.COM 		}
678*7369SJulian.Pullen@Sun.COM 	}
679*7369SJulian.Pullen@Sun.COM 
680*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
681*7369SJulian.Pullen@Sun.COM 
682*7369SJulian.Pullen@Sun.COM 	return (status);
683*7369SJulian.Pullen@Sun.COM }
684*7369SJulian.Pullen@Sun.COM 
685*7369SJulian.Pullen@Sun.COM 
686*7369SJulian.Pullen@Sun.COM idmap_stat
687*7369SJulian.Pullen@Sun.COM idmap_cache_lookup_winnamebygid(char **name, char **domain, gid_t gid)
688*7369SJulian.Pullen@Sun.COM {
689*7369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	entry;
690*7369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	*result;
691*7369SJulian.Pullen@Sun.COM 	avl_index_t	where;
692*7369SJulian.Pullen@Sun.COM 	int		status = IDMAP_ERR_NOMAPPING;
693*7369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
694*7369SJulian.Pullen@Sun.COM 
695*7369SJulian.Pullen@Sun.COM 	entry.pid = gid;
696*7369SJulian.Pullen@Sun.COM 
697*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
698*7369SJulian.Pullen@Sun.COM 
699*7369SJulian.Pullen@Sun.COM 	result = avl_find(&idmap_cache.gid2sid_winname.tree, &entry, &where);
700*7369SJulian.Pullen@Sun.COM 	if (result != NULL) {
701*7369SJulian.Pullen@Sun.COM 		list_move(&idmap_cache.gid2sid_winname.head, result);
702*7369SJulian.Pullen@Sun.COM 		if (result->winname_ttl > now) {
703*7369SJulian.Pullen@Sun.COM 			*name = strdup(result->winname);
704*7369SJulian.Pullen@Sun.COM 			if (*name != NULL) {
705*7369SJulian.Pullen@Sun.COM 				if (domain != NULL) {
706*7369SJulian.Pullen@Sun.COM 					if (result->windomain != NULL) {
707*7369SJulian.Pullen@Sun.COM 						*domain =
708*7369SJulian.Pullen@Sun.COM 						    strdup(result->windomain);
709*7369SJulian.Pullen@Sun.COM 						if (*domain != NULL)
710*7369SJulian.Pullen@Sun.COM 							status = IDMAP_SUCCESS;
711*7369SJulian.Pullen@Sun.COM 						else
712*7369SJulian.Pullen@Sun.COM 							status =
713*7369SJulian.Pullen@Sun.COM 							    IDMAP_ERR_MEMORY;
714*7369SJulian.Pullen@Sun.COM 					} else {
715*7369SJulian.Pullen@Sun.COM 						*domain = NULL;
716*7369SJulian.Pullen@Sun.COM 						status = IDMAP_SUCCESS;
717*7369SJulian.Pullen@Sun.COM 					}
718*7369SJulian.Pullen@Sun.COM 				} else
719*7369SJulian.Pullen@Sun.COM 					status = IDMAP_SUCCESS;
720*7369SJulian.Pullen@Sun.COM 			} else
721*7369SJulian.Pullen@Sun.COM 				status = IDMAP_ERR_MEMORY;
722*7369SJulian.Pullen@Sun.COM 		}
723*7369SJulian.Pullen@Sun.COM 	}
724*7369SJulian.Pullen@Sun.COM 
725*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
726*7369SJulian.Pullen@Sun.COM 
727*7369SJulian.Pullen@Sun.COM 	return (status);
728*7369SJulian.Pullen@Sun.COM }
729*7369SJulian.Pullen@Sun.COM 
730*7369SJulian.Pullen@Sun.COM 
731*7369SJulian.Pullen@Sun.COM idmap_stat
732*7369SJulian.Pullen@Sun.COM idmap_cache_lookup_uidbywinname(const char *name, const char *domain,
733*7369SJulian.Pullen@Sun.COM 			uid_t *uid)
734*7369SJulian.Pullen@Sun.COM {
735*7369SJulian.Pullen@Sun.COM 	winname2uid_gid_t	entry;
736*7369SJulian.Pullen@Sun.COM 	winname2uid_gid_t	*result;
737*7369SJulian.Pullen@Sun.COM 	avl_index_t	where;
738*7369SJulian.Pullen@Sun.COM 	int		status = IDMAP_ERR_NOMAPPING;
739*7369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
740*7369SJulian.Pullen@Sun.COM 
741*7369SJulian.Pullen@Sun.COM 	entry.winname = name;
742*7369SJulian.Pullen@Sun.COM 	entry.windomain = domain;
743*7369SJulian.Pullen@Sun.COM 
744*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
745*7369SJulian.Pullen@Sun.COM 
746*7369SJulian.Pullen@Sun.COM 	result = avl_find(&idmap_cache.winname2uid_gid.tree, &entry, &where);
747*7369SJulian.Pullen@Sun.COM 	if (result != NULL) {
748*7369SJulian.Pullen@Sun.COM 		list_move(&idmap_cache.winname2uid_gid.head, result);
749*7369SJulian.Pullen@Sun.COM 		if (result->uid != UNDEF_UID && result->uid_ttl > now) {
750*7369SJulian.Pullen@Sun.COM 			*uid = result->uid;
751*7369SJulian.Pullen@Sun.COM 			status = IDMAP_SUCCESS;
752*7369SJulian.Pullen@Sun.COM 		}
753*7369SJulian.Pullen@Sun.COM 	}
754*7369SJulian.Pullen@Sun.COM 
755*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
756*7369SJulian.Pullen@Sun.COM 
757*7369SJulian.Pullen@Sun.COM 	return (status);
758*7369SJulian.Pullen@Sun.COM }
759*7369SJulian.Pullen@Sun.COM 
760*7369SJulian.Pullen@Sun.COM 
761*7369SJulian.Pullen@Sun.COM idmap_stat
762*7369SJulian.Pullen@Sun.COM idmap_cache_lookup_gidbywinname(const char *name, const char *domain,
763*7369SJulian.Pullen@Sun.COM 			gid_t *gid)
764*7369SJulian.Pullen@Sun.COM {
765*7369SJulian.Pullen@Sun.COM 	winname2uid_gid_t	entry;
766*7369SJulian.Pullen@Sun.COM 	winname2uid_gid_t	*result;
767*7369SJulian.Pullen@Sun.COM 	avl_index_t	where;
768*7369SJulian.Pullen@Sun.COM 	int		status = IDMAP_ERR_NOMAPPING;
769*7369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
770*7369SJulian.Pullen@Sun.COM 
771*7369SJulian.Pullen@Sun.COM 	entry.winname = name;
772*7369SJulian.Pullen@Sun.COM 	entry.windomain = domain;
773*7369SJulian.Pullen@Sun.COM 
774*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
775*7369SJulian.Pullen@Sun.COM 
776*7369SJulian.Pullen@Sun.COM 	result = avl_find(&idmap_cache.winname2uid_gid.tree, &entry, &where);
777*7369SJulian.Pullen@Sun.COM 	if (result != NULL) {
778*7369SJulian.Pullen@Sun.COM 		list_move(&idmap_cache.winname2uid_gid.head, result);
779*7369SJulian.Pullen@Sun.COM 		if (result->gid != UNDEF_GID && result->gid_ttl > now) {
780*7369SJulian.Pullen@Sun.COM 			*gid = result->gid;
781*7369SJulian.Pullen@Sun.COM 			status = IDMAP_SUCCESS;
782*7369SJulian.Pullen@Sun.COM 		}
783*7369SJulian.Pullen@Sun.COM 	}
784*7369SJulian.Pullen@Sun.COM 
785*7369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
786*7369SJulian.Pullen@Sun.COM 
787*7369SJulian.Pullen@Sun.COM 	return (status);
788*7369SJulian.Pullen@Sun.COM }
789*7369SJulian.Pullen@Sun.COM 
790*7369SJulian.Pullen@Sun.COM 
791*7369SJulian.Pullen@Sun.COM void
792*7369SJulian.Pullen@Sun.COM idmap_cache_add_sid2uid(const char *sid_prefix,
793*7369SJulian.Pullen@Sun.COM 			idmap_rid_t rid, uid_t uid, int direction)
794*7369SJulian.Pullen@Sun.COM 
795*7369SJulian.Pullen@Sun.COM {
796*7369SJulian.Pullen@Sun.COM 	avl_index_t	where;
797*7369SJulian.Pullen@Sun.COM 	time_t		ttl = CACHE_TTL + time(NULL);
798*7369SJulian.Pullen@Sun.COM 
799*7369SJulian.Pullen@Sun.COM 
800*7369SJulian.Pullen@Sun.COM 	if (direction == IDMAP_DIRECTION_BI ||
801*7369SJulian.Pullen@Sun.COM 	    direction == IDMAP_DIRECTION_W2U) {
802*7369SJulian.Pullen@Sun.COM 		sid2uid_gid_t	find;
803*7369SJulian.Pullen@Sun.COM 		sid2uid_gid_t	*result;
804*7369SJulian.Pullen@Sun.COM 		sid2uid_gid_t	*new;
805*7369SJulian.Pullen@Sun.COM 
806*7369SJulian.Pullen@Sun.COM 		find.sid_prefix = sid_prefix;
807*7369SJulian.Pullen@Sun.COM 		find.rid = rid;
808*7369SJulian.Pullen@Sun.COM 
809*7369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
810*7369SJulian.Pullen@Sun.COM 		result = avl_find(&idmap_cache.sid2uid_gid.tree, &find, &where);
811*7369SJulian.Pullen@Sun.COM 
812*7369SJulian.Pullen@Sun.COM 		if (result) {
813*7369SJulian.Pullen@Sun.COM 			if (result->uid_ttl == 0)
814*7369SJulian.Pullen@Sun.COM 				idmap_cache.sid2uid_gid.uid_num++;
815*7369SJulian.Pullen@Sun.COM 			result->uid = uid;
816*7369SJulian.Pullen@Sun.COM 			result->uid_ttl = ttl;
817*7369SJulian.Pullen@Sun.COM 		} else {
818*7369SJulian.Pullen@Sun.COM 			new = malloc(sizeof (sid2uid_gid_t));
819*7369SJulian.Pullen@Sun.COM 			if (new == NULL)
820*7369SJulian.Pullen@Sun.COM 				goto exit_sid2uid_gid;
821*7369SJulian.Pullen@Sun.COM 			new->sid_prefix = strdup(sid_prefix);
822*7369SJulian.Pullen@Sun.COM 			if (new->sid_prefix == NULL) {
823*7369SJulian.Pullen@Sun.COM 				free(new);
824*7369SJulian.Pullen@Sun.COM 				goto exit_sid2uid_gid;
825*7369SJulian.Pullen@Sun.COM 			}
826*7369SJulian.Pullen@Sun.COM 			new->rid = rid;
827*7369SJulian.Pullen@Sun.COM 			new->uid = uid;
828*7369SJulian.Pullen@Sun.COM 			new->uid_ttl = ttl;
829*7369SJulian.Pullen@Sun.COM 			new->gid = UNDEF_GID;
830*7369SJulian.Pullen@Sun.COM 			new->gid_ttl = 0;
831*7369SJulian.Pullen@Sun.COM 			new->is_user = UNDEF_ISUSER; /* Unknown */
832*7369SJulian.Pullen@Sun.COM 			idmap_cache.sid2uid_gid.uid_num++;
833*7369SJulian.Pullen@Sun.COM 
834*7369SJulian.Pullen@Sun.COM 			list_insert(&idmap_cache.sid2uid_gid.head, new);
835*7369SJulian.Pullen@Sun.COM 			avl_insert(&idmap_cache.sid2uid_gid.tree, new, where);
836*7369SJulian.Pullen@Sun.COM 		}
837*7369SJulian.Pullen@Sun.COM 		if ((avl_numnodes(&idmap_cache.sid2uid_gid.tree) >
838*7369SJulian.Pullen@Sun.COM 		    CACHE_UID_GID_TRIGGER_SIZE) &&
839*7369SJulian.Pullen@Sun.COM 		    (idmap_cache.sid2uid_gid.purge_time + CACHE_PURGE_INTERVAL <
840*7369SJulian.Pullen@Sun.COM 		    time(NULL)))
841*7369SJulian.Pullen@Sun.COM 			idmap_purge_sid2uid_gid_cache(&idmap_cache.sid2uid_gid,
842*7369SJulian.Pullen@Sun.COM 			    CACHE_UID_GID_TRIGGER_SIZE);
843*7369SJulian.Pullen@Sun.COM 
844*7369SJulian.Pullen@Sun.COM exit_sid2uid_gid:
845*7369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
846*7369SJulian.Pullen@Sun.COM 	}
847*7369SJulian.Pullen@Sun.COM 
848*7369SJulian.Pullen@Sun.COM 	if (direction == IDMAP_DIRECTION_BI ||
849*7369SJulian.Pullen@Sun.COM 	    direction == IDMAP_DIRECTION_U2W) {
850*7369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	find;
851*7369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	*result;
852*7369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	*new;
853*7369SJulian.Pullen@Sun.COM 
854*7369SJulian.Pullen@Sun.COM 		find.pid = uid;
855*7369SJulian.Pullen@Sun.COM 
856*7369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
857*7369SJulian.Pullen@Sun.COM 		result = avl_find(&idmap_cache.uid2sid_winname.tree, &find,
858*7369SJulian.Pullen@Sun.COM 		    &where);
859*7369SJulian.Pullen@Sun.COM 
860*7369SJulian.Pullen@Sun.COM 		if (result) {
861*7369SJulian.Pullen@Sun.COM 			if (update_str(&result->sid_prefix, sid_prefix) != 0)
862*7369SJulian.Pullen@Sun.COM 				goto exit_pid2sid_winname;
863*7369SJulian.Pullen@Sun.COM 			if (result->sid_ttl == 0)
864*7369SJulian.Pullen@Sun.COM 					idmap_cache.uid2sid_winname.sid_num++;
865*7369SJulian.Pullen@Sun.COM 			result->rid = rid;
866*7369SJulian.Pullen@Sun.COM 			result->sid_ttl = ttl;
867*7369SJulian.Pullen@Sun.COM 		} else {
868*7369SJulian.Pullen@Sun.COM 			new = malloc(sizeof (pid2sid_winname_t));
869*7369SJulian.Pullen@Sun.COM 			if (new == NULL)
870*7369SJulian.Pullen@Sun.COM 				goto exit_pid2sid_winname;
871*7369SJulian.Pullen@Sun.COM 			new->pid = uid;
872*7369SJulian.Pullen@Sun.COM 			new->sid_prefix = strdup(sid_prefix);
873*7369SJulian.Pullen@Sun.COM 			if (new->sid_prefix == NULL) {
874*7369SJulian.Pullen@Sun.COM 				free(new);
875*7369SJulian.Pullen@Sun.COM 				goto exit_pid2sid_winname;
876*7369SJulian.Pullen@Sun.COM 			}
877*7369SJulian.Pullen@Sun.COM 			new->rid = rid;
878*7369SJulian.Pullen@Sun.COM 			new->sid_ttl = ttl;
879*7369SJulian.Pullen@Sun.COM 			new->winname = NULL;
880*7369SJulian.Pullen@Sun.COM 			new->windomain = NULL;
881*7369SJulian.Pullen@Sun.COM 			new->winname_ttl = 0;
882*7369SJulian.Pullen@Sun.COM 			idmap_cache.uid2sid_winname.sid_num ++;
883*7369SJulian.Pullen@Sun.COM 
884*7369SJulian.Pullen@Sun.COM 			list_insert(&idmap_cache.uid2sid_winname.head, new);
885*7369SJulian.Pullen@Sun.COM 			avl_insert(&idmap_cache.uid2sid_winname.tree, new,
886*7369SJulian.Pullen@Sun.COM 			    where);
887*7369SJulian.Pullen@Sun.COM 		}
888*7369SJulian.Pullen@Sun.COM 		if ((avl_numnodes(&idmap_cache.uid2sid_winname.tree) >
889*7369SJulian.Pullen@Sun.COM 		    CACHE_UID_TRIGGER_SIZE) &&
890*7369SJulian.Pullen@Sun.COM 		    (idmap_cache.uid2sid_winname.purge_time +
891*7369SJulian.Pullen@Sun.COM 		    CACHE_PURGE_INTERVAL < time(NULL)))
892*7369SJulian.Pullen@Sun.COM 			idmap_purge_pid2sid_winname_cache(
893*7369SJulian.Pullen@Sun.COM 			    &idmap_cache.uid2sid_winname,
894*7369SJulian.Pullen@Sun.COM 			    CACHE_UID_TRIGGER_SIZE);
895*7369SJulian.Pullen@Sun.COM 
896*7369SJulian.Pullen@Sun.COM 
897*7369SJulian.Pullen@Sun.COM exit_pid2sid_winname:
898*7369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
899*7369SJulian.Pullen@Sun.COM 	}
900*7369SJulian.Pullen@Sun.COM }
901*7369SJulian.Pullen@Sun.COM 
902*7369SJulian.Pullen@Sun.COM 
903*7369SJulian.Pullen@Sun.COM 
904*7369SJulian.Pullen@Sun.COM void
905*7369SJulian.Pullen@Sun.COM idmap_cache_add_sid2gid(const char *sid_prefix,
906*7369SJulian.Pullen@Sun.COM 			idmap_rid_t rid, gid_t gid, int direction)
907*7369SJulian.Pullen@Sun.COM {
908*7369SJulian.Pullen@Sun.COM 	avl_index_t	where;
909*7369SJulian.Pullen@Sun.COM 	time_t		ttl = CACHE_TTL + time(NULL);
910*7369SJulian.Pullen@Sun.COM 
911*7369SJulian.Pullen@Sun.COM 
912*7369SJulian.Pullen@Sun.COM 	if (direction == IDMAP_DIRECTION_BI ||
913*7369SJulian.Pullen@Sun.COM 	    direction == IDMAP_DIRECTION_W2U) {
914*7369SJulian.Pullen@Sun.COM 		sid2uid_gid_t	find;
915*7369SJulian.Pullen@Sun.COM 		sid2uid_gid_t	*result;
916*7369SJulian.Pullen@Sun.COM 		sid2uid_gid_t	*new;
917*7369SJulian.Pullen@Sun.COM 
918*7369SJulian.Pullen@Sun.COM 		find.sid_prefix = sid_prefix;
919*7369SJulian.Pullen@Sun.COM 		find.rid = rid;
920*7369SJulian.Pullen@Sun.COM 
921*7369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
922*7369SJulian.Pullen@Sun.COM 		result = avl_find(&idmap_cache.sid2uid_gid.tree, &find, &where);
923*7369SJulian.Pullen@Sun.COM 
924*7369SJulian.Pullen@Sun.COM 		if (result) {
925*7369SJulian.Pullen@Sun.COM 			if (result->gid_ttl == 0)
926*7369SJulian.Pullen@Sun.COM 				idmap_cache.sid2uid_gid.gid_num++;
927*7369SJulian.Pullen@Sun.COM 			result->gid = gid;
928*7369SJulian.Pullen@Sun.COM 			result->gid_ttl = ttl;
929*7369SJulian.Pullen@Sun.COM 		} else {
930*7369SJulian.Pullen@Sun.COM 			new = malloc(sizeof (sid2uid_gid_t));
931*7369SJulian.Pullen@Sun.COM 			if (new == NULL)
932*7369SJulian.Pullen@Sun.COM 				goto exit_sid2uid_gid;
933*7369SJulian.Pullen@Sun.COM 			new->sid_prefix = strdup(sid_prefix);
934*7369SJulian.Pullen@Sun.COM 			if (new->sid_prefix == NULL) {
935*7369SJulian.Pullen@Sun.COM 				free(new);
936*7369SJulian.Pullen@Sun.COM 				goto exit_sid2uid_gid;
937*7369SJulian.Pullen@Sun.COM 			}
938*7369SJulian.Pullen@Sun.COM 			new->rid = rid;
939*7369SJulian.Pullen@Sun.COM 			new->uid = UNDEF_UID;
940*7369SJulian.Pullen@Sun.COM 			new->uid_ttl = 0;
941*7369SJulian.Pullen@Sun.COM 			new->gid = gid;
942*7369SJulian.Pullen@Sun.COM 			new->gid_ttl = ttl;
943*7369SJulian.Pullen@Sun.COM 			new->is_user = UNDEF_ISUSER; /* Unknown */
944*7369SJulian.Pullen@Sun.COM 			idmap_cache.sid2uid_gid.gid_num++;
945*7369SJulian.Pullen@Sun.COM 
946*7369SJulian.Pullen@Sun.COM 			list_insert(&idmap_cache.sid2uid_gid.head, new);
947*7369SJulian.Pullen@Sun.COM 			avl_insert(&idmap_cache.sid2uid_gid.tree, new, where);
948*7369SJulian.Pullen@Sun.COM 		}
949*7369SJulian.Pullen@Sun.COM 		if ((avl_numnodes(&idmap_cache.sid2uid_gid.tree) >
950*7369SJulian.Pullen@Sun.COM 		    CACHE_UID_GID_TRIGGER_SIZE) &&
951*7369SJulian.Pullen@Sun.COM 		    (idmap_cache.sid2uid_gid.purge_time + CACHE_PURGE_INTERVAL <
952*7369SJulian.Pullen@Sun.COM 		    time(NULL)))
953*7369SJulian.Pullen@Sun.COM 			idmap_purge_sid2uid_gid_cache(&idmap_cache.sid2uid_gid,
954*7369SJulian.Pullen@Sun.COM 			    CACHE_UID_GID_TRIGGER_SIZE);
955*7369SJulian.Pullen@Sun.COM 
956*7369SJulian.Pullen@Sun.COM exit_sid2uid_gid:
957*7369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
958*7369SJulian.Pullen@Sun.COM 	}
959*7369SJulian.Pullen@Sun.COM 
960*7369SJulian.Pullen@Sun.COM 	if (direction == IDMAP_DIRECTION_BI ||
961*7369SJulian.Pullen@Sun.COM 	    direction == IDMAP_DIRECTION_U2W) {
962*7369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	find;
963*7369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	*result;
964*7369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	*new;
965*7369SJulian.Pullen@Sun.COM 
966*7369SJulian.Pullen@Sun.COM 		find.pid = gid;
967*7369SJulian.Pullen@Sun.COM 
968*7369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
969*7369SJulian.Pullen@Sun.COM 		result = avl_find(&idmap_cache.gid2sid_winname.tree, &find,
970*7369SJulian.Pullen@Sun.COM 		    &where);
971*7369SJulian.Pullen@Sun.COM 
972*7369SJulian.Pullen@Sun.COM 		if (result) {
973*7369SJulian.Pullen@Sun.COM 			if (update_str(&result->sid_prefix, sid_prefix) != 0)
974*7369SJulian.Pullen@Sun.COM 				goto  exit_gid2sid_winname;
975*7369SJulian.Pullen@Sun.COM 			if (result->sid_ttl == 0)
976*7369SJulian.Pullen@Sun.COM 				idmap_cache.gid2sid_winname.sid_num++;
977*7369SJulian.Pullen@Sun.COM 			result->rid = rid;
978*7369SJulian.Pullen@Sun.COM 			result->sid_ttl = ttl;
979*7369SJulian.Pullen@Sun.COM 		} else {
980*7369SJulian.Pullen@Sun.COM 			new = malloc(sizeof (pid2sid_winname_t));
981*7369SJulian.Pullen@Sun.COM 			if (new == NULL)
982*7369SJulian.Pullen@Sun.COM 				goto exit_gid2sid_winname;
983*7369SJulian.Pullen@Sun.COM 			new->sid_prefix = strdup(sid_prefix);
984*7369SJulian.Pullen@Sun.COM 			if (new->sid_prefix == NULL) {
985*7369SJulian.Pullen@Sun.COM 				free(new);
986*7369SJulian.Pullen@Sun.COM 				goto exit_gid2sid_winname;
987*7369SJulian.Pullen@Sun.COM 			}
988*7369SJulian.Pullen@Sun.COM 			new->rid = rid;
989*7369SJulian.Pullen@Sun.COM 			new->pid = gid;
990*7369SJulian.Pullen@Sun.COM 			new->sid_ttl = ttl;
991*7369SJulian.Pullen@Sun.COM 			new->winname = NULL;
992*7369SJulian.Pullen@Sun.COM 			new->windomain = NULL;
993*7369SJulian.Pullen@Sun.COM 			new->winname_ttl = 0;
994*7369SJulian.Pullen@Sun.COM 			idmap_cache.gid2sid_winname.sid_num++;
995*7369SJulian.Pullen@Sun.COM 
996*7369SJulian.Pullen@Sun.COM 			list_insert(&idmap_cache.gid2sid_winname.head, new);
997*7369SJulian.Pullen@Sun.COM 			avl_insert(&idmap_cache.gid2sid_winname.tree, new,
998*7369SJulian.Pullen@Sun.COM 			    where);
999*7369SJulian.Pullen@Sun.COM 		}
1000*7369SJulian.Pullen@Sun.COM 		if ((avl_numnodes(&idmap_cache.gid2sid_winname.tree) >
1001*7369SJulian.Pullen@Sun.COM 		    CACHE_GID_TRIGGER_SIZE) &&
1002*7369SJulian.Pullen@Sun.COM 		    (idmap_cache.gid2sid_winname.purge_time +
1003*7369SJulian.Pullen@Sun.COM 		    CACHE_PURGE_INTERVAL < time(NULL)))
1004*7369SJulian.Pullen@Sun.COM 			idmap_purge_pid2sid_winname_cache(
1005*7369SJulian.Pullen@Sun.COM 			    &idmap_cache.gid2sid_winname,
1006*7369SJulian.Pullen@Sun.COM 			    CACHE_GID_TRIGGER_SIZE);
1007*7369SJulian.Pullen@Sun.COM 
1008*7369SJulian.Pullen@Sun.COM exit_gid2sid_winname:
1009*7369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
1010*7369SJulian.Pullen@Sun.COM 	}
1011*7369SJulian.Pullen@Sun.COM }
1012*7369SJulian.Pullen@Sun.COM 
1013*7369SJulian.Pullen@Sun.COM 
1014*7369SJulian.Pullen@Sun.COM void
1015*7369SJulian.Pullen@Sun.COM idmap_cache_add_sid2pid(const char *sid_prefix,
1016*7369SJulian.Pullen@Sun.COM 			idmap_rid_t rid, uid_t pid, int is_user, int direction)
1017*7369SJulian.Pullen@Sun.COM {
1018*7369SJulian.Pullen@Sun.COM 	avl_index_t	where;
1019*7369SJulian.Pullen@Sun.COM 	time_t		ttl = CACHE_TTL + time(NULL);
1020*7369SJulian.Pullen@Sun.COM 
1021*7369SJulian.Pullen@Sun.COM 
1022*7369SJulian.Pullen@Sun.COM 	if (direction == IDMAP_DIRECTION_BI ||
1023*7369SJulian.Pullen@Sun.COM 	    direction == IDMAP_DIRECTION_W2U) {
1024*7369SJulian.Pullen@Sun.COM 		sid2uid_gid_t	find;
1025*7369SJulian.Pullen@Sun.COM 		sid2uid_gid_t	*result;
1026*7369SJulian.Pullen@Sun.COM 		sid2uid_gid_t	*new;
1027*7369SJulian.Pullen@Sun.COM 
1028*7369SJulian.Pullen@Sun.COM 		find.sid_prefix = sid_prefix;
1029*7369SJulian.Pullen@Sun.COM 		find.rid = rid;
1030*7369SJulian.Pullen@Sun.COM 
1031*7369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
1032*7369SJulian.Pullen@Sun.COM 		result = avl_find(&idmap_cache.sid2uid_gid.tree, &find, &where);
1033*7369SJulian.Pullen@Sun.COM 
1034*7369SJulian.Pullen@Sun.COM 		if (result) {
1035*7369SJulian.Pullen@Sun.COM 			if (result->is_user == UNDEF_ISUSER)
1036*7369SJulian.Pullen@Sun.COM 				idmap_cache.sid2uid_gid.pid_num++;
1037*7369SJulian.Pullen@Sun.COM 			result->is_user = is_user;
1038*7369SJulian.Pullen@Sun.COM 			if (is_user) {
1039*7369SJulian.Pullen@Sun.COM 				if (result->uid_ttl == 0)
1040*7369SJulian.Pullen@Sun.COM 					idmap_cache.sid2uid_gid.uid_num++;
1041*7369SJulian.Pullen@Sun.COM 				result->uid = pid;
1042*7369SJulian.Pullen@Sun.COM 				result->uid_ttl = ttl;
1043*7369SJulian.Pullen@Sun.COM 			} else {
1044*7369SJulian.Pullen@Sun.COM 				if (result->gid_ttl == 0)
1045*7369SJulian.Pullen@Sun.COM 					idmap_cache.sid2uid_gid.gid_num++;
1046*7369SJulian.Pullen@Sun.COM 				result->gid = pid;
1047*7369SJulian.Pullen@Sun.COM 				result->gid_ttl = ttl;
1048*7369SJulian.Pullen@Sun.COM 			}
1049*7369SJulian.Pullen@Sun.COM 		} else {
1050*7369SJulian.Pullen@Sun.COM 			new = malloc(sizeof (sid2uid_gid_t));
1051*7369SJulian.Pullen@Sun.COM 			if (new == NULL)
1052*7369SJulian.Pullen@Sun.COM 				goto exit_sid2uid_gid;
1053*7369SJulian.Pullen@Sun.COM 			new->sid_prefix = strdup(sid_prefix);
1054*7369SJulian.Pullen@Sun.COM 			if (new->sid_prefix == NULL) {
1055*7369SJulian.Pullen@Sun.COM 				free(new);
1056*7369SJulian.Pullen@Sun.COM 				goto exit_sid2uid_gid;
1057*7369SJulian.Pullen@Sun.COM 			}
1058*7369SJulian.Pullen@Sun.COM 			new->rid = rid;
1059*7369SJulian.Pullen@Sun.COM 			new->is_user = is_user;
1060*7369SJulian.Pullen@Sun.COM 			if (is_user) {
1061*7369SJulian.Pullen@Sun.COM 				new->uid = pid;
1062*7369SJulian.Pullen@Sun.COM 				new->uid_ttl = ttl;
1063*7369SJulian.Pullen@Sun.COM 				new->gid = UNDEF_GID;
1064*7369SJulian.Pullen@Sun.COM 				new->gid_ttl = 0;
1065*7369SJulian.Pullen@Sun.COM 				idmap_cache.sid2uid_gid.uid_num++;
1066*7369SJulian.Pullen@Sun.COM 			} else {
1067*7369SJulian.Pullen@Sun.COM 				new->uid = UNDEF_UID;
1068*7369SJulian.Pullen@Sun.COM 				new->uid_ttl = 0;
1069*7369SJulian.Pullen@Sun.COM 				new->gid = pid;
1070*7369SJulian.Pullen@Sun.COM 				new->gid_ttl = ttl;
1071*7369SJulian.Pullen@Sun.COM 				idmap_cache.sid2uid_gid.gid_num++;
1072*7369SJulian.Pullen@Sun.COM 			}
1073*7369SJulian.Pullen@Sun.COM 			idmap_cache.sid2uid_gid.pid_num++;
1074*7369SJulian.Pullen@Sun.COM 
1075*7369SJulian.Pullen@Sun.COM 			list_insert(&idmap_cache.sid2uid_gid.head, new);
1076*7369SJulian.Pullen@Sun.COM 			avl_insert(&idmap_cache.sid2uid_gid.tree, new, where);
1077*7369SJulian.Pullen@Sun.COM 		}
1078*7369SJulian.Pullen@Sun.COM 		if ((avl_numnodes(&idmap_cache.sid2uid_gid.tree) >
1079*7369SJulian.Pullen@Sun.COM 		    CACHE_UID_GID_TRIGGER_SIZE) &&
1080*7369SJulian.Pullen@Sun.COM 		    (idmap_cache.sid2uid_gid.purge_time + CACHE_PURGE_INTERVAL <
1081*7369SJulian.Pullen@Sun.COM 		    time(NULL)))
1082*7369SJulian.Pullen@Sun.COM 			idmap_purge_sid2uid_gid_cache(&idmap_cache.sid2uid_gid,
1083*7369SJulian.Pullen@Sun.COM 			    CACHE_UID_GID_TRIGGER_SIZE);
1084*7369SJulian.Pullen@Sun.COM 
1085*7369SJulian.Pullen@Sun.COM exit_sid2uid_gid:
1086*7369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
1087*7369SJulian.Pullen@Sun.COM 	}
1088*7369SJulian.Pullen@Sun.COM 
1089*7369SJulian.Pullen@Sun.COM 	if (direction == IDMAP_DIRECTION_BI ||
1090*7369SJulian.Pullen@Sun.COM 	    direction == IDMAP_DIRECTION_U2W) {
1091*7369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	find;
1092*7369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	*result;
1093*7369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	*new;
1094*7369SJulian.Pullen@Sun.COM 
1095*7369SJulian.Pullen@Sun.COM 		find.pid = pid;
1096*7369SJulian.Pullen@Sun.COM 		if (is_user) {
1097*7369SJulian.Pullen@Sun.COM 			(void) pthread_mutex_lock(
1098*7369SJulian.Pullen@Sun.COM 			    &idmap_cache.uid2sid_winname.mutex);
1099*7369SJulian.Pullen@Sun.COM 			result = avl_find(&idmap_cache.uid2sid_winname.tree,
1100*7369SJulian.Pullen@Sun.COM 			    &find, &where);
1101*7369SJulian.Pullen@Sun.COM 
1102*7369SJulian.Pullen@Sun.COM 			if (result) {
1103*7369SJulian.Pullen@Sun.COM 				if (update_str(&result->sid_prefix, sid_prefix)
1104*7369SJulian.Pullen@Sun.COM 				    != 0)
1105*7369SJulian.Pullen@Sun.COM 					goto exit_uid2sid_winname;
1106*7369SJulian.Pullen@Sun.COM 				if (result->sid_ttl == 0)
1107*7369SJulian.Pullen@Sun.COM 					idmap_cache.uid2sid_winname.sid_num++;
1108*7369SJulian.Pullen@Sun.COM 				result->rid = rid;
1109*7369SJulian.Pullen@Sun.COM 				result->sid_ttl = ttl;
1110*7369SJulian.Pullen@Sun.COM 			} else {
1111*7369SJulian.Pullen@Sun.COM 				new = malloc(sizeof (pid2sid_winname_t));
1112*7369SJulian.Pullen@Sun.COM 				if (new == NULL)
1113*7369SJulian.Pullen@Sun.COM 					goto exit_uid2sid_winname;
1114*7369SJulian.Pullen@Sun.COM 				new->sid_prefix = strdup(sid_prefix);
1115*7369SJulian.Pullen@Sun.COM 				if (new->sid_prefix == NULL) {
1116*7369SJulian.Pullen@Sun.COM 					free(new);
1117*7369SJulian.Pullen@Sun.COM 					goto exit_uid2sid_winname;
1118*7369SJulian.Pullen@Sun.COM 				}
1119*7369SJulian.Pullen@Sun.COM 				new->rid = rid;
1120*7369SJulian.Pullen@Sun.COM 				new->pid = pid;
1121*7369SJulian.Pullen@Sun.COM 				new->sid_ttl = ttl;
1122*7369SJulian.Pullen@Sun.COM 				new->winname = NULL;
1123*7369SJulian.Pullen@Sun.COM 				new->windomain = NULL;
1124*7369SJulian.Pullen@Sun.COM 				idmap_cache.uid2sid_winname.sid_num++;
1125*7369SJulian.Pullen@Sun.COM 
1126*7369SJulian.Pullen@Sun.COM 				list_insert(&idmap_cache.uid2sid_winname.head,
1127*7369SJulian.Pullen@Sun.COM 				    new);
1128*7369SJulian.Pullen@Sun.COM 				avl_insert(&idmap_cache.uid2sid_winname.tree,
1129*7369SJulian.Pullen@Sun.COM 				    new, where);
1130*7369SJulian.Pullen@Sun.COM 			}
1131*7369SJulian.Pullen@Sun.COM 			if ((avl_numnodes(&idmap_cache.uid2sid_winname.tree) >
1132*7369SJulian.Pullen@Sun.COM 			    CACHE_UID_TRIGGER_SIZE) &&
1133*7369SJulian.Pullen@Sun.COM 			    (idmap_cache.uid2sid_winname.purge_time +
1134*7369SJulian.Pullen@Sun.COM 			    CACHE_PURGE_INTERVAL < time(NULL)))
1135*7369SJulian.Pullen@Sun.COM 				idmap_purge_pid2sid_winname_cache(
1136*7369SJulian.Pullen@Sun.COM 				    &idmap_cache.uid2sid_winname,
1137*7369SJulian.Pullen@Sun.COM 				    CACHE_UID_TRIGGER_SIZE);
1138*7369SJulian.Pullen@Sun.COM 
1139*7369SJulian.Pullen@Sun.COM exit_uid2sid_winname:
1140*7369SJulian.Pullen@Sun.COM 			(void) pthread_mutex_unlock(
1141*7369SJulian.Pullen@Sun.COM 			    &idmap_cache.uid2sid_winname.mutex);
1142*7369SJulian.Pullen@Sun.COM 		} else {
1143*7369SJulian.Pullen@Sun.COM 			(void) pthread_mutex_lock(
1144*7369SJulian.Pullen@Sun.COM 			    &idmap_cache.gid2sid_winname.mutex);
1145*7369SJulian.Pullen@Sun.COM 			result = avl_find(&idmap_cache.gid2sid_winname.tree,
1146*7369SJulian.Pullen@Sun.COM 			    &find, &where);
1147*7369SJulian.Pullen@Sun.COM 
1148*7369SJulian.Pullen@Sun.COM 			if (result) {
1149*7369SJulian.Pullen@Sun.COM 				if (update_str(&result->sid_prefix, sid_prefix)
1150*7369SJulian.Pullen@Sun.COM 				    != 0)
1151*7369SJulian.Pullen@Sun.COM 					goto exit_gid2sid_winname;
1152*7369SJulian.Pullen@Sun.COM 				if (result->sid_ttl == 0)
1153*7369SJulian.Pullen@Sun.COM 					idmap_cache.gid2sid_winname.sid_num++;
1154*7369SJulian.Pullen@Sun.COM 				result->rid = rid;
1155*7369SJulian.Pullen@Sun.COM 				result->sid_ttl = ttl;
1156*7369SJulian.Pullen@Sun.COM 			} else {
1157*7369SJulian.Pullen@Sun.COM 				new = malloc(sizeof (pid2sid_winname_t));
1158*7369SJulian.Pullen@Sun.COM 				if (new == NULL)
1159*7369SJulian.Pullen@Sun.COM 					goto exit_gid2sid_winname;
1160*7369SJulian.Pullen@Sun.COM 				new->sid_prefix = strdup(sid_prefix);
1161*7369SJulian.Pullen@Sun.COM 				if (new->sid_prefix == NULL) {
1162*7369SJulian.Pullen@Sun.COM 					free(new);
1163*7369SJulian.Pullen@Sun.COM 					goto exit_gid2sid_winname;
1164*7369SJulian.Pullen@Sun.COM 				}
1165*7369SJulian.Pullen@Sun.COM 				new->rid = rid;
1166*7369SJulian.Pullen@Sun.COM 				new->pid = pid;
1167*7369SJulian.Pullen@Sun.COM 				new->sid_ttl = ttl;
1168*7369SJulian.Pullen@Sun.COM 				new->winname = NULL;
1169*7369SJulian.Pullen@Sun.COM 				new->windomain = NULL;
1170*7369SJulian.Pullen@Sun.COM 				idmap_cache.gid2sid_winname.sid_num++;
1171*7369SJulian.Pullen@Sun.COM 
1172*7369SJulian.Pullen@Sun.COM 				list_insert(&idmap_cache.gid2sid_winname.head,
1173*7369SJulian.Pullen@Sun.COM 				    new);
1174*7369SJulian.Pullen@Sun.COM 				avl_insert(&idmap_cache.gid2sid_winname.tree,
1175*7369SJulian.Pullen@Sun.COM 				    new, where);
1176*7369SJulian.Pullen@Sun.COM 			}
1177*7369SJulian.Pullen@Sun.COM 			if ((avl_numnodes(&idmap_cache.gid2sid_winname.tree) >
1178*7369SJulian.Pullen@Sun.COM 			    CACHE_GID_TRIGGER_SIZE) &&
1179*7369SJulian.Pullen@Sun.COM 			    (idmap_cache.gid2sid_winname.purge_time +
1180*7369SJulian.Pullen@Sun.COM 			    CACHE_PURGE_INTERVAL < time(NULL)))
1181*7369SJulian.Pullen@Sun.COM 				idmap_purge_pid2sid_winname_cache(
1182*7369SJulian.Pullen@Sun.COM 				    &idmap_cache.gid2sid_winname,
1183*7369SJulian.Pullen@Sun.COM 				    CACHE_GID_TRIGGER_SIZE);
1184*7369SJulian.Pullen@Sun.COM exit_gid2sid_winname:
1185*7369SJulian.Pullen@Sun.COM 			(void) pthread_mutex_unlock(
1186*7369SJulian.Pullen@Sun.COM 			    &idmap_cache.gid2sid_winname.mutex);
1187*7369SJulian.Pullen@Sun.COM 		}
1188*7369SJulian.Pullen@Sun.COM 	}
1189*7369SJulian.Pullen@Sun.COM }
1190*7369SJulian.Pullen@Sun.COM 
1191*7369SJulian.Pullen@Sun.COM 
1192*7369SJulian.Pullen@Sun.COM 
1193*7369SJulian.Pullen@Sun.COM void
1194*7369SJulian.Pullen@Sun.COM idmap_cache_add_winname2uid(const char *name, const char *domain, uid_t uid,
1195*7369SJulian.Pullen@Sun.COM 			int direction)
1196*7369SJulian.Pullen@Sun.COM {
1197*7369SJulian.Pullen@Sun.COM 	avl_index_t	where;
1198*7369SJulian.Pullen@Sun.COM 	time_t		ttl = CACHE_TTL + time(NULL);
1199*7369SJulian.Pullen@Sun.COM 
1200*7369SJulian.Pullen@Sun.COM 
1201*7369SJulian.Pullen@Sun.COM 	if (direction == IDMAP_DIRECTION_BI ||
1202*7369SJulian.Pullen@Sun.COM 	    direction == IDMAP_DIRECTION_W2U) {
1203*7369SJulian.Pullen@Sun.COM 		winname2uid_gid_t	find;
1204*7369SJulian.Pullen@Sun.COM 		winname2uid_gid_t	*result;
1205*7369SJulian.Pullen@Sun.COM 		winname2uid_gid_t	*new;
1206*7369SJulian.Pullen@Sun.COM 
1207*7369SJulian.Pullen@Sun.COM 		find.winname = name;
1208*7369SJulian.Pullen@Sun.COM 		find.windomain = domain;
1209*7369SJulian.Pullen@Sun.COM 
1210*7369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
1211*7369SJulian.Pullen@Sun.COM 		result = avl_find(&idmap_cache.winname2uid_gid.tree, &find,
1212*7369SJulian.Pullen@Sun.COM 		    &where);
1213*7369SJulian.Pullen@Sun.COM 
1214*7369SJulian.Pullen@Sun.COM 		if (result) {
1215*7369SJulian.Pullen@Sun.COM 			if (result->uid_ttl == 0)
1216*7369SJulian.Pullen@Sun.COM 				idmap_cache.winname2uid_gid.uid_num++;
1217*7369SJulian.Pullen@Sun.COM 			result->uid = uid;
1218*7369SJulian.Pullen@Sun.COM 			result->uid_ttl = ttl;
1219*7369SJulian.Pullen@Sun.COM 		} else {
1220*7369SJulian.Pullen@Sun.COM 			new = malloc(sizeof (winname2uid_gid_t));
1221*7369SJulian.Pullen@Sun.COM 			if (new == NULL)
1222*7369SJulian.Pullen@Sun.COM 				goto exit_winname2uid_gid;
1223*7369SJulian.Pullen@Sun.COM 			new->winname = strdup(name);
1224*7369SJulian.Pullen@Sun.COM 			if (new->winname == NULL) {
1225*7369SJulian.Pullen@Sun.COM 				free(new);
1226*7369SJulian.Pullen@Sun.COM 				goto exit_winname2uid_gid;
1227*7369SJulian.Pullen@Sun.COM 			}
1228*7369SJulian.Pullen@Sun.COM 			if (domain != NULL) {
1229*7369SJulian.Pullen@Sun.COM 				new->windomain = strdup(domain);
1230*7369SJulian.Pullen@Sun.COM 				if (new->winname == NULL) {
1231*7369SJulian.Pullen@Sun.COM 					free((char *)new->winname);
1232*7369SJulian.Pullen@Sun.COM 					free(new);
1233*7369SJulian.Pullen@Sun.COM 					goto exit_winname2uid_gid;
1234*7369SJulian.Pullen@Sun.COM 				}
1235*7369SJulian.Pullen@Sun.COM 			} else
1236*7369SJulian.Pullen@Sun.COM 				new->windomain = NULL;
1237*7369SJulian.Pullen@Sun.COM 			new->uid = uid;
1238*7369SJulian.Pullen@Sun.COM 			new->uid_ttl = ttl;
1239*7369SJulian.Pullen@Sun.COM 			new->gid = UNDEF_GID;
1240*7369SJulian.Pullen@Sun.COM 			new->gid_ttl = 0;
1241*7369SJulian.Pullen@Sun.COM 			idmap_cache.winname2uid_gid.uid_num++;
1242*7369SJulian.Pullen@Sun.COM 
1243*7369SJulian.Pullen@Sun.COM 			list_insert(&idmap_cache.winname2uid_gid.head, new);
1244*7369SJulian.Pullen@Sun.COM 			avl_insert(&idmap_cache.winname2uid_gid.tree, new,
1245*7369SJulian.Pullen@Sun.COM 			    where);
1246*7369SJulian.Pullen@Sun.COM 		}
1247*7369SJulian.Pullen@Sun.COM 		if ((avl_numnodes(&idmap_cache.winname2uid_gid.tree) >
1248*7369SJulian.Pullen@Sun.COM 		    CACHE_UID_GID_TRIGGER_SIZE) &&
1249*7369SJulian.Pullen@Sun.COM 		    (idmap_cache.winname2uid_gid.purge_time +
1250*7369SJulian.Pullen@Sun.COM 		    CACHE_PURGE_INTERVAL < time(NULL)))
1251*7369SJulian.Pullen@Sun.COM 			idmap_purge_winname2uid_gid_cache(
1252*7369SJulian.Pullen@Sun.COM 			    &idmap_cache.winname2uid_gid,
1253*7369SJulian.Pullen@Sun.COM 			    CACHE_UID_GID_TRIGGER_SIZE);
1254*7369SJulian.Pullen@Sun.COM exit_winname2uid_gid:
1255*7369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
1256*7369SJulian.Pullen@Sun.COM 	}
1257*7369SJulian.Pullen@Sun.COM 
1258*7369SJulian.Pullen@Sun.COM 	if (direction == IDMAP_DIRECTION_BI ||
1259*7369SJulian.Pullen@Sun.COM 	    direction == IDMAP_DIRECTION_U2W) {
1260*7369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	find;
1261*7369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	*result;
1262*7369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	*new;
1263*7369SJulian.Pullen@Sun.COM 
1264*7369SJulian.Pullen@Sun.COM 		find.pid = uid;
1265*7369SJulian.Pullen@Sun.COM 
1266*7369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
1267*7369SJulian.Pullen@Sun.COM 		result = avl_find(&idmap_cache.uid2sid_winname.tree, &find,
1268*7369SJulian.Pullen@Sun.COM 		    &where);
1269*7369SJulian.Pullen@Sun.COM 
1270*7369SJulian.Pullen@Sun.COM 		if (result) {
1271*7369SJulian.Pullen@Sun.COM 			if (update_str(&result->winname, name) != 0)
1272*7369SJulian.Pullen@Sun.COM 				goto exit_uid2sid_winname;
1273*7369SJulian.Pullen@Sun.COM 			if (update_str(&result->windomain, domain) != 0)
1274*7369SJulian.Pullen@Sun.COM 				goto exit_uid2sid_winname;
1275*7369SJulian.Pullen@Sun.COM 			if (result->winname_ttl == 0)
1276*7369SJulian.Pullen@Sun.COM 				idmap_cache.uid2sid_winname.winname_num++;
1277*7369SJulian.Pullen@Sun.COM 			result->winname_ttl = ttl;
1278*7369SJulian.Pullen@Sun.COM 		} else {
1279*7369SJulian.Pullen@Sun.COM 			new = malloc(sizeof (pid2sid_winname_t));
1280*7369SJulian.Pullen@Sun.COM 			if (new == NULL)
1281*7369SJulian.Pullen@Sun.COM 				goto exit_uid2sid_winname;
1282*7369SJulian.Pullen@Sun.COM 			new->pid = uid;
1283*7369SJulian.Pullen@Sun.COM 			new->winname = strdup(name);
1284*7369SJulian.Pullen@Sun.COM 			if (new->winname == NULL) {
1285*7369SJulian.Pullen@Sun.COM 				free(new);
1286*7369SJulian.Pullen@Sun.COM 				goto exit_uid2sid_winname;
1287*7369SJulian.Pullen@Sun.COM 			}
1288*7369SJulian.Pullen@Sun.COM 			if (domain != NULL) {
1289*7369SJulian.Pullen@Sun.COM 				new->windomain = strdup(domain);
1290*7369SJulian.Pullen@Sun.COM 				if (new->windomain == NULL) {
1291*7369SJulian.Pullen@Sun.COM 					free((char *)new->winname);
1292*7369SJulian.Pullen@Sun.COM 					free(new);
1293*7369SJulian.Pullen@Sun.COM 					goto exit_uid2sid_winname;
1294*7369SJulian.Pullen@Sun.COM 				}
1295*7369SJulian.Pullen@Sun.COM 			} else
1296*7369SJulian.Pullen@Sun.COM 				new->windomain = NULL;
1297*7369SJulian.Pullen@Sun.COM 			new->winname_ttl = ttl;
1298*7369SJulian.Pullen@Sun.COM 			new->sid_prefix = NULL;
1299*7369SJulian.Pullen@Sun.COM 			new->rid = 0;
1300*7369SJulian.Pullen@Sun.COM 			new->sid_ttl = 0;
1301*7369SJulian.Pullen@Sun.COM 			idmap_cache.uid2sid_winname.winname_num ++;
1302*7369SJulian.Pullen@Sun.COM 
1303*7369SJulian.Pullen@Sun.COM 			list_insert(&idmap_cache.uid2sid_winname.head, new);
1304*7369SJulian.Pullen@Sun.COM 			avl_insert(&idmap_cache.uid2sid_winname.tree, new,
1305*7369SJulian.Pullen@Sun.COM 			    where);
1306*7369SJulian.Pullen@Sun.COM 		}
1307*7369SJulian.Pullen@Sun.COM 		if ((avl_numnodes(&idmap_cache.uid2sid_winname.tree) >
1308*7369SJulian.Pullen@Sun.COM 		    CACHE_UID_TRIGGER_SIZE) &&
1309*7369SJulian.Pullen@Sun.COM 		    (idmap_cache.uid2sid_winname.purge_time +
1310*7369SJulian.Pullen@Sun.COM 		    CACHE_PURGE_INTERVAL < time(NULL)))
1311*7369SJulian.Pullen@Sun.COM 			idmap_purge_pid2sid_winname_cache(
1312*7369SJulian.Pullen@Sun.COM 			    &idmap_cache.uid2sid_winname,
1313*7369SJulian.Pullen@Sun.COM 			    CACHE_UID_TRIGGER_SIZE);
1314*7369SJulian.Pullen@Sun.COM exit_uid2sid_winname:
1315*7369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
1316*7369SJulian.Pullen@Sun.COM 	}
1317*7369SJulian.Pullen@Sun.COM }
1318*7369SJulian.Pullen@Sun.COM 
1319*7369SJulian.Pullen@Sun.COM 
1320*7369SJulian.Pullen@Sun.COM 
1321*7369SJulian.Pullen@Sun.COM 
1322*7369SJulian.Pullen@Sun.COM 
1323*7369SJulian.Pullen@Sun.COM void
1324*7369SJulian.Pullen@Sun.COM idmap_cache_add_winname2gid(const char *name, const char *domain, gid_t gid,
1325*7369SJulian.Pullen@Sun.COM 			int direction)
1326*7369SJulian.Pullen@Sun.COM {
1327*7369SJulian.Pullen@Sun.COM 	avl_index_t	where;
1328*7369SJulian.Pullen@Sun.COM 	time_t		ttl = CACHE_TTL + time(NULL);
1329*7369SJulian.Pullen@Sun.COM 
1330*7369SJulian.Pullen@Sun.COM 
1331*7369SJulian.Pullen@Sun.COM 	if (direction == IDMAP_DIRECTION_BI ||
1332*7369SJulian.Pullen@Sun.COM 	    direction == IDMAP_DIRECTION_W2U) {
1333*7369SJulian.Pullen@Sun.COM 		winname2uid_gid_t	find;
1334*7369SJulian.Pullen@Sun.COM 		winname2uid_gid_t	*result;
1335*7369SJulian.Pullen@Sun.COM 		winname2uid_gid_t	*new;
1336*7369SJulian.Pullen@Sun.COM 
1337*7369SJulian.Pullen@Sun.COM 		find.winname = name;
1338*7369SJulian.Pullen@Sun.COM 		find.windomain = domain;
1339*7369SJulian.Pullen@Sun.COM 
1340*7369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
1341*7369SJulian.Pullen@Sun.COM 		result = avl_find(&idmap_cache.winname2uid_gid.tree, &find,
1342*7369SJulian.Pullen@Sun.COM 		    &where);
1343*7369SJulian.Pullen@Sun.COM 
1344*7369SJulian.Pullen@Sun.COM 		if (result) {
1345*7369SJulian.Pullen@Sun.COM 			if (result->uid_ttl == 0)
1346*7369SJulian.Pullen@Sun.COM 				idmap_cache.winname2uid_gid.gid_num++;
1347*7369SJulian.Pullen@Sun.COM 			result->gid = gid;
1348*7369SJulian.Pullen@Sun.COM 			result->gid_ttl = ttl;
1349*7369SJulian.Pullen@Sun.COM 		} else {
1350*7369SJulian.Pullen@Sun.COM 			new = malloc(sizeof (winname2uid_gid_t));
1351*7369SJulian.Pullen@Sun.COM 			if (new == NULL)
1352*7369SJulian.Pullen@Sun.COM 				goto exit_winname2uid_gid;
1353*7369SJulian.Pullen@Sun.COM 			new->winname = strdup(name);
1354*7369SJulian.Pullen@Sun.COM 			if (new->winname == NULL) {
1355*7369SJulian.Pullen@Sun.COM 				free(new);
1356*7369SJulian.Pullen@Sun.COM 				goto exit_winname2uid_gid;
1357*7369SJulian.Pullen@Sun.COM 			}
1358*7369SJulian.Pullen@Sun.COM 			if (domain != NULL) {
1359*7369SJulian.Pullen@Sun.COM 				new->windomain = strdup(domain);
1360*7369SJulian.Pullen@Sun.COM 				if (new->windomain == NULL) {
1361*7369SJulian.Pullen@Sun.COM 					free((char *)new->winname);
1362*7369SJulian.Pullen@Sun.COM 					free(new);
1363*7369SJulian.Pullen@Sun.COM 					goto exit_winname2uid_gid;
1364*7369SJulian.Pullen@Sun.COM 				}
1365*7369SJulian.Pullen@Sun.COM 			}
1366*7369SJulian.Pullen@Sun.COM 			else
1367*7369SJulian.Pullen@Sun.COM 				new->windomain = NULL;
1368*7369SJulian.Pullen@Sun.COM 			new->uid = UNDEF_UID;
1369*7369SJulian.Pullen@Sun.COM 			new->uid_ttl = 0;
1370*7369SJulian.Pullen@Sun.COM 			new->gid = gid;
1371*7369SJulian.Pullen@Sun.COM 			new->gid_ttl = ttl;
1372*7369SJulian.Pullen@Sun.COM 			idmap_cache.winname2uid_gid.gid_num++;
1373*7369SJulian.Pullen@Sun.COM 
1374*7369SJulian.Pullen@Sun.COM 			list_insert(&idmap_cache.winname2uid_gid.head, new);
1375*7369SJulian.Pullen@Sun.COM 			avl_insert(&idmap_cache.winname2uid_gid.tree, new,
1376*7369SJulian.Pullen@Sun.COM 			    where);
1377*7369SJulian.Pullen@Sun.COM 		}
1378*7369SJulian.Pullen@Sun.COM 		if ((avl_numnodes(&idmap_cache.winname2uid_gid.tree) >
1379*7369SJulian.Pullen@Sun.COM 		    CACHE_UID_GID_TRIGGER_SIZE) &&
1380*7369SJulian.Pullen@Sun.COM 		    (idmap_cache.winname2uid_gid.purge_time +
1381*7369SJulian.Pullen@Sun.COM 		    CACHE_PURGE_INTERVAL < time(NULL)))
1382*7369SJulian.Pullen@Sun.COM 			idmap_purge_winname2uid_gid_cache(
1383*7369SJulian.Pullen@Sun.COM 			    &idmap_cache.winname2uid_gid,
1384*7369SJulian.Pullen@Sun.COM 			    CACHE_UID_GID_TRIGGER_SIZE);
1385*7369SJulian.Pullen@Sun.COM exit_winname2uid_gid:
1386*7369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
1387*7369SJulian.Pullen@Sun.COM 	}
1388*7369SJulian.Pullen@Sun.COM 
1389*7369SJulian.Pullen@Sun.COM 	if (direction == IDMAP_DIRECTION_BI ||
1390*7369SJulian.Pullen@Sun.COM 	    direction == IDMAP_DIRECTION_U2W) {
1391*7369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	find;
1392*7369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	*result;
1393*7369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	*new;
1394*7369SJulian.Pullen@Sun.COM 
1395*7369SJulian.Pullen@Sun.COM 		find.pid = gid;
1396*7369SJulian.Pullen@Sun.COM 
1397*7369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
1398*7369SJulian.Pullen@Sun.COM 		result = avl_find(&idmap_cache.gid2sid_winname.tree, &find,
1399*7369SJulian.Pullen@Sun.COM 		    &where);
1400*7369SJulian.Pullen@Sun.COM 
1401*7369SJulian.Pullen@Sun.COM 		if (result) {
1402*7369SJulian.Pullen@Sun.COM 			if (update_str(&result->winname, name) != 0)
1403*7369SJulian.Pullen@Sun.COM 				goto exit_gid2sid_winname;
1404*7369SJulian.Pullen@Sun.COM 			if (update_str(&result->windomain, domain) != 0)
1405*7369SJulian.Pullen@Sun.COM 				goto exit_gid2sid_winname;
1406*7369SJulian.Pullen@Sun.COM 			if (result->winname_ttl == 0)
1407*7369SJulian.Pullen@Sun.COM 				idmap_cache.gid2sid_winname.winname_num++;
1408*7369SJulian.Pullen@Sun.COM 			result->winname_ttl = ttl;
1409*7369SJulian.Pullen@Sun.COM 		} else {
1410*7369SJulian.Pullen@Sun.COM 			new = malloc(sizeof (pid2sid_winname_t));
1411*7369SJulian.Pullen@Sun.COM 			if (new == NULL)
1412*7369SJulian.Pullen@Sun.COM 				goto exit_gid2sid_winname;
1413*7369SJulian.Pullen@Sun.COM 			new->pid = gid;
1414*7369SJulian.Pullen@Sun.COM 			new->winname = strdup(name);
1415*7369SJulian.Pullen@Sun.COM 			if (new->winname == NULL) {
1416*7369SJulian.Pullen@Sun.COM 				free(new);
1417*7369SJulian.Pullen@Sun.COM 				goto exit_gid2sid_winname;
1418*7369SJulian.Pullen@Sun.COM 			}
1419*7369SJulian.Pullen@Sun.COM 			if (domain != NULL) {
1420*7369SJulian.Pullen@Sun.COM 				new->windomain = strdup(domain);
1421*7369SJulian.Pullen@Sun.COM 				if (new->windomain == NULL) {
1422*7369SJulian.Pullen@Sun.COM 					free((char *)new->winname);
1423*7369SJulian.Pullen@Sun.COM 					free(new);
1424*7369SJulian.Pullen@Sun.COM 					goto exit_gid2sid_winname;
1425*7369SJulian.Pullen@Sun.COM 				}
1426*7369SJulian.Pullen@Sun.COM 			}
1427*7369SJulian.Pullen@Sun.COM 			else
1428*7369SJulian.Pullen@Sun.COM 				new->windomain = NULL;
1429*7369SJulian.Pullen@Sun.COM 			new->winname_ttl = ttl;
1430*7369SJulian.Pullen@Sun.COM 			new->sid_prefix = NULL;
1431*7369SJulian.Pullen@Sun.COM 			new->rid = 0;
1432*7369SJulian.Pullen@Sun.COM 			new->sid_ttl = 0;
1433*7369SJulian.Pullen@Sun.COM 			idmap_cache.gid2sid_winname.winname_num ++;
1434*7369SJulian.Pullen@Sun.COM 
1435*7369SJulian.Pullen@Sun.COM 			list_insert(&idmap_cache.gid2sid_winname.head, new);
1436*7369SJulian.Pullen@Sun.COM 			avl_insert(&idmap_cache.gid2sid_winname.tree, new,
1437*7369SJulian.Pullen@Sun.COM 			    where);
1438*7369SJulian.Pullen@Sun.COM 		}
1439*7369SJulian.Pullen@Sun.COM 		if ((avl_numnodes(&idmap_cache.gid2sid_winname.tree) >
1440*7369SJulian.Pullen@Sun.COM 		    CACHE_UID_TRIGGER_SIZE) &&
1441*7369SJulian.Pullen@Sun.COM 		    (idmap_cache.gid2sid_winname.purge_time +
1442*7369SJulian.Pullen@Sun.COM 		    CACHE_PURGE_INTERVAL < time(NULL)))
1443*7369SJulian.Pullen@Sun.COM 			idmap_purge_pid2sid_winname_cache(
1444*7369SJulian.Pullen@Sun.COM 			    &idmap_cache.gid2sid_winname,
1445*7369SJulian.Pullen@Sun.COM 			    CACHE_UID_TRIGGER_SIZE);
1446*7369SJulian.Pullen@Sun.COM exit_gid2sid_winname:
1447*7369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
1448*7369SJulian.Pullen@Sun.COM 	}
1449*7369SJulian.Pullen@Sun.COM }
1450*7369SJulian.Pullen@Sun.COM 
1451*7369SJulian.Pullen@Sun.COM 
1452*7369SJulian.Pullen@Sun.COM static void
1453*7369SJulian.Pullen@Sun.COM idmap_purge_sid2uid_gid_cache(sid2uid_gid_cache_t *cache, size_t limit)
1454*7369SJulian.Pullen@Sun.COM {
1455*7369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
1456*7369SJulian.Pullen@Sun.COM 	sid2uid_gid_t	*item;
1457*7369SJulian.Pullen@Sun.COM 
1458*7369SJulian.Pullen@Sun.COM 	while (avl_numnodes(&cache->tree) > limit) {
1459*7369SJulian.Pullen@Sun.COM 		/* Remove least recently used */
1460*7369SJulian.Pullen@Sun.COM 		item = cache->head.blink;
1461*7369SJulian.Pullen@Sun.COM 		list_remove(item);
1462*7369SJulian.Pullen@Sun.COM 		avl_remove(&cache->tree, item);
1463*7369SJulian.Pullen@Sun.COM 		if (item->uid_ttl != 0)
1464*7369SJulian.Pullen@Sun.COM 			cache->uid_num--;
1465*7369SJulian.Pullen@Sun.COM 		if (item->gid_ttl != 0)
1466*7369SJulian.Pullen@Sun.COM 			cache->gid_num--;
1467*7369SJulian.Pullen@Sun.COM 		if (item->is_user != UNDEF_ISUSER)
1468*7369SJulian.Pullen@Sun.COM 			cache->pid_num--;
1469*7369SJulian.Pullen@Sun.COM 
1470*7369SJulian.Pullen@Sun.COM 		if (item->sid_prefix)
1471*7369SJulian.Pullen@Sun.COM 			free((char *)item->sid_prefix);
1472*7369SJulian.Pullen@Sun.COM 		free(item);
1473*7369SJulian.Pullen@Sun.COM 	}
1474*7369SJulian.Pullen@Sun.COM 	cache->purge_time = now;
1475*7369SJulian.Pullen@Sun.COM }
1476*7369SJulian.Pullen@Sun.COM 
1477*7369SJulian.Pullen@Sun.COM 
1478*7369SJulian.Pullen@Sun.COM static void
1479*7369SJulian.Pullen@Sun.COM idmap_purge_winname2uid_gid_cache(winname2uid_gid_cache_t *cache, size_t limit)
1480*7369SJulian.Pullen@Sun.COM {
1481*7369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
1482*7369SJulian.Pullen@Sun.COM 	winname2uid_gid_t	*item;
1483*7369SJulian.Pullen@Sun.COM 
1484*7369SJulian.Pullen@Sun.COM 	while (avl_numnodes(&cache->tree) > limit) {
1485*7369SJulian.Pullen@Sun.COM 		/* Remove least recently used */
1486*7369SJulian.Pullen@Sun.COM 		item = cache->head.blink;
1487*7369SJulian.Pullen@Sun.COM 		list_remove(item);
1488*7369SJulian.Pullen@Sun.COM 		avl_remove(&cache->tree, item);
1489*7369SJulian.Pullen@Sun.COM 		if (item->uid_ttl != 0)
1490*7369SJulian.Pullen@Sun.COM 			cache->uid_num--;
1491*7369SJulian.Pullen@Sun.COM 		if (item->gid_ttl != 0)
1492*7369SJulian.Pullen@Sun.COM 			cache->gid_num--;
1493*7369SJulian.Pullen@Sun.COM 
1494*7369SJulian.Pullen@Sun.COM 		if (item->winname)
1495*7369SJulian.Pullen@Sun.COM 			free((char *)item->winname);
1496*7369SJulian.Pullen@Sun.COM 		if (item->windomain)
1497*7369SJulian.Pullen@Sun.COM 			free((char *)item->windomain);
1498*7369SJulian.Pullen@Sun.COM 		free(item);
1499*7369SJulian.Pullen@Sun.COM 	}
1500*7369SJulian.Pullen@Sun.COM 	cache->purge_time = now;
1501*7369SJulian.Pullen@Sun.COM }
1502*7369SJulian.Pullen@Sun.COM 
1503*7369SJulian.Pullen@Sun.COM 
1504*7369SJulian.Pullen@Sun.COM static void
1505*7369SJulian.Pullen@Sun.COM idmap_purge_pid2sid_winname_cache(pid2sid_winname_cache_t *cache, size_t limit)
1506*7369SJulian.Pullen@Sun.COM {
1507*7369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
1508*7369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	*item;
1509*7369SJulian.Pullen@Sun.COM 
1510*7369SJulian.Pullen@Sun.COM 	while (avl_numnodes(&cache->tree) > limit) {
1511*7369SJulian.Pullen@Sun.COM 		/* Remove least recently used */
1512*7369SJulian.Pullen@Sun.COM 		item = cache->head.blink;
1513*7369SJulian.Pullen@Sun.COM 		list_remove(item);
1514*7369SJulian.Pullen@Sun.COM 		avl_remove(&cache->tree, item);
1515*7369SJulian.Pullen@Sun.COM 		if (item->winname_ttl != 0)
1516*7369SJulian.Pullen@Sun.COM 			cache->winname_num--;
1517*7369SJulian.Pullen@Sun.COM 		if (item->sid_ttl != 0)
1518*7369SJulian.Pullen@Sun.COM 			cache->sid_num--;
1519*7369SJulian.Pullen@Sun.COM 
1520*7369SJulian.Pullen@Sun.COM 		if (item->winname)
1521*7369SJulian.Pullen@Sun.COM 			free((char *)item->winname);
1522*7369SJulian.Pullen@Sun.COM 		if (item->windomain)
1523*7369SJulian.Pullen@Sun.COM 			free((char *)item->windomain);
1524*7369SJulian.Pullen@Sun.COM 		if (item->sid_prefix)
1525*7369SJulian.Pullen@Sun.COM 			free((char *)item->sid_prefix);
1526*7369SJulian.Pullen@Sun.COM 		free(item);
1527*7369SJulian.Pullen@Sun.COM 	}
1528*7369SJulian.Pullen@Sun.COM 	cache->purge_time = now;
1529*7369SJulian.Pullen@Sun.COM }
1530