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 if (clntstat != RPC_SUCCESS) { 217 return (IDMAP_ERR_RPC); 218 } 219 if (retcode != IDMAP_SUCCESS) 220 errno = idmap_stat2errno(retcode); 221 return (retcode); 222 } 223 224 225 /* 226 * Destroy the update handle 227 */ 228 void 229 idmap_udt_destroy(idmap_udt_handle_t *udthandle) { 230 if (udthandle == NULL) 231 return; 232 (void) xdr_free(xdr_idmap_update_batch, (caddr_t)&udthandle->batch); 233 free(udthandle); 234 } 235 236 237 idmap_stat 238 idmap_udt_add_namerule(idmap_udt_handle_t *udthandle, const char *windomain, 239 boolean_t is_user, const char *winname, const char *unixname, 240 boolean_t is_nt4, int direction) { 241 idmap_retcode retcode; 242 idmap_namerule *rule; 243 idmap_utf8str *str; 244 245 retcode = _udt_extend_batch(udthandle, OP_ADD_NAMERULE); 246 if (retcode != IDMAP_SUCCESS) 247 goto errout; 248 249 rule = &udthandle->batch. 250 idmap_update_batch_val[udthandle->next]. 251 idmap_update_op_u.rule; 252 rule->is_user = is_user; 253 rule->direction = direction; 254 rule->is_nt4 = is_nt4; 255 if (windomain) { 256 str = &rule->windomain; 257 retcode = idmap_str2utf8(&str, windomain, 0); 258 if (retcode != IDMAP_SUCCESS) 259 goto errout; 260 } 261 if (winname) { 262 str = &rule->winname; 263 retcode = idmap_str2utf8(&str, winname, 0); 264 if (retcode != IDMAP_SUCCESS) 265 goto errout; 266 } 267 if (unixname) { 268 str = &rule->unixname; 269 retcode = idmap_str2utf8(&str, unixname, 0); 270 if (retcode != IDMAP_SUCCESS) 271 goto errout; 272 } 273 udthandle->next++; 274 return (IDMAP_SUCCESS); 275 276 errout: 277 (void) xdr_free(xdr_idmap_update_batch, (caddr_t)&udthandle->batch); 278 errno = idmap_stat2errno(retcode); 279 return (retcode); 280 } 281 282 283 /* ARGSUSED */ 284 idmap_stat 285 idmap_udt_rm_namerule(idmap_udt_handle_t *udthandle, boolean_t is_user, 286 const char *windomain, const char *winname, 287 const char *unixname, int direction) { 288 idmap_retcode retcode; 289 idmap_namerule *rule; 290 idmap_utf8str *str; 291 292 retcode = _udt_extend_batch(udthandle, OP_RM_NAMERULE); 293 if (retcode != IDMAP_SUCCESS) 294 goto errout; 295 296 rule = &udthandle->batch. 297 idmap_update_batch_val[udthandle->next]. 298 idmap_update_op_u.rule; 299 rule->is_user = is_user; 300 rule->direction = direction; 301 if (windomain) { 302 str = &rule->windomain; 303 retcode = idmap_str2utf8(&str, windomain, 0); 304 if (retcode != IDMAP_SUCCESS) 305 goto errout; 306 } 307 if (winname) { 308 str = &rule->winname; 309 retcode = idmap_str2utf8(&str, winname, 0); 310 if (retcode != IDMAP_SUCCESS) 311 goto errout; 312 } 313 if (unixname) { 314 str = &rule->unixname; 315 retcode = idmap_str2utf8(&str, unixname, 0); 316 if (retcode != IDMAP_SUCCESS) 317 goto errout; 318 } 319 udthandle->next++; 320 return (IDMAP_SUCCESS); 321 322 errout: 323 (void) xdr_free(xdr_idmap_update_batch, (caddr_t)&udthandle->batch); 324 errno = idmap_stat2errno(retcode); 325 return (retcode); 326 } 327 328 329 /* ARGSUSED */ 330 idmap_stat 331 idmap_udt_flush_namerules(idmap_udt_handle_t *udthandle, boolean_t is_user) { 332 idmap_retcode retcode; 333 334 retcode = _udt_extend_batch(udthandle, OP_FLUSH_NAMERULES); 335 if (retcode != IDMAP_SUCCESS) 336 goto errout; 337 338 udthandle->batch.idmap_update_batch_val[udthandle->next]. 339 idmap_update_op_u.is_user = is_user; 340 341 udthandle->next++; 342 return (IDMAP_SUCCESS); 343 344 errout: 345 (void) xdr_free(xdr_idmap_update_batch, (caddr_t)&udthandle->batch); 346 errno = idmap_stat2errno(retcode); 347 return (retcode); 348 } 349 350 351 /* 352 * Set the number of entries requested per batch by the iterator 353 * 354 * Input: 355 * iter - iterator 356 * limit - number of entries requested per batch 357 */ 358 idmap_stat 359 idmap_iter_set_limit(idmap_iter_t *iter, uint64_t limit) { 360 if (iter == NULL) { 361 errno = EINVAL; 362 return (IDMAP_ERR_ARG); 363 } 364 iter->limit = limit; 365 return (IDMAP_SUCCESS); 366 } 367 368 369 /* 370 * Create iterator to get name-based mapping rules 371 * 372 * Input: 373 * windomain - Windows domain 374 * is_user - user or group rules 375 * winname - Windows user or group name 376 * unixname - Unix user or group name 377 * 378 * Output: 379 * iter - iterator 380 */ 381 idmap_stat 382 idmap_iter_namerules(idmap_handle_t *handle, const char *windomain, 383 boolean_t is_user, const char *winname, 384 const char *unixname, idmap_iter_t **iter) { 385 386 idmap_iter_t *tmpiter; 387 idmap_list_namerules_1_argument *arg = NULL; 388 idmap_namerule *rule; 389 idmap_utf8str *str; 390 idmap_retcode retcode; 391 392 __ITER_CREATE(tmpiter, arg, handle, IDMAP_LIST_NAMERULES); 393 394 rule = &arg->rule; 395 rule->is_user = is_user; 396 rule->direction = -1; 397 if (windomain) { 398 str = &rule->windomain; 399 retcode = idmap_str2utf8(&str, windomain, 0); 400 if (retcode != IDMAP_SUCCESS) { 401 errno = ENOMEM; 402 goto errout; 403 } 404 } 405 if (winname) { 406 str = &rule->winname; 407 retcode = idmap_str2utf8(&str, winname, 0); 408 if (retcode != IDMAP_SUCCESS) { 409 errno = ENOMEM; 410 goto errout; 411 } 412 } 413 if (unixname) { 414 str = &rule->unixname; 415 retcode = idmap_str2utf8(&str, unixname, 0); 416 if (retcode != IDMAP_SUCCESS) { 417 errno = ENOMEM; 418 goto errout; 419 } 420 } 421 422 *iter = tmpiter; 423 return (IDMAP_SUCCESS); 424 425 errout: 426 __ITER_ERR_RETURN(tmpiter, arg, 427 xdr_idmap_list_namerules_1_argument, retcode); 428 } 429 430 431 /* 432 * Iterate through the name-based mapping rules 433 * 434 * Input: 435 * iter - iterator 436 * 437 * Output: 438 * windomain - Windows domain 439 * winname - Windows user or group name 440 * unixname - Unix user or group name 441 * is_nt4 - NT4 or AD 442 * direction - bi(0), win2unix(1), unix2win(2) 443 * 444 * Return value: 445 * 0 - done 446 * 1 - more results available 447 * < 0 - error 448 */ 449 idmap_stat 450 idmap_iter_next_namerule(idmap_iter_t *iter, char **windomain, 451 char **winname, char **unixname, boolean_t *is_nt4, 452 int *direction) { 453 idmap_namerules_res *namerules; 454 idmap_list_namerules_1_argument *arg; 455 idmap_retcode retcode; 456 457 if (windomain) 458 *windomain = NULL; 459 if (winname) 460 *winname = NULL; 461 if (unixname) 462 *unixname = NULL; 463 if (is_nt4) 464 *is_nt4 = 0; 465 if (direction) 466 *direction = -1; 467 468 __ITER_CHECK(iter, IDMAP_LIST_NAMERULES); 469 470 namerules = (idmap_namerules_res *)iter->retlist; 471 if (iter->retcode == IDMAP_NEXT && (namerules == NULL || 472 iter->next >= namerules->rules.rules_len)) { 473 474 if ((arg = iter->arg) == NULL) { 475 errno = EINVAL; 476 return (IDMAP_ERR_ARG); 477 } 478 arg->limit = iter->limit; 479 480 retcode = _iter_get_next_list(IDMAP_LIST_NAMERULES, 481 iter, arg, 482 (uchar_t **)&namerules, sizeof (*namerules), 483 (xdrproc_t)xdr_idmap_list_namerules_1_argument, 484 (xdrproc_t)xdr_idmap_namerules_res); 485 if (retcode != IDMAP_SUCCESS) 486 return (retcode); 487 488 if (IDMAP_ERROR(namerules->retcode)) { 489 retcode = namerules->retcode; 490 xdr_free(xdr_idmap_namerules_res, (caddr_t)namerules); 491 free(namerules); 492 iter->retlist = NULL; 493 return (retcode); 494 } 495 iter->retcode = namerules->retcode; 496 arg->lastrowid = namerules->lastrowid; 497 } 498 499 if (namerules == NULL || namerules->rules.rules_len == 0) 500 return (IDMAP_SUCCESS); 501 502 if (iter->next >= namerules->rules.rules_len) { 503 return (IDMAP_ERR_ARG); 504 } 505 506 if (windomain) { 507 retcode = idmap_utf82str(windomain, 0, 508 &namerules->rules.rules_val[iter->next].windomain); 509 if (retcode != IDMAP_SUCCESS) 510 goto errout; 511 } 512 if (winname) { 513 retcode = idmap_utf82str(winname, 0, 514 &namerules->rules.rules_val[iter->next].winname); 515 if (retcode != IDMAP_SUCCESS) 516 goto errout; 517 } 518 if (unixname) { 519 retcode = idmap_utf82str(unixname, 0, 520 &namerules->rules.rules_val[iter->next].unixname); 521 if (retcode != IDMAP_SUCCESS) 522 goto errout; 523 } 524 if (is_nt4) 525 *is_nt4 = namerules->rules.rules_val[iter->next].is_nt4; 526 if (direction) 527 *direction = namerules->rules.rules_val[iter->next].direction; 528 iter->next++; 529 530 if (iter->next == namerules->rules.rules_len) 531 return (iter->retcode); 532 else 533 return (IDMAP_NEXT); 534 535 errout: 536 if (windomain && *windomain) 537 free(*windomain); 538 if (winname && *winname) 539 free(*winname); 540 if (unixname && *unixname) 541 free(*unixname); 542 return (retcode); 543 } 544 545 546 /* 547 * Create iterator to get SID to UID/GID mappings 548 * 549 * Input: 550 * is_user - user or group 551 * 552 * Output: 553 * iter - iterator 554 */ 555 idmap_stat 556 idmap_iter_mappings(idmap_handle_t *handle, boolean_t is_user, 557 idmap_iter_t **iter) { 558 idmap_iter_t *tmpiter; 559 idmap_list_mappings_1_argument *arg = NULL; 560 561 __ITER_CREATE(tmpiter, arg, handle, IDMAP_LIST_MAPPINGS); 562 563 arg->is_user = is_user; 564 *iter = tmpiter; 565 return (IDMAP_SUCCESS); 566 } 567 568 569 /* 570 * Iterate through the SID to UID/GID mappings 571 * 572 * Input: 573 * iter - iterator 574 * 575 * Output: 576 * sid - SID in canonical form 577 * pid - UID or GID 578 * 579 * Return value: 580 * 0 - done 581 * 1 - more results available 582 * < 0 - error 583 */ 584 idmap_stat 585 idmap_iter_next_mapping(idmap_iter_t *iter, char **sidprefix, 586 idmap_rid_t *rid, uid_t *pid, char **winname, 587 char **windomain, char **unixname, int *direction) { 588 idmap_mappings_res *mappings; 589 idmap_list_mappings_1_argument *arg; 590 idmap_retcode retcode; 591 char *str; 592 593 if (sidprefix) 594 *sidprefix = NULL; 595 if (rid) 596 *rid = UINT32_MAX; 597 if (winname) 598 *winname = NULL; 599 if (windomain) 600 *windomain = NULL; 601 if (unixname) 602 *unixname = NULL; 603 if (pid) 604 *pid = UINT32_MAX; 605 if (direction) 606 *direction = -1; 607 608 __ITER_CHECK(iter, IDMAP_LIST_MAPPINGS); 609 610 mappings = (idmap_mappings_res *)iter->retlist; 611 if (iter->retcode == IDMAP_NEXT && (mappings == NULL || 612 iter->next >= mappings->mappings.mappings_len)) { 613 614 if ((arg = iter->arg) == NULL) { 615 errno = EINVAL; 616 return (IDMAP_ERR_ARG); 617 } 618 arg->limit = iter->limit; 619 620 retcode = _iter_get_next_list(IDMAP_LIST_MAPPINGS, 621 iter, arg, 622 (uchar_t **)&mappings, sizeof (*mappings), 623 (xdrproc_t)xdr_idmap_list_mappings_1_argument, 624 (xdrproc_t)xdr_idmap_mappings_res); 625 if (retcode != IDMAP_SUCCESS) 626 return (retcode); 627 628 if (IDMAP_ERROR(mappings->retcode)) { 629 retcode = mappings->retcode; 630 xdr_free(xdr_idmap_mappings_res, (caddr_t)mappings); 631 free(mappings); 632 iter->retlist = NULL; 633 return (retcode); 634 } 635 iter->retcode = mappings->retcode; 636 arg->lastrowid = mappings->lastrowid; 637 } 638 639 if (mappings == NULL || mappings->mappings.mappings_len == 0) 640 return (IDMAP_SUCCESS); 641 642 if (iter->next >= mappings->mappings.mappings_len) { 643 return (IDMAP_ERR_ARG); 644 } 645 646 if (sidprefix) { 647 str = mappings->mappings.mappings_val[iter->next].id1. 648 idmap_id_u.sid.prefix; 649 if (str) { 650 *sidprefix = strdup(str); 651 if (*sidprefix == NULL) { 652 retcode = IDMAP_ERR_MEMORY; 653 goto errout; 654 } 655 } 656 } 657 if (rid) 658 *rid = mappings->mappings.mappings_val[iter->next].id1. 659 idmap_id_u.sid.rid; 660 if (winname) { 661 retcode = idmap_utf82str(winname, 0, 662 &mappings->mappings.mappings_val[iter->next].id1name); 663 if (retcode != IDMAP_SUCCESS) 664 goto errout; 665 } 666 if (windomain) { 667 retcode = idmap_utf82str(windomain, 0, 668 &mappings->mappings.mappings_val[iter->next].id1domain); 669 if (retcode != IDMAP_SUCCESS) 670 goto errout; 671 } 672 if (unixname) { 673 retcode = idmap_utf82str(unixname, 0, 674 &mappings->mappings.mappings_val[iter->next].id2name); 675 if (retcode != IDMAP_SUCCESS) 676 goto errout; 677 } 678 if (pid) 679 *pid = mappings->mappings.mappings_val[iter->next].id2. 680 idmap_id_u.uid; 681 if (direction) 682 *direction = mappings->mappings.mappings_val[iter->next]. 683 direction; 684 iter->next++; 685 686 if (iter->next == mappings->mappings.mappings_len) 687 return (iter->retcode); 688 else 689 return (IDMAP_NEXT); 690 691 errout: 692 if (sidprefix && *sidprefix) 693 free(*sidprefix); 694 if (winname && *winname) 695 free(*winname); 696 if (windomain && *windomain) 697 free(*windomain); 698 if (unixname && *unixname) 699 free(*unixname); 700 return (retcode); 701 } 702 703 704 /* 705 * Destroy the iterator 706 */ 707 void 708 idmap_iter_destroy(idmap_iter_t *iter) { 709 xdrproc_t _xdr_argument, _xdr_result; 710 711 if (iter == NULL) 712 return; 713 714 switch (iter->type) { 715 case IDMAP_LIST_NAMERULES: 716 _xdr_argument = (xdrproc_t)xdr_idmap_list_namerules_1_argument; 717 _xdr_result = (xdrproc_t)xdr_idmap_namerules_res; 718 break; 719 case IDMAP_LIST_MAPPINGS: 720 _xdr_argument = (xdrproc_t)xdr_idmap_list_mappings_1_argument; 721 _xdr_result = (xdrproc_t)xdr_idmap_mappings_res; 722 break; 723 default: 724 free(iter); 725 return; 726 }; 727 728 if (iter->arg) { 729 xdr_free(_xdr_argument, (caddr_t)iter->arg); 730 free(iter->arg); 731 } 732 if (iter->retlist) { 733 xdr_free(_xdr_result, (caddr_t)iter->retlist); 734 free(iter->retlist); 735 } 736 free(iter); 737 } 738 739 740 /* 741 * Create handle to get SID to UID/GID mapping entries 742 * 743 * Input: 744 * gh - "get mapping" handle 745 */ 746 idmap_stat 747 idmap_get_create(idmap_handle_t *handle, idmap_get_handle_t **gh) { 748 idmap_get_handle_t *tmp; 749 750 /* sanity checks */ 751 if (handle == NULL || gh == NULL) { 752 errno = EINVAL; 753 return (IDMAP_ERR_ARG); 754 } 755 756 /* allocate the handle */ 757 if ((tmp = calloc(1, sizeof (*tmp))) == NULL) { 758 errno = ENOMEM; 759 return (IDMAP_ERR_MEMORY); 760 } 761 762 tmp->ih = handle; 763 *gh = tmp; 764 return (IDMAP_SUCCESS); 765 } 766 767 768 /* 769 * Given SID, get UID 770 * 771 * Input: 772 * sidprefix - SID prefix 773 * rid - RID 774 * flag - flag 775 * 776 * Output: 777 * stat - status of the get request 778 * uid - POSIX UID if stat = 0 779 * 780 * Note: The output parameters will be set by idmap_get_mappings() 781 */ 782 idmap_stat 783 idmap_get_uidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid, 784 int flag, uid_t *uid, idmap_stat *stat) { 785 786 idmap_retcode retcode; 787 idmap_mapping *mapping; 788 789 /* sanity checks */ 790 if (gh == NULL) 791 return (IDMAP_ERR_ARG); 792 if (uid == NULL || sidprefix == NULL) 793 return (IDMAP_ERR_ARG); 794 795 /* Extend the request array and the return list */ 796 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS) 797 goto errout; 798 799 /* Setup the request */ 800 mapping = &gh->batch.idmap_mapping_batch_val[gh->next]; 801 mapping->flag = flag; 802 mapping->id1.idtype = IDMAP_SID; 803 mapping->id1.idmap_id_u.sid.rid = rid; 804 if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) { 805 retcode = IDMAP_ERR_MEMORY; 806 goto errout; 807 } 808 mapping->id2.idtype = IDMAP_UID; 809 810 /* Setup pointers for the result */ 811 gh->retlist[gh->next].idtype = IDMAP_UID; 812 gh->retlist[gh->next].uid = uid; 813 gh->retlist[gh->next].stat = stat; 814 815 gh->next++; 816 return (IDMAP_SUCCESS); 817 818 errout: 819 (void) xdr_free(xdr_idmap_mapping_batch, (caddr_t)&gh->batch); 820 free(gh->retlist); 821 gh->retlist = NULL; 822 gh->next = 0; 823 errno = idmap_stat2errno(retcode); 824 return (retcode); 825 } 826 827 828 /* 829 * Given SID, get GID 830 * 831 * Input: 832 * sidprefix - SID prefix 833 * rid - rid 834 * flag - flag 835 * 836 * Output: 837 * stat - status of the get request 838 * gid - POSIX GID if stat = 0 839 * 840 * Note: The output parameters will be set by idmap_get_mappings() 841 */ 842 idmap_stat 843 idmap_get_gidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid, 844 int flag, gid_t *gid, idmap_stat *stat) { 845 846 idmap_retcode retcode; 847 idmap_mapping *mapping; 848 849 /* sanity checks */ 850 if (gh == NULL) 851 return (IDMAP_ERR_ARG); 852 if (gid == NULL || sidprefix == NULL) 853 return (IDMAP_ERR_ARG); 854 855 /* Extend the request array and the return list */ 856 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS) 857 goto errout; 858 859 /* Setup the request */ 860 mapping = &gh->batch.idmap_mapping_batch_val[gh->next]; 861 mapping->flag = flag; 862 mapping->id1.idtype = IDMAP_SID; 863 mapping->id1.idmap_id_u.sid.rid = rid; 864 if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) { 865 retcode = IDMAP_ERR_MEMORY; 866 goto errout; 867 } 868 mapping->id2.idtype = IDMAP_GID; 869 870 /* Setup pointers for the result */ 871 gh->retlist[gh->next].idtype = IDMAP_GID; 872 gh->retlist[gh->next].gid = gid; 873 gh->retlist[gh->next].stat = stat; 874 875 gh->next++; 876 return (IDMAP_SUCCESS); 877 878 errout: 879 (void) xdr_free(xdr_idmap_mapping_batch, (caddr_t)&gh->batch); 880 free(gh->retlist); 881 gh->retlist = NULL; 882 gh->next = 0; 883 errno = idmap_stat2errno(retcode); 884 return (retcode); 885 } 886 887 888 /* 889 * Given SID, get POSIX ID i.e. UID/GID 890 * 891 * Input: 892 * sidprefix - SID prefix 893 * rid - rid 894 * flag - flag 895 * 896 * Output: 897 * stat - status of the get request 898 * is_user - user or group 899 * pid - POSIX UID if stat = 0 and is_user = 1 900 * POSIX GID if stat = 0 and is_user = 0 901 * 902 * Note: The output parameters will be set by idmap_get_mappings() 903 */ 904 idmap_stat 905 idmap_get_pidbysid(idmap_get_handle_t *gh, char *sidprefix, idmap_rid_t rid, 906 int flag, uid_t *pid, int *is_user, idmap_stat *stat) { 907 idmap_retcode retcode; 908 idmap_mapping *mapping; 909 910 /* sanity checks */ 911 if (gh == NULL) 912 return (IDMAP_ERR_ARG); 913 if (pid == NULL || sidprefix == NULL || is_user == NULL) 914 return (IDMAP_ERR_ARG); 915 916 /* Extend the request array and the return list */ 917 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS) 918 goto errout; 919 920 /* Setup the request */ 921 mapping = &gh->batch.idmap_mapping_batch_val[gh->next]; 922 mapping->flag = flag; 923 mapping->id1.idtype = IDMAP_SID; 924 mapping->id1.idmap_id_u.sid.rid = rid; 925 if ((mapping->id1.idmap_id_u.sid.prefix = strdup(sidprefix)) == NULL) { 926 retcode = IDMAP_ERR_MEMORY; 927 goto errout; 928 } 929 mapping->id2.idtype = IDMAP_POSIXID; 930 931 /* Setup pointers for the result */ 932 gh->retlist[gh->next].idtype = IDMAP_POSIXID; 933 gh->retlist[gh->next].uid = pid; 934 gh->retlist[gh->next].gid = pid; 935 gh->retlist[gh->next].is_user = is_user; 936 gh->retlist[gh->next].stat = stat; 937 938 gh->next++; 939 return (IDMAP_SUCCESS); 940 941 errout: 942 (void) xdr_free(xdr_idmap_mapping_batch, (caddr_t)&gh->batch); 943 free(gh->retlist); 944 gh->retlist = NULL; 945 gh->next = 0; 946 errno = idmap_stat2errno(retcode); 947 return (retcode); 948 } 949 950 951 /* 952 * Given UID, get SID 953 * 954 * Input: 955 * uid - POSIX UID 956 * flag - flag 957 * 958 * Output: 959 * stat - status of the get request 960 * sid - SID prefix (if stat == 0) 961 * rid - rid 962 * 963 * Note: The output parameters will be set by idmap_get_mappings() 964 */ 965 idmap_stat 966 idmap_get_sidbyuid(idmap_get_handle_t *gh, uid_t uid, int flag, 967 char **sidprefix, idmap_rid_t *rid, idmap_stat *stat) { 968 969 idmap_retcode retcode; 970 idmap_mapping *mapping; 971 972 /* sanity checks */ 973 if (gh == NULL) 974 return (IDMAP_ERR_ARG); 975 if (sidprefix == NULL) 976 return (IDMAP_ERR_ARG); 977 978 /* Extend the request array and the return list */ 979 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS) 980 goto errout; 981 982 /* Setup the request */ 983 mapping = &gh->batch.idmap_mapping_batch_val[gh->next]; 984 mapping->flag = flag; 985 mapping->id1.idtype = IDMAP_UID; 986 mapping->id1.idmap_id_u.uid = uid; 987 mapping->id2.idtype = IDMAP_SID; 988 989 /* Setup pointers for the result */ 990 gh->retlist[gh->next].idtype = IDMAP_SID; 991 gh->retlist[gh->next].sidprefix = sidprefix; 992 gh->retlist[gh->next].rid = rid; 993 gh->retlist[gh->next].stat = stat; 994 995 gh->next++; 996 return (IDMAP_SUCCESS); 997 998 errout: 999 (void) xdr_free(xdr_idmap_mapping_batch, (caddr_t)&gh->batch); 1000 free(gh->retlist); 1001 gh->retlist = NULL; 1002 gh->next = 0; 1003 errno = idmap_stat2errno(retcode); 1004 return (retcode); 1005 } 1006 1007 1008 /* 1009 * Given GID, get SID 1010 * 1011 * Input: 1012 * gid - POSIX GID 1013 * flag - flag 1014 * 1015 * Output: 1016 * stat - status of the get request 1017 * sidprefix - SID prefix (if stat == 0) 1018 * rid - rid 1019 * 1020 * Note: The output parameters will be set by idmap_get_mappings() 1021 */ 1022 idmap_stat 1023 idmap_get_sidbygid(idmap_get_handle_t *gh, gid_t gid, int flag, 1024 char **sidprefix, idmap_rid_t *rid, idmap_stat *stat) { 1025 1026 idmap_retcode retcode; 1027 idmap_mapping *mapping; 1028 1029 /* sanity checks */ 1030 if (gh == NULL) 1031 return (IDMAP_ERR_ARG); 1032 if (sidprefix == NULL) 1033 return (IDMAP_ERR_ARG); 1034 1035 /* Extend the request array and the return list */ 1036 if ((retcode = _get_ids_extend_batch(gh)) != IDMAP_SUCCESS) 1037 goto errout; 1038 1039 /* Setup the request */ 1040 mapping = &gh->batch.idmap_mapping_batch_val[gh->next]; 1041 mapping->flag = flag; 1042 mapping->id1.idtype = IDMAP_GID; 1043 mapping->id1.idmap_id_u.gid = gid; 1044 mapping->id2.idtype = IDMAP_SID; 1045 1046 /* Setup pointers for the result */ 1047 gh->retlist[gh->next].idtype = IDMAP_SID; 1048 gh->retlist[gh->next].sidprefix = sidprefix; 1049 gh->retlist[gh->next].rid = rid; 1050 gh->retlist[gh->next].stat = stat; 1051 1052 gh->next++; 1053 return (IDMAP_SUCCESS); 1054 1055 errout: 1056 (void) xdr_free(xdr_idmap_mapping_batch, (caddr_t)&gh->batch); 1057 free(gh->retlist); 1058 gh->retlist = NULL; 1059 gh->next = 0; 1060 errno = idmap_stat2errno(retcode); 1061 return (retcode); 1062 } 1063 1064 1065 /* 1066 * Process the batched "get mapping" requests. The results (i.e. 1067 * status and identity) will be available in the data areas 1068 * provided by individual requests. 1069 */ 1070 idmap_stat 1071 idmap_get_mappings(idmap_get_handle_t *gh) { 1072 CLIENT *clnt; 1073 enum clnt_stat clntstat; 1074 idmap_retcode retcode; 1075 idmap_ids_res res; 1076 idmap_id *id; 1077 int i; 1078 1079 if (gh == NULL) { 1080 errno = EINVAL; 1081 return (IDMAP_ERR_ARG); 1082 } 1083 _IDMAP_GET_CLIENT_HANDLE(gh->ih, clnt); 1084 1085 (void) memset(&res, 0, sizeof (idmap_ids_res)); 1086 clntstat = clnt_call(clnt, IDMAP_GET_MAPPED_IDS, 1087 (xdrproc_t)xdr_idmap_mapping_batch, 1088 (caddr_t)&gh->batch, 1089 (xdrproc_t)xdr_idmap_ids_res, 1090 (caddr_t)&res, 1091 TIMEOUT); 1092 if (clntstat != RPC_SUCCESS) { 1093 retcode = IDMAP_ERR_RPC; 1094 goto out; 1095 } 1096 if (res.retcode != IDMAP_SUCCESS) { 1097 retcode = res.retcode; 1098 goto out; 1099 } 1100 for (i = 0; i < gh->next; i++) { 1101 if (i >= res.ids.ids_len) { 1102 *gh->retlist[i].stat = IDMAP_ERR_NORESULT; 1103 continue; 1104 } 1105 *gh->retlist[i].stat = res.ids.ids_val[i].retcode; 1106 id = &res.ids.ids_val[i].id; 1107 switch (id->idtype) { 1108 case IDMAP_UID: 1109 if (gh->retlist[i].uid) 1110 *gh->retlist[i].uid = id->idmap_id_u.uid; 1111 if (gh->retlist[i].is_user) 1112 *gh->retlist[i].is_user = 1; 1113 break; 1114 case IDMAP_GID: 1115 if (gh->retlist[i].gid) 1116 *gh->retlist[i].gid = id->idmap_id_u.gid; 1117 if (gh->retlist[i].is_user) 1118 *gh->retlist[i].is_user = 0; 1119 break; 1120 case IDMAP_SID: 1121 if (gh->retlist[i].rid) 1122 *gh->retlist[i].rid = id->idmap_id_u.sid.rid; 1123 if (gh->retlist[i].sidprefix) { 1124 if (id->idmap_id_u.sid.prefix == NULL) { 1125 *gh->retlist[i].sidprefix = NULL; 1126 break; 1127 } 1128 *gh->retlist[i].sidprefix = 1129 strdup(id->idmap_id_u.sid.prefix); 1130 if (*gh->retlist[i].sidprefix == NULL) 1131 *gh->retlist[i].stat = 1132 IDMAP_ERR_MEMORY; 1133 } 1134 break; 1135 case IDMAP_NONE: 1136 break; 1137 default: 1138 *gh->retlist[i].stat = IDMAP_ERR_NORESULT; 1139 break; 1140 } 1141 } 1142 retcode = IDMAP_SUCCESS; 1143 1144 out: 1145 (void) xdr_free(xdr_idmap_mapping_batch, (caddr_t)&gh->batch); 1146 free(gh->retlist); 1147 gh->retlist = NULL; 1148 gh->next = 0; 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 = -1; 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_ERR_RPC); 1240 } 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 = -1; 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_ERR_RPC); 1333 } 1334 1335 retcode = result.retcode; 1336 1337 if ((mapping = result.mappings.mappings_val) == NULL) { 1338 if (retcode == IDMAP_SUCCESS) 1339 retcode = IDMAP_ERR_NORESULT; 1340 goto out; 1341 } 1342 1343 if (direction) 1344 *direction = mapping->direction; 1345 if (sidprefix) { 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"), EINVAL}, 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"), EINVAL}, 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"), EINVAL}, 1506 {IDMAP_ERR_PERMISSION_DENIED, gettext("Permisssion denied"), EINVAL}, 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