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