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