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