1c5c4113dSnw141292 /*
2c5c4113dSnw141292 * CDDL HEADER START
3c5c4113dSnw141292 *
4c5c4113dSnw141292 * The contents of this file are subject to the terms of the
5c5c4113dSnw141292 * Common Development and Distribution License (the "License").
6c5c4113dSnw141292 * You may not use this file except in compliance with the License.
7c5c4113dSnw141292 *
8c5c4113dSnw141292 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9c5c4113dSnw141292 * or http://www.opensolaris.org/os/licensing.
10c5c4113dSnw141292 * See the License for the specific language governing permissions
11c5c4113dSnw141292 * and limitations under the License.
12c5c4113dSnw141292 *
13c5c4113dSnw141292 * When distributing Covered Code, include this CDDL HEADER in each
14c5c4113dSnw141292 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15c5c4113dSnw141292 * If applicable, add the following below this CDDL HEADER, with the
16c5c4113dSnw141292 * fields enclosed by brackets "[]" replaced with your own identifying
17c5c4113dSnw141292 * information: Portions Copyright [yyyy] [name of copyright owner]
18c5c4113dSnw141292 *
19c5c4113dSnw141292 * CDDL HEADER END
20c5c4113dSnw141292 */
21c5c4113dSnw141292
22c5c4113dSnw141292 /*
23*9b214d32SJordan Brown * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24c5c4113dSnw141292 * Use is subject to license terms.
25c5c4113dSnw141292 */
26c5c4113dSnw141292
27c5c4113dSnw141292 /*
28c5c4113dSnw141292 * Windows to Solaris Identity Mapping kernel API
29c5c4113dSnw141292 * This module provides the kernel cache.
30c5c4113dSnw141292 */
31c5c4113dSnw141292
32c5c4113dSnw141292
33c5c4113dSnw141292 #include <sys/types.h>
34c5c4113dSnw141292 #include <sys/avl.h>
35c5c4113dSnw141292 #include <sys/systm.h>
36c5c4113dSnw141292 #include <sys/sysmacros.h>
37c5c4113dSnw141292 #include <sys/ksynch.h>
38c5c4113dSnw141292 #include <sys/kidmap.h>
39*9b214d32SJordan Brown #include <rpcsvc/idmap_prot.h>
40c5c4113dSnw141292 #include "kidmap_priv.h"
41c5c4113dSnw141292
42c5c4113dSnw141292
43c5c4113dSnw141292 /*
44c5c4113dSnw141292 * External functions
45c5c4113dSnw141292 */
46c5c4113dSnw141292 extern uintptr_t space_fetch(char *key);
47c5c4113dSnw141292 extern int space_store(char *key, uintptr_t ptr);
48c5c4113dSnw141292
49c5c4113dSnw141292
50c5c4113dSnw141292 /*
51c5c4113dSnw141292 * Internal definitions and functions
52c5c4113dSnw141292 */
53c5c4113dSnw141292
54d15447b6Sjp151216 #define CACHE_UID_TRIGGER_SIZE 4096
55d15447b6Sjp151216 #define CACHE_GID_TRIGGER_SIZE 2048
56d15447b6Sjp151216 #define CACHE_PID_TRIGGER_SIZE \
57d15447b6Sjp151216 (CACHE_UID_TRIGGER_SIZE + CACHE_GID_TRIGGER_SIZE)
58d15447b6Sjp151216
59d15447b6Sjp151216
60d15447b6Sjp151216 #define UNDEF_UID ((uid_t)-1)
61d15447b6Sjp151216 #define UNDEF_GID ((gid_t)-1)
62d15447b6Sjp151216 #define UNDEF_ISUSER (-1)
63d15447b6Sjp151216
64c5c4113dSnw141292 #define CACHE_PURGE_INTERVAL (60 * 3)
650b10de9fSjp151216 #define CACHE_TTL (60 * 10)
66c5c4113dSnw141292
6732ff2b3cSJulian Pullen
6832ff2b3cSJulian Pullen
6932ff2b3cSJulian Pullen #define list_insert(head, ele)\
7032ff2b3cSJulian Pullen do {\
7132ff2b3cSJulian Pullen (ele)->flink = (head)->flink;\
7232ff2b3cSJulian Pullen (head)->flink = (ele);\
7332ff2b3cSJulian Pullen (ele)->blink = (ele)->flink->blink;\
7432ff2b3cSJulian Pullen (ele)->flink->blink = (ele);\
7532ff2b3cSJulian Pullen } while (0)
7632ff2b3cSJulian Pullen
7732ff2b3cSJulian Pullen
7832ff2b3cSJulian Pullen
7932ff2b3cSJulian Pullen #define list_remove(ele)\
8032ff2b3cSJulian Pullen do {\
8132ff2b3cSJulian Pullen (ele)->flink->blink = (ele)->blink;\
8232ff2b3cSJulian Pullen (ele)->blink->flink = (ele)->flink;\
8332ff2b3cSJulian Pullen } while (0)
8432ff2b3cSJulian Pullen
8532ff2b3cSJulian Pullen
8632ff2b3cSJulian Pullen #define list_move(head, ele) \
8732ff2b3cSJulian Pullen do {\
8832ff2b3cSJulian Pullen if ((head)->flink != (ele)) {\
8932ff2b3cSJulian Pullen list_remove(ele);\
9032ff2b3cSJulian Pullen list_insert(head, ele);\
9132ff2b3cSJulian Pullen }\
9232ff2b3cSJulian Pullen } while (0)
9332ff2b3cSJulian Pullen
9432ff2b3cSJulian Pullen
95c5c4113dSnw141292 typedef struct sid_prefix_node {
96c5c4113dSnw141292 avl_node_t avl_link;
97c5c4113dSnw141292 const char *sid_prefix;
98c5c4113dSnw141292 } sid_prefix_node_t;
99c5c4113dSnw141292
100c5c4113dSnw141292
101c5c4113dSnw141292 typedef int (*avl_comp_fn)(const void*, const void*);
102c5c4113dSnw141292
103c5c4113dSnw141292
104c5c4113dSnw141292 struct sid_prefix_store {
105c5c4113dSnw141292 struct avl_tree tree;
106c5c4113dSnw141292 krwlock_t lock;
107c5c4113dSnw141292 };
108c5c4113dSnw141292
109c5c4113dSnw141292 struct sid_prefix_store *kidmap_sid_prefix_store = NULL;
110c5c4113dSnw141292
111c5c4113dSnw141292
112c5c4113dSnw141292
113c5c4113dSnw141292 static void
11432ff2b3cSJulian Pullen kidmap_purge_sid2pid_cache(idmap_sid2pid_cache_t *cache, size_t limit);
115d15447b6Sjp151216
116d15447b6Sjp151216 static void
11732ff2b3cSJulian Pullen kidmap_purge_pid2sid_cache(idmap_pid2sid_cache_t *cache, size_t limit);
118d15447b6Sjp151216
119c5c4113dSnw141292
120c5c4113dSnw141292 /*
121c5c4113dSnw141292 * kidmap_strdup() copied from uts/common/fs/sockfs/nl7c.c
122c5c4113dSnw141292 */
123c5c4113dSnw141292 static char *
kidmap_strdup(const char * s)124c5c4113dSnw141292 kidmap_strdup(const char *s)
125c5c4113dSnw141292 {
126c5c4113dSnw141292 int len = strlen(s) + 1;
127c5c4113dSnw141292 char *ret = kmem_alloc(len, KM_SLEEP);
128c5c4113dSnw141292
129c5c4113dSnw141292 bcopy(s, ret, len);
130c5c4113dSnw141292 return (ret);
131c5c4113dSnw141292 }
132c5c4113dSnw141292
133c5c4113dSnw141292
134c5c4113dSnw141292 static int
kidmap_compare_sid(const sid2pid_t * entry1,const sid2pid_t * entry2)135d15447b6Sjp151216 kidmap_compare_sid(const sid2pid_t *entry1, const sid2pid_t *entry2)
136c5c4113dSnw141292 {
1370b10de9fSjp151216 int64_t comp = ((int64_t)entry2->rid) - ((int64_t)entry1->rid);
138c5c4113dSnw141292
139c5c4113dSnw141292 if (comp == 0)
140c5c4113dSnw141292 comp = strcmp(entry2->sid_prefix, entry1->sid_prefix);
141c5c4113dSnw141292
142c5c4113dSnw141292 if (comp < 0)
143c5c4113dSnw141292 comp = -1;
144c5c4113dSnw141292 else if (comp > 0)
145c5c4113dSnw141292 comp = 1;
146c5c4113dSnw141292
1470b10de9fSjp151216 return ((int)comp);
148c5c4113dSnw141292 }
149c5c4113dSnw141292
150c5c4113dSnw141292
151c5c4113dSnw141292 static int
kidmap_compare_pid(const pid2sid_t * entry1,const pid2sid_t * entry2)152d15447b6Sjp151216 kidmap_compare_pid(const pid2sid_t *entry1, const pid2sid_t *entry2)
153c5c4113dSnw141292 {
1540b10de9fSjp151216 if (entry2->pid > entry1->pid)
1550b10de9fSjp151216 return (1);
1560b10de9fSjp151216 if (entry2->pid < entry1->pid)
1570b10de9fSjp151216 return (-1);
1580b10de9fSjp151216 return (0);
159c5c4113dSnw141292 }
160c5c4113dSnw141292
161c5c4113dSnw141292
162c5c4113dSnw141292 static int
kidmap_compare_sid_prefix(const sid_prefix_node_t * entry1,const sid_prefix_node_t * entry2)163c5c4113dSnw141292 kidmap_compare_sid_prefix(const sid_prefix_node_t *entry1,
164c5c4113dSnw141292 const sid_prefix_node_t *entry2)
165c5c4113dSnw141292 {
166c5c4113dSnw141292 int comp;
167c5c4113dSnw141292
168c5c4113dSnw141292 comp = strcmp(entry2->sid_prefix, entry1->sid_prefix);
169c5c4113dSnw141292
170c5c4113dSnw141292 if (comp < 0)
171c5c4113dSnw141292 comp = -1;
172c5c4113dSnw141292 else if (comp > 0)
173c5c4113dSnw141292 comp = 1;
174c5c4113dSnw141292
175c5c4113dSnw141292 return (comp);
176c5c4113dSnw141292 }
177c5c4113dSnw141292
178c5c4113dSnw141292
179c5c4113dSnw141292 void
kidmap_cache_create(idmap_cache_t * cache)180c5c4113dSnw141292 kidmap_cache_create(idmap_cache_t *cache)
181c5c4113dSnw141292 {
182d15447b6Sjp151216 avl_create(&cache->sid2pid.tree, (avl_comp_fn)kidmap_compare_sid,
183d15447b6Sjp151216 sizeof (sid2pid_t), offsetof(sid2pid_t, avl_link));
184d15447b6Sjp151216 mutex_init(&cache->sid2pid.mutex, NULL, MUTEX_DEFAULT, NULL);
185d15447b6Sjp151216 cache->sid2pid.purge_time = 0;
18632ff2b3cSJulian Pullen cache->sid2pid.head.flink = &cache->sid2pid.head;
18732ff2b3cSJulian Pullen cache->sid2pid.head.blink = &cache->sid2pid.head;
188d15447b6Sjp151216 cache->sid2pid.uid_num = 0;
189d15447b6Sjp151216 cache->sid2pid.gid_num = 0;
190d15447b6Sjp151216 cache->sid2pid.pid_num = 0;
191c5c4113dSnw141292
192d15447b6Sjp151216 avl_create(&cache->uid2sid.tree, (avl_comp_fn)kidmap_compare_pid,
193d15447b6Sjp151216 sizeof (pid2sid_t), offsetof(pid2sid_t, avl_link));
194d15447b6Sjp151216 mutex_init(&cache->uid2sid.mutex, NULL, MUTEX_DEFAULT, NULL);
195d15447b6Sjp151216 cache->uid2sid.purge_time = 0;
19632ff2b3cSJulian Pullen cache->uid2sid.head.flink = &cache->uid2sid.head;
19732ff2b3cSJulian Pullen cache->uid2sid.head.blink = &cache->uid2sid.head;
1980b10de9fSjp151216
199d15447b6Sjp151216 avl_create(&cache->gid2sid.tree, (avl_comp_fn)kidmap_compare_pid,
200d15447b6Sjp151216 sizeof (pid2sid_t), offsetof(pid2sid_t, avl_link));
201d15447b6Sjp151216 mutex_init(&cache->gid2sid.mutex, NULL, MUTEX_DEFAULT, NULL);
202d15447b6Sjp151216 cache->gid2sid.purge_time = 0;
20332ff2b3cSJulian Pullen cache->gid2sid.head.flink = &cache->gid2sid.head;
20432ff2b3cSJulian Pullen cache->gid2sid.head.blink = &cache->gid2sid.head;
205c5c4113dSnw141292 }
206c5c4113dSnw141292
207c5c4113dSnw141292
208c5c4113dSnw141292 void
kidmap_cache_delete(idmap_cache_t * cache)209c5c4113dSnw141292 kidmap_cache_delete(idmap_cache_t *cache)
210c5c4113dSnw141292 {
211d15447b6Sjp151216 sid2pid_t *sid2pid;
212d15447b6Sjp151216 pid2sid_t *pid2sid;
213c5c4113dSnw141292 void *cookie;
214c5c4113dSnw141292
215c5c4113dSnw141292 cookie = NULL;
216d15447b6Sjp151216 while ((sid2pid = avl_destroy_nodes(&cache->sid2pid.tree, &cookie))
217c5c4113dSnw141292 != NULL) {
218d15447b6Sjp151216 kmem_free(sid2pid, sizeof (sid2pid_t));
219c5c4113dSnw141292 }
220d15447b6Sjp151216 avl_destroy(&cache->sid2pid.tree);
221d15447b6Sjp151216 mutex_destroy(&cache->sid2pid.mutex);
222d15447b6Sjp151216
223c5c4113dSnw141292
224c5c4113dSnw141292 cookie = NULL;
225d15447b6Sjp151216 while ((pid2sid = avl_destroy_nodes(&cache->uid2sid.tree, &cookie))
226c5c4113dSnw141292 != NULL) {
227d15447b6Sjp151216 kmem_free(pid2sid, sizeof (pid2sid_t));
228c5c4113dSnw141292 }
229d15447b6Sjp151216 avl_destroy(&cache->uid2sid.tree);
230d15447b6Sjp151216 mutex_destroy(&cache->uid2sid.mutex);
231d15447b6Sjp151216
2320b10de9fSjp151216
2330b10de9fSjp151216 cookie = NULL;
234d15447b6Sjp151216 while ((pid2sid = avl_destroy_nodes(&cache->gid2sid.tree, &cookie))
2350b10de9fSjp151216 != NULL) {
236d15447b6Sjp151216 kmem_free(pid2sid, sizeof (pid2sid_t));
2370b10de9fSjp151216 }
238d15447b6Sjp151216 avl_destroy(&cache->gid2sid.tree);
239d15447b6Sjp151216 mutex_destroy(&cache->gid2sid.mutex);
2400b10de9fSjp151216 }
2410b10de9fSjp151216
2420b10de9fSjp151216
2430b10de9fSjp151216 void
kidmap_cache_get_data(idmap_cache_t * cache,size_t * uidbysid,size_t * gidbysid,size_t * pidbysid,size_t * sidbyuid,size_t * sidbygid)244f7b4b2feSjp151216 kidmap_cache_get_data(idmap_cache_t *cache, size_t *uidbysid, size_t *gidbysid,
245f7b4b2feSjp151216 size_t *pidbysid, size_t *sidbyuid, size_t *sidbygid)
246f7b4b2feSjp151216 {
247d15447b6Sjp151216 mutex_enter(&cache->sid2pid.mutex);
248d15447b6Sjp151216 *uidbysid = cache->sid2pid.uid_num;
249d15447b6Sjp151216 *gidbysid = cache->sid2pid.gid_num;
250d15447b6Sjp151216 *pidbysid = cache->sid2pid.pid_num;
251d15447b6Sjp151216 mutex_exit(&cache->sid2pid.mutex);
252f7b4b2feSjp151216
253d15447b6Sjp151216 mutex_enter(&cache->uid2sid.mutex);
254d15447b6Sjp151216 *sidbyuid = avl_numnodes(&cache->uid2sid.tree);
255d15447b6Sjp151216 mutex_exit(&cache->uid2sid.mutex);
256f7b4b2feSjp151216
257d15447b6Sjp151216 mutex_enter(&cache->gid2sid.mutex);
258d15447b6Sjp151216 *sidbygid = avl_numnodes(&cache->gid2sid.tree);
259d15447b6Sjp151216 mutex_exit(&cache->gid2sid.mutex);
260f7b4b2feSjp151216 }
261f7b4b2feSjp151216
262f7b4b2feSjp151216
263f7b4b2feSjp151216 void
kidmap_cache_purge(idmap_cache_t * cache)2640b10de9fSjp151216 kidmap_cache_purge(idmap_cache_t *cache)
2650b10de9fSjp151216 {
266d15447b6Sjp151216 sid2pid_t *sid2pid;
267d15447b6Sjp151216 pid2sid_t *pid2sid;
2680b10de9fSjp151216 void *cookie;
2690b10de9fSjp151216
270d15447b6Sjp151216 mutex_enter(&cache->sid2pid.mutex);
2710b10de9fSjp151216 cookie = NULL;
272d15447b6Sjp151216 while ((sid2pid = avl_destroy_nodes(&cache->sid2pid.tree, &cookie))
2730b10de9fSjp151216 != NULL) {
274d15447b6Sjp151216 kmem_free(sid2pid, sizeof (sid2pid_t));
2750b10de9fSjp151216 }
276d15447b6Sjp151216 avl_destroy(&cache->sid2pid.tree);
277d15447b6Sjp151216 avl_create(&cache->sid2pid.tree, (avl_comp_fn)kidmap_compare_sid,
278d15447b6Sjp151216 sizeof (sid2pid_t), offsetof(sid2pid_t, avl_link));
279d15447b6Sjp151216 cache->sid2pid.purge_time = 0;
28032ff2b3cSJulian Pullen cache->sid2pid.head.flink = &cache->sid2pid.head;
28132ff2b3cSJulian Pullen cache->sid2pid.head.blink = &cache->sid2pid.head;
282d15447b6Sjp151216 cache->sid2pid.uid_num = 0;
283d15447b6Sjp151216 cache->sid2pid.gid_num = 0;
284d15447b6Sjp151216 cache->sid2pid.pid_num = 0;
285d15447b6Sjp151216 mutex_exit(&cache->sid2pid.mutex);
2860b10de9fSjp151216
2870b10de9fSjp151216
288d15447b6Sjp151216 mutex_enter(&cache->uid2sid.mutex);
2890b10de9fSjp151216 cookie = NULL;
290d15447b6Sjp151216 while ((pid2sid = avl_destroy_nodes(&cache->uid2sid.tree, &cookie))
2910b10de9fSjp151216 != NULL) {
292d15447b6Sjp151216 kmem_free(pid2sid, sizeof (pid2sid_t));
2930b10de9fSjp151216 }
294d15447b6Sjp151216 avl_destroy(&cache->uid2sid.tree);
295d15447b6Sjp151216 avl_create(&cache->uid2sid.tree, (avl_comp_fn)kidmap_compare_pid,
296d15447b6Sjp151216 sizeof (pid2sid_t), offsetof(pid2sid_t, avl_link));
297d15447b6Sjp151216 cache->uid2sid.purge_time = 0;
29832ff2b3cSJulian Pullen cache->uid2sid.head.flink = &cache->uid2sid.head;
29932ff2b3cSJulian Pullen cache->uid2sid.head.blink = &cache->uid2sid.head;
300d15447b6Sjp151216 mutex_exit(&cache->uid2sid.mutex);
3010b10de9fSjp151216
3020b10de9fSjp151216
303d15447b6Sjp151216 mutex_enter(&cache->gid2sid.mutex);
3040b10de9fSjp151216 cookie = NULL;
305d15447b6Sjp151216 while ((pid2sid = avl_destroy_nodes(&cache->gid2sid.tree, &cookie))
3060b10de9fSjp151216 != NULL) {
307d15447b6Sjp151216 kmem_free(pid2sid, sizeof (pid2sid_t));
3080b10de9fSjp151216 }
309d15447b6Sjp151216 avl_destroy(&cache->gid2sid.tree);
310d15447b6Sjp151216 avl_create(&cache->gid2sid.tree, (avl_comp_fn)kidmap_compare_pid,
311d15447b6Sjp151216 sizeof (pid2sid_t), offsetof(pid2sid_t, avl_link));
312d15447b6Sjp151216 cache->gid2sid.purge_time = 0;
31332ff2b3cSJulian Pullen cache->gid2sid.head.flink = &cache->gid2sid.head;
31432ff2b3cSJulian Pullen cache->gid2sid.head.blink = &cache->gid2sid.head;
315d15447b6Sjp151216 mutex_exit(&cache->gid2sid.mutex);
316c5c4113dSnw141292 }
317c5c4113dSnw141292
318c5c4113dSnw141292
319c5c4113dSnw141292 int
kidmap_cache_lookup_uidbysid(idmap_cache_t * cache,const char * sid_prefix,uint32_t rid,uid_t * uid)3200b10de9fSjp151216 kidmap_cache_lookup_uidbysid(idmap_cache_t *cache, const char *sid_prefix,
3210b10de9fSjp151216 uint32_t rid, uid_t *uid)
322c5c4113dSnw141292 {
323d15447b6Sjp151216 sid2pid_t entry;
324d15447b6Sjp151216 sid2pid_t *result;
325c5c4113dSnw141292 avl_index_t where;
32632ff2b3cSJulian Pullen int status = IDMAP_ERR_NOMAPPING;
327c5c4113dSnw141292 time_t now = gethrestime_sec();
328c5c4113dSnw141292
3290b10de9fSjp151216 entry.sid_prefix = sid_prefix;
3300b10de9fSjp151216 entry.rid = rid;
331c5c4113dSnw141292
332d15447b6Sjp151216 mutex_enter(&cache->sid2pid.mutex);
333c5c4113dSnw141292
334d15447b6Sjp151216 result = avl_find(&cache->sid2pid.tree, &entry, &where);
33532ff2b3cSJulian Pullen if (result != NULL) {
33632ff2b3cSJulian Pullen list_move(&cache->sid2pid.head, result);
33732ff2b3cSJulian Pullen if (result->uid != UNDEF_UID && result->uid_ttl > now) {
338d15447b6Sjp151216 *uid = result->uid;
339c5c4113dSnw141292 status = IDMAP_SUCCESS;
34032ff2b3cSJulian Pullen }
34132ff2b3cSJulian Pullen }
342c5c4113dSnw141292
343d15447b6Sjp151216 mutex_exit(&cache->sid2pid.mutex);
344c5c4113dSnw141292
345c5c4113dSnw141292 return (status);
346c5c4113dSnw141292 }
347c5c4113dSnw141292
348c5c4113dSnw141292
349c5c4113dSnw141292 int
kidmap_cache_lookup_gidbysid(idmap_cache_t * cache,const char * sid_prefix,uint32_t rid,gid_t * gid)3500b10de9fSjp151216 kidmap_cache_lookup_gidbysid(idmap_cache_t *cache, const char *sid_prefix,
3510b10de9fSjp151216 uint32_t rid, gid_t *gid)
3520b10de9fSjp151216 {
353d15447b6Sjp151216 sid2pid_t entry;
354d15447b6Sjp151216 sid2pid_t *result;
3550b10de9fSjp151216 avl_index_t where;
35632ff2b3cSJulian Pullen int status = IDMAP_ERR_NOMAPPING;
3570b10de9fSjp151216 time_t now = gethrestime_sec();
3580b10de9fSjp151216
3590b10de9fSjp151216 entry.sid_prefix = sid_prefix;
3600b10de9fSjp151216 entry.rid = rid;
3610b10de9fSjp151216
362d15447b6Sjp151216 mutex_enter(&cache->sid2pid.mutex);
3630b10de9fSjp151216
364d15447b6Sjp151216 result = avl_find(&cache->sid2pid.tree, &entry, &where);
36532ff2b3cSJulian Pullen if (result != NULL) {
36632ff2b3cSJulian Pullen list_move(&cache->sid2pid.head, result);
36732ff2b3cSJulian Pullen if (result->gid != UNDEF_GID && result->gid_ttl > now) {
368d15447b6Sjp151216 *gid = result->gid;
3690b10de9fSjp151216 status = IDMAP_SUCCESS;
37032ff2b3cSJulian Pullen }
37132ff2b3cSJulian Pullen }
3720b10de9fSjp151216
373d15447b6Sjp151216 mutex_exit(&cache->sid2pid.mutex);
3740b10de9fSjp151216
3750b10de9fSjp151216 return (status);
3760b10de9fSjp151216 }
3770b10de9fSjp151216
3780b10de9fSjp151216
3790b10de9fSjp151216 int
kidmap_cache_lookup_pidbysid(idmap_cache_t * cache,const char * sid_prefix,uint32_t rid,uid_t * pid,int * is_user)3800b10de9fSjp151216 kidmap_cache_lookup_pidbysid(idmap_cache_t *cache, const char *sid_prefix,
381c5c4113dSnw141292 uint32_t rid, uid_t *pid, int *is_user)
382c5c4113dSnw141292 {
383d15447b6Sjp151216 sid2pid_t entry;
384d15447b6Sjp151216 sid2pid_t *result;
385c5c4113dSnw141292 avl_index_t where;
38632ff2b3cSJulian Pullen int status = IDMAP_ERR_NOMAPPING;
387c5c4113dSnw141292 time_t now = gethrestime_sec();
388c5c4113dSnw141292
389c5c4113dSnw141292 entry.sid_prefix = sid_prefix;
390c5c4113dSnw141292 entry.rid = rid;
391c5c4113dSnw141292
392d15447b6Sjp151216 mutex_enter(&cache->sid2pid.mutex);
393c5c4113dSnw141292
394d15447b6Sjp151216 result = avl_find(&cache->sid2pid.tree, &entry, &where);
39532ff2b3cSJulian Pullen if (result != NULL) {
39632ff2b3cSJulian Pullen list_move(&cache->sid2pid.head, result);
39732ff2b3cSJulian Pullen if (result->is_user != UNDEF_ISUSER) {
398d15447b6Sjp151216 if (result->is_user && result->uid_ttl > now) {
399d15447b6Sjp151216 *pid = result->uid;
400d15447b6Sjp151216 *is_user = result->is_user;
401d15447b6Sjp151216 status = IDMAP_SUCCESS;
402d15447b6Sjp151216 } else if (!result->is_user && result->gid_ttl > now) {
403d15447b6Sjp151216 *pid = result->gid;
404c5c4113dSnw141292 *is_user = result->is_user;
405c5c4113dSnw141292 status = IDMAP_SUCCESS;
40632ff2b3cSJulian Pullen }
40732ff2b3cSJulian Pullen }
40832ff2b3cSJulian Pullen }
409c5c4113dSnw141292
410d15447b6Sjp151216 mutex_exit(&cache->sid2pid.mutex);
411c5c4113dSnw141292
412c5c4113dSnw141292 return (status);
413c5c4113dSnw141292 }
414c5c4113dSnw141292
415c5c4113dSnw141292
4160b10de9fSjp151216
4170b10de9fSjp151216 int
kidmap_cache_lookup_sidbyuid(idmap_cache_t * cache,const char ** sid_prefix,uint32_t * rid,uid_t uid)4180b10de9fSjp151216 kidmap_cache_lookup_sidbyuid(idmap_cache_t *cache, const char **sid_prefix,
4190b10de9fSjp151216 uint32_t *rid, uid_t uid)
420c5c4113dSnw141292 {
421d15447b6Sjp151216 pid2sid_t entry;
422d15447b6Sjp151216 pid2sid_t *result;
423c5c4113dSnw141292 avl_index_t where;
42432ff2b3cSJulian Pullen int status = IDMAP_ERR_NOMAPPING;
4250b10de9fSjp151216 time_t now = gethrestime_sec();
426c5c4113dSnw141292
4270b10de9fSjp151216 entry.pid = uid;
428c5c4113dSnw141292
429d15447b6Sjp151216 mutex_enter(&cache->uid2sid.mutex);
430c5c4113dSnw141292
431d15447b6Sjp151216 result = avl_find(&cache->uid2sid.tree, &entry, &where);
43232ff2b3cSJulian Pullen if (result != NULL) {
43332ff2b3cSJulian Pullen list_move(&cache->uid2sid.head, result);
43432ff2b3cSJulian Pullen if (result->ttl > now) {
4350b10de9fSjp151216 *sid_prefix = result->sid_prefix;
4360b10de9fSjp151216 *rid = result->rid;
4370b10de9fSjp151216 status = IDMAP_SUCCESS;
43832ff2b3cSJulian Pullen }
43932ff2b3cSJulian Pullen }
4400b10de9fSjp151216
441d15447b6Sjp151216 mutex_exit(&cache->uid2sid.mutex);
4420b10de9fSjp151216
4430b10de9fSjp151216 return (status);
444c5c4113dSnw141292 }
445c5c4113dSnw141292
44632ff2b3cSJulian Pullen
4470b10de9fSjp151216 int
kidmap_cache_lookup_sidbygid(idmap_cache_t * cache,const char ** sid_prefix,uint32_t * rid,gid_t gid)4480b10de9fSjp151216 kidmap_cache_lookup_sidbygid(idmap_cache_t *cache, const char **sid_prefix,
4490b10de9fSjp151216 uint32_t *rid, gid_t gid)
4500b10de9fSjp151216 {
451d15447b6Sjp151216 pid2sid_t entry;
452d15447b6Sjp151216 pid2sid_t *result;
4530b10de9fSjp151216 avl_index_t where;
45432ff2b3cSJulian Pullen int status = IDMAP_ERR_NOMAPPING;
4550b10de9fSjp151216 time_t now = gethrestime_sec();
456c5c4113dSnw141292
4570b10de9fSjp151216 entry.pid = gid;
4580b10de9fSjp151216
459d15447b6Sjp151216 mutex_enter(&cache->gid2sid.mutex);
4600b10de9fSjp151216
461d15447b6Sjp151216 result = avl_find(&cache->gid2sid.tree, &entry, &where);
46232ff2b3cSJulian Pullen if (result != NULL) {
46332ff2b3cSJulian Pullen list_move(&cache->gid2sid.head, result);
46432ff2b3cSJulian Pullen if (result->ttl > now) {
4650b10de9fSjp151216 *sid_prefix = result->sid_prefix;
4660b10de9fSjp151216 *rid = result->rid;
4670b10de9fSjp151216 status = IDMAP_SUCCESS;
46832ff2b3cSJulian Pullen }
46932ff2b3cSJulian Pullen }
4700b10de9fSjp151216
471d15447b6Sjp151216 mutex_exit(&cache->gid2sid.mutex);
4720b10de9fSjp151216
4730b10de9fSjp151216 return (status);
474c5c4113dSnw141292 }
475c5c4113dSnw141292
476c5c4113dSnw141292
477c5c4113dSnw141292 void
kidmap_cache_add_sid2uid(idmap_cache_t * cache,const char * sid_prefix,uint32_t rid,uid_t uid,int direction)478d15447b6Sjp151216 kidmap_cache_add_sid2uid(idmap_cache_t *cache, const char *sid_prefix,
479d15447b6Sjp151216 uint32_t rid, uid_t uid, int direction)
480c5c4113dSnw141292
481c5c4113dSnw141292 {
482c5c4113dSnw141292 avl_index_t where;
4830b10de9fSjp151216 time_t ttl = CACHE_TTL + gethrestime_sec();
484c5c4113dSnw141292
485d15447b6Sjp151216
486d15447b6Sjp151216 if (direction == IDMAP_DIRECTION_BI ||
487d15447b6Sjp151216 direction == IDMAP_DIRECTION_W2U) {
488d15447b6Sjp151216 sid2pid_t find;
489d15447b6Sjp151216 sid2pid_t *result;
490d15447b6Sjp151216 sid2pid_t *new;
491d15447b6Sjp151216
492c5c4113dSnw141292 find.sid_prefix = sid_prefix;
493c5c4113dSnw141292 find.rid = rid;
494c5c4113dSnw141292
495d15447b6Sjp151216 mutex_enter(&cache->sid2pid.mutex);
4960b10de9fSjp151216
49732ff2b3cSJulian Pullen result = avl_find(&cache->sid2pid.tree, &find, &where);
4980b10de9fSjp151216 if (result) {
499d15447b6Sjp151216 if (result->uid == UNDEF_UID)
500d15447b6Sjp151216 cache->sid2pid.uid_num++;
501d15447b6Sjp151216 result->uid = uid;
502d15447b6Sjp151216 result->uid_ttl = ttl;
5030b10de9fSjp151216 } else {
504d15447b6Sjp151216 new = kmem_alloc(sizeof (sid2pid_t), KM_SLEEP);
5050b10de9fSjp151216 new->sid_prefix = sid_prefix;
5060b10de9fSjp151216 new->rid = rid;
507d15447b6Sjp151216 new->uid = uid;
508d15447b6Sjp151216 new->uid_ttl = ttl;
509d15447b6Sjp151216 new->gid = UNDEF_GID;
510d15447b6Sjp151216 new->gid_ttl = 0;
511d15447b6Sjp151216 new->is_user = UNDEF_ISUSER; /* Unknown */
512d15447b6Sjp151216 cache->sid2pid.uid_num++;
5130b10de9fSjp151216
51432ff2b3cSJulian Pullen list_insert(&cache->sid2pid.head, new);
515d15447b6Sjp151216 avl_insert(&cache->sid2pid.tree, new, where);
51632ff2b3cSJulian Pullen }
5170b10de9fSjp151216
518d15447b6Sjp151216 if ((avl_numnodes(&cache->sid2pid.tree) >
519d15447b6Sjp151216 CACHE_PID_TRIGGER_SIZE) &&
520d15447b6Sjp151216 (cache->sid2pid.purge_time + CACHE_PURGE_INTERVAL <
5210b10de9fSjp151216 gethrestime_sec()))
52232ff2b3cSJulian Pullen kidmap_purge_sid2pid_cache(&cache->sid2pid,
52332ff2b3cSJulian Pullen CACHE_PID_TRIGGER_SIZE);
5240b10de9fSjp151216
525d15447b6Sjp151216 mutex_exit(&cache->sid2pid.mutex);
5260b10de9fSjp151216 }
5270b10de9fSjp151216
528d15447b6Sjp151216 if (direction == IDMAP_DIRECTION_BI ||
529d15447b6Sjp151216 direction == IDMAP_DIRECTION_U2W) {
530d15447b6Sjp151216 pid2sid_t find;
531d15447b6Sjp151216 pid2sid_t *result;
532d15447b6Sjp151216 pid2sid_t *new;
5330b10de9fSjp151216
5340b10de9fSjp151216 find.pid = uid;
5350b10de9fSjp151216
536d15447b6Sjp151216 mutex_enter(&cache->uid2sid.mutex);
5370b10de9fSjp151216
53832ff2b3cSJulian Pullen result = avl_find(&cache->uid2sid.tree, &find, &where);
5390b10de9fSjp151216 if (result) {
5400b10de9fSjp151216 result->sid_prefix = sid_prefix;
5410b10de9fSjp151216 result->rid = rid;
5420b10de9fSjp151216 result->ttl = ttl;
5430b10de9fSjp151216 } else {
544d15447b6Sjp151216 new = kmem_alloc(sizeof (pid2sid_t), KM_SLEEP);
5450b10de9fSjp151216 new->sid_prefix = sid_prefix;
5460b10de9fSjp151216 new->rid = rid;
547d15447b6Sjp151216 new->pid = uid;
5480b10de9fSjp151216 new->ttl = ttl;
5490b10de9fSjp151216
55032ff2b3cSJulian Pullen list_insert(&cache->uid2sid.head, new);
551d15447b6Sjp151216 avl_insert(&cache->uid2sid.tree, new, where);
55232ff2b3cSJulian Pullen }
553d15447b6Sjp151216
554d15447b6Sjp151216 if ((avl_numnodes(&cache->uid2sid.tree) >
555d15447b6Sjp151216 CACHE_UID_TRIGGER_SIZE) &&
556d15447b6Sjp151216 (cache->uid2sid.purge_time + CACHE_PURGE_INTERVAL <
5570b10de9fSjp151216 gethrestime_sec()))
55832ff2b3cSJulian Pullen kidmap_purge_pid2sid_cache(&cache->uid2sid,
559d15447b6Sjp151216 CACHE_UID_TRIGGER_SIZE);
56032ff2b3cSJulian Pullen
56132ff2b3cSJulian Pullen mutex_exit(&cache->uid2sid.mutex);
562d15447b6Sjp151216 }
563d15447b6Sjp151216 }
564d15447b6Sjp151216
565d15447b6Sjp151216
566d15447b6Sjp151216
567d15447b6Sjp151216 void
kidmap_cache_add_sid2gid(idmap_cache_t * cache,const char * sid_prefix,uint32_t rid,gid_t gid,int direction)568d15447b6Sjp151216 kidmap_cache_add_sid2gid(idmap_cache_t *cache, const char *sid_prefix,
569d15447b6Sjp151216 uint32_t rid, gid_t gid, int direction)
570d15447b6Sjp151216 {
571d15447b6Sjp151216 avl_index_t where;
572d15447b6Sjp151216 time_t ttl = CACHE_TTL + gethrestime_sec();
573d15447b6Sjp151216
574d15447b6Sjp151216
575d15447b6Sjp151216 if (direction == IDMAP_DIRECTION_BI ||
576d15447b6Sjp151216 direction == IDMAP_DIRECTION_W2U) {
577d15447b6Sjp151216 sid2pid_t find;
578d15447b6Sjp151216 sid2pid_t *result;
579d15447b6Sjp151216 sid2pid_t *new;
580d15447b6Sjp151216
581d15447b6Sjp151216 find.sid_prefix = sid_prefix;
582d15447b6Sjp151216 find.rid = rid;
583d15447b6Sjp151216
584d15447b6Sjp151216 mutex_enter(&cache->sid2pid.mutex);
585d15447b6Sjp151216
58632ff2b3cSJulian Pullen result = avl_find(&cache->sid2pid.tree, &find, &where);
587d15447b6Sjp151216 if (result) {
588d15447b6Sjp151216 if (result->gid == UNDEF_GID)
589d15447b6Sjp151216 cache->sid2pid.gid_num++;
590d15447b6Sjp151216 result->gid = gid;
591d15447b6Sjp151216 result->gid_ttl = ttl;
592d15447b6Sjp151216 } else {
593d15447b6Sjp151216 new = kmem_alloc(sizeof (sid2pid_t), KM_SLEEP);
594d15447b6Sjp151216 new->sid_prefix = sid_prefix;
595d15447b6Sjp151216 new->rid = rid;
596d15447b6Sjp151216 new->uid = UNDEF_UID;
597d15447b6Sjp151216 new->uid_ttl = 0;
598d15447b6Sjp151216 new->gid = gid;
599d15447b6Sjp151216 new->gid_ttl = ttl;
600d15447b6Sjp151216 new->is_user = UNDEF_ISUSER; /* Unknown */
601d15447b6Sjp151216 cache->sid2pid.gid_num++;
602d15447b6Sjp151216
60332ff2b3cSJulian Pullen list_insert(&cache->sid2pid.head, new);
604d15447b6Sjp151216 avl_insert(&cache->sid2pid.tree, new, where);
60532ff2b3cSJulian Pullen }
606d15447b6Sjp151216
607d15447b6Sjp151216 if ((avl_numnodes(&cache->sid2pid.tree) >
608d15447b6Sjp151216 CACHE_PID_TRIGGER_SIZE) &&
609d15447b6Sjp151216 (cache->sid2pid.purge_time + CACHE_PURGE_INTERVAL <
610d15447b6Sjp151216 gethrestime_sec()))
61132ff2b3cSJulian Pullen kidmap_purge_sid2pid_cache(&cache->sid2pid,
612d15447b6Sjp151216 CACHE_PID_TRIGGER_SIZE);
61332ff2b3cSJulian Pullen
61432ff2b3cSJulian Pullen mutex_exit(&cache->sid2pid.mutex);
615d15447b6Sjp151216 }
616d15447b6Sjp151216
617d15447b6Sjp151216 if (direction == IDMAP_DIRECTION_BI ||
618d15447b6Sjp151216 direction == IDMAP_DIRECTION_U2W) {
619d15447b6Sjp151216 pid2sid_t find;
620d15447b6Sjp151216 pid2sid_t *result;
621d15447b6Sjp151216 pid2sid_t *new;
622d15447b6Sjp151216
623d15447b6Sjp151216 find.pid = gid;
624d15447b6Sjp151216
625d15447b6Sjp151216 mutex_enter(&cache->gid2sid.mutex);
626d15447b6Sjp151216
62732ff2b3cSJulian Pullen result = avl_find(&cache->gid2sid.tree, &find, &where);
628d15447b6Sjp151216 if (result) {
629d15447b6Sjp151216 result->sid_prefix = sid_prefix;
630d15447b6Sjp151216 result->rid = rid;
631d15447b6Sjp151216 result->ttl = ttl;
632d15447b6Sjp151216 } else {
633d15447b6Sjp151216 new = kmem_alloc(sizeof (pid2sid_t), KM_SLEEP);
634d15447b6Sjp151216 new->sid_prefix = sid_prefix;
635d15447b6Sjp151216 new->rid = rid;
636d15447b6Sjp151216 new->pid = gid;
637d15447b6Sjp151216 new->ttl = ttl;
638d15447b6Sjp151216
63932ff2b3cSJulian Pullen list_insert(&cache->gid2sid.head, new);
640d15447b6Sjp151216 avl_insert(&cache->gid2sid.tree, new, where);
64132ff2b3cSJulian Pullen }
642d15447b6Sjp151216
643d15447b6Sjp151216 if ((avl_numnodes(&cache->gid2sid.tree) >
644d15447b6Sjp151216 CACHE_GID_TRIGGER_SIZE) &&
645d15447b6Sjp151216 (cache->gid2sid.purge_time + CACHE_PURGE_INTERVAL <
646d15447b6Sjp151216 gethrestime_sec()))
64732ff2b3cSJulian Pullen kidmap_purge_pid2sid_cache(&cache->gid2sid,
648d15447b6Sjp151216 CACHE_GID_TRIGGER_SIZE);
64932ff2b3cSJulian Pullen
65032ff2b3cSJulian Pullen mutex_exit(&cache->gid2sid.mutex);
651d15447b6Sjp151216 }
6520b10de9fSjp151216 }
6530b10de9fSjp151216
6540b10de9fSjp151216
6550b10de9fSjp151216 void
kidmap_cache_add_sid2pid(idmap_cache_t * cache,const char * sid_prefix,uint32_t rid,uid_t pid,int is_user,int direction)656d15447b6Sjp151216 kidmap_cache_add_sid2pid(idmap_cache_t *cache, const char *sid_prefix,
657d15447b6Sjp151216 uint32_t rid, uid_t pid, int is_user, int direction)
6580b10de9fSjp151216 {
6590b10de9fSjp151216 avl_index_t where;
6600b10de9fSjp151216 time_t ttl = CACHE_TTL + gethrestime_sec();
6610b10de9fSjp151216
6620b10de9fSjp151216
663d15447b6Sjp151216 if (direction == IDMAP_DIRECTION_BI ||
664d15447b6Sjp151216 direction == IDMAP_DIRECTION_W2U) {
665d15447b6Sjp151216 sid2pid_t find;
666d15447b6Sjp151216 sid2pid_t *result;
667d15447b6Sjp151216 sid2pid_t *new;
668d15447b6Sjp151216
669d15447b6Sjp151216 find.sid_prefix = sid_prefix;
670d15447b6Sjp151216 find.rid = rid;
671d15447b6Sjp151216
672d15447b6Sjp151216 mutex_enter(&cache->sid2pid.mutex);
673d15447b6Sjp151216
67432ff2b3cSJulian Pullen result = avl_find(&cache->sid2pid.tree, &find, &where);
675d15447b6Sjp151216 if (result) {
676d15447b6Sjp151216 if (result->is_user == UNDEF_ISUSER)
677d15447b6Sjp151216 cache->sid2pid.pid_num++;
678d15447b6Sjp151216 result->is_user = is_user;
679d15447b6Sjp151216 if (is_user) {
680d15447b6Sjp151216 if (result->uid == UNDEF_UID)
681d15447b6Sjp151216 cache->sid2pid.uid_num++;
682d15447b6Sjp151216 result->uid = pid;
683d15447b6Sjp151216 result->uid_ttl = ttl;
684d15447b6Sjp151216 } else {
685d15447b6Sjp151216 if (result->gid == UNDEF_GID)
686d15447b6Sjp151216 cache->sid2pid.gid_num++;
687d15447b6Sjp151216 result->gid = pid;
688d15447b6Sjp151216 result->gid_ttl = ttl;
689d15447b6Sjp151216 }
690d15447b6Sjp151216 } else {
691d15447b6Sjp151216 new = kmem_alloc(sizeof (sid2pid_t), KM_SLEEP);
692d15447b6Sjp151216 new->sid_prefix = sid_prefix;
693d15447b6Sjp151216 new->rid = rid;
694d15447b6Sjp151216 new->is_user = is_user;
695d15447b6Sjp151216 if (is_user) {
696d15447b6Sjp151216 new->uid = pid;
697d15447b6Sjp151216 new->uid_ttl = ttl;
698d15447b6Sjp151216 new->gid = UNDEF_GID;
699d15447b6Sjp151216 new->gid_ttl = 0;
700d15447b6Sjp151216 cache->sid2pid.uid_num++;
701d15447b6Sjp151216 } else {
702d15447b6Sjp151216 new->uid = UNDEF_UID;
703d15447b6Sjp151216 new->uid_ttl = 0;
704d15447b6Sjp151216 new->gid = pid;
705d15447b6Sjp151216 new->gid_ttl = ttl;
706d15447b6Sjp151216 cache->sid2pid.gid_num++;
707d15447b6Sjp151216 }
708d15447b6Sjp151216 cache->sid2pid.pid_num++;
709d15447b6Sjp151216
71032ff2b3cSJulian Pullen list_insert(&cache->sid2pid.head, new);
711d15447b6Sjp151216 avl_insert(&cache->sid2pid.tree, new, where);
71232ff2b3cSJulian Pullen }
713d15447b6Sjp151216
714d15447b6Sjp151216 if ((avl_numnodes(&cache->sid2pid.tree) >
715d15447b6Sjp151216 CACHE_PID_TRIGGER_SIZE) &&
716d15447b6Sjp151216 (cache->sid2pid.purge_time + CACHE_PURGE_INTERVAL <
717d15447b6Sjp151216 gethrestime_sec()))
71832ff2b3cSJulian Pullen kidmap_purge_sid2pid_cache(&cache->sid2pid,
719d15447b6Sjp151216 CACHE_PID_TRIGGER_SIZE);
72032ff2b3cSJulian Pullen
72132ff2b3cSJulian Pullen mutex_exit(&cache->sid2pid.mutex);
722d15447b6Sjp151216 }
723d15447b6Sjp151216
724d15447b6Sjp151216 if (direction == IDMAP_DIRECTION_BI ||
725d15447b6Sjp151216 direction == IDMAP_DIRECTION_U2W) {
726d15447b6Sjp151216 pid2sid_t find;
727d15447b6Sjp151216 pid2sid_t *result;
728d15447b6Sjp151216 pid2sid_t *new;
729d15447b6Sjp151216
730d15447b6Sjp151216 find.pid = pid;
731d15447b6Sjp151216 if (is_user) {
732d15447b6Sjp151216 mutex_enter(&cache->uid2sid.mutex);
7330b10de9fSjp151216
73432ff2b3cSJulian Pullen result = avl_find(&cache->uid2sid.tree, &find, &where);
7350b10de9fSjp151216 if (result) {
7360b10de9fSjp151216 result->sid_prefix = sid_prefix;
7370b10de9fSjp151216 result->rid = rid;
7380b10de9fSjp151216 result->ttl = ttl;
7390b10de9fSjp151216 } else {
740d15447b6Sjp151216 new = kmem_alloc(sizeof (pid2sid_t), KM_SLEEP);
7410b10de9fSjp151216 new->sid_prefix = sid_prefix;
7420b10de9fSjp151216 new->rid = rid;
743d15447b6Sjp151216 new->pid = pid;
7440b10de9fSjp151216 new->ttl = ttl;
7450b10de9fSjp151216
74632ff2b3cSJulian Pullen list_insert(&cache->uid2sid.head, new);
747d15447b6Sjp151216 avl_insert(&cache->uid2sid.tree, new, where);
74832ff2b3cSJulian Pullen }
749d15447b6Sjp151216
750d15447b6Sjp151216 if ((avl_numnodes(&cache->uid2sid.tree) >
751d15447b6Sjp151216 CACHE_UID_TRIGGER_SIZE) &&
752d15447b6Sjp151216 (cache->uid2sid.purge_time +
753d15447b6Sjp151216 CACHE_PURGE_INTERVAL <
7540b10de9fSjp151216 gethrestime_sec()))
75532ff2b3cSJulian Pullen kidmap_purge_pid2sid_cache(&cache->uid2sid,
756d15447b6Sjp151216 CACHE_UID_TRIGGER_SIZE);
75732ff2b3cSJulian Pullen
75832ff2b3cSJulian Pullen mutex_exit(&cache->uid2sid.mutex);
759d15447b6Sjp151216 } else {
760d15447b6Sjp151216 mutex_enter(&cache->gid2sid.mutex);
761d15447b6Sjp151216
76232ff2b3cSJulian Pullen result = avl_find(&cache->gid2sid.tree, &find, &where);
763d15447b6Sjp151216 if (result) {
764d15447b6Sjp151216 result->sid_prefix = sid_prefix;
765d15447b6Sjp151216 result->rid = rid;
766d15447b6Sjp151216 result->ttl = ttl;
767d15447b6Sjp151216 } else {
768d15447b6Sjp151216 new = kmem_alloc(sizeof (pid2sid_t), KM_SLEEP);
769d15447b6Sjp151216 new->sid_prefix = sid_prefix;
770d15447b6Sjp151216 new->rid = rid;
771d15447b6Sjp151216 new->pid = pid;
772d15447b6Sjp151216 new->ttl = ttl;
773d15447b6Sjp151216
77432ff2b3cSJulian Pullen list_insert(&cache->gid2sid.head, new);
775d15447b6Sjp151216 avl_insert(&cache->gid2sid.tree, new, where);
77632ff2b3cSJulian Pullen }
777d15447b6Sjp151216
778d15447b6Sjp151216 if ((avl_numnodes(&cache->gid2sid.tree) >
779d15447b6Sjp151216 CACHE_GID_TRIGGER_SIZE) &&
780d15447b6Sjp151216 (cache->gid2sid.purge_time +
78132ff2b3cSJulian Pullen CACHE_PURGE_INTERVAL < gethrestime_sec()))
78232ff2b3cSJulian Pullen kidmap_purge_pid2sid_cache(&cache->gid2sid,
783d15447b6Sjp151216 CACHE_GID_TRIGGER_SIZE);
78432ff2b3cSJulian Pullen
78532ff2b3cSJulian Pullen mutex_exit(&cache->gid2sid.mutex);
786d15447b6Sjp151216 }
787d15447b6Sjp151216 }
788d15447b6Sjp151216 }
789d15447b6Sjp151216
790d15447b6Sjp151216
791d15447b6Sjp151216
792d15447b6Sjp151216
793d15447b6Sjp151216
794d15447b6Sjp151216 static void
kidmap_purge_sid2pid_cache(idmap_sid2pid_cache_t * cache,size_t limit)79532ff2b3cSJulian Pullen kidmap_purge_sid2pid_cache(idmap_sid2pid_cache_t *cache, size_t limit)
796d15447b6Sjp151216 {
797d15447b6Sjp151216 time_t now = gethrestime_sec();
79832ff2b3cSJulian Pullen sid2pid_t *item;
799d15447b6Sjp151216
80032ff2b3cSJulian Pullen while (avl_numnodes(&cache->tree) > limit) {
80132ff2b3cSJulian Pullen /* Remove least recently used */
80232ff2b3cSJulian Pullen item = cache->head.blink;
80332ff2b3cSJulian Pullen list_remove(item);
80432ff2b3cSJulian Pullen avl_remove(&cache->tree, item);
80532ff2b3cSJulian Pullen if (item->uid != UNDEF_UID)
80632ff2b3cSJulian Pullen cache->uid_num--;
80732ff2b3cSJulian Pullen if (item->gid != UNDEF_GID)
80832ff2b3cSJulian Pullen cache->gid_num--;
80932ff2b3cSJulian Pullen if (item->is_user != UNDEF_ISUSER)
81032ff2b3cSJulian Pullen cache->pid_num--;
81132ff2b3cSJulian Pullen kmem_free(item, sizeof (sid2pid_t));
812d15447b6Sjp151216 }
81332ff2b3cSJulian Pullen cache->purge_time = now;
814c5c4113dSnw141292 }
815c5c4113dSnw141292
816c5c4113dSnw141292
817c5c4113dSnw141292 static void
kidmap_purge_pid2sid_cache(idmap_pid2sid_cache_t * cache,size_t limit)81832ff2b3cSJulian Pullen kidmap_purge_pid2sid_cache(idmap_pid2sid_cache_t *cache, size_t limit)
819c5c4113dSnw141292 {
820c5c4113dSnw141292 time_t now = gethrestime_sec();
82132ff2b3cSJulian Pullen pid2sid_t *item;
822c5c4113dSnw141292
82332ff2b3cSJulian Pullen while (avl_numnodes(&cache->tree) > limit) {
82432ff2b3cSJulian Pullen /* Remove least recently used */
82532ff2b3cSJulian Pullen item = cache->head.blink;
82632ff2b3cSJulian Pullen list_remove(item);
82732ff2b3cSJulian Pullen avl_remove(&cache->tree, item);
82832ff2b3cSJulian Pullen kmem_free(item, sizeof (pid2sid_t));
829d15447b6Sjp151216 }
83032ff2b3cSJulian Pullen cache->purge_time = now;
831c5c4113dSnw141292 }
832d15447b6Sjp151216
833d15447b6Sjp151216
834c5c4113dSnw141292 void
kidmap_sid_prefix_store_init(void)835c5c4113dSnw141292 kidmap_sid_prefix_store_init(void)
836c5c4113dSnw141292 {
837c5c4113dSnw141292 kidmap_sid_prefix_store = (struct sid_prefix_store *)
838c5c4113dSnw141292 space_fetch("SUNW,idmap_sid_prefix");
839c5c4113dSnw141292 if (kidmap_sid_prefix_store == NULL) {
840c5c4113dSnw141292 kidmap_sid_prefix_store = kmem_alloc(
841c5c4113dSnw141292 sizeof (struct sid_prefix_store), KM_SLEEP);
842c5c4113dSnw141292 rw_init(&kidmap_sid_prefix_store->lock, NULL, RW_DRIVER, NULL);
843c5c4113dSnw141292 avl_create(&kidmap_sid_prefix_store->tree,
844c5c4113dSnw141292 (avl_comp_fn)kidmap_compare_sid_prefix,
845c5c4113dSnw141292 sizeof (sid_prefix_node_t),
846c5c4113dSnw141292 offsetof(sid_prefix_node_t, avl_link));
847c5c4113dSnw141292 (void) space_store("SUNW,idmap_sid_prefix",
848c5c4113dSnw141292 (uintptr_t)kidmap_sid_prefix_store);
849c5c4113dSnw141292 } else {
850c5c4113dSnw141292 /*
851c5c4113dSnw141292 * The AVL comparison function must be re-initialised on
852c5c4113dSnw141292 * re-load because may not be loaded into the same
853c5c4113dSnw141292 * address space.
854c5c4113dSnw141292 */
855c5c4113dSnw141292 kidmap_sid_prefix_store->tree.avl_compar =
856c5c4113dSnw141292 (avl_comp_fn)kidmap_compare_sid_prefix;
857c5c4113dSnw141292 }
858c5c4113dSnw141292 }
859c5c4113dSnw141292
860c5c4113dSnw141292
861c5c4113dSnw141292 const char *
kidmap_find_sid_prefix(const char * sid_prefix)862c5c4113dSnw141292 kidmap_find_sid_prefix(const char *sid_prefix) {
863c5c4113dSnw141292 sid_prefix_node_t find;
864c5c4113dSnw141292 sid_prefix_node_t *result;
865c5c4113dSnw141292 sid_prefix_node_t *new;
866c5c4113dSnw141292 avl_index_t where;
867c5c4113dSnw141292
868c5c4113dSnw141292 if (sid_prefix == NULL || *sid_prefix == '\0')
869c5c4113dSnw141292 return (NULL);
870c5c4113dSnw141292
871c5c4113dSnw141292 find.sid_prefix = sid_prefix;
872c5c4113dSnw141292
873c5c4113dSnw141292 rw_enter(&kidmap_sid_prefix_store->lock, RW_READER);
874c5c4113dSnw141292
875c5c4113dSnw141292 result = avl_find(&kidmap_sid_prefix_store->tree, &find, &where);
876c5c4113dSnw141292
877c5c4113dSnw141292 if (result) {
878c5c4113dSnw141292 rw_exit(&kidmap_sid_prefix_store->lock);
879c5c4113dSnw141292 return (result->sid_prefix);
880c5c4113dSnw141292 }
881c5c4113dSnw141292
882c5c4113dSnw141292 if (rw_tryupgrade(&kidmap_sid_prefix_store->lock) == 0) {
883c5c4113dSnw141292 /*
884c5c4113dSnw141292 * Could not upgrade lock so release lock
885da6c28aaSamw * and acquire the write lock
886c5c4113dSnw141292 */
887c5c4113dSnw141292 rw_exit(&kidmap_sid_prefix_store->lock);
888c5c4113dSnw141292 rw_enter(&kidmap_sid_prefix_store->lock, RW_WRITER);
889c5c4113dSnw141292
890c5c4113dSnw141292 result = avl_find(&kidmap_sid_prefix_store->tree,
891c5c4113dSnw141292 &find, &where);
892c5c4113dSnw141292 if (result) {
893c5c4113dSnw141292 rw_exit(&kidmap_sid_prefix_store->lock);
894c5c4113dSnw141292 return (result->sid_prefix);
895c5c4113dSnw141292 }
896c5c4113dSnw141292 }
897c5c4113dSnw141292
898c5c4113dSnw141292 new = kmem_alloc(sizeof (sid_prefix_node_t), KM_SLEEP);
899c5c4113dSnw141292 new->sid_prefix = kidmap_strdup(sid_prefix);
900c5c4113dSnw141292 avl_insert(&kidmap_sid_prefix_store->tree, new, where);
901c5c4113dSnw141292 rw_exit(&kidmap_sid_prefix_store->lock);
902c5c4113dSnw141292
903c5c4113dSnw141292 return (new->sid_prefix);
904c5c4113dSnw141292 }
905