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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * This module provides the high level interface to the LSA RPC functions. 28 */ 29 30 #include <strings.h> 31 #include <unistd.h> 32 #include <netdb.h> 33 #include <pwd.h> 34 #include <grp.h> 35 36 #include <smbsrv/libsmb.h> 37 #include <smbsrv/libsmbns.h> 38 #include <smbsrv/libmlsvc.h> 39 #include <smbsrv/libsmbrdr.h> 40 #include <lsalib.h> 41 #include <smbsrv/ntstatus.h> 42 #include <smbsrv/smbinfo.h> 43 #include <smbsrv/smb_token.h> 44 45 /* 46 * Name Lookup modes 47 */ 48 #define MLSVC_LOOKUP_BUILTIN 1 49 #define MLSVC_LOOKUP_LOCAL 2 50 #define MLSVC_LOOKUP_DOMAIN 3 51 #define MLSVC_LOOKUP_DOMLOC 4 52 53 static int lsa_lookup_mode(const char *, const char *); 54 static uint32_t lsa_lookup_name_builtin(char *, smb_userinfo_t *); 55 static uint32_t lsa_lookup_name_local(char *, char *, uint16_t, 56 smb_userinfo_t *); 57 static uint32_t lsa_lookup_name_lusr(char *, smb_sid_t **); 58 static uint32_t lsa_lookup_name_lgrp(char *, smb_sid_t **); 59 static uint32_t lsa_lookup_name_domain(char *, char *, char *, 60 smb_userinfo_t *); 61 62 static uint32_t lsa_lookup_sid_builtin(smb_sid_t *, smb_userinfo_t *); 63 static uint32_t lsa_lookup_sid_local(smb_sid_t *, smb_userinfo_t *); 64 static uint32_t lsa_lookup_sid_domain(smb_sid_t *, smb_userinfo_t *); 65 66 static int lsa_list_accounts(mlsvc_handle_t *); 67 68 /* 69 * lsa_lookup_name 70 * 71 * Lookup the given account and returns the account information 72 * in 'ainfo' 73 * 74 * If the name is a domain account, it may refer to a user, group or 75 * alias. If it is a local account, its type should be specified 76 * in the sid_type parameter. In case the account type is unknown 77 * sid_type should be set to SidTypeUnknown. 78 * 79 * account argument could be either [domain\\]name or [domain/]name. 80 * If domain is not specified and service is in domain mode then it 81 * first does a domain lookup and then a local lookup. 82 */ 83 uint32_t 84 lsa_lookup_name(char *account, uint16_t sid_type, 85 smb_userinfo_t *ainfo) 86 { 87 int lookup_mode; 88 char *name; 89 char *domain; 90 uint32_t status = NT_STATUS_NONE_MAPPED; 91 smb_domain_t dinfo; 92 93 (void) strsubst(account, '\\', '/'); 94 name = strchr(account, '/'); 95 if (name) { 96 /* domain is specified */ 97 *name++ = '\0'; 98 domain = account; 99 } else { 100 name = account; 101 domain = NULL; 102 } 103 104 lookup_mode = lsa_lookup_mode(domain, name); 105 106 switch (lookup_mode) { 107 case MLSVC_LOOKUP_BUILTIN: 108 return (lsa_lookup_name_builtin(name, ainfo)); 109 110 case MLSVC_LOOKUP_LOCAL: 111 return (lsa_lookup_name_local(domain, name, sid_type, ainfo)); 112 113 case MLSVC_LOOKUP_DOMAIN: 114 if (!smb_domain_getinfo(&dinfo)) 115 return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 116 117 return (lsa_lookup_name_domain(dinfo.d_dc, dinfo.d_nbdomain, 118 name, ainfo)); 119 120 default: 121 /* lookup the name in domain */ 122 if (!smb_domain_getinfo(&dinfo)) 123 return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 124 125 status = lsa_lookup_name_domain(dinfo.d_dc, dinfo.d_nbdomain, 126 name, ainfo); 127 128 if (status != NT_STATUS_NONE_MAPPED) 129 return (status); 130 131 mlsvc_release_user_info(ainfo); 132 /* lookup the name locally */ 133 status = lsa_lookup_name_local(domain, name, sid_type, ainfo); 134 } 135 136 return (status); 137 } 138 139 uint32_t 140 lsa_lookup_sid(smb_sid_t *sid, smb_userinfo_t *ainfo) 141 { 142 if (!smb_sid_isvalid(sid)) 143 return (NT_STATUS_INVALID_SID); 144 145 if (smb_sid_islocal(sid)) 146 return (lsa_lookup_sid_local(sid, ainfo)); 147 148 if (smb_wka_lookup_sid(sid, NULL)) 149 return (lsa_lookup_sid_builtin(sid, ainfo)); 150 151 return (lsa_lookup_sid_domain(sid, ainfo)); 152 } 153 154 /* 155 * lsa_query_primary_domain_info 156 * 157 * Obtains the primary domain SID and name from the specified server 158 * (domain controller). The information is stored in the NT domain 159 * database by the lower level lsar_query_info_policy call. The caller 160 * should query the database to obtain a reference to the primary 161 * domain information. 162 * 163 * The requested information will be returned via 'info' argument. 164 * Caller must call lsa_free_info() when done. 165 * 166 * Returns NT status codes. 167 */ 168 DWORD 169 lsa_query_primary_domain_info(char *server, char *domain, lsa_info_t *info) 170 { 171 mlsvc_handle_t domain_handle; 172 DWORD status; 173 char *user = smbrdr_ipc_get_user(); 174 175 if ((lsar_open(server, domain, user, &domain_handle)) != 0) 176 return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 177 178 status = lsar_query_info_policy(&domain_handle, 179 MSLSA_POLICY_PRIMARY_DOMAIN_INFO, info); 180 181 (void) lsar_close(&domain_handle); 182 return (status); 183 } 184 185 /* 186 * lsa_query_account_domain_info 187 * 188 * Obtains the account domain SID and name from the current server 189 * (domain controller). The information is stored in the NT domain 190 * database by the lower level lsar_query_info_policy call. The caller 191 * should query the database to obtain a reference to the account 192 * domain information. 193 * 194 * The requested information will be returned via 'info' argument. 195 * Caller must invoke lsa_free_info() to when done. 196 * 197 * Returns NT status codes. 198 */ 199 DWORD 200 lsa_query_account_domain_info(char *server, char *domain, lsa_info_t *info) 201 { 202 mlsvc_handle_t domain_handle; 203 DWORD status; 204 char *user = smbrdr_ipc_get_user(); 205 206 if ((lsar_open(server, domain, user, &domain_handle)) != 0) 207 return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 208 209 status = lsar_query_info_policy(&domain_handle, 210 MSLSA_POLICY_ACCOUNT_DOMAIN_INFO, info); 211 212 (void) lsar_close(&domain_handle); 213 return (status); 214 } 215 216 /* 217 * lsa_query_dns_domain_info 218 * 219 * Obtains the DNS domain info from the specified server 220 * (domain controller). 221 * 222 * The requested information will be returned via 'info' argument. 223 * Caller must call lsa_free_info() when done. 224 * 225 * Returns NT status codes. 226 */ 227 DWORD 228 lsa_query_dns_domain_info(char *server, char *domain, lsa_info_t *info) 229 { 230 mlsvc_handle_t domain_handle; 231 DWORD status; 232 char *user = smbrdr_ipc_get_user(); 233 234 if ((lsar_open(server, domain, user, &domain_handle)) != 0) 235 return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 236 237 status = lsar_query_info_policy(&domain_handle, 238 MSLSA_POLICY_DNS_DOMAIN_INFO, info); 239 240 (void) lsar_close(&domain_handle); 241 return (status); 242 } 243 244 /* 245 * lsa_enum_trusted_domains 246 * 247 * Enumerate the trusted domains in our primary domain. The information 248 * is stored in the NT domain database by the lower level 249 * lsar_enum_trusted_domains call. The caller should query the database 250 * to obtain a reference to the trusted domain information. 251 * 252 * The requested information will be returned via 'info' argument. 253 * Caller must call lsa_free_info() when done. 254 * 255 * Returns NT status codes. 256 */ 257 DWORD 258 lsa_enum_trusted_domains(char *server, char *domain, lsa_info_t *info) 259 { 260 mlsvc_handle_t domain_handle; 261 DWORD enum_context; 262 DWORD status; 263 char *user = smbrdr_ipc_get_user(); 264 265 if ((lsar_open(server, domain, user, &domain_handle)) != 0) 266 return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 267 268 enum_context = 0; 269 270 status = lsar_enum_trusted_domains(&domain_handle, &enum_context, info); 271 if (status == MLSVC_NO_MORE_DATA) { 272 /* 273 * MLSVC_NO_MORE_DATA indicates that we 274 * have all of the available information. 275 */ 276 status = NT_STATUS_SUCCESS; 277 } 278 279 (void) lsar_close(&domain_handle); 280 return (status); 281 } 282 283 /* 284 * lsa_free_info 285 */ 286 void 287 lsa_free_info(lsa_info_t *info) 288 { 289 lsa_trusted_domainlist_t *list; 290 int i; 291 292 if (!info) 293 return; 294 295 switch (info->i_type) { 296 case LSA_INFO_PRIMARY_DOMAIN: 297 smb_sid_free(info->i_domain.di_primary.n_sid); 298 break; 299 300 case LSA_INFO_ACCOUNT_DOMAIN: 301 smb_sid_free(info->i_domain.di_account.n_sid); 302 break; 303 304 case LSA_INFO_DNS_DOMAIN: 305 smb_sid_free(info->i_domain.di_dns.d_sid); 306 break; 307 308 case LSA_INFO_TRUSTED_DOMAINS: 309 list = &info->i_domain.di_trust; 310 for (i = 0; i < list->t_num; i++) 311 smb_sid_free(list->t_domains[i].n_sid); 312 free(list->t_domains); 313 break; 314 315 case LSA_INFO_NONE: 316 break; 317 } 318 } 319 320 /* 321 * lsa_lookup_name_builtin 322 * 323 * lookup builtin account table to see if account_name is 324 * there. If it is there, set sid_name_use, domain_sid, 325 * domain_name, and rid fields of the passed user_info 326 * structure. 327 */ 328 static uint32_t 329 lsa_lookup_name_builtin(char *account_name, smb_userinfo_t *user_info) 330 { 331 char *domain; 332 int res; 333 334 user_info->user_sid = smb_wka_lookup_name(account_name, 335 &user_info->sid_name_use); 336 337 if (user_info->user_sid == NULL) 338 return (NT_STATUS_NONE_MAPPED); 339 340 user_info->domain_sid = smb_sid_dup(user_info->user_sid); 341 res = smb_sid_split(user_info->domain_sid, &user_info->rid); 342 if (res < 0) 343 return (NT_STATUS_INTERNAL_ERROR); 344 345 domain = smb_wka_lookup_domain(account_name); 346 if (domain) { 347 user_info->domain_name = strdup(domain); 348 return (NT_STATUS_SUCCESS); 349 } 350 351 return (NT_STATUS_INTERNAL_ERROR); 352 } 353 354 /* 355 * lsa_lookup_name_local 356 * 357 * Obtains the infomation for the given local account name if it 358 * can be found. The type of account is specified by sid_type, 359 * which can be of user, group or unknown type. If the caller 360 * doesn't know whether the name is a user or group name then 361 * SidTypeUnknown should be passed, in which case this 362 * function first tries to find a user and then a group match. 363 * 364 * CAVEAT: if there are both a user and a group account with 365 * the same name, user SID will always be returned. 366 */ 367 static uint32_t 368 lsa_lookup_name_local(char *domain, char *name, uint16_t sid_type, 369 smb_userinfo_t *ainfo) 370 { 371 char hostname[MAXHOSTNAMELEN]; 372 smb_sid_t *sid; 373 uint32_t status; 374 375 switch (sid_type) { 376 case SidTypeUser: 377 status = lsa_lookup_name_lusr(name, &sid); 378 if (status != NT_STATUS_SUCCESS) 379 return (status); 380 break; 381 382 case SidTypeGroup: 383 case SidTypeAlias: 384 status = lsa_lookup_name_lgrp(name, &sid); 385 if (status != NT_STATUS_SUCCESS) 386 return (status); 387 break; 388 389 case SidTypeUnknown: 390 sid_type = SidTypeUser; 391 status = lsa_lookup_name_lusr(name, &sid); 392 if (status == NT_STATUS_SUCCESS) 393 break; 394 395 if (status == NT_STATUS_NONE_MAPPED) 396 return (status); 397 398 sid_type = SidTypeAlias; 399 status = lsa_lookup_name_lgrp(name, &sid); 400 if (status != NT_STATUS_SUCCESS) 401 return (status); 402 break; 403 404 default: 405 return (NT_STATUS_INVALID_PARAMETER); 406 } 407 408 ainfo->sid_name_use = sid_type; 409 ainfo->user_sid = sid; 410 ainfo->domain_sid = smb_sid_dup(sid); 411 if (ainfo->domain_sid == NULL) 412 return (NT_STATUS_NO_MEMORY); 413 414 (void) smb_sid_split(ainfo->domain_sid, &ainfo->rid); 415 if ((domain == NULL) || (*domain == '\0')) { 416 (void) smb_getnetbiosname(hostname, sizeof (hostname)); 417 ainfo->domain_name = strdup(hostname); 418 } else { 419 ainfo->domain_name = strdup(domain); 420 } 421 422 if (ainfo->domain_name == NULL) 423 return (NT_STATUS_NO_MEMORY); 424 425 return (NT_STATUS_SUCCESS); 426 } 427 428 /* 429 * lsa_lookup_name_domain 430 * 431 * Lookup a name on the specified server (domain controller) and obtain 432 * the appropriate SID. The information is returned in the user_info 433 * structure. The caller is responsible for allocating and releasing 434 * this structure. On success sid_name_use will be set to indicate the 435 * type of SID. If the name is the domain name, this function will be 436 * identical to lsa_domain_info. Otherwise the rid and name fields will 437 * also be valid. On failure sid_name_use will be set to SidTypeUnknown. 438 */ 439 static uint32_t 440 lsa_lookup_name_domain(char *server, char *domain, char *account_name, 441 smb_userinfo_t *user_info) 442 { 443 mlsvc_handle_t domain_handle; 444 char *user = smbrdr_ipc_get_user(); 445 uint32_t status; 446 447 if (lsar_open(server, domain, user, &domain_handle) != 0) 448 return (NT_STATUS_INVALID_PARAMETER); 449 450 status = lsar_lookup_names2(&domain_handle, account_name, user_info); 451 if (status == NT_STATUS_REVISION_MISMATCH) { 452 /* 453 * Not a Windows 2000 domain controller: 454 * use the NT compatible call. 455 */ 456 status = lsar_lookup_names(&domain_handle, account_name, 457 user_info); 458 } 459 460 (void) lsar_close(&domain_handle); 461 return (status); 462 } 463 464 /* 465 * lsa_test_lookup 466 * 467 * Test routine for lsa_lookup_name_domain and lsa_lookup_sid2. 468 */ 469 void 470 lsa_test_lookup(char *name) 471 { 472 smb_userinfo_t *user_info; 473 smb_sid_t *sid; 474 DWORD status; 475 smb_domain_t di; 476 477 if (!smb_domain_getinfo(&di)) 478 return; 479 480 user_info = mlsvc_alloc_user_info(); 481 482 if (lsa_lookup_name_builtin(name, user_info) != 0) { 483 status = lsa_lookup_name_domain(di.d_dc, di.d_nbdomain, name, 484 user_info); 485 486 if (status == 0) { 487 sid = smb_sid_splice(user_info->domain_sid, 488 user_info->rid); 489 490 (void) lsa_lookup_sid_domain(sid, user_info); 491 free(sid); 492 } 493 } 494 495 mlsvc_free_user_info(user_info); 496 } 497 498 /* 499 * lsa_lookup_privs 500 * 501 * Request the privileges associated with the specified account. In 502 * order to get the privileges, we first have to lookup the name on 503 * the specified domain controller and obtain the appropriate SID. 504 * The SID can then be used to open the account and obtain the 505 * account privileges. The results from both the name lookup and the 506 * privileges are returned in the user_info structure. The caller is 507 * responsible for allocating and releasing this structure. 508 * 509 * On success 0 is returned. Otherwise a -ve error code. 510 */ 511 /*ARGSUSED*/ 512 int 513 lsa_lookup_privs(char *account_name, char *target_name, 514 smb_userinfo_t *user_info) 515 { 516 mlsvc_handle_t domain_handle; 517 int rc; 518 char *user = smbrdr_ipc_get_user(); 519 smb_domain_t dinfo; 520 521 if (!smb_domain_getinfo(&dinfo)) 522 return (-1); 523 524 if ((lsar_open(dinfo.d_dc, dinfo.d_nbdomain, user, 525 &domain_handle)) != 0) 526 return (-1); 527 528 rc = lsa_list_accounts(&domain_handle); 529 (void) lsar_close(&domain_handle); 530 return (rc); 531 } 532 533 /* 534 * lsa_list_privs 535 * 536 * List the privileges supported by the specified server. 537 * This function is only intended for diagnostics. 538 * 539 * Returns NT status codes. 540 */ 541 DWORD 542 lsa_list_privs(char *server, char *domain) 543 { 544 static char name[128]; 545 static struct ms_luid luid; 546 mlsvc_handle_t domain_handle; 547 int rc; 548 int i; 549 char *user = smbrdr_ipc_get_user(); 550 551 rc = lsar_open(server, domain, user, &domain_handle); 552 if (rc != 0) 553 return (NT_STATUS_INVALID_PARAMETER); 554 555 for (i = 0; i < 30; ++i) { 556 luid.low_part = i; 557 rc = lsar_lookup_priv_name(&domain_handle, &luid, name, 128); 558 if (rc != 0) 559 continue; 560 561 (void) lsar_lookup_priv_value(&domain_handle, name, &luid); 562 (void) lsar_lookup_priv_display_name(&domain_handle, name, 563 name, 128); 564 } 565 566 (void) lsar_close(&domain_handle); 567 return (NT_STATUS_SUCCESS); 568 } 569 570 /* 571 * lsa_test 572 * 573 * LSA test routine: open and close the LSA interface. 574 * 575 * On success 0 is returned. Otherwise a -ve error code. 576 */ 577 int 578 lsa_test(char *server, char *domain) 579 { 580 mlsvc_handle_t domain_handle; 581 int rc; 582 char *user = smbrdr_ipc_get_user(); 583 584 rc = lsar_open(server, domain, user, &domain_handle); 585 if (rc != 0) 586 return (-1); 587 588 if (lsar_close(&domain_handle) != 0) 589 return (-1); 590 591 return (0); 592 } 593 594 /* 595 * lsa_list_accounts 596 * 597 * This function can be used to list the accounts in the specified 598 * domain. For now the SIDs are just listed in the system log. 599 * 600 * On success 0 is returned. Otherwise a -ve error code. 601 */ 602 static int 603 lsa_list_accounts(mlsvc_handle_t *domain_handle) 604 { 605 mlsvc_handle_t account_handle; 606 struct mslsa_EnumAccountBuf accounts; 607 struct mslsa_sid *sid; 608 char *name; 609 WORD sid_name_use; 610 smb_userinfo_t *user_info; 611 DWORD enum_context = 0; 612 int rc; 613 int i; 614 615 user_info = mlsvc_alloc_user_info(); 616 bzero(&accounts, sizeof (struct mslsa_EnumAccountBuf)); 617 618 do { 619 rc = lsar_enum_accounts(domain_handle, &enum_context, 620 &accounts); 621 if (rc != 0) 622 return (rc); 623 624 for (i = 0; i < accounts.entries_read; ++i) { 625 sid = accounts.info[i].sid; 626 627 name = smb_wka_lookup_sid((smb_sid_t *)sid, 628 &sid_name_use); 629 630 if (name == 0) { 631 if (lsar_lookup_sids(domain_handle, sid, 632 user_info) == 0) { 633 name = user_info->name; 634 sid_name_use = user_info->sid_name_use; 635 } else { 636 name = "unknown"; 637 sid_name_use = SidTypeUnknown; 638 } 639 } 640 641 if (lsar_open_account(domain_handle, sid, 642 &account_handle) == 0) { 643 (void) lsar_enum_privs_account(&account_handle, 644 user_info); 645 (void) lsar_close(&account_handle); 646 } 647 648 free(accounts.info[i].sid); 649 mlsvc_release_user_info(user_info); 650 } 651 652 if (accounts.info) 653 free(accounts.info); 654 } while (rc == 0 && accounts.entries_read != 0); 655 656 mlsvc_free_user_info(user_info); 657 return (0); 658 } 659 660 /* 661 * lsa_lookup_name_lusr 662 * 663 * Obtains the SID for the given local user name if it 664 * can be found. Upon successful return the allocated memory 665 * for the returned SID must be freed by the caller. 666 * 667 * Note that in domain mode this function might actually return 668 * a domain SID if local users are mapped to domain users. 669 */ 670 static uint32_t 671 lsa_lookup_name_lusr(char *name, smb_sid_t **sid) 672 { 673 struct passwd *pw; 674 675 if ((pw = getpwnam(name)) == NULL) 676 return (NT_STATUS_NO_SUCH_USER); 677 678 if (smb_idmap_getsid(pw->pw_uid, SMB_IDMAP_USER, sid) != IDMAP_SUCCESS) 679 return (NT_STATUS_NONE_MAPPED); 680 681 return (NT_STATUS_SUCCESS); 682 } 683 684 /* 685 * lsa_lookup_name_lgrp 686 * 687 * Obtains the SID for the given local group name if it 688 * can be found. Upon successful return the allocated memory 689 * for the returned SID must be freed by the caller. 690 * 691 * Note that in domain mode this function might actually return 692 * a domain SID if local groups are mapped to domain groups. 693 */ 694 static uint32_t 695 lsa_lookup_name_lgrp(char *name, smb_sid_t **sid) 696 { 697 struct group *gr; 698 699 if ((gr = getgrnam(name)) == NULL) 700 return (NT_STATUS_NO_SUCH_ALIAS); 701 702 if (smb_idmap_getsid(gr->gr_gid, SMB_IDMAP_GROUP, sid) != IDMAP_SUCCESS) 703 return (NT_STATUS_NONE_MAPPED); 704 705 return (NT_STATUS_SUCCESS); 706 } 707 708 static int 709 lsa_lookup_mode(const char *domain, const char *name) 710 { 711 int lookup_mode; 712 713 if (smb_wka_lookup((char *)name)) 714 return (MLSVC_LOOKUP_BUILTIN); 715 716 if (smb_config_get_secmode() == SMB_SECMODE_WORKGRP) 717 return (MLSVC_LOOKUP_LOCAL); 718 719 if ((domain == NULL) || (*domain == '\0')) 720 return (MLSVC_LOOKUP_DOMLOC); 721 722 if (mlsvc_is_local_domain(domain) == 1) 723 lookup_mode = MLSVC_LOOKUP_LOCAL; 724 else 725 lookup_mode = MLSVC_LOOKUP_DOMAIN; 726 727 return (lookup_mode); 728 } 729 730 static uint32_t 731 lsa_lookup_sid_local(smb_sid_t *sid, smb_userinfo_t *ainfo) 732 { 733 char hostname[MAXHOSTNAMELEN]; 734 struct passwd *pw; 735 struct group *gr; 736 uid_t id; 737 int id_type; 738 739 id_type = SMB_IDMAP_UNKNOWN; 740 if (smb_idmap_getid(sid, &id, &id_type) != IDMAP_SUCCESS) 741 return (NT_STATUS_NONE_MAPPED); 742 743 switch (id_type) { 744 case SMB_IDMAP_USER: 745 ainfo->sid_name_use = SidTypeUser; 746 if ((pw = getpwuid(id)) == NULL) 747 return (NT_STATUS_NO_SUCH_USER); 748 749 ainfo->name = strdup(pw->pw_name); 750 break; 751 752 case SMB_IDMAP_GROUP: 753 ainfo->sid_name_use = SidTypeAlias; 754 if ((gr = getgrgid(id)) == NULL) 755 return (NT_STATUS_NO_SUCH_ALIAS); 756 757 ainfo->name = strdup(gr->gr_name); 758 break; 759 760 default: 761 return (NT_STATUS_NONE_MAPPED); 762 } 763 764 if (ainfo->name == NULL) 765 return (NT_STATUS_NO_MEMORY); 766 767 ainfo->domain_sid = smb_sid_dup(sid); 768 if (smb_sid_split(ainfo->domain_sid, &ainfo->rid) < 0) 769 return (NT_STATUS_INTERNAL_ERROR); 770 *hostname = '\0'; 771 (void) smb_getnetbiosname(hostname, MAXHOSTNAMELEN); 772 if ((ainfo->domain_name = strdup(hostname)) == NULL) 773 return (NT_STATUS_NO_MEMORY); 774 775 return (NT_STATUS_SUCCESS); 776 } 777 778 static uint32_t 779 lsa_lookup_sid_builtin(smb_sid_t *sid, smb_userinfo_t *ainfo) 780 { 781 char *name; 782 WORD sid_name_use; 783 784 if ((name = smb_wka_lookup_sid(sid, &sid_name_use)) == NULL) 785 return (NT_STATUS_NONE_MAPPED); 786 787 ainfo->sid_name_use = sid_name_use; 788 ainfo->name = strdup(name); 789 ainfo->domain_sid = smb_sid_dup(sid); 790 791 if (ainfo->name == NULL || ainfo->domain_sid == NULL) 792 return (NT_STATUS_NO_MEMORY); 793 794 if (sid_name_use != SidTypeDomain) 795 (void) smb_sid_split(ainfo->domain_sid, &ainfo->rid); 796 797 if ((name = smb_wka_lookup_domain(ainfo->name)) != NULL) 798 ainfo->domain_name = strdup(name); 799 else 800 ainfo->domain_name = strdup("UNKNOWN"); 801 802 if (ainfo->domain_name == NULL) 803 return (NT_STATUS_NO_MEMORY); 804 805 return (NT_STATUS_SUCCESS); 806 } 807 808 static uint32_t 809 lsa_lookup_sid_domain(smb_sid_t *sid, smb_userinfo_t *ainfo) 810 { 811 mlsvc_handle_t domain_handle; 812 char *user = smbrdr_ipc_get_user(); 813 uint32_t status; 814 smb_domain_t dinfo; 815 816 if (!smb_domain_getinfo(&dinfo)) 817 return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); 818 819 if (lsar_open(dinfo.d_dc, dinfo.d_nbdomain, user, &domain_handle) != 0) 820 return (NT_STATUS_INVALID_PARAMETER); 821 822 status = lsar_lookup_sids2(&domain_handle, 823 (struct mslsa_sid *)sid, ainfo); 824 825 if (status == NT_STATUS_REVISION_MISMATCH) { 826 /* 827 * Not a Windows 2000 domain controller: 828 * use the NT compatible call. 829 */ 830 status = lsar_lookup_sids(&domain_handle, 831 (struct mslsa_sid *)sid, ainfo); 832 } 833 834 (void) lsar_close(&domain_handle); 835 return (status); 836 } 837