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