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 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 26 /* 27 * libidmap API 28 */ 29 30 #include <stdlib.h> 31 #include <sys/varargs.h> 32 #include <inttypes.h> 33 #include <errno.h> 34 #include <strings.h> 35 #include <ctype.h> 36 #include <sys/param.h> 37 #include <sys/types.h> 38 #include <sys/stat.h> 39 #include <dlfcn.h> 40 #include <libintl.h> 41 #include <syslog.h> 42 #include <assert.h> 43 #include "idmap_impl.h" 44 #include "idmap_cache.h" 45 46 static struct timeval TIMEOUT = { 25, 0 }; 47 48 static int idmap_stat2errno(idmap_stat); 49 static idmap_stat idmap_strdupnull(char **, const char *); 50 51 #define __ITER_CREATE(itera, argu, ityp)\ 52 itera = calloc(1, sizeof (*itera));\ 53 if (itera == NULL) {\ 54 errno = ENOMEM;\ 55 return (IDMAP_ERR_MEMORY);\ 56 }\ 57 argu = calloc(1, sizeof (*argu));\ 58 if (argu == NULL) {\ 59 free(itera);\ 60 errno = ENOMEM;\ 61 return (IDMAP_ERR_MEMORY);\ 62 }\ 63 itera->type = ityp;\ 64 itera->retcode = IDMAP_NEXT;\ 65 itera->limit = 1024;\ 66 itera->arg = argu; 67 68 69 #define __ITER_ERR_RETURN(itera, argu, xdr_argu, iretcod)\ 70 if (argu) {\ 71 xdr_free(xdr_argu, (caddr_t)argu);\ 72 free(argu);\ 73 }\ 74 if (itera)\ 75 free(itera);\ 76 return (iretcod); 77 78 79 #define __ITER_CHECK(itera, ityp)\ 80 if (itera == NULL) {\ 81 errno = EINVAL;\ 82 return (IDMAP_ERR_ARG);\ 83 }\ 84 if (itera->type != ityp) {\ 85 errno = EINVAL;\ 86 return (IDMAP_ERR_ARG);\ 87 } 88 89 /* 90 * Free memory allocated by libidmap API 91 * 92 * Input: 93 * ptr - memory to be freed 94 */ 95 void 96 idmap_free(void *ptr) 97 { 98 free(ptr); 99 } 100 101 102 static idmap_stat 103 idmap_get_prop(idmap_prop_type pr, idmap_prop_res *res) 104 { 105 idmap_stat retcode; 106 107 (void) memset(res, 0, sizeof (*res)); 108 109 retcode = _idmap_clnt_call(IDMAP_GET_PROP, 110 (xdrproc_t)xdr_idmap_prop_type, (caddr_t)&pr, 111 (xdrproc_t)xdr_idmap_prop_res, (caddr_t)res, TIMEOUT); 112 if (retcode != IDMAP_SUCCESS) 113 return (retcode); 114 115 return (res->retcode); /* This might not be IDMAP_SUCCESS! */ 116 } 117 118 119 idmap_stat 120 idmap_get_prop_ds(idmap_prop_type pr, idmap_ad_disc_ds_t *dc) 121 { 122 idmap_prop_res res; 123 idmap_stat rc = IDMAP_SUCCESS; 124 125 rc = idmap_get_prop(pr, &res); 126 if (rc < 0) 127 return (rc); 128 129 dc->port = res.value.idmap_prop_val_u.dsval.port; 130 (void) strlcpy(dc->host, res.value.idmap_prop_val_u.dsval.host, 131 AD_DISC_MAXHOSTNAME); 132 133 /* xdr doesn't guarantee 0-termination of char[]: */ 134 dc->host[AD_DISC_MAXHOSTNAME - 1] = '\0'; 135 136 return (rc); 137 } 138 139 140 /* 141 * Sometimes the property is not set. In that case, str is set to NULL but 142 * otherwise IDMAP_SUCCESS is returned. 143 */ 144 idmap_stat 145 idmap_get_prop_str(idmap_prop_type pr, char **str) 146 { 147 idmap_prop_res res; 148 idmap_stat rc = IDMAP_SUCCESS; 149 150 rc = idmap_get_prop(pr, &res); 151 if (rc < 0) 152 return (rc); 153 154 rc = idmap_strdupnull(str, res.value.idmap_prop_val_u.utf8val); 155 return (rc); 156 } 157 158 /* 159 * Create/Initialize handle for updates 160 * 161 * Output: 162 * udthandle - update handle 163 */ 164 idmap_stat 165 idmap_udt_create(idmap_udt_handle_t **udthandle) 166 { 167 idmap_udt_handle_t *tmp; 168 169 if (udthandle == NULL) { 170 errno = EINVAL; 171 return (IDMAP_ERR_ARG); 172 } 173 if ((tmp = calloc(1, sizeof (*tmp))) == NULL) { 174 errno = ENOMEM; 175 return (IDMAP_ERR_MEMORY); 176 } 177 178 *udthandle = tmp; 179 return (IDMAP_SUCCESS); 180 } 181 182 183 /* 184 * All the updates specified by the update handle are committed 185 * in a single transaction. i.e either all succeed or none. 186 * 187 * Input: 188 * udthandle - update handle with the update requests 189 * 190 * Return value: 191 * Status of the commit 192 */ 193 idmap_stat 194 idmap_udt_commit(idmap_udt_handle_t *udthandle) 195 { 196 idmap_update_res res; 197 idmap_stat retcode; 198 199 if (udthandle == NULL) { 200 errno = EINVAL; 201 return (IDMAP_ERR_ARG); 202 } 203 204 (void) memset(&res, 0, sizeof (res)); 205 206 retcode = _idmap_clnt_call(IDMAP_UPDATE, 207 (xdrproc_t)xdr_idmap_update_batch, (caddr_t)&udthandle->batch, 208 (xdrproc_t)xdr_idmap_update_res, (caddr_t)&res, 209 TIMEOUT); 210 if (retcode != IDMAP_SUCCESS) 211 goto out; 212 213 retcode = udthandle->commit_stat = res.retcode; 214 udthandle->error_index = res.error_index; 215 216 if (retcode != IDMAP_SUCCESS) { 217 218 if (udthandle->error_index < 0) 219 goto out; 220 221 retcode = idmap_namerule_cpy(&udthandle->error_rule, 222 &res.error_rule); 223 if (retcode != IDMAP_SUCCESS) { 224 udthandle->error_index = -2; 225 goto out; 226 } 227 228 retcode = idmap_namerule_cpy(&udthandle->conflict_rule, 229 &res.conflict_rule); 230 if (retcode != IDMAP_SUCCESS) { 231 udthandle->error_index = -2; 232 goto out; 233 } 234 } 235 236 retcode = res.retcode; 237 238 239 out: 240 /* reset handle so that it can be used again */ 241 if (retcode == IDMAP_SUCCESS) { 242 _IDMAP_RESET_UDT_HANDLE(udthandle); 243 } 244 245 (void) xdr_free(xdr_idmap_update_res, (caddr_t)&res); 246 errno = idmap_stat2errno(retcode); 247 return (retcode); 248 } 249 250 251 static void 252 idmap_namerule_parts_clear(char **windomain, char **winname, 253 char **unixname, boolean_t *is_user, boolean_t *is_wuser, 254 boolean_t *is_nt4, int *direction) 255 { 256 if (windomain) 257 *windomain = NULL; 258 if (winname) 259 *winname = NULL; 260 if (unixname) 261 *unixname = NULL; 262 263 if (is_nt4) 264 *is_nt4 = 0; 265 if (is_user) 266 *is_user = -1; 267 if (is_wuser) 268 *is_wuser = -1; 269 if (direction) 270 *direction = IDMAP_DIRECTION_UNDEF; 271 } 272 273 static idmap_stat 274 idmap_namerule2parts(idmap_namerule *rule, 275 char **windomain, char **winname, 276 char **unixname, boolean_t *is_user, boolean_t *is_wuser, 277 boolean_t *is_nt4, int *direction) 278 { 279 idmap_stat retcode; 280 281 if (EMPTY_STRING(rule->winname) && EMPTY_STRING(rule->unixname)) 282 return (IDMAP_ERR_NORESULT); 283 284 285 retcode = idmap_strdupnull(windomain, rule->windomain); 286 if (retcode != IDMAP_SUCCESS) 287 goto errout; 288 289 retcode = idmap_strdupnull(winname, rule->winname); 290 if (retcode != IDMAP_SUCCESS) 291 goto errout; 292 293 retcode = idmap_strdupnull(unixname, rule->unixname); 294 if (retcode != IDMAP_SUCCESS) 295 goto errout; 296 297 298 if (is_user) 299 *is_user = rule->is_user; 300 if (is_wuser) 301 *is_wuser = rule->is_wuser; 302 if (is_nt4) 303 *is_nt4 = rule->is_nt4; 304 if (direction) 305 *direction = rule->direction; 306 307 308 return (IDMAP_SUCCESS); 309 310 errout: 311 if (windomain && *windomain) 312 free(*windomain); 313 if (winname && *winname) 314 free(*winname); 315 if (unixname && *unixname) 316 free(*unixname); 317 318 idmap_namerule_parts_clear(windomain, winname, 319 unixname, is_user, is_wuser, is_nt4, direction); 320 321 return (retcode); 322 323 } 324 325 /* 326 * Retrieve the index of the failed batch element. error_index == -1 327 * indicates failure at the beginning, -2 at the end. 328 * 329 * If idmap_udt_commit didn't return error, the returned value is undefined. 330 * 331 * Return value: 332 * IDMAP_SUCCESS 333 */ 334 335 idmap_stat 336 idmap_udt_get_error_index(idmap_udt_handle_t *udthandle, 337 int64_t *error_index) 338 { 339 if (error_index) 340 *error_index = udthandle->error_index; 341 342 return (IDMAP_SUCCESS); 343 } 344 345 346 /* 347 * Retrieve the rule which caused the batch to fail. If 348 * idmap_udt_commit didn't return error or if error_index is < 0, the 349 * retrieved rule is undefined. 350 * 351 * Return value: 352 * IDMAP_ERR_NORESULT if there is no error rule. 353 * IDMAP_SUCCESS if the rule was obtained OK. 354 * other error code (IDMAP_ERR_NOMEMORY etc) 355 */ 356 357 idmap_stat 358 idmap_udt_get_error_rule(idmap_udt_handle_t *udthandle, 359 char **windomain, char **winname, 360 char **unixname, boolean_t *is_user, boolean_t *is_wuser, 361 boolean_t *is_nt4, int *direction) 362 { 363 idmap_namerule_parts_clear(windomain, winname, 364 unixname, is_user, is_wuser, is_nt4, direction); 365 366 if (udthandle->commit_stat == IDMAP_SUCCESS || 367 udthandle->error_index < 0) 368 return (IDMAP_ERR_NORESULT); 369 370 return (idmap_namerule2parts( 371 &udthandle->error_rule, 372 windomain, 373 winname, 374 unixname, 375 is_user, 376 is_wuser, 377 is_nt4, 378 direction)); 379 } 380 381 /* 382 * Retrieve the rule with which there was a conflict. TODO: retrieve 383 * the value. 384 * 385 * Return value: 386 * IDMAP_ERR_NORESULT if there is no error rule. 387 * IDMAP_SUCCESS if the rule was obtained OK. 388 * other error code (IDMAP_ERR_NOMEMORY etc) 389 */ 390 391 idmap_stat 392 idmap_udt_get_conflict_rule(idmap_udt_handle_t *udthandle, 393 char **windomain, char **winname, 394 char **unixname, boolean_t *is_user, boolean_t *is_wuser, 395 boolean_t *is_nt4, int *direction) 396 { 397 idmap_namerule_parts_clear(windomain, winname, 398 unixname, is_user, is_wuser, is_nt4, direction); 399 400 if (udthandle->commit_stat != IDMAP_ERR_W2U_NAMERULE_CONFLICT && 401 udthandle->commit_stat != IDMAP_ERR_U2W_NAMERULE_CONFLICT) { 402 return (IDMAP_ERR_NORESULT); 403 } 404 405 return (idmap_namerule2parts( 406 &udthandle->conflict_rule, 407 windomain, 408 winname, 409 unixname, 410 is_user, 411 is_wuser, 412 is_nt4, 413 direction)); 414 } 415 416 417 /* 418 * Destroy the update handle 419 */ 420 void 421 idmap_udt_destroy(idmap_udt_handle_t *udthandle) 422 { 423 if (udthandle == NULL) 424 return; 425 (void) xdr_free(xdr_idmap_update_batch, (caddr_t)&udthandle->batch); 426 (void) xdr_free(xdr_idmap_namerule, (caddr_t)&udthandle->error_rule); 427 (void) xdr_free(xdr_idmap_namerule, (caddr_t)&udthandle->conflict_rule); 428 free(udthandle); 429 } 430 431 432 idmap_stat 433 idmap_udt_add_namerule(idmap_udt_handle_t *udthandle, const char *windomain, 434 boolean_t is_user, boolean_t is_wuser, const char *winname, 435 const char *unixname, boolean_t is_nt4, int direction) 436 { 437 idmap_retcode retcode; 438 idmap_namerule *rule = NULL; 439 440 retcode = _udt_extend_batch(udthandle); 441 if (retcode != IDMAP_SUCCESS) 442 goto errout; 443 444 rule = &udthandle->batch. 445 idmap_update_batch_val[udthandle->next]. 446 idmap_update_op_u.rule; 447 rule->is_user = is_user; 448 rule->is_wuser = is_wuser; 449 rule->direction = direction; 450 rule->is_nt4 = is_nt4; 451 452 retcode = idmap_strdupnull(&rule->windomain, windomain); 453 if (retcode != IDMAP_SUCCESS) 454 goto errout; 455 456 retcode = idmap_strdupnull(&rule->winname, winname); 457 if (retcode != IDMAP_SUCCESS) 458 goto errout; 459 460 retcode = idmap_strdupnull(&rule->unixname, unixname); 461 if (retcode != IDMAP_SUCCESS) 462 goto errout; 463 464 udthandle->batch.idmap_update_batch_val[udthandle->next].opnum = 465 OP_ADD_NAMERULE; 466 udthandle->next++; 467 return (IDMAP_SUCCESS); 468 469 errout: 470 /* The batch should still be usable */ 471 if (rule) 472 (void) xdr_free(xdr_idmap_namerule, (caddr_t)rule); 473 errno = idmap_stat2errno(retcode); 474 return (retcode); 475 } 476 477 478 /* ARGSUSED */ 479 idmap_stat 480 idmap_udt_rm_namerule(idmap_udt_handle_t *udthandle, boolean_t is_user, 481 boolean_t is_wuser, const char *windomain, const char *winname, 482 const char *unixname, int direction) 483 { 484 idmap_retcode retcode; 485 idmap_namerule *rule = NULL; 486 487 retcode = _udt_extend_batch(udthandle); 488 if (retcode != IDMAP_SUCCESS) 489 goto errout; 490 491 rule = &udthandle->batch. 492 idmap_update_batch_val[udthandle->next]. 493 idmap_update_op_u.rule; 494 rule->is_user = is_user; 495 rule->is_wuser = is_wuser; 496 rule->direction = direction; 497 498 retcode = idmap_strdupnull(&rule->windomain, windomain); 499 if (retcode != IDMAP_SUCCESS) 500 goto errout; 501 502 retcode = idmap_strdupnull(&rule->winname, winname); 503 if (retcode != IDMAP_SUCCESS) 504 goto errout; 505 506 retcode = idmap_strdupnull(&rule->unixname, unixname); 507 if (retcode != IDMAP_SUCCESS) 508 goto errout; 509 510 udthandle->batch.idmap_update_batch_val[udthandle->next].opnum = 511 OP_RM_NAMERULE; 512 udthandle->next++; 513 return (IDMAP_SUCCESS); 514 515 errout: 516 if (rule) 517 (void) xdr_free(xdr_idmap_namerule, (caddr_t)rule); 518 errno = idmap_stat2errno(retcode); 519 return (retcode); 520 } 521 522 523 /* ARGSUSED */ 524 idmap_stat 525 idmap_udt_flush_namerules(idmap_udt_handle_t *udthandle) 526 { 527 idmap_retcode retcode; 528 529 retcode = _udt_extend_batch(udthandle); 530 if (retcode != IDMAP_SUCCESS) 531 goto errout; 532 533 udthandle->batch.idmap_update_batch_val[udthandle->next].opnum = 534 OP_FLUSH_NAMERULES; 535 udthandle->next++; 536 return (IDMAP_SUCCESS); 537 538 errout: 539 errno = idmap_stat2errno(retcode); 540 return (retcode); 541 } 542 543 544 /* 545 * Set the number of entries requested per batch by the iterator 546 * 547 * Input: 548 * iter - iterator 549 * limit - number of entries requested per batch 550 */ 551 idmap_stat 552 idmap_iter_set_limit(idmap_iter_t *iter, uint64_t limit) 553 { 554 if (iter == NULL) { 555 errno = EINVAL; 556 return (IDMAP_ERR_ARG); 557 } 558 iter->limit = limit; 559 return (IDMAP_SUCCESS); 560 } 561 562 563 /* 564 * Create iterator to get name-based mapping rules 565 * 566 * Input: 567 * windomain - Windows domain 568 * is_user - user or group rules 569 * winname - Windows user or group name 570 * unixname - Unix user or group name 571 * 572 * Output: 573 * iter - iterator 574 */ 575 idmap_stat 576 idmap_iter_namerules(const char *windomain, 577 boolean_t is_user, boolean_t is_wuser, const char *winname, 578 const char *unixname, idmap_iter_t **iter) 579 { 580 581 idmap_iter_t *tmpiter; 582 idmap_list_namerules_1_argument *arg = NULL; 583 idmap_namerule *rule; 584 idmap_retcode retcode; 585 586 __ITER_CREATE(tmpiter, arg, IDMAP_LIST_NAMERULES); 587 588 rule = &arg->rule; 589 rule->is_user = is_user; 590 rule->is_wuser = is_wuser; 591 rule->direction = IDMAP_DIRECTION_UNDEF; 592 593 retcode = idmap_strdupnull(&rule->windomain, windomain); 594 if (retcode != IDMAP_SUCCESS) 595 goto errout; 596 597 retcode = idmap_strdupnull(&rule->winname, winname); 598 if (retcode != IDMAP_SUCCESS) 599 goto errout; 600 601 retcode = idmap_strdupnull(&rule->unixname, unixname); 602 if (retcode != IDMAP_SUCCESS) 603 goto errout; 604 605 *iter = tmpiter; 606 return (IDMAP_SUCCESS); 607 608 errout: 609 __ITER_ERR_RETURN(tmpiter, arg, 610 xdr_idmap_list_namerules_1_argument, retcode); 611 } 612 613 614 /* 615 * Iterate through the name-based mapping rules 616 * 617 * Input: 618 * iter - iterator 619 * 620 * Output: 621 * windomain - Windows domain 622 * winname - Windows user or group name 623 * unixname - Unix user or group name 624 * is_nt4 - NT4 or AD 625 * direction - bi(0), win2unix(1), unix2win(2) 626 * 627 * Return value: 628 * 0 - done 629 * 1 - more results available 630 * < 0 - error 631 */ 632 idmap_stat 633 idmap_iter_next_namerule(idmap_iter_t *iter, char **windomain, 634 char **winname, char **unixname, boolean_t *is_user, 635 boolean_t *is_wuser, boolean_t *is_nt4, int *direction) 636 { 637 idmap_namerules_res *namerules; 638 idmap_list_namerules_1_argument *arg; 639 idmap_retcode retcode; 640 641 idmap_namerule_parts_clear(windomain, winname, 642 unixname, is_user, is_wuser, is_nt4, direction); 643 644 645 __ITER_CHECK(iter, IDMAP_LIST_NAMERULES); 646 647 namerules = (idmap_namerules_res *)iter->retlist; 648 if (iter->retcode == IDMAP_NEXT && (namerules == NULL || 649 iter->next >= namerules->rules.rules_len)) { 650 651 if ((arg = iter->arg) == NULL) { 652 errno = EINVAL; 653 return (IDMAP_ERR_ARG); 654 } 655 arg->limit = iter->limit; 656 657 retcode = _iter_get_next_list(IDMAP_LIST_NAMERULES, 658 iter, arg, 659 (uchar_t **)&namerules, sizeof (*namerules), 660 (xdrproc_t)xdr_idmap_list_namerules_1_argument, 661 (xdrproc_t)xdr_idmap_namerules_res); 662 if (retcode != IDMAP_SUCCESS) 663 return (retcode); 664 665 if (IDMAP_ERROR(namerules->retcode)) { 666 retcode = namerules->retcode; 667 xdr_free(xdr_idmap_namerules_res, (caddr_t)namerules); 668 free(namerules); 669 iter->retlist = NULL; 670 return (retcode); 671 } 672 iter->retcode = namerules->retcode; 673 arg->lastrowid = namerules->lastrowid; 674 } 675 676 if (namerules == NULL || namerules->rules.rules_len == 0) 677 return (IDMAP_SUCCESS); 678 679 if (iter->next >= namerules->rules.rules_len) { 680 return (IDMAP_ERR_ARG); 681 } 682 683 retcode = idmap_strdupnull(windomain, 684 namerules->rules.rules_val[iter->next].windomain); 685 if (retcode != IDMAP_SUCCESS) 686 goto errout; 687 688 retcode = idmap_strdupnull(winname, 689 namerules->rules.rules_val[iter->next].winname); 690 if (retcode != IDMAP_SUCCESS) 691 goto errout; 692 693 retcode = idmap_strdupnull(unixname, 694 namerules->rules.rules_val[iter->next].unixname); 695 if (retcode != IDMAP_SUCCESS) 696 goto errout; 697 698 if (is_nt4) 699 *is_nt4 = namerules->rules.rules_val[iter->next].is_nt4; 700 if (is_user) 701 *is_user = namerules->rules.rules_val[iter->next].is_user; 702 if (is_wuser) 703 *is_wuser = namerules->rules.rules_val[iter->next].is_wuser; 704 if (direction) 705 *direction = namerules->rules.rules_val[iter->next].direction; 706 iter->next++; 707 708 if (iter->next == namerules->rules.rules_len) 709 return (iter->retcode); 710 else 711 return (IDMAP_NEXT); 712 713 errout: 714 if (windomain && *windomain) 715 free(*windomain); 716 if (winname && *winname) 717 free(*winname); 718 if (unixname && *unixname) 719 free(*unixname); 720 return (retcode); 721 } 722 723 724 /* 725 * Create iterator to get SID to UID/GID mappings 726 * 727 * Output: 728 * iter - iterator 729 */ 730 idmap_stat 731 idmap_iter_mappings(idmap_iter_t **iter, int flag) 732 { 733 idmap_iter_t *tmpiter; 734 idmap_list_mappings_1_argument *arg = NULL; 735 736 __ITER_CREATE(tmpiter, arg, IDMAP_LIST_MAPPINGS); 737 738 arg->flag = flag; 739 *iter = tmpiter; 740 return (IDMAP_SUCCESS); 741 } 742 743 744 /* 745 * Iterate through the SID to UID/GID mappings 746 * 747 * Input: 748 * iter - iterator 749 * 750 * Output: 751 * sid - SID in canonical form 752 * pid - UID or GID 753 * 754 * Return value: 755 * 0 - done 756 * 1 - more results available 757 * < 0 - error 758 */ 759 idmap_stat 760 idmap_iter_next_mapping(idmap_iter_t *iter, char **sidprefix, 761 idmap_rid_t *rid, uid_t *pid, char **winname, 762 char **windomain, char **unixname, boolean_t *is_user, 763 boolean_t *is_wuser, int *direction, idmap_info *info) 764 { 765 idmap_mappings_res *mappings; 766 idmap_list_mappings_1_argument *arg; 767 idmap_retcode retcode; 768 char *str; 769 770 if (sidprefix) 771 *sidprefix = NULL; 772 if (rid) 773 *rid = UINT32_MAX; 774 if (winname) 775 *winname = NULL; 776 if (windomain) 777 *windomain = NULL; 778 if (unixname) 779 *unixname = NULL; 780 if (pid) 781 *pid = UINT32_MAX; 782 if (is_user) 783 *is_user = -1; 784 if (is_wuser) 785 *is_wuser = -1; 786 if (direction) 787 *direction = IDMAP_DIRECTION_UNDEF; 788 789 __ITER_CHECK(iter, IDMAP_LIST_MAPPINGS); 790 791 mappings = (idmap_mappings_res *)iter->retlist; 792 if (iter->retcode == IDMAP_NEXT && (mappings == NULL || 793 iter->next >= mappings->mappings.mappings_len)) { 794 795 if ((arg = iter->arg) == NULL) { 796 errno = EINVAL; 797 return (IDMAP_ERR_ARG); 798 } 799 arg->limit = iter->limit; 800 801 retcode = _iter_get_next_list(IDMAP_LIST_MAPPINGS, 802 iter, arg, 803 (uchar_t **)&mappings, sizeof (*mappings), 804 (xdrproc_t)xdr_idmap_list_mappings_1_argument, 805 (xdrproc_t)xdr_idmap_mappings_res); 806 if (retcode != IDMAP_SUCCESS) 807 return (retcode); 808 809 if (IDMAP_ERROR(mappings->retcode)) { 810 retcode = mappings->retcode; 811 xdr_free(xdr_idmap_mappings_res, (caddr_t)mappings); 812 free(mappings); 813 iter->retlist = NULL; 814 return (retcode); 815 } 816 iter->retcode = mappings->retcode; 817 arg->lastrowid = mappings->lastrowid; 818 } 819 820 if (mappings == NULL || mappings->mappings.mappings_len == 0) 821 return (IDMAP_SUCCESS); 822 823 if (iter->next >= mappings->mappings.mappings_len) { 824 return (IDMAP_ERR_ARG); 825 } 826 827 if (sidprefix) { 828 str = mappings->mappings.mappings_val[iter->next].id1. 829 idmap_id_u.sid.prefix; 830 if (str && *str != '\0') { 831 *sidprefix = strdup(str); 832 if (*sidprefix == NULL) { 833 retcode = IDMAP_ERR_MEMORY; 834 goto errout; 835 } 836 } 837 } 838 if (rid) 839 *rid = mappings->mappings.mappings_val[iter->next].id1. 840 idmap_id_u.sid.rid; 841 842 retcode = idmap_strdupnull(windomain, 843 mappings->mappings.mappings_val[iter->next].id1domain); 844 if (retcode != IDMAP_SUCCESS) 845 goto errout; 846 847 retcode = idmap_strdupnull(winname, 848 mappings->mappings.mappings_val[iter->next].id1name); 849 if (retcode != IDMAP_SUCCESS) 850 goto errout; 851 852 retcode = idmap_strdupnull(unixname, 853 mappings->mappings.mappings_val[iter->next].id2name); 854 if (retcode != IDMAP_SUCCESS) 855 goto errout; 856 857 858 if (pid) 859 *pid = mappings->mappings.mappings_val[iter->next].id2. 860 idmap_id_u.uid; 861 if (direction) 862 *direction = mappings->mappings.mappings_val[iter->next]. 863 direction; 864 if (is_user) 865 *is_user = (mappings->mappings.mappings_val[iter->next].id2 866 .idtype == IDMAP_UID)?1:0; 867 if (is_wuser) 868 *is_wuser = (mappings->mappings.mappings_val[iter->next].id1 869 .idtype == IDMAP_USID)?1:0; 870 871 if (info) { 872 idmap_info_mov(info, 873 &mappings->mappings.mappings_val[iter->next].info); 874 } 875 iter->next++; 876 877 if (iter->next == mappings->mappings.mappings_len) 878 return (iter->retcode); 879 else 880 return (IDMAP_NEXT); 881 882 errout: 883 if (sidprefix && *sidprefix) 884 free(*sidprefix); 885 if (winname && *winname) 886 free(*winname); 887 if (windomain && *windomain) 888 free(*windomain); 889 if (unixname && *unixname) 890 free(*unixname); 891 return (retcode); 892 } 893 894 895 /* 896 * Destroy the iterator 897 */ 898 void 899 idmap_iter_destroy(idmap_iter_t *iter) 900 { 901 xdrproc_t _xdr_argument, _xdr_result; 902 903 if (iter == NULL) 904 return; 905 906 switch (iter->type) { 907 case IDMAP_LIST_NAMERULES: 908 _xdr_argument = (xdrproc_t)xdr_idmap_list_namerules_1_argument; 909 _xdr_result = (xdrproc_t)xdr_idmap_namerules_res; 910 break; 911 case IDMAP_LIST_MAPPINGS: 912 _xdr_argument = (xdrproc_t)xdr_idmap_list_mappings_1_argument; 913 _xdr_result = (xdrproc_t)xdr_idmap_mappings_res; 914 break; 915 default: 916 free(iter); 917 return; 918 }; 919 920 if (iter->arg) { 921 xdr_free(_xdr_argument, (caddr_t)iter->arg); 922 free(iter->arg); 923 } 924 if (iter->retlist) { 925 xdr_free(_xdr_result, (caddr_t)iter->retlist); 926 free(iter->retlist); 927 } 928 free(iter); 929 } 930 931 932 /* 933 * Create handle to get SID to UID/GID mapping entries 934 * 935 * Input: 936 * gh - "get mapping" handle 937 */ 938 idmap_stat 939 idmap_get_create(idmap_get_handle_t **gh) 940 { 941 idmap_get_handle_t *tmp; 942 943 /* allocate the handle */ 944 if ((tmp = calloc(1, sizeof (*tmp))) == NULL) { 945 errno = ENOMEM; 946 return (IDMAP_ERR_MEMORY); 947 } 948 949 *gh = tmp; 950 return (IDMAP_SUCCESS); 951 } 952 953 954 /* 955 * Given SID, get UID 956 * 957 * Input: 958 * sidprefix - SID prefix 959 * rid - RID 960 * flag - flag 961 * 962 * Output: 963 * stat - status of the get request 964 * uid - POSIX UID if stat = 0 965 * 966 * Note: The output parameters will be set by idmap_get_mappings() 967 */ 968 idmap_stat 969 idmap_get_uidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid, 970 int flag, uid_t *uid, idmap_stat *stat) 971 { 972 return (idmap_getext_uidbysid(gh, sidprefix, rid, flag, uid, 973 NULL, stat)); 974 } 975 976 /* 977 * Given SID, get UID 978 * 979 * Input: 980 * sidprefix - SID prefix 981 * rid - RID 982 * flag - flag 983 * 984 * Output: 985 * stat - status of the get request 986 * uid - POSIX UID if stat = 0 987 * how - mapping type if stat = 0 988 * 989 * Note: The output parameters will be set by idmap_get_mappings() 990 */ 991 992 idmap_stat 993 idmap_getext_uidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid, 994 int flag, uid_t *uid, idmap_info *info, idmap_stat *stat) 995 { 996 idmap_retcode retcode; 997 idmap_mapping *mapping = NULL; 998 999 /* sanity checks */ 1000 if (gh == NULL) 1001 return (IDMAP_ERR_ARG); 1002 if (uid == NULL || sidprefix == NULL) 1003 return (IDMAP_ERR_ARG); 1004 1005 if ((flag & IDMAP_REQ_FLG_USE_CACHE) && 1006 !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) { 1007 retcode = idmap_cache_lookup_uidbysid(sidprefix, rid, uid); 1008 if (retcode == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) { 1009 *stat = retcode; 1010 return (retcode); 1011 } 1012 } 1013 1014 /* Extend the request array and the return list */ 1015 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS) 1016 goto errout; 1017 1018 /* Setup the request */ 1019 mapping = &gh->batch.idmap_mapping_batch_val[gh->next]; 1020 mapping->flag = flag; 1021 mapping->id1.idtype = IDMAP_SID; 1022 mapping->id1.idmap_id_u.sid.rid = rid; 1023 if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) { 1024 retcode = IDMAP_ERR_MEMORY; 1025 goto errout; 1026 } 1027 mapping->id2.idtype = IDMAP_UID; 1028 1029 /* Setup pointers for the result */ 1030 gh->retlist[gh->next].idtype = IDMAP_UID; 1031 gh->retlist[gh->next].uid = uid; 1032 gh->retlist[gh->next].stat = stat; 1033 gh->retlist[gh->next].info = info; 1034 gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE; 1035 1036 gh->next++; 1037 return (IDMAP_SUCCESS); 1038 1039 errout: 1040 /* Batch created so far should still be usable */ 1041 if (mapping) 1042 (void) memset(mapping, 0, sizeof (*mapping)); 1043 errno = idmap_stat2errno(retcode); 1044 return (retcode); 1045 } 1046 1047 1048 /* 1049 * Given SID, get GID 1050 * 1051 * Input: 1052 * sidprefix - SID prefix 1053 * rid - rid 1054 * flag - flag 1055 * 1056 * Output: 1057 * stat - status of the get request 1058 * gid - POSIX GID if stat = 0 1059 * 1060 * Note: The output parameters will be set by idmap_get_mappings() 1061 */ 1062 idmap_stat 1063 idmap_get_gidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid, 1064 int flag, gid_t *gid, idmap_stat *stat) 1065 { 1066 return (idmap_getext_gidbysid(gh, sidprefix, rid, flag, gid, 1067 NULL, stat)); 1068 } 1069 1070 1071 /* 1072 * Given SID, get GID 1073 * 1074 * Input: 1075 * sidprefix - SID prefix 1076 * rid - rid 1077 * flag - flag 1078 * 1079 * Output: 1080 * stat - status of the get request 1081 * gid - POSIX GID if stat = 0 1082 * how - mapping type if stat = 0 1083 * 1084 * Note: The output parameters will be set by idmap_get_mappings() 1085 */ 1086 idmap_stat 1087 idmap_getext_gidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid, 1088 int flag, gid_t *gid, idmap_info *info, idmap_stat *stat) 1089 { 1090 1091 idmap_retcode retcode; 1092 idmap_mapping *mapping = NULL; 1093 1094 /* sanity checks */ 1095 if (gh == NULL) 1096 return (IDMAP_ERR_ARG); 1097 if (gid == NULL || sidprefix == NULL) 1098 return (IDMAP_ERR_ARG); 1099 1100 if ((flag & IDMAP_REQ_FLG_USE_CACHE) && 1101 !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) { 1102 retcode = idmap_cache_lookup_gidbysid(sidprefix, rid, gid); 1103 if (retcode == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) { 1104 *stat = retcode; 1105 return (retcode); 1106 } 1107 } 1108 1109 /* Extend the request array and the return list */ 1110 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS) 1111 goto errout; 1112 1113 /* Setup the request */ 1114 mapping = &gh->batch.idmap_mapping_batch_val[gh->next]; 1115 mapping->flag = flag; 1116 mapping->id1.idtype = IDMAP_SID; 1117 mapping->id1.idmap_id_u.sid.rid = rid; 1118 if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) { 1119 retcode = IDMAP_ERR_MEMORY; 1120 goto errout; 1121 } 1122 mapping->id2.idtype = IDMAP_GID; 1123 1124 /* Setup pointers for the result */ 1125 gh->retlist[gh->next].idtype = IDMAP_GID; 1126 gh->retlist[gh->next].gid = gid; 1127 gh->retlist[gh->next].stat = stat; 1128 gh->retlist[gh->next].info = info; 1129 gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE; 1130 1131 gh->next++; 1132 return (IDMAP_SUCCESS); 1133 1134 errout: 1135 if (mapping) 1136 (void) memset(mapping, 0, sizeof (*mapping)); 1137 errno = idmap_stat2errno(retcode); 1138 return (retcode); 1139 } 1140 1141 1142 1143 /* 1144 * Given SID, get POSIX ID i.e. UID/GID 1145 * 1146 * Input: 1147 * sidprefix - SID prefix 1148 * rid - rid 1149 * flag - flag 1150 * 1151 * Output: 1152 * stat - status of the get request 1153 * is_user - user or group 1154 * pid - POSIX UID if stat = 0 and is_user = 1 1155 * POSIX GID if stat = 0 and is_user = 0 1156 * 1157 * Note: The output parameters will be set by idmap_get_mappings() 1158 */ 1159 idmap_stat 1160 idmap_get_pidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid, 1161 int flag, uid_t *pid, int *is_user, idmap_stat *stat) 1162 { 1163 return (idmap_getext_pidbysid(gh, sidprefix, rid, flag, pid, is_user, 1164 NULL, stat)); 1165 } 1166 1167 1168 1169 /* 1170 * Given SID, get POSIX ID i.e. UID/GID 1171 * 1172 * Input: 1173 * sidprefix - SID prefix 1174 * rid - rid 1175 * flag - flag 1176 * 1177 * Output: 1178 * stat - status of the get request 1179 * is_user - user or group 1180 * pid - POSIX UID if stat = 0 and is_user = 1 1181 * POSIX GID if stat = 0 and is_user = 0 1182 * how - mapping type if stat = 0 1183 * 1184 * Note: The output parameters will be set by idmap_get_mappings() 1185 */ 1186 idmap_stat 1187 idmap_getext_pidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid, 1188 int flag, uid_t *pid, int *is_user, idmap_info *info, idmap_stat *stat) 1189 { 1190 idmap_retcode retcode; 1191 idmap_mapping *mapping = NULL; 1192 1193 /* sanity checks */ 1194 if (gh == NULL) 1195 return (IDMAP_ERR_ARG); 1196 if (pid == NULL || sidprefix == NULL || is_user == NULL) 1197 return (IDMAP_ERR_ARG); 1198 1199 if ((flag & IDMAP_REQ_FLG_USE_CACHE) && 1200 !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) { 1201 retcode = idmap_cache_lookup_pidbysid(sidprefix, rid, pid, 1202 is_user); 1203 if (retcode == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) { 1204 *stat = retcode; 1205 return (retcode); 1206 } 1207 } 1208 1209 /* Extend the request array and the return list */ 1210 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS) 1211 goto errout; 1212 1213 /* Setup the request */ 1214 mapping = &gh->batch.idmap_mapping_batch_val[gh->next]; 1215 mapping->flag = flag; 1216 mapping->id1.idtype = IDMAP_SID; 1217 mapping->id1.idmap_id_u.sid.rid = rid; 1218 if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) { 1219 retcode = IDMAP_ERR_MEMORY; 1220 goto errout; 1221 } 1222 mapping->id2.idtype = IDMAP_POSIXID; 1223 1224 /* Setup pointers for the result */ 1225 gh->retlist[gh->next].idtype = IDMAP_POSIXID; 1226 gh->retlist[gh->next].uid = pid; 1227 gh->retlist[gh->next].gid = pid; 1228 gh->retlist[gh->next].is_user = is_user; 1229 gh->retlist[gh->next].stat = stat; 1230 gh->retlist[gh->next].info = info; 1231 gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE; 1232 1233 gh->next++; 1234 return (IDMAP_SUCCESS); 1235 1236 errout: 1237 if (mapping) 1238 (void) memset(mapping, 0, sizeof (*mapping)); 1239 errno = idmap_stat2errno(retcode); 1240 return (retcode); 1241 } 1242 1243 1244 /* 1245 * Given UID, get SID 1246 * 1247 * Input: 1248 * uid - POSIX UID 1249 * flag - flag 1250 * 1251 * Output: 1252 * stat - status of the get request 1253 * sid - SID prefix (if stat == 0) 1254 * rid - rid 1255 * 1256 * Note: The output parameters will be set by idmap_get_mappings() 1257 */ 1258 idmap_stat 1259 idmap_get_sidbyuid(idmap_get_handle_t *gh, uid_t uid, int flag, 1260 char **sidprefix, idmap_rid_t *rid, idmap_stat *stat) 1261 { 1262 return (idmap_getext_sidbyuid(gh, uid, flag, sidprefix, rid, 1263 NULL, stat)); 1264 } 1265 1266 1267 /* 1268 * Given UID, get SID 1269 * 1270 * Input: 1271 * uid - POSIX UID 1272 * flag - flag 1273 * 1274 * Output: 1275 * stat - status of the get request 1276 * sid - SID prefix (if stat == 0) 1277 * rid - rid 1278 * how - mapping type if stat = 0 1279 * 1280 * Note: The output parameters will be set by idmap_get_mappings() 1281 */ 1282 idmap_stat 1283 idmap_getext_sidbyuid(idmap_get_handle_t *gh, uid_t uid, int flag, 1284 char **sidprefix, idmap_rid_t *rid, idmap_info *info, idmap_stat *stat) 1285 { 1286 1287 idmap_retcode retcode; 1288 idmap_mapping *mapping = NULL; 1289 1290 /* sanity checks */ 1291 if (gh == NULL) 1292 return (IDMAP_ERR_ARG); 1293 if (sidprefix == NULL) 1294 return (IDMAP_ERR_ARG); 1295 1296 if ((flag & IDMAP_REQ_FLG_USE_CACHE) && 1297 !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) { 1298 retcode = idmap_cache_lookup_sidbyuid(sidprefix, rid, uid); 1299 if (retcode == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) { 1300 *stat = retcode; 1301 return (retcode); 1302 } 1303 } 1304 1305 /* Extend the request array and the return list */ 1306 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS) 1307 goto errout; 1308 1309 /* Setup the request */ 1310 mapping = &gh->batch.idmap_mapping_batch_val[gh->next]; 1311 mapping->flag = flag; 1312 mapping->id1.idtype = IDMAP_UID; 1313 mapping->id1.idmap_id_u.uid = uid; 1314 mapping->id2.idtype = IDMAP_SID; 1315 1316 /* Setup pointers for the result */ 1317 gh->retlist[gh->next].idtype = IDMAP_SID; 1318 gh->retlist[gh->next].sidprefix = sidprefix; 1319 gh->retlist[gh->next].rid = rid; 1320 gh->retlist[gh->next].stat = stat; 1321 gh->retlist[gh->next].info = info; 1322 gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE; 1323 1324 gh->next++; 1325 return (IDMAP_SUCCESS); 1326 1327 errout: 1328 if (mapping) 1329 (void) memset(mapping, 0, sizeof (*mapping)); 1330 errno = idmap_stat2errno(retcode); 1331 return (retcode); 1332 } 1333 1334 1335 /* 1336 * Given GID, get SID 1337 * 1338 * Input: 1339 * gid - POSIX GID 1340 * flag - flag 1341 * 1342 * Output: 1343 * stat - status of the get request 1344 * sidprefix - SID prefix (if stat == 0) 1345 * rid - rid 1346 * 1347 * Note: The output parameters will be set by idmap_get_mappings() 1348 */ 1349 idmap_stat 1350 idmap_get_sidbygid(idmap_get_handle_t *gh, gid_t gid, int flag, 1351 char **sidprefix, idmap_rid_t *rid, idmap_stat *stat) 1352 { 1353 return (idmap_getext_sidbygid(gh, gid, flag, sidprefix, rid, 1354 NULL, stat)); 1355 } 1356 1357 1358 /* 1359 * Given GID, get SID 1360 * 1361 * Input: 1362 * gid - POSIX GID 1363 * flag - flag 1364 * 1365 * Output: 1366 * stat - status of the get request 1367 * sidprefix - SID prefix (if stat == 0) 1368 * rid - rid 1369 * how - mapping type if stat = 0 1370 * 1371 * Note: The output parameters will be set by idmap_get_mappings() 1372 */ 1373 idmap_stat 1374 idmap_getext_sidbygid(idmap_get_handle_t *gh, gid_t gid, int flag, 1375 char **sidprefix, idmap_rid_t *rid, idmap_info *info, idmap_stat *stat) 1376 { 1377 1378 idmap_retcode retcode; 1379 idmap_mapping *mapping = NULL; 1380 1381 /* sanity checks */ 1382 if (gh == NULL) 1383 return (IDMAP_ERR_ARG); 1384 if (sidprefix == NULL) 1385 return (IDMAP_ERR_ARG); 1386 1387 if ((flag & IDMAP_REQ_FLG_USE_CACHE) && 1388 !(flag & IDMAP_REQ_FLG_MAPPING_INFO)) { 1389 retcode = idmap_cache_lookup_sidbygid(sidprefix, rid, gid); 1390 if (retcode == IDMAP_SUCCESS || retcode == IDMAP_ERR_MEMORY) { 1391 *stat = retcode; 1392 return (retcode); 1393 } 1394 } 1395 1396 /* Extend the request array and the return list */ 1397 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS) 1398 goto errout; 1399 1400 /* Setup the request */ 1401 mapping = &gh->batch.idmap_mapping_batch_val[gh->next]; 1402 mapping->flag = flag; 1403 mapping->id1.idtype = IDMAP_GID; 1404 mapping->id1.idmap_id_u.gid = gid; 1405 mapping->id2.idtype = IDMAP_SID; 1406 1407 /* Setup pointers for the result */ 1408 gh->retlist[gh->next].idtype = IDMAP_SID; 1409 gh->retlist[gh->next].sidprefix = sidprefix; 1410 gh->retlist[gh->next].rid = rid; 1411 gh->retlist[gh->next].stat = stat; 1412 gh->retlist[gh->next].info = info; 1413 gh->retlist[gh->next].cache_res = flag & IDMAP_REQ_FLG_USE_CACHE; 1414 1415 gh->next++; 1416 return (IDMAP_SUCCESS); 1417 1418 errout: 1419 if (mapping) 1420 (void) memset(mapping, 0, sizeof (*mapping)); 1421 errno = idmap_stat2errno(retcode); 1422 return (retcode); 1423 } 1424 1425 1426 /* 1427 * Process the batched "get mapping" requests. The results (i.e. 1428 * status and identity) will be available in the data areas 1429 * provided by individual requests. 1430 */ 1431 idmap_stat 1432 idmap_get_mappings(idmap_get_handle_t *gh) 1433 { 1434 idmap_retcode retcode; 1435 idmap_ids_res res; 1436 idmap_id *res_id; 1437 int i; 1438 idmap_id *req_id; 1439 int direction; 1440 1441 if (gh == NULL) { 1442 errno = EINVAL; 1443 return (IDMAP_ERR_ARG); 1444 } 1445 1446 (void) memset(&res, 0, sizeof (idmap_ids_res)); 1447 retcode = _idmap_clnt_call(IDMAP_GET_MAPPED_IDS, 1448 (xdrproc_t)xdr_idmap_mapping_batch, 1449 (caddr_t)&gh->batch, 1450 (xdrproc_t)xdr_idmap_ids_res, 1451 (caddr_t)&res, 1452 TIMEOUT); 1453 if (retcode != IDMAP_SUCCESS) { 1454 goto out; 1455 } 1456 if (res.retcode != IDMAP_SUCCESS) { 1457 retcode = res.retcode; 1458 goto out; 1459 } 1460 for (i = 0; i < gh->next; i++) { 1461 if (i >= res.ids.ids_len) { 1462 *gh->retlist[i].stat = IDMAP_ERR_NORESULT; 1463 continue; 1464 } 1465 *gh->retlist[i].stat = res.ids.ids_val[i].retcode; 1466 res_id = &res.ids.ids_val[i].id; 1467 direction = res.ids.ids_val[i].direction; 1468 req_id = &gh->batch.idmap_mapping_batch_val[i].id1; 1469 switch (res_id->idtype) { 1470 case IDMAP_UID: 1471 if (gh->retlist[i].uid) 1472 *gh->retlist[i].uid = res_id->idmap_id_u.uid; 1473 if (gh->retlist[i].is_user) 1474 *gh->retlist[i].is_user = 1; 1475 1476 if (res.ids.ids_val[i].retcode == IDMAP_SUCCESS && 1477 gh->retlist[i].cache_res) { 1478 if (gh->retlist[i].is_user != NULL) 1479 idmap_cache_add_sid2pid( 1480 req_id->idmap_id_u.sid.prefix, 1481 req_id->idmap_id_u.sid.rid, 1482 res_id->idmap_id_u.uid, 1, 1483 direction); 1484 else 1485 idmap_cache_add_sid2uid( 1486 req_id->idmap_id_u.sid.prefix, 1487 req_id->idmap_id_u.sid.rid, 1488 res_id->idmap_id_u.uid, 1489 direction); 1490 } 1491 break; 1492 1493 case IDMAP_GID: 1494 if (gh->retlist[i].gid) 1495 *gh->retlist[i].gid = res_id->idmap_id_u.gid; 1496 if (gh->retlist[i].is_user) 1497 *gh->retlist[i].is_user = 0; 1498 1499 if (res.ids.ids_val[i].retcode == IDMAP_SUCCESS && 1500 gh->retlist[i].cache_res) { 1501 if (gh->retlist[i].is_user != NULL) 1502 idmap_cache_add_sid2pid( 1503 req_id->idmap_id_u.sid.prefix, 1504 req_id->idmap_id_u.sid.rid, 1505 res_id->idmap_id_u.gid, 0, 1506 direction); 1507 else 1508 idmap_cache_add_sid2gid( 1509 req_id->idmap_id_u.sid.prefix, 1510 req_id->idmap_id_u.sid.rid, 1511 res_id->idmap_id_u.gid, 1512 direction); 1513 } 1514 break; 1515 1516 case IDMAP_POSIXID: 1517 if (gh->retlist[i].uid) 1518 *gh->retlist[i].uid = 60001; 1519 if (gh->retlist[i].is_user) 1520 *gh->retlist[i].is_user = -1; 1521 break; 1522 1523 case IDMAP_SID: 1524 case IDMAP_USID: 1525 case IDMAP_GSID: 1526 if (gh->retlist[i].rid) 1527 *gh->retlist[i].rid = 1528 res_id->idmap_id_u.sid.rid; 1529 if (gh->retlist[i].sidprefix) { 1530 if (res_id->idmap_id_u.sid.prefix == NULL || 1531 *res_id->idmap_id_u.sid.prefix == '\0') { 1532 *gh->retlist[i].sidprefix = NULL; 1533 break; 1534 } 1535 *gh->retlist[i].sidprefix = 1536 strdup(res_id->idmap_id_u.sid.prefix); 1537 if (*gh->retlist[i].sidprefix == NULL) 1538 *gh->retlist[i].stat = 1539 IDMAP_ERR_MEMORY; 1540 } 1541 if (res.ids.ids_val[i].retcode == IDMAP_SUCCESS && 1542 gh->retlist[i].cache_res) { 1543 if (req_id->idtype == IDMAP_UID) 1544 idmap_cache_add_sid2uid( 1545 res_id->idmap_id_u.sid.prefix, 1546 res_id->idmap_id_u.sid.rid, 1547 req_id->idmap_id_u.uid, 1548 direction); 1549 else /* req_id->idtype == IDMAP_GID */ 1550 idmap_cache_add_sid2gid( 1551 res_id->idmap_id_u.sid.prefix, 1552 res_id->idmap_id_u.sid.rid, 1553 req_id->idmap_id_u.gid, 1554 direction); 1555 } 1556 break; 1557 1558 case IDMAP_NONE: 1559 break; 1560 1561 default: 1562 *gh->retlist[i].stat = IDMAP_ERR_NORESULT; 1563 break; 1564 } 1565 if (gh->retlist[i].info != NULL) { 1566 idmap_info_mov(gh->retlist[i].info, 1567 &res.ids.ids_val[i].info); 1568 } 1569 } 1570 retcode = IDMAP_SUCCESS; 1571 1572 out: 1573 _IDMAP_RESET_GET_HANDLE(gh); 1574 (void) xdr_free(xdr_idmap_ids_res, (caddr_t)&res); 1575 errno = idmap_stat2errno(retcode); 1576 return (retcode); 1577 } 1578 1579 1580 /* 1581 * Destroy the "get mapping" handle 1582 */ 1583 void 1584 idmap_get_destroy(idmap_get_handle_t *gh) 1585 { 1586 if (gh == NULL) 1587 return; 1588 (void) xdr_free(xdr_idmap_mapping_batch, (caddr_t)&gh->batch); 1589 if (gh->retlist) 1590 free(gh->retlist); 1591 free(gh); 1592 } 1593 1594 1595 /* 1596 * Get windows to unix mapping 1597 */ 1598 idmap_stat 1599 idmap_get_w2u_mapping( 1600 const char *sidprefix, idmap_rid_t *rid, 1601 const char *winname, const char *windomain, 1602 int flag, int *is_user, int *is_wuser, 1603 uid_t *pid, char **unixname, int *direction, idmap_info *info) 1604 { 1605 idmap_mapping request, *mapping; 1606 idmap_mappings_res result; 1607 idmap_retcode retcode, rc; 1608 1609 (void) memset(&request, 0, sizeof (request)); 1610 (void) memset(&result, 0, sizeof (result)); 1611 1612 if (pid) 1613 *pid = UINT32_MAX; 1614 if (unixname) 1615 *unixname = NULL; 1616 if (direction) 1617 *direction = IDMAP_DIRECTION_UNDEF; 1618 1619 request.flag = flag; 1620 request.id1.idtype = IDMAP_SID; 1621 if (sidprefix && rid) { 1622 request.id1.idmap_id_u.sid.prefix = (char *)sidprefix; 1623 request.id1.idmap_id_u.sid.rid = *rid; 1624 } else if (winname) { 1625 retcode = idmap_strdupnull(&request.id1name, winname); 1626 if (retcode != IDMAP_SUCCESS) 1627 goto out; 1628 1629 retcode = idmap_strdupnull(&request.id1domain, windomain); 1630 if (retcode != IDMAP_SUCCESS) 1631 goto out; 1632 1633 request.id1.idmap_id_u.sid.prefix = NULL; 1634 } else { 1635 errno = EINVAL; 1636 return (IDMAP_ERR_ARG); 1637 } 1638 1639 if (*is_user == 1) 1640 request.id2.idtype = IDMAP_UID; 1641 else if (*is_user == 0) 1642 request.id2.idtype = IDMAP_GID; 1643 else 1644 request.id2.idtype = IDMAP_POSIXID; 1645 1646 if (*is_wuser == 1) 1647 request.id1.idtype = IDMAP_USID; 1648 else if (*is_wuser == 0) 1649 request.id1.idtype = IDMAP_GSID; 1650 else 1651 request.id1.idtype = IDMAP_SID; 1652 1653 retcode = _idmap_clnt_call(IDMAP_GET_MAPPED_ID_BY_NAME, 1654 (xdrproc_t)xdr_idmap_mapping, (caddr_t)&request, 1655 (xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result, 1656 TIMEOUT); 1657 1658 if (retcode != IDMAP_SUCCESS) 1659 return (retcode); 1660 1661 retcode = result.retcode; 1662 1663 if ((mapping = result.mappings.mappings_val) == NULL) { 1664 if (retcode == IDMAP_SUCCESS) 1665 retcode = IDMAP_ERR_NORESULT; 1666 goto out; 1667 } 1668 1669 if (info != NULL) 1670 idmap_info_mov(info, &mapping->info); 1671 1672 if (mapping->id2.idtype == IDMAP_UID) { 1673 *is_user = 1; 1674 } else if (mapping->id2.idtype == IDMAP_GID) { 1675 *is_user = 0; 1676 } else { 1677 goto out; 1678 } 1679 1680 if (mapping->id1.idtype == IDMAP_USID) { 1681 *is_wuser = 1; 1682 } else if (mapping->id1.idtype == IDMAP_GSID) { 1683 *is_wuser = 0; 1684 } else { 1685 goto out; 1686 } 1687 1688 if (direction) 1689 *direction = mapping->direction; 1690 if (pid) 1691 *pid = mapping->id2.idmap_id_u.uid; 1692 1693 rc = idmap_strdupnull(unixname, mapping->id2name); 1694 if (rc != IDMAP_SUCCESS) 1695 retcode = rc; 1696 1697 out: 1698 if (request.id1name != NULL) 1699 free(request.id1name); 1700 if (request.id1domain != NULL) 1701 free(request.id1domain); 1702 xdr_free(xdr_idmap_mappings_res, (caddr_t)&result); 1703 if (retcode != IDMAP_SUCCESS) 1704 errno = idmap_stat2errno(retcode); 1705 return (retcode); 1706 } 1707 1708 1709 /* 1710 * Get unix to windows mapping 1711 */ 1712 idmap_stat 1713 idmap_get_u2w_mapping( 1714 uid_t *pid, const char *unixname, 1715 int flag, int is_user, int *is_wuser, 1716 char **sidprefix, idmap_rid_t *rid, 1717 char **winname, char **windomain, 1718 int *direction, idmap_info *info) 1719 { 1720 idmap_mapping request, *mapping; 1721 idmap_mappings_res result; 1722 idmap_retcode retcode, rc; 1723 1724 if (sidprefix) 1725 *sidprefix = NULL; 1726 if (winname) 1727 *winname = NULL; 1728 if (windomain) 1729 *windomain = NULL; 1730 if (rid) 1731 *rid = UINT32_MAX; 1732 if (direction) 1733 *direction = IDMAP_DIRECTION_UNDEF; 1734 1735 (void) memset(&request, 0, sizeof (request)); 1736 (void) memset(&result, 0, sizeof (result)); 1737 1738 request.flag = flag; 1739 request.id1.idtype = is_user?IDMAP_UID:IDMAP_GID; 1740 1741 if (pid && *pid != UINT32_MAX) { 1742 request.id1.idmap_id_u.uid = *pid; 1743 } else if (unixname) { 1744 request.id1name = (char *)unixname; 1745 request.id1.idmap_id_u.uid = UINT32_MAX; 1746 } else { 1747 errno = EINVAL; 1748 return (IDMAP_ERR_ARG); 1749 } 1750 1751 if (is_wuser == NULL) 1752 request.id2.idtype = IDMAP_SID; 1753 else if (*is_wuser == -1) 1754 request.id2.idtype = IDMAP_SID; 1755 else if (*is_wuser == 0) 1756 request.id2.idtype = IDMAP_GSID; 1757 else if (*is_wuser == 1) 1758 request.id2.idtype = IDMAP_USID; 1759 1760 retcode = _idmap_clnt_call(IDMAP_GET_MAPPED_ID_BY_NAME, 1761 (xdrproc_t)xdr_idmap_mapping, (caddr_t)&request, 1762 (xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result, 1763 TIMEOUT); 1764 1765 if (retcode != IDMAP_SUCCESS) 1766 return (retcode); 1767 1768 retcode = result.retcode; 1769 1770 if ((mapping = result.mappings.mappings_val) == NULL) { 1771 if (retcode == IDMAP_SUCCESS) 1772 retcode = IDMAP_ERR_NORESULT; 1773 goto out; 1774 } 1775 1776 if (info != NULL) 1777 idmap_info_mov(info, &mapping->info); 1778 1779 if (direction != NULL) 1780 *direction = mapping->direction; 1781 1782 if (is_wuser != NULL) { 1783 if (mapping->id2.idtype == IDMAP_USID) 1784 *is_wuser = 1; 1785 else if (mapping->id2.idtype == IDMAP_GSID) 1786 *is_wuser = 0; 1787 else 1788 *is_wuser = -1; 1789 } 1790 1791 if (sidprefix && mapping->id2.idmap_id_u.sid.prefix && 1792 *mapping->id2.idmap_id_u.sid.prefix != '\0') { 1793 *sidprefix = strdup(mapping->id2.idmap_id_u.sid.prefix); 1794 if (*sidprefix == NULL) { 1795 retcode = IDMAP_ERR_MEMORY; 1796 goto errout; 1797 } 1798 } 1799 if (rid) 1800 *rid = mapping->id2.idmap_id_u.sid.rid; 1801 1802 rc = idmap_strdupnull(winname, mapping->id2name); 1803 if (rc != IDMAP_SUCCESS) 1804 retcode = rc; 1805 1806 rc = idmap_strdupnull(windomain, mapping->id2domain); 1807 if (rc != IDMAP_SUCCESS) 1808 retcode = rc; 1809 1810 goto out; 1811 1812 errout: 1813 if (sidprefix && *sidprefix) { 1814 free(*sidprefix); 1815 *sidprefix = NULL; 1816 } 1817 if (winname && *winname) { 1818 free(*winname); 1819 *winname = NULL; 1820 } 1821 if (windomain && *windomain) { 1822 free(*windomain); 1823 *windomain = NULL; 1824 } 1825 1826 out: 1827 xdr_free(xdr_idmap_mappings_res, (caddr_t)&result); 1828 if (retcode != IDMAP_SUCCESS) 1829 errno = idmap_stat2errno(retcode); 1830 return (retcode); 1831 } 1832 1833 1834 1835 #define gettext(s) s 1836 static stat_table_t stattable[] = { 1837 {IDMAP_SUCCESS, gettext("Success"), 0}, 1838 {IDMAP_NEXT, gettext("More results available"), 0}, 1839 {IDMAP_ERR_OTHER, gettext("Undefined error"), EINVAL}, 1840 {IDMAP_ERR_INTERNAL, gettext("Internal error"), EINVAL}, 1841 {IDMAP_ERR_MEMORY, gettext("Out of memory"), ENOMEM}, 1842 {IDMAP_ERR_NORESULT, gettext("No results available"), EINVAL}, 1843 {IDMAP_ERR_NOTUSER, gettext("Not a user"), EINVAL}, 1844 {IDMAP_ERR_NOTGROUP, gettext("Not a group"), EINVAL}, 1845 {IDMAP_ERR_NOTSUPPORTED, gettext("Operation not supported"), ENOTSUP}, 1846 {IDMAP_ERR_W2U_NAMERULE, 1847 gettext("Invalid Windows to UNIX name-based rule"), EINVAL}, 1848 {IDMAP_ERR_U2W_NAMERULE, 1849 gettext("Invalid UNIX to Windows name-based rule"), EINVAL}, 1850 {IDMAP_ERR_CACHE, gettext("Invalid cache"), EINVAL}, 1851 {IDMAP_ERR_DB, gettext("Invalid database"), EINVAL}, 1852 {IDMAP_ERR_ARG, gettext("Invalid argument"), EINVAL}, 1853 {IDMAP_ERR_SID, gettext("Invalid SID"), EINVAL}, 1854 {IDMAP_ERR_IDTYPE, gettext("Invalid identity type"), EINVAL}, 1855 {IDMAP_ERR_RPC_HANDLE, gettext("Bad RPC handle"), EBADF}, 1856 {IDMAP_ERR_RPC, gettext("RPC error"), EINVAL}, 1857 {IDMAP_ERR_CLIENT_HANDLE, gettext("Bad client handle"), EINVAL}, 1858 {IDMAP_ERR_BUSY, gettext("Server is busy"), EBUSY}, 1859 {IDMAP_ERR_PERMISSION_DENIED, gettext("Permission denied"), EACCES}, 1860 {IDMAP_ERR_NOMAPPING, 1861 gettext("Mapping not found or inhibited"), EINVAL}, 1862 {IDMAP_ERR_NEW_ID_ALLOC_REQD, 1863 gettext("New mapping needs to be created"), EINVAL}, 1864 {IDMAP_ERR_DOMAIN, gettext("Invalid domain"), EINVAL}, 1865 {IDMAP_ERR_SECURITY, gettext("Security issue"), EINVAL}, 1866 {IDMAP_ERR_NOTFOUND, gettext("Not found"), EINVAL}, 1867 {IDMAP_ERR_DOMAIN_NOTFOUND, gettext("Domain not found"), EINVAL}, 1868 {IDMAP_ERR_UPDATE_NOTALLOWED, gettext("Update not allowed"), EINVAL}, 1869 {IDMAP_ERR_CFG, gettext("Configuration error"), EINVAL}, 1870 {IDMAP_ERR_CFG_CHANGE, gettext("Invalid configuration change"), EINVAL}, 1871 {IDMAP_ERR_NOTMAPPED_WELLKNOWN, 1872 gettext("No mapping for well-known SID"), EINVAL}, 1873 {IDMAP_ERR_RETRIABLE_NET_ERR, 1874 gettext("Windows lookup failed"), EINVAL}, 1875 {IDMAP_ERR_W2U_NAMERULE_CONFLICT, 1876 gettext("Duplicate rule or conflicts with an existing " 1877 "Windows to UNIX name-based rule"), EINVAL}, 1878 {IDMAP_ERR_U2W_NAMERULE_CONFLICT, 1879 gettext("Duplicate rule or conflicts with an existing " 1880 "Unix to Windows name-based rule"), EINVAL}, 1881 {IDMAP_ERR_BAD_UTF8, 1882 gettext("Invalid or illegal UTF-8 sequence found in " 1883 "a given Windows entity name or domain name"), EINVAL}, 1884 {IDMAP_ERR_NONE_GENERATED, 1885 gettext("Mapping not found and none created (see -c option)"), 1886 EINVAL}, 1887 {IDMAP_ERR_PROP_UNKNOWN, 1888 gettext("Undefined property"), 1889 EINVAL}, 1890 {IDMAP_ERR_NS_LDAP_CFG, 1891 gettext("Native LDAP configuration error"), EINVAL}, 1892 {IDMAP_ERR_NS_LDAP_PARTIAL, 1893 gettext("Partial result from Native LDAP"), EINVAL}, 1894 {IDMAP_ERR_NS_LDAP_OP_FAILED, 1895 gettext("Native LDAP operation failed"), EINVAL}, 1896 {IDMAP_ERR_NS_LDAP_BAD_WINNAME, 1897 gettext("Improper winname form found in Native LDAP"), EINVAL}, 1898 {IDMAP_ERR_NO_ACTIVEDIRECTORY, 1899 gettext("No AD servers"), 1900 EINVAL}, 1901 {-1, NULL, 0} 1902 }; 1903 #undef gettext 1904 1905 1906 /* 1907 * Get description of status code 1908 * 1909 * Input: 1910 * status - Status code returned by libidmap API call 1911 * 1912 * Return Value: 1913 * human-readable localized description of idmap_stat 1914 */ 1915 const char * 1916 idmap_stat2string(idmap_stat status) 1917 { 1918 int i; 1919 1920 for (i = 0; stattable[i].msg; i++) { 1921 if (stattable[i].retcode == status) 1922 return (dgettext(TEXT_DOMAIN, stattable[i].msg)); 1923 } 1924 return (dgettext(TEXT_DOMAIN, "Unknown error")); 1925 } 1926 1927 1928 static int 1929 idmap_stat2errno(idmap_stat stat) 1930 { 1931 int i; 1932 for (i = 0; stattable[i].msg; i++) { 1933 if (stattable[i].retcode == stat) 1934 return (stattable[i].errnum); 1935 } 1936 return (EINVAL); 1937 } 1938 1939 1940 /* 1941 * Get status code from string 1942 */ 1943 idmap_stat 1944 idmap_string2stat(const char *str) 1945 { 1946 if (str == NULL) 1947 return (IDMAP_ERR_INTERNAL); 1948 1949 #define return_cmp(a) \ 1950 if (0 == strcmp(str, "IDMAP_ERR_" #a)) \ 1951 return (IDMAP_ERR_ ## a); 1952 1953 return_cmp(OTHER); 1954 return_cmp(INTERNAL); 1955 return_cmp(MEMORY); 1956 return_cmp(NORESULT); 1957 return_cmp(NOTUSER); 1958 return_cmp(NOTGROUP); 1959 return_cmp(NOTSUPPORTED); 1960 return_cmp(W2U_NAMERULE); 1961 return_cmp(U2W_NAMERULE); 1962 return_cmp(CACHE); 1963 return_cmp(DB); 1964 return_cmp(ARG); 1965 return_cmp(SID); 1966 return_cmp(IDTYPE); 1967 return_cmp(RPC_HANDLE); 1968 return_cmp(RPC); 1969 return_cmp(CLIENT_HANDLE); 1970 return_cmp(BUSY); 1971 return_cmp(PERMISSION_DENIED); 1972 return_cmp(NOMAPPING); 1973 return_cmp(NEW_ID_ALLOC_REQD); 1974 return_cmp(DOMAIN); 1975 return_cmp(SECURITY); 1976 return_cmp(NOTFOUND); 1977 return_cmp(DOMAIN_NOTFOUND); 1978 return_cmp(MEMORY); 1979 return_cmp(UPDATE_NOTALLOWED); 1980 return_cmp(CFG); 1981 return_cmp(CFG_CHANGE); 1982 return_cmp(NOTMAPPED_WELLKNOWN); 1983 return_cmp(RETRIABLE_NET_ERR); 1984 return_cmp(W2U_NAMERULE_CONFLICT); 1985 return_cmp(U2W_NAMERULE_CONFLICT); 1986 return_cmp(BAD_UTF8); 1987 return_cmp(NONE_GENERATED); 1988 return_cmp(PROP_UNKNOWN); 1989 return_cmp(NS_LDAP_CFG); 1990 return_cmp(NS_LDAP_PARTIAL); 1991 return_cmp(NS_LDAP_OP_FAILED); 1992 return_cmp(NS_LDAP_BAD_WINNAME); 1993 return_cmp(NO_ACTIVEDIRECTORY); 1994 #undef return_cmp 1995 1996 return (IDMAP_ERR_OTHER); 1997 } 1998 1999 2000 /* 2001 * Map the given status to one that can be returned by the protocol 2002 */ 2003 idmap_stat 2004 idmap_stat4prot(idmap_stat status) 2005 { 2006 switch (status) { 2007 case IDMAP_ERR_MEMORY: 2008 case IDMAP_ERR_CACHE: 2009 return (IDMAP_ERR_INTERNAL); 2010 } 2011 return (status); 2012 } 2013 2014 2015 /* 2016 * This is a convenience routine which duplicates a string after 2017 * checking for NULL pointers. This function will return success if 2018 * either the 'to' OR 'from' pointers are NULL. 2019 */ 2020 static idmap_stat 2021 idmap_strdupnull(char **to, const char *from) 2022 { 2023 if (to == NULL) 2024 return (IDMAP_SUCCESS); 2025 2026 if (from == NULL || *from == '\0') { 2027 *to = NULL; 2028 return (IDMAP_SUCCESS); 2029 } 2030 2031 *to = strdup(from); 2032 if (*to == NULL) 2033 return (IDMAP_ERR_MEMORY); 2034 return (IDMAP_SUCCESS); 2035 } 2036 2037 2038 idmap_stat 2039 idmap_namerule_cpy(idmap_namerule *to, idmap_namerule *from) 2040 { 2041 idmap_stat retval; 2042 2043 if (to == NULL) 2044 return (IDMAP_SUCCESS); 2045 2046 (void) memcpy(to, from, sizeof (idmap_namerule)); 2047 to->windomain = NULL; 2048 to->winname = NULL; 2049 to->unixname = NULL; 2050 2051 retval = idmap_strdupnull(&to->windomain, from->windomain); 2052 if (retval != IDMAP_SUCCESS) 2053 return (retval); 2054 2055 retval = idmap_strdupnull(&to->winname, from->winname); 2056 if (retval != IDMAP_SUCCESS) { 2057 free(to->windomain); 2058 to->windomain = NULL; 2059 return (retval); 2060 } 2061 2062 retval = idmap_strdupnull(&to->unixname, from->unixname); 2063 if (retval != IDMAP_SUCCESS) { 2064 free(to->windomain); 2065 to->windomain = NULL; 2066 free(to->winname); 2067 to->winname = NULL; 2068 return (retval); 2069 } 2070 2071 return (retval); 2072 } 2073 2074 2075 /* 2076 * Move the contents of the "info" structure from "from" to "to". 2077 */ 2078 void 2079 idmap_info_mov(idmap_info *to, idmap_info *from) 2080 { 2081 (void) memcpy(to, from, sizeof (idmap_info)); 2082 (void) memset(from, 0, sizeof (idmap_info)); 2083 } 2084 2085 2086 void 2087 idmap_info_free(idmap_info *info) 2088 { 2089 if (info == NULL) 2090 return; 2091 2092 xdr_free(xdr_idmap_info, (caddr_t)info); 2093 (void) memset(info, 0, sizeof (idmap_info)); 2094 } 2095 2096 2097 void 2098 idmap_how_clear(idmap_how *how) 2099 { 2100 xdr_free(xdr_idmap_how, (caddr_t)how); 2101 (void) memset(how, 0, sizeof (*how)); 2102 } 2103 2104 2105 /* 2106 * Get uid given Windows name 2107 */ 2108 idmap_stat 2109 idmap_getuidbywinname(const char *name, const char *domain, int flag, 2110 uid_t *uid) 2111 { 2112 idmap_retcode rc; 2113 int is_user = 1; 2114 int is_wuser = -1; 2115 int direction; 2116 2117 if (uid == NULL) 2118 return (IDMAP_ERR_ARG); 2119 2120 if (flag & IDMAP_REQ_FLG_USE_CACHE) { 2121 rc = idmap_cache_lookup_uidbywinname(name, domain, uid); 2122 if (rc == IDMAP_SUCCESS || rc == IDMAP_ERR_MEMORY) 2123 return (rc); 2124 } 2125 /* Get mapping */ 2126 rc = idmap_get_w2u_mapping(NULL, NULL, name, domain, flag, 2127 &is_user, &is_wuser, uid, NULL, &direction, NULL); 2128 2129 if (rc == IDMAP_SUCCESS && (flag & IDMAP_REQ_FLG_USE_CACHE)) { 2130 /* If we have not got the domain don't store UID to winname */ 2131 if (domain == NULL) 2132 direction = IDMAP_DIRECTION_W2U; 2133 idmap_cache_add_winname2uid(name, domain, *uid, direction); 2134 } 2135 2136 return (rc); 2137 } 2138 2139 2140 /* 2141 * Get gid given Windows name 2142 */ 2143 idmap_stat 2144 idmap_getgidbywinname(const char *name, const char *domain, int flag, 2145 gid_t *gid) 2146 { 2147 idmap_retcode rc; 2148 int is_user = 0; 2149 int is_wuser = -1; 2150 int direction; 2151 2152 if (gid == NULL) 2153 return (IDMAP_ERR_ARG); 2154 2155 if (flag & IDMAP_REQ_FLG_USE_CACHE) { 2156 rc = idmap_cache_lookup_gidbywinname(name, domain, gid); 2157 if (rc == IDMAP_SUCCESS || rc == IDMAP_ERR_MEMORY) 2158 return (rc); 2159 } 2160 2161 /* Get mapping */ 2162 rc = idmap_get_w2u_mapping(NULL, NULL, name, domain, flag, 2163 &is_user, &is_wuser, gid, NULL, &direction, NULL); 2164 2165 if (rc == IDMAP_SUCCESS && (flag & IDMAP_REQ_FLG_USE_CACHE)) { 2166 /* If we have not got the domain don't store GID to winname */ 2167 if (domain == NULL) 2168 direction = IDMAP_DIRECTION_W2U; 2169 idmap_cache_add_winname2gid(name, domain, *gid, direction); 2170 } 2171 2172 return (rc); 2173 } 2174 2175 2176 /* 2177 * Get winname given pid 2178 */ 2179 static idmap_retcode 2180 idmap_getwinnamebypid(uid_t pid, int is_user, int flag, char **name, 2181 char **domain) 2182 { 2183 idmap_retcode rc; 2184 int len; 2185 char *winname, *windomain; 2186 int direction; 2187 2188 if (name == NULL) 2189 return (IDMAP_ERR_ARG); 2190 2191 if (flag & IDMAP_REQ_FLG_USE_CACHE) { 2192 if (is_user) 2193 rc = idmap_cache_lookup_winnamebyuid(&winname, 2194 &windomain, pid); 2195 else 2196 rc = idmap_cache_lookup_winnamebygid(&winname, 2197 &windomain, pid); 2198 if (rc == IDMAP_SUCCESS) 2199 goto out; 2200 if (rc == IDMAP_ERR_MEMORY) 2201 return (rc); 2202 } 2203 2204 /* Get mapping */ 2205 rc = idmap_get_u2w_mapping(&pid, NULL, flag, is_user, NULL, 2206 NULL, NULL, &winname, &windomain, &direction, NULL); 2207 2208 /* Return on error */ 2209 if (rc != IDMAP_SUCCESS) 2210 return (rc); 2211 2212 /* 2213 * The given PID may have been mapped to a locally 2214 * generated SID in which case there isn't any 2215 * Windows name 2216 */ 2217 if (winname == NULL || windomain == NULL) { 2218 idmap_free(winname); 2219 idmap_free(windomain); 2220 return (IDMAP_ERR_NORESULT); 2221 } 2222 2223 if (flag & IDMAP_REQ_FLG_USE_CACHE) { 2224 if (is_user) 2225 idmap_cache_add_winname2uid(winname, windomain, 2226 pid, direction); 2227 else 2228 idmap_cache_add_winname2gid(winname, windomain, 2229 pid, direction); 2230 } 2231 2232 out: 2233 if (domain != NULL) { 2234 *name = winname; 2235 *domain = windomain; 2236 } else { 2237 len = strlen(winname) + strlen(windomain) + 2; 2238 if ((*name = malloc(len)) != NULL) 2239 (void) snprintf(*name, len, "%s@%s", winname, 2240 windomain); 2241 else 2242 rc = IDMAP_ERR_MEMORY; 2243 idmap_free(winname); 2244 idmap_free(windomain); 2245 } 2246 2247 return (rc); 2248 } 2249 2250 2251 /* 2252 * Get winname given uid 2253 */ 2254 idmap_stat 2255 idmap_getwinnamebyuid(uid_t uid, int flag, char **name, char **domain) 2256 { 2257 return (idmap_getwinnamebypid(uid, 1, flag, name, domain)); 2258 } 2259 2260 2261 /* 2262 * Get winname given gid 2263 */ 2264 idmap_stat 2265 idmap_getwinnamebygid(gid_t gid, int flag, char **name, char **domain) 2266 { 2267 return (idmap_getwinnamebypid(gid, 0, flag, name, domain)); 2268 } 2269 2270 idmap_stat 2271 idmap_flush(idmap_flush_op op) 2272 { 2273 idmap_retcode rc1, rc2; 2274 2275 rc1 = _idmap_clnt_call(IDMAP_FLUSH, 2276 (xdrproc_t)xdr_idmap_flush_op, (caddr_t)&op, 2277 (xdrproc_t)xdr_idmap_retcode, (caddr_t)&rc2, TIMEOUT); 2278 2279 if (rc1 != IDMAP_SUCCESS) 2280 return (rc1); 2281 return (rc2); 2282 } 2283 2284 2285 /* 2286 * syslog is the default logger. 2287 * It can be overwritten by supplying a logger 2288 * with idmap_set_logger() 2289 */ 2290 idmap_logger_t logger = syslog; 2291 2292 2293 void 2294 idmap_set_logger(idmap_logger_t funct) 2295 { 2296 logger = funct; 2297 } 2298 2299 /* 2300 * Helper functions that concatenate two parts of a name and then 2301 * look up a value, so that the same set of functions can be used to 2302 * process both "in" and "out" parameters. 2303 */ 2304 static 2305 boolean_t 2306 idmap_trace_get_str(nvlist_t *entry, char *n1, char *n2, char **ret) 2307 { 2308 char name[IDMAP_TRACE_NAME_MAX+1]; /* Max used is about 11 */ 2309 int err; 2310 2311 (void) strlcpy(name, n1, sizeof (name)); 2312 if (n2 != NULL) 2313 (void) strlcat(name, n2, sizeof (name)); 2314 2315 err = nvlist_lookup_string(entry, name, ret); 2316 return (err == 0); 2317 } 2318 2319 static 2320 boolean_t 2321 idmap_trace_get_int(nvlist_t *entry, char *n1, char *n2, int64_t *ret) 2322 { 2323 char name[IDMAP_TRACE_NAME_MAX+1]; /* Max used is about 11 */ 2324 int err; 2325 2326 (void) strlcpy(name, n1, sizeof (name)); 2327 if (n2 != NULL) 2328 (void) strlcat(name, n2, sizeof (name)); 2329 2330 err = nvlist_lookup_int64(entry, name, ret); 2331 return (err == 0); 2332 } 2333 2334 static 2335 void 2336 idmap_trace_print_id(FILE *out, nvlist_t *entry, char *fromto) 2337 { 2338 char *s; 2339 int64_t i64; 2340 2341 if (idmap_trace_get_int(entry, fromto, IDMAP_TRACE_TYPE, &i64)) { 2342 switch (i64) { 2343 case IDMAP_POSIXID: 2344 (void) fprintf(out, "unixname "); 2345 break; 2346 case IDMAP_UID: 2347 (void) fprintf(out, "unixuser "); 2348 break; 2349 case IDMAP_GID: 2350 (void) fprintf(out, "unixgroup "); 2351 break; 2352 case IDMAP_SID: 2353 (void) fprintf(out, "winname "); 2354 break; 2355 case IDMAP_USID: 2356 (void) fprintf(out, "winuser "); 2357 break; 2358 case IDMAP_GSID: 2359 (void) fprintf(out, "wingroup "); 2360 break; 2361 case IDMAP_NONE: 2362 (void) fprintf(out, gettext("unknown ")); 2363 break; 2364 default: 2365 (void) fprintf(out, gettext("bad %d "), (int)i64); 2366 break; 2367 } 2368 } 2369 2370 if (idmap_trace_get_str(entry, fromto, IDMAP_TRACE_NAME, &s)) 2371 (void) fprintf(out, "%s ", s); 2372 2373 if (idmap_trace_get_str(entry, fromto, IDMAP_TRACE_SID, &s)) 2374 (void) fprintf(out, "%s ", s); 2375 2376 if (idmap_trace_get_int(entry, fromto, IDMAP_TRACE_UNIXID, &i64)) 2377 (void) fprintf(out, "%u ", (uid_t)i64); 2378 } 2379 2380 void 2381 idmap_trace_print_1(FILE *out, char *prefix, nvlist_t *entry) 2382 { 2383 char *s; 2384 int64_t i64; 2385 2386 (void) fprintf(out, "%s", prefix); 2387 idmap_trace_print_id(out, entry, "from"); 2388 (void) fprintf(out, "-> "); 2389 idmap_trace_print_id(out, entry, "to"); 2390 if (idmap_trace_get_int(entry, IDMAP_TRACE_ERROR, NULL, &i64)) 2391 (void) fprintf(out, gettext("Error %d "), (int)i64); 2392 (void) fprintf(out, "-"); 2393 if (idmap_trace_get_str(entry, IDMAP_TRACE_MESSAGE, NULL, &s)) 2394 (void) fprintf(out, " %s", s); 2395 (void) fprintf(out, "\n"); 2396 } 2397 2398 void 2399 idmap_trace_print(FILE *out, char *prefix, nvlist_t *trace) 2400 { 2401 nvpair_t *nvp; 2402 2403 for (nvp = nvlist_next_nvpair(trace, NULL); 2404 nvp != NULL; 2405 nvp = nvlist_next_nvpair(trace, nvp)) { 2406 nvlist_t *entry; 2407 int err; 2408 2409 err = nvpair_value_nvlist(nvp, &entry); 2410 assert(err == 0); 2411 2412 idmap_trace_print_1(out, prefix, entry); 2413 } 2414 } 2415