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 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * Local Security Authority RPC (LSAR) client-side interface. 28 */ 29 30 #include <sys/errno.h> 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <strings.h> 34 35 #include <smbsrv/libsmb.h> 36 #include <smbsrv/libmlsvc.h> 37 #include <smbsrv/smbinfo.h> 38 #include <smbsrv/ntaccess.h> 39 #include <smbsrv/ntstatus.h> 40 #include <smbsrv/ntlocale.h> 41 #include <smbsrv/string.h> 42 #include <lsalib.h> 43 44 /* 45 * The maximum number of bytes we are prepared to deal with in a 46 * response. 47 */ 48 #define MLSVC_MAX_RESPONSE_LEN 1024 49 50 /* 51 * This structure is used when looking up names. We only lookup one 52 * name at a time but the structure will allow for more. 53 */ 54 typedef struct lsa_names { 55 uint32_t n_entry; 56 mslsa_string_t name[8]; 57 } lsa_names_t; 58 59 typedef DWORD (*lsar_nameop_t)(mlsvc_handle_t *, lsa_names_t *, 60 smb_account_t *); 61 62 static uint32_t lsar_lookup_names1(mlsvc_handle_t *, lsa_names_t *, 63 smb_account_t *); 64 static uint32_t lsar_lookup_names2(mlsvc_handle_t *, lsa_names_t *, 65 smb_account_t *); 66 static uint32_t lsar_lookup_names3(mlsvc_handle_t *, lsa_names_t *, 67 smb_account_t *); 68 static uint32_t lsar_lookup_sids1(mlsvc_handle_t *, lsa_sid_t *, 69 smb_account_t *); 70 static uint32_t lsar_lookup_sids2(mlsvc_handle_t *, lsa_sid_t *, 71 smb_account_t *account); 72 73 static char *lsar_get_username(const char *); 74 static void smb_account_trace(const smb_account_t *); 75 76 static void lsar_set_trusted_domains_ex(struct mslsa_EnumTrustedDomainBufEx *, 77 smb_trusted_domains_t *); 78 static void lsar_set_trusted_domains(struct mslsa_EnumTrustedDomainBuf *, 79 smb_trusted_domains_t *); 80 81 /* 82 * lsar_open 83 * 84 * This is a wrapper round lsar_open_policy2 to ensure that we connect 85 * using the appropriate domain information. 86 * 87 * If username argument is NULL, an anonymous connection will be established. 88 * Otherwise, an authenticated connection will be established. 89 * 90 * On success 0 is returned. Otherwise a -ve error code. 91 */ 92 int lsar_open(char *server, char *domain, char *username, 93 mlsvc_handle_t *domain_handle) 94 { 95 if (server == NULL || domain == NULL) 96 return (-1); 97 98 if (username == NULL) 99 username = MLSVC_ANON_USER; 100 101 return (lsar_open_policy2(server, domain, username, domain_handle)); 102 } 103 104 /* 105 * lsar_open_policy2 106 * 107 * Obtain an LSA policy handle. A policy handle is required to access 108 * LSA resources on a remote server. The server name supplied here does 109 * not need the double backslash prefix; it is added here. Call this 110 * function via lsar_open to ensure that the appropriate connection is 111 * in place. 112 * 113 * I'm not sure if it makes a difference whether we use GENERIC_EXECUTE 114 * or STANDARD_RIGHTS_EXECUTE. For a long time I used the standard bit 115 * and then I added the generic bit while working on privileges because 116 * NT sets that bit. I don't think it matters. 117 * 118 * Returns 0 on success. Otherwise non-zero to indicate a failure. 119 */ 120 int 121 lsar_open_policy2(char *server, char *domain, char *username, 122 mlsvc_handle_t *lsa_handle) 123 { 124 struct mslsa_OpenPolicy2 arg; 125 int opnum; 126 int len; 127 int rc; 128 129 rc = ndr_rpc_bind(lsa_handle, server, domain, username, "LSARPC"); 130 if (rc != 0) 131 return (-1); 132 133 opnum = LSARPC_OPNUM_OpenPolicy2; 134 bzero(&arg, sizeof (struct mslsa_OpenPolicy2)); 135 136 len = strlen(server) + 4; 137 arg.servername = ndr_rpc_malloc(lsa_handle, len); 138 if (arg.servername == NULL) { 139 ndr_rpc_unbind(lsa_handle); 140 return (-1); 141 } 142 143 (void) snprintf((char *)arg.servername, len, "\\\\%s", server); 144 arg.attributes.length = sizeof (struct mslsa_object_attributes); 145 146 if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000) { 147 arg.desiredAccess = MAXIMUM_ALLOWED; 148 } else { 149 arg.desiredAccess = GENERIC_EXECUTE 150 | STANDARD_RIGHTS_EXECUTE 151 | POLICY_VIEW_LOCAL_INFORMATION 152 | POLICY_LOOKUP_NAMES; 153 } 154 155 if ((rc = ndr_rpc_call(lsa_handle, opnum, &arg)) != 0) { 156 ndr_rpc_unbind(lsa_handle); 157 return (-1); 158 } 159 160 if (arg.status != 0) { 161 rc = -1; 162 } else { 163 (void) memcpy(&lsa_handle->handle, &arg.domain_handle, 164 sizeof (ndr_hdid_t)); 165 166 if (ndr_is_null_handle(lsa_handle)) 167 rc = -1; 168 } 169 170 ndr_rpc_release(lsa_handle); 171 172 if (rc != 0) 173 ndr_rpc_unbind(lsa_handle); 174 return (rc); 175 } 176 177 /* 178 * lsar_open_account 179 * 180 * Obtain an LSA account handle. The lsa_handle must be a valid handle 181 * obtained via lsar_open_policy2. The main thing to remember here is 182 * to set up the context in the lsa_account_handle. I'm not sure what 183 * the requirements are for desired access. Some values require admin 184 * access. 185 * 186 * Returns 0 on success. Otherwise non-zero to indicate a failure. 187 */ 188 int 189 lsar_open_account(mlsvc_handle_t *lsa_handle, struct mslsa_sid *sid, 190 mlsvc_handle_t *lsa_account_handle) 191 { 192 struct mslsa_OpenAccount arg; 193 int opnum; 194 int rc; 195 196 if (ndr_is_null_handle(lsa_handle) || sid == NULL) 197 return (-1); 198 199 opnum = LSARPC_OPNUM_OpenAccount; 200 bzero(&arg, sizeof (struct mslsa_OpenAccount)); 201 202 (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 203 arg.sid = sid; 204 arg.access_mask = STANDARD_RIGHTS_REQUIRED 205 #if 0 206 | POLICY_VIEW_AUDIT_INFORMATION 207 | POLICY_GET_PRIVATE_INFORMATION 208 | POLICY_TRUST_ADMIN 209 #endif 210 | POLICY_VIEW_LOCAL_INFORMATION; 211 212 if ((rc = ndr_rpc_call(lsa_handle, opnum, &arg)) != 0) 213 return (-1); 214 215 if (arg.status != 0) { 216 rc = -1; 217 } else { 218 ndr_inherit_handle(lsa_account_handle, lsa_handle); 219 220 (void) memcpy(&lsa_account_handle->handle, 221 &arg.account_handle, sizeof (ndr_hdid_t)); 222 223 if (ndr_is_null_handle(lsa_account_handle)) 224 rc = -1; 225 } 226 227 ndr_rpc_release(lsa_handle); 228 return (rc); 229 } 230 231 /* 232 * lsar_close 233 * 234 * Close the LSA connection associated with the handle. The lsa_handle 235 * must be a valid handle obtained via a call to lsar_open_policy2 or 236 * lsar_open_account. On success the handle will be zeroed out to 237 * ensure that it is not used again. If this is the top level handle 238 * (i.e. the one obtained via lsar_open_policy2) the pipe is closed. 239 * 240 * Returns 0 on success. Otherwise non-zero to indicate a failure. 241 */ 242 int 243 lsar_close(mlsvc_handle_t *lsa_handle) 244 { 245 struct mslsa_CloseHandle arg; 246 int opnum; 247 248 if (ndr_is_null_handle(lsa_handle)) 249 return (-1); 250 251 opnum = LSARPC_OPNUM_CloseHandle; 252 bzero(&arg, sizeof (struct mslsa_CloseHandle)); 253 (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 254 255 (void) ndr_rpc_call(lsa_handle, opnum, &arg); 256 ndr_rpc_release(lsa_handle); 257 258 if (ndr_is_bind_handle(lsa_handle)) 259 ndr_rpc_unbind(lsa_handle); 260 261 bzero(lsa_handle, sizeof (mlsvc_handle_t)); 262 return (0); 263 } 264 265 /* 266 * lsar_query_security_desc 267 * 268 * Don't use this call yet. It is just a place holder for now. 269 */ 270 int 271 lsar_query_security_desc(mlsvc_handle_t *lsa_handle) 272 { 273 struct mslsa_QuerySecurityObject arg; 274 int rc; 275 int opnum; 276 277 opnum = LSARPC_OPNUM_QuerySecurityObject; 278 279 bzero(&arg, sizeof (struct mslsa_QuerySecurityObject)); 280 (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 281 282 rc = ndr_rpc_call(lsa_handle, opnum, &arg); 283 ndr_rpc_release(lsa_handle); 284 return (rc); 285 } 286 287 /* 288 * lsar_query_info_policy 289 * 290 * The general purpose of this function is to allow various pieces of 291 * information to be queried on the domain controller. The only 292 * information queries supported are MSLSA_POLICY_PRIMARY_DOMAIN_INFO 293 * and MSLSA_POLICY_ACCOUNT_DOMAIN_INFO. 294 * 295 * On success, the return code will be 0 and the user_info structure 296 * will be set up. The sid_name_use field will be set to SidTypeDomain 297 * indicating that the domain name and domain sid fields are vaild. If 298 * the infoClass returned from the server is not one of the supported 299 * values, the sid_name_use willbe set to SidTypeUnknown. If the RPC 300 * fails, a negative error code will be returned, in which case the 301 * user_info will not have been updated. 302 */ 303 DWORD 304 lsar_query_info_policy(mlsvc_handle_t *lsa_handle, WORD infoClass, 305 smb_domain_t *info) 306 { 307 struct mslsa_QueryInfoPolicy arg; 308 struct mslsa_PrimaryDomainInfo *pd_info; 309 struct mslsa_AccountDomainInfo *ad_info; 310 struct mslsa_DnsDomainInfo *dns_info; 311 char guid_str[UUID_PRINTABLE_STRING_LENGTH]; 312 char sidstr[SMB_SID_STRSZ]; 313 int opnum; 314 DWORD status; 315 316 if (lsa_handle == NULL || info == NULL) 317 return (NT_STATUS_INVALID_PARAMETER); 318 319 opnum = LSARPC_OPNUM_QueryInfoPolicy; 320 321 bzero(info, sizeof (smb_domain_t)); 322 bzero(&arg, sizeof (struct mslsa_QueryInfoPolicy)); 323 (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 324 325 arg.info_class = infoClass; 326 327 if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { 328 status = NT_STATUS_INVALID_PARAMETER; 329 } else if (arg.status != 0) { 330 ndr_rpc_status(lsa_handle, opnum, arg.status); 331 status = NT_SC_VALUE(arg.status); 332 } else { 333 334 switch (infoClass) { 335 case MSLSA_POLICY_PRIMARY_DOMAIN_INFO: 336 pd_info = &arg.ru.pd_info; 337 338 smb_sid_tostr((smb_sid_t *)pd_info->sid, sidstr); 339 info->di_type = SMB_DOMAIN_PRIMARY; 340 smb_domain_set_basic_info(sidstr, 341 (char *)pd_info->name.str, "", info); 342 343 status = NT_STATUS_SUCCESS; 344 break; 345 346 case MSLSA_POLICY_ACCOUNT_DOMAIN_INFO: 347 ad_info = &arg.ru.ad_info; 348 349 smb_sid_tostr((smb_sid_t *)ad_info->sid, sidstr); 350 info->di_type = SMB_DOMAIN_ACCOUNT; 351 smb_domain_set_basic_info(sidstr, 352 (char *)ad_info->name.str, "", info); 353 354 status = NT_STATUS_SUCCESS; 355 break; 356 357 case MSLSA_POLICY_DNS_DOMAIN_INFO: 358 dns_info = &arg.ru.dns_info; 359 ndr_uuid_unparse((ndr_uuid_t *)&dns_info->guid, 360 guid_str); 361 smb_sid_tostr((smb_sid_t *)dns_info->sid, sidstr); 362 363 info->di_type = SMB_DOMAIN_PRIMARY; 364 smb_domain_set_dns_info(sidstr, 365 (char *)dns_info->nb_domain.str, 366 (char *)dns_info->dns_domain.str, 367 (char *)dns_info->forest.str, 368 guid_str, info); 369 status = NT_STATUS_SUCCESS; 370 break; 371 372 default: 373 status = NT_STATUS_INVALID_INFO_CLASS; 374 break; 375 } 376 } 377 378 ndr_rpc_release(lsa_handle); 379 return (status); 380 } 381 382 /* 383 * Lookup a name and obtain the sid/rid. 384 * This is a wrapper for the various lookup sid RPCs. 385 */ 386 uint32_t 387 lsar_lookup_names(mlsvc_handle_t *lsa_handle, char *name, smb_account_t *info) 388 { 389 static lsar_nameop_t ops[] = { 390 lsar_lookup_names3, 391 lsar_lookup_names2, 392 lsar_lookup_names1 393 }; 394 395 const srvsvc_server_info_t *svinfo; 396 lsa_names_t names; 397 char *p; 398 uint32_t length; 399 uint32_t status = NT_STATUS_INVALID_PARAMETER; 400 int n_op = (sizeof (ops) / sizeof (ops[0])); 401 int i; 402 403 if (lsa_handle == NULL || name == NULL || info == NULL) 404 return (NT_STATUS_INVALID_PARAMETER); 405 406 bzero(info, sizeof (smb_account_t)); 407 408 svinfo = ndr_rpc_server_info(lsa_handle); 409 if (svinfo->sv_os == NATIVE_OS_WIN2000 && 410 svinfo->sv_version_major == 5 && svinfo->sv_version_minor == 0) { 411 /* 412 * Windows 2000 doesn't like an LSA lookup for 413 * DOMAIN\Administrator. 414 */ 415 if ((p = strchr(name, '\\')) != 0) { 416 ++p; 417 418 if (strcasecmp(p, "administrator") == 0) 419 name = p; 420 } 421 422 } 423 424 length = smb_wcequiv_strlen(name); 425 names.name[0].length = length; 426 names.name[0].allosize = length; 427 names.name[0].str = (unsigned char *)name; 428 names.n_entry = 1; 429 430 if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000) { 431 for (i = 0; i < n_op; ++i) { 432 ndr_rpc_set_nonull(lsa_handle); 433 status = (*ops[i])(lsa_handle, &names, info); 434 435 if (status != NT_STATUS_INVALID_PARAMETER) 436 break; 437 } 438 } else { 439 ndr_rpc_set_nonull(lsa_handle); 440 status = lsar_lookup_names1(lsa_handle, &names, info); 441 } 442 443 if (status == NT_STATUS_SUCCESS) { 444 info->a_name = lsar_get_username(name); 445 446 if (!smb_account_validate(info)) { 447 smb_account_free(info); 448 status = NT_STATUS_NO_MEMORY; 449 } else { 450 smb_account_trace(info); 451 } 452 } 453 454 return (status); 455 } 456 457 /* 458 * The name may be in one of the following forms: 459 * 460 * domain\username 461 * domain/username 462 * username 463 * username@domain 464 * 465 * Return a strdup'd copy of the username. The caller is responsible 466 * for freeing the allocated memory. 467 */ 468 static char * 469 lsar_get_username(const char *name) 470 { 471 char tmp[MAXNAMELEN]; 472 char *dp = NULL; 473 char *np = NULL; 474 475 (void) strlcpy(tmp, name, MAXNAMELEN); 476 smb_name_parse(tmp, &np, &dp); 477 478 if (dp != NULL && np != NULL) 479 return (strdup(np)); 480 else 481 return (strdup(name)); 482 } 483 484 /* 485 * lsar_lookup_names1 486 * 487 * Lookup a name and obtain the domain and user rid. 488 * 489 * Note: NT returns an error if the mapped_count is non-zero when the RPC 490 * is called. 491 * 492 * If the lookup fails, the status will typically be NT_STATUS_NONE_MAPPED. 493 */ 494 static uint32_t 495 lsar_lookup_names1(mlsvc_handle_t *lsa_handle, lsa_names_t *names, 496 smb_account_t *info) 497 { 498 struct mslsa_LookupNames arg; 499 struct mslsa_rid_entry *rid_entry; 500 struct mslsa_domain_entry *domain_entry; 501 uint32_t status = NT_STATUS_SUCCESS; 502 char *domname; 503 int opnum = LSARPC_OPNUM_LookupNames; 504 505 bzero(&arg, sizeof (struct mslsa_LookupNames)); 506 (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 507 arg.lookup_level = LSA_LOOKUP_WKSTA; 508 arg.name_table = (struct mslsa_lup_name_table *)names; 509 510 if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { 511 ndr_rpc_release(lsa_handle); 512 return (NT_STATUS_INVALID_PARAMETER); 513 } 514 515 if (arg.status != NT_STATUS_SUCCESS) { 516 ndr_rpc_status(lsa_handle, opnum, arg.status); 517 ndr_rpc_release(lsa_handle); 518 return (NT_SC_VALUE(arg.status)); 519 } 520 521 if (arg.mapped_count == 0) { 522 ndr_rpc_release(lsa_handle); 523 return (NT_STATUS_NONE_MAPPED); 524 } 525 526 rid_entry = &arg.translated_sids.rids[0]; 527 if (rid_entry->domain_index != 0) { 528 ndr_rpc_release(lsa_handle); 529 return (NT_STATUS_NONE_MAPPED); 530 } 531 532 domain_entry = &arg.domain_table->entries[0]; 533 534 info->a_type = rid_entry->sid_name_use; 535 info->a_domsid = smb_sid_dup((smb_sid_t *)domain_entry->domain_sid); 536 if ((domname = (char *)domain_entry->domain_name.str) != NULL) 537 info->a_domain = strdup(domname); 538 info->a_rid = rid_entry->rid; 539 info->a_sid = smb_sid_splice(info->a_domsid, info->a_rid); 540 541 ndr_rpc_release(lsa_handle); 542 return (status); 543 } 544 545 /* 546 * lsar_lookup_names2 547 */ 548 static uint32_t 549 lsar_lookup_names2(mlsvc_handle_t *lsa_handle, lsa_names_t *names, 550 smb_account_t *info) 551 { 552 struct lsar_LookupNames2 arg; 553 struct lsar_rid_entry2 *rid_entry; 554 struct mslsa_domain_entry *domain_entry; 555 uint32_t status = NT_STATUS_SUCCESS; 556 char *domname; 557 int opnum = LSARPC_OPNUM_LookupNames2; 558 559 bzero(&arg, sizeof (struct lsar_LookupNames2)); 560 (void) memcpy(&arg.policy_handle, lsa_handle, sizeof (mslsa_handle_t)); 561 arg.lookup_level = LSA_LOOKUP_WKSTA; 562 arg.client_revision = LSA_CLIENT_REVISION_AD; 563 arg.name_table = (struct mslsa_lup_name_table *)names; 564 565 if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { 566 ndr_rpc_release(lsa_handle); 567 return (NT_STATUS_INVALID_PARAMETER); 568 } 569 570 if (arg.status != NT_STATUS_SUCCESS) { 571 ndr_rpc_status(lsa_handle, opnum, arg.status); 572 ndr_rpc_release(lsa_handle); 573 return (NT_SC_VALUE(arg.status)); 574 } 575 576 if (arg.mapped_count == 0) { 577 ndr_rpc_release(lsa_handle); 578 return (NT_STATUS_NONE_MAPPED); 579 } 580 581 rid_entry = &arg.translated_sids.rids[0]; 582 if (rid_entry->domain_index != 0) { 583 ndr_rpc_release(lsa_handle); 584 return (NT_STATUS_NONE_MAPPED); 585 } 586 587 domain_entry = &arg.domain_table->entries[0]; 588 589 info->a_type = rid_entry->sid_name_use; 590 info->a_domsid = smb_sid_dup((smb_sid_t *)domain_entry->domain_sid); 591 if ((domname = (char *)domain_entry->domain_name.str) != NULL) 592 info->a_domain = strdup(domname); 593 info->a_rid = rid_entry->rid; 594 info->a_sid = smb_sid_splice(info->a_domsid, info->a_rid); 595 596 ndr_rpc_release(lsa_handle); 597 return (status); 598 } 599 600 /* 601 * lsar_lookup_names3 602 */ 603 static uint32_t 604 lsar_lookup_names3(mlsvc_handle_t *lsa_handle, lsa_names_t *names, 605 smb_account_t *info) 606 { 607 struct lsar_LookupNames3 arg; 608 lsar_translated_sid_ex2_t *sid_entry; 609 struct mslsa_domain_entry *domain_entry; 610 uint32_t status = NT_STATUS_SUCCESS; 611 char *domname; 612 int opnum = LSARPC_OPNUM_LookupNames3; 613 614 bzero(&arg, sizeof (struct lsar_LookupNames3)); 615 (void) memcpy(&arg.policy_handle, lsa_handle, sizeof (mslsa_handle_t)); 616 arg.lookup_level = LSA_LOOKUP_WKSTA; 617 arg.client_revision = LSA_CLIENT_REVISION_AD; 618 arg.name_table = (struct mslsa_lup_name_table *)names; 619 620 if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { 621 ndr_rpc_release(lsa_handle); 622 return (NT_STATUS_INVALID_PARAMETER); 623 } 624 625 if (arg.status != NT_STATUS_SUCCESS) { 626 ndr_rpc_status(lsa_handle, opnum, arg.status); 627 ndr_rpc_release(lsa_handle); 628 return (NT_SC_VALUE(arg.status)); 629 } 630 631 if (arg.mapped_count == 0) { 632 ndr_rpc_release(lsa_handle); 633 return (NT_STATUS_NONE_MAPPED); 634 } 635 636 sid_entry = &arg.translated_sids.sids[0]; 637 if (sid_entry->domain_index != 0) { 638 ndr_rpc_release(lsa_handle); 639 return (NT_STATUS_NONE_MAPPED); 640 } 641 642 domain_entry = &arg.domain_table->entries[0]; 643 644 info->a_type = sid_entry->sid_name_use; 645 info->a_domsid = smb_sid_dup((smb_sid_t *)domain_entry->domain_sid); 646 if ((domname = (char *)domain_entry->domain_name.str) != NULL) 647 info->a_domain = strdup(domname); 648 info->a_sid = smb_sid_dup((smb_sid_t *)sid_entry->sid); 649 (void) smb_sid_getrid(info->a_sid, &info->a_rid); 650 651 ndr_rpc_release(lsa_handle); 652 return (status); 653 } 654 655 /* 656 * lsar_lookup_names4 657 * 658 * This function is only valid if the remote RPC server is a domain 659 * controller and requires the security extensions defined in MS-RPCE. 660 * 661 * Domain controllers will return RPC_NT_PROTSEQ_NOT_SUPPORTED here 662 * because we don't support the RPC_C_AUTHN_NETLOGON security provider. 663 * Non-domain controllers will return NT_STATUS_INVALID_SERVER_STATE. 664 */ 665 static uint32_t /*LINTED E_STATIC_UNUSED*/ 666 lsar_lookup_names4(mlsvc_handle_t *lsa_handle, lsa_names_t *names, 667 smb_account_t *info) 668 { 669 struct lsar_LookupNames4 arg; 670 lsar_translated_sid_ex2_t *sid_entry; 671 struct mslsa_domain_entry *domain_entry; 672 uint32_t status = NT_STATUS_SUCCESS; 673 char *domname; 674 int opnum = LSARPC_OPNUM_LookupNames4; 675 676 bzero(&arg, sizeof (struct lsar_LookupNames4)); 677 arg.lookup_level = LSA_LOOKUP_WKSTA; 678 arg.client_revision = LSA_CLIENT_REVISION_AD; 679 arg.name_table = (struct mslsa_lup_name_table *)names; 680 681 if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { 682 ndr_rpc_release(lsa_handle); 683 return (NT_STATUS_INVALID_PARAMETER); 684 } 685 686 if (arg.status != NT_STATUS_SUCCESS) { 687 ndr_rpc_status(lsa_handle, opnum, arg.status); 688 ndr_rpc_release(lsa_handle); 689 if (arg.status == RPC_NT_PROTSEQ_NOT_SUPPORTED || 690 arg.status == NT_STATUS_INVALID_SERVER_STATE) 691 return (NT_STATUS_INVALID_PARAMETER); 692 return (NT_SC_VALUE(arg.status)); 693 } 694 695 if (arg.mapped_count == 0) { 696 ndr_rpc_release(lsa_handle); 697 return (NT_STATUS_NONE_MAPPED); 698 } 699 700 sid_entry = &arg.translated_sids.sids[0]; 701 if (sid_entry->domain_index != 0) { 702 ndr_rpc_release(lsa_handle); 703 return (NT_STATUS_NONE_MAPPED); 704 } 705 706 domain_entry = &arg.domain_table->entries[0]; 707 708 info->a_type = sid_entry->sid_name_use; 709 info->a_domsid = smb_sid_dup((smb_sid_t *)domain_entry->domain_sid); 710 if ((domname = (char *)domain_entry->domain_name.str) != NULL) 711 info->a_domain = strdup(domname); 712 info->a_sid = smb_sid_dup((smb_sid_t *)sid_entry->sid); 713 (void) smb_sid_getrid(info->a_sid, &info->a_rid); 714 715 ndr_rpc_release(lsa_handle); 716 return (status); 717 } 718 719 /* 720 * Lookup a sid and obtain the domain sid and account name. 721 * This is a wrapper for the various lookup sid RPCs. 722 */ 723 uint32_t 724 lsar_lookup_sids(mlsvc_handle_t *lsa_handle, smb_sid_t *sid, 725 smb_account_t *account) 726 { 727 char sidbuf[SMB_SID_STRSZ]; 728 uint32_t status; 729 730 if (lsa_handle == NULL || sid == NULL || account == NULL) 731 return (NT_STATUS_INVALID_PARAMETER); 732 733 bzero(account, sizeof (smb_account_t)); 734 bzero(sidbuf, SMB_SID_STRSZ); 735 smb_sid_tostr(sid, sidbuf); 736 smb_tracef("%s", sidbuf); 737 738 if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000) 739 status = lsar_lookup_sids2(lsa_handle, (lsa_sid_t *)sid, 740 account); 741 else 742 status = lsar_lookup_sids1(lsa_handle, (lsa_sid_t *)sid, 743 account); 744 745 if (status == NT_STATUS_SUCCESS) { 746 if (!smb_account_validate(account)) { 747 smb_account_free(account); 748 status = NT_STATUS_NO_MEMORY; 749 } else { 750 smb_account_trace(account); 751 } 752 } 753 754 return (status); 755 } 756 757 /* 758 * lsar_lookup_sids1 759 */ 760 static uint32_t 761 lsar_lookup_sids1(mlsvc_handle_t *lsa_handle, lsa_sid_t *sid, 762 smb_account_t *account) 763 { 764 struct mslsa_LookupSids arg; 765 struct mslsa_lup_sid_entry sid_entry; 766 struct mslsa_name_entry *name_entry; 767 struct mslsa_domain_entry *domain_entry; 768 uint32_t status = NT_STATUS_SUCCESS; 769 char *name; 770 int opnum = LSARPC_OPNUM_LookupSids; 771 772 bzero(&arg, sizeof (struct mslsa_LookupSids)); 773 (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 774 arg.lookup_level = LSA_LOOKUP_WKSTA; 775 776 sid_entry.psid = sid; 777 arg.lup_sid_table.n_entry = 1; 778 arg.lup_sid_table.entries = &sid_entry; 779 780 if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { 781 ndr_rpc_release(lsa_handle); 782 return (NT_STATUS_INVALID_PARAMETER); 783 } 784 785 if (arg.status != NT_STATUS_SUCCESS) { 786 ndr_rpc_status(lsa_handle, opnum, arg.status); 787 ndr_rpc_release(lsa_handle); 788 return (NT_SC_VALUE(arg.status)); 789 } 790 791 if (arg.mapped_count == 0) { 792 ndr_rpc_release(lsa_handle); 793 return (NT_STATUS_NONE_MAPPED); 794 } 795 796 name_entry = &arg.name_table.entries[0]; 797 if (name_entry->domain_ix != 0) { 798 ndr_rpc_release(lsa_handle); 799 return (NT_STATUS_NONE_MAPPED); 800 } 801 802 name = (char *)name_entry->name.str; 803 account->a_name = (name) ? strdup(name) : strdup(""); 804 account->a_type = name_entry->sid_name_use; 805 account->a_sid = smb_sid_dup((smb_sid_t *)sid); 806 (void) smb_sid_getrid(account->a_sid, &account->a_rid); 807 808 domain_entry = &arg.domain_table->entries[0]; 809 if ((name = (char *)domain_entry->domain_name.str) != NULL) 810 account->a_domain = strdup(name); 811 account->a_domsid = smb_sid_dup((smb_sid_t *)domain_entry->domain_sid); 812 813 ndr_rpc_release(lsa_handle); 814 return (status); 815 } 816 817 /* 818 * lsar_lookup_sids2 819 */ 820 static uint32_t 821 lsar_lookup_sids2(mlsvc_handle_t *lsa_handle, lsa_sid_t *sid, 822 smb_account_t *account) 823 { 824 struct lsar_lookup_sids2 arg; 825 struct lsar_name_entry2 *name_entry; 826 struct mslsa_lup_sid_entry sid_entry; 827 struct mslsa_domain_entry *domain_entry; 828 uint32_t status = NT_STATUS_SUCCESS; 829 char *name; 830 int opnum = LSARPC_OPNUM_LookupSids2; 831 832 bzero(&arg, sizeof (struct lsar_lookup_sids2)); 833 (void) memcpy(&arg.policy_handle, lsa_handle, sizeof (mslsa_handle_t)); 834 835 sid_entry.psid = sid; 836 arg.lup_sid_table.n_entry = 1; 837 arg.lup_sid_table.entries = &sid_entry; 838 arg.lookup_level = LSA_LOOKUP_WKSTA; 839 arg.client_revision = LSA_CLIENT_REVISION_AD; 840 841 if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { 842 ndr_rpc_release(lsa_handle); 843 return (NT_STATUS_INVALID_PARAMETER); 844 } 845 846 if (arg.status != NT_STATUS_SUCCESS) { 847 ndr_rpc_status(lsa_handle, opnum, arg.status); 848 ndr_rpc_release(lsa_handle); 849 return (NT_SC_VALUE(arg.status)); 850 } 851 852 if (arg.mapped_count == 0) { 853 ndr_rpc_release(lsa_handle); 854 return (NT_STATUS_NONE_MAPPED); 855 } 856 857 name_entry = &arg.name_table.entries[0]; 858 if (name_entry->domain_ix != 0) { 859 ndr_rpc_release(lsa_handle); 860 return (NT_STATUS_NONE_MAPPED); 861 } 862 863 name = (char *)name_entry->name.str; 864 account->a_name = (name) ? strdup(name) : strdup(""); 865 account->a_type = name_entry->sid_name_use; 866 account->a_sid = smb_sid_dup((smb_sid_t *)sid); 867 (void) smb_sid_getrid(account->a_sid, &account->a_rid); 868 869 domain_entry = &arg.domain_table->entries[0]; 870 if ((name = (char *)domain_entry->domain_name.str) != NULL) 871 account->a_domain = strdup(name); 872 account->a_domsid = smb_sid_dup((smb_sid_t *)domain_entry->domain_sid); 873 874 ndr_rpc_release(lsa_handle); 875 return (status); 876 } 877 878 /* 879 * lsar_lookup_sids3 880 * 881 * This function is only valid if the remote RPC server is a domain 882 * controller and requires the security extensions defined in MS-RPCE. 883 * 884 * Domain controllers will return RPC_NT_PROTSEQ_NOT_SUPPORTED here 885 * because we don't support the RPC_C_AUTHN_NETLOGON security provider. 886 * Non-domain controllers will return NT_STATUS_INVALID_SERVER_STATE. 887 */ 888 static uint32_t /*LINTED E_STATIC_UNUSED*/ 889 lsar_lookup_sids3(mlsvc_handle_t *lsa_handle, lsa_sid_t *sid, 890 smb_account_t *account) 891 { 892 struct lsar_lookup_sids3 arg; 893 lsar_translated_name_ex_t *name_entry; 894 struct mslsa_lup_sid_entry sid_entry; 895 struct mslsa_domain_entry *domain_entry; 896 uint32_t status = NT_STATUS_SUCCESS; 897 char *name; 898 int opnum = LSARPC_OPNUM_LookupSids3; 899 900 bzero(&arg, sizeof (struct lsar_lookup_sids3)); 901 902 sid_entry.psid = sid; 903 arg.lup_sid_table.n_entry = 1; 904 arg.lup_sid_table.entries = &sid_entry; 905 arg.lookup_level = LSA_LOOKUP_WKSTA; 906 arg.client_revision = LSA_CLIENT_REVISION_AD; 907 908 if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { 909 ndr_rpc_release(lsa_handle); 910 return (NT_STATUS_INVALID_PARAMETER); 911 } 912 913 if (arg.status != NT_STATUS_SUCCESS) { 914 ndr_rpc_status(lsa_handle, opnum, arg.status); 915 ndr_rpc_release(lsa_handle); 916 if (arg.status == RPC_NT_PROTSEQ_NOT_SUPPORTED || 917 arg.status == NT_STATUS_INVALID_SERVER_STATE) 918 return (NT_STATUS_INVALID_PARAMETER); 919 return (NT_SC_VALUE(arg.status)); 920 } 921 922 if (arg.mapped_count == 0) { 923 ndr_rpc_release(lsa_handle); 924 return (NT_STATUS_NONE_MAPPED); 925 } 926 927 name_entry = &arg.name_table.entries[0]; 928 if (name_entry->domain_ix != 0) { 929 ndr_rpc_release(lsa_handle); 930 return (NT_STATUS_NONE_MAPPED); 931 } 932 933 name = (char *)name_entry->name.str; 934 account->a_name = (name) ? strdup(name) : strdup(""); 935 account->a_type = name_entry->sid_name_use; 936 account->a_sid = smb_sid_dup((smb_sid_t *)sid); 937 (void) smb_sid_getrid(account->a_sid, &account->a_rid); 938 939 domain_entry = &arg.domain_table->entries[0]; 940 if ((name = (char *)domain_entry->domain_name.str) != NULL) 941 account->a_domain = strdup(name); 942 account->a_domsid = smb_sid_dup((smb_sid_t *)domain_entry->domain_sid); 943 944 ndr_rpc_release(lsa_handle); 945 return (status); 946 } 947 948 /* 949 * lsar_enum_accounts 950 * 951 * Enumerate the list of accounts (i.e. SIDs). Use the handle returned 952 * from lsa_open_policy2. The enum_context is used to support multiple 953 * calls to this enumeration function. It should be set to 0 on the 954 * first call. It will be updated by the domain controller and should 955 * simply be passed unchanged to subsequent calls until there are no 956 * more accounts. A warning status of 0x1A indicates that no more data 957 * is available. The list of accounts will be returned in accounts. 958 * This list is dynamically allocated using malloc, it should be freed 959 * by the caller when it is no longer required. 960 */ 961 int 962 lsar_enum_accounts(mlsvc_handle_t *lsa_handle, DWORD *enum_context, 963 struct mslsa_EnumAccountBuf *accounts) 964 { 965 struct mslsa_EnumerateAccounts arg; 966 struct mslsa_AccountInfo *info; 967 int opnum; 968 int rc; 969 DWORD n_entries; 970 DWORD i; 971 int nbytes; 972 973 if (lsa_handle == NULL || enum_context == NULL || accounts == NULL) 974 return (-1); 975 976 accounts->entries_read = 0; 977 accounts->info = 0; 978 979 opnum = LSARPC_OPNUM_EnumerateAccounts; 980 981 bzero(&arg, sizeof (struct mslsa_EnumerateAccounts)); 982 (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 983 arg.enum_context = *enum_context; 984 arg.max_length = MLSVC_MAX_RESPONSE_LEN; 985 986 rc = ndr_rpc_call(lsa_handle, opnum, &arg); 987 if (rc == 0) { 988 if (arg.status != 0) { 989 if ((arg.status & 0x00FFFFFF) == 990 NT_STATUS_NO_MORE_DATA) { 991 *enum_context = arg.enum_context; 992 } else { 993 ndr_rpc_status(lsa_handle, opnum, arg.status); 994 rc = -1; 995 } 996 } else if (arg.enum_buf->entries_read != 0) { 997 n_entries = arg.enum_buf->entries_read; 998 nbytes = n_entries * sizeof (struct mslsa_AccountInfo); 999 1000 if ((info = malloc(nbytes)) == NULL) { 1001 ndr_rpc_release(lsa_handle); 1002 return (-1); 1003 } 1004 1005 for (i = 0; i < n_entries; ++i) 1006 info[i].sid = (lsa_sid_t *)smb_sid_dup( 1007 (smb_sid_t *)arg.enum_buf->info[i].sid); 1008 1009 accounts->entries_read = n_entries; 1010 accounts->info = info; 1011 *enum_context = arg.enum_context; 1012 } 1013 } 1014 1015 ndr_rpc_release(lsa_handle); 1016 return (rc); 1017 } 1018 1019 /* 1020 * lsar_enum_trusted_domains 1021 * 1022 * Enumerate the list of trusted domains. Use the handle returned from 1023 * lsa_open_policy2. The enum_context is used to support multiple calls 1024 * to this enumeration function. It should be set to 0 on the first 1025 * call. It will be updated by the domain controller and should simply 1026 * be passed unchanged to subsequent calls until there are no more 1027 * domains. 1028 * 1029 * The trusted domains aren't actually returned here. They are added 1030 * to the NT domain database. After all of the trusted domains have 1031 * been discovered, the database can be interrogated to find all of 1032 * the trusted domains. 1033 */ 1034 DWORD 1035 lsar_enum_trusted_domains(mlsvc_handle_t *lsa_handle, DWORD *enum_context, 1036 smb_trusted_domains_t *list) 1037 { 1038 struct mslsa_EnumTrustedDomain arg; 1039 int opnum; 1040 DWORD status; 1041 1042 if (list == NULL) 1043 return (NT_STATUS_INVALID_PARAMETER); 1044 1045 opnum = LSARPC_OPNUM_EnumTrustedDomain; 1046 1047 bzero(list, sizeof (smb_trusted_domains_t)); 1048 bzero(&arg, sizeof (struct mslsa_EnumTrustedDomain)); 1049 (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 1050 arg.enum_context = *enum_context; 1051 arg.max_length = MLSVC_MAX_RESPONSE_LEN; 1052 1053 if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { 1054 status = NT_STATUS_INVALID_PARAMETER; 1055 } else if (arg.status != 0) { 1056 *enum_context = arg.enum_context; 1057 status = NT_SC_VALUE(arg.status); 1058 1059 /* 1060 * status 0x8000001A means NO_MORE_DATA, 1061 * which is not an error. 1062 */ 1063 if (status != NT_STATUS_NO_MORE_DATA) 1064 ndr_rpc_status(lsa_handle, opnum, arg.status); 1065 } else if (arg.enum_buf->entries_read == 0) { 1066 *enum_context = arg.enum_context; 1067 status = 0; 1068 } else { 1069 lsar_set_trusted_domains(arg.enum_buf, list); 1070 *enum_context = arg.enum_context; 1071 status = 0; 1072 } 1073 1074 ndr_rpc_release(lsa_handle); 1075 return (status); 1076 } 1077 1078 DWORD 1079 lsar_enum_trusted_domains_ex(mlsvc_handle_t *lsa_handle, DWORD *enum_context, 1080 smb_trusted_domains_t *list) 1081 { 1082 struct mslsa_EnumTrustedDomainEx arg; 1083 int opnum; 1084 DWORD status; 1085 1086 if (list == NULL) 1087 return (NT_STATUS_INVALID_PARAMETER); 1088 1089 opnum = LSARPC_OPNUM_EnumTrustedDomainsEx; 1090 1091 bzero(list, sizeof (smb_trusted_domains_t)); 1092 bzero(&arg, sizeof (struct mslsa_EnumTrustedDomainEx)); 1093 (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 1094 arg.enum_context = *enum_context; 1095 arg.max_length = MLSVC_MAX_RESPONSE_LEN; 1096 1097 if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) { 1098 status = NT_STATUS_INVALID_PARAMETER; 1099 } else if (arg.status != 0) { 1100 *enum_context = arg.enum_context; 1101 status = NT_SC_VALUE(arg.status); 1102 1103 /* 1104 * status 0x8000001A means NO_MORE_DATA, 1105 * which is not an error. 1106 */ 1107 if (status != NT_STATUS_NO_MORE_DATA) 1108 ndr_rpc_status(lsa_handle, opnum, arg.status); 1109 } else if (arg.enum_buf->entries_read == 0) { 1110 *enum_context = arg.enum_context; 1111 status = 0; 1112 } else { 1113 lsar_set_trusted_domains_ex(arg.enum_buf, list); 1114 *enum_context = arg.enum_context; 1115 status = 0; 1116 } 1117 1118 ndr_rpc_release(lsa_handle); 1119 return (status); 1120 } 1121 1122 /* 1123 * lsar_enum_privs_account 1124 * 1125 * Privileges enum? Need an account handle. 1126 */ 1127 /*ARGSUSED*/ 1128 int 1129 lsar_enum_privs_account(mlsvc_handle_t *account_handle, smb_account_t *account) 1130 { 1131 struct mslsa_EnumPrivsAccount arg; 1132 int opnum; 1133 int rc; 1134 1135 opnum = LSARPC_OPNUM_EnumPrivsAccount; 1136 1137 bzero(&arg, sizeof (struct mslsa_EnumPrivsAccount)); 1138 (void) memcpy(&arg.account_handle, &account_handle->handle, 1139 sizeof (mslsa_handle_t)); 1140 1141 rc = ndr_rpc_call(account_handle, opnum, &arg); 1142 if ((rc == 0) && (arg.status != 0)) { 1143 ndr_rpc_status(account_handle, opnum, arg.status); 1144 rc = -1; 1145 } 1146 ndr_rpc_release(account_handle); 1147 return (rc); 1148 } 1149 1150 /* 1151 * lsar_lookup_priv_value 1152 * 1153 * Map a privilege name to a local unique id (LUID). Privilege names 1154 * are consistent across the network. LUIDs are machine specific. 1155 * This function provides the means to map a privilege name to the 1156 * LUID used by a remote server to represent it. The handle here is 1157 * a policy handle. 1158 */ 1159 int 1160 lsar_lookup_priv_value(mlsvc_handle_t *lsa_handle, char *name, 1161 struct ms_luid *luid) 1162 { 1163 struct mslsa_LookupPrivValue arg; 1164 int opnum; 1165 int rc; 1166 size_t length; 1167 1168 if (lsa_handle == NULL || name == NULL || luid == NULL) 1169 return (-1); 1170 1171 opnum = LSARPC_OPNUM_LookupPrivValue; 1172 1173 bzero(&arg, sizeof (struct mslsa_LookupPrivValue)); 1174 (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 1175 1176 length = smb_wcequiv_strlen(name); 1177 if (ndr_rpc_server_os(lsa_handle) == NATIVE_OS_WIN2000) 1178 length += sizeof (smb_wchar_t); 1179 1180 arg.name.length = length; 1181 arg.name.allosize = length; 1182 arg.name.str = (unsigned char *)name; 1183 1184 rc = ndr_rpc_call(lsa_handle, opnum, &arg); 1185 if (rc == 0) { 1186 if (arg.status != 0) 1187 rc = -1; 1188 else 1189 (void) memcpy(luid, &arg.luid, sizeof (struct ms_luid)); 1190 } 1191 1192 ndr_rpc_release(lsa_handle); 1193 return (rc); 1194 } 1195 1196 /* 1197 * lsar_lookup_priv_name 1198 * 1199 * Map a local unique id (LUID) to a privilege name. Privilege names 1200 * are consistent across the network. LUIDs are machine specific. 1201 * This function the means to map the LUID used by a remote server to 1202 * the appropriate privilege name. The handle here is a policy handle. 1203 */ 1204 int 1205 lsar_lookup_priv_name(mlsvc_handle_t *lsa_handle, struct ms_luid *luid, 1206 char *name, int namelen) 1207 { 1208 struct mslsa_LookupPrivName arg; 1209 int opnum; 1210 int rc; 1211 1212 if (lsa_handle == NULL || luid == NULL || name == NULL) 1213 return (-1); 1214 1215 opnum = LSARPC_OPNUM_LookupPrivName; 1216 1217 bzero(&arg, sizeof (struct mslsa_LookupPrivName)); 1218 (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 1219 (void) memcpy(&arg.luid, luid, sizeof (struct ms_luid)); 1220 1221 rc = ndr_rpc_call(lsa_handle, opnum, &arg); 1222 if (rc == 0) { 1223 if (arg.status != 0) 1224 rc = -1; 1225 else 1226 (void) strlcpy(name, (char const *)arg.name->str, 1227 namelen); 1228 } 1229 1230 ndr_rpc_release(lsa_handle); 1231 return (rc); 1232 } 1233 1234 /* 1235 * lsar_lookup_priv_display_name 1236 * 1237 * Map a privilege name to a privilege display name. The input handle 1238 * should be an LSA policy handle and the name would normally be one 1239 * of the privileges defined in smb_privilege.h 1240 * 1241 * There's something peculiar about the return status from NT servers, 1242 * it's not always present. So for now, I'm ignoring the status in the 1243 * RPC response. 1244 * 1245 * Returns NT status codes. 1246 */ 1247 DWORD 1248 lsar_lookup_priv_display_name(mlsvc_handle_t *lsa_handle, char *name, 1249 char *display_name, int display_len) 1250 { 1251 struct mslsa_LookupPrivDisplayName arg; 1252 int opnum; 1253 size_t length; 1254 DWORD status; 1255 1256 if (lsa_handle == NULL || name == NULL || display_name == NULL) 1257 return (NT_STATUS_INVALID_PARAMETER); 1258 1259 opnum = LSARPC_OPNUM_LookupPrivDisplayName; 1260 1261 bzero(&arg, sizeof (struct mslsa_LookupPrivDisplayName)); 1262 (void) memcpy(&arg.handle, lsa_handle, sizeof (mslsa_handle_t)); 1263 1264 length = smb_wcequiv_strlen(name); 1265 arg.name.length = length; 1266 arg.name.allosize = length; 1267 arg.name.str = (unsigned char *)name; 1268 1269 arg.client_language = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US); 1270 arg.default_language = MAKELANGID(LANG_ENGLISH, SUBLANG_NEUTRAL); 1271 1272 if (ndr_rpc_call(lsa_handle, opnum, &arg) != 0) 1273 status = NT_STATUS_INVALID_PARAMETER; 1274 #if 0 1275 else if (arg.status != 0) 1276 status = NT_SC_VALUE(arg.status); 1277 #endif 1278 else { 1279 (void) strlcpy(display_name, 1280 (char const *)arg.display_name->str, display_len); 1281 status = NT_STATUS_SUCCESS; 1282 } 1283 1284 ndr_rpc_release(lsa_handle); 1285 return (status); 1286 } 1287 1288 static void 1289 lsar_set_trusted_domains_ex(struct mslsa_EnumTrustedDomainBufEx *enum_buf, 1290 smb_trusted_domains_t *list) 1291 { 1292 char sidstr[SMB_SID_STRSZ]; 1293 int i; 1294 1295 if (list == NULL || enum_buf == NULL || enum_buf->entries_read == 0) 1296 return; 1297 1298 list->td_num = 0; 1299 list->td_domains = calloc(enum_buf->entries_read, 1300 sizeof (smb_domain_t)); 1301 1302 if (list->td_domains == NULL) 1303 return; 1304 1305 list->td_num = enum_buf->entries_read; 1306 for (i = 0; i < list->td_num; i++) { 1307 smb_sid_tostr((smb_sid_t *)enum_buf->info[i].sid, sidstr); 1308 smb_domain_set_trust_info( 1309 sidstr, 1310 (char *)enum_buf->info[i].nb_name.str, 1311 (char *)enum_buf->info[i].dns_name.str, 1312 enum_buf->info[i].trust_direction, 1313 enum_buf->info[i].trust_type, 1314 enum_buf->info[i].trust_attrs, 1315 &list->td_domains[i]); 1316 } 1317 } 1318 1319 static void 1320 lsar_set_trusted_domains(struct mslsa_EnumTrustedDomainBuf *enum_buf, 1321 smb_trusted_domains_t *list) 1322 { 1323 char sidstr[SMB_SID_STRSZ]; 1324 int i; 1325 1326 if (list == NULL || enum_buf == NULL || enum_buf->entries_read == 0) 1327 return; 1328 1329 list->td_num = 0; 1330 list->td_domains = calloc(enum_buf->entries_read, 1331 sizeof (smb_domain_t)); 1332 1333 if (list->td_domains == NULL) 1334 return; 1335 1336 list->td_num = enum_buf->entries_read; 1337 for (i = 0; i < list->td_num; i++) { 1338 smb_sid_tostr((smb_sid_t *)enum_buf->info[i].sid, sidstr); 1339 smb_domain_set_trust_info( 1340 sidstr, (char *)enum_buf->info[i].name.str, 1341 "", 0, 0, 0, &list->td_domains[i]); 1342 } 1343 } 1344 1345 static void 1346 smb_account_trace(const smb_account_t *info) 1347 { 1348 char sidbuf[SMB_SID_STRSZ]; 1349 1350 bzero(sidbuf, SMB_SID_STRSZ); 1351 smb_sid_tostr(info->a_sid, sidbuf); 1352 1353 smb_tracef("%s %s %s %lu %s", info->a_domain, info->a_name, 1354 sidbuf, info->a_rid, smb_sid_type2str(info->a_type)); 1355 } 1356