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