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