xref: /onnv-gate/usr/src/lib/libidmap/common/idmap_cache.c (revision 9565:f0422a11592c)
17369SJulian.Pullen@Sun.COM /*
27369SJulian.Pullen@Sun.COM  * CDDL HEADER START
37369SJulian.Pullen@Sun.COM  *
47369SJulian.Pullen@Sun.COM  * The contents of this file are subject to the terms of the
57369SJulian.Pullen@Sun.COM  * Common Development and Distribution License (the "License").
67369SJulian.Pullen@Sun.COM  * You may not use this file except in compliance with the License.
77369SJulian.Pullen@Sun.COM  *
87369SJulian.Pullen@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97369SJulian.Pullen@Sun.COM  * or http://www.opensolaris.org/os/licensing.
107369SJulian.Pullen@Sun.COM  * See the License for the specific language governing permissions
117369SJulian.Pullen@Sun.COM  * and limitations under the License.
127369SJulian.Pullen@Sun.COM  *
137369SJulian.Pullen@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
147369SJulian.Pullen@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157369SJulian.Pullen@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
167369SJulian.Pullen@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
177369SJulian.Pullen@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
187369SJulian.Pullen@Sun.COM  *
197369SJulian.Pullen@Sun.COM  * CDDL HEADER END
207369SJulian.Pullen@Sun.COM  */
217369SJulian.Pullen@Sun.COM 
227369SJulian.Pullen@Sun.COM /*
23*9565SJordan.Brown@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
247369SJulian.Pullen@Sun.COM  * Use is subject to license terms.
257369SJulian.Pullen@Sun.COM  */
267369SJulian.Pullen@Sun.COM 
277369SJulian.Pullen@Sun.COM /*
287369SJulian.Pullen@Sun.COM  * Windows to Solaris Identity Mapping
297369SJulian.Pullen@Sun.COM  * This module provides the libidmap idmap_cache.
307369SJulian.Pullen@Sun.COM  */
317369SJulian.Pullen@Sun.COM 
327369SJulian.Pullen@Sun.COM 
337369SJulian.Pullen@Sun.COM #include <sys/types.h>
347369SJulian.Pullen@Sun.COM #include <sys/avl.h>
357369SJulian.Pullen@Sun.COM #include <assert.h>
367369SJulian.Pullen@Sun.COM #include <pthread.h>
377369SJulian.Pullen@Sun.COM #include <strings.h>
387369SJulian.Pullen@Sun.COM #include <sys/idmap.h>
397369SJulian.Pullen@Sun.COM #include <stddef.h>
407369SJulian.Pullen@Sun.COM #include <stdlib.h>
41*9565SJordan.Brown@Sun.COM #include <rpcsvc/idmap_prot.h>
427369SJulian.Pullen@Sun.COM #include "idmap_cache.h"
437369SJulian.Pullen@Sun.COM 
447369SJulian.Pullen@Sun.COM 
457369SJulian.Pullen@Sun.COM /*
467369SJulian.Pullen@Sun.COM  * Internal definitions and functions
477369SJulian.Pullen@Sun.COM  */
487369SJulian.Pullen@Sun.COM 
497369SJulian.Pullen@Sun.COM #define	CACHE_UID_TRIGGER_SIZE	4096
507369SJulian.Pullen@Sun.COM #define	CACHE_GID_TRIGGER_SIZE	2048
517369SJulian.Pullen@Sun.COM #define	CACHE_UID_GID_TRIGGER_SIZE \
527369SJulian.Pullen@Sun.COM 	(CACHE_UID_TRIGGER_SIZE + CACHE_GID_TRIGGER_SIZE)
537369SJulian.Pullen@Sun.COM 
547369SJulian.Pullen@Sun.COM 
557369SJulian.Pullen@Sun.COM #define	UNDEF_UID	((uid_t)-1)
567369SJulian.Pullen@Sun.COM #define	UNDEF_GID	((gid_t)-1)
577369SJulian.Pullen@Sun.COM #define	UNDEF_ISUSER	(-1)
587369SJulian.Pullen@Sun.COM 
597369SJulian.Pullen@Sun.COM #define	CACHE_PURGE_INTERVAL	(60 * 3)
607369SJulian.Pullen@Sun.COM #define	CACHE_TTL		(60 * 10)
617369SJulian.Pullen@Sun.COM 
627369SJulian.Pullen@Sun.COM 
637369SJulian.Pullen@Sun.COM 
647369SJulian.Pullen@Sun.COM 
657369SJulian.Pullen@Sun.COM #define	list_insert(head, ele)\
667369SJulian.Pullen@Sun.COM 	do {\
677369SJulian.Pullen@Sun.COM 		(ele)->flink = (head)->flink;\
687369SJulian.Pullen@Sun.COM 		(head)->flink = (ele);\
697369SJulian.Pullen@Sun.COM 		(ele)->blink = (ele)->flink->blink;\
707369SJulian.Pullen@Sun.COM 		(ele)->flink->blink = (ele);\
717369SJulian.Pullen@Sun.COM 	} while (0)
727369SJulian.Pullen@Sun.COM 
737369SJulian.Pullen@Sun.COM 
747369SJulian.Pullen@Sun.COM 
757369SJulian.Pullen@Sun.COM #define	list_remove(ele)\
767369SJulian.Pullen@Sun.COM 	do {\
777369SJulian.Pullen@Sun.COM 		(ele)->flink->blink = (ele)->blink;\
787369SJulian.Pullen@Sun.COM 		(ele)->blink->flink = (ele)->flink;\
797369SJulian.Pullen@Sun.COM 	} while (0)
807369SJulian.Pullen@Sun.COM 
817369SJulian.Pullen@Sun.COM 
827369SJulian.Pullen@Sun.COM #define	list_move(head, ele) \
837369SJulian.Pullen@Sun.COM 	do {\
847369SJulian.Pullen@Sun.COM 		if ((head)->flink != (ele)) {\
857369SJulian.Pullen@Sun.COM 			list_remove(ele);\
867369SJulian.Pullen@Sun.COM 			list_insert(head, ele);\
877369SJulian.Pullen@Sun.COM 		}\
887369SJulian.Pullen@Sun.COM 	} while (0)
897369SJulian.Pullen@Sun.COM 
907369SJulian.Pullen@Sun.COM typedef struct sid2uid_gid {
917369SJulian.Pullen@Sun.COM 	avl_node_t		avl_link;
927369SJulian.Pullen@Sun.COM 	struct sid2uid_gid	*flink;
937369SJulian.Pullen@Sun.COM 	struct sid2uid_gid	*blink;
947369SJulian.Pullen@Sun.COM 	const char 		*sid_prefix;
957369SJulian.Pullen@Sun.COM 	idmap_rid_t		rid;
967369SJulian.Pullen@Sun.COM 	uid_t			uid;
977369SJulian.Pullen@Sun.COM 	time_t			uid_ttl;
987369SJulian.Pullen@Sun.COM 	gid_t			gid;
997369SJulian.Pullen@Sun.COM 	time_t			gid_ttl;
1007369SJulian.Pullen@Sun.COM 	int			is_user;
1017369SJulian.Pullen@Sun.COM } sid2uid_gid_t;
1027369SJulian.Pullen@Sun.COM 
1037369SJulian.Pullen@Sun.COM 
1047369SJulian.Pullen@Sun.COM typedef struct pid2sid_winname {
1057369SJulian.Pullen@Sun.COM 	avl_node_t		avl_link;
1067369SJulian.Pullen@Sun.COM 	struct pid2sid_winname	*flink;
1077369SJulian.Pullen@Sun.COM 	struct pid2sid_winname	*blink;
1087369SJulian.Pullen@Sun.COM 	uid_t			pid;
1097369SJulian.Pullen@Sun.COM 	const char		*sid_prefix;
1107369SJulian.Pullen@Sun.COM 	idmap_rid_t		rid;
1117369SJulian.Pullen@Sun.COM 	time_t			sid_ttl;
1127369SJulian.Pullen@Sun.COM 	const char		*winname;
1137369SJulian.Pullen@Sun.COM 	const char		*windomain;
1147369SJulian.Pullen@Sun.COM 	time_t			winname_ttl;
1157369SJulian.Pullen@Sun.COM } pid2sid_winname_t;
1167369SJulian.Pullen@Sun.COM 
1177369SJulian.Pullen@Sun.COM 
1187369SJulian.Pullen@Sun.COM typedef struct winname2uid_gid {
1197369SJulian.Pullen@Sun.COM 	avl_node_t		avl_link;
1207369SJulian.Pullen@Sun.COM 	struct winname2uid_gid	*flink;
1217369SJulian.Pullen@Sun.COM 	struct winname2uid_gid	*blink;
1227369SJulian.Pullen@Sun.COM 	const char		*winname;
1237369SJulian.Pullen@Sun.COM 	const char		*windomain;
1247369SJulian.Pullen@Sun.COM 	uid_t			uid;
1257369SJulian.Pullen@Sun.COM 	time_t			uid_ttl;
1267369SJulian.Pullen@Sun.COM 	gid_t			gid;
1277369SJulian.Pullen@Sun.COM 	time_t			gid_ttl;
1287369SJulian.Pullen@Sun.COM } winname2uid_gid_t;
1297369SJulian.Pullen@Sun.COM 
1307369SJulian.Pullen@Sun.COM 
1317369SJulian.Pullen@Sun.COM typedef struct sid2uid_gid_cache {
1327369SJulian.Pullen@Sun.COM 	avl_tree_t		tree;
1337369SJulian.Pullen@Sun.COM 	pthread_mutex_t		mutex;
1347369SJulian.Pullen@Sun.COM 	sid2uid_gid_t		head;
1357369SJulian.Pullen@Sun.COM 	sid2uid_gid_t		*prev;
1367369SJulian.Pullen@Sun.COM 	time_t			purge_time;
1377369SJulian.Pullen@Sun.COM 	int			uid_num;
1387369SJulian.Pullen@Sun.COM 	int			gid_num;
1397369SJulian.Pullen@Sun.COM 	int			pid_num;
1407369SJulian.Pullen@Sun.COM } sid2uid_gid_cache_t;
1417369SJulian.Pullen@Sun.COM 
1427369SJulian.Pullen@Sun.COM 
1437369SJulian.Pullen@Sun.COM typedef struct pid2sid_winname_cache {
1447369SJulian.Pullen@Sun.COM 	avl_tree_t		tree;
1457369SJulian.Pullen@Sun.COM 	pthread_mutex_t		mutex;
1467369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	head;
1477369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	*prev;
1487369SJulian.Pullen@Sun.COM 	time_t			purge_time;
1497369SJulian.Pullen@Sun.COM 	int			sid_num;
1507369SJulian.Pullen@Sun.COM 	int			winname_num;
1517369SJulian.Pullen@Sun.COM } pid2sid_winname_cache_t;
1527369SJulian.Pullen@Sun.COM 
1537369SJulian.Pullen@Sun.COM 
1547369SJulian.Pullen@Sun.COM 
1557369SJulian.Pullen@Sun.COM typedef struct winname2uid_gid_cache {
1567369SJulian.Pullen@Sun.COM 	avl_tree_t		tree;
1577369SJulian.Pullen@Sun.COM 	pthread_mutex_t		mutex;
1587369SJulian.Pullen@Sun.COM 	winname2uid_gid_t	head;
1597369SJulian.Pullen@Sun.COM 	winname2uid_gid_t	*prev;
1607369SJulian.Pullen@Sun.COM 	time_t			purge_time;
1617369SJulian.Pullen@Sun.COM 	int			uid_num;
1627369SJulian.Pullen@Sun.COM 	int			gid_num;
1637369SJulian.Pullen@Sun.COM } winname2uid_gid_cache_t;
1647369SJulian.Pullen@Sun.COM 
1657369SJulian.Pullen@Sun.COM 
1667369SJulian.Pullen@Sun.COM typedef struct idmap_cache {
1677369SJulian.Pullen@Sun.COM 	sid2uid_gid_cache_t	sid2uid_gid;
1687369SJulian.Pullen@Sun.COM 	pid2sid_winname_cache_t	uid2sid_winname;
1697369SJulian.Pullen@Sun.COM 	pid2sid_winname_cache_t	gid2sid_winname;
1707369SJulian.Pullen@Sun.COM 	winname2uid_gid_cache_t	winname2uid_gid;
1717369SJulian.Pullen@Sun.COM } idmap_cache_t;
1727369SJulian.Pullen@Sun.COM 
1737369SJulian.Pullen@Sun.COM 
1747369SJulian.Pullen@Sun.COM 
1757369SJulian.Pullen@Sun.COM typedef int (*avl_comp_fn)(const void*, const void*);
1767369SJulian.Pullen@Sun.COM 
1777369SJulian.Pullen@Sun.COM static void
1787369SJulian.Pullen@Sun.COM idmap_purge_sid2uid_gid_cache(sid2uid_gid_cache_t *cache, size_t limit);
1797369SJulian.Pullen@Sun.COM 
1807369SJulian.Pullen@Sun.COM static void
1817369SJulian.Pullen@Sun.COM idmap_purge_pid2sid_winname_cache(pid2sid_winname_cache_t *cache, size_t limit);
1827369SJulian.Pullen@Sun.COM 
1837369SJulian.Pullen@Sun.COM static void
1847369SJulian.Pullen@Sun.COM idmap_purge_winname2uid_gid_cache(winname2uid_gid_cache_t *avl, size_t limit);
1857369SJulian.Pullen@Sun.COM 
1867369SJulian.Pullen@Sun.COM /*
1877369SJulian.Pullen@Sun.COM  * Global structures
1887369SJulian.Pullen@Sun.COM  */
1897369SJulian.Pullen@Sun.COM 
1907369SJulian.Pullen@Sun.COM static idmap_cache_t idmap_cache;
1917369SJulian.Pullen@Sun.COM 
1927369SJulian.Pullen@Sun.COM 
1937369SJulian.Pullen@Sun.COM 
1947369SJulian.Pullen@Sun.COM 
1957369SJulian.Pullen@Sun.COM static int
idmap_compare_sid(const sid2uid_gid_t * entry1,const sid2uid_gid_t * entry2)1967369SJulian.Pullen@Sun.COM idmap_compare_sid(const sid2uid_gid_t *entry1, const sid2uid_gid_t *entry2)
1977369SJulian.Pullen@Sun.COM {
1987369SJulian.Pullen@Sun.COM 	int64_t comp = ((int64_t)entry2->rid) - ((int64_t)entry1->rid);
1997369SJulian.Pullen@Sun.COM 
2007369SJulian.Pullen@Sun.COM 	if (comp == 0)
2017369SJulian.Pullen@Sun.COM 		comp = strcmp(entry2->sid_prefix, entry1->sid_prefix);
2027369SJulian.Pullen@Sun.COM 
2037369SJulian.Pullen@Sun.COM 	if (comp < 0)
2047369SJulian.Pullen@Sun.COM 		comp = -1;
2057369SJulian.Pullen@Sun.COM 	else if (comp > 0)
2067369SJulian.Pullen@Sun.COM 		comp = 1;
2077369SJulian.Pullen@Sun.COM 
2087369SJulian.Pullen@Sun.COM 	return ((int)comp);
2097369SJulian.Pullen@Sun.COM }
2107369SJulian.Pullen@Sun.COM 
2117369SJulian.Pullen@Sun.COM 
2127369SJulian.Pullen@Sun.COM static int
idmap_compare_pid(const pid2sid_winname_t * entry1,const pid2sid_winname_t * entry2)2137369SJulian.Pullen@Sun.COM idmap_compare_pid(const pid2sid_winname_t *entry1,
2147369SJulian.Pullen@Sun.COM 			const pid2sid_winname_t *entry2)
2157369SJulian.Pullen@Sun.COM {
2167369SJulian.Pullen@Sun.COM 	if (entry2->pid > entry1->pid)
2177369SJulian.Pullen@Sun.COM 		return (1);
2187369SJulian.Pullen@Sun.COM 	if (entry2->pid < entry1->pid)
2197369SJulian.Pullen@Sun.COM 		return (-1);
2207369SJulian.Pullen@Sun.COM 	return (0);
2217369SJulian.Pullen@Sun.COM }
2227369SJulian.Pullen@Sun.COM 
2237369SJulian.Pullen@Sun.COM 
2247369SJulian.Pullen@Sun.COM static int
idmap_compare_winname(const winname2uid_gid_t * entry1,const winname2uid_gid_t * entry2)2257369SJulian.Pullen@Sun.COM idmap_compare_winname(const winname2uid_gid_t *entry1,
2267369SJulian.Pullen@Sun.COM 			const winname2uid_gid_t *entry2)
2277369SJulian.Pullen@Sun.COM {
2287369SJulian.Pullen@Sun.COM 	int comp;
2297369SJulian.Pullen@Sun.COM 
2307369SJulian.Pullen@Sun.COM 	comp = strcasecmp(entry2->winname, entry1->winname);
2317369SJulian.Pullen@Sun.COM 	if (comp == 0) {
2327369SJulian.Pullen@Sun.COM 		if (entry2->windomain == NULL && entry1->windomain == NULL)
2337369SJulian.Pullen@Sun.COM 			return (0);
2347369SJulian.Pullen@Sun.COM 		if (entry1->windomain == NULL)
2357369SJulian.Pullen@Sun.COM 			return (1);
2367369SJulian.Pullen@Sun.COM 		if (entry2->windomain == NULL)
2377369SJulian.Pullen@Sun.COM 			return (-1);
2387369SJulian.Pullen@Sun.COM 
2397369SJulian.Pullen@Sun.COM 		comp = strcasecmp(entry2->windomain, entry1->windomain);
2407369SJulian.Pullen@Sun.COM 	}
2417369SJulian.Pullen@Sun.COM 
2427369SJulian.Pullen@Sun.COM 	if (comp < 0)
2437369SJulian.Pullen@Sun.COM 		comp = -1;
2447369SJulian.Pullen@Sun.COM 	else if (comp > 0)
2457369SJulian.Pullen@Sun.COM 		comp = 1;
2467369SJulian.Pullen@Sun.COM 
2477369SJulian.Pullen@Sun.COM 	return (comp);
2487369SJulian.Pullen@Sun.COM }
2497369SJulian.Pullen@Sun.COM 
2507369SJulian.Pullen@Sun.COM /*
2517369SJulian.Pullen@Sun.COM  * Routine to update item
2527369SJulian.Pullen@Sun.COM  *
2537369SJulian.Pullen@Sun.COM  * Returns:	0 Success
2547369SJulian.Pullen@Sun.COM  *		-1 Error
2557369SJulian.Pullen@Sun.COM  */
2567369SJulian.Pullen@Sun.COM static int
update_str(const char ** item,const char * str)2577369SJulian.Pullen@Sun.COM update_str(const char **item, const char *str)
2587369SJulian.Pullen@Sun.COM {
2597369SJulian.Pullen@Sun.COM 	char *tmp;
2607369SJulian.Pullen@Sun.COM 
2617369SJulian.Pullen@Sun.COM 	if (*item != NULL && str != NULL) {
2627369SJulian.Pullen@Sun.COM 		if (strcmp(*item, str) != 0) {
2637369SJulian.Pullen@Sun.COM 			if ((tmp = strdup(str)) == NULL)
2647369SJulian.Pullen@Sun.COM 				return (-1);
2657369SJulian.Pullen@Sun.COM 			free((char *)*item);
2667369SJulian.Pullen@Sun.COM 			*item = tmp;
2677369SJulian.Pullen@Sun.COM 		}
2687369SJulian.Pullen@Sun.COM 	} else if (str != NULL) {
2697369SJulian.Pullen@Sun.COM 		/* *item is NULL */
2707369SJulian.Pullen@Sun.COM 		if ((*item = strdup(str)) == NULL)
2717369SJulian.Pullen@Sun.COM 			return (-1);
2727369SJulian.Pullen@Sun.COM 	} else if (*item != NULL) {
2737369SJulian.Pullen@Sun.COM 		/* str is NULL */
2747369SJulian.Pullen@Sun.COM 		free((char *)*item);
2757369SJulian.Pullen@Sun.COM 		*item = NULL;
2767369SJulian.Pullen@Sun.COM 	}
2777369SJulian.Pullen@Sun.COM 
2787369SJulian.Pullen@Sun.COM 	return (0);
2797369SJulian.Pullen@Sun.COM }
2807369SJulian.Pullen@Sun.COM 
2817369SJulian.Pullen@Sun.COM /*
2827369SJulian.Pullen@Sun.COM  * The Cache is initialized on loading libidmap.so
2837369SJulian.Pullen@Sun.COM  */
2847369SJulian.Pullen@Sun.COM #pragma	init(idmap_cache_create)
2857369SJulian.Pullen@Sun.COM 
2867369SJulian.Pullen@Sun.COM void
idmap_cache_create(void)2877369SJulian.Pullen@Sun.COM idmap_cache_create(void)
2887369SJulian.Pullen@Sun.COM {
2897369SJulian.Pullen@Sun.COM 	avl_create(&idmap_cache.sid2uid_gid.tree,
2907369SJulian.Pullen@Sun.COM 	    (avl_comp_fn)idmap_compare_sid, sizeof (sid2uid_gid_t),
2917369SJulian.Pullen@Sun.COM 	    offsetof(sid2uid_gid_t, avl_link));
2927369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_init(&idmap_cache.sid2uid_gid.mutex, NULL);
2937369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.head.flink = &idmap_cache.sid2uid_gid.head;
2947369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.head.blink = &idmap_cache.sid2uid_gid.head;
2957369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.prev = NULL;
2967369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.purge_time = 0;
2977369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.uid_num = 0;
2987369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.gid_num = 0;
2997369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.pid_num = 0;
3007369SJulian.Pullen@Sun.COM 
3017369SJulian.Pullen@Sun.COM 	avl_create(&idmap_cache.uid2sid_winname.tree,
3027369SJulian.Pullen@Sun.COM 	    (avl_comp_fn)idmap_compare_pid, sizeof (pid2sid_winname_t),
3037369SJulian.Pullen@Sun.COM 	    offsetof(pid2sid_winname_t, avl_link));
3047369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_init(&idmap_cache.uid2sid_winname.mutex, NULL);
3057369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.head.flink =
3067369SJulian.Pullen@Sun.COM 	    &idmap_cache.uid2sid_winname.head;
3077369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.head.blink =
3087369SJulian.Pullen@Sun.COM 	    &idmap_cache.uid2sid_winname.head;
3097369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.prev = NULL;
3107369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.purge_time = 0;
3117369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.sid_num = 0;
3127369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.winname_num = 0;
3137369SJulian.Pullen@Sun.COM 
3147369SJulian.Pullen@Sun.COM 	avl_create(&idmap_cache.gid2sid_winname.tree,
3157369SJulian.Pullen@Sun.COM 	    (avl_comp_fn)idmap_compare_pid, sizeof (pid2sid_winname_t),
3167369SJulian.Pullen@Sun.COM 	    offsetof(pid2sid_winname_t, avl_link));
3177369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_init(&idmap_cache.gid2sid_winname.mutex, NULL);
3187369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.head.flink =
3197369SJulian.Pullen@Sun.COM 	    &idmap_cache.gid2sid_winname.head;
3207369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.head.blink =
3217369SJulian.Pullen@Sun.COM 	    &idmap_cache.gid2sid_winname.head;
3227369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.prev = NULL;
3237369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.purge_time = 0;
3247369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.sid_num = 0;
3257369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.winname_num = 0;
3267369SJulian.Pullen@Sun.COM 
3277369SJulian.Pullen@Sun.COM 	avl_create(&idmap_cache.winname2uid_gid.tree,
3287369SJulian.Pullen@Sun.COM 	    (avl_comp_fn)idmap_compare_winname, sizeof (winname2uid_gid_t),
3297369SJulian.Pullen@Sun.COM 	    offsetof(winname2uid_gid_t, avl_link));
3307369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_init(&idmap_cache.winname2uid_gid.mutex, NULL);
3317369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.head.flink =
3327369SJulian.Pullen@Sun.COM 	    &idmap_cache.winname2uid_gid.head;
3337369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.head.blink =
3347369SJulian.Pullen@Sun.COM 	    &idmap_cache.winname2uid_gid.head;
3357369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.prev = NULL;
3367369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.purge_time = 0;
3377369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.uid_num = 0;
3387369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.gid_num = 0;
3397369SJulian.Pullen@Sun.COM }
3407369SJulian.Pullen@Sun.COM 
3417369SJulian.Pullen@Sun.COM 
3427369SJulian.Pullen@Sun.COM void
idmap_cache_purge(void)3437369SJulian.Pullen@Sun.COM idmap_cache_purge(void)
3447369SJulian.Pullen@Sun.COM {
3457369SJulian.Pullen@Sun.COM 	sid2uid_gid_t		*sid2uid_gid;
3467369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	*uid2sid_winname;
3477369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	*gid2sid_winname;
3487369SJulian.Pullen@Sun.COM 	winname2uid_gid_t	*winname2uid_gid;
3497369SJulian.Pullen@Sun.COM 	void			*cookie;
3507369SJulian.Pullen@Sun.COM 
3517369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
3527369SJulian.Pullen@Sun.COM 	cookie = NULL;
3537369SJulian.Pullen@Sun.COM 	while ((sid2uid_gid = avl_destroy_nodes(
3547369SJulian.Pullen@Sun.COM 	    &idmap_cache.sid2uid_gid.tree, &cookie)) != NULL) {
3557369SJulian.Pullen@Sun.COM 		free((char *)sid2uid_gid->sid_prefix);
3567369SJulian.Pullen@Sun.COM 		free(sid2uid_gid);
3577369SJulian.Pullen@Sun.COM 	}
3587369SJulian.Pullen@Sun.COM 	avl_destroy(&idmap_cache.sid2uid_gid.tree);
3597369SJulian.Pullen@Sun.COM 	avl_create(&idmap_cache.sid2uid_gid.tree,
3607369SJulian.Pullen@Sun.COM 	    (avl_comp_fn)idmap_compare_sid, sizeof (sid2uid_gid_t),
3617369SJulian.Pullen@Sun.COM 	    offsetof(sid2uid_gid_t, avl_link));
3627369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.head.flink = &idmap_cache.sid2uid_gid.head;
3637369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.head.blink = &idmap_cache.sid2uid_gid.head;
3647369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.prev = NULL;
3657369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.purge_time = 0;
3667369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.uid_num = 0;
3677369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.gid_num = 0;
3687369SJulian.Pullen@Sun.COM 	idmap_cache.sid2uid_gid.pid_num = 0;
3697369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
3707369SJulian.Pullen@Sun.COM 
3717369SJulian.Pullen@Sun.COM 
3727369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
3737369SJulian.Pullen@Sun.COM 	cookie = NULL;
3747369SJulian.Pullen@Sun.COM 	while ((uid2sid_winname = avl_destroy_nodes(
3757369SJulian.Pullen@Sun.COM 	    &idmap_cache.uid2sid_winname.tree, &cookie)) != NULL) {
3767369SJulian.Pullen@Sun.COM 		free((char *)uid2sid_winname->sid_prefix);
3777369SJulian.Pullen@Sun.COM 		free((char *)uid2sid_winname->winname);
3787369SJulian.Pullen@Sun.COM 		if (uid2sid_winname->windomain != NULL)
3797369SJulian.Pullen@Sun.COM 			free((char *)uid2sid_winname->windomain);
3807369SJulian.Pullen@Sun.COM 		free(uid2sid_winname);
3817369SJulian.Pullen@Sun.COM 	}
3827369SJulian.Pullen@Sun.COM 	avl_destroy(&idmap_cache.uid2sid_winname.tree);
3837369SJulian.Pullen@Sun.COM 	avl_create(&idmap_cache.uid2sid_winname.tree,
3847369SJulian.Pullen@Sun.COM 	    (avl_comp_fn)idmap_compare_pid, sizeof (pid2sid_winname_t),
3857369SJulian.Pullen@Sun.COM 	    offsetof(pid2sid_winname_t, avl_link));
3867369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.head.flink =
3877369SJulian.Pullen@Sun.COM 	    &idmap_cache.uid2sid_winname.head;
3887369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.head.blink =
3897369SJulian.Pullen@Sun.COM 	    &idmap_cache.uid2sid_winname.head;
3907369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.prev = NULL;
3917369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.purge_time = 0;
3927369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.sid_num = 0;
3937369SJulian.Pullen@Sun.COM 	idmap_cache.uid2sid_winname.winname_num = 0;
3947369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
3957369SJulian.Pullen@Sun.COM 
3967369SJulian.Pullen@Sun.COM 
3977369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
3987369SJulian.Pullen@Sun.COM 	cookie = NULL;
3997369SJulian.Pullen@Sun.COM 	while ((gid2sid_winname = avl_destroy_nodes(
4007369SJulian.Pullen@Sun.COM 	    &idmap_cache.gid2sid_winname.tree, &cookie)) != NULL) {
4017369SJulian.Pullen@Sun.COM 		free((char *)gid2sid_winname->sid_prefix);
4027369SJulian.Pullen@Sun.COM 		free((char *)gid2sid_winname->winname);
4037369SJulian.Pullen@Sun.COM 		if (gid2sid_winname->windomain != NULL)
4047369SJulian.Pullen@Sun.COM 			free((char *)gid2sid_winname->windomain);
4057369SJulian.Pullen@Sun.COM 		free(gid2sid_winname);
4067369SJulian.Pullen@Sun.COM 	}
4077369SJulian.Pullen@Sun.COM 	avl_destroy(&idmap_cache.gid2sid_winname.tree);
4087369SJulian.Pullen@Sun.COM 	avl_create(&idmap_cache.gid2sid_winname.tree,
4097369SJulian.Pullen@Sun.COM 	    (avl_comp_fn)idmap_compare_pid, sizeof (pid2sid_winname_t),
4107369SJulian.Pullen@Sun.COM 	    offsetof(pid2sid_winname_t, avl_link));
4117369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.head.flink =
4127369SJulian.Pullen@Sun.COM 	    &idmap_cache.gid2sid_winname.head;
4137369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.head.blink =
4147369SJulian.Pullen@Sun.COM 	    &idmap_cache.gid2sid_winname.head;
4157369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.prev = NULL;
4167369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.purge_time = 0;
4177369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.sid_num = 0;
4187369SJulian.Pullen@Sun.COM 	idmap_cache.gid2sid_winname.winname_num = 0;
4197369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
4207369SJulian.Pullen@Sun.COM 
4217369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
4227369SJulian.Pullen@Sun.COM 	cookie = NULL;
4237369SJulian.Pullen@Sun.COM 	while ((winname2uid_gid = avl_destroy_nodes(
4247369SJulian.Pullen@Sun.COM 	    &idmap_cache.winname2uid_gid.tree, &cookie)) != NULL) {
4257369SJulian.Pullen@Sun.COM 		free((char *)winname2uid_gid->winname);
4267369SJulian.Pullen@Sun.COM 		if (winname2uid_gid->windomain)
4277369SJulian.Pullen@Sun.COM 			free((char *)winname2uid_gid->windomain);
4287369SJulian.Pullen@Sun.COM 		free(winname2uid_gid);
4297369SJulian.Pullen@Sun.COM 	}
4307369SJulian.Pullen@Sun.COM 	avl_destroy(&idmap_cache.winname2uid_gid.tree);
4317369SJulian.Pullen@Sun.COM 	avl_create(&idmap_cache.winname2uid_gid.tree,
4327369SJulian.Pullen@Sun.COM 	    (avl_comp_fn)idmap_compare_winname, sizeof (winname2uid_gid_t),
4337369SJulian.Pullen@Sun.COM 	    offsetof(winname2uid_gid_t, avl_link));
4347369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.head.flink =
4357369SJulian.Pullen@Sun.COM 	    &idmap_cache.winname2uid_gid.head;
4367369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.head.blink =
4377369SJulian.Pullen@Sun.COM 	    &idmap_cache.winname2uid_gid.head;
4387369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.prev = NULL;
4397369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.purge_time = 0;
4407369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.uid_num = 0;
4417369SJulian.Pullen@Sun.COM 	idmap_cache.winname2uid_gid.gid_num = 0;
4427369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
4437369SJulian.Pullen@Sun.COM 
4447369SJulian.Pullen@Sun.COM }
4457369SJulian.Pullen@Sun.COM 
4467369SJulian.Pullen@Sun.COM 
4477369SJulian.Pullen@Sun.COM void
idmap_cache_get_data(size_t * uidbysid,size_t * gidbysid,size_t * pidbysid,size_t * sidbyuid,size_t * sidbygid,size_t * winnamebyuid,size_t * winnamebygid,size_t * uidbywinname,size_t * gidbywinname)4487369SJulian.Pullen@Sun.COM idmap_cache_get_data(size_t *uidbysid, size_t *gidbysid,
4497369SJulian.Pullen@Sun.COM 	size_t *pidbysid, size_t *sidbyuid, size_t *sidbygid,
4507369SJulian.Pullen@Sun.COM 	size_t *winnamebyuid, size_t *winnamebygid,
4517369SJulian.Pullen@Sun.COM 	size_t *uidbywinname, size_t *gidbywinname)
4527369SJulian.Pullen@Sun.COM {
4537369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
4547369SJulian.Pullen@Sun.COM 	*uidbysid = idmap_cache.sid2uid_gid.uid_num;
4557369SJulian.Pullen@Sun.COM 	*gidbysid = idmap_cache.sid2uid_gid.gid_num;
4567369SJulian.Pullen@Sun.COM 	*pidbysid = idmap_cache.sid2uid_gid.pid_num;
4577369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
4587369SJulian.Pullen@Sun.COM 
4597369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
4607369SJulian.Pullen@Sun.COM 	*sidbyuid = idmap_cache.uid2sid_winname.sid_num;
4617369SJulian.Pullen@Sun.COM 	*winnamebyuid = idmap_cache.uid2sid_winname.winname_num;
4627369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
4637369SJulian.Pullen@Sun.COM 
4647369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
4657369SJulian.Pullen@Sun.COM 	*sidbygid = idmap_cache.gid2sid_winname.sid_num;
4667369SJulian.Pullen@Sun.COM 	*winnamebygid = idmap_cache.gid2sid_winname.winname_num;
4677369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
4687369SJulian.Pullen@Sun.COM 
4697369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
4707369SJulian.Pullen@Sun.COM 	*uidbywinname = idmap_cache.winname2uid_gid.uid_num;
4717369SJulian.Pullen@Sun.COM 	*gidbywinname = idmap_cache.winname2uid_gid.gid_num;
4727369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
4737369SJulian.Pullen@Sun.COM }
4747369SJulian.Pullen@Sun.COM 
4757369SJulian.Pullen@Sun.COM 
4767369SJulian.Pullen@Sun.COM idmap_stat
idmap_cache_lookup_uidbysid(const char * sid_prefix,idmap_rid_t rid,uid_t * uid)4777369SJulian.Pullen@Sun.COM idmap_cache_lookup_uidbysid(const char *sid_prefix,
4787369SJulian.Pullen@Sun.COM 			idmap_rid_t rid, uid_t *uid)
4797369SJulian.Pullen@Sun.COM {
4807369SJulian.Pullen@Sun.COM 	sid2uid_gid_t	entry;
4817369SJulian.Pullen@Sun.COM 	sid2uid_gid_t	*result;
4827369SJulian.Pullen@Sun.COM 	avl_index_t	where;
4837369SJulian.Pullen@Sun.COM 	int		status = IDMAP_ERR_NOMAPPING;
4847369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
4857369SJulian.Pullen@Sun.COM 
4867369SJulian.Pullen@Sun.COM 	entry.sid_prefix = sid_prefix;
4877369SJulian.Pullen@Sun.COM 	entry.rid = rid;
4887369SJulian.Pullen@Sun.COM 
4897369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
4907369SJulian.Pullen@Sun.COM 
4917369SJulian.Pullen@Sun.COM 	result = avl_find(&idmap_cache.sid2uid_gid.tree, &entry, &where);
4927369SJulian.Pullen@Sun.COM 	if (result != NULL) {
4937369SJulian.Pullen@Sun.COM 		list_move(&idmap_cache.sid2uid_gid.head, result);
4947369SJulian.Pullen@Sun.COM 		if (result->uid != UNDEF_UID && result->uid_ttl > now) {
4957369SJulian.Pullen@Sun.COM 			*uid = result->uid;
4967369SJulian.Pullen@Sun.COM 			status = IDMAP_SUCCESS;
4977369SJulian.Pullen@Sun.COM 		}
4987369SJulian.Pullen@Sun.COM 	}
4997369SJulian.Pullen@Sun.COM 
5007369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
5017369SJulian.Pullen@Sun.COM 
5027369SJulian.Pullen@Sun.COM 	return (status);
5037369SJulian.Pullen@Sun.COM }
5047369SJulian.Pullen@Sun.COM 
5057369SJulian.Pullen@Sun.COM 
5067369SJulian.Pullen@Sun.COM 
5077369SJulian.Pullen@Sun.COM idmap_stat
idmap_cache_lookup_gidbysid(const char * sid_prefix,idmap_rid_t rid,gid_t * gid)5087369SJulian.Pullen@Sun.COM idmap_cache_lookup_gidbysid(const char *sid_prefix,
5097369SJulian.Pullen@Sun.COM 			idmap_rid_t rid, gid_t *gid)
5107369SJulian.Pullen@Sun.COM {
5117369SJulian.Pullen@Sun.COM 	sid2uid_gid_t	entry;
5127369SJulian.Pullen@Sun.COM 	sid2uid_gid_t	*result;
5137369SJulian.Pullen@Sun.COM 	avl_index_t	where;
5147369SJulian.Pullen@Sun.COM 	int		status = IDMAP_ERR_NOMAPPING;
5157369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
5167369SJulian.Pullen@Sun.COM 
5177369SJulian.Pullen@Sun.COM 	entry.sid_prefix = sid_prefix;
5187369SJulian.Pullen@Sun.COM 	entry.rid = rid;
5197369SJulian.Pullen@Sun.COM 
5207369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
5217369SJulian.Pullen@Sun.COM 
5227369SJulian.Pullen@Sun.COM 	result = avl_find(&idmap_cache.sid2uid_gid.tree, &entry, &where);
5237369SJulian.Pullen@Sun.COM 	if (result != NULL) {
5247369SJulian.Pullen@Sun.COM 		list_move(&idmap_cache.sid2uid_gid.head, result);
5257369SJulian.Pullen@Sun.COM 		if (result->gid != UNDEF_GID && result->gid_ttl > now) {
5267369SJulian.Pullen@Sun.COM 			*gid = result->gid;
5277369SJulian.Pullen@Sun.COM 			status = IDMAP_SUCCESS;
5287369SJulian.Pullen@Sun.COM 		}
5297369SJulian.Pullen@Sun.COM 	}
5307369SJulian.Pullen@Sun.COM 
5317369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
5327369SJulian.Pullen@Sun.COM 
5337369SJulian.Pullen@Sun.COM 	return (status);
5347369SJulian.Pullen@Sun.COM }
5357369SJulian.Pullen@Sun.COM 
5367369SJulian.Pullen@Sun.COM 
5377369SJulian.Pullen@Sun.COM 
5387369SJulian.Pullen@Sun.COM 
5397369SJulian.Pullen@Sun.COM idmap_stat
idmap_cache_lookup_pidbysid(const char * sid_prefix,idmap_rid_t rid,uid_t * pid,int * is_user)5407369SJulian.Pullen@Sun.COM idmap_cache_lookup_pidbysid(const char *sid_prefix,
5417369SJulian.Pullen@Sun.COM 			idmap_rid_t rid, uid_t *pid, int *is_user)
5427369SJulian.Pullen@Sun.COM {
5437369SJulian.Pullen@Sun.COM 	sid2uid_gid_t	entry;
5447369SJulian.Pullen@Sun.COM 	sid2uid_gid_t	*result;
5457369SJulian.Pullen@Sun.COM 	avl_index_t	where;
5467369SJulian.Pullen@Sun.COM 	int		status = IDMAP_ERR_NOMAPPING;
5477369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
5487369SJulian.Pullen@Sun.COM 
5497369SJulian.Pullen@Sun.COM 	entry.sid_prefix = sid_prefix;
5507369SJulian.Pullen@Sun.COM 	entry.rid = rid;
5517369SJulian.Pullen@Sun.COM 
5527369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
5537369SJulian.Pullen@Sun.COM 
5547369SJulian.Pullen@Sun.COM 	result = avl_find(&idmap_cache.sid2uid_gid.tree, &entry, &where);
5557369SJulian.Pullen@Sun.COM 	if (result != NULL) {
5567369SJulian.Pullen@Sun.COM 		list_move(&idmap_cache.sid2uid_gid.head, result);
5577369SJulian.Pullen@Sun.COM 		if (result->is_user != UNDEF_ISUSER) {
5587369SJulian.Pullen@Sun.COM 			*is_user = result->is_user;
5597369SJulian.Pullen@Sun.COM 			if (result->is_user && result->uid_ttl > now) {
5607369SJulian.Pullen@Sun.COM 				*pid = result->uid;
5617369SJulian.Pullen@Sun.COM 				status = IDMAP_SUCCESS;
5627369SJulian.Pullen@Sun.COM 			} else if (!result->is_user && result->gid_ttl > now) {
5637369SJulian.Pullen@Sun.COM 				*pid = result->gid;
5647369SJulian.Pullen@Sun.COM 				status = IDMAP_SUCCESS;
5657369SJulian.Pullen@Sun.COM 			}
5667369SJulian.Pullen@Sun.COM 		}
5677369SJulian.Pullen@Sun.COM 	}
5687369SJulian.Pullen@Sun.COM 
5697369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
5707369SJulian.Pullen@Sun.COM 
5717369SJulian.Pullen@Sun.COM 	return (status);
5727369SJulian.Pullen@Sun.COM }
5737369SJulian.Pullen@Sun.COM 
5747369SJulian.Pullen@Sun.COM 
5757369SJulian.Pullen@Sun.COM 
5767369SJulian.Pullen@Sun.COM idmap_stat
idmap_cache_lookup_sidbyuid(char ** sid_prefix,idmap_rid_t * rid,uid_t uid)5777369SJulian.Pullen@Sun.COM idmap_cache_lookup_sidbyuid(char **sid_prefix,
5787369SJulian.Pullen@Sun.COM 			idmap_rid_t *rid, uid_t uid)
5797369SJulian.Pullen@Sun.COM {
5807369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	entry;
5817369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	*result;
5827369SJulian.Pullen@Sun.COM 	avl_index_t	where;
5837369SJulian.Pullen@Sun.COM 	int		status = IDMAP_ERR_NOMAPPING;
5847369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
5857369SJulian.Pullen@Sun.COM 
5867369SJulian.Pullen@Sun.COM 	entry.pid = uid;
5877369SJulian.Pullen@Sun.COM 
5887369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
5897369SJulian.Pullen@Sun.COM 
5907369SJulian.Pullen@Sun.COM 	result = avl_find(&idmap_cache.uid2sid_winname.tree, &entry, &where);
5917369SJulian.Pullen@Sun.COM 	if (result != NULL) {
5927369SJulian.Pullen@Sun.COM 		list_move(&idmap_cache.uid2sid_winname.head, result);
5937369SJulian.Pullen@Sun.COM 		if (result->sid_ttl > now) {
5947369SJulian.Pullen@Sun.COM 			*rid = result->rid;
5957369SJulian.Pullen@Sun.COM 			*sid_prefix = strdup(result->sid_prefix);
5967369SJulian.Pullen@Sun.COM 			if (*sid_prefix != NULL)
5977369SJulian.Pullen@Sun.COM 				status = IDMAP_SUCCESS;
5987369SJulian.Pullen@Sun.COM 			else
5997369SJulian.Pullen@Sun.COM 				status = IDMAP_ERR_MEMORY;
6007369SJulian.Pullen@Sun.COM 		}
6017369SJulian.Pullen@Sun.COM 	}
6027369SJulian.Pullen@Sun.COM 
6037369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
6047369SJulian.Pullen@Sun.COM 
6057369SJulian.Pullen@Sun.COM 	return (status);
6067369SJulian.Pullen@Sun.COM }
6077369SJulian.Pullen@Sun.COM 
6087369SJulian.Pullen@Sun.COM idmap_stat
idmap_cache_lookup_sidbygid(char ** sid_prefix,idmap_rid_t * rid,gid_t gid)6097369SJulian.Pullen@Sun.COM idmap_cache_lookup_sidbygid(char **sid_prefix,
6107369SJulian.Pullen@Sun.COM 			idmap_rid_t *rid, gid_t gid)
6117369SJulian.Pullen@Sun.COM {
6127369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	entry;
6137369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	*result;
6147369SJulian.Pullen@Sun.COM 	avl_index_t	where;
6157369SJulian.Pullen@Sun.COM 	int		status = IDMAP_ERR_NOMAPPING;
6167369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
6177369SJulian.Pullen@Sun.COM 
6187369SJulian.Pullen@Sun.COM 	entry.pid = gid;
6197369SJulian.Pullen@Sun.COM 
6207369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
6217369SJulian.Pullen@Sun.COM 
6227369SJulian.Pullen@Sun.COM 	result = avl_find(&idmap_cache.gid2sid_winname.tree, &entry, &where);
6237369SJulian.Pullen@Sun.COM 	if (result != NULL) {
6247369SJulian.Pullen@Sun.COM 		list_move(&idmap_cache.gid2sid_winname.head, result);
6257369SJulian.Pullen@Sun.COM 		if (result->sid_ttl > now) {
6267369SJulian.Pullen@Sun.COM 			*rid = result->rid;
6277369SJulian.Pullen@Sun.COM 			*sid_prefix = strdup(result->sid_prefix);
6287369SJulian.Pullen@Sun.COM 			if (*sid_prefix != NULL)
6297369SJulian.Pullen@Sun.COM 				status = IDMAP_SUCCESS;
6307369SJulian.Pullen@Sun.COM 			else
6317369SJulian.Pullen@Sun.COM 				status = IDMAP_ERR_MEMORY;
6327369SJulian.Pullen@Sun.COM 		}
6337369SJulian.Pullen@Sun.COM 	}
6347369SJulian.Pullen@Sun.COM 
6357369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
6367369SJulian.Pullen@Sun.COM 
6377369SJulian.Pullen@Sun.COM 	return (status);
6387369SJulian.Pullen@Sun.COM }
6397369SJulian.Pullen@Sun.COM 
6407369SJulian.Pullen@Sun.COM 
6417369SJulian.Pullen@Sun.COM idmap_stat
idmap_cache_lookup_winnamebyuid(char ** name,char ** domain,uid_t uid)6427369SJulian.Pullen@Sun.COM idmap_cache_lookup_winnamebyuid(char **name, char **domain, uid_t uid)
6437369SJulian.Pullen@Sun.COM {
6447369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	entry;
6457369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	*result;
6467369SJulian.Pullen@Sun.COM 	avl_index_t	where;
6477369SJulian.Pullen@Sun.COM 	int		status = IDMAP_ERR_NOMAPPING;
6487369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
6497369SJulian.Pullen@Sun.COM 
6507369SJulian.Pullen@Sun.COM 	entry.pid = uid;
6517369SJulian.Pullen@Sun.COM 
6527369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
6537369SJulian.Pullen@Sun.COM 
6547369SJulian.Pullen@Sun.COM 	result = avl_find(&idmap_cache.uid2sid_winname.tree, &entry, &where);
6557369SJulian.Pullen@Sun.COM 	if (result != NULL) {
6567369SJulian.Pullen@Sun.COM 		list_move(&idmap_cache.uid2sid_winname.head, result);
6577369SJulian.Pullen@Sun.COM 		if (result->winname_ttl > now) {
6587369SJulian.Pullen@Sun.COM 			*name = strdup(result->winname);
6597369SJulian.Pullen@Sun.COM 			if (*name != NULL) {
6607369SJulian.Pullen@Sun.COM 				if (domain != NULL) {
6617369SJulian.Pullen@Sun.COM 					if (result->windomain != NULL) {
6627369SJulian.Pullen@Sun.COM 						*domain =
6637369SJulian.Pullen@Sun.COM 						    strdup(result->windomain);
6647369SJulian.Pullen@Sun.COM 						if (*domain != NULL)
6657369SJulian.Pullen@Sun.COM 							status = IDMAP_SUCCESS;
6667369SJulian.Pullen@Sun.COM 						else
6677369SJulian.Pullen@Sun.COM 							status =
6687369SJulian.Pullen@Sun.COM 							    IDMAP_ERR_MEMORY;
6697369SJulian.Pullen@Sun.COM 					} else {
6707369SJulian.Pullen@Sun.COM 						*domain = NULL;
6717369SJulian.Pullen@Sun.COM 						status = IDMAP_SUCCESS;
6727369SJulian.Pullen@Sun.COM 					}
6737369SJulian.Pullen@Sun.COM 				} else
6747369SJulian.Pullen@Sun.COM 					status = IDMAP_SUCCESS;
6757369SJulian.Pullen@Sun.COM 			} else
6767369SJulian.Pullen@Sun.COM 				status = IDMAP_ERR_MEMORY;
6777369SJulian.Pullen@Sun.COM 		}
6787369SJulian.Pullen@Sun.COM 	}
6797369SJulian.Pullen@Sun.COM 
6807369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
6817369SJulian.Pullen@Sun.COM 
6827369SJulian.Pullen@Sun.COM 	return (status);
6837369SJulian.Pullen@Sun.COM }
6847369SJulian.Pullen@Sun.COM 
6857369SJulian.Pullen@Sun.COM 
6867369SJulian.Pullen@Sun.COM idmap_stat
idmap_cache_lookup_winnamebygid(char ** name,char ** domain,gid_t gid)6877369SJulian.Pullen@Sun.COM idmap_cache_lookup_winnamebygid(char **name, char **domain, gid_t gid)
6887369SJulian.Pullen@Sun.COM {
6897369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	entry;
6907369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	*result;
6917369SJulian.Pullen@Sun.COM 	avl_index_t	where;
6927369SJulian.Pullen@Sun.COM 	int		status = IDMAP_ERR_NOMAPPING;
6937369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
6947369SJulian.Pullen@Sun.COM 
6957369SJulian.Pullen@Sun.COM 	entry.pid = gid;
6967369SJulian.Pullen@Sun.COM 
6977369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
6987369SJulian.Pullen@Sun.COM 
6997369SJulian.Pullen@Sun.COM 	result = avl_find(&idmap_cache.gid2sid_winname.tree, &entry, &where);
7007369SJulian.Pullen@Sun.COM 	if (result != NULL) {
7017369SJulian.Pullen@Sun.COM 		list_move(&idmap_cache.gid2sid_winname.head, result);
7027369SJulian.Pullen@Sun.COM 		if (result->winname_ttl > now) {
7037369SJulian.Pullen@Sun.COM 			*name = strdup(result->winname);
7047369SJulian.Pullen@Sun.COM 			if (*name != NULL) {
7057369SJulian.Pullen@Sun.COM 				if (domain != NULL) {
7067369SJulian.Pullen@Sun.COM 					if (result->windomain != NULL) {
7077369SJulian.Pullen@Sun.COM 						*domain =
7087369SJulian.Pullen@Sun.COM 						    strdup(result->windomain);
7097369SJulian.Pullen@Sun.COM 						if (*domain != NULL)
7107369SJulian.Pullen@Sun.COM 							status = IDMAP_SUCCESS;
7117369SJulian.Pullen@Sun.COM 						else
7127369SJulian.Pullen@Sun.COM 							status =
7137369SJulian.Pullen@Sun.COM 							    IDMAP_ERR_MEMORY;
7147369SJulian.Pullen@Sun.COM 					} else {
7157369SJulian.Pullen@Sun.COM 						*domain = NULL;
7167369SJulian.Pullen@Sun.COM 						status = IDMAP_SUCCESS;
7177369SJulian.Pullen@Sun.COM 					}
7187369SJulian.Pullen@Sun.COM 				} else
7197369SJulian.Pullen@Sun.COM 					status = IDMAP_SUCCESS;
7207369SJulian.Pullen@Sun.COM 			} else
7217369SJulian.Pullen@Sun.COM 				status = IDMAP_ERR_MEMORY;
7227369SJulian.Pullen@Sun.COM 		}
7237369SJulian.Pullen@Sun.COM 	}
7247369SJulian.Pullen@Sun.COM 
7257369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
7267369SJulian.Pullen@Sun.COM 
7277369SJulian.Pullen@Sun.COM 	return (status);
7287369SJulian.Pullen@Sun.COM }
7297369SJulian.Pullen@Sun.COM 
7307369SJulian.Pullen@Sun.COM 
7317369SJulian.Pullen@Sun.COM idmap_stat
idmap_cache_lookup_uidbywinname(const char * name,const char * domain,uid_t * uid)7327369SJulian.Pullen@Sun.COM idmap_cache_lookup_uidbywinname(const char *name, const char *domain,
7337369SJulian.Pullen@Sun.COM 			uid_t *uid)
7347369SJulian.Pullen@Sun.COM {
7357369SJulian.Pullen@Sun.COM 	winname2uid_gid_t	entry;
7367369SJulian.Pullen@Sun.COM 	winname2uid_gid_t	*result;
7377369SJulian.Pullen@Sun.COM 	avl_index_t	where;
7387369SJulian.Pullen@Sun.COM 	int		status = IDMAP_ERR_NOMAPPING;
7397369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
7407369SJulian.Pullen@Sun.COM 
7417369SJulian.Pullen@Sun.COM 	entry.winname = name;
7427369SJulian.Pullen@Sun.COM 	entry.windomain = domain;
7437369SJulian.Pullen@Sun.COM 
7447369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
7457369SJulian.Pullen@Sun.COM 
7467369SJulian.Pullen@Sun.COM 	result = avl_find(&idmap_cache.winname2uid_gid.tree, &entry, &where);
7477369SJulian.Pullen@Sun.COM 	if (result != NULL) {
7487369SJulian.Pullen@Sun.COM 		list_move(&idmap_cache.winname2uid_gid.head, result);
7497369SJulian.Pullen@Sun.COM 		if (result->uid != UNDEF_UID && result->uid_ttl > now) {
7507369SJulian.Pullen@Sun.COM 			*uid = result->uid;
7517369SJulian.Pullen@Sun.COM 			status = IDMAP_SUCCESS;
7527369SJulian.Pullen@Sun.COM 		}
7537369SJulian.Pullen@Sun.COM 	}
7547369SJulian.Pullen@Sun.COM 
7557369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
7567369SJulian.Pullen@Sun.COM 
7577369SJulian.Pullen@Sun.COM 	return (status);
7587369SJulian.Pullen@Sun.COM }
7597369SJulian.Pullen@Sun.COM 
7607369SJulian.Pullen@Sun.COM 
7617369SJulian.Pullen@Sun.COM idmap_stat
idmap_cache_lookup_gidbywinname(const char * name,const char * domain,gid_t * gid)7627369SJulian.Pullen@Sun.COM idmap_cache_lookup_gidbywinname(const char *name, const char *domain,
7637369SJulian.Pullen@Sun.COM 			gid_t *gid)
7647369SJulian.Pullen@Sun.COM {
7657369SJulian.Pullen@Sun.COM 	winname2uid_gid_t	entry;
7667369SJulian.Pullen@Sun.COM 	winname2uid_gid_t	*result;
7677369SJulian.Pullen@Sun.COM 	avl_index_t	where;
7687369SJulian.Pullen@Sun.COM 	int		status = IDMAP_ERR_NOMAPPING;
7697369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
7707369SJulian.Pullen@Sun.COM 
7717369SJulian.Pullen@Sun.COM 	entry.winname = name;
7727369SJulian.Pullen@Sun.COM 	entry.windomain = domain;
7737369SJulian.Pullen@Sun.COM 
7747369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
7757369SJulian.Pullen@Sun.COM 
7767369SJulian.Pullen@Sun.COM 	result = avl_find(&idmap_cache.winname2uid_gid.tree, &entry, &where);
7777369SJulian.Pullen@Sun.COM 	if (result != NULL) {
7787369SJulian.Pullen@Sun.COM 		list_move(&idmap_cache.winname2uid_gid.head, result);
7797369SJulian.Pullen@Sun.COM 		if (result->gid != UNDEF_GID && result->gid_ttl > now) {
7807369SJulian.Pullen@Sun.COM 			*gid = result->gid;
7817369SJulian.Pullen@Sun.COM 			status = IDMAP_SUCCESS;
7827369SJulian.Pullen@Sun.COM 		}
7837369SJulian.Pullen@Sun.COM 	}
7847369SJulian.Pullen@Sun.COM 
7857369SJulian.Pullen@Sun.COM 	(void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
7867369SJulian.Pullen@Sun.COM 
7877369SJulian.Pullen@Sun.COM 	return (status);
7887369SJulian.Pullen@Sun.COM }
7897369SJulian.Pullen@Sun.COM 
7907369SJulian.Pullen@Sun.COM 
7917369SJulian.Pullen@Sun.COM void
idmap_cache_add_sid2uid(const char * sid_prefix,idmap_rid_t rid,uid_t uid,int direction)7927369SJulian.Pullen@Sun.COM idmap_cache_add_sid2uid(const char *sid_prefix,
7937369SJulian.Pullen@Sun.COM 			idmap_rid_t rid, uid_t uid, int direction)
7947369SJulian.Pullen@Sun.COM 
7957369SJulian.Pullen@Sun.COM {
7967369SJulian.Pullen@Sun.COM 	avl_index_t	where;
7977369SJulian.Pullen@Sun.COM 	time_t		ttl = CACHE_TTL + time(NULL);
7987369SJulian.Pullen@Sun.COM 
7997369SJulian.Pullen@Sun.COM 
8007369SJulian.Pullen@Sun.COM 	if (direction == IDMAP_DIRECTION_BI ||
8017369SJulian.Pullen@Sun.COM 	    direction == IDMAP_DIRECTION_W2U) {
8027369SJulian.Pullen@Sun.COM 		sid2uid_gid_t	find;
8037369SJulian.Pullen@Sun.COM 		sid2uid_gid_t	*result;
8047369SJulian.Pullen@Sun.COM 		sid2uid_gid_t	*new;
8057369SJulian.Pullen@Sun.COM 
8067369SJulian.Pullen@Sun.COM 		find.sid_prefix = sid_prefix;
8077369SJulian.Pullen@Sun.COM 		find.rid = rid;
8087369SJulian.Pullen@Sun.COM 
8097369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
8107369SJulian.Pullen@Sun.COM 		result = avl_find(&idmap_cache.sid2uid_gid.tree, &find, &where);
8117369SJulian.Pullen@Sun.COM 
8127369SJulian.Pullen@Sun.COM 		if (result) {
8137369SJulian.Pullen@Sun.COM 			if (result->uid_ttl == 0)
8147369SJulian.Pullen@Sun.COM 				idmap_cache.sid2uid_gid.uid_num++;
8157369SJulian.Pullen@Sun.COM 			result->uid = uid;
8167369SJulian.Pullen@Sun.COM 			result->uid_ttl = ttl;
8177369SJulian.Pullen@Sun.COM 		} else {
8187369SJulian.Pullen@Sun.COM 			new = malloc(sizeof (sid2uid_gid_t));
8197369SJulian.Pullen@Sun.COM 			if (new == NULL)
8207369SJulian.Pullen@Sun.COM 				goto exit_sid2uid_gid;
8217369SJulian.Pullen@Sun.COM 			new->sid_prefix = strdup(sid_prefix);
8227369SJulian.Pullen@Sun.COM 			if (new->sid_prefix == NULL) {
8237369SJulian.Pullen@Sun.COM 				free(new);
8247369SJulian.Pullen@Sun.COM 				goto exit_sid2uid_gid;
8257369SJulian.Pullen@Sun.COM 			}
8267369SJulian.Pullen@Sun.COM 			new->rid = rid;
8277369SJulian.Pullen@Sun.COM 			new->uid = uid;
8287369SJulian.Pullen@Sun.COM 			new->uid_ttl = ttl;
8297369SJulian.Pullen@Sun.COM 			new->gid = UNDEF_GID;
8307369SJulian.Pullen@Sun.COM 			new->gid_ttl = 0;
8317369SJulian.Pullen@Sun.COM 			new->is_user = UNDEF_ISUSER; /* Unknown */
8327369SJulian.Pullen@Sun.COM 			idmap_cache.sid2uid_gid.uid_num++;
8337369SJulian.Pullen@Sun.COM 
8347369SJulian.Pullen@Sun.COM 			list_insert(&idmap_cache.sid2uid_gid.head, new);
8357369SJulian.Pullen@Sun.COM 			avl_insert(&idmap_cache.sid2uid_gid.tree, new, where);
8367369SJulian.Pullen@Sun.COM 		}
8377369SJulian.Pullen@Sun.COM 		if ((avl_numnodes(&idmap_cache.sid2uid_gid.tree) >
8387369SJulian.Pullen@Sun.COM 		    CACHE_UID_GID_TRIGGER_SIZE) &&
8397369SJulian.Pullen@Sun.COM 		    (idmap_cache.sid2uid_gid.purge_time + CACHE_PURGE_INTERVAL <
8407369SJulian.Pullen@Sun.COM 		    time(NULL)))
8417369SJulian.Pullen@Sun.COM 			idmap_purge_sid2uid_gid_cache(&idmap_cache.sid2uid_gid,
8427369SJulian.Pullen@Sun.COM 			    CACHE_UID_GID_TRIGGER_SIZE);
8437369SJulian.Pullen@Sun.COM 
8447369SJulian.Pullen@Sun.COM exit_sid2uid_gid:
8457369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
8467369SJulian.Pullen@Sun.COM 	}
8477369SJulian.Pullen@Sun.COM 
8487369SJulian.Pullen@Sun.COM 	if (direction == IDMAP_DIRECTION_BI ||
8497369SJulian.Pullen@Sun.COM 	    direction == IDMAP_DIRECTION_U2W) {
8507369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	find;
8517369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	*result;
8527369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	*new;
8537369SJulian.Pullen@Sun.COM 
8547369SJulian.Pullen@Sun.COM 		find.pid = uid;
8557369SJulian.Pullen@Sun.COM 
8567369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
8577369SJulian.Pullen@Sun.COM 		result = avl_find(&idmap_cache.uid2sid_winname.tree, &find,
8587369SJulian.Pullen@Sun.COM 		    &where);
8597369SJulian.Pullen@Sun.COM 
8607369SJulian.Pullen@Sun.COM 		if (result) {
8617369SJulian.Pullen@Sun.COM 			if (update_str(&result->sid_prefix, sid_prefix) != 0)
8627369SJulian.Pullen@Sun.COM 				goto exit_pid2sid_winname;
8637369SJulian.Pullen@Sun.COM 			if (result->sid_ttl == 0)
8647369SJulian.Pullen@Sun.COM 					idmap_cache.uid2sid_winname.sid_num++;
8657369SJulian.Pullen@Sun.COM 			result->rid = rid;
8667369SJulian.Pullen@Sun.COM 			result->sid_ttl = ttl;
8677369SJulian.Pullen@Sun.COM 		} else {
8687369SJulian.Pullen@Sun.COM 			new = malloc(sizeof (pid2sid_winname_t));
8697369SJulian.Pullen@Sun.COM 			if (new == NULL)
8707369SJulian.Pullen@Sun.COM 				goto exit_pid2sid_winname;
8717369SJulian.Pullen@Sun.COM 			new->pid = uid;
8727369SJulian.Pullen@Sun.COM 			new->sid_prefix = strdup(sid_prefix);
8737369SJulian.Pullen@Sun.COM 			if (new->sid_prefix == NULL) {
8747369SJulian.Pullen@Sun.COM 				free(new);
8757369SJulian.Pullen@Sun.COM 				goto exit_pid2sid_winname;
8767369SJulian.Pullen@Sun.COM 			}
8777369SJulian.Pullen@Sun.COM 			new->rid = rid;
8787369SJulian.Pullen@Sun.COM 			new->sid_ttl = ttl;
8797369SJulian.Pullen@Sun.COM 			new->winname = NULL;
8807369SJulian.Pullen@Sun.COM 			new->windomain = NULL;
8817369SJulian.Pullen@Sun.COM 			new->winname_ttl = 0;
8827369SJulian.Pullen@Sun.COM 			idmap_cache.uid2sid_winname.sid_num ++;
8837369SJulian.Pullen@Sun.COM 
8847369SJulian.Pullen@Sun.COM 			list_insert(&idmap_cache.uid2sid_winname.head, new);
8857369SJulian.Pullen@Sun.COM 			avl_insert(&idmap_cache.uid2sid_winname.tree, new,
8867369SJulian.Pullen@Sun.COM 			    where);
8877369SJulian.Pullen@Sun.COM 		}
8887369SJulian.Pullen@Sun.COM 		if ((avl_numnodes(&idmap_cache.uid2sid_winname.tree) >
8897369SJulian.Pullen@Sun.COM 		    CACHE_UID_TRIGGER_SIZE) &&
8907369SJulian.Pullen@Sun.COM 		    (idmap_cache.uid2sid_winname.purge_time +
8917369SJulian.Pullen@Sun.COM 		    CACHE_PURGE_INTERVAL < time(NULL)))
8927369SJulian.Pullen@Sun.COM 			idmap_purge_pid2sid_winname_cache(
8937369SJulian.Pullen@Sun.COM 			    &idmap_cache.uid2sid_winname,
8947369SJulian.Pullen@Sun.COM 			    CACHE_UID_TRIGGER_SIZE);
8957369SJulian.Pullen@Sun.COM 
8967369SJulian.Pullen@Sun.COM 
8977369SJulian.Pullen@Sun.COM exit_pid2sid_winname:
8987369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
8997369SJulian.Pullen@Sun.COM 	}
9007369SJulian.Pullen@Sun.COM }
9017369SJulian.Pullen@Sun.COM 
9027369SJulian.Pullen@Sun.COM 
9037369SJulian.Pullen@Sun.COM 
9047369SJulian.Pullen@Sun.COM void
idmap_cache_add_sid2gid(const char * sid_prefix,idmap_rid_t rid,gid_t gid,int direction)9057369SJulian.Pullen@Sun.COM idmap_cache_add_sid2gid(const char *sid_prefix,
9067369SJulian.Pullen@Sun.COM 			idmap_rid_t rid, gid_t gid, int direction)
9077369SJulian.Pullen@Sun.COM {
9087369SJulian.Pullen@Sun.COM 	avl_index_t	where;
9097369SJulian.Pullen@Sun.COM 	time_t		ttl = CACHE_TTL + time(NULL);
9107369SJulian.Pullen@Sun.COM 
9117369SJulian.Pullen@Sun.COM 
9127369SJulian.Pullen@Sun.COM 	if (direction == IDMAP_DIRECTION_BI ||
9137369SJulian.Pullen@Sun.COM 	    direction == IDMAP_DIRECTION_W2U) {
9147369SJulian.Pullen@Sun.COM 		sid2uid_gid_t	find;
9157369SJulian.Pullen@Sun.COM 		sid2uid_gid_t	*result;
9167369SJulian.Pullen@Sun.COM 		sid2uid_gid_t	*new;
9177369SJulian.Pullen@Sun.COM 
9187369SJulian.Pullen@Sun.COM 		find.sid_prefix = sid_prefix;
9197369SJulian.Pullen@Sun.COM 		find.rid = rid;
9207369SJulian.Pullen@Sun.COM 
9217369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
9227369SJulian.Pullen@Sun.COM 		result = avl_find(&idmap_cache.sid2uid_gid.tree, &find, &where);
9237369SJulian.Pullen@Sun.COM 
9247369SJulian.Pullen@Sun.COM 		if (result) {
9257369SJulian.Pullen@Sun.COM 			if (result->gid_ttl == 0)
9267369SJulian.Pullen@Sun.COM 				idmap_cache.sid2uid_gid.gid_num++;
9277369SJulian.Pullen@Sun.COM 			result->gid = gid;
9287369SJulian.Pullen@Sun.COM 			result->gid_ttl = ttl;
9297369SJulian.Pullen@Sun.COM 		} else {
9307369SJulian.Pullen@Sun.COM 			new = malloc(sizeof (sid2uid_gid_t));
9317369SJulian.Pullen@Sun.COM 			if (new == NULL)
9327369SJulian.Pullen@Sun.COM 				goto exit_sid2uid_gid;
9337369SJulian.Pullen@Sun.COM 			new->sid_prefix = strdup(sid_prefix);
9347369SJulian.Pullen@Sun.COM 			if (new->sid_prefix == NULL) {
9357369SJulian.Pullen@Sun.COM 				free(new);
9367369SJulian.Pullen@Sun.COM 				goto exit_sid2uid_gid;
9377369SJulian.Pullen@Sun.COM 			}
9387369SJulian.Pullen@Sun.COM 			new->rid = rid;
9397369SJulian.Pullen@Sun.COM 			new->uid = UNDEF_UID;
9407369SJulian.Pullen@Sun.COM 			new->uid_ttl = 0;
9417369SJulian.Pullen@Sun.COM 			new->gid = gid;
9427369SJulian.Pullen@Sun.COM 			new->gid_ttl = ttl;
9437369SJulian.Pullen@Sun.COM 			new->is_user = UNDEF_ISUSER; /* Unknown */
9447369SJulian.Pullen@Sun.COM 			idmap_cache.sid2uid_gid.gid_num++;
9457369SJulian.Pullen@Sun.COM 
9467369SJulian.Pullen@Sun.COM 			list_insert(&idmap_cache.sid2uid_gid.head, new);
9477369SJulian.Pullen@Sun.COM 			avl_insert(&idmap_cache.sid2uid_gid.tree, new, where);
9487369SJulian.Pullen@Sun.COM 		}
9497369SJulian.Pullen@Sun.COM 		if ((avl_numnodes(&idmap_cache.sid2uid_gid.tree) >
9507369SJulian.Pullen@Sun.COM 		    CACHE_UID_GID_TRIGGER_SIZE) &&
9517369SJulian.Pullen@Sun.COM 		    (idmap_cache.sid2uid_gid.purge_time + CACHE_PURGE_INTERVAL <
9527369SJulian.Pullen@Sun.COM 		    time(NULL)))
9537369SJulian.Pullen@Sun.COM 			idmap_purge_sid2uid_gid_cache(&idmap_cache.sid2uid_gid,
9547369SJulian.Pullen@Sun.COM 			    CACHE_UID_GID_TRIGGER_SIZE);
9557369SJulian.Pullen@Sun.COM 
9567369SJulian.Pullen@Sun.COM exit_sid2uid_gid:
9577369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
9587369SJulian.Pullen@Sun.COM 	}
9597369SJulian.Pullen@Sun.COM 
9607369SJulian.Pullen@Sun.COM 	if (direction == IDMAP_DIRECTION_BI ||
9617369SJulian.Pullen@Sun.COM 	    direction == IDMAP_DIRECTION_U2W) {
9627369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	find;
9637369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	*result;
9647369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	*new;
9657369SJulian.Pullen@Sun.COM 
9667369SJulian.Pullen@Sun.COM 		find.pid = gid;
9677369SJulian.Pullen@Sun.COM 
9687369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
9697369SJulian.Pullen@Sun.COM 		result = avl_find(&idmap_cache.gid2sid_winname.tree, &find,
9707369SJulian.Pullen@Sun.COM 		    &where);
9717369SJulian.Pullen@Sun.COM 
9727369SJulian.Pullen@Sun.COM 		if (result) {
9737369SJulian.Pullen@Sun.COM 			if (update_str(&result->sid_prefix, sid_prefix) != 0)
9747369SJulian.Pullen@Sun.COM 				goto  exit_gid2sid_winname;
9757369SJulian.Pullen@Sun.COM 			if (result->sid_ttl == 0)
9767369SJulian.Pullen@Sun.COM 				idmap_cache.gid2sid_winname.sid_num++;
9777369SJulian.Pullen@Sun.COM 			result->rid = rid;
9787369SJulian.Pullen@Sun.COM 			result->sid_ttl = ttl;
9797369SJulian.Pullen@Sun.COM 		} else {
9807369SJulian.Pullen@Sun.COM 			new = malloc(sizeof (pid2sid_winname_t));
9817369SJulian.Pullen@Sun.COM 			if (new == NULL)
9827369SJulian.Pullen@Sun.COM 				goto exit_gid2sid_winname;
9837369SJulian.Pullen@Sun.COM 			new->sid_prefix = strdup(sid_prefix);
9847369SJulian.Pullen@Sun.COM 			if (new->sid_prefix == NULL) {
9857369SJulian.Pullen@Sun.COM 				free(new);
9867369SJulian.Pullen@Sun.COM 				goto exit_gid2sid_winname;
9877369SJulian.Pullen@Sun.COM 			}
9887369SJulian.Pullen@Sun.COM 			new->rid = rid;
9897369SJulian.Pullen@Sun.COM 			new->pid = gid;
9907369SJulian.Pullen@Sun.COM 			new->sid_ttl = ttl;
9917369SJulian.Pullen@Sun.COM 			new->winname = NULL;
9927369SJulian.Pullen@Sun.COM 			new->windomain = NULL;
9937369SJulian.Pullen@Sun.COM 			new->winname_ttl = 0;
9947369SJulian.Pullen@Sun.COM 			idmap_cache.gid2sid_winname.sid_num++;
9957369SJulian.Pullen@Sun.COM 
9967369SJulian.Pullen@Sun.COM 			list_insert(&idmap_cache.gid2sid_winname.head, new);
9977369SJulian.Pullen@Sun.COM 			avl_insert(&idmap_cache.gid2sid_winname.tree, new,
9987369SJulian.Pullen@Sun.COM 			    where);
9997369SJulian.Pullen@Sun.COM 		}
10007369SJulian.Pullen@Sun.COM 		if ((avl_numnodes(&idmap_cache.gid2sid_winname.tree) >
10017369SJulian.Pullen@Sun.COM 		    CACHE_GID_TRIGGER_SIZE) &&
10027369SJulian.Pullen@Sun.COM 		    (idmap_cache.gid2sid_winname.purge_time +
10037369SJulian.Pullen@Sun.COM 		    CACHE_PURGE_INTERVAL < time(NULL)))
10047369SJulian.Pullen@Sun.COM 			idmap_purge_pid2sid_winname_cache(
10057369SJulian.Pullen@Sun.COM 			    &idmap_cache.gid2sid_winname,
10067369SJulian.Pullen@Sun.COM 			    CACHE_GID_TRIGGER_SIZE);
10077369SJulian.Pullen@Sun.COM 
10087369SJulian.Pullen@Sun.COM exit_gid2sid_winname:
10097369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
10107369SJulian.Pullen@Sun.COM 	}
10117369SJulian.Pullen@Sun.COM }
10127369SJulian.Pullen@Sun.COM 
10137369SJulian.Pullen@Sun.COM 
10147369SJulian.Pullen@Sun.COM void
idmap_cache_add_sid2pid(const char * sid_prefix,idmap_rid_t rid,uid_t pid,int is_user,int direction)10157369SJulian.Pullen@Sun.COM idmap_cache_add_sid2pid(const char *sid_prefix,
10167369SJulian.Pullen@Sun.COM 			idmap_rid_t rid, uid_t pid, int is_user, int direction)
10177369SJulian.Pullen@Sun.COM {
10187369SJulian.Pullen@Sun.COM 	avl_index_t	where;
10197369SJulian.Pullen@Sun.COM 	time_t		ttl = CACHE_TTL + time(NULL);
10207369SJulian.Pullen@Sun.COM 
10217369SJulian.Pullen@Sun.COM 
10227369SJulian.Pullen@Sun.COM 	if (direction == IDMAP_DIRECTION_BI ||
10237369SJulian.Pullen@Sun.COM 	    direction == IDMAP_DIRECTION_W2U) {
10247369SJulian.Pullen@Sun.COM 		sid2uid_gid_t	find;
10257369SJulian.Pullen@Sun.COM 		sid2uid_gid_t	*result;
10267369SJulian.Pullen@Sun.COM 		sid2uid_gid_t	*new;
10277369SJulian.Pullen@Sun.COM 
10287369SJulian.Pullen@Sun.COM 		find.sid_prefix = sid_prefix;
10297369SJulian.Pullen@Sun.COM 		find.rid = rid;
10307369SJulian.Pullen@Sun.COM 
10317369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
10327369SJulian.Pullen@Sun.COM 		result = avl_find(&idmap_cache.sid2uid_gid.tree, &find, &where);
10337369SJulian.Pullen@Sun.COM 
10347369SJulian.Pullen@Sun.COM 		if (result) {
10357369SJulian.Pullen@Sun.COM 			if (result->is_user == UNDEF_ISUSER)
10367369SJulian.Pullen@Sun.COM 				idmap_cache.sid2uid_gid.pid_num++;
10377369SJulian.Pullen@Sun.COM 			result->is_user = is_user;
10387369SJulian.Pullen@Sun.COM 			if (is_user) {
10397369SJulian.Pullen@Sun.COM 				if (result->uid_ttl == 0)
10407369SJulian.Pullen@Sun.COM 					idmap_cache.sid2uid_gid.uid_num++;
10417369SJulian.Pullen@Sun.COM 				result->uid = pid;
10427369SJulian.Pullen@Sun.COM 				result->uid_ttl = ttl;
10437369SJulian.Pullen@Sun.COM 			} else {
10447369SJulian.Pullen@Sun.COM 				if (result->gid_ttl == 0)
10457369SJulian.Pullen@Sun.COM 					idmap_cache.sid2uid_gid.gid_num++;
10467369SJulian.Pullen@Sun.COM 				result->gid = pid;
10477369SJulian.Pullen@Sun.COM 				result->gid_ttl = ttl;
10487369SJulian.Pullen@Sun.COM 			}
10497369SJulian.Pullen@Sun.COM 		} else {
10507369SJulian.Pullen@Sun.COM 			new = malloc(sizeof (sid2uid_gid_t));
10517369SJulian.Pullen@Sun.COM 			if (new == NULL)
10527369SJulian.Pullen@Sun.COM 				goto exit_sid2uid_gid;
10537369SJulian.Pullen@Sun.COM 			new->sid_prefix = strdup(sid_prefix);
10547369SJulian.Pullen@Sun.COM 			if (new->sid_prefix == NULL) {
10557369SJulian.Pullen@Sun.COM 				free(new);
10567369SJulian.Pullen@Sun.COM 				goto exit_sid2uid_gid;
10577369SJulian.Pullen@Sun.COM 			}
10587369SJulian.Pullen@Sun.COM 			new->rid = rid;
10597369SJulian.Pullen@Sun.COM 			new->is_user = is_user;
10607369SJulian.Pullen@Sun.COM 			if (is_user) {
10617369SJulian.Pullen@Sun.COM 				new->uid = pid;
10627369SJulian.Pullen@Sun.COM 				new->uid_ttl = ttl;
10637369SJulian.Pullen@Sun.COM 				new->gid = UNDEF_GID;
10647369SJulian.Pullen@Sun.COM 				new->gid_ttl = 0;
10657369SJulian.Pullen@Sun.COM 				idmap_cache.sid2uid_gid.uid_num++;
10667369SJulian.Pullen@Sun.COM 			} else {
10677369SJulian.Pullen@Sun.COM 				new->uid = UNDEF_UID;
10687369SJulian.Pullen@Sun.COM 				new->uid_ttl = 0;
10697369SJulian.Pullen@Sun.COM 				new->gid = pid;
10707369SJulian.Pullen@Sun.COM 				new->gid_ttl = ttl;
10717369SJulian.Pullen@Sun.COM 				idmap_cache.sid2uid_gid.gid_num++;
10727369SJulian.Pullen@Sun.COM 			}
10737369SJulian.Pullen@Sun.COM 			idmap_cache.sid2uid_gid.pid_num++;
10747369SJulian.Pullen@Sun.COM 
10757369SJulian.Pullen@Sun.COM 			list_insert(&idmap_cache.sid2uid_gid.head, new);
10767369SJulian.Pullen@Sun.COM 			avl_insert(&idmap_cache.sid2uid_gid.tree, new, where);
10777369SJulian.Pullen@Sun.COM 		}
10787369SJulian.Pullen@Sun.COM 		if ((avl_numnodes(&idmap_cache.sid2uid_gid.tree) >
10797369SJulian.Pullen@Sun.COM 		    CACHE_UID_GID_TRIGGER_SIZE) &&
10807369SJulian.Pullen@Sun.COM 		    (idmap_cache.sid2uid_gid.purge_time + CACHE_PURGE_INTERVAL <
10817369SJulian.Pullen@Sun.COM 		    time(NULL)))
10827369SJulian.Pullen@Sun.COM 			idmap_purge_sid2uid_gid_cache(&idmap_cache.sid2uid_gid,
10837369SJulian.Pullen@Sun.COM 			    CACHE_UID_GID_TRIGGER_SIZE);
10847369SJulian.Pullen@Sun.COM 
10857369SJulian.Pullen@Sun.COM exit_sid2uid_gid:
10867369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
10877369SJulian.Pullen@Sun.COM 	}
10887369SJulian.Pullen@Sun.COM 
10897369SJulian.Pullen@Sun.COM 	if (direction == IDMAP_DIRECTION_BI ||
10907369SJulian.Pullen@Sun.COM 	    direction == IDMAP_DIRECTION_U2W) {
10917369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	find;
10927369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	*result;
10937369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	*new;
10947369SJulian.Pullen@Sun.COM 
10957369SJulian.Pullen@Sun.COM 		find.pid = pid;
10967369SJulian.Pullen@Sun.COM 		if (is_user) {
10977369SJulian.Pullen@Sun.COM 			(void) pthread_mutex_lock(
10987369SJulian.Pullen@Sun.COM 			    &idmap_cache.uid2sid_winname.mutex);
10997369SJulian.Pullen@Sun.COM 			result = avl_find(&idmap_cache.uid2sid_winname.tree,
11007369SJulian.Pullen@Sun.COM 			    &find, &where);
11017369SJulian.Pullen@Sun.COM 
11027369SJulian.Pullen@Sun.COM 			if (result) {
11037369SJulian.Pullen@Sun.COM 				if (update_str(&result->sid_prefix, sid_prefix)
11047369SJulian.Pullen@Sun.COM 				    != 0)
11057369SJulian.Pullen@Sun.COM 					goto exit_uid2sid_winname;
11067369SJulian.Pullen@Sun.COM 				if (result->sid_ttl == 0)
11077369SJulian.Pullen@Sun.COM 					idmap_cache.uid2sid_winname.sid_num++;
11087369SJulian.Pullen@Sun.COM 				result->rid = rid;
11097369SJulian.Pullen@Sun.COM 				result->sid_ttl = ttl;
11107369SJulian.Pullen@Sun.COM 			} else {
11117369SJulian.Pullen@Sun.COM 				new = malloc(sizeof (pid2sid_winname_t));
11127369SJulian.Pullen@Sun.COM 				if (new == NULL)
11137369SJulian.Pullen@Sun.COM 					goto exit_uid2sid_winname;
11147369SJulian.Pullen@Sun.COM 				new->sid_prefix = strdup(sid_prefix);
11157369SJulian.Pullen@Sun.COM 				if (new->sid_prefix == NULL) {
11167369SJulian.Pullen@Sun.COM 					free(new);
11177369SJulian.Pullen@Sun.COM 					goto exit_uid2sid_winname;
11187369SJulian.Pullen@Sun.COM 				}
11197369SJulian.Pullen@Sun.COM 				new->rid = rid;
11207369SJulian.Pullen@Sun.COM 				new->pid = pid;
11217369SJulian.Pullen@Sun.COM 				new->sid_ttl = ttl;
11227369SJulian.Pullen@Sun.COM 				new->winname = NULL;
11237369SJulian.Pullen@Sun.COM 				new->windomain = NULL;
11247369SJulian.Pullen@Sun.COM 				idmap_cache.uid2sid_winname.sid_num++;
11257369SJulian.Pullen@Sun.COM 
11267369SJulian.Pullen@Sun.COM 				list_insert(&idmap_cache.uid2sid_winname.head,
11277369SJulian.Pullen@Sun.COM 				    new);
11287369SJulian.Pullen@Sun.COM 				avl_insert(&idmap_cache.uid2sid_winname.tree,
11297369SJulian.Pullen@Sun.COM 				    new, where);
11307369SJulian.Pullen@Sun.COM 			}
11317369SJulian.Pullen@Sun.COM 			if ((avl_numnodes(&idmap_cache.uid2sid_winname.tree) >
11327369SJulian.Pullen@Sun.COM 			    CACHE_UID_TRIGGER_SIZE) &&
11337369SJulian.Pullen@Sun.COM 			    (idmap_cache.uid2sid_winname.purge_time +
11347369SJulian.Pullen@Sun.COM 			    CACHE_PURGE_INTERVAL < time(NULL)))
11357369SJulian.Pullen@Sun.COM 				idmap_purge_pid2sid_winname_cache(
11367369SJulian.Pullen@Sun.COM 				    &idmap_cache.uid2sid_winname,
11377369SJulian.Pullen@Sun.COM 				    CACHE_UID_TRIGGER_SIZE);
11387369SJulian.Pullen@Sun.COM 
11397369SJulian.Pullen@Sun.COM exit_uid2sid_winname:
11407369SJulian.Pullen@Sun.COM 			(void) pthread_mutex_unlock(
11417369SJulian.Pullen@Sun.COM 			    &idmap_cache.uid2sid_winname.mutex);
11427369SJulian.Pullen@Sun.COM 		} else {
11437369SJulian.Pullen@Sun.COM 			(void) pthread_mutex_lock(
11447369SJulian.Pullen@Sun.COM 			    &idmap_cache.gid2sid_winname.mutex);
11457369SJulian.Pullen@Sun.COM 			result = avl_find(&idmap_cache.gid2sid_winname.tree,
11467369SJulian.Pullen@Sun.COM 			    &find, &where);
11477369SJulian.Pullen@Sun.COM 
11487369SJulian.Pullen@Sun.COM 			if (result) {
11497369SJulian.Pullen@Sun.COM 				if (update_str(&result->sid_prefix, sid_prefix)
11507369SJulian.Pullen@Sun.COM 				    != 0)
11517369SJulian.Pullen@Sun.COM 					goto exit_gid2sid_winname;
11527369SJulian.Pullen@Sun.COM 				if (result->sid_ttl == 0)
11537369SJulian.Pullen@Sun.COM 					idmap_cache.gid2sid_winname.sid_num++;
11547369SJulian.Pullen@Sun.COM 				result->rid = rid;
11557369SJulian.Pullen@Sun.COM 				result->sid_ttl = ttl;
11567369SJulian.Pullen@Sun.COM 			} else {
11577369SJulian.Pullen@Sun.COM 				new = malloc(sizeof (pid2sid_winname_t));
11587369SJulian.Pullen@Sun.COM 				if (new == NULL)
11597369SJulian.Pullen@Sun.COM 					goto exit_gid2sid_winname;
11607369SJulian.Pullen@Sun.COM 				new->sid_prefix = strdup(sid_prefix);
11617369SJulian.Pullen@Sun.COM 				if (new->sid_prefix == NULL) {
11627369SJulian.Pullen@Sun.COM 					free(new);
11637369SJulian.Pullen@Sun.COM 					goto exit_gid2sid_winname;
11647369SJulian.Pullen@Sun.COM 				}
11657369SJulian.Pullen@Sun.COM 				new->rid = rid;
11667369SJulian.Pullen@Sun.COM 				new->pid = pid;
11677369SJulian.Pullen@Sun.COM 				new->sid_ttl = ttl;
11687369SJulian.Pullen@Sun.COM 				new->winname = NULL;
11697369SJulian.Pullen@Sun.COM 				new->windomain = NULL;
11707369SJulian.Pullen@Sun.COM 				idmap_cache.gid2sid_winname.sid_num++;
11717369SJulian.Pullen@Sun.COM 
11727369SJulian.Pullen@Sun.COM 				list_insert(&idmap_cache.gid2sid_winname.head,
11737369SJulian.Pullen@Sun.COM 				    new);
11747369SJulian.Pullen@Sun.COM 				avl_insert(&idmap_cache.gid2sid_winname.tree,
11757369SJulian.Pullen@Sun.COM 				    new, where);
11767369SJulian.Pullen@Sun.COM 			}
11777369SJulian.Pullen@Sun.COM 			if ((avl_numnodes(&idmap_cache.gid2sid_winname.tree) >
11787369SJulian.Pullen@Sun.COM 			    CACHE_GID_TRIGGER_SIZE) &&
11797369SJulian.Pullen@Sun.COM 			    (idmap_cache.gid2sid_winname.purge_time +
11807369SJulian.Pullen@Sun.COM 			    CACHE_PURGE_INTERVAL < time(NULL)))
11817369SJulian.Pullen@Sun.COM 				idmap_purge_pid2sid_winname_cache(
11827369SJulian.Pullen@Sun.COM 				    &idmap_cache.gid2sid_winname,
11837369SJulian.Pullen@Sun.COM 				    CACHE_GID_TRIGGER_SIZE);
11847369SJulian.Pullen@Sun.COM exit_gid2sid_winname:
11857369SJulian.Pullen@Sun.COM 			(void) pthread_mutex_unlock(
11867369SJulian.Pullen@Sun.COM 			    &idmap_cache.gid2sid_winname.mutex);
11877369SJulian.Pullen@Sun.COM 		}
11887369SJulian.Pullen@Sun.COM 	}
11897369SJulian.Pullen@Sun.COM }
11907369SJulian.Pullen@Sun.COM 
11917369SJulian.Pullen@Sun.COM 
11927369SJulian.Pullen@Sun.COM 
11937369SJulian.Pullen@Sun.COM void
idmap_cache_add_winname2uid(const char * name,const char * domain,uid_t uid,int direction)11947369SJulian.Pullen@Sun.COM idmap_cache_add_winname2uid(const char *name, const char *domain, uid_t uid,
11957369SJulian.Pullen@Sun.COM 			int direction)
11967369SJulian.Pullen@Sun.COM {
11977369SJulian.Pullen@Sun.COM 	avl_index_t	where;
11987369SJulian.Pullen@Sun.COM 	time_t		ttl = CACHE_TTL + time(NULL);
11997369SJulian.Pullen@Sun.COM 
12007369SJulian.Pullen@Sun.COM 
12017369SJulian.Pullen@Sun.COM 	if (direction == IDMAP_DIRECTION_BI ||
12027369SJulian.Pullen@Sun.COM 	    direction == IDMAP_DIRECTION_W2U) {
12037369SJulian.Pullen@Sun.COM 		winname2uid_gid_t	find;
12047369SJulian.Pullen@Sun.COM 		winname2uid_gid_t	*result;
12057369SJulian.Pullen@Sun.COM 		winname2uid_gid_t	*new;
12067369SJulian.Pullen@Sun.COM 
12077369SJulian.Pullen@Sun.COM 		find.winname = name;
12087369SJulian.Pullen@Sun.COM 		find.windomain = domain;
12097369SJulian.Pullen@Sun.COM 
12107369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
12117369SJulian.Pullen@Sun.COM 		result = avl_find(&idmap_cache.winname2uid_gid.tree, &find,
12127369SJulian.Pullen@Sun.COM 		    &where);
12137369SJulian.Pullen@Sun.COM 
12147369SJulian.Pullen@Sun.COM 		if (result) {
12157369SJulian.Pullen@Sun.COM 			if (result->uid_ttl == 0)
12167369SJulian.Pullen@Sun.COM 				idmap_cache.winname2uid_gid.uid_num++;
12177369SJulian.Pullen@Sun.COM 			result->uid = uid;
12187369SJulian.Pullen@Sun.COM 			result->uid_ttl = ttl;
12197369SJulian.Pullen@Sun.COM 		} else {
12207369SJulian.Pullen@Sun.COM 			new = malloc(sizeof (winname2uid_gid_t));
12217369SJulian.Pullen@Sun.COM 			if (new == NULL)
12227369SJulian.Pullen@Sun.COM 				goto exit_winname2uid_gid;
12237369SJulian.Pullen@Sun.COM 			new->winname = strdup(name);
12247369SJulian.Pullen@Sun.COM 			if (new->winname == NULL) {
12257369SJulian.Pullen@Sun.COM 				free(new);
12267369SJulian.Pullen@Sun.COM 				goto exit_winname2uid_gid;
12277369SJulian.Pullen@Sun.COM 			}
12287369SJulian.Pullen@Sun.COM 			if (domain != NULL) {
12297369SJulian.Pullen@Sun.COM 				new->windomain = strdup(domain);
12307369SJulian.Pullen@Sun.COM 				if (new->winname == NULL) {
12317369SJulian.Pullen@Sun.COM 					free((char *)new->winname);
12327369SJulian.Pullen@Sun.COM 					free(new);
12337369SJulian.Pullen@Sun.COM 					goto exit_winname2uid_gid;
12347369SJulian.Pullen@Sun.COM 				}
12357369SJulian.Pullen@Sun.COM 			} else
12367369SJulian.Pullen@Sun.COM 				new->windomain = NULL;
12377369SJulian.Pullen@Sun.COM 			new->uid = uid;
12387369SJulian.Pullen@Sun.COM 			new->uid_ttl = ttl;
12397369SJulian.Pullen@Sun.COM 			new->gid = UNDEF_GID;
12407369SJulian.Pullen@Sun.COM 			new->gid_ttl = 0;
12417369SJulian.Pullen@Sun.COM 			idmap_cache.winname2uid_gid.uid_num++;
12427369SJulian.Pullen@Sun.COM 
12437369SJulian.Pullen@Sun.COM 			list_insert(&idmap_cache.winname2uid_gid.head, new);
12447369SJulian.Pullen@Sun.COM 			avl_insert(&idmap_cache.winname2uid_gid.tree, new,
12457369SJulian.Pullen@Sun.COM 			    where);
12467369SJulian.Pullen@Sun.COM 		}
12477369SJulian.Pullen@Sun.COM 		if ((avl_numnodes(&idmap_cache.winname2uid_gid.tree) >
12487369SJulian.Pullen@Sun.COM 		    CACHE_UID_GID_TRIGGER_SIZE) &&
12497369SJulian.Pullen@Sun.COM 		    (idmap_cache.winname2uid_gid.purge_time +
12507369SJulian.Pullen@Sun.COM 		    CACHE_PURGE_INTERVAL < time(NULL)))
12517369SJulian.Pullen@Sun.COM 			idmap_purge_winname2uid_gid_cache(
12527369SJulian.Pullen@Sun.COM 			    &idmap_cache.winname2uid_gid,
12537369SJulian.Pullen@Sun.COM 			    CACHE_UID_GID_TRIGGER_SIZE);
12547369SJulian.Pullen@Sun.COM exit_winname2uid_gid:
12557369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
12567369SJulian.Pullen@Sun.COM 	}
12577369SJulian.Pullen@Sun.COM 
12587369SJulian.Pullen@Sun.COM 	if (direction == IDMAP_DIRECTION_BI ||
12597369SJulian.Pullen@Sun.COM 	    direction == IDMAP_DIRECTION_U2W) {
12607369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	find;
12617369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	*result;
12627369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	*new;
12637369SJulian.Pullen@Sun.COM 
12647369SJulian.Pullen@Sun.COM 		find.pid = uid;
12657369SJulian.Pullen@Sun.COM 
12667369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
12677369SJulian.Pullen@Sun.COM 		result = avl_find(&idmap_cache.uid2sid_winname.tree, &find,
12687369SJulian.Pullen@Sun.COM 		    &where);
12697369SJulian.Pullen@Sun.COM 
12707369SJulian.Pullen@Sun.COM 		if (result) {
12717369SJulian.Pullen@Sun.COM 			if (update_str(&result->winname, name) != 0)
12727369SJulian.Pullen@Sun.COM 				goto exit_uid2sid_winname;
12737369SJulian.Pullen@Sun.COM 			if (update_str(&result->windomain, domain) != 0)
12747369SJulian.Pullen@Sun.COM 				goto exit_uid2sid_winname;
12757369SJulian.Pullen@Sun.COM 			if (result->winname_ttl == 0)
12767369SJulian.Pullen@Sun.COM 				idmap_cache.uid2sid_winname.winname_num++;
12777369SJulian.Pullen@Sun.COM 			result->winname_ttl = ttl;
12787369SJulian.Pullen@Sun.COM 		} else {
12797369SJulian.Pullen@Sun.COM 			new = malloc(sizeof (pid2sid_winname_t));
12807369SJulian.Pullen@Sun.COM 			if (new == NULL)
12817369SJulian.Pullen@Sun.COM 				goto exit_uid2sid_winname;
12827369SJulian.Pullen@Sun.COM 			new->pid = uid;
12837369SJulian.Pullen@Sun.COM 			new->winname = strdup(name);
12847369SJulian.Pullen@Sun.COM 			if (new->winname == NULL) {
12857369SJulian.Pullen@Sun.COM 				free(new);
12867369SJulian.Pullen@Sun.COM 				goto exit_uid2sid_winname;
12877369SJulian.Pullen@Sun.COM 			}
12887369SJulian.Pullen@Sun.COM 			if (domain != NULL) {
12897369SJulian.Pullen@Sun.COM 				new->windomain = strdup(domain);
12907369SJulian.Pullen@Sun.COM 				if (new->windomain == NULL) {
12917369SJulian.Pullen@Sun.COM 					free((char *)new->winname);
12927369SJulian.Pullen@Sun.COM 					free(new);
12937369SJulian.Pullen@Sun.COM 					goto exit_uid2sid_winname;
12947369SJulian.Pullen@Sun.COM 				}
12957369SJulian.Pullen@Sun.COM 			} else
12967369SJulian.Pullen@Sun.COM 				new->windomain = NULL;
12977369SJulian.Pullen@Sun.COM 			new->winname_ttl = ttl;
12987369SJulian.Pullen@Sun.COM 			new->sid_prefix = NULL;
12997369SJulian.Pullen@Sun.COM 			new->rid = 0;
13007369SJulian.Pullen@Sun.COM 			new->sid_ttl = 0;
13017369SJulian.Pullen@Sun.COM 			idmap_cache.uid2sid_winname.winname_num ++;
13027369SJulian.Pullen@Sun.COM 
13037369SJulian.Pullen@Sun.COM 			list_insert(&idmap_cache.uid2sid_winname.head, new);
13047369SJulian.Pullen@Sun.COM 			avl_insert(&idmap_cache.uid2sid_winname.tree, new,
13057369SJulian.Pullen@Sun.COM 			    where);
13067369SJulian.Pullen@Sun.COM 		}
13077369SJulian.Pullen@Sun.COM 		if ((avl_numnodes(&idmap_cache.uid2sid_winname.tree) >
13087369SJulian.Pullen@Sun.COM 		    CACHE_UID_TRIGGER_SIZE) &&
13097369SJulian.Pullen@Sun.COM 		    (idmap_cache.uid2sid_winname.purge_time +
13107369SJulian.Pullen@Sun.COM 		    CACHE_PURGE_INTERVAL < time(NULL)))
13117369SJulian.Pullen@Sun.COM 			idmap_purge_pid2sid_winname_cache(
13127369SJulian.Pullen@Sun.COM 			    &idmap_cache.uid2sid_winname,
13137369SJulian.Pullen@Sun.COM 			    CACHE_UID_TRIGGER_SIZE);
13147369SJulian.Pullen@Sun.COM exit_uid2sid_winname:
13157369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
13167369SJulian.Pullen@Sun.COM 	}
13177369SJulian.Pullen@Sun.COM }
13187369SJulian.Pullen@Sun.COM 
13197369SJulian.Pullen@Sun.COM 
13207369SJulian.Pullen@Sun.COM 
13217369SJulian.Pullen@Sun.COM 
13227369SJulian.Pullen@Sun.COM 
13237369SJulian.Pullen@Sun.COM void
idmap_cache_add_winname2gid(const char * name,const char * domain,gid_t gid,int direction)13247369SJulian.Pullen@Sun.COM idmap_cache_add_winname2gid(const char *name, const char *domain, gid_t gid,
13257369SJulian.Pullen@Sun.COM 			int direction)
13267369SJulian.Pullen@Sun.COM {
13277369SJulian.Pullen@Sun.COM 	avl_index_t	where;
13287369SJulian.Pullen@Sun.COM 	time_t		ttl = CACHE_TTL + time(NULL);
13297369SJulian.Pullen@Sun.COM 
13307369SJulian.Pullen@Sun.COM 
13317369SJulian.Pullen@Sun.COM 	if (direction == IDMAP_DIRECTION_BI ||
13327369SJulian.Pullen@Sun.COM 	    direction == IDMAP_DIRECTION_W2U) {
13337369SJulian.Pullen@Sun.COM 		winname2uid_gid_t	find;
13347369SJulian.Pullen@Sun.COM 		winname2uid_gid_t	*result;
13357369SJulian.Pullen@Sun.COM 		winname2uid_gid_t	*new;
13367369SJulian.Pullen@Sun.COM 
13377369SJulian.Pullen@Sun.COM 		find.winname = name;
13387369SJulian.Pullen@Sun.COM 		find.windomain = domain;
13397369SJulian.Pullen@Sun.COM 
13407369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
13417369SJulian.Pullen@Sun.COM 		result = avl_find(&idmap_cache.winname2uid_gid.tree, &find,
13427369SJulian.Pullen@Sun.COM 		    &where);
13437369SJulian.Pullen@Sun.COM 
13447369SJulian.Pullen@Sun.COM 		if (result) {
13457369SJulian.Pullen@Sun.COM 			if (result->uid_ttl == 0)
13467369SJulian.Pullen@Sun.COM 				idmap_cache.winname2uid_gid.gid_num++;
13477369SJulian.Pullen@Sun.COM 			result->gid = gid;
13487369SJulian.Pullen@Sun.COM 			result->gid_ttl = ttl;
13497369SJulian.Pullen@Sun.COM 		} else {
13507369SJulian.Pullen@Sun.COM 			new = malloc(sizeof (winname2uid_gid_t));
13517369SJulian.Pullen@Sun.COM 			if (new == NULL)
13527369SJulian.Pullen@Sun.COM 				goto exit_winname2uid_gid;
13537369SJulian.Pullen@Sun.COM 			new->winname = strdup(name);
13547369SJulian.Pullen@Sun.COM 			if (new->winname == NULL) {
13557369SJulian.Pullen@Sun.COM 				free(new);
13567369SJulian.Pullen@Sun.COM 				goto exit_winname2uid_gid;
13577369SJulian.Pullen@Sun.COM 			}
13587369SJulian.Pullen@Sun.COM 			if (domain != NULL) {
13597369SJulian.Pullen@Sun.COM 				new->windomain = strdup(domain);
13607369SJulian.Pullen@Sun.COM 				if (new->windomain == NULL) {
13617369SJulian.Pullen@Sun.COM 					free((char *)new->winname);
13627369SJulian.Pullen@Sun.COM 					free(new);
13637369SJulian.Pullen@Sun.COM 					goto exit_winname2uid_gid;
13647369SJulian.Pullen@Sun.COM 				}
13657369SJulian.Pullen@Sun.COM 			}
13667369SJulian.Pullen@Sun.COM 			else
13677369SJulian.Pullen@Sun.COM 				new->windomain = NULL;
13687369SJulian.Pullen@Sun.COM 			new->uid = UNDEF_UID;
13697369SJulian.Pullen@Sun.COM 			new->uid_ttl = 0;
13707369SJulian.Pullen@Sun.COM 			new->gid = gid;
13717369SJulian.Pullen@Sun.COM 			new->gid_ttl = ttl;
13727369SJulian.Pullen@Sun.COM 			idmap_cache.winname2uid_gid.gid_num++;
13737369SJulian.Pullen@Sun.COM 
13747369SJulian.Pullen@Sun.COM 			list_insert(&idmap_cache.winname2uid_gid.head, new);
13757369SJulian.Pullen@Sun.COM 			avl_insert(&idmap_cache.winname2uid_gid.tree, new,
13767369SJulian.Pullen@Sun.COM 			    where);
13777369SJulian.Pullen@Sun.COM 		}
13787369SJulian.Pullen@Sun.COM 		if ((avl_numnodes(&idmap_cache.winname2uid_gid.tree) >
13797369SJulian.Pullen@Sun.COM 		    CACHE_UID_GID_TRIGGER_SIZE) &&
13807369SJulian.Pullen@Sun.COM 		    (idmap_cache.winname2uid_gid.purge_time +
13817369SJulian.Pullen@Sun.COM 		    CACHE_PURGE_INTERVAL < time(NULL)))
13827369SJulian.Pullen@Sun.COM 			idmap_purge_winname2uid_gid_cache(
13837369SJulian.Pullen@Sun.COM 			    &idmap_cache.winname2uid_gid,
13847369SJulian.Pullen@Sun.COM 			    CACHE_UID_GID_TRIGGER_SIZE);
13857369SJulian.Pullen@Sun.COM exit_winname2uid_gid:
13867369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
13877369SJulian.Pullen@Sun.COM 	}
13887369SJulian.Pullen@Sun.COM 
13897369SJulian.Pullen@Sun.COM 	if (direction == IDMAP_DIRECTION_BI ||
13907369SJulian.Pullen@Sun.COM 	    direction == IDMAP_DIRECTION_U2W) {
13917369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	find;
13927369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	*result;
13937369SJulian.Pullen@Sun.COM 		pid2sid_winname_t	*new;
13947369SJulian.Pullen@Sun.COM 
13957369SJulian.Pullen@Sun.COM 		find.pid = gid;
13967369SJulian.Pullen@Sun.COM 
13977369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
13987369SJulian.Pullen@Sun.COM 		result = avl_find(&idmap_cache.gid2sid_winname.tree, &find,
13997369SJulian.Pullen@Sun.COM 		    &where);
14007369SJulian.Pullen@Sun.COM 
14017369SJulian.Pullen@Sun.COM 		if (result) {
14027369SJulian.Pullen@Sun.COM 			if (update_str(&result->winname, name) != 0)
14037369SJulian.Pullen@Sun.COM 				goto exit_gid2sid_winname;
14047369SJulian.Pullen@Sun.COM 			if (update_str(&result->windomain, domain) != 0)
14057369SJulian.Pullen@Sun.COM 				goto exit_gid2sid_winname;
14067369SJulian.Pullen@Sun.COM 			if (result->winname_ttl == 0)
14077369SJulian.Pullen@Sun.COM 				idmap_cache.gid2sid_winname.winname_num++;
14087369SJulian.Pullen@Sun.COM 			result->winname_ttl = ttl;
14097369SJulian.Pullen@Sun.COM 		} else {
14107369SJulian.Pullen@Sun.COM 			new = malloc(sizeof (pid2sid_winname_t));
14117369SJulian.Pullen@Sun.COM 			if (new == NULL)
14127369SJulian.Pullen@Sun.COM 				goto exit_gid2sid_winname;
14137369SJulian.Pullen@Sun.COM 			new->pid = gid;
14147369SJulian.Pullen@Sun.COM 			new->winname = strdup(name);
14157369SJulian.Pullen@Sun.COM 			if (new->winname == NULL) {
14167369SJulian.Pullen@Sun.COM 				free(new);
14177369SJulian.Pullen@Sun.COM 				goto exit_gid2sid_winname;
14187369SJulian.Pullen@Sun.COM 			}
14197369SJulian.Pullen@Sun.COM 			if (domain != NULL) {
14207369SJulian.Pullen@Sun.COM 				new->windomain = strdup(domain);
14217369SJulian.Pullen@Sun.COM 				if (new->windomain == NULL) {
14227369SJulian.Pullen@Sun.COM 					free((char *)new->winname);
14237369SJulian.Pullen@Sun.COM 					free(new);
14247369SJulian.Pullen@Sun.COM 					goto exit_gid2sid_winname;
14257369SJulian.Pullen@Sun.COM 				}
14267369SJulian.Pullen@Sun.COM 			}
14277369SJulian.Pullen@Sun.COM 			else
14287369SJulian.Pullen@Sun.COM 				new->windomain = NULL;
14297369SJulian.Pullen@Sun.COM 			new->winname_ttl = ttl;
14307369SJulian.Pullen@Sun.COM 			new->sid_prefix = NULL;
14317369SJulian.Pullen@Sun.COM 			new->rid = 0;
14327369SJulian.Pullen@Sun.COM 			new->sid_ttl = 0;
14337369SJulian.Pullen@Sun.COM 			idmap_cache.gid2sid_winname.winname_num ++;
14347369SJulian.Pullen@Sun.COM 
14357369SJulian.Pullen@Sun.COM 			list_insert(&idmap_cache.gid2sid_winname.head, new);
14367369SJulian.Pullen@Sun.COM 			avl_insert(&idmap_cache.gid2sid_winname.tree, new,
14377369SJulian.Pullen@Sun.COM 			    where);
14387369SJulian.Pullen@Sun.COM 		}
14397369SJulian.Pullen@Sun.COM 		if ((avl_numnodes(&idmap_cache.gid2sid_winname.tree) >
14407369SJulian.Pullen@Sun.COM 		    CACHE_UID_TRIGGER_SIZE) &&
14417369SJulian.Pullen@Sun.COM 		    (idmap_cache.gid2sid_winname.purge_time +
14427369SJulian.Pullen@Sun.COM 		    CACHE_PURGE_INTERVAL < time(NULL)))
14437369SJulian.Pullen@Sun.COM 			idmap_purge_pid2sid_winname_cache(
14447369SJulian.Pullen@Sun.COM 			    &idmap_cache.gid2sid_winname,
14457369SJulian.Pullen@Sun.COM 			    CACHE_UID_TRIGGER_SIZE);
14467369SJulian.Pullen@Sun.COM exit_gid2sid_winname:
14477369SJulian.Pullen@Sun.COM 		(void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
14487369SJulian.Pullen@Sun.COM 	}
14497369SJulian.Pullen@Sun.COM }
14507369SJulian.Pullen@Sun.COM 
14517369SJulian.Pullen@Sun.COM 
14527369SJulian.Pullen@Sun.COM static void
idmap_purge_sid2uid_gid_cache(sid2uid_gid_cache_t * cache,size_t limit)14537369SJulian.Pullen@Sun.COM idmap_purge_sid2uid_gid_cache(sid2uid_gid_cache_t *cache, size_t limit)
14547369SJulian.Pullen@Sun.COM {
14557369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
14567369SJulian.Pullen@Sun.COM 	sid2uid_gid_t	*item;
14577369SJulian.Pullen@Sun.COM 
14587369SJulian.Pullen@Sun.COM 	while (avl_numnodes(&cache->tree) > limit) {
14597369SJulian.Pullen@Sun.COM 		/* Remove least recently used */
14607369SJulian.Pullen@Sun.COM 		item = cache->head.blink;
14617369SJulian.Pullen@Sun.COM 		list_remove(item);
14627369SJulian.Pullen@Sun.COM 		avl_remove(&cache->tree, item);
14637369SJulian.Pullen@Sun.COM 		if (item->uid_ttl != 0)
14647369SJulian.Pullen@Sun.COM 			cache->uid_num--;
14657369SJulian.Pullen@Sun.COM 		if (item->gid_ttl != 0)
14667369SJulian.Pullen@Sun.COM 			cache->gid_num--;
14677369SJulian.Pullen@Sun.COM 		if (item->is_user != UNDEF_ISUSER)
14687369SJulian.Pullen@Sun.COM 			cache->pid_num--;
14697369SJulian.Pullen@Sun.COM 
14707369SJulian.Pullen@Sun.COM 		if (item->sid_prefix)
14717369SJulian.Pullen@Sun.COM 			free((char *)item->sid_prefix);
14727369SJulian.Pullen@Sun.COM 		free(item);
14737369SJulian.Pullen@Sun.COM 	}
14747369SJulian.Pullen@Sun.COM 	cache->purge_time = now;
14757369SJulian.Pullen@Sun.COM }
14767369SJulian.Pullen@Sun.COM 
14777369SJulian.Pullen@Sun.COM 
14787369SJulian.Pullen@Sun.COM static void
idmap_purge_winname2uid_gid_cache(winname2uid_gid_cache_t * cache,size_t limit)14797369SJulian.Pullen@Sun.COM idmap_purge_winname2uid_gid_cache(winname2uid_gid_cache_t *cache, size_t limit)
14807369SJulian.Pullen@Sun.COM {
14817369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
14827369SJulian.Pullen@Sun.COM 	winname2uid_gid_t	*item;
14837369SJulian.Pullen@Sun.COM 
14847369SJulian.Pullen@Sun.COM 	while (avl_numnodes(&cache->tree) > limit) {
14857369SJulian.Pullen@Sun.COM 		/* Remove least recently used */
14867369SJulian.Pullen@Sun.COM 		item = cache->head.blink;
14877369SJulian.Pullen@Sun.COM 		list_remove(item);
14887369SJulian.Pullen@Sun.COM 		avl_remove(&cache->tree, item);
14897369SJulian.Pullen@Sun.COM 		if (item->uid_ttl != 0)
14907369SJulian.Pullen@Sun.COM 			cache->uid_num--;
14917369SJulian.Pullen@Sun.COM 		if (item->gid_ttl != 0)
14927369SJulian.Pullen@Sun.COM 			cache->gid_num--;
14937369SJulian.Pullen@Sun.COM 
14947369SJulian.Pullen@Sun.COM 		if (item->winname)
14957369SJulian.Pullen@Sun.COM 			free((char *)item->winname);
14967369SJulian.Pullen@Sun.COM 		if (item->windomain)
14977369SJulian.Pullen@Sun.COM 			free((char *)item->windomain);
14987369SJulian.Pullen@Sun.COM 		free(item);
14997369SJulian.Pullen@Sun.COM 	}
15007369SJulian.Pullen@Sun.COM 	cache->purge_time = now;
15017369SJulian.Pullen@Sun.COM }
15027369SJulian.Pullen@Sun.COM 
15037369SJulian.Pullen@Sun.COM 
15047369SJulian.Pullen@Sun.COM static void
idmap_purge_pid2sid_winname_cache(pid2sid_winname_cache_t * cache,size_t limit)15057369SJulian.Pullen@Sun.COM idmap_purge_pid2sid_winname_cache(pid2sid_winname_cache_t *cache, size_t limit)
15067369SJulian.Pullen@Sun.COM {
15077369SJulian.Pullen@Sun.COM 	time_t		now = time(NULL);
15087369SJulian.Pullen@Sun.COM 	pid2sid_winname_t	*item;
15097369SJulian.Pullen@Sun.COM 
15107369SJulian.Pullen@Sun.COM 	while (avl_numnodes(&cache->tree) > limit) {
15117369SJulian.Pullen@Sun.COM 		/* Remove least recently used */
15127369SJulian.Pullen@Sun.COM 		item = cache->head.blink;
15137369SJulian.Pullen@Sun.COM 		list_remove(item);
15147369SJulian.Pullen@Sun.COM 		avl_remove(&cache->tree, item);
15157369SJulian.Pullen@Sun.COM 		if (item->winname_ttl != 0)
15167369SJulian.Pullen@Sun.COM 			cache->winname_num--;
15177369SJulian.Pullen@Sun.COM 		if (item->sid_ttl != 0)
15187369SJulian.Pullen@Sun.COM 			cache->sid_num--;
15197369SJulian.Pullen@Sun.COM 
15207369SJulian.Pullen@Sun.COM 		if (item->winname)
15217369SJulian.Pullen@Sun.COM 			free((char *)item->winname);
15227369SJulian.Pullen@Sun.COM 		if (item->windomain)
15237369SJulian.Pullen@Sun.COM 			free((char *)item->windomain);
15247369SJulian.Pullen@Sun.COM 		if (item->sid_prefix)
15257369SJulian.Pullen@Sun.COM 			free((char *)item->sid_prefix);
15267369SJulian.Pullen@Sun.COM 		free(item);
15277369SJulian.Pullen@Sun.COM 	}
15287369SJulian.Pullen@Sun.COM 	cache->purge_time = now;
15297369SJulian.Pullen@Sun.COM }
1530