1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Windows to Solaris Identity Mapping
29 * This module provides the libidmap idmap_cache.
30 */
31
32
33 #include <sys/types.h>
34 #include <sys/avl.h>
35 #include <assert.h>
36 #include <pthread.h>
37 #include <strings.h>
38 #include <sys/idmap.h>
39 #include <stddef.h>
40 #include <stdlib.h>
41 #include <rpcsvc/idmap_prot.h>
42 #include "idmap_cache.h"
43
44
45 /*
46 * Internal definitions and functions
47 */
48
49 #define CACHE_UID_TRIGGER_SIZE 4096
50 #define CACHE_GID_TRIGGER_SIZE 2048
51 #define CACHE_UID_GID_TRIGGER_SIZE \
52 (CACHE_UID_TRIGGER_SIZE + CACHE_GID_TRIGGER_SIZE)
53
54
55 #define UNDEF_UID ((uid_t)-1)
56 #define UNDEF_GID ((gid_t)-1)
57 #define UNDEF_ISUSER (-1)
58
59 #define CACHE_PURGE_INTERVAL (60 * 3)
60 #define CACHE_TTL (60 * 10)
61
62
63
64
65 #define list_insert(head, ele)\
66 do {\
67 (ele)->flink = (head)->flink;\
68 (head)->flink = (ele);\
69 (ele)->blink = (ele)->flink->blink;\
70 (ele)->flink->blink = (ele);\
71 } while (0)
72
73
74
75 #define list_remove(ele)\
76 do {\
77 (ele)->flink->blink = (ele)->blink;\
78 (ele)->blink->flink = (ele)->flink;\
79 } while (0)
80
81
82 #define list_move(head, ele) \
83 do {\
84 if ((head)->flink != (ele)) {\
85 list_remove(ele);\
86 list_insert(head, ele);\
87 }\
88 } while (0)
89
90 typedef struct sid2uid_gid {
91 avl_node_t avl_link;
92 struct sid2uid_gid *flink;
93 struct sid2uid_gid *blink;
94 const char *sid_prefix;
95 idmap_rid_t rid;
96 uid_t uid;
97 time_t uid_ttl;
98 gid_t gid;
99 time_t gid_ttl;
100 int is_user;
101 } sid2uid_gid_t;
102
103
104 typedef struct pid2sid_winname {
105 avl_node_t avl_link;
106 struct pid2sid_winname *flink;
107 struct pid2sid_winname *blink;
108 uid_t pid;
109 const char *sid_prefix;
110 idmap_rid_t rid;
111 time_t sid_ttl;
112 const char *winname;
113 const char *windomain;
114 time_t winname_ttl;
115 } pid2sid_winname_t;
116
117
118 typedef struct winname2uid_gid {
119 avl_node_t avl_link;
120 struct winname2uid_gid *flink;
121 struct winname2uid_gid *blink;
122 const char *winname;
123 const char *windomain;
124 uid_t uid;
125 time_t uid_ttl;
126 gid_t gid;
127 time_t gid_ttl;
128 } winname2uid_gid_t;
129
130
131 typedef struct sid2uid_gid_cache {
132 avl_tree_t tree;
133 pthread_mutex_t mutex;
134 sid2uid_gid_t head;
135 sid2uid_gid_t *prev;
136 time_t purge_time;
137 int uid_num;
138 int gid_num;
139 int pid_num;
140 } sid2uid_gid_cache_t;
141
142
143 typedef struct pid2sid_winname_cache {
144 avl_tree_t tree;
145 pthread_mutex_t mutex;
146 pid2sid_winname_t head;
147 pid2sid_winname_t *prev;
148 time_t purge_time;
149 int sid_num;
150 int winname_num;
151 } pid2sid_winname_cache_t;
152
153
154
155 typedef struct winname2uid_gid_cache {
156 avl_tree_t tree;
157 pthread_mutex_t mutex;
158 winname2uid_gid_t head;
159 winname2uid_gid_t *prev;
160 time_t purge_time;
161 int uid_num;
162 int gid_num;
163 } winname2uid_gid_cache_t;
164
165
166 typedef struct idmap_cache {
167 sid2uid_gid_cache_t sid2uid_gid;
168 pid2sid_winname_cache_t uid2sid_winname;
169 pid2sid_winname_cache_t gid2sid_winname;
170 winname2uid_gid_cache_t winname2uid_gid;
171 } idmap_cache_t;
172
173
174
175 typedef int (*avl_comp_fn)(const void*, const void*);
176
177 static void
178 idmap_purge_sid2uid_gid_cache(sid2uid_gid_cache_t *cache, size_t limit);
179
180 static void
181 idmap_purge_pid2sid_winname_cache(pid2sid_winname_cache_t *cache, size_t limit);
182
183 static void
184 idmap_purge_winname2uid_gid_cache(winname2uid_gid_cache_t *avl, size_t limit);
185
186 /*
187 * Global structures
188 */
189
190 static idmap_cache_t idmap_cache;
191
192
193
194
195 static int
idmap_compare_sid(const sid2uid_gid_t * entry1,const sid2uid_gid_t * entry2)196 idmap_compare_sid(const sid2uid_gid_t *entry1, const sid2uid_gid_t *entry2)
197 {
198 int64_t comp = ((int64_t)entry2->rid) - ((int64_t)entry1->rid);
199
200 if (comp == 0)
201 comp = strcmp(entry2->sid_prefix, entry1->sid_prefix);
202
203 if (comp < 0)
204 comp = -1;
205 else if (comp > 0)
206 comp = 1;
207
208 return ((int)comp);
209 }
210
211
212 static int
idmap_compare_pid(const pid2sid_winname_t * entry1,const pid2sid_winname_t * entry2)213 idmap_compare_pid(const pid2sid_winname_t *entry1,
214 const pid2sid_winname_t *entry2)
215 {
216 if (entry2->pid > entry1->pid)
217 return (1);
218 if (entry2->pid < entry1->pid)
219 return (-1);
220 return (0);
221 }
222
223
224 static int
idmap_compare_winname(const winname2uid_gid_t * entry1,const winname2uid_gid_t * entry2)225 idmap_compare_winname(const winname2uid_gid_t *entry1,
226 const winname2uid_gid_t *entry2)
227 {
228 int comp;
229
230 comp = strcasecmp(entry2->winname, entry1->winname);
231 if (comp == 0) {
232 if (entry2->windomain == NULL && entry1->windomain == NULL)
233 return (0);
234 if (entry1->windomain == NULL)
235 return (1);
236 if (entry2->windomain == NULL)
237 return (-1);
238
239 comp = strcasecmp(entry2->windomain, entry1->windomain);
240 }
241
242 if (comp < 0)
243 comp = -1;
244 else if (comp > 0)
245 comp = 1;
246
247 return (comp);
248 }
249
250 /*
251 * Routine to update item
252 *
253 * Returns: 0 Success
254 * -1 Error
255 */
256 static int
update_str(const char ** item,const char * str)257 update_str(const char **item, const char *str)
258 {
259 char *tmp;
260
261 if (*item != NULL && str != NULL) {
262 if (strcmp(*item, str) != 0) {
263 if ((tmp = strdup(str)) == NULL)
264 return (-1);
265 free((char *)*item);
266 *item = tmp;
267 }
268 } else if (str != NULL) {
269 /* *item is NULL */
270 if ((*item = strdup(str)) == NULL)
271 return (-1);
272 } else if (*item != NULL) {
273 /* str is NULL */
274 free((char *)*item);
275 *item = NULL;
276 }
277
278 return (0);
279 }
280
281 /*
282 * The Cache is initialized on loading libidmap.so
283 */
284 #pragma init(idmap_cache_create)
285
286 void
idmap_cache_create(void)287 idmap_cache_create(void)
288 {
289 avl_create(&idmap_cache.sid2uid_gid.tree,
290 (avl_comp_fn)idmap_compare_sid, sizeof (sid2uid_gid_t),
291 offsetof(sid2uid_gid_t, avl_link));
292 (void) pthread_mutex_init(&idmap_cache.sid2uid_gid.mutex, NULL);
293 idmap_cache.sid2uid_gid.head.flink = &idmap_cache.sid2uid_gid.head;
294 idmap_cache.sid2uid_gid.head.blink = &idmap_cache.sid2uid_gid.head;
295 idmap_cache.sid2uid_gid.prev = NULL;
296 idmap_cache.sid2uid_gid.purge_time = 0;
297 idmap_cache.sid2uid_gid.uid_num = 0;
298 idmap_cache.sid2uid_gid.gid_num = 0;
299 idmap_cache.sid2uid_gid.pid_num = 0;
300
301 avl_create(&idmap_cache.uid2sid_winname.tree,
302 (avl_comp_fn)idmap_compare_pid, sizeof (pid2sid_winname_t),
303 offsetof(pid2sid_winname_t, avl_link));
304 (void) pthread_mutex_init(&idmap_cache.uid2sid_winname.mutex, NULL);
305 idmap_cache.uid2sid_winname.head.flink =
306 &idmap_cache.uid2sid_winname.head;
307 idmap_cache.uid2sid_winname.head.blink =
308 &idmap_cache.uid2sid_winname.head;
309 idmap_cache.uid2sid_winname.prev = NULL;
310 idmap_cache.uid2sid_winname.purge_time = 0;
311 idmap_cache.uid2sid_winname.sid_num = 0;
312 idmap_cache.uid2sid_winname.winname_num = 0;
313
314 avl_create(&idmap_cache.gid2sid_winname.tree,
315 (avl_comp_fn)idmap_compare_pid, sizeof (pid2sid_winname_t),
316 offsetof(pid2sid_winname_t, avl_link));
317 (void) pthread_mutex_init(&idmap_cache.gid2sid_winname.mutex, NULL);
318 idmap_cache.gid2sid_winname.head.flink =
319 &idmap_cache.gid2sid_winname.head;
320 idmap_cache.gid2sid_winname.head.blink =
321 &idmap_cache.gid2sid_winname.head;
322 idmap_cache.gid2sid_winname.prev = NULL;
323 idmap_cache.gid2sid_winname.purge_time = 0;
324 idmap_cache.gid2sid_winname.sid_num = 0;
325 idmap_cache.gid2sid_winname.winname_num = 0;
326
327 avl_create(&idmap_cache.winname2uid_gid.tree,
328 (avl_comp_fn)idmap_compare_winname, sizeof (winname2uid_gid_t),
329 offsetof(winname2uid_gid_t, avl_link));
330 (void) pthread_mutex_init(&idmap_cache.winname2uid_gid.mutex, NULL);
331 idmap_cache.winname2uid_gid.head.flink =
332 &idmap_cache.winname2uid_gid.head;
333 idmap_cache.winname2uid_gid.head.blink =
334 &idmap_cache.winname2uid_gid.head;
335 idmap_cache.winname2uid_gid.prev = NULL;
336 idmap_cache.winname2uid_gid.purge_time = 0;
337 idmap_cache.winname2uid_gid.uid_num = 0;
338 idmap_cache.winname2uid_gid.gid_num = 0;
339 }
340
341
342 void
idmap_cache_purge(void)343 idmap_cache_purge(void)
344 {
345 sid2uid_gid_t *sid2uid_gid;
346 pid2sid_winname_t *uid2sid_winname;
347 pid2sid_winname_t *gid2sid_winname;
348 winname2uid_gid_t *winname2uid_gid;
349 void *cookie;
350
351 (void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
352 cookie = NULL;
353 while ((sid2uid_gid = avl_destroy_nodes(
354 &idmap_cache.sid2uid_gid.tree, &cookie)) != NULL) {
355 free((char *)sid2uid_gid->sid_prefix);
356 free(sid2uid_gid);
357 }
358 avl_destroy(&idmap_cache.sid2uid_gid.tree);
359 avl_create(&idmap_cache.sid2uid_gid.tree,
360 (avl_comp_fn)idmap_compare_sid, sizeof (sid2uid_gid_t),
361 offsetof(sid2uid_gid_t, avl_link));
362 idmap_cache.sid2uid_gid.head.flink = &idmap_cache.sid2uid_gid.head;
363 idmap_cache.sid2uid_gid.head.blink = &idmap_cache.sid2uid_gid.head;
364 idmap_cache.sid2uid_gid.prev = NULL;
365 idmap_cache.sid2uid_gid.purge_time = 0;
366 idmap_cache.sid2uid_gid.uid_num = 0;
367 idmap_cache.sid2uid_gid.gid_num = 0;
368 idmap_cache.sid2uid_gid.pid_num = 0;
369 (void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
370
371
372 (void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
373 cookie = NULL;
374 while ((uid2sid_winname = avl_destroy_nodes(
375 &idmap_cache.uid2sid_winname.tree, &cookie)) != NULL) {
376 free((char *)uid2sid_winname->sid_prefix);
377 free((char *)uid2sid_winname->winname);
378 if (uid2sid_winname->windomain != NULL)
379 free((char *)uid2sid_winname->windomain);
380 free(uid2sid_winname);
381 }
382 avl_destroy(&idmap_cache.uid2sid_winname.tree);
383 avl_create(&idmap_cache.uid2sid_winname.tree,
384 (avl_comp_fn)idmap_compare_pid, sizeof (pid2sid_winname_t),
385 offsetof(pid2sid_winname_t, avl_link));
386 idmap_cache.uid2sid_winname.head.flink =
387 &idmap_cache.uid2sid_winname.head;
388 idmap_cache.uid2sid_winname.head.blink =
389 &idmap_cache.uid2sid_winname.head;
390 idmap_cache.uid2sid_winname.prev = NULL;
391 idmap_cache.uid2sid_winname.purge_time = 0;
392 idmap_cache.uid2sid_winname.sid_num = 0;
393 idmap_cache.uid2sid_winname.winname_num = 0;
394 (void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
395
396
397 (void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
398 cookie = NULL;
399 while ((gid2sid_winname = avl_destroy_nodes(
400 &idmap_cache.gid2sid_winname.tree, &cookie)) != NULL) {
401 free((char *)gid2sid_winname->sid_prefix);
402 free((char *)gid2sid_winname->winname);
403 if (gid2sid_winname->windomain != NULL)
404 free((char *)gid2sid_winname->windomain);
405 free(gid2sid_winname);
406 }
407 avl_destroy(&idmap_cache.gid2sid_winname.tree);
408 avl_create(&idmap_cache.gid2sid_winname.tree,
409 (avl_comp_fn)idmap_compare_pid, sizeof (pid2sid_winname_t),
410 offsetof(pid2sid_winname_t, avl_link));
411 idmap_cache.gid2sid_winname.head.flink =
412 &idmap_cache.gid2sid_winname.head;
413 idmap_cache.gid2sid_winname.head.blink =
414 &idmap_cache.gid2sid_winname.head;
415 idmap_cache.gid2sid_winname.prev = NULL;
416 idmap_cache.gid2sid_winname.purge_time = 0;
417 idmap_cache.gid2sid_winname.sid_num = 0;
418 idmap_cache.gid2sid_winname.winname_num = 0;
419 (void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
420
421 (void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
422 cookie = NULL;
423 while ((winname2uid_gid = avl_destroy_nodes(
424 &idmap_cache.winname2uid_gid.tree, &cookie)) != NULL) {
425 free((char *)winname2uid_gid->winname);
426 if (winname2uid_gid->windomain)
427 free((char *)winname2uid_gid->windomain);
428 free(winname2uid_gid);
429 }
430 avl_destroy(&idmap_cache.winname2uid_gid.tree);
431 avl_create(&idmap_cache.winname2uid_gid.tree,
432 (avl_comp_fn)idmap_compare_winname, sizeof (winname2uid_gid_t),
433 offsetof(winname2uid_gid_t, avl_link));
434 idmap_cache.winname2uid_gid.head.flink =
435 &idmap_cache.winname2uid_gid.head;
436 idmap_cache.winname2uid_gid.head.blink =
437 &idmap_cache.winname2uid_gid.head;
438 idmap_cache.winname2uid_gid.prev = NULL;
439 idmap_cache.winname2uid_gid.purge_time = 0;
440 idmap_cache.winname2uid_gid.uid_num = 0;
441 idmap_cache.winname2uid_gid.gid_num = 0;
442 (void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
443
444 }
445
446
447 void
idmap_cache_get_data(size_t * uidbysid,size_t * gidbysid,size_t * pidbysid,size_t * sidbyuid,size_t * sidbygid,size_t * winnamebyuid,size_t * winnamebygid,size_t * uidbywinname,size_t * gidbywinname)448 idmap_cache_get_data(size_t *uidbysid, size_t *gidbysid,
449 size_t *pidbysid, size_t *sidbyuid, size_t *sidbygid,
450 size_t *winnamebyuid, size_t *winnamebygid,
451 size_t *uidbywinname, size_t *gidbywinname)
452 {
453 (void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
454 *uidbysid = idmap_cache.sid2uid_gid.uid_num;
455 *gidbysid = idmap_cache.sid2uid_gid.gid_num;
456 *pidbysid = idmap_cache.sid2uid_gid.pid_num;
457 (void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
458
459 (void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
460 *sidbyuid = idmap_cache.uid2sid_winname.sid_num;
461 *winnamebyuid = idmap_cache.uid2sid_winname.winname_num;
462 (void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
463
464 (void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
465 *sidbygid = idmap_cache.gid2sid_winname.sid_num;
466 *winnamebygid = idmap_cache.gid2sid_winname.winname_num;
467 (void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
468
469 (void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
470 *uidbywinname = idmap_cache.winname2uid_gid.uid_num;
471 *gidbywinname = idmap_cache.winname2uid_gid.gid_num;
472 (void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
473 }
474
475
476 idmap_stat
idmap_cache_lookup_uidbysid(const char * sid_prefix,idmap_rid_t rid,uid_t * uid)477 idmap_cache_lookup_uidbysid(const char *sid_prefix,
478 idmap_rid_t rid, uid_t *uid)
479 {
480 sid2uid_gid_t entry;
481 sid2uid_gid_t *result;
482 avl_index_t where;
483 int status = IDMAP_ERR_NOMAPPING;
484 time_t now = time(NULL);
485
486 entry.sid_prefix = sid_prefix;
487 entry.rid = rid;
488
489 (void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
490
491 result = avl_find(&idmap_cache.sid2uid_gid.tree, &entry, &where);
492 if (result != NULL) {
493 list_move(&idmap_cache.sid2uid_gid.head, result);
494 if (result->uid != UNDEF_UID && result->uid_ttl > now) {
495 *uid = result->uid;
496 status = IDMAP_SUCCESS;
497 }
498 }
499
500 (void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
501
502 return (status);
503 }
504
505
506
507 idmap_stat
idmap_cache_lookup_gidbysid(const char * sid_prefix,idmap_rid_t rid,gid_t * gid)508 idmap_cache_lookup_gidbysid(const char *sid_prefix,
509 idmap_rid_t rid, gid_t *gid)
510 {
511 sid2uid_gid_t entry;
512 sid2uid_gid_t *result;
513 avl_index_t where;
514 int status = IDMAP_ERR_NOMAPPING;
515 time_t now = time(NULL);
516
517 entry.sid_prefix = sid_prefix;
518 entry.rid = rid;
519
520 (void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
521
522 result = avl_find(&idmap_cache.sid2uid_gid.tree, &entry, &where);
523 if (result != NULL) {
524 list_move(&idmap_cache.sid2uid_gid.head, result);
525 if (result->gid != UNDEF_GID && result->gid_ttl > now) {
526 *gid = result->gid;
527 status = IDMAP_SUCCESS;
528 }
529 }
530
531 (void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
532
533 return (status);
534 }
535
536
537
538
539 idmap_stat
idmap_cache_lookup_pidbysid(const char * sid_prefix,idmap_rid_t rid,uid_t * pid,int * is_user)540 idmap_cache_lookup_pidbysid(const char *sid_prefix,
541 idmap_rid_t rid, uid_t *pid, int *is_user)
542 {
543 sid2uid_gid_t entry;
544 sid2uid_gid_t *result;
545 avl_index_t where;
546 int status = IDMAP_ERR_NOMAPPING;
547 time_t now = time(NULL);
548
549 entry.sid_prefix = sid_prefix;
550 entry.rid = rid;
551
552 (void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
553
554 result = avl_find(&idmap_cache.sid2uid_gid.tree, &entry, &where);
555 if (result != NULL) {
556 list_move(&idmap_cache.sid2uid_gid.head, result);
557 if (result->is_user != UNDEF_ISUSER) {
558 *is_user = result->is_user;
559 if (result->is_user && result->uid_ttl > now) {
560 *pid = result->uid;
561 status = IDMAP_SUCCESS;
562 } else if (!result->is_user && result->gid_ttl > now) {
563 *pid = result->gid;
564 status = IDMAP_SUCCESS;
565 }
566 }
567 }
568
569 (void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
570
571 return (status);
572 }
573
574
575
576 idmap_stat
idmap_cache_lookup_sidbyuid(char ** sid_prefix,idmap_rid_t * rid,uid_t uid)577 idmap_cache_lookup_sidbyuid(char **sid_prefix,
578 idmap_rid_t *rid, uid_t uid)
579 {
580 pid2sid_winname_t entry;
581 pid2sid_winname_t *result;
582 avl_index_t where;
583 int status = IDMAP_ERR_NOMAPPING;
584 time_t now = time(NULL);
585
586 entry.pid = uid;
587
588 (void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
589
590 result = avl_find(&idmap_cache.uid2sid_winname.tree, &entry, &where);
591 if (result != NULL) {
592 list_move(&idmap_cache.uid2sid_winname.head, result);
593 if (result->sid_ttl > now) {
594 *rid = result->rid;
595 *sid_prefix = strdup(result->sid_prefix);
596 if (*sid_prefix != NULL)
597 status = IDMAP_SUCCESS;
598 else
599 status = IDMAP_ERR_MEMORY;
600 }
601 }
602
603 (void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
604
605 return (status);
606 }
607
608 idmap_stat
idmap_cache_lookup_sidbygid(char ** sid_prefix,idmap_rid_t * rid,gid_t gid)609 idmap_cache_lookup_sidbygid(char **sid_prefix,
610 idmap_rid_t *rid, gid_t gid)
611 {
612 pid2sid_winname_t entry;
613 pid2sid_winname_t *result;
614 avl_index_t where;
615 int status = IDMAP_ERR_NOMAPPING;
616 time_t now = time(NULL);
617
618 entry.pid = gid;
619
620 (void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
621
622 result = avl_find(&idmap_cache.gid2sid_winname.tree, &entry, &where);
623 if (result != NULL) {
624 list_move(&idmap_cache.gid2sid_winname.head, result);
625 if (result->sid_ttl > now) {
626 *rid = result->rid;
627 *sid_prefix = strdup(result->sid_prefix);
628 if (*sid_prefix != NULL)
629 status = IDMAP_SUCCESS;
630 else
631 status = IDMAP_ERR_MEMORY;
632 }
633 }
634
635 (void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
636
637 return (status);
638 }
639
640
641 idmap_stat
idmap_cache_lookup_winnamebyuid(char ** name,char ** domain,uid_t uid)642 idmap_cache_lookup_winnamebyuid(char **name, char **domain, uid_t uid)
643 {
644 pid2sid_winname_t entry;
645 pid2sid_winname_t *result;
646 avl_index_t where;
647 int status = IDMAP_ERR_NOMAPPING;
648 time_t now = time(NULL);
649
650 entry.pid = uid;
651
652 (void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
653
654 result = avl_find(&idmap_cache.uid2sid_winname.tree, &entry, &where);
655 if (result != NULL) {
656 list_move(&idmap_cache.uid2sid_winname.head, result);
657 if (result->winname_ttl > now) {
658 *name = strdup(result->winname);
659 if (*name != NULL) {
660 if (domain != NULL) {
661 if (result->windomain != NULL) {
662 *domain =
663 strdup(result->windomain);
664 if (*domain != NULL)
665 status = IDMAP_SUCCESS;
666 else
667 status =
668 IDMAP_ERR_MEMORY;
669 } else {
670 *domain = NULL;
671 status = IDMAP_SUCCESS;
672 }
673 } else
674 status = IDMAP_SUCCESS;
675 } else
676 status = IDMAP_ERR_MEMORY;
677 }
678 }
679
680 (void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
681
682 return (status);
683 }
684
685
686 idmap_stat
idmap_cache_lookup_winnamebygid(char ** name,char ** domain,gid_t gid)687 idmap_cache_lookup_winnamebygid(char **name, char **domain, gid_t gid)
688 {
689 pid2sid_winname_t entry;
690 pid2sid_winname_t *result;
691 avl_index_t where;
692 int status = IDMAP_ERR_NOMAPPING;
693 time_t now = time(NULL);
694
695 entry.pid = gid;
696
697 (void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
698
699 result = avl_find(&idmap_cache.gid2sid_winname.tree, &entry, &where);
700 if (result != NULL) {
701 list_move(&idmap_cache.gid2sid_winname.head, result);
702 if (result->winname_ttl > now) {
703 *name = strdup(result->winname);
704 if (*name != NULL) {
705 if (domain != NULL) {
706 if (result->windomain != NULL) {
707 *domain =
708 strdup(result->windomain);
709 if (*domain != NULL)
710 status = IDMAP_SUCCESS;
711 else
712 status =
713 IDMAP_ERR_MEMORY;
714 } else {
715 *domain = NULL;
716 status = IDMAP_SUCCESS;
717 }
718 } else
719 status = IDMAP_SUCCESS;
720 } else
721 status = IDMAP_ERR_MEMORY;
722 }
723 }
724
725 (void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
726
727 return (status);
728 }
729
730
731 idmap_stat
idmap_cache_lookup_uidbywinname(const char * name,const char * domain,uid_t * uid)732 idmap_cache_lookup_uidbywinname(const char *name, const char *domain,
733 uid_t *uid)
734 {
735 winname2uid_gid_t entry;
736 winname2uid_gid_t *result;
737 avl_index_t where;
738 int status = IDMAP_ERR_NOMAPPING;
739 time_t now = time(NULL);
740
741 entry.winname = name;
742 entry.windomain = domain;
743
744 (void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
745
746 result = avl_find(&idmap_cache.winname2uid_gid.tree, &entry, &where);
747 if (result != NULL) {
748 list_move(&idmap_cache.winname2uid_gid.head, result);
749 if (result->uid != UNDEF_UID && result->uid_ttl > now) {
750 *uid = result->uid;
751 status = IDMAP_SUCCESS;
752 }
753 }
754
755 (void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
756
757 return (status);
758 }
759
760
761 idmap_stat
idmap_cache_lookup_gidbywinname(const char * name,const char * domain,gid_t * gid)762 idmap_cache_lookup_gidbywinname(const char *name, const char *domain,
763 gid_t *gid)
764 {
765 winname2uid_gid_t entry;
766 winname2uid_gid_t *result;
767 avl_index_t where;
768 int status = IDMAP_ERR_NOMAPPING;
769 time_t now = time(NULL);
770
771 entry.winname = name;
772 entry.windomain = domain;
773
774 (void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
775
776 result = avl_find(&idmap_cache.winname2uid_gid.tree, &entry, &where);
777 if (result != NULL) {
778 list_move(&idmap_cache.winname2uid_gid.head, result);
779 if (result->gid != UNDEF_GID && result->gid_ttl > now) {
780 *gid = result->gid;
781 status = IDMAP_SUCCESS;
782 }
783 }
784
785 (void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
786
787 return (status);
788 }
789
790
791 void
idmap_cache_add_sid2uid(const char * sid_prefix,idmap_rid_t rid,uid_t uid,int direction)792 idmap_cache_add_sid2uid(const char *sid_prefix,
793 idmap_rid_t rid, uid_t uid, int direction)
794
795 {
796 avl_index_t where;
797 time_t ttl = CACHE_TTL + time(NULL);
798
799
800 if (direction == IDMAP_DIRECTION_BI ||
801 direction == IDMAP_DIRECTION_W2U) {
802 sid2uid_gid_t find;
803 sid2uid_gid_t *result;
804 sid2uid_gid_t *new;
805
806 find.sid_prefix = sid_prefix;
807 find.rid = rid;
808
809 (void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
810 result = avl_find(&idmap_cache.sid2uid_gid.tree, &find, &where);
811
812 if (result) {
813 if (result->uid_ttl == 0)
814 idmap_cache.sid2uid_gid.uid_num++;
815 result->uid = uid;
816 result->uid_ttl = ttl;
817 } else {
818 new = malloc(sizeof (sid2uid_gid_t));
819 if (new == NULL)
820 goto exit_sid2uid_gid;
821 new->sid_prefix = strdup(sid_prefix);
822 if (new->sid_prefix == NULL) {
823 free(new);
824 goto exit_sid2uid_gid;
825 }
826 new->rid = rid;
827 new->uid = uid;
828 new->uid_ttl = ttl;
829 new->gid = UNDEF_GID;
830 new->gid_ttl = 0;
831 new->is_user = UNDEF_ISUSER; /* Unknown */
832 idmap_cache.sid2uid_gid.uid_num++;
833
834 list_insert(&idmap_cache.sid2uid_gid.head, new);
835 avl_insert(&idmap_cache.sid2uid_gid.tree, new, where);
836 }
837 if ((avl_numnodes(&idmap_cache.sid2uid_gid.tree) >
838 CACHE_UID_GID_TRIGGER_SIZE) &&
839 (idmap_cache.sid2uid_gid.purge_time + CACHE_PURGE_INTERVAL <
840 time(NULL)))
841 idmap_purge_sid2uid_gid_cache(&idmap_cache.sid2uid_gid,
842 CACHE_UID_GID_TRIGGER_SIZE);
843
844 exit_sid2uid_gid:
845 (void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
846 }
847
848 if (direction == IDMAP_DIRECTION_BI ||
849 direction == IDMAP_DIRECTION_U2W) {
850 pid2sid_winname_t find;
851 pid2sid_winname_t *result;
852 pid2sid_winname_t *new;
853
854 find.pid = uid;
855
856 (void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
857 result = avl_find(&idmap_cache.uid2sid_winname.tree, &find,
858 &where);
859
860 if (result) {
861 if (update_str(&result->sid_prefix, sid_prefix) != 0)
862 goto exit_pid2sid_winname;
863 if (result->sid_ttl == 0)
864 idmap_cache.uid2sid_winname.sid_num++;
865 result->rid = rid;
866 result->sid_ttl = ttl;
867 } else {
868 new = malloc(sizeof (pid2sid_winname_t));
869 if (new == NULL)
870 goto exit_pid2sid_winname;
871 new->pid = uid;
872 new->sid_prefix = strdup(sid_prefix);
873 if (new->sid_prefix == NULL) {
874 free(new);
875 goto exit_pid2sid_winname;
876 }
877 new->rid = rid;
878 new->sid_ttl = ttl;
879 new->winname = NULL;
880 new->windomain = NULL;
881 new->winname_ttl = 0;
882 idmap_cache.uid2sid_winname.sid_num ++;
883
884 list_insert(&idmap_cache.uid2sid_winname.head, new);
885 avl_insert(&idmap_cache.uid2sid_winname.tree, new,
886 where);
887 }
888 if ((avl_numnodes(&idmap_cache.uid2sid_winname.tree) >
889 CACHE_UID_TRIGGER_SIZE) &&
890 (idmap_cache.uid2sid_winname.purge_time +
891 CACHE_PURGE_INTERVAL < time(NULL)))
892 idmap_purge_pid2sid_winname_cache(
893 &idmap_cache.uid2sid_winname,
894 CACHE_UID_TRIGGER_SIZE);
895
896
897 exit_pid2sid_winname:
898 (void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
899 }
900 }
901
902
903
904 void
idmap_cache_add_sid2gid(const char * sid_prefix,idmap_rid_t rid,gid_t gid,int direction)905 idmap_cache_add_sid2gid(const char *sid_prefix,
906 idmap_rid_t rid, gid_t gid, int direction)
907 {
908 avl_index_t where;
909 time_t ttl = CACHE_TTL + time(NULL);
910
911
912 if (direction == IDMAP_DIRECTION_BI ||
913 direction == IDMAP_DIRECTION_W2U) {
914 sid2uid_gid_t find;
915 sid2uid_gid_t *result;
916 sid2uid_gid_t *new;
917
918 find.sid_prefix = sid_prefix;
919 find.rid = rid;
920
921 (void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
922 result = avl_find(&idmap_cache.sid2uid_gid.tree, &find, &where);
923
924 if (result) {
925 if (result->gid_ttl == 0)
926 idmap_cache.sid2uid_gid.gid_num++;
927 result->gid = gid;
928 result->gid_ttl = ttl;
929 } else {
930 new = malloc(sizeof (sid2uid_gid_t));
931 if (new == NULL)
932 goto exit_sid2uid_gid;
933 new->sid_prefix = strdup(sid_prefix);
934 if (new->sid_prefix == NULL) {
935 free(new);
936 goto exit_sid2uid_gid;
937 }
938 new->rid = rid;
939 new->uid = UNDEF_UID;
940 new->uid_ttl = 0;
941 new->gid = gid;
942 new->gid_ttl = ttl;
943 new->is_user = UNDEF_ISUSER; /* Unknown */
944 idmap_cache.sid2uid_gid.gid_num++;
945
946 list_insert(&idmap_cache.sid2uid_gid.head, new);
947 avl_insert(&idmap_cache.sid2uid_gid.tree, new, where);
948 }
949 if ((avl_numnodes(&idmap_cache.sid2uid_gid.tree) >
950 CACHE_UID_GID_TRIGGER_SIZE) &&
951 (idmap_cache.sid2uid_gid.purge_time + CACHE_PURGE_INTERVAL <
952 time(NULL)))
953 idmap_purge_sid2uid_gid_cache(&idmap_cache.sid2uid_gid,
954 CACHE_UID_GID_TRIGGER_SIZE);
955
956 exit_sid2uid_gid:
957 (void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
958 }
959
960 if (direction == IDMAP_DIRECTION_BI ||
961 direction == IDMAP_DIRECTION_U2W) {
962 pid2sid_winname_t find;
963 pid2sid_winname_t *result;
964 pid2sid_winname_t *new;
965
966 find.pid = gid;
967
968 (void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
969 result = avl_find(&idmap_cache.gid2sid_winname.tree, &find,
970 &where);
971
972 if (result) {
973 if (update_str(&result->sid_prefix, sid_prefix) != 0)
974 goto exit_gid2sid_winname;
975 if (result->sid_ttl == 0)
976 idmap_cache.gid2sid_winname.sid_num++;
977 result->rid = rid;
978 result->sid_ttl = ttl;
979 } else {
980 new = malloc(sizeof (pid2sid_winname_t));
981 if (new == NULL)
982 goto exit_gid2sid_winname;
983 new->sid_prefix = strdup(sid_prefix);
984 if (new->sid_prefix == NULL) {
985 free(new);
986 goto exit_gid2sid_winname;
987 }
988 new->rid = rid;
989 new->pid = gid;
990 new->sid_ttl = ttl;
991 new->winname = NULL;
992 new->windomain = NULL;
993 new->winname_ttl = 0;
994 idmap_cache.gid2sid_winname.sid_num++;
995
996 list_insert(&idmap_cache.gid2sid_winname.head, new);
997 avl_insert(&idmap_cache.gid2sid_winname.tree, new,
998 where);
999 }
1000 if ((avl_numnodes(&idmap_cache.gid2sid_winname.tree) >
1001 CACHE_GID_TRIGGER_SIZE) &&
1002 (idmap_cache.gid2sid_winname.purge_time +
1003 CACHE_PURGE_INTERVAL < time(NULL)))
1004 idmap_purge_pid2sid_winname_cache(
1005 &idmap_cache.gid2sid_winname,
1006 CACHE_GID_TRIGGER_SIZE);
1007
1008 exit_gid2sid_winname:
1009 (void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
1010 }
1011 }
1012
1013
1014 void
idmap_cache_add_sid2pid(const char * sid_prefix,idmap_rid_t rid,uid_t pid,int is_user,int direction)1015 idmap_cache_add_sid2pid(const char *sid_prefix,
1016 idmap_rid_t rid, uid_t pid, int is_user, int direction)
1017 {
1018 avl_index_t where;
1019 time_t ttl = CACHE_TTL + time(NULL);
1020
1021
1022 if (direction == IDMAP_DIRECTION_BI ||
1023 direction == IDMAP_DIRECTION_W2U) {
1024 sid2uid_gid_t find;
1025 sid2uid_gid_t *result;
1026 sid2uid_gid_t *new;
1027
1028 find.sid_prefix = sid_prefix;
1029 find.rid = rid;
1030
1031 (void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
1032 result = avl_find(&idmap_cache.sid2uid_gid.tree, &find, &where);
1033
1034 if (result) {
1035 if (result->is_user == UNDEF_ISUSER)
1036 idmap_cache.sid2uid_gid.pid_num++;
1037 result->is_user = is_user;
1038 if (is_user) {
1039 if (result->uid_ttl == 0)
1040 idmap_cache.sid2uid_gid.uid_num++;
1041 result->uid = pid;
1042 result->uid_ttl = ttl;
1043 } else {
1044 if (result->gid_ttl == 0)
1045 idmap_cache.sid2uid_gid.gid_num++;
1046 result->gid = pid;
1047 result->gid_ttl = ttl;
1048 }
1049 } else {
1050 new = malloc(sizeof (sid2uid_gid_t));
1051 if (new == NULL)
1052 goto exit_sid2uid_gid;
1053 new->sid_prefix = strdup(sid_prefix);
1054 if (new->sid_prefix == NULL) {
1055 free(new);
1056 goto exit_sid2uid_gid;
1057 }
1058 new->rid = rid;
1059 new->is_user = is_user;
1060 if (is_user) {
1061 new->uid = pid;
1062 new->uid_ttl = ttl;
1063 new->gid = UNDEF_GID;
1064 new->gid_ttl = 0;
1065 idmap_cache.sid2uid_gid.uid_num++;
1066 } else {
1067 new->uid = UNDEF_UID;
1068 new->uid_ttl = 0;
1069 new->gid = pid;
1070 new->gid_ttl = ttl;
1071 idmap_cache.sid2uid_gid.gid_num++;
1072 }
1073 idmap_cache.sid2uid_gid.pid_num++;
1074
1075 list_insert(&idmap_cache.sid2uid_gid.head, new);
1076 avl_insert(&idmap_cache.sid2uid_gid.tree, new, where);
1077 }
1078 if ((avl_numnodes(&idmap_cache.sid2uid_gid.tree) >
1079 CACHE_UID_GID_TRIGGER_SIZE) &&
1080 (idmap_cache.sid2uid_gid.purge_time + CACHE_PURGE_INTERVAL <
1081 time(NULL)))
1082 idmap_purge_sid2uid_gid_cache(&idmap_cache.sid2uid_gid,
1083 CACHE_UID_GID_TRIGGER_SIZE);
1084
1085 exit_sid2uid_gid:
1086 (void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
1087 }
1088
1089 if (direction == IDMAP_DIRECTION_BI ||
1090 direction == IDMAP_DIRECTION_U2W) {
1091 pid2sid_winname_t find;
1092 pid2sid_winname_t *result;
1093 pid2sid_winname_t *new;
1094
1095 find.pid = pid;
1096 if (is_user) {
1097 (void) pthread_mutex_lock(
1098 &idmap_cache.uid2sid_winname.mutex);
1099 result = avl_find(&idmap_cache.uid2sid_winname.tree,
1100 &find, &where);
1101
1102 if (result) {
1103 if (update_str(&result->sid_prefix, sid_prefix)
1104 != 0)
1105 goto exit_uid2sid_winname;
1106 if (result->sid_ttl == 0)
1107 idmap_cache.uid2sid_winname.sid_num++;
1108 result->rid = rid;
1109 result->sid_ttl = ttl;
1110 } else {
1111 new = malloc(sizeof (pid2sid_winname_t));
1112 if (new == NULL)
1113 goto exit_uid2sid_winname;
1114 new->sid_prefix = strdup(sid_prefix);
1115 if (new->sid_prefix == NULL) {
1116 free(new);
1117 goto exit_uid2sid_winname;
1118 }
1119 new->rid = rid;
1120 new->pid = pid;
1121 new->sid_ttl = ttl;
1122 new->winname = NULL;
1123 new->windomain = NULL;
1124 idmap_cache.uid2sid_winname.sid_num++;
1125
1126 list_insert(&idmap_cache.uid2sid_winname.head,
1127 new);
1128 avl_insert(&idmap_cache.uid2sid_winname.tree,
1129 new, where);
1130 }
1131 if ((avl_numnodes(&idmap_cache.uid2sid_winname.tree) >
1132 CACHE_UID_TRIGGER_SIZE) &&
1133 (idmap_cache.uid2sid_winname.purge_time +
1134 CACHE_PURGE_INTERVAL < time(NULL)))
1135 idmap_purge_pid2sid_winname_cache(
1136 &idmap_cache.uid2sid_winname,
1137 CACHE_UID_TRIGGER_SIZE);
1138
1139 exit_uid2sid_winname:
1140 (void) pthread_mutex_unlock(
1141 &idmap_cache.uid2sid_winname.mutex);
1142 } else {
1143 (void) pthread_mutex_lock(
1144 &idmap_cache.gid2sid_winname.mutex);
1145 result = avl_find(&idmap_cache.gid2sid_winname.tree,
1146 &find, &where);
1147
1148 if (result) {
1149 if (update_str(&result->sid_prefix, sid_prefix)
1150 != 0)
1151 goto exit_gid2sid_winname;
1152 if (result->sid_ttl == 0)
1153 idmap_cache.gid2sid_winname.sid_num++;
1154 result->rid = rid;
1155 result->sid_ttl = ttl;
1156 } else {
1157 new = malloc(sizeof (pid2sid_winname_t));
1158 if (new == NULL)
1159 goto exit_gid2sid_winname;
1160 new->sid_prefix = strdup(sid_prefix);
1161 if (new->sid_prefix == NULL) {
1162 free(new);
1163 goto exit_gid2sid_winname;
1164 }
1165 new->rid = rid;
1166 new->pid = pid;
1167 new->sid_ttl = ttl;
1168 new->winname = NULL;
1169 new->windomain = NULL;
1170 idmap_cache.gid2sid_winname.sid_num++;
1171
1172 list_insert(&idmap_cache.gid2sid_winname.head,
1173 new);
1174 avl_insert(&idmap_cache.gid2sid_winname.tree,
1175 new, where);
1176 }
1177 if ((avl_numnodes(&idmap_cache.gid2sid_winname.tree) >
1178 CACHE_GID_TRIGGER_SIZE) &&
1179 (idmap_cache.gid2sid_winname.purge_time +
1180 CACHE_PURGE_INTERVAL < time(NULL)))
1181 idmap_purge_pid2sid_winname_cache(
1182 &idmap_cache.gid2sid_winname,
1183 CACHE_GID_TRIGGER_SIZE);
1184 exit_gid2sid_winname:
1185 (void) pthread_mutex_unlock(
1186 &idmap_cache.gid2sid_winname.mutex);
1187 }
1188 }
1189 }
1190
1191
1192
1193 void
idmap_cache_add_winname2uid(const char * name,const char * domain,uid_t uid,int direction)1194 idmap_cache_add_winname2uid(const char *name, const char *domain, uid_t uid,
1195 int direction)
1196 {
1197 avl_index_t where;
1198 time_t ttl = CACHE_TTL + time(NULL);
1199
1200
1201 if (direction == IDMAP_DIRECTION_BI ||
1202 direction == IDMAP_DIRECTION_W2U) {
1203 winname2uid_gid_t find;
1204 winname2uid_gid_t *result;
1205 winname2uid_gid_t *new;
1206
1207 find.winname = name;
1208 find.windomain = domain;
1209
1210 (void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
1211 result = avl_find(&idmap_cache.winname2uid_gid.tree, &find,
1212 &where);
1213
1214 if (result) {
1215 if (result->uid_ttl == 0)
1216 idmap_cache.winname2uid_gid.uid_num++;
1217 result->uid = uid;
1218 result->uid_ttl = ttl;
1219 } else {
1220 new = malloc(sizeof (winname2uid_gid_t));
1221 if (new == NULL)
1222 goto exit_winname2uid_gid;
1223 new->winname = strdup(name);
1224 if (new->winname == NULL) {
1225 free(new);
1226 goto exit_winname2uid_gid;
1227 }
1228 if (domain != NULL) {
1229 new->windomain = strdup(domain);
1230 if (new->winname == NULL) {
1231 free((char *)new->winname);
1232 free(new);
1233 goto exit_winname2uid_gid;
1234 }
1235 } else
1236 new->windomain = NULL;
1237 new->uid = uid;
1238 new->uid_ttl = ttl;
1239 new->gid = UNDEF_GID;
1240 new->gid_ttl = 0;
1241 idmap_cache.winname2uid_gid.uid_num++;
1242
1243 list_insert(&idmap_cache.winname2uid_gid.head, new);
1244 avl_insert(&idmap_cache.winname2uid_gid.tree, new,
1245 where);
1246 }
1247 if ((avl_numnodes(&idmap_cache.winname2uid_gid.tree) >
1248 CACHE_UID_GID_TRIGGER_SIZE) &&
1249 (idmap_cache.winname2uid_gid.purge_time +
1250 CACHE_PURGE_INTERVAL < time(NULL)))
1251 idmap_purge_winname2uid_gid_cache(
1252 &idmap_cache.winname2uid_gid,
1253 CACHE_UID_GID_TRIGGER_SIZE);
1254 exit_winname2uid_gid:
1255 (void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
1256 }
1257
1258 if (direction == IDMAP_DIRECTION_BI ||
1259 direction == IDMAP_DIRECTION_U2W) {
1260 pid2sid_winname_t find;
1261 pid2sid_winname_t *result;
1262 pid2sid_winname_t *new;
1263
1264 find.pid = uid;
1265
1266 (void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
1267 result = avl_find(&idmap_cache.uid2sid_winname.tree, &find,
1268 &where);
1269
1270 if (result) {
1271 if (update_str(&result->winname, name) != 0)
1272 goto exit_uid2sid_winname;
1273 if (update_str(&result->windomain, domain) != 0)
1274 goto exit_uid2sid_winname;
1275 if (result->winname_ttl == 0)
1276 idmap_cache.uid2sid_winname.winname_num++;
1277 result->winname_ttl = ttl;
1278 } else {
1279 new = malloc(sizeof (pid2sid_winname_t));
1280 if (new == NULL)
1281 goto exit_uid2sid_winname;
1282 new->pid = uid;
1283 new->winname = strdup(name);
1284 if (new->winname == NULL) {
1285 free(new);
1286 goto exit_uid2sid_winname;
1287 }
1288 if (domain != NULL) {
1289 new->windomain = strdup(domain);
1290 if (new->windomain == NULL) {
1291 free((char *)new->winname);
1292 free(new);
1293 goto exit_uid2sid_winname;
1294 }
1295 } else
1296 new->windomain = NULL;
1297 new->winname_ttl = ttl;
1298 new->sid_prefix = NULL;
1299 new->rid = 0;
1300 new->sid_ttl = 0;
1301 idmap_cache.uid2sid_winname.winname_num ++;
1302
1303 list_insert(&idmap_cache.uid2sid_winname.head, new);
1304 avl_insert(&idmap_cache.uid2sid_winname.tree, new,
1305 where);
1306 }
1307 if ((avl_numnodes(&idmap_cache.uid2sid_winname.tree) >
1308 CACHE_UID_TRIGGER_SIZE) &&
1309 (idmap_cache.uid2sid_winname.purge_time +
1310 CACHE_PURGE_INTERVAL < time(NULL)))
1311 idmap_purge_pid2sid_winname_cache(
1312 &idmap_cache.uid2sid_winname,
1313 CACHE_UID_TRIGGER_SIZE);
1314 exit_uid2sid_winname:
1315 (void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
1316 }
1317 }
1318
1319
1320
1321
1322
1323 void
idmap_cache_add_winname2gid(const char * name,const char * domain,gid_t gid,int direction)1324 idmap_cache_add_winname2gid(const char *name, const char *domain, gid_t gid,
1325 int direction)
1326 {
1327 avl_index_t where;
1328 time_t ttl = CACHE_TTL + time(NULL);
1329
1330
1331 if (direction == IDMAP_DIRECTION_BI ||
1332 direction == IDMAP_DIRECTION_W2U) {
1333 winname2uid_gid_t find;
1334 winname2uid_gid_t *result;
1335 winname2uid_gid_t *new;
1336
1337 find.winname = name;
1338 find.windomain = domain;
1339
1340 (void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
1341 result = avl_find(&idmap_cache.winname2uid_gid.tree, &find,
1342 &where);
1343
1344 if (result) {
1345 if (result->uid_ttl == 0)
1346 idmap_cache.winname2uid_gid.gid_num++;
1347 result->gid = gid;
1348 result->gid_ttl = ttl;
1349 } else {
1350 new = malloc(sizeof (winname2uid_gid_t));
1351 if (new == NULL)
1352 goto exit_winname2uid_gid;
1353 new->winname = strdup(name);
1354 if (new->winname == NULL) {
1355 free(new);
1356 goto exit_winname2uid_gid;
1357 }
1358 if (domain != NULL) {
1359 new->windomain = strdup(domain);
1360 if (new->windomain == NULL) {
1361 free((char *)new->winname);
1362 free(new);
1363 goto exit_winname2uid_gid;
1364 }
1365 }
1366 else
1367 new->windomain = NULL;
1368 new->uid = UNDEF_UID;
1369 new->uid_ttl = 0;
1370 new->gid = gid;
1371 new->gid_ttl = ttl;
1372 idmap_cache.winname2uid_gid.gid_num++;
1373
1374 list_insert(&idmap_cache.winname2uid_gid.head, new);
1375 avl_insert(&idmap_cache.winname2uid_gid.tree, new,
1376 where);
1377 }
1378 if ((avl_numnodes(&idmap_cache.winname2uid_gid.tree) >
1379 CACHE_UID_GID_TRIGGER_SIZE) &&
1380 (idmap_cache.winname2uid_gid.purge_time +
1381 CACHE_PURGE_INTERVAL < time(NULL)))
1382 idmap_purge_winname2uid_gid_cache(
1383 &idmap_cache.winname2uid_gid,
1384 CACHE_UID_GID_TRIGGER_SIZE);
1385 exit_winname2uid_gid:
1386 (void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
1387 }
1388
1389 if (direction == IDMAP_DIRECTION_BI ||
1390 direction == IDMAP_DIRECTION_U2W) {
1391 pid2sid_winname_t find;
1392 pid2sid_winname_t *result;
1393 pid2sid_winname_t *new;
1394
1395 find.pid = gid;
1396
1397 (void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
1398 result = avl_find(&idmap_cache.gid2sid_winname.tree, &find,
1399 &where);
1400
1401 if (result) {
1402 if (update_str(&result->winname, name) != 0)
1403 goto exit_gid2sid_winname;
1404 if (update_str(&result->windomain, domain) != 0)
1405 goto exit_gid2sid_winname;
1406 if (result->winname_ttl == 0)
1407 idmap_cache.gid2sid_winname.winname_num++;
1408 result->winname_ttl = ttl;
1409 } else {
1410 new = malloc(sizeof (pid2sid_winname_t));
1411 if (new == NULL)
1412 goto exit_gid2sid_winname;
1413 new->pid = gid;
1414 new->winname = strdup(name);
1415 if (new->winname == NULL) {
1416 free(new);
1417 goto exit_gid2sid_winname;
1418 }
1419 if (domain != NULL) {
1420 new->windomain = strdup(domain);
1421 if (new->windomain == NULL) {
1422 free((char *)new->winname);
1423 free(new);
1424 goto exit_gid2sid_winname;
1425 }
1426 }
1427 else
1428 new->windomain = NULL;
1429 new->winname_ttl = ttl;
1430 new->sid_prefix = NULL;
1431 new->rid = 0;
1432 new->sid_ttl = 0;
1433 idmap_cache.gid2sid_winname.winname_num ++;
1434
1435 list_insert(&idmap_cache.gid2sid_winname.head, new);
1436 avl_insert(&idmap_cache.gid2sid_winname.tree, new,
1437 where);
1438 }
1439 if ((avl_numnodes(&idmap_cache.gid2sid_winname.tree) >
1440 CACHE_UID_TRIGGER_SIZE) &&
1441 (idmap_cache.gid2sid_winname.purge_time +
1442 CACHE_PURGE_INTERVAL < time(NULL)))
1443 idmap_purge_pid2sid_winname_cache(
1444 &idmap_cache.gid2sid_winname,
1445 CACHE_UID_TRIGGER_SIZE);
1446 exit_gid2sid_winname:
1447 (void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
1448 }
1449 }
1450
1451
1452 static void
idmap_purge_sid2uid_gid_cache(sid2uid_gid_cache_t * cache,size_t limit)1453 idmap_purge_sid2uid_gid_cache(sid2uid_gid_cache_t *cache, size_t limit)
1454 {
1455 time_t now = time(NULL);
1456 sid2uid_gid_t *item;
1457
1458 while (avl_numnodes(&cache->tree) > limit) {
1459 /* Remove least recently used */
1460 item = cache->head.blink;
1461 list_remove(item);
1462 avl_remove(&cache->tree, item);
1463 if (item->uid_ttl != 0)
1464 cache->uid_num--;
1465 if (item->gid_ttl != 0)
1466 cache->gid_num--;
1467 if (item->is_user != UNDEF_ISUSER)
1468 cache->pid_num--;
1469
1470 if (item->sid_prefix)
1471 free((char *)item->sid_prefix);
1472 free(item);
1473 }
1474 cache->purge_time = now;
1475 }
1476
1477
1478 static void
idmap_purge_winname2uid_gid_cache(winname2uid_gid_cache_t * cache,size_t limit)1479 idmap_purge_winname2uid_gid_cache(winname2uid_gid_cache_t *cache, size_t limit)
1480 {
1481 time_t now = time(NULL);
1482 winname2uid_gid_t *item;
1483
1484 while (avl_numnodes(&cache->tree) > limit) {
1485 /* Remove least recently used */
1486 item = cache->head.blink;
1487 list_remove(item);
1488 avl_remove(&cache->tree, item);
1489 if (item->uid_ttl != 0)
1490 cache->uid_num--;
1491 if (item->gid_ttl != 0)
1492 cache->gid_num--;
1493
1494 if (item->winname)
1495 free((char *)item->winname);
1496 if (item->windomain)
1497 free((char *)item->windomain);
1498 free(item);
1499 }
1500 cache->purge_time = now;
1501 }
1502
1503
1504 static void
idmap_purge_pid2sid_winname_cache(pid2sid_winname_cache_t * cache,size_t limit)1505 idmap_purge_pid2sid_winname_cache(pid2sid_winname_cache_t *cache, size_t limit)
1506 {
1507 time_t now = time(NULL);
1508 pid2sid_winname_t *item;
1509
1510 while (avl_numnodes(&cache->tree) > limit) {
1511 /* Remove least recently used */
1512 item = cache->head.blink;
1513 list_remove(item);
1514 avl_remove(&cache->tree, item);
1515 if (item->winname_ttl != 0)
1516 cache->winname_num--;
1517 if (item->sid_ttl != 0)
1518 cache->sid_num--;
1519
1520 if (item->winname)
1521 free((char *)item->winname);
1522 if (item->windomain)
1523 free((char *)item->windomain);
1524 if (item->sid_prefix)
1525 free((char *)item->sid_prefix);
1526 free(item);
1527 }
1528 cache->purge_time = now;
1529 }
1530