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 2008 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 "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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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