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 2007 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 "idmap_impl.h" 43 44 static struct timeval TIMEOUT = { 25, 0 }; 45 46 static int idmap_stat2errno(idmap_stat); 47 48 #define __ITER_CREATE(itera, argu, handl, ityp)\ 49 if (handl == NULL) {\ 50 errno = EINVAL;\ 51 return (IDMAP_ERR_ARG);\ 52 }\ 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->ih = handl;\ 65 itera->type = ityp;\ 66 itera->retcode = IDMAP_NEXT;\ 67 itera->limit = 1024;\ 68 itera->arg = argu; 69 70 71 #define __ITER_ERR_RETURN(itera, argu, xdr_argu, iretcod)\ 72 if (argu) {\ 73 xdr_free(xdr_argu, (caddr_t)argu);\ 74 free(argu);\ 75 }\ 76 if (itera)\ 77 free(itera);\ 78 return (iretcod); 79 80 81 #define __ITER_CHECK(itera, ityp)\ 82 if (itera == NULL) {\ 83 errno = EINVAL;\ 84 return (IDMAP_ERR_ARG);\ 85 }\ 86 if (itera->type != ityp) {\ 87 errno = EINVAL;\ 88 return (IDMAP_ERR_ARG);\ 89 } 90 91 92 /* 93 * Free memory allocated by libidmap API 94 * 95 * Input: 96 * ptr - memory to be freed 97 */ 98 void 99 idmap_free(void *ptr) { 100 free(ptr); 101 } 102 103 104 /* 105 * Create and Initialize idmap client handle for rpc/doors 106 * 107 * Output: 108 * handle - idmap handle 109 */ 110 idmap_stat 111 idmap_init(idmap_handle_t **handle) { 112 CLIENT *clnt = NULL; 113 struct idmap_handle *hptr; 114 115 *handle = NULL; 116 hptr = (struct idmap_handle *)calloc(1, sizeof (*hptr)); 117 if (hptr == NULL) 118 return (IDMAP_ERR_MEMORY); 119 120 clnt = clnt_door_create(IDMAP_PROG, IDMAP_V1, 0); 121 if (clnt == NULL) { 122 free(hptr); 123 return (IDMAP_ERR_RPC); 124 } 125 hptr->type = _IDMAP_HANDLE_RPC_DOORS; 126 hptr->privhandle = clnt; 127 *handle = hptr; 128 return (IDMAP_SUCCESS); 129 } 130 131 132 /* 133 * Finalize idmap handle 134 * 135 * Input: 136 * handle - idmap handle 137 */ 138 idmap_stat 139 idmap_fini(idmap_handle_t *handle) { 140 CLIENT *clnt; 141 struct idmap_handle *hptr; 142 143 if (handle == NULL) 144 return (IDMAP_SUCCESS); 145 146 hptr = (struct idmap_handle *)handle; 147 148 switch (hptr->type) { 149 case _IDMAP_HANDLE_RPC_DOORS: 150 clnt = (CLIENT *)hptr->privhandle; 151 if (clnt) { 152 if (clnt->cl_auth) 153 auth_destroy(clnt->cl_auth); 154 clnt_destroy(clnt); 155 } 156 break; 157 default: 158 break; 159 } 160 free(hptr); 161 return (IDMAP_SUCCESS); 162 } 163 164 165 166 /* 167 * Create/Initialize handle for updates 168 * 169 * Output: 170 * udthandle - update handle 171 */ 172 idmap_stat 173 idmap_udt_create(idmap_handle_t *handle, idmap_udt_handle_t **udthandle) { 174 idmap_udt_handle_t *tmp; 175 176 if (handle == NULL || udthandle == NULL) { 177 errno = EINVAL; 178 return (IDMAP_ERR_ARG); 179 } 180 if ((tmp = calloc(1, sizeof (*tmp))) == NULL) { 181 errno = ENOMEM; 182 return (IDMAP_ERR_MEMORY); 183 } 184 185 tmp->ih = handle; 186 *udthandle = tmp; 187 return (IDMAP_SUCCESS); 188 } 189 190 191 /* 192 * All the updates specified by the update handle are committed 193 * in a single transaction. i.e either all succeed or none. 194 * 195 * Input: 196 * udthandle - update handle with the update requests 197 * 198 * Return value: 199 * Status of the commit 200 */ 201 idmap_stat 202 idmap_udt_commit(idmap_udt_handle_t *udthandle) { 203 CLIENT *clnt; 204 enum clnt_stat clntstat; 205 idmap_retcode retcode; 206 207 if (udthandle == NULL) { 208 errno = EINVAL; 209 return (IDMAP_ERR_ARG); 210 } 211 _IDMAP_GET_CLIENT_HANDLE(udthandle->ih, clnt); 212 clntstat = clnt_call(clnt, IDMAP_UPDATE, 213 (xdrproc_t)xdr_idmap_update_batch, (caddr_t)&udthandle->batch, 214 (xdrproc_t)xdr_idmap_retcode, (caddr_t)&retcode, 215 TIMEOUT); 216 217 /* reset handle so that it can be used again */ 218 _IDMAP_RESET_UDT_HANDLE(udthandle); 219 220 if (clntstat != RPC_SUCCESS) 221 return (_idmap_rpc2stat(clnt)); 222 if (retcode != IDMAP_SUCCESS) 223 errno = idmap_stat2errno(retcode); 224 return (retcode); 225 } 226 227 228 /* 229 * Destroy the update handle 230 */ 231 void 232 idmap_udt_destroy(idmap_udt_handle_t *udthandle) { 233 if (udthandle == NULL) 234 return; 235 (void) xdr_free(xdr_idmap_update_batch, (caddr_t)&udthandle->batch); 236 free(udthandle); 237 } 238 239 240 idmap_stat 241 idmap_udt_add_namerule(idmap_udt_handle_t *udthandle, const char *windomain, 242 boolean_t is_user, const char *winname, const char *unixname, 243 boolean_t is_nt4, int direction) { 244 idmap_retcode retcode; 245 idmap_namerule *rule = NULL; 246 idmap_utf8str *str; 247 248 retcode = _udt_extend_batch(udthandle); 249 if (retcode != IDMAP_SUCCESS) 250 goto errout; 251 252 rule = &udthandle->batch. 253 idmap_update_batch_val[udthandle->next]. 254 idmap_update_op_u.rule; 255 rule->is_user = is_user; 256 rule->direction = direction; 257 rule->is_nt4 = is_nt4; 258 if (windomain) { 259 str = &rule->windomain; 260 retcode = idmap_str2utf8(&str, windomain, 0); 261 if (retcode != IDMAP_SUCCESS) 262 goto errout; 263 } 264 if (winname) { 265 str = &rule->winname; 266 retcode = idmap_str2utf8(&str, winname, 0); 267 if (retcode != IDMAP_SUCCESS) 268 goto errout; 269 } 270 if (unixname) { 271 str = &rule->unixname; 272 retcode = idmap_str2utf8(&str, unixname, 0); 273 if (retcode != IDMAP_SUCCESS) 274 goto errout; 275 } 276 277 udthandle->batch.idmap_update_batch_val[udthandle->next].opnum = 278 OP_ADD_NAMERULE; 279 udthandle->next++; 280 return (IDMAP_SUCCESS); 281 282 errout: 283 /* The batch should still be usable */ 284 if (rule) 285 (void) xdr_free(xdr_idmap_namerule, (caddr_t)rule); 286 errno = idmap_stat2errno(retcode); 287 return (retcode); 288 } 289 290 291 /* ARGSUSED */ 292 idmap_stat 293 idmap_udt_rm_namerule(idmap_udt_handle_t *udthandle, boolean_t is_user, 294 const char *windomain, const char *winname, 295 const char *unixname, int direction) { 296 idmap_retcode retcode; 297 idmap_namerule *rule = NULL; 298 idmap_utf8str *str; 299 300 retcode = _udt_extend_batch(udthandle); 301 if (retcode != IDMAP_SUCCESS) 302 goto errout; 303 304 rule = &udthandle->batch. 305 idmap_update_batch_val[udthandle->next]. 306 idmap_update_op_u.rule; 307 rule->is_user = is_user; 308 rule->direction = direction; 309 if (windomain) { 310 str = &rule->windomain; 311 retcode = idmap_str2utf8(&str, windomain, 0); 312 if (retcode != IDMAP_SUCCESS) 313 goto errout; 314 } 315 if (winname) { 316 str = &rule->winname; 317 retcode = idmap_str2utf8(&str, winname, 0); 318 if (retcode != IDMAP_SUCCESS) 319 goto errout; 320 } 321 if (unixname) { 322 str = &rule->unixname; 323 retcode = idmap_str2utf8(&str, unixname, 0); 324 if (retcode != IDMAP_SUCCESS) 325 goto errout; 326 } 327 udthandle->batch.idmap_update_batch_val[udthandle->next].opnum = 328 OP_RM_NAMERULE; 329 udthandle->next++; 330 return (IDMAP_SUCCESS); 331 332 errout: 333 if (rule) 334 (void) xdr_free(xdr_idmap_namerule, (caddr_t)rule); 335 errno = idmap_stat2errno(retcode); 336 return (retcode); 337 } 338 339 340 /* ARGSUSED */ 341 idmap_stat 342 idmap_udt_flush_namerules(idmap_udt_handle_t *udthandle, boolean_t is_user) { 343 idmap_retcode retcode; 344 345 retcode = _udt_extend_batch(udthandle); 346 if (retcode != IDMAP_SUCCESS) 347 goto errout; 348 349 udthandle->batch.idmap_update_batch_val[udthandle->next]. 350 idmap_update_op_u.is_user = is_user; 351 352 udthandle->batch.idmap_update_batch_val[udthandle->next].opnum = 353 OP_FLUSH_NAMERULES; 354 udthandle->next++; 355 return (IDMAP_SUCCESS); 356 357 errout: 358 errno = idmap_stat2errno(retcode); 359 return (retcode); 360 } 361 362 363 /* 364 * Set the number of entries requested per batch by the iterator 365 * 366 * Input: 367 * iter - iterator 368 * limit - number of entries requested per batch 369 */ 370 idmap_stat 371 idmap_iter_set_limit(idmap_iter_t *iter, uint64_t limit) { 372 if (iter == NULL) { 373 errno = EINVAL; 374 return (IDMAP_ERR_ARG); 375 } 376 iter->limit = limit; 377 return (IDMAP_SUCCESS); 378 } 379 380 381 /* 382 * Create iterator to get name-based mapping rules 383 * 384 * Input: 385 * windomain - Windows domain 386 * is_user - user or group rules 387 * winname - Windows user or group name 388 * unixname - Unix user or group name 389 * 390 * Output: 391 * iter - iterator 392 */ 393 idmap_stat 394 idmap_iter_namerules(idmap_handle_t *handle, const char *windomain, 395 boolean_t is_user, const char *winname, 396 const char *unixname, idmap_iter_t **iter) { 397 398 idmap_iter_t *tmpiter; 399 idmap_list_namerules_1_argument *arg = NULL; 400 idmap_namerule *rule; 401 idmap_utf8str *str; 402 idmap_retcode retcode; 403 404 __ITER_CREATE(tmpiter, arg, handle, IDMAP_LIST_NAMERULES); 405 406 rule = &arg->rule; 407 rule->is_user = is_user; 408 rule->direction = IDMAP_DIRECTION_UNDEF; 409 if (windomain) { 410 str = &rule->windomain; 411 retcode = idmap_str2utf8(&str, windomain, 0); 412 if (retcode != IDMAP_SUCCESS) { 413 errno = ENOMEM; 414 goto errout; 415 } 416 } 417 if (winname) { 418 str = &rule->winname; 419 retcode = idmap_str2utf8(&str, winname, 0); 420 if (retcode != IDMAP_SUCCESS) { 421 errno = ENOMEM; 422 goto errout; 423 } 424 } 425 if (unixname) { 426 str = &rule->unixname; 427 retcode = idmap_str2utf8(&str, unixname, 0); 428 if (retcode != IDMAP_SUCCESS) { 429 errno = ENOMEM; 430 goto errout; 431 } 432 } 433 434 *iter = tmpiter; 435 return (IDMAP_SUCCESS); 436 437 errout: 438 __ITER_ERR_RETURN(tmpiter, arg, 439 xdr_idmap_list_namerules_1_argument, retcode); 440 } 441 442 443 /* 444 * Iterate through the name-based mapping rules 445 * 446 * Input: 447 * iter - iterator 448 * 449 * Output: 450 * windomain - Windows domain 451 * winname - Windows user or group name 452 * unixname - Unix user or group name 453 * is_nt4 - NT4 or AD 454 * direction - bi(0), win2unix(1), unix2win(2) 455 * 456 * Return value: 457 * 0 - done 458 * 1 - more results available 459 * < 0 - error 460 */ 461 idmap_stat 462 idmap_iter_next_namerule(idmap_iter_t *iter, char **windomain, 463 char **winname, char **unixname, boolean_t *is_nt4, 464 int *direction) { 465 idmap_namerules_res *namerules; 466 idmap_list_namerules_1_argument *arg; 467 idmap_retcode retcode; 468 469 if (windomain) 470 *windomain = NULL; 471 if (winname) 472 *winname = NULL; 473 if (unixname) 474 *unixname = NULL; 475 if (is_nt4) 476 *is_nt4 = 0; 477 if (direction) 478 *direction = IDMAP_DIRECTION_UNDEF; 479 480 __ITER_CHECK(iter, IDMAP_LIST_NAMERULES); 481 482 namerules = (idmap_namerules_res *)iter->retlist; 483 if (iter->retcode == IDMAP_NEXT && (namerules == NULL || 484 iter->next >= namerules->rules.rules_len)) { 485 486 if ((arg = iter->arg) == NULL) { 487 errno = EINVAL; 488 return (IDMAP_ERR_ARG); 489 } 490 arg->limit = iter->limit; 491 492 retcode = _iter_get_next_list(IDMAP_LIST_NAMERULES, 493 iter, arg, 494 (uchar_t **)&namerules, sizeof (*namerules), 495 (xdrproc_t)xdr_idmap_list_namerules_1_argument, 496 (xdrproc_t)xdr_idmap_namerules_res); 497 if (retcode != IDMAP_SUCCESS) 498 return (retcode); 499 500 if (IDMAP_ERROR(namerules->retcode)) { 501 retcode = namerules->retcode; 502 xdr_free(xdr_idmap_namerules_res, (caddr_t)namerules); 503 free(namerules); 504 iter->retlist = NULL; 505 return (retcode); 506 } 507 iter->retcode = namerules->retcode; 508 arg->lastrowid = namerules->lastrowid; 509 } 510 511 if (namerules == NULL || namerules->rules.rules_len == 0) 512 return (IDMAP_SUCCESS); 513 514 if (iter->next >= namerules->rules.rules_len) { 515 return (IDMAP_ERR_ARG); 516 } 517 518 if (windomain) { 519 retcode = idmap_utf82str(windomain, 0, 520 &namerules->rules.rules_val[iter->next].windomain); 521 if (retcode != IDMAP_SUCCESS) 522 goto errout; 523 } 524 if (winname) { 525 retcode = idmap_utf82str(winname, 0, 526 &namerules->rules.rules_val[iter->next].winname); 527 if (retcode != IDMAP_SUCCESS) 528 goto errout; 529 } 530 if (unixname) { 531 retcode = idmap_utf82str(unixname, 0, 532 &namerules->rules.rules_val[iter->next].unixname); 533 if (retcode != IDMAP_SUCCESS) 534 goto errout; 535 } 536 if (is_nt4) 537 *is_nt4 = namerules->rules.rules_val[iter->next].is_nt4; 538 if (direction) 539 *direction = namerules->rules.rules_val[iter->next].direction; 540 iter->next++; 541 542 if (iter->next == namerules->rules.rules_len) 543 return (iter->retcode); 544 else 545 return (IDMAP_NEXT); 546 547 errout: 548 if (windomain && *windomain) 549 free(*windomain); 550 if (winname && *winname) 551 free(*winname); 552 if (unixname && *unixname) 553 free(*unixname); 554 return (retcode); 555 } 556 557 558 /* 559 * Create iterator to get SID to UID/GID mappings 560 * 561 * Input: 562 * is_user - user or group 563 * 564 * Output: 565 * iter - iterator 566 */ 567 idmap_stat 568 idmap_iter_mappings(idmap_handle_t *handle, boolean_t is_user, 569 idmap_iter_t **iter) { 570 idmap_iter_t *tmpiter; 571 idmap_list_mappings_1_argument *arg = NULL; 572 573 __ITER_CREATE(tmpiter, arg, handle, IDMAP_LIST_MAPPINGS); 574 575 arg->is_user = is_user; 576 *iter = tmpiter; 577 return (IDMAP_SUCCESS); 578 } 579 580 581 /* 582 * Iterate through the SID to UID/GID mappings 583 * 584 * Input: 585 * iter - iterator 586 * 587 * Output: 588 * sid - SID in canonical form 589 * pid - UID or GID 590 * 591 * Return value: 592 * 0 - done 593 * 1 - more results available 594 * < 0 - error 595 */ 596 idmap_stat 597 idmap_iter_next_mapping(idmap_iter_t *iter, char **sidprefix, 598 idmap_rid_t *rid, uid_t *pid, char **winname, 599 char **windomain, char **unixname, int *direction) { 600 idmap_mappings_res *mappings; 601 idmap_list_mappings_1_argument *arg; 602 idmap_retcode retcode; 603 char *str; 604 605 if (sidprefix) 606 *sidprefix = NULL; 607 if (rid) 608 *rid = UINT32_MAX; 609 if (winname) 610 *winname = NULL; 611 if (windomain) 612 *windomain = NULL; 613 if (unixname) 614 *unixname = NULL; 615 if (pid) 616 *pid = UINT32_MAX; 617 if (direction) 618 *direction = IDMAP_DIRECTION_UNDEF; 619 620 __ITER_CHECK(iter, IDMAP_LIST_MAPPINGS); 621 622 mappings = (idmap_mappings_res *)iter->retlist; 623 if (iter->retcode == IDMAP_NEXT && (mappings == NULL || 624 iter->next >= mappings->mappings.mappings_len)) { 625 626 if ((arg = iter->arg) == NULL) { 627 errno = EINVAL; 628 return (IDMAP_ERR_ARG); 629 } 630 arg->limit = iter->limit; 631 632 retcode = _iter_get_next_list(IDMAP_LIST_MAPPINGS, 633 iter, arg, 634 (uchar_t **)&mappings, sizeof (*mappings), 635 (xdrproc_t)xdr_idmap_list_mappings_1_argument, 636 (xdrproc_t)xdr_idmap_mappings_res); 637 if (retcode != IDMAP_SUCCESS) 638 return (retcode); 639 640 if (IDMAP_ERROR(mappings->retcode)) { 641 retcode = mappings->retcode; 642 xdr_free(xdr_idmap_mappings_res, (caddr_t)mappings); 643 free(mappings); 644 iter->retlist = NULL; 645 return (retcode); 646 } 647 iter->retcode = mappings->retcode; 648 arg->lastrowid = mappings->lastrowid; 649 } 650 651 if (mappings == NULL || mappings->mappings.mappings_len == 0) 652 return (IDMAP_SUCCESS); 653 654 if (iter->next >= mappings->mappings.mappings_len) { 655 return (IDMAP_ERR_ARG); 656 } 657 658 if (sidprefix) { 659 str = mappings->mappings.mappings_val[iter->next].id1. 660 idmap_id_u.sid.prefix; 661 if (str && *str != '\0') { 662 *sidprefix = strdup(str); 663 if (*sidprefix == NULL) { 664 retcode = IDMAP_ERR_MEMORY; 665 goto errout; 666 } 667 } 668 } 669 if (rid) 670 *rid = mappings->mappings.mappings_val[iter->next].id1. 671 idmap_id_u.sid.rid; 672 if (winname) { 673 retcode = idmap_utf82str(winname, 0, 674 &mappings->mappings.mappings_val[iter->next].id1name); 675 if (retcode != IDMAP_SUCCESS) 676 goto errout; 677 } 678 if (windomain) { 679 retcode = idmap_utf82str(windomain, 0, 680 &mappings->mappings.mappings_val[iter->next].id1domain); 681 if (retcode != IDMAP_SUCCESS) 682 goto errout; 683 } 684 if (unixname) { 685 retcode = idmap_utf82str(unixname, 0, 686 &mappings->mappings.mappings_val[iter->next].id2name); 687 if (retcode != IDMAP_SUCCESS) 688 goto errout; 689 } 690 if (pid) 691 *pid = mappings->mappings.mappings_val[iter->next].id2. 692 idmap_id_u.uid; 693 if (direction) 694 *direction = mappings->mappings.mappings_val[iter->next]. 695 direction; 696 iter->next++; 697 698 if (iter->next == mappings->mappings.mappings_len) 699 return (iter->retcode); 700 else 701 return (IDMAP_NEXT); 702 703 errout: 704 if (sidprefix && *sidprefix) 705 free(*sidprefix); 706 if (winname && *winname) 707 free(*winname); 708 if (windomain && *windomain) 709 free(*windomain); 710 if (unixname && *unixname) 711 free(*unixname); 712 return (retcode); 713 } 714 715 716 /* 717 * Destroy the iterator 718 */ 719 void 720 idmap_iter_destroy(idmap_iter_t *iter) { 721 xdrproc_t _xdr_argument, _xdr_result; 722 723 if (iter == NULL) 724 return; 725 726 switch (iter->type) { 727 case IDMAP_LIST_NAMERULES: 728 _xdr_argument = (xdrproc_t)xdr_idmap_list_namerules_1_argument; 729 _xdr_result = (xdrproc_t)xdr_idmap_namerules_res; 730 break; 731 case IDMAP_LIST_MAPPINGS: 732 _xdr_argument = (xdrproc_t)xdr_idmap_list_mappings_1_argument; 733 _xdr_result = (xdrproc_t)xdr_idmap_mappings_res; 734 break; 735 default: 736 free(iter); 737 return; 738 }; 739 740 if (iter->arg) { 741 xdr_free(_xdr_argument, (caddr_t)iter->arg); 742 free(iter->arg); 743 } 744 if (iter->retlist) { 745 xdr_free(_xdr_result, (caddr_t)iter->retlist); 746 free(iter->retlist); 747 } 748 free(iter); 749 } 750 751 752 /* 753 * Create handle to get SID to UID/GID mapping entries 754 * 755 * Input: 756 * gh - "get mapping" handle 757 */ 758 idmap_stat 759 idmap_get_create(idmap_handle_t *handle, idmap_get_handle_t **gh) { 760 idmap_get_handle_t *tmp; 761 762 /* sanity checks */ 763 if (handle == NULL || gh == NULL) { 764 errno = EINVAL; 765 return (IDMAP_ERR_ARG); 766 } 767 768 /* allocate the handle */ 769 if ((tmp = calloc(1, sizeof (*tmp))) == NULL) { 770 errno = ENOMEM; 771 return (IDMAP_ERR_MEMORY); 772 } 773 774 tmp->ih = handle; 775 *gh = tmp; 776 return (IDMAP_SUCCESS); 777 } 778 779 780 /* 781 * Given SID, get UID 782 * 783 * Input: 784 * sidprefix - SID prefix 785 * rid - RID 786 * flag - flag 787 * 788 * Output: 789 * stat - status of the get request 790 * uid - POSIX UID if stat = 0 791 * 792 * Note: The output parameters will be set by idmap_get_mappings() 793 */ 794 idmap_stat 795 idmap_get_uidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid, 796 int flag, uid_t *uid, idmap_stat *stat) { 797 798 idmap_retcode retcode; 799 idmap_mapping *mapping = NULL; 800 801 /* sanity checks */ 802 if (gh == NULL) 803 return (IDMAP_ERR_ARG); 804 if (uid == NULL || sidprefix == NULL) 805 return (IDMAP_ERR_ARG); 806 807 /* Extend the request array and the return list */ 808 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS) 809 goto errout; 810 811 /* Setup the request */ 812 mapping = &gh->batch.idmap_mapping_batch_val[gh->next]; 813 mapping->flag = flag; 814 mapping->id1.idtype = IDMAP_SID; 815 mapping->id1.idmap_id_u.sid.rid = rid; 816 if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) { 817 retcode = IDMAP_ERR_MEMORY; 818 goto errout; 819 } 820 mapping->id2.idtype = IDMAP_UID; 821 822 /* Setup pointers for the result */ 823 gh->retlist[gh->next].idtype = IDMAP_UID; 824 gh->retlist[gh->next].uid = uid; 825 gh->retlist[gh->next].stat = stat; 826 827 gh->next++; 828 return (IDMAP_SUCCESS); 829 830 errout: 831 /* Batch created so far should still be usable */ 832 if (mapping) 833 (void) memset(mapping, 0, sizeof (*mapping)); 834 errno = idmap_stat2errno(retcode); 835 return (retcode); 836 } 837 838 839 /* 840 * Given SID, get GID 841 * 842 * Input: 843 * sidprefix - SID prefix 844 * rid - rid 845 * flag - flag 846 * 847 * Output: 848 * stat - status of the get request 849 * gid - POSIX GID if stat = 0 850 * 851 * Note: The output parameters will be set by idmap_get_mappings() 852 */ 853 idmap_stat 854 idmap_get_gidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid, 855 int flag, gid_t *gid, idmap_stat *stat) { 856 857 idmap_retcode retcode; 858 idmap_mapping *mapping = NULL; 859 860 /* sanity checks */ 861 if (gh == NULL) 862 return (IDMAP_ERR_ARG); 863 if (gid == NULL || sidprefix == NULL) 864 return (IDMAP_ERR_ARG); 865 866 /* Extend the request array and the return list */ 867 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS) 868 goto errout; 869 870 /* Setup the request */ 871 mapping = &gh->batch.idmap_mapping_batch_val[gh->next]; 872 mapping->flag = flag; 873 mapping->id1.idtype = IDMAP_SID; 874 mapping->id1.idmap_id_u.sid.rid = rid; 875 if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) { 876 retcode = IDMAP_ERR_MEMORY; 877 goto errout; 878 } 879 mapping->id2.idtype = IDMAP_GID; 880 881 /* Setup pointers for the result */ 882 gh->retlist[gh->next].idtype = IDMAP_GID; 883 gh->retlist[gh->next].gid = gid; 884 gh->retlist[gh->next].stat = stat; 885 886 gh->next++; 887 return (IDMAP_SUCCESS); 888 889 errout: 890 if (mapping) 891 (void) memset(mapping, 0, sizeof (*mapping)); 892 errno = idmap_stat2errno(retcode); 893 return (retcode); 894 } 895 896 897 /* 898 * Given SID, get POSIX ID i.e. UID/GID 899 * 900 * Input: 901 * sidprefix - SID prefix 902 * rid - rid 903 * flag - flag 904 * 905 * Output: 906 * stat - status of the get request 907 * is_user - user or group 908 * pid - POSIX UID if stat = 0 and is_user = 1 909 * POSIX GID if stat = 0 and is_user = 0 910 * 911 * Note: The output parameters will be set by idmap_get_mappings() 912 */ 913 idmap_stat 914 idmap_get_pidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid, 915 int flag, uid_t *pid, int *is_user, idmap_stat *stat) { 916 idmap_retcode retcode; 917 idmap_mapping *mapping = NULL; 918 919 /* sanity checks */ 920 if (gh == NULL) 921 return (IDMAP_ERR_ARG); 922 if (pid == NULL || sidprefix == NULL || is_user == NULL) 923 return (IDMAP_ERR_ARG); 924 925 /* Extend the request array and the return list */ 926 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS) 927 goto errout; 928 929 /* Setup the request */ 930 mapping = &gh->batch.idmap_mapping_batch_val[gh->next]; 931 mapping->flag = flag; 932 mapping->id1.idtype = IDMAP_SID; 933 mapping->id1.idmap_id_u.sid.rid = rid; 934 if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) { 935 retcode = IDMAP_ERR_MEMORY; 936 goto errout; 937 } 938 mapping->id2.idtype = IDMAP_POSIXID; 939 940 /* Setup pointers for the result */ 941 gh->retlist[gh->next].idtype = IDMAP_POSIXID; 942 gh->retlist[gh->next].uid = pid; 943 gh->retlist[gh->next].gid = pid; 944 gh->retlist[gh->next].is_user = is_user; 945 gh->retlist[gh->next].stat = stat; 946 947 gh->next++; 948 return (IDMAP_SUCCESS); 949 950 errout: 951 if (mapping) 952 (void) memset(mapping, 0, sizeof (*mapping)); 953 errno = idmap_stat2errno(retcode); 954 return (retcode); 955 } 956 957 958 /* 959 * Given UID, get SID 960 * 961 * Input: 962 * uid - POSIX UID 963 * flag - flag 964 * 965 * Output: 966 * stat - status of the get request 967 * sid - SID prefix (if stat == 0) 968 * rid - rid 969 * 970 * Note: The output parameters will be set by idmap_get_mappings() 971 */ 972 idmap_stat 973 idmap_get_sidbyuid(idmap_get_handle_t *gh, uid_t uid, int flag, 974 char **sidprefix, idmap_rid_t *rid, idmap_stat *stat) { 975 976 idmap_retcode retcode; 977 idmap_mapping *mapping = NULL; 978 979 /* sanity checks */ 980 if (gh == NULL) 981 return (IDMAP_ERR_ARG); 982 if (sidprefix == NULL) 983 return (IDMAP_ERR_ARG); 984 985 /* Extend the request array and the return list */ 986 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS) 987 goto errout; 988 989 /* Setup the request */ 990 mapping = &gh->batch.idmap_mapping_batch_val[gh->next]; 991 mapping->flag = flag; 992 mapping->id1.idtype = IDMAP_UID; 993 mapping->id1.idmap_id_u.uid = uid; 994 mapping->id2.idtype = IDMAP_SID; 995 996 /* Setup pointers for the result */ 997 gh->retlist[gh->next].idtype = IDMAP_SID; 998 gh->retlist[gh->next].sidprefix = sidprefix; 999 gh->retlist[gh->next].rid = rid; 1000 gh->retlist[gh->next].stat = stat; 1001 1002 gh->next++; 1003 return (IDMAP_SUCCESS); 1004 1005 errout: 1006 if (mapping) 1007 (void) memset(mapping, 0, sizeof (*mapping)); 1008 errno = idmap_stat2errno(retcode); 1009 return (retcode); 1010 } 1011 1012 1013 /* 1014 * Given GID, get SID 1015 * 1016 * Input: 1017 * gid - POSIX GID 1018 * flag - flag 1019 * 1020 * Output: 1021 * stat - status of the get request 1022 * sidprefix - SID prefix (if stat == 0) 1023 * rid - rid 1024 * 1025 * Note: The output parameters will be set by idmap_get_mappings() 1026 */ 1027 idmap_stat 1028 idmap_get_sidbygid(idmap_get_handle_t *gh, gid_t gid, int flag, 1029 char **sidprefix, idmap_rid_t *rid, idmap_stat *stat) { 1030 1031 idmap_retcode retcode; 1032 idmap_mapping *mapping = NULL; 1033 1034 /* sanity checks */ 1035 if (gh == NULL) 1036 return (IDMAP_ERR_ARG); 1037 if (sidprefix == NULL) 1038 return (IDMAP_ERR_ARG); 1039 1040 /* Extend the request array and the return list */ 1041 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS) 1042 goto errout; 1043 1044 /* Setup the request */ 1045 mapping = &gh->batch.idmap_mapping_batch_val[gh->next]; 1046 mapping->flag = flag; 1047 mapping->id1.idtype = IDMAP_GID; 1048 mapping->id1.idmap_id_u.gid = gid; 1049 mapping->id2.idtype = IDMAP_SID; 1050 1051 /* Setup pointers for the result */ 1052 gh->retlist[gh->next].idtype = IDMAP_SID; 1053 gh->retlist[gh->next].sidprefix = sidprefix; 1054 gh->retlist[gh->next].rid = rid; 1055 gh->retlist[gh->next].stat = stat; 1056 1057 gh->next++; 1058 return (IDMAP_SUCCESS); 1059 1060 errout: 1061 if (mapping) 1062 (void) memset(mapping, 0, sizeof (*mapping)); 1063 errno = idmap_stat2errno(retcode); 1064 return (retcode); 1065 } 1066 1067 1068 /* 1069 * Process the batched "get mapping" requests. The results (i.e. 1070 * status and identity) will be available in the data areas 1071 * provided by individual requests. 1072 */ 1073 idmap_stat 1074 idmap_get_mappings(idmap_get_handle_t *gh) { 1075 CLIENT *clnt; 1076 enum clnt_stat clntstat; 1077 idmap_retcode retcode; 1078 idmap_ids_res res; 1079 idmap_id *id; 1080 int i; 1081 1082 if (gh == NULL) { 1083 errno = EINVAL; 1084 return (IDMAP_ERR_ARG); 1085 } 1086 _IDMAP_GET_CLIENT_HANDLE(gh->ih, clnt); 1087 1088 (void) memset(&res, 0, sizeof (idmap_ids_res)); 1089 clntstat = clnt_call(clnt, IDMAP_GET_MAPPED_IDS, 1090 (xdrproc_t)xdr_idmap_mapping_batch, 1091 (caddr_t)&gh->batch, 1092 (xdrproc_t)xdr_idmap_ids_res, 1093 (caddr_t)&res, 1094 TIMEOUT); 1095 if (clntstat != RPC_SUCCESS) { 1096 retcode = _idmap_rpc2stat(clnt); 1097 goto out; 1098 } 1099 if (res.retcode != IDMAP_SUCCESS) { 1100 retcode = res.retcode; 1101 goto out; 1102 } 1103 for (i = 0; i < gh->next; i++) { 1104 if (i >= res.ids.ids_len) { 1105 *gh->retlist[i].stat = IDMAP_ERR_NORESULT; 1106 continue; 1107 } 1108 *gh->retlist[i].stat = res.ids.ids_val[i].retcode; 1109 id = &res.ids.ids_val[i].id; 1110 switch (id->idtype) { 1111 case IDMAP_UID: 1112 if (gh->retlist[i].uid) 1113 *gh->retlist[i].uid = id->idmap_id_u.uid; 1114 if (gh->retlist[i].is_user) 1115 *gh->retlist[i].is_user = 1; 1116 break; 1117 case IDMAP_GID: 1118 if (gh->retlist[i].gid) 1119 *gh->retlist[i].gid = id->idmap_id_u.gid; 1120 if (gh->retlist[i].is_user) 1121 *gh->retlist[i].is_user = 0; 1122 break; 1123 case IDMAP_SID: 1124 if (gh->retlist[i].rid) 1125 *gh->retlist[i].rid = id->idmap_id_u.sid.rid; 1126 if (gh->retlist[i].sidprefix) { 1127 if (id->idmap_id_u.sid.prefix == NULL || 1128 *id->idmap_id_u.sid.prefix == '\0') { 1129 *gh->retlist[i].sidprefix = NULL; 1130 break; 1131 } 1132 *gh->retlist[i].sidprefix = 1133 strdup(id->idmap_id_u.sid.prefix); 1134 if (*gh->retlist[i].sidprefix == NULL) 1135 *gh->retlist[i].stat = 1136 IDMAP_ERR_MEMORY; 1137 } 1138 break; 1139 case IDMAP_NONE: 1140 break; 1141 default: 1142 *gh->retlist[i].stat = IDMAP_ERR_NORESULT; 1143 break; 1144 } 1145 } 1146 retcode = IDMAP_SUCCESS; 1147 1148 out: 1149 _IDMAP_RESET_GET_HANDLE(gh); 1150 (void) xdr_free(xdr_idmap_ids_res, (caddr_t)&res); 1151 errno = idmap_stat2errno(retcode); 1152 return (retcode); 1153 } 1154 1155 1156 /* 1157 * Destroy the "get mapping" handle 1158 */ 1159 void 1160 idmap_get_destroy(idmap_get_handle_t *gh) { 1161 if (gh == NULL) 1162 return; 1163 (void) xdr_free(xdr_idmap_mapping_batch, (caddr_t)&gh->batch); 1164 if (gh->retlist) 1165 free(gh->retlist); 1166 free(gh); 1167 } 1168 1169 1170 /* 1171 * Get windows to unix mapping 1172 */ 1173 idmap_stat 1174 idmap_get_w2u_mapping(idmap_handle_t *handle, 1175 const char *sidprefix, idmap_rid_t *rid, 1176 const char *winname, const char *windomain, 1177 int flag, int *is_user, 1178 uid_t *pid, char **unixname, int *direction) { 1179 CLIENT *clnt; 1180 enum clnt_stat clntstat; 1181 idmap_mapping request, *mapping; 1182 idmap_mappings_res result; 1183 idmap_retcode retcode, rc; 1184 idmap_utf8str *str; 1185 1186 if (handle == NULL) { 1187 errno = EINVAL; 1188 return (IDMAP_ERR_ARG); 1189 } 1190 1191 _IDMAP_GET_CLIENT_HANDLE(handle, clnt); 1192 1193 (void) memset(&request, 0, sizeof (request)); 1194 (void) memset(&result, 0, sizeof (result)); 1195 1196 if (pid) 1197 *pid = UINT32_MAX; 1198 if (unixname) 1199 *unixname = NULL; 1200 if (direction) 1201 *direction = IDMAP_DIRECTION_UNDEF; 1202 1203 request.flag = flag; 1204 request.id1.idtype = IDMAP_SID; 1205 if (sidprefix && rid) { 1206 request.id1.idmap_id_u.sid.prefix = (char *)sidprefix; 1207 request.id1.idmap_id_u.sid.rid = *rid; 1208 } else if (winname) { 1209 str = &request.id1name; 1210 retcode = idmap_str2utf8(&str, winname, 1); 1211 if (retcode != IDMAP_SUCCESS) 1212 goto out; 1213 if (windomain) { 1214 str = &request.id1domain; 1215 retcode = idmap_str2utf8(&str, windomain, 1); 1216 if (retcode != IDMAP_SUCCESS) 1217 return (retcode); 1218 } 1219 request.id1.idmap_id_u.sid.prefix = NULL; 1220 } else { 1221 errno = EINVAL; 1222 return (IDMAP_ERR_ARG); 1223 } 1224 1225 if (is_user == NULL) 1226 request.id2.idtype = IDMAP_POSIXID; 1227 else if (*is_user == 1) 1228 request.id2.idtype = IDMAP_UID; 1229 else if (*is_user == 0) 1230 request.id2.idtype = IDMAP_GID; 1231 else 1232 request.id2.idtype = IDMAP_POSIXID; 1233 1234 clntstat = clnt_call(clnt, IDMAP_GET_MAPPED_ID_BY_NAME, 1235 (xdrproc_t)xdr_idmap_mapping, (caddr_t)&request, 1236 (xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result, 1237 TIMEOUT); 1238 1239 if (clntstat != RPC_SUCCESS) 1240 return (_idmap_rpc2stat(clnt)); 1241 1242 retcode = result.retcode; 1243 1244 if ((mapping = result.mappings.mappings_val) == NULL) { 1245 if (retcode == IDMAP_SUCCESS) 1246 retcode = IDMAP_ERR_NORESULT; 1247 goto out; 1248 } 1249 1250 if (is_user) 1251 *is_user = (mapping->id2.idtype == IDMAP_UID)?1:0; 1252 if (direction) 1253 *direction = mapping->direction; 1254 if (pid) 1255 *pid = mapping->id2.idmap_id_u.uid; 1256 if (unixname) { 1257 rc = idmap_utf82str(unixname, 0, &mapping->id2name); 1258 if (rc != IDMAP_SUCCESS) 1259 retcode = rc; 1260 } 1261 1262 out: 1263 xdr_free(xdr_idmap_mappings_res, (caddr_t)&result); 1264 if (retcode != IDMAP_SUCCESS) 1265 errno = idmap_stat2errno(retcode); 1266 return (retcode); 1267 } 1268 1269 1270 /* 1271 * Get unix to windows mapping 1272 */ 1273 idmap_stat 1274 idmap_get_u2w_mapping(idmap_handle_t *handle, 1275 uid_t *pid, const char *unixname, 1276 int flag, int is_user, 1277 char **sidprefix, idmap_rid_t *rid, 1278 char **winname, char **windomain, 1279 int *direction) { 1280 CLIENT *clnt; 1281 enum clnt_stat clntstat; 1282 idmap_mapping request, *mapping; 1283 idmap_mappings_res result; 1284 idmap_retcode retcode, rc; 1285 idmap_utf8str *str; 1286 1287 if (handle == NULL) { 1288 errno = EINVAL; 1289 return (IDMAP_ERR_ARG); 1290 } 1291 1292 _IDMAP_GET_CLIENT_HANDLE(handle, clnt); 1293 1294 if (sidprefix) 1295 *sidprefix = NULL; 1296 if (winname) 1297 *winname = NULL; 1298 if (windomain) 1299 *windomain = NULL; 1300 if (rid) 1301 *rid = UINT32_MAX; 1302 if (direction) 1303 *direction = IDMAP_DIRECTION_UNDEF; 1304 1305 (void) memset(&request, 0, sizeof (request)); 1306 (void) memset(&result, 0, sizeof (result)); 1307 1308 request.flag = flag; 1309 request.id1.idtype = is_user?IDMAP_UID:IDMAP_GID; 1310 1311 if (pid && *pid != UINT32_MAX) { 1312 request.id1.idmap_id_u.uid = *pid; 1313 } else if (unixname) { 1314 str = &request.id1name; 1315 retcode = idmap_str2utf8(&str, unixname, 1); 1316 if (retcode != IDMAP_SUCCESS) 1317 goto out; 1318 request.id1.idmap_id_u.uid = UINT32_MAX; 1319 } else { 1320 errno = EINVAL; 1321 return (IDMAP_ERR_ARG); 1322 } 1323 1324 request.id2.idtype = IDMAP_SID; 1325 1326 clntstat = clnt_call(clnt, IDMAP_GET_MAPPED_ID_BY_NAME, 1327 (xdrproc_t)xdr_idmap_mapping, (caddr_t)&request, 1328 (xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result, 1329 TIMEOUT); 1330 1331 if (clntstat != RPC_SUCCESS) 1332 return (_idmap_rpc2stat(clnt)); 1333 1334 retcode = result.retcode; 1335 1336 if ((mapping = result.mappings.mappings_val) == NULL) { 1337 if (retcode == IDMAP_SUCCESS) 1338 retcode = IDMAP_ERR_NORESULT; 1339 goto out; 1340 } 1341 1342 if (direction) 1343 *direction = mapping->direction; 1344 if (sidprefix && mapping->id2.idmap_id_u.sid.prefix && 1345 *mapping->id2.idmap_id_u.sid.prefix != '\0') { 1346 *sidprefix = strdup(mapping->id2.idmap_id_u.sid.prefix); 1347 if (*sidprefix == NULL) { 1348 retcode = IDMAP_ERR_MEMORY; 1349 goto errout; 1350 } 1351 } 1352 if (rid) 1353 *rid = mapping->id2.idmap_id_u.sid.rid; 1354 if (winname) { 1355 rc = idmap_utf82str(winname, 0, &mapping->id2name); 1356 if (rc != IDMAP_SUCCESS) { 1357 retcode = rc; 1358 goto errout; 1359 } 1360 } 1361 if (windomain) { 1362 rc = idmap_utf82str(windomain, 0, &mapping->id2domain); 1363 if (rc != IDMAP_SUCCESS) { 1364 retcode = rc; 1365 goto errout; 1366 } 1367 } 1368 1369 goto out; 1370 1371 errout: 1372 if (sidprefix && *sidprefix) { 1373 free(*sidprefix); 1374 *sidprefix = NULL; 1375 } 1376 if (winname && *winname) { 1377 free(*winname); 1378 *winname = NULL; 1379 } 1380 if (windomain && *windomain) { 1381 free(*windomain); 1382 *windomain = NULL; 1383 } 1384 1385 out: 1386 xdr_free(xdr_idmap_mappings_res, (caddr_t)&result); 1387 if (retcode != IDMAP_SUCCESS) 1388 errno = idmap_stat2errno(retcode); 1389 return (retcode); 1390 } 1391 1392 1393 /* 1394 * utf8str to string 1395 */ 1396 idmap_stat 1397 idmap_utf82str(char **out, size_t outsize, idmap_utf8str *in) { 1398 int len; 1399 1400 if (in == NULL || out == NULL) 1401 return (IDMAP_ERR_ARG); 1402 1403 if (outsize == 0) { 1404 *out = NULL; 1405 if ((len = in->idmap_utf8str_len) == 0) 1406 return (IDMAP_SUCCESS); 1407 if (in->idmap_utf8str_val == NULL) 1408 return (IDMAP_ERR_ARG); 1409 if (in->idmap_utf8str_val[len - 1] != '\0') 1410 len++; 1411 *out = calloc(1, len); 1412 if (*out == NULL) 1413 return (IDMAP_ERR_MEMORY); 1414 } else { 1415 if (*out == NULL) 1416 return (IDMAP_ERR_ARG); 1417 (void) memset(*out, 0, outsize); 1418 if ((len = in->idmap_utf8str_len) == 0) 1419 return (IDMAP_SUCCESS); 1420 if (in->idmap_utf8str_val == NULL) 1421 return (IDMAP_ERR_ARG); 1422 if (in->idmap_utf8str_val[len - 1] != '\0') 1423 len++; 1424 if (outsize < len) 1425 return (IDMAP_ERR_ARG); 1426 } 1427 (void) memcpy(*out, in->idmap_utf8str_val, in->idmap_utf8str_len); 1428 return (IDMAP_SUCCESS); 1429 } 1430 1431 1432 /* 1433 * string to utf8str 1434 */ 1435 idmap_stat 1436 idmap_str2utf8(idmap_utf8str **out, const char *in, int flag) { 1437 idmap_utf8str *tmp; 1438 1439 if (out == NULL) 1440 return (IDMAP_ERR_ARG); 1441 else if (*out == NULL) { 1442 tmp = malloc(sizeof (idmap_utf8str)); 1443 if (tmp == NULL) 1444 return (IDMAP_ERR_MEMORY); 1445 } else { 1446 tmp = *out; 1447 } 1448 1449 if (in == NULL) { 1450 tmp->idmap_utf8str_len = 0; 1451 tmp->idmap_utf8str_val = NULL; 1452 if (*out == NULL) 1453 *out = tmp; 1454 return (IDMAP_SUCCESS); 1455 } 1456 1457 /* include the null terminator */ 1458 tmp->idmap_utf8str_len = strlen(in) + 1; 1459 1460 if (flag == 1) { 1461 /* Don't malloc, simply assign */ 1462 tmp->idmap_utf8str_val = (char *)in; 1463 if (*out == NULL) 1464 *out = tmp; 1465 return (IDMAP_SUCCESS); 1466 } 1467 1468 tmp->idmap_utf8str_val = malloc(tmp->idmap_utf8str_len); 1469 if (tmp->idmap_utf8str_val == NULL) { 1470 tmp->idmap_utf8str_len = 0; 1471 if (*out == NULL) 1472 free(tmp); 1473 return (IDMAP_ERR_MEMORY); 1474 } 1475 (void) memcpy(tmp->idmap_utf8str_val, in, tmp->idmap_utf8str_len); 1476 if (*out == NULL) 1477 *out = tmp; 1478 return (IDMAP_SUCCESS); 1479 } 1480 1481 1482 #define gettext(s) s 1483 static stat_table_t stattable[] = { 1484 {IDMAP_SUCCESS, gettext("Success"), 0}, 1485 {IDMAP_NEXT, gettext("More results available"), 0}, 1486 {IDMAP_ERR_OTHER, gettext("Undefined error"), EINVAL}, 1487 {IDMAP_ERR_INTERNAL, gettext("Internal error"), EINVAL}, 1488 {IDMAP_ERR_MEMORY, gettext("Out of memory"), ENOMEM}, 1489 {IDMAP_ERR_NORESULT, gettext("No results available"), EINVAL}, 1490 {IDMAP_ERR_NOTUSER, gettext("Not a user"), EINVAL}, 1491 {IDMAP_ERR_NOTGROUP, gettext("Not a group"), EINVAL}, 1492 {IDMAP_ERR_NOTSUPPORTED, gettext("Operation not supported"), ENOTSUP}, 1493 {IDMAP_ERR_W2U_NAMERULE, 1494 gettext("Invalid Windows to UNIX name-based rule"), EINVAL}, 1495 {IDMAP_ERR_U2W_NAMERULE, 1496 gettext("Invalid UNIX to Windows name-based rule"), EINVAL}, 1497 {IDMAP_ERR_CACHE, gettext("Invalid cache"), EINVAL}, 1498 {IDMAP_ERR_DB, gettext("Invalid database"), EINVAL}, 1499 {IDMAP_ERR_ARG, gettext("Invalid argument"), EINVAL}, 1500 {IDMAP_ERR_SID, gettext("Invalid SID"), EINVAL}, 1501 {IDMAP_ERR_IDTYPE, gettext("Invalid identity type"), EINVAL}, 1502 {IDMAP_ERR_RPC_HANDLE, gettext("Bad RPC handle"), EBADF}, 1503 {IDMAP_ERR_RPC, gettext("RPC error"), EINVAL}, 1504 {IDMAP_ERR_CLIENT_HANDLE, gettext("Bad client handle"), EINVAL}, 1505 {IDMAP_ERR_BUSY, gettext("Server is busy"), EBUSY}, 1506 {IDMAP_ERR_PERMISSION_DENIED, gettext("Permission denied"), EACCES}, 1507 {IDMAP_ERR_NOMAPPING, 1508 gettext("Mapping not found or inhibited"), EINVAL}, 1509 {IDMAP_ERR_NEW_ID_ALLOC_REQD, 1510 gettext("New mapping needs to be created"), EINVAL}, 1511 {IDMAP_ERR_DOMAIN, gettext("Invalid domain"), EINVAL}, 1512 {IDMAP_ERR_SECURITY, gettext("Security issue"), EINVAL}, 1513 {IDMAP_ERR_NOTFOUND, gettext("Not found"), EINVAL}, 1514 {IDMAP_ERR_DOMAIN_NOTFOUND, gettext("Domain not found"), EINVAL}, 1515 {IDMAP_ERR_UPDATE_NOTALLOWED, gettext("Update not allowed"), EINVAL}, 1516 {IDMAP_ERR_CFG, gettext("Configuration error"), EINVAL}, 1517 {IDMAP_ERR_CFG_CHANGE, gettext("Invalid configuration change"), EINVAL}, 1518 {IDMAP_ERR_NOTMAPPED_WELLKNOWN, 1519 gettext("No mapping for well-known SID"), EINVAL}, 1520 {IDMAP_ERR_RETRIABLE_NET_ERR, 1521 gettext("Network error"), EINVAL}, 1522 {-1, NULL, 0} 1523 }; 1524 #undef gettext 1525 1526 1527 /* 1528 * Get description of status code 1529 * 1530 * Input: 1531 * status - Status code returned by libidmap API call 1532 * 1533 * Return Value: 1534 * human-readable localized description of idmap_stat 1535 */ 1536 /* ARGSUSED */ 1537 const char * 1538 idmap_stat2string(idmap_handle_t *handle, idmap_stat status) { 1539 int i; 1540 1541 for (i = 0; stattable[i].msg; i++) { 1542 if (stattable[i].retcode == status) 1543 return (gettext(stattable[i].msg)); 1544 } 1545 return (gettext("Unknown error")); 1546 } 1547 1548 1549 static int 1550 idmap_stat2errno(idmap_stat stat) { 1551 int i; 1552 for (i = 0; stattable[i].msg; i++) { 1553 if (stattable[i].retcode == stat) 1554 return (stattable[i].errnum); 1555 } 1556 return (EINVAL); 1557 } 1558 1559 1560 /* 1561 * Get status code from string 1562 */ 1563 idmap_stat 1564 idmap_string2stat(const char *str) { 1565 if (str == NULL) 1566 return (IDMAP_ERR_INTERNAL); 1567 1568 #define return_cmp(a) \ 1569 if (0 == strcmp(str, "IDMAP_ERR_" #a)) \ 1570 return (IDMAP_ERR_ ## a); 1571 1572 return_cmp(OTHER); 1573 return_cmp(INTERNAL); 1574 return_cmp(MEMORY); 1575 return_cmp(NORESULT); 1576 return_cmp(NOTUSER); 1577 return_cmp(NOTGROUP); 1578 return_cmp(NOTSUPPORTED); 1579 return_cmp(W2U_NAMERULE); 1580 return_cmp(U2W_NAMERULE); 1581 return_cmp(CACHE); 1582 return_cmp(DB); 1583 return_cmp(ARG); 1584 return_cmp(SID); 1585 return_cmp(IDTYPE); 1586 return_cmp(RPC_HANDLE); 1587 return_cmp(RPC); 1588 return_cmp(CLIENT_HANDLE); 1589 return_cmp(BUSY); 1590 return_cmp(PERMISSION_DENIED); 1591 return_cmp(NOMAPPING); 1592 return_cmp(NEW_ID_ALLOC_REQD); 1593 return_cmp(DOMAIN); 1594 return_cmp(SECURITY); 1595 return_cmp(NOTFOUND); 1596 return_cmp(DOMAIN_NOTFOUND); 1597 return_cmp(MEMORY); 1598 return_cmp(UPDATE_NOTALLOWED); 1599 return_cmp(CFG); 1600 return_cmp(CFG_CHANGE); 1601 return_cmp(NOTMAPPED_WELLKNOWN); 1602 return_cmp(RETRIABLE_NET_ERR); 1603 #undef return_cmp 1604 1605 return (IDMAP_ERR_OTHER); 1606 } 1607 1608 1609 /* 1610 * Map the given status to one that can be returned by the protocol 1611 */ 1612 idmap_stat 1613 idmap_stat4prot(idmap_stat status) { 1614 switch (status) { 1615 case IDMAP_ERR_MEMORY: 1616 case IDMAP_ERR_CACHE: 1617 return (IDMAP_ERR_INTERNAL); 1618 } 1619 return (status); 1620 } 1621