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