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