xref: /illumos-gate/usr/src/lib/libidmap/common/idmap_cache.c (revision 9b214d32697277d03ed2e5d98c4a7bfef16dcf4d)
13ee87bcaSJulian Pullen /*
23ee87bcaSJulian Pullen  * CDDL HEADER START
33ee87bcaSJulian Pullen  *
43ee87bcaSJulian Pullen  * The contents of this file are subject to the terms of the
53ee87bcaSJulian Pullen  * Common Development and Distribution License (the "License").
63ee87bcaSJulian Pullen  * You may not use this file except in compliance with the License.
73ee87bcaSJulian Pullen  *
83ee87bcaSJulian Pullen  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93ee87bcaSJulian Pullen  * or http://www.opensolaris.org/os/licensing.
103ee87bcaSJulian Pullen  * See the License for the specific language governing permissions
113ee87bcaSJulian Pullen  * and limitations under the License.
123ee87bcaSJulian Pullen  *
133ee87bcaSJulian Pullen  * When distributing Covered Code, include this CDDL HEADER in each
143ee87bcaSJulian Pullen  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153ee87bcaSJulian Pullen  * If applicable, add the following below this CDDL HEADER, with the
163ee87bcaSJulian Pullen  * fields enclosed by brackets "[]" replaced with your own identifying
173ee87bcaSJulian Pullen  * information: Portions Copyright [yyyy] [name of copyright owner]
183ee87bcaSJulian Pullen  *
193ee87bcaSJulian Pullen  * CDDL HEADER END
203ee87bcaSJulian Pullen  */
213ee87bcaSJulian Pullen 
223ee87bcaSJulian Pullen /*
23*9b214d32SJordan Brown  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
243ee87bcaSJulian Pullen  * Use is subject to license terms.
253ee87bcaSJulian Pullen  */
263ee87bcaSJulian Pullen 
273ee87bcaSJulian Pullen /*
283ee87bcaSJulian Pullen  * Windows to Solaris Identity Mapping
293ee87bcaSJulian Pullen  * This module provides the libidmap idmap_cache.
303ee87bcaSJulian Pullen  */
313ee87bcaSJulian Pullen 
323ee87bcaSJulian Pullen 
333ee87bcaSJulian Pullen #include <sys/types.h>
343ee87bcaSJulian Pullen #include <sys/avl.h>
353ee87bcaSJulian Pullen #include <assert.h>
363ee87bcaSJulian Pullen #include <pthread.h>
373ee87bcaSJulian Pullen #include <strings.h>
383ee87bcaSJulian Pullen #include <sys/idmap.h>
393ee87bcaSJulian Pullen #include <stddef.h>
403ee87bcaSJulian Pullen #include <stdlib.h>
41*9b214d32SJordan Brown #include <rpcsvc/idmap_prot.h>
423ee87bcaSJulian Pullen #include "idmap_cache.h"
433ee87bcaSJulian Pullen 
443ee87bcaSJulian Pullen 
453ee87bcaSJulian Pullen /*
463ee87bcaSJulian Pullen  * Internal definitions and functions
473ee87bcaSJulian Pullen  */
483ee87bcaSJulian Pullen 
493ee87bcaSJulian Pullen #define	CACHE_UID_TRIGGER_SIZE	4096
503ee87bcaSJulian Pullen #define	CACHE_GID_TRIGGER_SIZE	2048
513ee87bcaSJulian Pullen #define	CACHE_UID_GID_TRIGGER_SIZE \
523ee87bcaSJulian Pullen 	(CACHE_UID_TRIGGER_SIZE + CACHE_GID_TRIGGER_SIZE)
533ee87bcaSJulian Pullen 
543ee87bcaSJulian Pullen 
553ee87bcaSJulian Pullen #define	UNDEF_UID	((uid_t)-1)
563ee87bcaSJulian Pullen #define	UNDEF_GID	((gid_t)-1)
573ee87bcaSJulian Pullen #define	UNDEF_ISUSER	(-1)
583ee87bcaSJulian Pullen 
593ee87bcaSJulian Pullen #define	CACHE_PURGE_INTERVAL	(60 * 3)
603ee87bcaSJulian Pullen #define	CACHE_TTL		(60 * 10)
613ee87bcaSJulian Pullen 
623ee87bcaSJulian Pullen 
633ee87bcaSJulian Pullen 
643ee87bcaSJulian Pullen 
653ee87bcaSJulian Pullen #define	list_insert(head, ele)\
663ee87bcaSJulian Pullen 	do {\
673ee87bcaSJulian Pullen 		(ele)->flink = (head)->flink;\
683ee87bcaSJulian Pullen 		(head)->flink = (ele);\
693ee87bcaSJulian Pullen 		(ele)->blink = (ele)->flink->blink;\
703ee87bcaSJulian Pullen 		(ele)->flink->blink = (ele);\
713ee87bcaSJulian Pullen 	} while (0)
723ee87bcaSJulian Pullen 
733ee87bcaSJulian Pullen 
743ee87bcaSJulian Pullen 
753ee87bcaSJulian Pullen #define	list_remove(ele)\
763ee87bcaSJulian Pullen 	do {\
773ee87bcaSJulian Pullen 		(ele)->flink->blink = (ele)->blink;\
783ee87bcaSJulian Pullen 		(ele)->blink->flink = (ele)->flink;\
793ee87bcaSJulian Pullen 	} while (0)
803ee87bcaSJulian Pullen 
813ee87bcaSJulian Pullen 
823ee87bcaSJulian Pullen #define	list_move(head, ele) \
833ee87bcaSJulian Pullen 	do {\
843ee87bcaSJulian Pullen 		if ((head)->flink != (ele)) {\
853ee87bcaSJulian Pullen 			list_remove(ele);\
863ee87bcaSJulian Pullen 			list_insert(head, ele);\
873ee87bcaSJulian Pullen 		}\
883ee87bcaSJulian Pullen 	} while (0)
893ee87bcaSJulian Pullen 
903ee87bcaSJulian Pullen typedef struct sid2uid_gid {
913ee87bcaSJulian Pullen 	avl_node_t		avl_link;
923ee87bcaSJulian Pullen 	struct sid2uid_gid	*flink;
933ee87bcaSJulian Pullen 	struct sid2uid_gid	*blink;
943ee87bcaSJulian Pullen 	const char 		*sid_prefix;
953ee87bcaSJulian Pullen 	idmap_rid_t		rid;
963ee87bcaSJulian Pullen 	uid_t			uid;
973ee87bcaSJulian Pullen 	time_t			uid_ttl;
983ee87bcaSJulian Pullen 	gid_t			gid;
993ee87bcaSJulian Pullen 	time_t			gid_ttl;
1003ee87bcaSJulian Pullen 	int			is_user;
1013ee87bcaSJulian Pullen } sid2uid_gid_t;
1023ee87bcaSJulian Pullen 
1033ee87bcaSJulian Pullen 
1043ee87bcaSJulian Pullen typedef struct pid2sid_winname {
1053ee87bcaSJulian Pullen 	avl_node_t		avl_link;
1063ee87bcaSJulian Pullen 	struct pid2sid_winname	*flink;
1073ee87bcaSJulian Pullen 	struct pid2sid_winname	*blink;
1083ee87bcaSJulian Pullen 	uid_t			pid;
1093ee87bcaSJulian Pullen 	const char		*sid_prefix;
1103ee87bcaSJulian Pullen 	idmap_rid_t		rid;
1113ee87bcaSJulian Pullen 	time_t			sid_ttl;
1123ee87bcaSJulian Pullen 	const char		*winname;
1133ee87bcaSJulian Pullen 	const char		*windomain;
1143ee87bcaSJulian Pullen 	time_t			winname_ttl;
1153ee87bcaSJulian Pullen } pid2sid_winname_t;
1163ee87bcaSJulian Pullen 
1173ee87bcaSJulian Pullen 
1183ee87bcaSJulian Pullen typedef struct winname2uid_gid {
1193ee87bcaSJulian Pullen 	avl_node_t		avl_link;
1203ee87bcaSJulian Pullen 	struct winname2uid_gid	*flink;
1213ee87bcaSJulian Pullen 	struct winname2uid_gid	*blink;
1223ee87bcaSJulian Pullen 	const char		*winname;
1233ee87bcaSJulian Pullen 	const char		*windomain;
1243ee87bcaSJulian Pullen 	uid_t			uid;
1253ee87bcaSJulian Pullen 	time_t			uid_ttl;
1263ee87bcaSJulian Pullen 	gid_t			gid;
1273ee87bcaSJulian Pullen 	time_t			gid_ttl;
1283ee87bcaSJulian Pullen } winname2uid_gid_t;
1293ee87bcaSJulian Pullen 
1303ee87bcaSJulian Pullen 
1313ee87bcaSJulian Pullen typedef struct sid2uid_gid_cache {
1323ee87bcaSJulian Pullen 	avl_tree_t		tree;
1333ee87bcaSJulian Pullen 	pthread_mutex_t		mutex;
1343ee87bcaSJulian Pullen 	sid2uid_gid_t		head;
1353ee87bcaSJulian Pullen 	sid2uid_gid_t		*prev;
1363ee87bcaSJulian Pullen 	time_t			purge_time;
1373ee87bcaSJulian Pullen 	int			uid_num;
1383ee87bcaSJulian Pullen 	int			gid_num;
1393ee87bcaSJulian Pullen 	int			pid_num;
1403ee87bcaSJulian Pullen } sid2uid_gid_cache_t;
1413ee87bcaSJulian Pullen 
1423ee87bcaSJulian Pullen 
1433ee87bcaSJulian Pullen typedef struct pid2sid_winname_cache {
1443ee87bcaSJulian Pullen 	avl_tree_t		tree;
1453ee87bcaSJulian Pullen 	pthread_mutex_t		mutex;
1463ee87bcaSJulian Pullen 	pid2sid_winname_t	head;
1473ee87bcaSJulian Pullen 	pid2sid_winname_t	*prev;
1483ee87bcaSJulian Pullen 	time_t			purge_time;
1493ee87bcaSJulian Pullen 	int			sid_num;
1503ee87bcaSJulian Pullen 	int			winname_num;
1513ee87bcaSJulian Pullen } pid2sid_winname_cache_t;
1523ee87bcaSJulian Pullen 
1533ee87bcaSJulian Pullen 
1543ee87bcaSJulian Pullen 
1553ee87bcaSJulian Pullen typedef struct winname2uid_gid_cache {
1563ee87bcaSJulian Pullen 	avl_tree_t		tree;
1573ee87bcaSJulian Pullen 	pthread_mutex_t		mutex;
1583ee87bcaSJulian Pullen 	winname2uid_gid_t	head;
1593ee87bcaSJulian Pullen 	winname2uid_gid_t	*prev;
1603ee87bcaSJulian Pullen 	time_t			purge_time;
1613ee87bcaSJulian Pullen 	int			uid_num;
1623ee87bcaSJulian Pullen 	int			gid_num;
1633ee87bcaSJulian Pullen } winname2uid_gid_cache_t;
1643ee87bcaSJulian Pullen 
1653ee87bcaSJulian Pullen 
1663ee87bcaSJulian Pullen typedef struct idmap_cache {
1673ee87bcaSJulian Pullen 	sid2uid_gid_cache_t	sid2uid_gid;
1683ee87bcaSJulian Pullen 	pid2sid_winname_cache_t	uid2sid_winname;
1693ee87bcaSJulian Pullen 	pid2sid_winname_cache_t	gid2sid_winname;
1703ee87bcaSJulian Pullen 	winname2uid_gid_cache_t	winname2uid_gid;
1713ee87bcaSJulian Pullen } idmap_cache_t;
1723ee87bcaSJulian Pullen 
1733ee87bcaSJulian Pullen 
1743ee87bcaSJulian Pullen 
1753ee87bcaSJulian Pullen typedef int (*avl_comp_fn)(const void*, const void*);
1763ee87bcaSJulian Pullen 
1773ee87bcaSJulian Pullen static void
1783ee87bcaSJulian Pullen idmap_purge_sid2uid_gid_cache(sid2uid_gid_cache_t *cache, size_t limit);
1793ee87bcaSJulian Pullen 
1803ee87bcaSJulian Pullen static void
1813ee87bcaSJulian Pullen idmap_purge_pid2sid_winname_cache(pid2sid_winname_cache_t *cache, size_t limit);
1823ee87bcaSJulian Pullen 
1833ee87bcaSJulian Pullen static void
1843ee87bcaSJulian Pullen idmap_purge_winname2uid_gid_cache(winname2uid_gid_cache_t *avl, size_t limit);
1853ee87bcaSJulian Pullen 
1863ee87bcaSJulian Pullen /*
1873ee87bcaSJulian Pullen  * Global structures
1883ee87bcaSJulian Pullen  */
1893ee87bcaSJulian Pullen 
1903ee87bcaSJulian Pullen static idmap_cache_t idmap_cache;
1913ee87bcaSJulian Pullen 
1923ee87bcaSJulian Pullen 
1933ee87bcaSJulian Pullen 
1943ee87bcaSJulian Pullen 
1953ee87bcaSJulian Pullen static int
1963ee87bcaSJulian Pullen idmap_compare_sid(const sid2uid_gid_t *entry1, const sid2uid_gid_t *entry2)
1973ee87bcaSJulian Pullen {
1983ee87bcaSJulian Pullen 	int64_t comp = ((int64_t)entry2->rid) - ((int64_t)entry1->rid);
1993ee87bcaSJulian Pullen 
2003ee87bcaSJulian Pullen 	if (comp == 0)
2013ee87bcaSJulian Pullen 		comp = strcmp(entry2->sid_prefix, entry1->sid_prefix);
2023ee87bcaSJulian Pullen 
2033ee87bcaSJulian Pullen 	if (comp < 0)
2043ee87bcaSJulian Pullen 		comp = -1;
2053ee87bcaSJulian Pullen 	else if (comp > 0)
2063ee87bcaSJulian Pullen 		comp = 1;
2073ee87bcaSJulian Pullen 
2083ee87bcaSJulian Pullen 	return ((int)comp);
2093ee87bcaSJulian Pullen }
2103ee87bcaSJulian Pullen 
2113ee87bcaSJulian Pullen 
2123ee87bcaSJulian Pullen static int
2133ee87bcaSJulian Pullen idmap_compare_pid(const pid2sid_winname_t *entry1,
2143ee87bcaSJulian Pullen 			const pid2sid_winname_t *entry2)
2153ee87bcaSJulian Pullen {
2163ee87bcaSJulian Pullen 	if (entry2->pid > entry1->pid)
2173ee87bcaSJulian Pullen 		return (1);
2183ee87bcaSJulian Pullen 	if (entry2->pid < entry1->pid)
2193ee87bcaSJulian Pullen 		return (-1);
2203ee87bcaSJulian Pullen 	return (0);
2213ee87bcaSJulian Pullen }
2223ee87bcaSJulian Pullen 
2233ee87bcaSJulian Pullen 
2243ee87bcaSJulian Pullen static int
2253ee87bcaSJulian Pullen idmap_compare_winname(const winname2uid_gid_t *entry1,
2263ee87bcaSJulian Pullen 			const winname2uid_gid_t *entry2)
2273ee87bcaSJulian Pullen {
2283ee87bcaSJulian Pullen 	int comp;
2293ee87bcaSJulian Pullen 
2303ee87bcaSJulian Pullen 	comp = strcasecmp(entry2->winname, entry1->winname);
2313ee87bcaSJulian Pullen 	if (comp == 0) {
2323ee87bcaSJulian Pullen 		if (entry2->windomain == NULL && entry1->windomain == NULL)
2333ee87bcaSJulian Pullen 			return (0);
2343ee87bcaSJulian Pullen 		if (entry1->windomain == NULL)
2353ee87bcaSJulian Pullen 			return (1);
2363ee87bcaSJulian Pullen 		if (entry2->windomain == NULL)
2373ee87bcaSJulian Pullen 			return (-1);
2383ee87bcaSJulian Pullen 
2393ee87bcaSJulian Pullen 		comp = strcasecmp(entry2->windomain, entry1->windomain);
2403ee87bcaSJulian Pullen 	}
2413ee87bcaSJulian Pullen 
2423ee87bcaSJulian Pullen 	if (comp < 0)
2433ee87bcaSJulian Pullen 		comp = -1;
2443ee87bcaSJulian Pullen 	else if (comp > 0)
2453ee87bcaSJulian Pullen 		comp = 1;
2463ee87bcaSJulian Pullen 
2473ee87bcaSJulian Pullen 	return (comp);
2483ee87bcaSJulian Pullen }
2493ee87bcaSJulian Pullen 
2503ee87bcaSJulian Pullen /*
2513ee87bcaSJulian Pullen  * Routine to update item
2523ee87bcaSJulian Pullen  *
2533ee87bcaSJulian Pullen  * Returns:	0 Success
2543ee87bcaSJulian Pullen  *		-1 Error
2553ee87bcaSJulian Pullen  */
2563ee87bcaSJulian Pullen static int
2573ee87bcaSJulian Pullen update_str(const char **item, const char *str)
2583ee87bcaSJulian Pullen {
2593ee87bcaSJulian Pullen 	char *tmp;
2603ee87bcaSJulian Pullen 
2613ee87bcaSJulian Pullen 	if (*item != NULL && str != NULL) {
2623ee87bcaSJulian Pullen 		if (strcmp(*item, str) != 0) {
2633ee87bcaSJulian Pullen 			if ((tmp = strdup(str)) == NULL)
2643ee87bcaSJulian Pullen 				return (-1);
2653ee87bcaSJulian Pullen 			free((char *)*item);
2663ee87bcaSJulian Pullen 			*item = tmp;
2673ee87bcaSJulian Pullen 		}
2683ee87bcaSJulian Pullen 	} else if (str != NULL) {
2693ee87bcaSJulian Pullen 		/* *item is NULL */
2703ee87bcaSJulian Pullen 		if ((*item = strdup(str)) == NULL)
2713ee87bcaSJulian Pullen 			return (-1);
2723ee87bcaSJulian Pullen 	} else if (*item != NULL) {
2733ee87bcaSJulian Pullen 		/* str is NULL */
2743ee87bcaSJulian Pullen 		free((char *)*item);
2753ee87bcaSJulian Pullen 		*item = NULL;
2763ee87bcaSJulian Pullen 	}
2773ee87bcaSJulian Pullen 
2783ee87bcaSJulian Pullen 	return (0);
2793ee87bcaSJulian Pullen }
2803ee87bcaSJulian Pullen 
2813ee87bcaSJulian Pullen /*
2823ee87bcaSJulian Pullen  * The Cache is initialized on loading libidmap.so
2833ee87bcaSJulian Pullen  */
2843ee87bcaSJulian Pullen #pragma	init(idmap_cache_create)
2853ee87bcaSJulian Pullen 
2863ee87bcaSJulian Pullen void
2873ee87bcaSJulian Pullen idmap_cache_create(void)
2883ee87bcaSJulian Pullen {
2893ee87bcaSJulian Pullen 	avl_create(&idmap_cache.sid2uid_gid.tree,
2903ee87bcaSJulian Pullen 	    (avl_comp_fn)idmap_compare_sid, sizeof (sid2uid_gid_t),
2913ee87bcaSJulian Pullen 	    offsetof(sid2uid_gid_t, avl_link));
2923ee87bcaSJulian Pullen 	(void) pthread_mutex_init(&idmap_cache.sid2uid_gid.mutex, NULL);
2933ee87bcaSJulian Pullen 	idmap_cache.sid2uid_gid.head.flink = &idmap_cache.sid2uid_gid.head;
2943ee87bcaSJulian Pullen 	idmap_cache.sid2uid_gid.head.blink = &idmap_cache.sid2uid_gid.head;
2953ee87bcaSJulian Pullen 	idmap_cache.sid2uid_gid.prev = NULL;
2963ee87bcaSJulian Pullen 	idmap_cache.sid2uid_gid.purge_time = 0;
2973ee87bcaSJulian Pullen 	idmap_cache.sid2uid_gid.uid_num = 0;
2983ee87bcaSJulian Pullen 	idmap_cache.sid2uid_gid.gid_num = 0;
2993ee87bcaSJulian Pullen 	idmap_cache.sid2uid_gid.pid_num = 0;
3003ee87bcaSJulian Pullen 
3013ee87bcaSJulian Pullen 	avl_create(&idmap_cache.uid2sid_winname.tree,
3023ee87bcaSJulian Pullen 	    (avl_comp_fn)idmap_compare_pid, sizeof (pid2sid_winname_t),
3033ee87bcaSJulian Pullen 	    offsetof(pid2sid_winname_t, avl_link));
3043ee87bcaSJulian Pullen 	(void) pthread_mutex_init(&idmap_cache.uid2sid_winname.mutex, NULL);
3053ee87bcaSJulian Pullen 	idmap_cache.uid2sid_winname.head.flink =
3063ee87bcaSJulian Pullen 	    &idmap_cache.uid2sid_winname.head;
3073ee87bcaSJulian Pullen 	idmap_cache.uid2sid_winname.head.blink =
3083ee87bcaSJulian Pullen 	    &idmap_cache.uid2sid_winname.head;
3093ee87bcaSJulian Pullen 	idmap_cache.uid2sid_winname.prev = NULL;
3103ee87bcaSJulian Pullen 	idmap_cache.uid2sid_winname.purge_time = 0;
3113ee87bcaSJulian Pullen 	idmap_cache.uid2sid_winname.sid_num = 0;
3123ee87bcaSJulian Pullen 	idmap_cache.uid2sid_winname.winname_num = 0;
3133ee87bcaSJulian Pullen 
3143ee87bcaSJulian Pullen 	avl_create(&idmap_cache.gid2sid_winname.tree,
3153ee87bcaSJulian Pullen 	    (avl_comp_fn)idmap_compare_pid, sizeof (pid2sid_winname_t),
3163ee87bcaSJulian Pullen 	    offsetof(pid2sid_winname_t, avl_link));
3173ee87bcaSJulian Pullen 	(void) pthread_mutex_init(&idmap_cache.gid2sid_winname.mutex, NULL);
3183ee87bcaSJulian Pullen 	idmap_cache.gid2sid_winname.head.flink =
3193ee87bcaSJulian Pullen 	    &idmap_cache.gid2sid_winname.head;
3203ee87bcaSJulian Pullen 	idmap_cache.gid2sid_winname.head.blink =
3213ee87bcaSJulian Pullen 	    &idmap_cache.gid2sid_winname.head;
3223ee87bcaSJulian Pullen 	idmap_cache.gid2sid_winname.prev = NULL;
3233ee87bcaSJulian Pullen 	idmap_cache.gid2sid_winname.purge_time = 0;
3243ee87bcaSJulian Pullen 	idmap_cache.gid2sid_winname.sid_num = 0;
3253ee87bcaSJulian Pullen 	idmap_cache.gid2sid_winname.winname_num = 0;
3263ee87bcaSJulian Pullen 
3273ee87bcaSJulian Pullen 	avl_create(&idmap_cache.winname2uid_gid.tree,
3283ee87bcaSJulian Pullen 	    (avl_comp_fn)idmap_compare_winname, sizeof (winname2uid_gid_t),
3293ee87bcaSJulian Pullen 	    offsetof(winname2uid_gid_t, avl_link));
3303ee87bcaSJulian Pullen 	(void) pthread_mutex_init(&idmap_cache.winname2uid_gid.mutex, NULL);
3313ee87bcaSJulian Pullen 	idmap_cache.winname2uid_gid.head.flink =
3323ee87bcaSJulian Pullen 	    &idmap_cache.winname2uid_gid.head;
3333ee87bcaSJulian Pullen 	idmap_cache.winname2uid_gid.head.blink =
3343ee87bcaSJulian Pullen 	    &idmap_cache.winname2uid_gid.head;
3353ee87bcaSJulian Pullen 	idmap_cache.winname2uid_gid.prev = NULL;
3363ee87bcaSJulian Pullen 	idmap_cache.winname2uid_gid.purge_time = 0;
3373ee87bcaSJulian Pullen 	idmap_cache.winname2uid_gid.uid_num = 0;
3383ee87bcaSJulian Pullen 	idmap_cache.winname2uid_gid.gid_num = 0;
3393ee87bcaSJulian Pullen }
3403ee87bcaSJulian Pullen 
3413ee87bcaSJulian Pullen 
3423ee87bcaSJulian Pullen void
3433ee87bcaSJulian Pullen idmap_cache_purge(void)
3443ee87bcaSJulian Pullen {
3453ee87bcaSJulian Pullen 	sid2uid_gid_t		*sid2uid_gid;
3463ee87bcaSJulian Pullen 	pid2sid_winname_t	*uid2sid_winname;
3473ee87bcaSJulian Pullen 	pid2sid_winname_t	*gid2sid_winname;
3483ee87bcaSJulian Pullen 	winname2uid_gid_t	*winname2uid_gid;
3493ee87bcaSJulian Pullen 	void			*cookie;
3503ee87bcaSJulian Pullen 
3513ee87bcaSJulian Pullen 	(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
3523ee87bcaSJulian Pullen 	cookie = NULL;
3533ee87bcaSJulian Pullen 	while ((sid2uid_gid = avl_destroy_nodes(
3543ee87bcaSJulian Pullen 	    &idmap_cache.sid2uid_gid.tree, &cookie)) != NULL) {
3553ee87bcaSJulian Pullen 		free((char *)sid2uid_gid->sid_prefix);
3563ee87bcaSJulian Pullen 		free(sid2uid_gid);
3573ee87bcaSJulian Pullen 	}
3583ee87bcaSJulian Pullen 	avl_destroy(&idmap_cache.sid2uid_gid.tree);
3593ee87bcaSJulian Pullen 	avl_create(&idmap_cache.sid2uid_gid.tree,
3603ee87bcaSJulian Pullen 	    (avl_comp_fn)idmap_compare_sid, sizeof (sid2uid_gid_t),
3613ee87bcaSJulian Pullen 	    offsetof(sid2uid_gid_t, avl_link));
3623ee87bcaSJulian Pullen 	idmap_cache.sid2uid_gid.head.flink = &idmap_cache.sid2uid_gid.head;
3633ee87bcaSJulian Pullen 	idmap_cache.sid2uid_gid.head.blink = &idmap_cache.sid2uid_gid.head;
3643ee87bcaSJulian Pullen 	idmap_cache.sid2uid_gid.prev = NULL;
3653ee87bcaSJulian Pullen 	idmap_cache.sid2uid_gid.purge_time = 0;
3663ee87bcaSJulian Pullen 	idmap_cache.sid2uid_gid.uid_num = 0;
3673ee87bcaSJulian Pullen 	idmap_cache.sid2uid_gid.gid_num = 0;
3683ee87bcaSJulian Pullen 	idmap_cache.sid2uid_gid.pid_num = 0;
3693ee87bcaSJulian Pullen 	(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
3703ee87bcaSJulian Pullen 
3713ee87bcaSJulian Pullen 
3723ee87bcaSJulian Pullen 	(void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
3733ee87bcaSJulian Pullen 	cookie = NULL;
3743ee87bcaSJulian Pullen 	while ((uid2sid_winname = avl_destroy_nodes(
3753ee87bcaSJulian Pullen 	    &idmap_cache.uid2sid_winname.tree, &cookie)) != NULL) {
3763ee87bcaSJulian Pullen 		free((char *)uid2sid_winname->sid_prefix);
3773ee87bcaSJulian Pullen 		free((char *)uid2sid_winname->winname);
3783ee87bcaSJulian Pullen 		if (uid2sid_winname->windomain != NULL)
3793ee87bcaSJulian Pullen 			free((char *)uid2sid_winname->windomain);
3803ee87bcaSJulian Pullen 		free(uid2sid_winname);
3813ee87bcaSJulian Pullen 	}
3823ee87bcaSJulian Pullen 	avl_destroy(&idmap_cache.uid2sid_winname.tree);
3833ee87bcaSJulian Pullen 	avl_create(&idmap_cache.uid2sid_winname.tree,
3843ee87bcaSJulian Pullen 	    (avl_comp_fn)idmap_compare_pid, sizeof (pid2sid_winname_t),
3853ee87bcaSJulian Pullen 	    offsetof(pid2sid_winname_t, avl_link));
3863ee87bcaSJulian Pullen 	idmap_cache.uid2sid_winname.head.flink =
3873ee87bcaSJulian Pullen 	    &idmap_cache.uid2sid_winname.head;
3883ee87bcaSJulian Pullen 	idmap_cache.uid2sid_winname.head.blink =
3893ee87bcaSJulian Pullen 	    &idmap_cache.uid2sid_winname.head;
3903ee87bcaSJulian Pullen 	idmap_cache.uid2sid_winname.prev = NULL;
3913ee87bcaSJulian Pullen 	idmap_cache.uid2sid_winname.purge_time = 0;
3923ee87bcaSJulian Pullen 	idmap_cache.uid2sid_winname.sid_num = 0;
3933ee87bcaSJulian Pullen 	idmap_cache.uid2sid_winname.winname_num = 0;
3943ee87bcaSJulian Pullen 	(void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
3953ee87bcaSJulian Pullen 
3963ee87bcaSJulian Pullen 
3973ee87bcaSJulian Pullen 	(void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
3983ee87bcaSJulian Pullen 	cookie = NULL;
3993ee87bcaSJulian Pullen 	while ((gid2sid_winname = avl_destroy_nodes(
4003ee87bcaSJulian Pullen 	    &idmap_cache.gid2sid_winname.tree, &cookie)) != NULL) {
4013ee87bcaSJulian Pullen 		free((char *)gid2sid_winname->sid_prefix);
4023ee87bcaSJulian Pullen 		free((char *)gid2sid_winname->winname);
4033ee87bcaSJulian Pullen 		if (gid2sid_winname->windomain != NULL)
4043ee87bcaSJulian Pullen 			free((char *)gid2sid_winname->windomain);
4053ee87bcaSJulian Pullen 		free(gid2sid_winname);
4063ee87bcaSJulian Pullen 	}
4073ee87bcaSJulian Pullen 	avl_destroy(&idmap_cache.gid2sid_winname.tree);
4083ee87bcaSJulian Pullen 	avl_create(&idmap_cache.gid2sid_winname.tree,
4093ee87bcaSJulian Pullen 	    (avl_comp_fn)idmap_compare_pid, sizeof (pid2sid_winname_t),
4103ee87bcaSJulian Pullen 	    offsetof(pid2sid_winname_t, avl_link));
4113ee87bcaSJulian Pullen 	idmap_cache.gid2sid_winname.head.flink =
4123ee87bcaSJulian Pullen 	    &idmap_cache.gid2sid_winname.head;
4133ee87bcaSJulian Pullen 	idmap_cache.gid2sid_winname.head.blink =
4143ee87bcaSJulian Pullen 	    &idmap_cache.gid2sid_winname.head;
4153ee87bcaSJulian Pullen 	idmap_cache.gid2sid_winname.prev = NULL;
4163ee87bcaSJulian Pullen 	idmap_cache.gid2sid_winname.purge_time = 0;
4173ee87bcaSJulian Pullen 	idmap_cache.gid2sid_winname.sid_num = 0;
4183ee87bcaSJulian Pullen 	idmap_cache.gid2sid_winname.winname_num = 0;
4193ee87bcaSJulian Pullen 	(void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
4203ee87bcaSJulian Pullen 
4213ee87bcaSJulian Pullen 	(void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
4223ee87bcaSJulian Pullen 	cookie = NULL;
4233ee87bcaSJulian Pullen 	while ((winname2uid_gid = avl_destroy_nodes(
4243ee87bcaSJulian Pullen 	    &idmap_cache.winname2uid_gid.tree, &cookie)) != NULL) {
4253ee87bcaSJulian Pullen 		free((char *)winname2uid_gid->winname);
4263ee87bcaSJulian Pullen 		if (winname2uid_gid->windomain)
4273ee87bcaSJulian Pullen 			free((char *)winname2uid_gid->windomain);
4283ee87bcaSJulian Pullen 		free(winname2uid_gid);
4293ee87bcaSJulian Pullen 	}
4303ee87bcaSJulian Pullen 	avl_destroy(&idmap_cache.winname2uid_gid.tree);
4313ee87bcaSJulian Pullen 	avl_create(&idmap_cache.winname2uid_gid.tree,
4323ee87bcaSJulian Pullen 	    (avl_comp_fn)idmap_compare_winname, sizeof (winname2uid_gid_t),
4333ee87bcaSJulian Pullen 	    offsetof(winname2uid_gid_t, avl_link));
4343ee87bcaSJulian Pullen 	idmap_cache.winname2uid_gid.head.flink =
4353ee87bcaSJulian Pullen 	    &idmap_cache.winname2uid_gid.head;
4363ee87bcaSJulian Pullen 	idmap_cache.winname2uid_gid.head.blink =
4373ee87bcaSJulian Pullen 	    &idmap_cache.winname2uid_gid.head;
4383ee87bcaSJulian Pullen 	idmap_cache.winname2uid_gid.prev = NULL;
4393ee87bcaSJulian Pullen 	idmap_cache.winname2uid_gid.purge_time = 0;
4403ee87bcaSJulian Pullen 	idmap_cache.winname2uid_gid.uid_num = 0;
4413ee87bcaSJulian Pullen 	idmap_cache.winname2uid_gid.gid_num = 0;
4423ee87bcaSJulian Pullen 	(void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
4433ee87bcaSJulian Pullen 
4443ee87bcaSJulian Pullen }
4453ee87bcaSJulian Pullen 
4463ee87bcaSJulian Pullen 
4473ee87bcaSJulian Pullen void
4483ee87bcaSJulian Pullen idmap_cache_get_data(size_t *uidbysid, size_t *gidbysid,
4493ee87bcaSJulian Pullen 	size_t *pidbysid, size_t *sidbyuid, size_t *sidbygid,
4503ee87bcaSJulian Pullen 	size_t *winnamebyuid, size_t *winnamebygid,
4513ee87bcaSJulian Pullen 	size_t *uidbywinname, size_t *gidbywinname)
4523ee87bcaSJulian Pullen {
4533ee87bcaSJulian Pullen 	(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
4543ee87bcaSJulian Pullen 	*uidbysid = idmap_cache.sid2uid_gid.uid_num;
4553ee87bcaSJulian Pullen 	*gidbysid = idmap_cache.sid2uid_gid.gid_num;
4563ee87bcaSJulian Pullen 	*pidbysid = idmap_cache.sid2uid_gid.pid_num;
4573ee87bcaSJulian Pullen 	(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
4583ee87bcaSJulian Pullen 
4593ee87bcaSJulian Pullen 	(void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
4603ee87bcaSJulian Pullen 	*sidbyuid = idmap_cache.uid2sid_winname.sid_num;
4613ee87bcaSJulian Pullen 	*winnamebyuid = idmap_cache.uid2sid_winname.winname_num;
4623ee87bcaSJulian Pullen 	(void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
4633ee87bcaSJulian Pullen 
4643ee87bcaSJulian Pullen 	(void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
4653ee87bcaSJulian Pullen 	*sidbygid = idmap_cache.gid2sid_winname.sid_num;
4663ee87bcaSJulian Pullen 	*winnamebygid = idmap_cache.gid2sid_winname.winname_num;
4673ee87bcaSJulian Pullen 	(void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
4683ee87bcaSJulian Pullen 
4693ee87bcaSJulian Pullen 	(void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
4703ee87bcaSJulian Pullen 	*uidbywinname = idmap_cache.winname2uid_gid.uid_num;
4713ee87bcaSJulian Pullen 	*gidbywinname = idmap_cache.winname2uid_gid.gid_num;
4723ee87bcaSJulian Pullen 	(void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
4733ee87bcaSJulian Pullen }
4743ee87bcaSJulian Pullen 
4753ee87bcaSJulian Pullen 
4763ee87bcaSJulian Pullen idmap_stat
4773ee87bcaSJulian Pullen idmap_cache_lookup_uidbysid(const char *sid_prefix,
4783ee87bcaSJulian Pullen 			idmap_rid_t rid, uid_t *uid)
4793ee87bcaSJulian Pullen {
4803ee87bcaSJulian Pullen 	sid2uid_gid_t	entry;
4813ee87bcaSJulian Pullen 	sid2uid_gid_t	*result;
4823ee87bcaSJulian Pullen 	avl_index_t	where;
4833ee87bcaSJulian Pullen 	int		status = IDMAP_ERR_NOMAPPING;
4843ee87bcaSJulian Pullen 	time_t		now = time(NULL);
4853ee87bcaSJulian Pullen 
4863ee87bcaSJulian Pullen 	entry.sid_prefix = sid_prefix;
4873ee87bcaSJulian Pullen 	entry.rid = rid;
4883ee87bcaSJulian Pullen 
4893ee87bcaSJulian Pullen 	(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
4903ee87bcaSJulian Pullen 
4913ee87bcaSJulian Pullen 	result = avl_find(&idmap_cache.sid2uid_gid.tree, &entry, &where);
4923ee87bcaSJulian Pullen 	if (result != NULL) {
4933ee87bcaSJulian Pullen 		list_move(&idmap_cache.sid2uid_gid.head, result);
4943ee87bcaSJulian Pullen 		if (result->uid != UNDEF_UID && result->uid_ttl > now) {
4953ee87bcaSJulian Pullen 			*uid = result->uid;
4963ee87bcaSJulian Pullen 			status = IDMAP_SUCCESS;
4973ee87bcaSJulian Pullen 		}
4983ee87bcaSJulian Pullen 	}
4993ee87bcaSJulian Pullen 
5003ee87bcaSJulian Pullen 	(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
5013ee87bcaSJulian Pullen 
5023ee87bcaSJulian Pullen 	return (status);
5033ee87bcaSJulian Pullen }
5043ee87bcaSJulian Pullen 
5053ee87bcaSJulian Pullen 
5063ee87bcaSJulian Pullen 
5073ee87bcaSJulian Pullen idmap_stat
5083ee87bcaSJulian Pullen idmap_cache_lookup_gidbysid(const char *sid_prefix,
5093ee87bcaSJulian Pullen 			idmap_rid_t rid, gid_t *gid)
5103ee87bcaSJulian Pullen {
5113ee87bcaSJulian Pullen 	sid2uid_gid_t	entry;
5123ee87bcaSJulian Pullen 	sid2uid_gid_t	*result;
5133ee87bcaSJulian Pullen 	avl_index_t	where;
5143ee87bcaSJulian Pullen 	int		status = IDMAP_ERR_NOMAPPING;
5153ee87bcaSJulian Pullen 	time_t		now = time(NULL);
5163ee87bcaSJulian Pullen 
5173ee87bcaSJulian Pullen 	entry.sid_prefix = sid_prefix;
5183ee87bcaSJulian Pullen 	entry.rid = rid;
5193ee87bcaSJulian Pullen 
5203ee87bcaSJulian Pullen 	(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
5213ee87bcaSJulian Pullen 
5223ee87bcaSJulian Pullen 	result = avl_find(&idmap_cache.sid2uid_gid.tree, &entry, &where);
5233ee87bcaSJulian Pullen 	if (result != NULL) {
5243ee87bcaSJulian Pullen 		list_move(&idmap_cache.sid2uid_gid.head, result);
5253ee87bcaSJulian Pullen 		if (result->gid != UNDEF_GID && result->gid_ttl > now) {
5263ee87bcaSJulian Pullen 			*gid = result->gid;
5273ee87bcaSJulian Pullen 			status = IDMAP_SUCCESS;
5283ee87bcaSJulian Pullen 		}
5293ee87bcaSJulian Pullen 	}
5303ee87bcaSJulian Pullen 
5313ee87bcaSJulian Pullen 	(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
5323ee87bcaSJulian Pullen 
5333ee87bcaSJulian Pullen 	return (status);
5343ee87bcaSJulian Pullen }
5353ee87bcaSJulian Pullen 
5363ee87bcaSJulian Pullen 
5373ee87bcaSJulian Pullen 
5383ee87bcaSJulian Pullen 
5393ee87bcaSJulian Pullen idmap_stat
5403ee87bcaSJulian Pullen idmap_cache_lookup_pidbysid(const char *sid_prefix,
5413ee87bcaSJulian Pullen 			idmap_rid_t rid, uid_t *pid, int *is_user)
5423ee87bcaSJulian Pullen {
5433ee87bcaSJulian Pullen 	sid2uid_gid_t	entry;
5443ee87bcaSJulian Pullen 	sid2uid_gid_t	*result;
5453ee87bcaSJulian Pullen 	avl_index_t	where;
5463ee87bcaSJulian Pullen 	int		status = IDMAP_ERR_NOMAPPING;
5473ee87bcaSJulian Pullen 	time_t		now = time(NULL);
5483ee87bcaSJulian Pullen 
5493ee87bcaSJulian Pullen 	entry.sid_prefix = sid_prefix;
5503ee87bcaSJulian Pullen 	entry.rid = rid;
5513ee87bcaSJulian Pullen 
5523ee87bcaSJulian Pullen 	(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
5533ee87bcaSJulian Pullen 
5543ee87bcaSJulian Pullen 	result = avl_find(&idmap_cache.sid2uid_gid.tree, &entry, &where);
5553ee87bcaSJulian Pullen 	if (result != NULL) {
5563ee87bcaSJulian Pullen 		list_move(&idmap_cache.sid2uid_gid.head, result);
5573ee87bcaSJulian Pullen 		if (result->is_user != UNDEF_ISUSER) {
5583ee87bcaSJulian Pullen 			*is_user = result->is_user;
5593ee87bcaSJulian Pullen 			if (result->is_user && result->uid_ttl > now) {
5603ee87bcaSJulian Pullen 				*pid = result->uid;
5613ee87bcaSJulian Pullen 				status = IDMAP_SUCCESS;
5623ee87bcaSJulian Pullen 			} else if (!result->is_user && result->gid_ttl > now) {
5633ee87bcaSJulian Pullen 				*pid = result->gid;
5643ee87bcaSJulian Pullen 				status = IDMAP_SUCCESS;
5653ee87bcaSJulian Pullen 			}
5663ee87bcaSJulian Pullen 		}
5673ee87bcaSJulian Pullen 	}
5683ee87bcaSJulian Pullen 
5693ee87bcaSJulian Pullen 	(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
5703ee87bcaSJulian Pullen 
5713ee87bcaSJulian Pullen 	return (status);
5723ee87bcaSJulian Pullen }
5733ee87bcaSJulian Pullen 
5743ee87bcaSJulian Pullen 
5753ee87bcaSJulian Pullen 
5763ee87bcaSJulian Pullen idmap_stat
5773ee87bcaSJulian Pullen idmap_cache_lookup_sidbyuid(char **sid_prefix,
5783ee87bcaSJulian Pullen 			idmap_rid_t *rid, uid_t uid)
5793ee87bcaSJulian Pullen {
5803ee87bcaSJulian Pullen 	pid2sid_winname_t	entry;
5813ee87bcaSJulian Pullen 	pid2sid_winname_t	*result;
5823ee87bcaSJulian Pullen 	avl_index_t	where;
5833ee87bcaSJulian Pullen 	int		status = IDMAP_ERR_NOMAPPING;
5843ee87bcaSJulian Pullen 	time_t		now = time(NULL);
5853ee87bcaSJulian Pullen 
5863ee87bcaSJulian Pullen 	entry.pid = uid;
5873ee87bcaSJulian Pullen 
5883ee87bcaSJulian Pullen 	(void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
5893ee87bcaSJulian Pullen 
5903ee87bcaSJulian Pullen 	result = avl_find(&idmap_cache.uid2sid_winname.tree, &entry, &where);
5913ee87bcaSJulian Pullen 	if (result != NULL) {
5923ee87bcaSJulian Pullen 		list_move(&idmap_cache.uid2sid_winname.head, result);
5933ee87bcaSJulian Pullen 		if (result->sid_ttl > now) {
5943ee87bcaSJulian Pullen 			*rid = result->rid;
5953ee87bcaSJulian Pullen 			*sid_prefix = strdup(result->sid_prefix);
5963ee87bcaSJulian Pullen 			if (*sid_prefix != NULL)
5973ee87bcaSJulian Pullen 				status = IDMAP_SUCCESS;
5983ee87bcaSJulian Pullen 			else
5993ee87bcaSJulian Pullen 				status = IDMAP_ERR_MEMORY;
6003ee87bcaSJulian Pullen 		}
6013ee87bcaSJulian Pullen 	}
6023ee87bcaSJulian Pullen 
6033ee87bcaSJulian Pullen 	(void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
6043ee87bcaSJulian Pullen 
6053ee87bcaSJulian Pullen 	return (status);
6063ee87bcaSJulian Pullen }
6073ee87bcaSJulian Pullen 
6083ee87bcaSJulian Pullen idmap_stat
6093ee87bcaSJulian Pullen idmap_cache_lookup_sidbygid(char **sid_prefix,
6103ee87bcaSJulian Pullen 			idmap_rid_t *rid, gid_t gid)
6113ee87bcaSJulian Pullen {
6123ee87bcaSJulian Pullen 	pid2sid_winname_t	entry;
6133ee87bcaSJulian Pullen 	pid2sid_winname_t	*result;
6143ee87bcaSJulian Pullen 	avl_index_t	where;
6153ee87bcaSJulian Pullen 	int		status = IDMAP_ERR_NOMAPPING;
6163ee87bcaSJulian Pullen 	time_t		now = time(NULL);
6173ee87bcaSJulian Pullen 
6183ee87bcaSJulian Pullen 	entry.pid = gid;
6193ee87bcaSJulian Pullen 
6203ee87bcaSJulian Pullen 	(void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
6213ee87bcaSJulian Pullen 
6223ee87bcaSJulian Pullen 	result = avl_find(&idmap_cache.gid2sid_winname.tree, &entry, &where);
6233ee87bcaSJulian Pullen 	if (result != NULL) {
6243ee87bcaSJulian Pullen 		list_move(&idmap_cache.gid2sid_winname.head, result);
6253ee87bcaSJulian Pullen 		if (result->sid_ttl > now) {
6263ee87bcaSJulian Pullen 			*rid = result->rid;
6273ee87bcaSJulian Pullen 			*sid_prefix = strdup(result->sid_prefix);
6283ee87bcaSJulian Pullen 			if (*sid_prefix != NULL)
6293ee87bcaSJulian Pullen 				status = IDMAP_SUCCESS;
6303ee87bcaSJulian Pullen 			else
6313ee87bcaSJulian Pullen 				status = IDMAP_ERR_MEMORY;
6323ee87bcaSJulian Pullen 		}
6333ee87bcaSJulian Pullen 	}
6343ee87bcaSJulian Pullen 
6353ee87bcaSJulian Pullen 	(void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
6363ee87bcaSJulian Pullen 
6373ee87bcaSJulian Pullen 	return (status);
6383ee87bcaSJulian Pullen }
6393ee87bcaSJulian Pullen 
6403ee87bcaSJulian Pullen 
6413ee87bcaSJulian Pullen idmap_stat
6423ee87bcaSJulian Pullen idmap_cache_lookup_winnamebyuid(char **name, char **domain, uid_t uid)
6433ee87bcaSJulian Pullen {
6443ee87bcaSJulian Pullen 	pid2sid_winname_t	entry;
6453ee87bcaSJulian Pullen 	pid2sid_winname_t	*result;
6463ee87bcaSJulian Pullen 	avl_index_t	where;
6473ee87bcaSJulian Pullen 	int		status = IDMAP_ERR_NOMAPPING;
6483ee87bcaSJulian Pullen 	time_t		now = time(NULL);
6493ee87bcaSJulian Pullen 
6503ee87bcaSJulian Pullen 	entry.pid = uid;
6513ee87bcaSJulian Pullen 
6523ee87bcaSJulian Pullen 	(void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
6533ee87bcaSJulian Pullen 
6543ee87bcaSJulian Pullen 	result = avl_find(&idmap_cache.uid2sid_winname.tree, &entry, &where);
6553ee87bcaSJulian Pullen 	if (result != NULL) {
6563ee87bcaSJulian Pullen 		list_move(&idmap_cache.uid2sid_winname.head, result);
6573ee87bcaSJulian Pullen 		if (result->winname_ttl > now) {
6583ee87bcaSJulian Pullen 			*name = strdup(result->winname);
6593ee87bcaSJulian Pullen 			if (*name != NULL) {
6603ee87bcaSJulian Pullen 				if (domain != NULL) {
6613ee87bcaSJulian Pullen 					if (result->windomain != NULL) {
6623ee87bcaSJulian Pullen 						*domain =
6633ee87bcaSJulian Pullen 						    strdup(result->windomain);
6643ee87bcaSJulian Pullen 						if (*domain != NULL)
6653ee87bcaSJulian Pullen 							status = IDMAP_SUCCESS;
6663ee87bcaSJulian Pullen 						else
6673ee87bcaSJulian Pullen 							status =
6683ee87bcaSJulian Pullen 							    IDMAP_ERR_MEMORY;
6693ee87bcaSJulian Pullen 					} else {
6703ee87bcaSJulian Pullen 						*domain = NULL;
6713ee87bcaSJulian Pullen 						status = IDMAP_SUCCESS;
6723ee87bcaSJulian Pullen 					}
6733ee87bcaSJulian Pullen 				} else
6743ee87bcaSJulian Pullen 					status = IDMAP_SUCCESS;
6753ee87bcaSJulian Pullen 			} else
6763ee87bcaSJulian Pullen 				status = IDMAP_ERR_MEMORY;
6773ee87bcaSJulian Pullen 		}
6783ee87bcaSJulian Pullen 	}
6793ee87bcaSJulian Pullen 
6803ee87bcaSJulian Pullen 	(void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
6813ee87bcaSJulian Pullen 
6823ee87bcaSJulian Pullen 	return (status);
6833ee87bcaSJulian Pullen }
6843ee87bcaSJulian Pullen 
6853ee87bcaSJulian Pullen 
6863ee87bcaSJulian Pullen idmap_stat
6873ee87bcaSJulian Pullen idmap_cache_lookup_winnamebygid(char **name, char **domain, gid_t gid)
6883ee87bcaSJulian Pullen {
6893ee87bcaSJulian Pullen 	pid2sid_winname_t	entry;
6903ee87bcaSJulian Pullen 	pid2sid_winname_t	*result;
6913ee87bcaSJulian Pullen 	avl_index_t	where;
6923ee87bcaSJulian Pullen 	int		status = IDMAP_ERR_NOMAPPING;
6933ee87bcaSJulian Pullen 	time_t		now = time(NULL);
6943ee87bcaSJulian Pullen 
6953ee87bcaSJulian Pullen 	entry.pid = gid;
6963ee87bcaSJulian Pullen 
6973ee87bcaSJulian Pullen 	(void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
6983ee87bcaSJulian Pullen 
6993ee87bcaSJulian Pullen 	result = avl_find(&idmap_cache.gid2sid_winname.tree, &entry, &where);
7003ee87bcaSJulian Pullen 	if (result != NULL) {
7013ee87bcaSJulian Pullen 		list_move(&idmap_cache.gid2sid_winname.head, result);
7023ee87bcaSJulian Pullen 		if (result->winname_ttl > now) {
7033ee87bcaSJulian Pullen 			*name = strdup(result->winname);
7043ee87bcaSJulian Pullen 			if (*name != NULL) {
7053ee87bcaSJulian Pullen 				if (domain != NULL) {
7063ee87bcaSJulian Pullen 					if (result->windomain != NULL) {
7073ee87bcaSJulian Pullen 						*domain =
7083ee87bcaSJulian Pullen 						    strdup(result->windomain);
7093ee87bcaSJulian Pullen 						if (*domain != NULL)
7103ee87bcaSJulian Pullen 							status = IDMAP_SUCCESS;
7113ee87bcaSJulian Pullen 						else
7123ee87bcaSJulian Pullen 							status =
7133ee87bcaSJulian Pullen 							    IDMAP_ERR_MEMORY;
7143ee87bcaSJulian Pullen 					} else {
7153ee87bcaSJulian Pullen 						*domain = NULL;
7163ee87bcaSJulian Pullen 						status = IDMAP_SUCCESS;
7173ee87bcaSJulian Pullen 					}
7183ee87bcaSJulian Pullen 				} else
7193ee87bcaSJulian Pullen 					status = IDMAP_SUCCESS;
7203ee87bcaSJulian Pullen 			} else
7213ee87bcaSJulian Pullen 				status = IDMAP_ERR_MEMORY;
7223ee87bcaSJulian Pullen 		}
7233ee87bcaSJulian Pullen 	}
7243ee87bcaSJulian Pullen 
7253ee87bcaSJulian Pullen 	(void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
7263ee87bcaSJulian Pullen 
7273ee87bcaSJulian Pullen 	return (status);
7283ee87bcaSJulian Pullen }
7293ee87bcaSJulian Pullen 
7303ee87bcaSJulian Pullen 
7313ee87bcaSJulian Pullen idmap_stat
7323ee87bcaSJulian Pullen idmap_cache_lookup_uidbywinname(const char *name, const char *domain,
7333ee87bcaSJulian Pullen 			uid_t *uid)
7343ee87bcaSJulian Pullen {
7353ee87bcaSJulian Pullen 	winname2uid_gid_t	entry;
7363ee87bcaSJulian Pullen 	winname2uid_gid_t	*result;
7373ee87bcaSJulian Pullen 	avl_index_t	where;
7383ee87bcaSJulian Pullen 	int		status = IDMAP_ERR_NOMAPPING;
7393ee87bcaSJulian Pullen 	time_t		now = time(NULL);
7403ee87bcaSJulian Pullen 
7413ee87bcaSJulian Pullen 	entry.winname = name;
7423ee87bcaSJulian Pullen 	entry.windomain = domain;
7433ee87bcaSJulian Pullen 
7443ee87bcaSJulian Pullen 	(void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
7453ee87bcaSJulian Pullen 
7463ee87bcaSJulian Pullen 	result = avl_find(&idmap_cache.winname2uid_gid.tree, &entry, &where);
7473ee87bcaSJulian Pullen 	if (result != NULL) {
7483ee87bcaSJulian Pullen 		list_move(&idmap_cache.winname2uid_gid.head, result);
7493ee87bcaSJulian Pullen 		if (result->uid != UNDEF_UID && result->uid_ttl > now) {
7503ee87bcaSJulian Pullen 			*uid = result->uid;
7513ee87bcaSJulian Pullen 			status = IDMAP_SUCCESS;
7523ee87bcaSJulian Pullen 		}
7533ee87bcaSJulian Pullen 	}
7543ee87bcaSJulian Pullen 
7553ee87bcaSJulian Pullen 	(void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
7563ee87bcaSJulian Pullen 
7573ee87bcaSJulian Pullen 	return (status);
7583ee87bcaSJulian Pullen }
7593ee87bcaSJulian Pullen 
7603ee87bcaSJulian Pullen 
7613ee87bcaSJulian Pullen idmap_stat
7623ee87bcaSJulian Pullen idmap_cache_lookup_gidbywinname(const char *name, const char *domain,
7633ee87bcaSJulian Pullen 			gid_t *gid)
7643ee87bcaSJulian Pullen {
7653ee87bcaSJulian Pullen 	winname2uid_gid_t	entry;
7663ee87bcaSJulian Pullen 	winname2uid_gid_t	*result;
7673ee87bcaSJulian Pullen 	avl_index_t	where;
7683ee87bcaSJulian Pullen 	int		status = IDMAP_ERR_NOMAPPING;
7693ee87bcaSJulian Pullen 	time_t		now = time(NULL);
7703ee87bcaSJulian Pullen 
7713ee87bcaSJulian Pullen 	entry.winname = name;
7723ee87bcaSJulian Pullen 	entry.windomain = domain;
7733ee87bcaSJulian Pullen 
7743ee87bcaSJulian Pullen 	(void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
7753ee87bcaSJulian Pullen 
7763ee87bcaSJulian Pullen 	result = avl_find(&idmap_cache.winname2uid_gid.tree, &entry, &where);
7773ee87bcaSJulian Pullen 	if (result != NULL) {
7783ee87bcaSJulian Pullen 		list_move(&idmap_cache.winname2uid_gid.head, result);
7793ee87bcaSJulian Pullen 		if (result->gid != UNDEF_GID && result->gid_ttl > now) {
7803ee87bcaSJulian Pullen 			*gid = result->gid;
7813ee87bcaSJulian Pullen 			status = IDMAP_SUCCESS;
7823ee87bcaSJulian Pullen 		}
7833ee87bcaSJulian Pullen 	}
7843ee87bcaSJulian Pullen 
7853ee87bcaSJulian Pullen 	(void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
7863ee87bcaSJulian Pullen 
7873ee87bcaSJulian Pullen 	return (status);
7883ee87bcaSJulian Pullen }
7893ee87bcaSJulian Pullen 
7903ee87bcaSJulian Pullen 
7913ee87bcaSJulian Pullen void
7923ee87bcaSJulian Pullen idmap_cache_add_sid2uid(const char *sid_prefix,
7933ee87bcaSJulian Pullen 			idmap_rid_t rid, uid_t uid, int direction)
7943ee87bcaSJulian Pullen 
7953ee87bcaSJulian Pullen {
7963ee87bcaSJulian Pullen 	avl_index_t	where;
7973ee87bcaSJulian Pullen 	time_t		ttl = CACHE_TTL + time(NULL);
7983ee87bcaSJulian Pullen 
7993ee87bcaSJulian Pullen 
8003ee87bcaSJulian Pullen 	if (direction == IDMAP_DIRECTION_BI ||
8013ee87bcaSJulian Pullen 	    direction == IDMAP_DIRECTION_W2U) {
8023ee87bcaSJulian Pullen 		sid2uid_gid_t	find;
8033ee87bcaSJulian Pullen 		sid2uid_gid_t	*result;
8043ee87bcaSJulian Pullen 		sid2uid_gid_t	*new;
8053ee87bcaSJulian Pullen 
8063ee87bcaSJulian Pullen 		find.sid_prefix = sid_prefix;
8073ee87bcaSJulian Pullen 		find.rid = rid;
8083ee87bcaSJulian Pullen 
8093ee87bcaSJulian Pullen 		(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
8103ee87bcaSJulian Pullen 		result = avl_find(&idmap_cache.sid2uid_gid.tree, &find, &where);
8113ee87bcaSJulian Pullen 
8123ee87bcaSJulian Pullen 		if (result) {
8133ee87bcaSJulian Pullen 			if (result->uid_ttl == 0)
8143ee87bcaSJulian Pullen 				idmap_cache.sid2uid_gid.uid_num++;
8153ee87bcaSJulian Pullen 			result->uid = uid;
8163ee87bcaSJulian Pullen 			result->uid_ttl = ttl;
8173ee87bcaSJulian Pullen 		} else {
8183ee87bcaSJulian Pullen 			new = malloc(sizeof (sid2uid_gid_t));
8193ee87bcaSJulian Pullen 			if (new == NULL)
8203ee87bcaSJulian Pullen 				goto exit_sid2uid_gid;
8213ee87bcaSJulian Pullen 			new->sid_prefix = strdup(sid_prefix);
8223ee87bcaSJulian Pullen 			if (new->sid_prefix == NULL) {
8233ee87bcaSJulian Pullen 				free(new);
8243ee87bcaSJulian Pullen 				goto exit_sid2uid_gid;
8253ee87bcaSJulian Pullen 			}
8263ee87bcaSJulian Pullen 			new->rid = rid;
8273ee87bcaSJulian Pullen 			new->uid = uid;
8283ee87bcaSJulian Pullen 			new->uid_ttl = ttl;
8293ee87bcaSJulian Pullen 			new->gid = UNDEF_GID;
8303ee87bcaSJulian Pullen 			new->gid_ttl = 0;
8313ee87bcaSJulian Pullen 			new->is_user = UNDEF_ISUSER; /* Unknown */
8323ee87bcaSJulian Pullen 			idmap_cache.sid2uid_gid.uid_num++;
8333ee87bcaSJulian Pullen 
8343ee87bcaSJulian Pullen 			list_insert(&idmap_cache.sid2uid_gid.head, new);
8353ee87bcaSJulian Pullen 			avl_insert(&idmap_cache.sid2uid_gid.tree, new, where);
8363ee87bcaSJulian Pullen 		}
8373ee87bcaSJulian Pullen 		if ((avl_numnodes(&idmap_cache.sid2uid_gid.tree) >
8383ee87bcaSJulian Pullen 		    CACHE_UID_GID_TRIGGER_SIZE) &&
8393ee87bcaSJulian Pullen 		    (idmap_cache.sid2uid_gid.purge_time + CACHE_PURGE_INTERVAL <
8403ee87bcaSJulian Pullen 		    time(NULL)))
8413ee87bcaSJulian Pullen 			idmap_purge_sid2uid_gid_cache(&idmap_cache.sid2uid_gid,
8423ee87bcaSJulian Pullen 			    CACHE_UID_GID_TRIGGER_SIZE);
8433ee87bcaSJulian Pullen 
8443ee87bcaSJulian Pullen exit_sid2uid_gid:
8453ee87bcaSJulian Pullen 		(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
8463ee87bcaSJulian Pullen 	}
8473ee87bcaSJulian Pullen 
8483ee87bcaSJulian Pullen 	if (direction == IDMAP_DIRECTION_BI ||
8493ee87bcaSJulian Pullen 	    direction == IDMAP_DIRECTION_U2W) {
8503ee87bcaSJulian Pullen 		pid2sid_winname_t	find;
8513ee87bcaSJulian Pullen 		pid2sid_winname_t	*result;
8523ee87bcaSJulian Pullen 		pid2sid_winname_t	*new;
8533ee87bcaSJulian Pullen 
8543ee87bcaSJulian Pullen 		find.pid = uid;
8553ee87bcaSJulian Pullen 
8563ee87bcaSJulian Pullen 		(void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
8573ee87bcaSJulian Pullen 		result = avl_find(&idmap_cache.uid2sid_winname.tree, &find,
8583ee87bcaSJulian Pullen 		    &where);
8593ee87bcaSJulian Pullen 
8603ee87bcaSJulian Pullen 		if (result) {
8613ee87bcaSJulian Pullen 			if (update_str(&result->sid_prefix, sid_prefix) != 0)
8623ee87bcaSJulian Pullen 				goto exit_pid2sid_winname;
8633ee87bcaSJulian Pullen 			if (result->sid_ttl == 0)
8643ee87bcaSJulian Pullen 					idmap_cache.uid2sid_winname.sid_num++;
8653ee87bcaSJulian Pullen 			result->rid = rid;
8663ee87bcaSJulian Pullen 			result->sid_ttl = ttl;
8673ee87bcaSJulian Pullen 		} else {
8683ee87bcaSJulian Pullen 			new = malloc(sizeof (pid2sid_winname_t));
8693ee87bcaSJulian Pullen 			if (new == NULL)
8703ee87bcaSJulian Pullen 				goto exit_pid2sid_winname;
8713ee87bcaSJulian Pullen 			new->pid = uid;
8723ee87bcaSJulian Pullen 			new->sid_prefix = strdup(sid_prefix);
8733ee87bcaSJulian Pullen 			if (new->sid_prefix == NULL) {
8743ee87bcaSJulian Pullen 				free(new);
8753ee87bcaSJulian Pullen 				goto exit_pid2sid_winname;
8763ee87bcaSJulian Pullen 			}
8773ee87bcaSJulian Pullen 			new->rid = rid;
8783ee87bcaSJulian Pullen 			new->sid_ttl = ttl;
8793ee87bcaSJulian Pullen 			new->winname = NULL;
8803ee87bcaSJulian Pullen 			new->windomain = NULL;
8813ee87bcaSJulian Pullen 			new->winname_ttl = 0;
8823ee87bcaSJulian Pullen 			idmap_cache.uid2sid_winname.sid_num ++;
8833ee87bcaSJulian Pullen 
8843ee87bcaSJulian Pullen 			list_insert(&idmap_cache.uid2sid_winname.head, new);
8853ee87bcaSJulian Pullen 			avl_insert(&idmap_cache.uid2sid_winname.tree, new,
8863ee87bcaSJulian Pullen 			    where);
8873ee87bcaSJulian Pullen 		}
8883ee87bcaSJulian Pullen 		if ((avl_numnodes(&idmap_cache.uid2sid_winname.tree) >
8893ee87bcaSJulian Pullen 		    CACHE_UID_TRIGGER_SIZE) &&
8903ee87bcaSJulian Pullen 		    (idmap_cache.uid2sid_winname.purge_time +
8913ee87bcaSJulian Pullen 		    CACHE_PURGE_INTERVAL < time(NULL)))
8923ee87bcaSJulian Pullen 			idmap_purge_pid2sid_winname_cache(
8933ee87bcaSJulian Pullen 			    &idmap_cache.uid2sid_winname,
8943ee87bcaSJulian Pullen 			    CACHE_UID_TRIGGER_SIZE);
8953ee87bcaSJulian Pullen 
8963ee87bcaSJulian Pullen 
8973ee87bcaSJulian Pullen exit_pid2sid_winname:
8983ee87bcaSJulian Pullen 		(void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
8993ee87bcaSJulian Pullen 	}
9003ee87bcaSJulian Pullen }
9013ee87bcaSJulian Pullen 
9023ee87bcaSJulian Pullen 
9033ee87bcaSJulian Pullen 
9043ee87bcaSJulian Pullen void
9053ee87bcaSJulian Pullen idmap_cache_add_sid2gid(const char *sid_prefix,
9063ee87bcaSJulian Pullen 			idmap_rid_t rid, gid_t gid, int direction)
9073ee87bcaSJulian Pullen {
9083ee87bcaSJulian Pullen 	avl_index_t	where;
9093ee87bcaSJulian Pullen 	time_t		ttl = CACHE_TTL + time(NULL);
9103ee87bcaSJulian Pullen 
9113ee87bcaSJulian Pullen 
9123ee87bcaSJulian Pullen 	if (direction == IDMAP_DIRECTION_BI ||
9133ee87bcaSJulian Pullen 	    direction == IDMAP_DIRECTION_W2U) {
9143ee87bcaSJulian Pullen 		sid2uid_gid_t	find;
9153ee87bcaSJulian Pullen 		sid2uid_gid_t	*result;
9163ee87bcaSJulian Pullen 		sid2uid_gid_t	*new;
9173ee87bcaSJulian Pullen 
9183ee87bcaSJulian Pullen 		find.sid_prefix = sid_prefix;
9193ee87bcaSJulian Pullen 		find.rid = rid;
9203ee87bcaSJulian Pullen 
9213ee87bcaSJulian Pullen 		(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
9223ee87bcaSJulian Pullen 		result = avl_find(&idmap_cache.sid2uid_gid.tree, &find, &where);
9233ee87bcaSJulian Pullen 
9243ee87bcaSJulian Pullen 		if (result) {
9253ee87bcaSJulian Pullen 			if (result->gid_ttl == 0)
9263ee87bcaSJulian Pullen 				idmap_cache.sid2uid_gid.gid_num++;
9273ee87bcaSJulian Pullen 			result->gid = gid;
9283ee87bcaSJulian Pullen 			result->gid_ttl = ttl;
9293ee87bcaSJulian Pullen 		} else {
9303ee87bcaSJulian Pullen 			new = malloc(sizeof (sid2uid_gid_t));
9313ee87bcaSJulian Pullen 			if (new == NULL)
9323ee87bcaSJulian Pullen 				goto exit_sid2uid_gid;
9333ee87bcaSJulian Pullen 			new->sid_prefix = strdup(sid_prefix);
9343ee87bcaSJulian Pullen 			if (new->sid_prefix == NULL) {
9353ee87bcaSJulian Pullen 				free(new);
9363ee87bcaSJulian Pullen 				goto exit_sid2uid_gid;
9373ee87bcaSJulian Pullen 			}
9383ee87bcaSJulian Pullen 			new->rid = rid;
9393ee87bcaSJulian Pullen 			new->uid = UNDEF_UID;
9403ee87bcaSJulian Pullen 			new->uid_ttl = 0;
9413ee87bcaSJulian Pullen 			new->gid = gid;
9423ee87bcaSJulian Pullen 			new->gid_ttl = ttl;
9433ee87bcaSJulian Pullen 			new->is_user = UNDEF_ISUSER; /* Unknown */
9443ee87bcaSJulian Pullen 			idmap_cache.sid2uid_gid.gid_num++;
9453ee87bcaSJulian Pullen 
9463ee87bcaSJulian Pullen 			list_insert(&idmap_cache.sid2uid_gid.head, new);
9473ee87bcaSJulian Pullen 			avl_insert(&idmap_cache.sid2uid_gid.tree, new, where);
9483ee87bcaSJulian Pullen 		}
9493ee87bcaSJulian Pullen 		if ((avl_numnodes(&idmap_cache.sid2uid_gid.tree) >
9503ee87bcaSJulian Pullen 		    CACHE_UID_GID_TRIGGER_SIZE) &&
9513ee87bcaSJulian Pullen 		    (idmap_cache.sid2uid_gid.purge_time + CACHE_PURGE_INTERVAL <
9523ee87bcaSJulian Pullen 		    time(NULL)))
9533ee87bcaSJulian Pullen 			idmap_purge_sid2uid_gid_cache(&idmap_cache.sid2uid_gid,
9543ee87bcaSJulian Pullen 			    CACHE_UID_GID_TRIGGER_SIZE);
9553ee87bcaSJulian Pullen 
9563ee87bcaSJulian Pullen exit_sid2uid_gid:
9573ee87bcaSJulian Pullen 		(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
9583ee87bcaSJulian Pullen 	}
9593ee87bcaSJulian Pullen 
9603ee87bcaSJulian Pullen 	if (direction == IDMAP_DIRECTION_BI ||
9613ee87bcaSJulian Pullen 	    direction == IDMAP_DIRECTION_U2W) {
9623ee87bcaSJulian Pullen 		pid2sid_winname_t	find;
9633ee87bcaSJulian Pullen 		pid2sid_winname_t	*result;
9643ee87bcaSJulian Pullen 		pid2sid_winname_t	*new;
9653ee87bcaSJulian Pullen 
9663ee87bcaSJulian Pullen 		find.pid = gid;
9673ee87bcaSJulian Pullen 
9683ee87bcaSJulian Pullen 		(void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
9693ee87bcaSJulian Pullen 		result = avl_find(&idmap_cache.gid2sid_winname.tree, &find,
9703ee87bcaSJulian Pullen 		    &where);
9713ee87bcaSJulian Pullen 
9723ee87bcaSJulian Pullen 		if (result) {
9733ee87bcaSJulian Pullen 			if (update_str(&result->sid_prefix, sid_prefix) != 0)
9743ee87bcaSJulian Pullen 				goto  exit_gid2sid_winname;
9753ee87bcaSJulian Pullen 			if (result->sid_ttl == 0)
9763ee87bcaSJulian Pullen 				idmap_cache.gid2sid_winname.sid_num++;
9773ee87bcaSJulian Pullen 			result->rid = rid;
9783ee87bcaSJulian Pullen 			result->sid_ttl = ttl;
9793ee87bcaSJulian Pullen 		} else {
9803ee87bcaSJulian Pullen 			new = malloc(sizeof (pid2sid_winname_t));
9813ee87bcaSJulian Pullen 			if (new == NULL)
9823ee87bcaSJulian Pullen 				goto exit_gid2sid_winname;
9833ee87bcaSJulian Pullen 			new->sid_prefix = strdup(sid_prefix);
9843ee87bcaSJulian Pullen 			if (new->sid_prefix == NULL) {
9853ee87bcaSJulian Pullen 				free(new);
9863ee87bcaSJulian Pullen 				goto exit_gid2sid_winname;
9873ee87bcaSJulian Pullen 			}
9883ee87bcaSJulian Pullen 			new->rid = rid;
9893ee87bcaSJulian Pullen 			new->pid = gid;
9903ee87bcaSJulian Pullen 			new->sid_ttl = ttl;
9913ee87bcaSJulian Pullen 			new->winname = NULL;
9923ee87bcaSJulian Pullen 			new->windomain = NULL;
9933ee87bcaSJulian Pullen 			new->winname_ttl = 0;
9943ee87bcaSJulian Pullen 			idmap_cache.gid2sid_winname.sid_num++;
9953ee87bcaSJulian Pullen 
9963ee87bcaSJulian Pullen 			list_insert(&idmap_cache.gid2sid_winname.head, new);
9973ee87bcaSJulian Pullen 			avl_insert(&idmap_cache.gid2sid_winname.tree, new,
9983ee87bcaSJulian Pullen 			    where);
9993ee87bcaSJulian Pullen 		}
10003ee87bcaSJulian Pullen 		if ((avl_numnodes(&idmap_cache.gid2sid_winname.tree) >
10013ee87bcaSJulian Pullen 		    CACHE_GID_TRIGGER_SIZE) &&
10023ee87bcaSJulian Pullen 		    (idmap_cache.gid2sid_winname.purge_time +
10033ee87bcaSJulian Pullen 		    CACHE_PURGE_INTERVAL < time(NULL)))
10043ee87bcaSJulian Pullen 			idmap_purge_pid2sid_winname_cache(
10053ee87bcaSJulian Pullen 			    &idmap_cache.gid2sid_winname,
10063ee87bcaSJulian Pullen 			    CACHE_GID_TRIGGER_SIZE);
10073ee87bcaSJulian Pullen 
10083ee87bcaSJulian Pullen exit_gid2sid_winname:
10093ee87bcaSJulian Pullen 		(void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
10103ee87bcaSJulian Pullen 	}
10113ee87bcaSJulian Pullen }
10123ee87bcaSJulian Pullen 
10133ee87bcaSJulian Pullen 
10143ee87bcaSJulian Pullen void
10153ee87bcaSJulian Pullen idmap_cache_add_sid2pid(const char *sid_prefix,
10163ee87bcaSJulian Pullen 			idmap_rid_t rid, uid_t pid, int is_user, int direction)
10173ee87bcaSJulian Pullen {
10183ee87bcaSJulian Pullen 	avl_index_t	where;
10193ee87bcaSJulian Pullen 	time_t		ttl = CACHE_TTL + time(NULL);
10203ee87bcaSJulian Pullen 
10213ee87bcaSJulian Pullen 
10223ee87bcaSJulian Pullen 	if (direction == IDMAP_DIRECTION_BI ||
10233ee87bcaSJulian Pullen 	    direction == IDMAP_DIRECTION_W2U) {
10243ee87bcaSJulian Pullen 		sid2uid_gid_t	find;
10253ee87bcaSJulian Pullen 		sid2uid_gid_t	*result;
10263ee87bcaSJulian Pullen 		sid2uid_gid_t	*new;
10273ee87bcaSJulian Pullen 
10283ee87bcaSJulian Pullen 		find.sid_prefix = sid_prefix;
10293ee87bcaSJulian Pullen 		find.rid = rid;
10303ee87bcaSJulian Pullen 
10313ee87bcaSJulian Pullen 		(void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
10323ee87bcaSJulian Pullen 		result = avl_find(&idmap_cache.sid2uid_gid.tree, &find, &where);
10333ee87bcaSJulian Pullen 
10343ee87bcaSJulian Pullen 		if (result) {
10353ee87bcaSJulian Pullen 			if (result->is_user == UNDEF_ISUSER)
10363ee87bcaSJulian Pullen 				idmap_cache.sid2uid_gid.pid_num++;
10373ee87bcaSJulian Pullen 			result->is_user = is_user;
10383ee87bcaSJulian Pullen 			if (is_user) {
10393ee87bcaSJulian Pullen 				if (result->uid_ttl == 0)
10403ee87bcaSJulian Pullen 					idmap_cache.sid2uid_gid.uid_num++;
10413ee87bcaSJulian Pullen 				result->uid = pid;
10423ee87bcaSJulian Pullen 				result->uid_ttl = ttl;
10433ee87bcaSJulian Pullen 			} else {
10443ee87bcaSJulian Pullen 				if (result->gid_ttl == 0)
10453ee87bcaSJulian Pullen 					idmap_cache.sid2uid_gid.gid_num++;
10463ee87bcaSJulian Pullen 				result->gid = pid;
10473ee87bcaSJulian Pullen 				result->gid_ttl = ttl;
10483ee87bcaSJulian Pullen 			}
10493ee87bcaSJulian Pullen 		} else {
10503ee87bcaSJulian Pullen 			new = malloc(sizeof (sid2uid_gid_t));
10513ee87bcaSJulian Pullen 			if (new == NULL)
10523ee87bcaSJulian Pullen 				goto exit_sid2uid_gid;
10533ee87bcaSJulian Pullen 			new->sid_prefix = strdup(sid_prefix);
10543ee87bcaSJulian Pullen 			if (new->sid_prefix == NULL) {
10553ee87bcaSJulian Pullen 				free(new);
10563ee87bcaSJulian Pullen 				goto exit_sid2uid_gid;
10573ee87bcaSJulian Pullen 			}
10583ee87bcaSJulian Pullen 			new->rid = rid;
10593ee87bcaSJulian Pullen 			new->is_user = is_user;
10603ee87bcaSJulian Pullen 			if (is_user) {
10613ee87bcaSJulian Pullen 				new->uid = pid;
10623ee87bcaSJulian Pullen 				new->uid_ttl = ttl;
10633ee87bcaSJulian Pullen 				new->gid = UNDEF_GID;
10643ee87bcaSJulian Pullen 				new->gid_ttl = 0;
10653ee87bcaSJulian Pullen 				idmap_cache.sid2uid_gid.uid_num++;
10663ee87bcaSJulian Pullen 			} else {
10673ee87bcaSJulian Pullen 				new->uid = UNDEF_UID;
10683ee87bcaSJulian Pullen 				new->uid_ttl = 0;
10693ee87bcaSJulian Pullen 				new->gid = pid;
10703ee87bcaSJulian Pullen 				new->gid_ttl = ttl;
10713ee87bcaSJulian Pullen 				idmap_cache.sid2uid_gid.gid_num++;
10723ee87bcaSJulian Pullen 			}
10733ee87bcaSJulian Pullen 			idmap_cache.sid2uid_gid.pid_num++;
10743ee87bcaSJulian Pullen 
10753ee87bcaSJulian Pullen 			list_insert(&idmap_cache.sid2uid_gid.head, new);
10763ee87bcaSJulian Pullen 			avl_insert(&idmap_cache.sid2uid_gid.tree, new, where);
10773ee87bcaSJulian Pullen 		}
10783ee87bcaSJulian Pullen 		if ((avl_numnodes(&idmap_cache.sid2uid_gid.tree) >
10793ee87bcaSJulian Pullen 		    CACHE_UID_GID_TRIGGER_SIZE) &&
10803ee87bcaSJulian Pullen 		    (idmap_cache.sid2uid_gid.purge_time + CACHE_PURGE_INTERVAL <
10813ee87bcaSJulian Pullen 		    time(NULL)))
10823ee87bcaSJulian Pullen 			idmap_purge_sid2uid_gid_cache(&idmap_cache.sid2uid_gid,
10833ee87bcaSJulian Pullen 			    CACHE_UID_GID_TRIGGER_SIZE);
10843ee87bcaSJulian Pullen 
10853ee87bcaSJulian Pullen exit_sid2uid_gid:
10863ee87bcaSJulian Pullen 		(void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
10873ee87bcaSJulian Pullen 	}
10883ee87bcaSJulian Pullen 
10893ee87bcaSJulian Pullen 	if (direction == IDMAP_DIRECTION_BI ||
10903ee87bcaSJulian Pullen 	    direction == IDMAP_DIRECTION_U2W) {
10913ee87bcaSJulian Pullen 		pid2sid_winname_t	find;
10923ee87bcaSJulian Pullen 		pid2sid_winname_t	*result;
10933ee87bcaSJulian Pullen 		pid2sid_winname_t	*new;
10943ee87bcaSJulian Pullen 
10953ee87bcaSJulian Pullen 		find.pid = pid;
10963ee87bcaSJulian Pullen 		if (is_user) {
10973ee87bcaSJulian Pullen 			(void) pthread_mutex_lock(
10983ee87bcaSJulian Pullen 			    &idmap_cache.uid2sid_winname.mutex);
10993ee87bcaSJulian Pullen 			result = avl_find(&idmap_cache.uid2sid_winname.tree,
11003ee87bcaSJulian Pullen 			    &find, &where);
11013ee87bcaSJulian Pullen 
11023ee87bcaSJulian Pullen 			if (result) {
11033ee87bcaSJulian Pullen 				if (update_str(&result->sid_prefix, sid_prefix)
11043ee87bcaSJulian Pullen 				    != 0)
11053ee87bcaSJulian Pullen 					goto exit_uid2sid_winname;
11063ee87bcaSJulian Pullen 				if (result->sid_ttl == 0)
11073ee87bcaSJulian Pullen 					idmap_cache.uid2sid_winname.sid_num++;
11083ee87bcaSJulian Pullen 				result->rid = rid;
11093ee87bcaSJulian Pullen 				result->sid_ttl = ttl;
11103ee87bcaSJulian Pullen 			} else {
11113ee87bcaSJulian Pullen 				new = malloc(sizeof (pid2sid_winname_t));
11123ee87bcaSJulian Pullen 				if (new == NULL)
11133ee87bcaSJulian Pullen 					goto exit_uid2sid_winname;
11143ee87bcaSJulian Pullen 				new->sid_prefix = strdup(sid_prefix);
11153ee87bcaSJulian Pullen 				if (new->sid_prefix == NULL) {
11163ee87bcaSJulian Pullen 					free(new);
11173ee87bcaSJulian Pullen 					goto exit_uid2sid_winname;
11183ee87bcaSJulian Pullen 				}
11193ee87bcaSJulian Pullen 				new->rid = rid;
11203ee87bcaSJulian Pullen 				new->pid = pid;
11213ee87bcaSJulian Pullen 				new->sid_ttl = ttl;
11223ee87bcaSJulian Pullen 				new->winname = NULL;
11233ee87bcaSJulian Pullen 				new->windomain = NULL;
11243ee87bcaSJulian Pullen 				idmap_cache.uid2sid_winname.sid_num++;
11253ee87bcaSJulian Pullen 
11263ee87bcaSJulian Pullen 				list_insert(&idmap_cache.uid2sid_winname.head,
11273ee87bcaSJulian Pullen 				    new);
11283ee87bcaSJulian Pullen 				avl_insert(&idmap_cache.uid2sid_winname.tree,
11293ee87bcaSJulian Pullen 				    new, where);
11303ee87bcaSJulian Pullen 			}
11313ee87bcaSJulian Pullen 			if ((avl_numnodes(&idmap_cache.uid2sid_winname.tree) >
11323ee87bcaSJulian Pullen 			    CACHE_UID_TRIGGER_SIZE) &&
11333ee87bcaSJulian Pullen 			    (idmap_cache.uid2sid_winname.purge_time +
11343ee87bcaSJulian Pullen 			    CACHE_PURGE_INTERVAL < time(NULL)))
11353ee87bcaSJulian Pullen 				idmap_purge_pid2sid_winname_cache(
11363ee87bcaSJulian Pullen 				    &idmap_cache.uid2sid_winname,
11373ee87bcaSJulian Pullen 				    CACHE_UID_TRIGGER_SIZE);
11383ee87bcaSJulian Pullen 
11393ee87bcaSJulian Pullen exit_uid2sid_winname:
11403ee87bcaSJulian Pullen 			(void) pthread_mutex_unlock(
11413ee87bcaSJulian Pullen 			    &idmap_cache.uid2sid_winname.mutex);
11423ee87bcaSJulian Pullen 		} else {
11433ee87bcaSJulian Pullen 			(void) pthread_mutex_lock(
11443ee87bcaSJulian Pullen 			    &idmap_cache.gid2sid_winname.mutex);
11453ee87bcaSJulian Pullen 			result = avl_find(&idmap_cache.gid2sid_winname.tree,
11463ee87bcaSJulian Pullen 			    &find, &where);
11473ee87bcaSJulian Pullen 
11483ee87bcaSJulian Pullen 			if (result) {
11493ee87bcaSJulian Pullen 				if (update_str(&result->sid_prefix, sid_prefix)
11503ee87bcaSJulian Pullen 				    != 0)
11513ee87bcaSJulian Pullen 					goto exit_gid2sid_winname;
11523ee87bcaSJulian Pullen 				if (result->sid_ttl == 0)
11533ee87bcaSJulian Pullen 					idmap_cache.gid2sid_winname.sid_num++;
11543ee87bcaSJulian Pullen 				result->rid = rid;
11553ee87bcaSJulian Pullen 				result->sid_ttl = ttl;
11563ee87bcaSJulian Pullen 			} else {
11573ee87bcaSJulian Pullen 				new = malloc(sizeof (pid2sid_winname_t));
11583ee87bcaSJulian Pullen 				if (new == NULL)
11593ee87bcaSJulian Pullen 					goto exit_gid2sid_winname;
11603ee87bcaSJulian Pullen 				new->sid_prefix = strdup(sid_prefix);
11613ee87bcaSJulian Pullen 				if (new->sid_prefix == NULL) {
11623ee87bcaSJulian Pullen 					free(new);
11633ee87bcaSJulian Pullen 					goto exit_gid2sid_winname;
11643ee87bcaSJulian Pullen 				}
11653ee87bcaSJulian Pullen 				new->rid = rid;
11663ee87bcaSJulian Pullen 				new->pid = pid;
11673ee87bcaSJulian Pullen 				new->sid_ttl = ttl;
11683ee87bcaSJulian Pullen 				new->winname = NULL;
11693ee87bcaSJulian Pullen 				new->windomain = NULL;
11703ee87bcaSJulian Pullen 				idmap_cache.gid2sid_winname.sid_num++;
11713ee87bcaSJulian Pullen 
11723ee87bcaSJulian Pullen 				list_insert(&idmap_cache.gid2sid_winname.head,
11733ee87bcaSJulian Pullen 				    new);
11743ee87bcaSJulian Pullen 				avl_insert(&idmap_cache.gid2sid_winname.tree,
11753ee87bcaSJulian Pullen 				    new, where);
11763ee87bcaSJulian Pullen 			}
11773ee87bcaSJulian Pullen 			if ((avl_numnodes(&idmap_cache.gid2sid_winname.tree) >
11783ee87bcaSJulian Pullen 			    CACHE_GID_TRIGGER_SIZE) &&
11793ee87bcaSJulian Pullen 			    (idmap_cache.gid2sid_winname.purge_time +
11803ee87bcaSJulian Pullen 			    CACHE_PURGE_INTERVAL < time(NULL)))
11813ee87bcaSJulian Pullen 				idmap_purge_pid2sid_winname_cache(
11823ee87bcaSJulian Pullen 				    &idmap_cache.gid2sid_winname,
11833ee87bcaSJulian Pullen 				    CACHE_GID_TRIGGER_SIZE);
11843ee87bcaSJulian Pullen exit_gid2sid_winname:
11853ee87bcaSJulian Pullen 			(void) pthread_mutex_unlock(
11863ee87bcaSJulian Pullen 			    &idmap_cache.gid2sid_winname.mutex);
11873ee87bcaSJulian Pullen 		}
11883ee87bcaSJulian Pullen 	}
11893ee87bcaSJulian Pullen }
11903ee87bcaSJulian Pullen 
11913ee87bcaSJulian Pullen 
11923ee87bcaSJulian Pullen 
11933ee87bcaSJulian Pullen void
11943ee87bcaSJulian Pullen idmap_cache_add_winname2uid(const char *name, const char *domain, uid_t uid,
11953ee87bcaSJulian Pullen 			int direction)
11963ee87bcaSJulian Pullen {
11973ee87bcaSJulian Pullen 	avl_index_t	where;
11983ee87bcaSJulian Pullen 	time_t		ttl = CACHE_TTL + time(NULL);
11993ee87bcaSJulian Pullen 
12003ee87bcaSJulian Pullen 
12013ee87bcaSJulian Pullen 	if (direction == IDMAP_DIRECTION_BI ||
12023ee87bcaSJulian Pullen 	    direction == IDMAP_DIRECTION_W2U) {
12033ee87bcaSJulian Pullen 		winname2uid_gid_t	find;
12043ee87bcaSJulian Pullen 		winname2uid_gid_t	*result;
12053ee87bcaSJulian Pullen 		winname2uid_gid_t	*new;
12063ee87bcaSJulian Pullen 
12073ee87bcaSJulian Pullen 		find.winname = name;
12083ee87bcaSJulian Pullen 		find.windomain = domain;
12093ee87bcaSJulian Pullen 
12103ee87bcaSJulian Pullen 		(void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
12113ee87bcaSJulian Pullen 		result = avl_find(&idmap_cache.winname2uid_gid.tree, &find,
12123ee87bcaSJulian Pullen 		    &where);
12133ee87bcaSJulian Pullen 
12143ee87bcaSJulian Pullen 		if (result) {
12153ee87bcaSJulian Pullen 			if (result->uid_ttl == 0)
12163ee87bcaSJulian Pullen 				idmap_cache.winname2uid_gid.uid_num++;
12173ee87bcaSJulian Pullen 			result->uid = uid;
12183ee87bcaSJulian Pullen 			result->uid_ttl = ttl;
12193ee87bcaSJulian Pullen 		} else {
12203ee87bcaSJulian Pullen 			new = malloc(sizeof (winname2uid_gid_t));
12213ee87bcaSJulian Pullen 			if (new == NULL)
12223ee87bcaSJulian Pullen 				goto exit_winname2uid_gid;
12233ee87bcaSJulian Pullen 			new->winname = strdup(name);
12243ee87bcaSJulian Pullen 			if (new->winname == NULL) {
12253ee87bcaSJulian Pullen 				free(new);
12263ee87bcaSJulian Pullen 				goto exit_winname2uid_gid;
12273ee87bcaSJulian Pullen 			}
12283ee87bcaSJulian Pullen 			if (domain != NULL) {
12293ee87bcaSJulian Pullen 				new->windomain = strdup(domain);
12303ee87bcaSJulian Pullen 				if (new->winname == NULL) {
12313ee87bcaSJulian Pullen 					free((char *)new->winname);
12323ee87bcaSJulian Pullen 					free(new);
12333ee87bcaSJulian Pullen 					goto exit_winname2uid_gid;
12343ee87bcaSJulian Pullen 				}
12353ee87bcaSJulian Pullen 			} else
12363ee87bcaSJulian Pullen 				new->windomain = NULL;
12373ee87bcaSJulian Pullen 			new->uid = uid;
12383ee87bcaSJulian Pullen 			new->uid_ttl = ttl;
12393ee87bcaSJulian Pullen 			new->gid = UNDEF_GID;
12403ee87bcaSJulian Pullen 			new->gid_ttl = 0;
12413ee87bcaSJulian Pullen 			idmap_cache.winname2uid_gid.uid_num++;
12423ee87bcaSJulian Pullen 
12433ee87bcaSJulian Pullen 			list_insert(&idmap_cache.winname2uid_gid.head, new);
12443ee87bcaSJulian Pullen 			avl_insert(&idmap_cache.winname2uid_gid.tree, new,
12453ee87bcaSJulian Pullen 			    where);
12463ee87bcaSJulian Pullen 		}
12473ee87bcaSJulian Pullen 		if ((avl_numnodes(&idmap_cache.winname2uid_gid.tree) >
12483ee87bcaSJulian Pullen 		    CACHE_UID_GID_TRIGGER_SIZE) &&
12493ee87bcaSJulian Pullen 		    (idmap_cache.winname2uid_gid.purge_time +
12503ee87bcaSJulian Pullen 		    CACHE_PURGE_INTERVAL < time(NULL)))
12513ee87bcaSJulian Pullen 			idmap_purge_winname2uid_gid_cache(
12523ee87bcaSJulian Pullen 			    &idmap_cache.winname2uid_gid,
12533ee87bcaSJulian Pullen 			    CACHE_UID_GID_TRIGGER_SIZE);
12543ee87bcaSJulian Pullen exit_winname2uid_gid:
12553ee87bcaSJulian Pullen 		(void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
12563ee87bcaSJulian Pullen 	}
12573ee87bcaSJulian Pullen 
12583ee87bcaSJulian Pullen 	if (direction == IDMAP_DIRECTION_BI ||
12593ee87bcaSJulian Pullen 	    direction == IDMAP_DIRECTION_U2W) {
12603ee87bcaSJulian Pullen 		pid2sid_winname_t	find;
12613ee87bcaSJulian Pullen 		pid2sid_winname_t	*result;
12623ee87bcaSJulian Pullen 		pid2sid_winname_t	*new;
12633ee87bcaSJulian Pullen 
12643ee87bcaSJulian Pullen 		find.pid = uid;
12653ee87bcaSJulian Pullen 
12663ee87bcaSJulian Pullen 		(void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
12673ee87bcaSJulian Pullen 		result = avl_find(&idmap_cache.uid2sid_winname.tree, &find,
12683ee87bcaSJulian Pullen 		    &where);
12693ee87bcaSJulian Pullen 
12703ee87bcaSJulian Pullen 		if (result) {
12713ee87bcaSJulian Pullen 			if (update_str(&result->winname, name) != 0)
12723ee87bcaSJulian Pullen 				goto exit_uid2sid_winname;
12733ee87bcaSJulian Pullen 			if (update_str(&result->windomain, domain) != 0)
12743ee87bcaSJulian Pullen 				goto exit_uid2sid_winname;
12753ee87bcaSJulian Pullen 			if (result->winname_ttl == 0)
12763ee87bcaSJulian Pullen 				idmap_cache.uid2sid_winname.winname_num++;
12773ee87bcaSJulian Pullen 			result->winname_ttl = ttl;
12783ee87bcaSJulian Pullen 		} else {
12793ee87bcaSJulian Pullen 			new = malloc(sizeof (pid2sid_winname_t));
12803ee87bcaSJulian Pullen 			if (new == NULL)
12813ee87bcaSJulian Pullen 				goto exit_uid2sid_winname;
12823ee87bcaSJulian Pullen 			new->pid = uid;
12833ee87bcaSJulian Pullen 			new->winname = strdup(name);
12843ee87bcaSJulian Pullen 			if (new->winname == NULL) {
12853ee87bcaSJulian Pullen 				free(new);
12863ee87bcaSJulian Pullen 				goto exit_uid2sid_winname;
12873ee87bcaSJulian Pullen 			}
12883ee87bcaSJulian Pullen 			if (domain != NULL) {
12893ee87bcaSJulian Pullen 				new->windomain = strdup(domain);
12903ee87bcaSJulian Pullen 				if (new->windomain == NULL) {
12913ee87bcaSJulian Pullen 					free((char *)new->winname);
12923ee87bcaSJulian Pullen 					free(new);
12933ee87bcaSJulian Pullen 					goto exit_uid2sid_winname;
12943ee87bcaSJulian Pullen 				}
12953ee87bcaSJulian Pullen 			} else
12963ee87bcaSJulian Pullen 				new->windomain = NULL;
12973ee87bcaSJulian Pullen 			new->winname_ttl = ttl;
12983ee87bcaSJulian Pullen 			new->sid_prefix = NULL;
12993ee87bcaSJulian Pullen 			new->rid = 0;
13003ee87bcaSJulian Pullen 			new->sid_ttl = 0;
13013ee87bcaSJulian Pullen 			idmap_cache.uid2sid_winname.winname_num ++;
13023ee87bcaSJulian Pullen 
13033ee87bcaSJulian Pullen 			list_insert(&idmap_cache.uid2sid_winname.head, new);
13043ee87bcaSJulian Pullen 			avl_insert(&idmap_cache.uid2sid_winname.tree, new,
13053ee87bcaSJulian Pullen 			    where);
13063ee87bcaSJulian Pullen 		}
13073ee87bcaSJulian Pullen 		if ((avl_numnodes(&idmap_cache.uid2sid_winname.tree) >
13083ee87bcaSJulian Pullen 		    CACHE_UID_TRIGGER_SIZE) &&
13093ee87bcaSJulian Pullen 		    (idmap_cache.uid2sid_winname.purge_time +
13103ee87bcaSJulian Pullen 		    CACHE_PURGE_INTERVAL < time(NULL)))
13113ee87bcaSJulian Pullen 			idmap_purge_pid2sid_winname_cache(
13123ee87bcaSJulian Pullen 			    &idmap_cache.uid2sid_winname,
13133ee87bcaSJulian Pullen 			    CACHE_UID_TRIGGER_SIZE);
13143ee87bcaSJulian Pullen exit_uid2sid_winname:
13153ee87bcaSJulian Pullen 		(void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
13163ee87bcaSJulian Pullen 	}
13173ee87bcaSJulian Pullen }
13183ee87bcaSJulian Pullen 
13193ee87bcaSJulian Pullen 
13203ee87bcaSJulian Pullen 
13213ee87bcaSJulian Pullen 
13223ee87bcaSJulian Pullen 
13233ee87bcaSJulian Pullen void
13243ee87bcaSJulian Pullen idmap_cache_add_winname2gid(const char *name, const char *domain, gid_t gid,
13253ee87bcaSJulian Pullen 			int direction)
13263ee87bcaSJulian Pullen {
13273ee87bcaSJulian Pullen 	avl_index_t	where;
13283ee87bcaSJulian Pullen 	time_t		ttl = CACHE_TTL + time(NULL);
13293ee87bcaSJulian Pullen 
13303ee87bcaSJulian Pullen 
13313ee87bcaSJulian Pullen 	if (direction == IDMAP_DIRECTION_BI ||
13323ee87bcaSJulian Pullen 	    direction == IDMAP_DIRECTION_W2U) {
13333ee87bcaSJulian Pullen 		winname2uid_gid_t	find;
13343ee87bcaSJulian Pullen 		winname2uid_gid_t	*result;
13353ee87bcaSJulian Pullen 		winname2uid_gid_t	*new;
13363ee87bcaSJulian Pullen 
13373ee87bcaSJulian Pullen 		find.winname = name;
13383ee87bcaSJulian Pullen 		find.windomain = domain;
13393ee87bcaSJulian Pullen 
13403ee87bcaSJulian Pullen 		(void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
13413ee87bcaSJulian Pullen 		result = avl_find(&idmap_cache.winname2uid_gid.tree, &find,
13423ee87bcaSJulian Pullen 		    &where);
13433ee87bcaSJulian Pullen 
13443ee87bcaSJulian Pullen 		if (result) {
13453ee87bcaSJulian Pullen 			if (result->uid_ttl == 0)
13463ee87bcaSJulian Pullen 				idmap_cache.winname2uid_gid.gid_num++;
13473ee87bcaSJulian Pullen 			result->gid = gid;
13483ee87bcaSJulian Pullen 			result->gid_ttl = ttl;
13493ee87bcaSJulian Pullen 		} else {
13503ee87bcaSJulian Pullen 			new = malloc(sizeof (winname2uid_gid_t));
13513ee87bcaSJulian Pullen 			if (new == NULL)
13523ee87bcaSJulian Pullen 				goto exit_winname2uid_gid;
13533ee87bcaSJulian Pullen 			new->winname = strdup(name);
13543ee87bcaSJulian Pullen 			if (new->winname == NULL) {
13553ee87bcaSJulian Pullen 				free(new);
13563ee87bcaSJulian Pullen 				goto exit_winname2uid_gid;
13573ee87bcaSJulian Pullen 			}
13583ee87bcaSJulian Pullen 			if (domain != NULL) {
13593ee87bcaSJulian Pullen 				new->windomain = strdup(domain);
13603ee87bcaSJulian Pullen 				if (new->windomain == NULL) {
13613ee87bcaSJulian Pullen 					free((char *)new->winname);
13623ee87bcaSJulian Pullen 					free(new);
13633ee87bcaSJulian Pullen 					goto exit_winname2uid_gid;
13643ee87bcaSJulian Pullen 				}
13653ee87bcaSJulian Pullen 			}
13663ee87bcaSJulian Pullen 			else
13673ee87bcaSJulian Pullen 				new->windomain = NULL;
13683ee87bcaSJulian Pullen 			new->uid = UNDEF_UID;
13693ee87bcaSJulian Pullen 			new->uid_ttl = 0;
13703ee87bcaSJulian Pullen 			new->gid = gid;
13713ee87bcaSJulian Pullen 			new->gid_ttl = ttl;
13723ee87bcaSJulian Pullen 			idmap_cache.winname2uid_gid.gid_num++;
13733ee87bcaSJulian Pullen 
13743ee87bcaSJulian Pullen 			list_insert(&idmap_cache.winname2uid_gid.head, new);
13753ee87bcaSJulian Pullen 			avl_insert(&idmap_cache.winname2uid_gid.tree, new,
13763ee87bcaSJulian Pullen 			    where);
13773ee87bcaSJulian Pullen 		}
13783ee87bcaSJulian Pullen 		if ((avl_numnodes(&idmap_cache.winname2uid_gid.tree) >
13793ee87bcaSJulian Pullen 		    CACHE_UID_GID_TRIGGER_SIZE) &&
13803ee87bcaSJulian Pullen 		    (idmap_cache.winname2uid_gid.purge_time +
13813ee87bcaSJulian Pullen 		    CACHE_PURGE_INTERVAL < time(NULL)))
13823ee87bcaSJulian Pullen 			idmap_purge_winname2uid_gid_cache(
13833ee87bcaSJulian Pullen 			    &idmap_cache.winname2uid_gid,
13843ee87bcaSJulian Pullen 			    CACHE_UID_GID_TRIGGER_SIZE);
13853ee87bcaSJulian Pullen exit_winname2uid_gid:
13863ee87bcaSJulian Pullen 		(void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
13873ee87bcaSJulian Pullen 	}
13883ee87bcaSJulian Pullen 
13893ee87bcaSJulian Pullen 	if (direction == IDMAP_DIRECTION_BI ||
13903ee87bcaSJulian Pullen 	    direction == IDMAP_DIRECTION_U2W) {
13913ee87bcaSJulian Pullen 		pid2sid_winname_t	find;
13923ee87bcaSJulian Pullen 		pid2sid_winname_t	*result;
13933ee87bcaSJulian Pullen 		pid2sid_winname_t	*new;
13943ee87bcaSJulian Pullen 
13953ee87bcaSJulian Pullen 		find.pid = gid;
13963ee87bcaSJulian Pullen 
13973ee87bcaSJulian Pullen 		(void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
13983ee87bcaSJulian Pullen 		result = avl_find(&idmap_cache.gid2sid_winname.tree, &find,
13993ee87bcaSJulian Pullen 		    &where);
14003ee87bcaSJulian Pullen 
14013ee87bcaSJulian Pullen 		if (result) {
14023ee87bcaSJulian Pullen 			if (update_str(&result->winname, name) != 0)
14033ee87bcaSJulian Pullen 				goto exit_gid2sid_winname;
14043ee87bcaSJulian Pullen 			if (update_str(&result->windomain, domain) != 0)
14053ee87bcaSJulian Pullen 				goto exit_gid2sid_winname;
14063ee87bcaSJulian Pullen 			if (result->winname_ttl == 0)
14073ee87bcaSJulian Pullen 				idmap_cache.gid2sid_winname.winname_num++;
14083ee87bcaSJulian Pullen 			result->winname_ttl = ttl;
14093ee87bcaSJulian Pullen 		} else {
14103ee87bcaSJulian Pullen 			new = malloc(sizeof (pid2sid_winname_t));
14113ee87bcaSJulian Pullen 			if (new == NULL)
14123ee87bcaSJulian Pullen 				goto exit_gid2sid_winname;
14133ee87bcaSJulian Pullen 			new->pid = gid;
14143ee87bcaSJulian Pullen 			new->winname = strdup(name);
14153ee87bcaSJulian Pullen 			if (new->winname == NULL) {
14163ee87bcaSJulian Pullen 				free(new);
14173ee87bcaSJulian Pullen 				goto exit_gid2sid_winname;
14183ee87bcaSJulian Pullen 			}
14193ee87bcaSJulian Pullen 			if (domain != NULL) {
14203ee87bcaSJulian Pullen 				new->windomain = strdup(domain);
14213ee87bcaSJulian Pullen 				if (new->windomain == NULL) {
14223ee87bcaSJulian Pullen 					free((char *)new->winname);
14233ee87bcaSJulian Pullen 					free(new);
14243ee87bcaSJulian Pullen 					goto exit_gid2sid_winname;
14253ee87bcaSJulian Pullen 				}
14263ee87bcaSJulian Pullen 			}
14273ee87bcaSJulian Pullen 			else
14283ee87bcaSJulian Pullen 				new->windomain = NULL;
14293ee87bcaSJulian Pullen 			new->winname_ttl = ttl;
14303ee87bcaSJulian Pullen 			new->sid_prefix = NULL;
14313ee87bcaSJulian Pullen 			new->rid = 0;
14323ee87bcaSJulian Pullen 			new->sid_ttl = 0;
14333ee87bcaSJulian Pullen 			idmap_cache.gid2sid_winname.winname_num ++;
14343ee87bcaSJulian Pullen 
14353ee87bcaSJulian Pullen 			list_insert(&idmap_cache.gid2sid_winname.head, new);
14363ee87bcaSJulian Pullen 			avl_insert(&idmap_cache.gid2sid_winname.tree, new,
14373ee87bcaSJulian Pullen 			    where);
14383ee87bcaSJulian Pullen 		}
14393ee87bcaSJulian Pullen 		if ((avl_numnodes(&idmap_cache.gid2sid_winname.tree) >
14403ee87bcaSJulian Pullen 		    CACHE_UID_TRIGGER_SIZE) &&
14413ee87bcaSJulian Pullen 		    (idmap_cache.gid2sid_winname.purge_time +
14423ee87bcaSJulian Pullen 		    CACHE_PURGE_INTERVAL < time(NULL)))
14433ee87bcaSJulian Pullen 			idmap_purge_pid2sid_winname_cache(
14443ee87bcaSJulian Pullen 			    &idmap_cache.gid2sid_winname,
14453ee87bcaSJulian Pullen 			    CACHE_UID_TRIGGER_SIZE);
14463ee87bcaSJulian Pullen exit_gid2sid_winname:
14473ee87bcaSJulian Pullen 		(void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
14483ee87bcaSJulian Pullen 	}
14493ee87bcaSJulian Pullen }
14503ee87bcaSJulian Pullen 
14513ee87bcaSJulian Pullen 
14523ee87bcaSJulian Pullen static void
14533ee87bcaSJulian Pullen idmap_purge_sid2uid_gid_cache(sid2uid_gid_cache_t *cache, size_t limit)
14543ee87bcaSJulian Pullen {
14553ee87bcaSJulian Pullen 	time_t		now = time(NULL);
14563ee87bcaSJulian Pullen 	sid2uid_gid_t	*item;
14573ee87bcaSJulian Pullen 
14583ee87bcaSJulian Pullen 	while (avl_numnodes(&cache->tree) > limit) {
14593ee87bcaSJulian Pullen 		/* Remove least recently used */
14603ee87bcaSJulian Pullen 		item = cache->head.blink;
14613ee87bcaSJulian Pullen 		list_remove(item);
14623ee87bcaSJulian Pullen 		avl_remove(&cache->tree, item);
14633ee87bcaSJulian Pullen 		if (item->uid_ttl != 0)
14643ee87bcaSJulian Pullen 			cache->uid_num--;
14653ee87bcaSJulian Pullen 		if (item->gid_ttl != 0)
14663ee87bcaSJulian Pullen 			cache->gid_num--;
14673ee87bcaSJulian Pullen 		if (item->is_user != UNDEF_ISUSER)
14683ee87bcaSJulian Pullen 			cache->pid_num--;
14693ee87bcaSJulian Pullen 
14703ee87bcaSJulian Pullen 		if (item->sid_prefix)
14713ee87bcaSJulian Pullen 			free((char *)item->sid_prefix);
14723ee87bcaSJulian Pullen 		free(item);
14733ee87bcaSJulian Pullen 	}
14743ee87bcaSJulian Pullen 	cache->purge_time = now;
14753ee87bcaSJulian Pullen }
14763ee87bcaSJulian Pullen 
14773ee87bcaSJulian Pullen 
14783ee87bcaSJulian Pullen static void
14793ee87bcaSJulian Pullen idmap_purge_winname2uid_gid_cache(winname2uid_gid_cache_t *cache, size_t limit)
14803ee87bcaSJulian Pullen {
14813ee87bcaSJulian Pullen 	time_t		now = time(NULL);
14823ee87bcaSJulian Pullen 	winname2uid_gid_t	*item;
14833ee87bcaSJulian Pullen 
14843ee87bcaSJulian Pullen 	while (avl_numnodes(&cache->tree) > limit) {
14853ee87bcaSJulian Pullen 		/* Remove least recently used */
14863ee87bcaSJulian Pullen 		item = cache->head.blink;
14873ee87bcaSJulian Pullen 		list_remove(item);
14883ee87bcaSJulian Pullen 		avl_remove(&cache->tree, item);
14893ee87bcaSJulian Pullen 		if (item->uid_ttl != 0)
14903ee87bcaSJulian Pullen 			cache->uid_num--;
14913ee87bcaSJulian Pullen 		if (item->gid_ttl != 0)
14923ee87bcaSJulian Pullen 			cache->gid_num--;
14933ee87bcaSJulian Pullen 
14943ee87bcaSJulian Pullen 		if (item->winname)
14953ee87bcaSJulian Pullen 			free((char *)item->winname);
14963ee87bcaSJulian Pullen 		if (item->windomain)
14973ee87bcaSJulian Pullen 			free((char *)item->windomain);
14983ee87bcaSJulian Pullen 		free(item);
14993ee87bcaSJulian Pullen 	}
15003ee87bcaSJulian Pullen 	cache->purge_time = now;
15013ee87bcaSJulian Pullen }
15023ee87bcaSJulian Pullen 
15033ee87bcaSJulian Pullen 
15043ee87bcaSJulian Pullen static void
15053ee87bcaSJulian Pullen idmap_purge_pid2sid_winname_cache(pid2sid_winname_cache_t *cache, size_t limit)
15063ee87bcaSJulian Pullen {
15073ee87bcaSJulian Pullen 	time_t		now = time(NULL);
15083ee87bcaSJulian Pullen 	pid2sid_winname_t	*item;
15093ee87bcaSJulian Pullen 
15103ee87bcaSJulian Pullen 	while (avl_numnodes(&cache->tree) > limit) {
15113ee87bcaSJulian Pullen 		/* Remove least recently used */
15123ee87bcaSJulian Pullen 		item = cache->head.blink;
15133ee87bcaSJulian Pullen 		list_remove(item);
15143ee87bcaSJulian Pullen 		avl_remove(&cache->tree, item);
15153ee87bcaSJulian Pullen 		if (item->winname_ttl != 0)
15163ee87bcaSJulian Pullen 			cache->winname_num--;
15173ee87bcaSJulian Pullen 		if (item->sid_ttl != 0)
15183ee87bcaSJulian Pullen 			cache->sid_num--;
15193ee87bcaSJulian Pullen 
15203ee87bcaSJulian Pullen 		if (item->winname)
15213ee87bcaSJulian Pullen 			free((char *)item->winname);
15223ee87bcaSJulian Pullen 		if (item->windomain)
15233ee87bcaSJulian Pullen 			free((char *)item->windomain);
15243ee87bcaSJulian Pullen 		if (item->sid_prefix)
15253ee87bcaSJulian Pullen 			free((char *)item->sid_prefix);
15263ee87bcaSJulian Pullen 		free(item);
15273ee87bcaSJulian Pullen 	}
15283ee87bcaSJulian Pullen 	cache->purge_time = now;
15293ee87bcaSJulian Pullen }
1530