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