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) { 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 *gh->retlist[i].sidprefix = NULL; 1129 break; 1130 } 1131 *gh->retlist[i].sidprefix = 1132 strdup(id->idmap_id_u.sid.prefix); 1133 if (*gh->retlist[i].sidprefix == NULL) 1134 *gh->retlist[i].stat = 1135 IDMAP_ERR_MEMORY; 1136 } 1137 break; 1138 case IDMAP_NONE: 1139 break; 1140 default: 1141 *gh->retlist[i].stat = IDMAP_ERR_NORESULT; 1142 break; 1143 } 1144 } 1145 retcode = IDMAP_SUCCESS; 1146 1147 out: 1148 _IDMAP_RESET_GET_HANDLE(gh); 1149 (void) xdr_free(xdr_idmap_ids_res, (caddr_t)&res); 1150 errno = idmap_stat2errno(retcode); 1151 return (retcode); 1152 } 1153 1154 1155 /* 1156 * Destroy the "get mapping" handle 1157 */ 1158 void 1159 idmap_get_destroy(idmap_get_handle_t *gh) { 1160 if (gh == NULL) 1161 return; 1162 (void) xdr_free(xdr_idmap_mapping_batch, (caddr_t)&gh->batch); 1163 if (gh->retlist) 1164 free(gh->retlist); 1165 free(gh); 1166 } 1167 1168 1169 /* 1170 * Get windows to unix mapping 1171 */ 1172 idmap_stat 1173 idmap_get_w2u_mapping(idmap_handle_t *handle, 1174 const char *sidprefix, idmap_rid_t *rid, 1175 const char *winname, const char *windomain, 1176 int flag, int *is_user, 1177 uid_t *pid, char **unixname, int *direction) { 1178 CLIENT *clnt; 1179 enum clnt_stat clntstat; 1180 idmap_mapping request, *mapping; 1181 idmap_mappings_res result; 1182 idmap_retcode retcode, rc; 1183 idmap_utf8str *str; 1184 1185 if (handle == NULL) { 1186 errno = EINVAL; 1187 return (IDMAP_ERR_ARG); 1188 } 1189 1190 _IDMAP_GET_CLIENT_HANDLE(handle, clnt); 1191 1192 (void) memset(&request, 0, sizeof (request)); 1193 (void) memset(&result, 0, sizeof (result)); 1194 1195 if (pid) 1196 *pid = UINT32_MAX; 1197 if (unixname) 1198 *unixname = NULL; 1199 if (direction) 1200 *direction = IDMAP_DIRECTION_UNDEF; 1201 1202 request.flag = flag; 1203 request.id1.idtype = IDMAP_SID; 1204 if (sidprefix && rid) { 1205 request.id1.idmap_id_u.sid.prefix = (char *)sidprefix; 1206 request.id1.idmap_id_u.sid.rid = *rid; 1207 } else if (winname) { 1208 str = &request.id1name; 1209 retcode = idmap_str2utf8(&str, winname, 1); 1210 if (retcode != IDMAP_SUCCESS) 1211 goto out; 1212 if (windomain) { 1213 str = &request.id1domain; 1214 retcode = idmap_str2utf8(&str, windomain, 1); 1215 if (retcode != IDMAP_SUCCESS) 1216 return (retcode); 1217 } 1218 request.id1.idmap_id_u.sid.prefix = NULL; 1219 } else { 1220 errno = EINVAL; 1221 return (IDMAP_ERR_ARG); 1222 } 1223 1224 if (is_user == NULL) 1225 request.id2.idtype = IDMAP_POSIXID; 1226 else if (*is_user == 1) 1227 request.id2.idtype = IDMAP_UID; 1228 else if (*is_user == 0) 1229 request.id2.idtype = IDMAP_GID; 1230 else 1231 request.id2.idtype = IDMAP_POSIXID; 1232 1233 clntstat = clnt_call(clnt, IDMAP_GET_MAPPED_ID_BY_NAME, 1234 (xdrproc_t)xdr_idmap_mapping, (caddr_t)&request, 1235 (xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result, 1236 TIMEOUT); 1237 1238 if (clntstat != RPC_SUCCESS) 1239 return (_idmap_rpc2stat(clnt)); 1240 1241 retcode = result.retcode; 1242 1243 if ((mapping = result.mappings.mappings_val) == NULL) { 1244 if (retcode == IDMAP_SUCCESS) 1245 retcode = IDMAP_ERR_NORESULT; 1246 goto out; 1247 } 1248 1249 if (is_user) 1250 *is_user = (mapping->id2.idtype == IDMAP_UID)?1:0; 1251 if (direction) 1252 *direction = mapping->direction; 1253 if (pid) 1254 *pid = mapping->id2.idmap_id_u.uid; 1255 if (unixname) { 1256 rc = idmap_utf82str(unixname, 0, &mapping->id2name); 1257 if (rc != IDMAP_SUCCESS) 1258 retcode = rc; 1259 } 1260 1261 out: 1262 xdr_free(xdr_idmap_mappings_res, (caddr_t)&result); 1263 if (retcode != IDMAP_SUCCESS) 1264 errno = idmap_stat2errno(retcode); 1265 return (retcode); 1266 } 1267 1268 1269 /* 1270 * Get unix to windows mapping 1271 */ 1272 idmap_stat 1273 idmap_get_u2w_mapping(idmap_handle_t *handle, 1274 uid_t *pid, const char *unixname, 1275 int flag, int is_user, 1276 char **sidprefix, idmap_rid_t *rid, 1277 char **winname, char **windomain, 1278 int *direction) { 1279 CLIENT *clnt; 1280 enum clnt_stat clntstat; 1281 idmap_mapping request, *mapping; 1282 idmap_mappings_res result; 1283 idmap_retcode retcode, rc; 1284 idmap_utf8str *str; 1285 1286 if (handle == NULL) { 1287 errno = EINVAL; 1288 return (IDMAP_ERR_ARG); 1289 } 1290 1291 _IDMAP_GET_CLIENT_HANDLE(handle, clnt); 1292 1293 if (sidprefix) 1294 *sidprefix = NULL; 1295 if (winname) 1296 *winname = NULL; 1297 if (windomain) 1298 *windomain = NULL; 1299 if (rid) 1300 *rid = UINT32_MAX; 1301 if (direction) 1302 *direction = IDMAP_DIRECTION_UNDEF; 1303 1304 (void) memset(&request, 0, sizeof (request)); 1305 (void) memset(&result, 0, sizeof (result)); 1306 1307 request.flag = flag; 1308 request.id1.idtype = is_user?IDMAP_UID:IDMAP_GID; 1309 1310 if (pid && *pid != UINT32_MAX) { 1311 request.id1.idmap_id_u.uid = *pid; 1312 } else if (unixname) { 1313 str = &request.id1name; 1314 retcode = idmap_str2utf8(&str, unixname, 1); 1315 if (retcode != IDMAP_SUCCESS) 1316 goto out; 1317 request.id1.idmap_id_u.uid = UINT32_MAX; 1318 } else { 1319 errno = EINVAL; 1320 return (IDMAP_ERR_ARG); 1321 } 1322 1323 request.id2.idtype = IDMAP_SID; 1324 1325 clntstat = clnt_call(clnt, IDMAP_GET_MAPPED_ID_BY_NAME, 1326 (xdrproc_t)xdr_idmap_mapping, (caddr_t)&request, 1327 (xdrproc_t)xdr_idmap_mappings_res, (caddr_t)&result, 1328 TIMEOUT); 1329 1330 if (clntstat != RPC_SUCCESS) 1331 return (_idmap_rpc2stat(clnt)); 1332 1333 retcode = result.retcode; 1334 1335 if ((mapping = result.mappings.mappings_val) == NULL) { 1336 if (retcode == IDMAP_SUCCESS) 1337 retcode = IDMAP_ERR_NORESULT; 1338 goto out; 1339 } 1340 1341 if (direction) 1342 *direction = mapping->direction; 1343 if (sidprefix && mapping->id2.idmap_id_u.sid.prefix) { 1344 *sidprefix = strdup(mapping->id2.idmap_id_u.sid.prefix); 1345 if (*sidprefix == NULL) { 1346 retcode = IDMAP_ERR_MEMORY; 1347 goto errout; 1348 } 1349 } 1350 if (rid) 1351 *rid = mapping->id2.idmap_id_u.sid.rid; 1352 if (winname) { 1353 rc = idmap_utf82str(winname, 0, &mapping->id2name); 1354 if (rc != IDMAP_SUCCESS) { 1355 retcode = rc; 1356 goto errout; 1357 } 1358 } 1359 if (windomain) { 1360 rc = idmap_utf82str(windomain, 0, &mapping->id2domain); 1361 if (rc != IDMAP_SUCCESS) { 1362 retcode = rc; 1363 goto errout; 1364 } 1365 } 1366 1367 goto out; 1368 1369 errout: 1370 if (sidprefix && *sidprefix) { 1371 free(*sidprefix); 1372 *sidprefix = NULL; 1373 } 1374 if (winname && *winname) { 1375 free(*winname); 1376 *winname = NULL; 1377 } 1378 if (windomain && *windomain) { 1379 free(*windomain); 1380 *windomain = NULL; 1381 } 1382 1383 out: 1384 xdr_free(xdr_idmap_mappings_res, (caddr_t)&result); 1385 if (retcode != IDMAP_SUCCESS) 1386 errno = idmap_stat2errno(retcode); 1387 return (retcode); 1388 } 1389 1390 1391 /* 1392 * utf8str to string 1393 */ 1394 idmap_stat 1395 idmap_utf82str(char **out, size_t outsize, idmap_utf8str *in) { 1396 int len; 1397 1398 if (in == NULL || out == NULL) 1399 return (IDMAP_ERR_ARG); 1400 1401 if (outsize == 0) { 1402 *out = NULL; 1403 if ((len = in->idmap_utf8str_len) == 0) 1404 return (IDMAP_SUCCESS); 1405 if (in->idmap_utf8str_val == NULL) 1406 return (IDMAP_ERR_ARG); 1407 if (in->idmap_utf8str_val[len - 1] != 0) 1408 len++; 1409 *out = calloc(1, len); 1410 if (*out == NULL) 1411 return (IDMAP_ERR_MEMORY); 1412 } else { 1413 if (*out == NULL) 1414 return (IDMAP_ERR_ARG); 1415 (void) memset(*out, 0, outsize); 1416 if ((len = in->idmap_utf8str_len) == 0) 1417 return (IDMAP_SUCCESS); 1418 if (in->idmap_utf8str_val == NULL) 1419 return (IDMAP_ERR_ARG); 1420 if (in->idmap_utf8str_val[len - 1] != 0) 1421 len++; 1422 if (outsize < len) 1423 return (IDMAP_ERR_ARG); 1424 } 1425 (void) memcpy(*out, in->idmap_utf8str_val, in->idmap_utf8str_len); 1426 return (IDMAP_SUCCESS); 1427 } 1428 1429 1430 /* 1431 * string to utf8str 1432 */ 1433 idmap_stat 1434 idmap_str2utf8(idmap_utf8str **out, const char *in, int flag) { 1435 idmap_utf8str *tmp; 1436 1437 if (out == NULL) 1438 return (IDMAP_ERR_ARG); 1439 else if (*out == NULL) { 1440 tmp = malloc(sizeof (idmap_utf8str)); 1441 if (tmp == NULL) 1442 return (IDMAP_ERR_MEMORY); 1443 } else { 1444 tmp = *out; 1445 } 1446 1447 if (in == NULL) { 1448 tmp->idmap_utf8str_len = 0; 1449 tmp->idmap_utf8str_val = NULL; 1450 if (*out == NULL) 1451 *out = tmp; 1452 return (IDMAP_SUCCESS); 1453 } 1454 1455 /* include the null terminator */ 1456 tmp->idmap_utf8str_len = strlen(in) + 1; 1457 1458 if (flag == 1) { 1459 /* Don't malloc, simply assign */ 1460 tmp->idmap_utf8str_val = (char *)in; 1461 if (*out == NULL) 1462 *out = tmp; 1463 return (IDMAP_SUCCESS); 1464 } 1465 1466 tmp->idmap_utf8str_val = malloc(tmp->idmap_utf8str_len); 1467 if (tmp->idmap_utf8str_val == NULL) { 1468 tmp->idmap_utf8str_len = 0; 1469 if (*out == NULL) 1470 free(tmp); 1471 return (IDMAP_ERR_MEMORY); 1472 } 1473 (void) memcpy(tmp->idmap_utf8str_val, in, tmp->idmap_utf8str_len); 1474 if (*out == NULL) 1475 *out = tmp; 1476 return (IDMAP_SUCCESS); 1477 } 1478 1479 1480 #define gettext(s) s 1481 static stat_table_t stattable[] = { 1482 {IDMAP_SUCCESS, gettext("Success"), 0}, 1483 {IDMAP_NEXT, gettext("More results available"), 0}, 1484 {IDMAP_ERR_OTHER, gettext("Undefined error"), EINVAL}, 1485 {IDMAP_ERR_INTERNAL, gettext("Internal error"), EINVAL}, 1486 {IDMAP_ERR_MEMORY, gettext("Out of memory"), ENOMEM}, 1487 {IDMAP_ERR_NORESULT, gettext("No results available"), EINVAL}, 1488 {IDMAP_ERR_NOTUSER, gettext("Not a user"), EINVAL}, 1489 {IDMAP_ERR_NOTGROUP, gettext("Not a group"), EINVAL}, 1490 {IDMAP_ERR_NOTSUPPORTED, gettext("Operation not supported"), ENOTSUP}, 1491 {IDMAP_ERR_W2U_NAMERULE, 1492 gettext("Invalid Windows to UNIX name-based rule"), EINVAL}, 1493 {IDMAP_ERR_U2W_NAMERULE, 1494 gettext("Invalid UNIX to Windows name-based rule"), EINVAL}, 1495 {IDMAP_ERR_CACHE, gettext("Invalid cache"), EINVAL}, 1496 {IDMAP_ERR_DB, gettext("Invalid database"), EINVAL}, 1497 {IDMAP_ERR_ARG, gettext("Invalid argument"), EINVAL}, 1498 {IDMAP_ERR_SID, gettext("Invalid SID"), EINVAL}, 1499 {IDMAP_ERR_IDTYPE, gettext("Invalid identity type"), EINVAL}, 1500 {IDMAP_ERR_RPC_HANDLE, gettext("Bad RPC handle"), EBADF}, 1501 {IDMAP_ERR_RPC, gettext("RPC error"), EINVAL}, 1502 {IDMAP_ERR_CLIENT_HANDLE, gettext("Bad client handle"), EINVAL}, 1503 {IDMAP_ERR_BUSY, gettext("Server is busy"), EBUSY}, 1504 {IDMAP_ERR_PERMISSION_DENIED, gettext("Permisssion denied"), EACCES}, 1505 {IDMAP_ERR_NOMAPPING, 1506 gettext("Mapping not found or inhibited"), EINVAL}, 1507 {IDMAP_ERR_NEW_ID_ALLOC_REQD, 1508 gettext("New mapping needs to be created"), EINVAL}, 1509 {IDMAP_ERR_DOMAIN, gettext("Invalid domain"), EINVAL}, 1510 {IDMAP_ERR_SECURITY, gettext("Security issue"), EINVAL}, 1511 {IDMAP_ERR_NOTFOUND, gettext("Not found"), EINVAL}, 1512 {IDMAP_ERR_DOMAIN_NOTFOUND, gettext("Domain not found"), EINVAL}, 1513 {IDMAP_ERR_UPDATE_NOTALLOWED, gettext("Update not allowed"), EINVAL}, 1514 {IDMAP_ERR_CFG, gettext("Configuration error"), EINVAL}, 1515 {IDMAP_ERR_CFG_CHANGE, gettext("Invalid configuration change"), EINVAL}, 1516 {IDMAP_ERR_NOTMAPPED_WELLKNOWN, 1517 gettext("No mapping for well-known SID"), EINVAL}, 1518 {IDMAP_ERR_RETRIABLE_NET_ERR, 1519 gettext("Network error"), EINVAL}, 1520 {-1, NULL, 0} 1521 }; 1522 #undef gettext 1523 1524 1525 /* 1526 * Get description of status code 1527 * 1528 * Input: 1529 * status - Status code returned by libidmap API call 1530 * 1531 * Return Value: 1532 * human-readable localized description of idmap_stat 1533 */ 1534 /* ARGSUSED */ 1535 const char * 1536 idmap_stat2string(idmap_handle_t *handle, idmap_stat status) { 1537 int i; 1538 1539 for (i = 0; stattable[i].msg; i++) { 1540 if (stattable[i].retcode == status) 1541 return (gettext(stattable[i].msg)); 1542 } 1543 return (gettext("Unknown error")); 1544 } 1545 1546 1547 static int 1548 idmap_stat2errno(idmap_stat stat) { 1549 int i; 1550 for (i = 0; stattable[i].msg; i++) { 1551 if (stattable[i].retcode == stat) 1552 return (stattable[i].errnum); 1553 } 1554 return (EINVAL); 1555 } 1556 1557 1558 /* 1559 * Get status code from string 1560 */ 1561 idmap_stat 1562 idmap_string2stat(const char *str) { 1563 if (str == NULL) 1564 return (IDMAP_ERR_INTERNAL); 1565 1566 #define return_cmp(a) \ 1567 if (0 == strcmp(str, "IDMAP_ERR_" #a)) \ 1568 return (IDMAP_ERR_ ## a); 1569 1570 return_cmp(OTHER); 1571 return_cmp(INTERNAL); 1572 return_cmp(MEMORY); 1573 return_cmp(NORESULT); 1574 return_cmp(NOTUSER); 1575 return_cmp(NOTGROUP); 1576 return_cmp(NOTSUPPORTED); 1577 return_cmp(W2U_NAMERULE); 1578 return_cmp(U2W_NAMERULE); 1579 return_cmp(CACHE); 1580 return_cmp(DB); 1581 return_cmp(ARG); 1582 return_cmp(SID); 1583 return_cmp(IDTYPE); 1584 return_cmp(RPC_HANDLE); 1585 return_cmp(RPC); 1586 return_cmp(CLIENT_HANDLE); 1587 return_cmp(BUSY); 1588 return_cmp(PERMISSION_DENIED); 1589 return_cmp(NOMAPPING); 1590 return_cmp(NEW_ID_ALLOC_REQD); 1591 return_cmp(DOMAIN); 1592 return_cmp(SECURITY); 1593 return_cmp(NOTFOUND); 1594 return_cmp(DOMAIN_NOTFOUND); 1595 return_cmp(MEMORY); 1596 return_cmp(UPDATE_NOTALLOWED); 1597 return_cmp(CFG); 1598 return_cmp(CFG_CHANGE); 1599 return_cmp(NOTMAPPED_WELLKNOWN); 1600 return_cmp(RETRIABLE_NET_ERR); 1601 #undef return_cmp 1602 1603 return (IDMAP_ERR_OTHER); 1604 } 1605 1606 1607 /* 1608 * Map the given status to one that can be returned by the protocol 1609 */ 1610 idmap_stat 1611 idmap_stat4prot(idmap_stat status) { 1612 switch (status) { 1613 case IDMAP_ERR_MEMORY: 1614 case IDMAP_ERR_CACHE: 1615 return (IDMAP_ERR_INTERNAL); 1616 } 1617 return (status); 1618 } 1619