1 /* 2 * ReactOS kernel 3 * Copyright (C) 2004 ReactOS Team 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 /* 20 * COPYRIGHT: See COPYING in the top level directory 21 * PROJECT: ReactOS system libraries 22 * PURPOSE: SAM interface library 23 * FILE: lib/samlib/samlib.c 24 * PROGRAMER: Eric Kohl 25 */ 26 27 #include "precomp.h" 28 29 #define NTOS_MODE_USER 30 #include <ndk/rtlfuncs.h> 31 #include <ntsam.h> 32 #include <sam_c.h> 33 34 #include <wine/debug.h> 35 36 WINE_DEFAULT_DEBUG_CHANNEL(samlib); 37 38 NTSTATUS 39 WINAPI 40 SystemFunction006(LPCSTR password, 41 LPSTR hash); 42 43 NTSTATUS 44 WINAPI 45 SystemFunction007(PUNICODE_STRING string, 46 LPBYTE hash); 47 48 NTSTATUS 49 WINAPI 50 SystemFunction012(const BYTE *in, 51 const BYTE *key, 52 LPBYTE out); 53 54 /* GLOBALS *******************************************************************/ 55 56 57 /* FUNCTIONS *****************************************************************/ 58 59 void __RPC_FAR * __RPC_USER midl_user_allocate(SIZE_T len) 60 { 61 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); 62 } 63 64 65 void __RPC_USER midl_user_free(void __RPC_FAR * ptr) 66 { 67 HeapFree(GetProcessHeap(), 0, ptr); 68 } 69 70 71 handle_t __RPC_USER 72 PSAMPR_SERVER_NAME_bind(PSAMPR_SERVER_NAME pszSystemName) 73 { 74 handle_t hBinding = NULL; 75 LPWSTR pszStringBinding; 76 RPC_STATUS status; 77 78 TRACE("PSAMPR_SERVER_NAME_bind(%S)\n", pszSystemName); 79 80 /* Check the server name prefix and server name length */ 81 if (pszSystemName != NULL) 82 { 83 int nLength = wcslen(pszSystemName); 84 int nNameLength = nLength; 85 86 if (nLength >= 1 && pszSystemName[0] == L'\\') 87 nNameLength--; 88 89 if (nLength >= 2 && pszSystemName[1] == L'\\') 90 nNameLength--; 91 92 if (((nLength - nNameLength != 0) && 93 (nLength - nNameLength != 2)) || 94 (nNameLength == 0)) 95 { 96 WARN("Invalid server name %S", pszSystemName); 97 RpcRaiseException(STATUS_OBJECT_NAME_INVALID); 98 } 99 } 100 101 status = RpcStringBindingComposeW(NULL, 102 L"ncacn_np", 103 pszSystemName, 104 L"\\pipe\\samr", 105 NULL, 106 &pszStringBinding); 107 if (status) 108 { 109 TRACE("RpcStringBindingCompose returned 0x%x\n", status); 110 return NULL; 111 } 112 113 /* Set the binding handle that will be used to bind to the server. */ 114 status = RpcBindingFromStringBindingW(pszStringBinding, 115 &hBinding); 116 if (status) 117 { 118 TRACE("RpcBindingFromStringBinding returned 0x%x\n", status); 119 } 120 121 status = RpcStringFreeW(&pszStringBinding); 122 if (status) 123 { 124 // TRACE("RpcStringFree returned 0x%x\n", status); 125 } 126 127 return hBinding; 128 } 129 130 131 void __RPC_USER 132 PSAMPR_SERVER_NAME_unbind(PSAMPR_SERVER_NAME pszSystemName, 133 handle_t hBinding) 134 { 135 RPC_STATUS status; 136 137 TRACE("PSAMPR_SERVER_NAME_unbind(%S)\n", pszSystemName); 138 139 status = RpcBindingFree(&hBinding); 140 if (status) 141 { 142 TRACE("RpcBindingFree returned 0x%x\n", status); 143 } 144 } 145 146 147 NTSTATUS 148 SampCheckPassword(IN SAMPR_HANDLE UserHandle, 149 IN PUNICODE_STRING Password) 150 { 151 USER_DOMAIN_PASSWORD_INFORMATION DomainPasswordInformation; 152 LPWORD CharTypeBuffer = NULL; 153 ULONG PasswordLength; 154 ULONG i; 155 ULONG Upper = 0, Lower = 0, Digit = 0, Punct = 0, Alpha = 0; 156 NTSTATUS Status = STATUS_SUCCESS; 157 158 TRACE("SampCheckPassword(%p %p)\n", UserHandle, Password); 159 160 /* Get the domain password information */ 161 Status = SamrGetUserDomainPasswordInformation(UserHandle, 162 &DomainPasswordInformation); 163 if (!NT_SUCCESS(Status)) 164 { 165 TRACE("SamrGetUserDomainPasswordInformation failed (Status 0x%08lx)\n", Status); 166 return Status; 167 } 168 169 PasswordLength = (ULONG)(Password->Length / sizeof(WCHAR)); 170 171 /* Fail if the password is too short or too long */ 172 if ((PasswordLength < DomainPasswordInformation.MinPasswordLength) || 173 (PasswordLength > 256)) 174 return STATUS_PASSWORD_RESTRICTION; 175 176 /* Check the password complexity */ 177 if (DomainPasswordInformation.PasswordProperties & DOMAIN_PASSWORD_COMPLEX) 178 { 179 CharTypeBuffer = midl_user_allocate(PasswordLength * sizeof(WORD)); 180 if (CharTypeBuffer == NULL) 181 return STATUS_INSUFFICIENT_RESOURCES; 182 183 GetStringTypeW(CT_CTYPE1, 184 Password->Buffer, 185 PasswordLength, 186 CharTypeBuffer); 187 188 for (i = 0; i < PasswordLength; i++) 189 { 190 TRACE("%lu: %C %s %s %s %s\n", i, Password->Buffer[i], 191 (CharTypeBuffer[i] & C1_UPPER) ? "C1_UPPER" : " ", 192 (CharTypeBuffer[i] & C1_LOWER) ? "C1_LOWER" : " ", 193 (CharTypeBuffer[i] & C1_DIGIT) ? "C1_DIGIT" : " ", 194 (CharTypeBuffer[i] & C1_PUNCT) ? "C1_PUNCT" : " ", 195 (CharTypeBuffer[i] & C1_ALPHA) ? "C1_ALPHA" : " "); 196 197 if (CharTypeBuffer[i] & C1_UPPER) 198 Upper = 1; 199 200 if (CharTypeBuffer[i] & C1_LOWER) 201 Lower = 1; 202 203 if (CharTypeBuffer[i] & C1_DIGIT) 204 Digit = 1; 205 206 if (CharTypeBuffer[i] & C1_PUNCT) 207 Punct = 1; 208 209 if ((CharTypeBuffer[i] & C1_ALPHA) && 210 !(CharTypeBuffer[i] & C1_UPPER) && 211 !(CharTypeBuffer[i] & C1_LOWER)) 212 Alpha = 1; 213 } 214 215 TRACE("Upper: %lu\n", Upper); 216 TRACE("Lower: %lu\n", Lower); 217 TRACE("Digit: %lu\n", Digit); 218 TRACE("Punct: %lu\n", Punct); 219 TRACE("Alpha: %lu\n", Alpha); 220 221 TRACE("Total: %lu\n", Upper + Lower + Digit + Punct + Alpha); 222 if (Upper + Lower + Digit + Punct + Alpha < 3) 223 Status = STATUS_PASSWORD_RESTRICTION; 224 } 225 226 if (CharTypeBuffer != NULL) 227 midl_user_free(CharTypeBuffer); 228 229 return Status; 230 } 231 232 233 NTSTATUS 234 NTAPI 235 SamAddMemberToAlias(IN SAM_HANDLE AliasHandle, 236 IN PSID MemberId) 237 { 238 NTSTATUS Status; 239 240 TRACE("SamAddMemberToAlias(%p %p)\n", 241 AliasHandle, MemberId); 242 243 RpcTryExcept 244 { 245 Status = SamrAddMemberToAlias((SAMPR_HANDLE)AliasHandle, 246 (PRPC_SID)MemberId); 247 } 248 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 249 { 250 Status = I_RpcMapWin32Status(RpcExceptionCode()); 251 } 252 RpcEndExcept; 253 254 return Status; 255 } 256 257 258 NTSTATUS 259 NTAPI 260 SamAddMemberToGroup(IN SAM_HANDLE GroupHandle, 261 IN ULONG MemberId, 262 IN ULONG Attributes) 263 { 264 NTSTATUS Status; 265 266 TRACE("SamAddMemberToGroup(%p %lu %lx)\n", 267 GroupHandle, MemberId, Attributes); 268 269 RpcTryExcept 270 { 271 Status = SamrAddMemberToGroup((SAMPR_HANDLE)GroupHandle, 272 MemberId, 273 Attributes); 274 } 275 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 276 { 277 Status = I_RpcMapWin32Status(RpcExceptionCode()); 278 } 279 RpcEndExcept; 280 281 return Status; 282 } 283 284 285 NTSTATUS 286 NTAPI 287 SamAddMultipleMembersToAlias(IN SAM_HANDLE AliasHandle, 288 IN PSID *MemberIds, 289 IN ULONG MemberCount) 290 { 291 SAMPR_PSID_ARRAY Buffer; 292 NTSTATUS Status; 293 294 TRACE("SamAddMultipleMembersToAlias(%p %p %lu)\n", 295 AliasHandle, MemberIds, MemberCount); 296 297 if (MemberIds == NULL) 298 return STATUS_INVALID_PARAMETER_2; 299 300 Buffer.Count = MemberCount; 301 Buffer.Sids = (PSAMPR_SID_INFORMATION)MemberIds; 302 303 RpcTryExcept 304 { 305 Status = SamrAddMultipleMembersToAlias((SAMPR_HANDLE)AliasHandle, 306 &Buffer); 307 } 308 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 309 { 310 Status = I_RpcMapWin32Status(RpcExceptionCode()); 311 } 312 RpcEndExcept; 313 314 return Status; 315 } 316 317 318 NTSTATUS 319 NTAPI 320 SamChangePasswordUser(IN SAM_HANDLE UserHandle, 321 IN PUNICODE_STRING OldPassword, 322 IN PUNICODE_STRING NewPassword) 323 { 324 NT_OWF_PASSWORD OldNtPassword; 325 NT_OWF_PASSWORD NewNtPassword; 326 LM_OWF_PASSWORD OldLmPassword; 327 LM_OWF_PASSWORD NewLmPassword; 328 OEM_STRING LmPwdString; 329 CHAR LmPwdBuffer[15]; 330 BOOLEAN OldLmPasswordPresent = FALSE; 331 BOOLEAN NewLmPasswordPresent = FALSE; 332 NTSTATUS Status; 333 334 ENCRYPTED_LM_OWF_PASSWORD OldLmEncryptedWithNewLm; 335 ENCRYPTED_LM_OWF_PASSWORD NewLmEncryptedWithOldLm; 336 ENCRYPTED_NT_OWF_PASSWORD OldNtEncryptedWithNewNt; 337 ENCRYPTED_NT_OWF_PASSWORD NewNtEncryptedWithOldNt; 338 PENCRYPTED_LM_OWF_PASSWORD pOldLmEncryptedWithNewLm = NULL; 339 PENCRYPTED_LM_OWF_PASSWORD pNewLmEncryptedWithOldLm = NULL; 340 341 /* Calculate the NT hash for the old password */ 342 Status = SystemFunction007(OldPassword, 343 (LPBYTE)&OldNtPassword); 344 if (!NT_SUCCESS(Status)) 345 { 346 TRACE("SystemFunction007 failed (Status 0x%08lx)\n", Status); 347 return Status; 348 } 349 350 /* Calculate the NT hash for the new password */ 351 Status = SystemFunction007(NewPassword, 352 (LPBYTE)&NewNtPassword); 353 if (!NT_SUCCESS(Status)) 354 { 355 TRACE("SystemFunction007 failed (Status 0x%08lx)\n", Status); 356 return Status; 357 } 358 359 /* Calculate the LM password and hash for the old password */ 360 LmPwdString.Length = 15; 361 LmPwdString.MaximumLength = 15; 362 LmPwdString.Buffer = LmPwdBuffer; 363 ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength); 364 365 Status = RtlUpcaseUnicodeStringToOemString(&LmPwdString, 366 OldPassword, 367 FALSE); 368 if (NT_SUCCESS(Status)) 369 { 370 /* Calculate the LM hash value of the password */ 371 Status = SystemFunction006(LmPwdString.Buffer, 372 (LPSTR)&OldLmPassword); 373 if (NT_SUCCESS(Status)) 374 { 375 OldLmPasswordPresent = TRUE; 376 } 377 } 378 379 /* Calculate the LM password and hash for the new password */ 380 LmPwdString.Length = 15; 381 LmPwdString.MaximumLength = 15; 382 LmPwdString.Buffer = LmPwdBuffer; 383 ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength); 384 385 Status = RtlUpcaseUnicodeStringToOemString(&LmPwdString, 386 NewPassword, 387 FALSE); 388 if (NT_SUCCESS(Status)) 389 { 390 /* Calculate the LM hash value of the password */ 391 Status = SystemFunction006(LmPwdString.Buffer, 392 (LPSTR)&NewLmPassword); 393 if (NT_SUCCESS(Status)) 394 { 395 NewLmPasswordPresent = TRUE; 396 } 397 } 398 399 if (OldLmPasswordPresent && NewLmPasswordPresent) 400 { 401 /* Encrypt the old LM hash with the new LM hash */ 402 Status = SystemFunction012((const BYTE *)&OldLmPassword, 403 (const BYTE *)&NewLmPassword, 404 (LPBYTE)&OldLmEncryptedWithNewLm); 405 if (!NT_SUCCESS(Status)) 406 { 407 TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status); 408 return Status; 409 } 410 411 /* Encrypt the new LM hash with the old LM hash */ 412 Status = SystemFunction012((const BYTE *)&NewLmPassword, 413 (const BYTE *)&OldLmPassword, 414 (LPBYTE)&NewLmEncryptedWithOldLm); 415 if (!NT_SUCCESS(Status)) 416 { 417 TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status); 418 return Status; 419 } 420 421 pOldLmEncryptedWithNewLm = &OldLmEncryptedWithNewLm; 422 pNewLmEncryptedWithOldLm = &NewLmEncryptedWithOldLm; 423 } 424 425 /* Encrypt the old NT hash with the new NT hash */ 426 Status = SystemFunction012((const BYTE *)&OldNtPassword, 427 (const BYTE *)&NewNtPassword, 428 (LPBYTE)&OldNtEncryptedWithNewNt); 429 if (!NT_SUCCESS(Status)) 430 { 431 TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status); 432 return Status; 433 } 434 435 /* Encrypt the new NT hash with the old NT hash */ 436 Status = SystemFunction012((const BYTE *)&NewNtPassword, 437 (const BYTE *)&OldNtPassword, 438 (LPBYTE)&NewNtEncryptedWithOldNt); 439 if (!NT_SUCCESS(Status)) 440 { 441 TRACE("SystemFunction012 failed (Status 0x%08lx)\n", Status); 442 return Status; 443 } 444 445 RpcTryExcept 446 { 447 Status = SamrChangePasswordUser((SAMPR_HANDLE)UserHandle, 448 OldLmPasswordPresent && NewLmPasswordPresent, 449 pOldLmEncryptedWithNewLm, 450 pNewLmEncryptedWithOldLm, 451 TRUE, 452 &OldNtEncryptedWithNewNt, 453 &NewNtEncryptedWithOldNt, 454 FALSE, 455 NULL, 456 FALSE, 457 NULL); 458 } 459 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 460 { 461 Status = I_RpcMapWin32Status(RpcExceptionCode()); 462 } 463 RpcEndExcept; 464 465 return Status; 466 } 467 468 469 NTSTATUS 470 NTAPI 471 SamChangePasswordUser2(IN PUNICODE_STRING ServerName, 472 IN PUNICODE_STRING UserName, 473 IN PUNICODE_STRING OldPassword, 474 IN PUNICODE_STRING NewPassword) 475 { 476 UNIMPLEMENTED; 477 return STATUS_NOT_IMPLEMENTED; 478 } 479 480 481 NTSTATUS 482 NTAPI 483 SamChangePasswordUser3(IN PUNICODE_STRING ServerName, 484 IN PUNICODE_STRING UserName, 485 IN PUNICODE_STRING OldPassword, 486 IN PUNICODE_STRING NewPassword, 487 OUT PDOMAIN_PASSWORD_INFORMATION *EffectivePasswordPolicy, 488 OUT PUSER_PWD_CHANGE_FAILURE_INFORMATION *PasswordChangeFailureInfo) 489 { 490 UNIMPLEMENTED; 491 return STATUS_NOT_IMPLEMENTED; 492 } 493 494 495 NTSTATUS 496 NTAPI 497 SamCloseHandle(IN SAM_HANDLE SamHandle) 498 { 499 NTSTATUS Status; 500 501 TRACE("SamCloseHandle(%p)\n", SamHandle); 502 503 RpcTryExcept 504 { 505 Status = SamrCloseHandle((SAMPR_HANDLE *)&SamHandle); 506 } 507 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 508 { 509 Status = I_RpcMapWin32Status(RpcExceptionCode()); 510 } 511 RpcEndExcept; 512 513 return Status; 514 } 515 516 517 NTSTATUS 518 NTAPI 519 SamConnect(IN OUT PUNICODE_STRING ServerName OPTIONAL, 520 OUT PSAM_HANDLE ServerHandle, 521 IN ACCESS_MASK DesiredAccess, 522 IN POBJECT_ATTRIBUTES ObjectAttributes) 523 { 524 PSAMPR_SERVER_NAME pServerName = NULL; 525 NTSTATUS Status; 526 527 TRACE("SamConnect(%p %p 0x%08x %p)\n", 528 ServerName, ServerHandle, DesiredAccess, ObjectAttributes); 529 530 if (ServerName != NULL && ServerName->Length > 0 && ServerName->Buffer != NULL) 531 { 532 /* Create a zero-terminated server name */ 533 pServerName = midl_user_allocate(ServerName->Length + sizeof(WCHAR)); 534 if (pServerName == NULL) 535 return STATUS_INSUFFICIENT_RESOURCES; 536 537 CopyMemory(pServerName, ServerName->Buffer, ServerName->Length); 538 pServerName[ServerName->Length / sizeof(WCHAR)] = UNICODE_NULL; 539 } 540 541 RpcTryExcept 542 { 543 Status = SamrConnect(pServerName, 544 (SAMPR_HANDLE *)ServerHandle, 545 DesiredAccess); 546 } 547 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 548 { 549 Status = I_RpcMapWin32Status(RpcExceptionCode()); 550 } 551 RpcEndExcept; 552 553 if (pServerName) 554 midl_user_free(pServerName); 555 556 return Status; 557 } 558 559 560 NTSTATUS 561 NTAPI 562 SamCreateAliasInDomain(IN SAM_HANDLE DomainHandle, 563 IN PUNICODE_STRING AccountName, 564 IN ACCESS_MASK DesiredAccess, 565 OUT PSAM_HANDLE AliasHandle, 566 OUT PULONG RelativeId) 567 { 568 NTSTATUS Status; 569 570 TRACE("SamCreateAliasInDomain(%p %p 0x%08x %p %p)\n", 571 DomainHandle, AccountName, DesiredAccess, AliasHandle, RelativeId); 572 573 *AliasHandle = NULL; 574 *RelativeId = 0; 575 576 RpcTryExcept 577 { 578 Status = SamrCreateAliasInDomain((SAMPR_HANDLE)DomainHandle, 579 (PRPC_UNICODE_STRING)AccountName, 580 DesiredAccess, 581 (SAMPR_HANDLE *)AliasHandle, 582 RelativeId); 583 } 584 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 585 { 586 Status = I_RpcMapWin32Status(RpcExceptionCode()); 587 } 588 RpcEndExcept; 589 590 return Status; 591 } 592 593 594 NTSTATUS 595 NTAPI 596 SamCreateGroupInDomain(IN SAM_HANDLE DomainHandle, 597 IN PUNICODE_STRING AccountName, 598 IN ACCESS_MASK DesiredAccess, 599 OUT PSAM_HANDLE GroupHandle, 600 OUT PULONG RelativeId) 601 { 602 NTSTATUS Status; 603 604 TRACE("SamCreateGroupInDomain(%p %p 0x%08x %p %p)\n", 605 DomainHandle, AccountName, DesiredAccess, GroupHandle, RelativeId); 606 607 *GroupHandle = NULL; 608 *RelativeId = 0; 609 610 RpcTryExcept 611 { 612 Status = SamrCreateGroupInDomain((SAMPR_HANDLE)DomainHandle, 613 (PRPC_UNICODE_STRING)AccountName, 614 DesiredAccess, 615 (SAMPR_HANDLE *)GroupHandle, 616 RelativeId); 617 } 618 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 619 { 620 Status = I_RpcMapWin32Status(RpcExceptionCode()); 621 } 622 RpcEndExcept; 623 624 return Status; 625 } 626 627 628 NTSTATUS 629 NTAPI 630 SamCreateUser2InDomain(IN SAM_HANDLE DomainHandle, 631 IN PUNICODE_STRING AccountName, 632 IN ULONG AccountType, 633 IN ACCESS_MASK DesiredAccess, 634 OUT PSAM_HANDLE UserHandle, 635 OUT PULONG GrantedAccess, 636 OUT PULONG RelativeId) 637 { 638 NTSTATUS Status; 639 640 TRACE("SamCreateUser2InDomain(%p %p %lu 0x%08x %p %p %p)\n", 641 DomainHandle, AccountName, AccountType, DesiredAccess, 642 UserHandle, GrantedAccess, RelativeId); 643 644 *UserHandle = NULL; 645 *RelativeId = 0; 646 647 RpcTryExcept 648 { 649 Status = SamrCreateUser2InDomain((SAMPR_HANDLE)DomainHandle, 650 (PRPC_UNICODE_STRING)AccountName, 651 AccountType, 652 DesiredAccess, 653 (SAMPR_HANDLE *)UserHandle, 654 GrantedAccess, 655 RelativeId); 656 657 } 658 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 659 { 660 Status = I_RpcMapWin32Status(RpcExceptionCode()); 661 } 662 RpcEndExcept; 663 664 return Status; 665 } 666 667 668 NTSTATUS 669 NTAPI 670 SamCreateUserInDomain(IN SAM_HANDLE DomainHandle, 671 IN PUNICODE_STRING AccountName, 672 IN ACCESS_MASK DesiredAccess, 673 OUT PSAM_HANDLE UserHandle, 674 OUT PULONG RelativeId) 675 { 676 NTSTATUS Status; 677 678 TRACE("SamCreateUserInDomain(%p %p 0x%08x %p %p)\n", 679 DomainHandle, AccountName, DesiredAccess, UserHandle, RelativeId); 680 681 *UserHandle = NULL; 682 *RelativeId = 0; 683 684 RpcTryExcept 685 { 686 Status = SamrCreateUserInDomain((SAMPR_HANDLE)DomainHandle, 687 (PRPC_UNICODE_STRING)AccountName, 688 DesiredAccess, 689 (SAMPR_HANDLE *)UserHandle, 690 RelativeId); 691 } 692 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 693 { 694 Status = I_RpcMapWin32Status(RpcExceptionCode()); 695 } 696 RpcEndExcept; 697 698 return Status; 699 } 700 701 702 NTSTATUS 703 NTAPI 704 SamDeleteAlias(IN SAM_HANDLE AliasHandle) 705 { 706 SAMPR_HANDLE LocalAliasHandle; 707 NTSTATUS Status; 708 709 TRACE("SamDeleteAlias(%p)\n", AliasHandle); 710 711 LocalAliasHandle = (SAMPR_HANDLE)AliasHandle; 712 713 if (LocalAliasHandle == NULL) 714 return STATUS_INVALID_HANDLE; 715 716 RpcTryExcept 717 { 718 Status = SamrDeleteAlias(&LocalAliasHandle); 719 } 720 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 721 { 722 Status = I_RpcMapWin32Status(RpcExceptionCode()); 723 } 724 RpcEndExcept; 725 726 return Status; 727 } 728 729 730 NTSTATUS 731 NTAPI 732 SamDeleteGroup(IN SAM_HANDLE GroupHandle) 733 { 734 SAMPR_HANDLE LocalGroupHandle; 735 NTSTATUS Status; 736 737 TRACE("SamDeleteGroup(%p)\n", GroupHandle); 738 739 LocalGroupHandle = (SAMPR_HANDLE)GroupHandle; 740 741 if (LocalGroupHandle == NULL) 742 return STATUS_INVALID_HANDLE; 743 744 RpcTryExcept 745 { 746 Status = SamrDeleteGroup(&LocalGroupHandle); 747 } 748 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 749 { 750 Status = I_RpcMapWin32Status(RpcExceptionCode()); 751 } 752 RpcEndExcept; 753 754 return Status; 755 } 756 757 758 NTSTATUS 759 NTAPI 760 SamDeleteUser(IN SAM_HANDLE UserHandle) 761 { 762 SAMPR_HANDLE LocalUserHandle; 763 NTSTATUS Status; 764 765 TRACE("SamDeleteUser(%p)\n", UserHandle); 766 767 LocalUserHandle = (SAMPR_HANDLE)UserHandle; 768 769 if (LocalUserHandle == NULL) 770 return STATUS_INVALID_HANDLE; 771 772 RpcTryExcept 773 { 774 Status = SamrDeleteUser(&LocalUserHandle); 775 } 776 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 777 { 778 Status = I_RpcMapWin32Status(RpcExceptionCode()); 779 } 780 RpcEndExcept; 781 782 return Status; 783 } 784 785 786 NTSTATUS 787 NTAPI 788 SamEnumerateAliasesInDomain(IN SAM_HANDLE DomainHandle, 789 IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext, 790 OUT PVOID *Buffer, 791 IN ULONG PreferedMaximumLength, 792 OUT PULONG CountReturned) 793 { 794 PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL; 795 NTSTATUS Status; 796 797 TRACE("SamEnumerateAliasesInDomain(%p %p %p %lu %p)\n", 798 DomainHandle, EnumerationContext, Buffer, PreferedMaximumLength, 799 CountReturned); 800 801 if ((EnumerationContext == NULL) || 802 (Buffer == NULL) || 803 (CountReturned == NULL)) 804 return STATUS_INVALID_PARAMETER; 805 806 *Buffer = NULL; 807 808 RpcTryExcept 809 { 810 Status = SamrEnumerateAliasesInDomain((SAMPR_HANDLE)DomainHandle, 811 EnumerationContext, 812 &EnumBuffer, 813 PreferedMaximumLength, 814 CountReturned); 815 816 if (EnumBuffer != NULL) 817 { 818 if (EnumBuffer->Buffer != NULL) 819 { 820 *Buffer = EnumBuffer->Buffer; 821 } 822 823 midl_user_free(EnumBuffer); 824 } 825 } 826 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 827 { 828 Status = I_RpcMapWin32Status(RpcExceptionCode()); 829 } 830 RpcEndExcept; 831 832 return Status; 833 } 834 835 836 NTSTATUS 837 NTAPI 838 SamEnumerateDomainsInSamServer(IN SAM_HANDLE ServerHandle, 839 IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext, 840 OUT PVOID *Buffer, 841 IN ULONG PreferedMaximumLength, 842 OUT PULONG CountReturned) 843 { 844 PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL; 845 NTSTATUS Status; 846 847 TRACE("SamEnumerateDomainsInSamServer(%p %p %p %lu %p)\n", 848 ServerHandle, EnumerationContext, Buffer, PreferedMaximumLength, 849 CountReturned); 850 851 if ((EnumerationContext == NULL) || 852 (Buffer == NULL) || 853 (CountReturned == NULL)) 854 return STATUS_INVALID_PARAMETER; 855 856 *Buffer = NULL; 857 858 RpcTryExcept 859 { 860 Status = SamrEnumerateDomainsInSamServer((SAMPR_HANDLE)ServerHandle, 861 EnumerationContext, 862 &EnumBuffer, 863 PreferedMaximumLength, 864 CountReturned); 865 866 if (EnumBuffer != NULL) 867 { 868 if (EnumBuffer->Buffer != NULL) 869 { 870 *Buffer = EnumBuffer->Buffer; 871 } 872 873 midl_user_free(EnumBuffer); 874 } 875 } 876 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 877 { 878 Status = I_RpcMapWin32Status(RpcExceptionCode()); 879 } 880 RpcEndExcept; 881 882 return Status; 883 } 884 885 886 NTSTATUS 887 NTAPI 888 SamEnumerateGroupsInDomain(IN SAM_HANDLE DomainHandle, 889 IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext, 890 IN PVOID *Buffer, 891 IN ULONG PreferedMaximumLength, 892 OUT PULONG CountReturned) 893 { 894 PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL; 895 NTSTATUS Status; 896 897 TRACE("SamEnumerateGroupsInDomain(%p %p %p %lu %p)\n", 898 DomainHandle, EnumerationContext, Buffer, 899 PreferedMaximumLength, CountReturned); 900 901 if (EnumerationContext == NULL || Buffer == NULL || CountReturned == NULL) 902 return STATUS_INVALID_PARAMETER; 903 904 *Buffer = NULL; 905 906 RpcTryExcept 907 { 908 Status = SamrEnumerateGroupsInDomain((SAMPR_HANDLE)DomainHandle, 909 EnumerationContext, 910 &EnumBuffer, 911 PreferedMaximumLength, 912 CountReturned); 913 if (EnumBuffer != NULL) 914 { 915 if (EnumBuffer->Buffer != NULL) 916 *Buffer = EnumBuffer->Buffer; 917 918 midl_user_free(EnumBuffer); 919 } 920 } 921 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 922 { 923 Status = I_RpcMapWin32Status(RpcExceptionCode()); 924 } 925 RpcEndExcept; 926 927 return Status; 928 } 929 930 931 NTSTATUS 932 NTAPI 933 SamEnumerateUsersInDomain(IN SAM_HANDLE DomainHandle, 934 IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext, 935 IN ULONG UserAccountControl, 936 OUT PVOID *Buffer, 937 IN ULONG PreferedMaximumLength, 938 OUT PULONG CountReturned) 939 { 940 PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL; 941 NTSTATUS Status; 942 943 TRACE("SamEnumerateUsersInDomain(%p %p %lx %p %lu %p)\n", 944 DomainHandle, EnumerationContext, UserAccountControl, Buffer, 945 PreferedMaximumLength, CountReturned); 946 947 if (EnumerationContext == NULL || Buffer == NULL || CountReturned == NULL) 948 return STATUS_INVALID_PARAMETER; 949 950 *Buffer = NULL; 951 952 RpcTryExcept 953 { 954 Status = SamrEnumerateUsersInDomain((SAMPR_HANDLE)DomainHandle, 955 EnumerationContext, 956 UserAccountControl, 957 &EnumBuffer, 958 PreferedMaximumLength, 959 CountReturned); 960 if (EnumBuffer != NULL) 961 { 962 if (EnumBuffer->Buffer != NULL) 963 { 964 *Buffer = EnumBuffer->Buffer; 965 } 966 967 midl_user_free(EnumBuffer); 968 } 969 970 } 971 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 972 { 973 Status = I_RpcMapWin32Status(RpcExceptionCode()); 974 } 975 RpcEndExcept; 976 977 return Status; 978 } 979 980 981 NTSTATUS 982 NTAPI 983 SamFreeMemory(IN PVOID Buffer) 984 { 985 if (Buffer != NULL) 986 midl_user_free(Buffer); 987 988 return STATUS_SUCCESS; 989 } 990 991 992 NTSTATUS 993 NTAPI 994 SamGetAliasMembership(IN SAM_HANDLE DomainHandle, 995 IN ULONG PassedCount, 996 IN PSID *Sids, 997 OUT PULONG MembershipCount, 998 OUT PULONG *Aliases) 999 { 1000 SAMPR_PSID_ARRAY SidArray; 1001 SAMPR_ULONG_ARRAY Membership; 1002 NTSTATUS Status; 1003 1004 TRACE("SamAliasMembership(%p %lu %p %p %p)\n", 1005 DomainHandle, PassedCount, Sids, MembershipCount, Aliases); 1006 1007 if (Sids == NULL || 1008 MembershipCount == NULL || 1009 Aliases == NULL) 1010 return STATUS_INVALID_PARAMETER; 1011 1012 Membership.Element = NULL; 1013 1014 RpcTryExcept 1015 { 1016 SidArray.Count = PassedCount; 1017 SidArray.Sids = (PSAMPR_SID_INFORMATION)Sids; 1018 1019 Status = SamrGetAliasMembership((SAMPR_HANDLE)DomainHandle, 1020 &SidArray, 1021 &Membership); 1022 if (NT_SUCCESS(Status)) 1023 { 1024 *MembershipCount = Membership.Count; 1025 *Aliases = Membership.Element; 1026 } 1027 else 1028 { 1029 if (Membership.Element != NULL) 1030 midl_user_free(Membership.Element); 1031 } 1032 } 1033 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1034 { 1035 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1036 } 1037 RpcEndExcept; 1038 1039 return Status; 1040 } 1041 1042 1043 NTSTATUS 1044 NTAPI 1045 SamGetCompatibilityMode(IN SAM_HANDLE ObjectHandle, 1046 OUT PULONG Mode) 1047 { 1048 TRACE("SamGetCompatibilityMode(%p %p)\n", ObjectHandle, Mode); 1049 1050 if (Mode == NULL) 1051 return STATUS_INVALID_PARAMETER; 1052 1053 *Mode = SAM_SID_COMPATIBILITY_ALL; 1054 1055 return STATUS_SUCCESS; 1056 } 1057 1058 1059 NTSTATUS 1060 NTAPI 1061 SamGetDisplayEnumerationIndex(IN SAM_HANDLE DomainHandle, 1062 IN DOMAIN_DISPLAY_INFORMATION DisplayInformation, 1063 IN PUNICODE_STRING Prefix, 1064 OUT PULONG Index) 1065 { 1066 NTSTATUS Status; 1067 1068 TRACE("SamGetDisplayEnumerationIndex(%p %lu %wZ %p)\n", 1069 DomainHandle, DisplayInformation, Prefix, Index); 1070 1071 if ((Prefix == NULL) || 1072 (Index == NULL)) 1073 return STATUS_INVALID_PARAMETER; 1074 1075 RpcTryExcept 1076 { 1077 Status = SamrGetDisplayEnumerationIndex2((SAMPR_HANDLE)DomainHandle, 1078 DisplayInformation, 1079 (PRPC_UNICODE_STRING)Prefix, 1080 Index); 1081 } 1082 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1083 { 1084 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1085 } 1086 RpcEndExcept; 1087 1088 return Status; 1089 } 1090 1091 1092 NTSTATUS 1093 NTAPI 1094 SamGetGroupsForUser(IN SAM_HANDLE UserHandle, 1095 OUT PGROUP_MEMBERSHIP *Groups, 1096 OUT PULONG MembershipCount) 1097 { 1098 PSAMPR_GET_GROUPS_BUFFER GroupsBuffer = NULL; 1099 NTSTATUS Status; 1100 1101 TRACE("SamGetGroupsForUser(%p %p %p)\n", 1102 UserHandle, Groups, MembershipCount); 1103 1104 RpcTryExcept 1105 { 1106 Status = SamrGetGroupsForUser((SAMPR_HANDLE)UserHandle, 1107 &GroupsBuffer); 1108 if (NT_SUCCESS(Status)) 1109 { 1110 *Groups = GroupsBuffer->Groups; 1111 *MembershipCount = GroupsBuffer->MembershipCount; 1112 1113 MIDL_user_free(GroupsBuffer); 1114 } 1115 else 1116 { 1117 if (GroupsBuffer != NULL) 1118 { 1119 if (GroupsBuffer->Groups != NULL) 1120 MIDL_user_free(GroupsBuffer->Groups); 1121 1122 MIDL_user_free(GroupsBuffer); 1123 } 1124 } 1125 } 1126 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1127 { 1128 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1129 } 1130 RpcEndExcept; 1131 1132 return Status; 1133 } 1134 1135 1136 NTSTATUS 1137 NTAPI 1138 SamGetMembersInAlias(IN SAM_HANDLE AliasHandle, 1139 OUT PSID **MemberIds, 1140 OUT PULONG MemberCount) 1141 { 1142 SAMPR_PSID_ARRAY_OUT SidArray; 1143 NTSTATUS Status; 1144 1145 TRACE("SamGetMembersInAlias(%p %p %p)\n", 1146 AliasHandle, MemberIds, MemberCount); 1147 1148 if ((MemberIds == NULL) || 1149 (MemberCount == NULL)) 1150 return STATUS_INVALID_PARAMETER; 1151 1152 *MemberIds = NULL; 1153 *MemberCount = 0; 1154 1155 SidArray.Sids = NULL; 1156 1157 RpcTryExcept 1158 { 1159 Status = SamrGetMembersInAlias((SAMPR_HANDLE)AliasHandle, 1160 &SidArray); 1161 if (NT_SUCCESS(Status)) 1162 { 1163 *MemberCount = SidArray.Count; 1164 *MemberIds = (PSID *)SidArray.Sids; 1165 } 1166 1167 } 1168 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1169 { 1170 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1171 } 1172 RpcEndExcept; 1173 1174 return Status; 1175 } 1176 1177 1178 NTSTATUS 1179 NTAPI 1180 SamGetMembersInGroup(IN SAM_HANDLE GroupHandle, 1181 OUT PULONG *MemberIds, 1182 OUT PULONG *Attributes, 1183 OUT PULONG MemberCount) 1184 { 1185 PSAMPR_GET_MEMBERS_BUFFER MembersBuffer = NULL; 1186 NTSTATUS Status; 1187 1188 TRACE("SamGetMembersInGroup(%p %p %p %p)\n", 1189 GroupHandle, MemberIds, Attributes, MemberCount); 1190 1191 RpcTryExcept 1192 { 1193 Status = SamrGetMembersInGroup((SAMPR_HANDLE)GroupHandle, 1194 &MembersBuffer); 1195 if (NT_SUCCESS(Status)) 1196 { 1197 *MemberIds = MembersBuffer->Members; 1198 *Attributes = MembersBuffer->Attributes; 1199 *MemberCount = MembersBuffer->MemberCount; 1200 1201 MIDL_user_free(MembersBuffer); 1202 } 1203 else 1204 { 1205 if (MembersBuffer != NULL) 1206 { 1207 if (MembersBuffer->Members != NULL) 1208 MIDL_user_free(MembersBuffer->Members); 1209 1210 if (MembersBuffer->Attributes != NULL) 1211 MIDL_user_free(MembersBuffer->Attributes); 1212 1213 MIDL_user_free(MembersBuffer); 1214 } 1215 } 1216 } 1217 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1218 { 1219 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1220 } 1221 RpcEndExcept; 1222 1223 return Status; 1224 } 1225 1226 1227 NTSTATUS 1228 NTAPI 1229 SamLookupDomainInSamServer(IN SAM_HANDLE ServerHandle, 1230 IN PUNICODE_STRING Name, 1231 OUT PSID *DomainId) 1232 { 1233 NTSTATUS Status; 1234 1235 TRACE("SamLookupDomainInSamServer(%p %p %p)\n", 1236 ServerHandle, Name, DomainId); 1237 1238 RpcTryExcept 1239 { 1240 Status = SamrLookupDomainInSamServer((SAMPR_HANDLE)ServerHandle, 1241 (PRPC_UNICODE_STRING)Name, 1242 (PRPC_SID *)DomainId); 1243 } 1244 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1245 { 1246 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1247 } 1248 RpcEndExcept; 1249 1250 return Status; 1251 } 1252 1253 1254 NTSTATUS 1255 NTAPI 1256 SamLookupIdsInDomain(IN SAM_HANDLE DomainHandle, 1257 IN ULONG Count, 1258 IN PULONG RelativeIds, 1259 OUT PUNICODE_STRING *Names, 1260 OUT PSID_NAME_USE *Use OPTIONAL) 1261 { 1262 SAMPR_RETURNED_USTRING_ARRAY NamesBuffer = {0, NULL}; 1263 SAMPR_ULONG_ARRAY UseBuffer = {0, NULL}; 1264 ULONG i; 1265 NTSTATUS Status; 1266 1267 TRACE("SamLookupIdsInDomain(%p %lu %p %p %p)\n", 1268 DomainHandle, Count, RelativeIds, Names, Use); 1269 1270 *Names = NULL; 1271 1272 if (Use != NULL) 1273 *Use = NULL; 1274 1275 RpcTryExcept 1276 { 1277 Status = SamrLookupIdsInDomain((SAMPR_HANDLE)DomainHandle, 1278 Count, 1279 RelativeIds, 1280 &NamesBuffer, 1281 &UseBuffer); 1282 } 1283 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1284 { 1285 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1286 } 1287 RpcEndExcept; 1288 1289 if (NT_SUCCESS(Status)) 1290 { 1291 *Names = midl_user_allocate(Count * sizeof(RPC_UNICODE_STRING)); 1292 if (*Names == NULL) 1293 { 1294 Status = STATUS_INSUFFICIENT_RESOURCES; 1295 goto done; 1296 } 1297 1298 for (i = 0; i < Count; i++) 1299 { 1300 (*Names)[i].Buffer = midl_user_allocate(NamesBuffer.Element[i].MaximumLength); 1301 if ((*Names)[i].Buffer == NULL) 1302 { 1303 Status = STATUS_INSUFFICIENT_RESOURCES; 1304 goto done; 1305 } 1306 } 1307 1308 for (i = 0; i < Count; i++) 1309 { 1310 (*Names)[i].Length = NamesBuffer.Element[i].Length; 1311 (*Names)[i].MaximumLength = NamesBuffer.Element[i].MaximumLength; 1312 1313 RtlCopyMemory((*Names)[i].Buffer, 1314 NamesBuffer.Element[i].Buffer, 1315 NamesBuffer.Element[i].Length); 1316 } 1317 1318 if (Use != NULL) 1319 { 1320 *Use = midl_user_allocate(Count * sizeof(SID_NAME_USE)); 1321 if (*Use == NULL) 1322 { 1323 Status = STATUS_INSUFFICIENT_RESOURCES; 1324 goto done; 1325 } 1326 1327 RtlCopyMemory(*Use, 1328 UseBuffer.Element, 1329 Count * sizeof(SID_NAME_USE)); 1330 } 1331 } 1332 1333 done: 1334 if (!NT_SUCCESS(Status)) 1335 { 1336 if (*Names != NULL) 1337 { 1338 for (i = 0; i < Count; i++) 1339 { 1340 if ((*Names)[i].Buffer != NULL) 1341 midl_user_free((*Names)[i].Buffer); 1342 } 1343 1344 midl_user_free(*Names); 1345 } 1346 1347 if (Use != NULL && *Use != NULL) 1348 midl_user_free(*Use); 1349 } 1350 1351 if (NamesBuffer.Element != NULL) 1352 { 1353 for (i = 0; i < NamesBuffer.Count; i++) 1354 { 1355 if (NamesBuffer.Element[i].Buffer != NULL) 1356 midl_user_free(NamesBuffer.Element[i].Buffer); 1357 } 1358 1359 midl_user_free(NamesBuffer.Element); 1360 } 1361 1362 if (UseBuffer.Element != NULL) 1363 midl_user_free(UseBuffer.Element); 1364 1365 return 0; 1366 } 1367 1368 1369 NTSTATUS 1370 NTAPI 1371 SamLookupNamesInDomain(IN SAM_HANDLE DomainHandle, 1372 IN ULONG Count, 1373 IN PUNICODE_STRING Names, 1374 OUT PULONG *RelativeIds, 1375 OUT PSID_NAME_USE *Use) 1376 { 1377 SAMPR_ULONG_ARRAY RidBuffer = {0, NULL}; 1378 SAMPR_ULONG_ARRAY UseBuffer = {0, NULL}; 1379 NTSTATUS Status; 1380 1381 TRACE("SamLookupNamesInDomain(%p %lu %p %p %p)\n", 1382 DomainHandle, Count, Names, RelativeIds, Use); 1383 1384 *RelativeIds = NULL; 1385 *Use = NULL; 1386 1387 RpcTryExcept 1388 { 1389 Status = SamrLookupNamesInDomain((SAMPR_HANDLE)DomainHandle, 1390 Count, 1391 (PRPC_UNICODE_STRING)Names, 1392 &RidBuffer, 1393 &UseBuffer); 1394 } 1395 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1396 { 1397 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1398 } 1399 RpcEndExcept; 1400 1401 if (NT_SUCCESS(Status)) 1402 { 1403 *RelativeIds = midl_user_allocate(Count * sizeof(ULONG)); 1404 if (*RelativeIds == NULL) 1405 { 1406 Status = STATUS_INSUFFICIENT_RESOURCES; 1407 goto done; 1408 } 1409 1410 *Use = midl_user_allocate(Count * sizeof(SID_NAME_USE)); 1411 if (*Use == NULL) 1412 { 1413 Status = STATUS_INSUFFICIENT_RESOURCES; 1414 goto done; 1415 } 1416 1417 RtlCopyMemory(*RelativeIds, 1418 RidBuffer.Element, 1419 Count * sizeof(ULONG)); 1420 1421 RtlCopyMemory(*Use, 1422 UseBuffer.Element, 1423 Count * sizeof(SID_NAME_USE)); 1424 } 1425 1426 done: 1427 if (!NT_SUCCESS(Status)) 1428 { 1429 if (*RelativeIds != NULL) 1430 midl_user_free(*RelativeIds); 1431 1432 if (*Use != NULL) 1433 midl_user_free(*Use); 1434 } 1435 1436 if (RidBuffer.Element != NULL) 1437 midl_user_free(RidBuffer.Element); 1438 1439 if (UseBuffer.Element != NULL) 1440 midl_user_free(UseBuffer.Element); 1441 1442 return Status; 1443 } 1444 1445 1446 NTSTATUS 1447 NTAPI 1448 SamOpenAlias(IN SAM_HANDLE DomainHandle, 1449 IN ACCESS_MASK DesiredAccess, 1450 IN ULONG AliasId, 1451 OUT PSAM_HANDLE AliasHandle) 1452 { 1453 NTSTATUS Status; 1454 1455 TRACE("SamOpenAlias(%p 0x%08x %lx %p)\n", 1456 DomainHandle, DesiredAccess, AliasId, AliasHandle); 1457 1458 RpcTryExcept 1459 { 1460 Status = SamrOpenAlias((SAMPR_HANDLE)DomainHandle, 1461 DesiredAccess, 1462 AliasId, 1463 (SAMPR_HANDLE *)AliasHandle); 1464 } 1465 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1466 { 1467 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1468 } 1469 RpcEndExcept; 1470 1471 return Status; 1472 } 1473 1474 1475 NTSTATUS 1476 NTAPI 1477 SamOpenDomain(IN SAM_HANDLE ServerHandle, 1478 IN ACCESS_MASK DesiredAccess, 1479 IN PSID DomainId, 1480 OUT PSAM_HANDLE DomainHandle) 1481 { 1482 NTSTATUS Status; 1483 1484 TRACE("SamOpenDomain(%p 0x%08x %p %p)\n", 1485 ServerHandle, DesiredAccess, DomainId, DomainHandle); 1486 1487 RpcTryExcept 1488 { 1489 Status = SamrOpenDomain((SAMPR_HANDLE)ServerHandle, 1490 DesiredAccess, 1491 (PRPC_SID)DomainId, 1492 (SAMPR_HANDLE *)DomainHandle); 1493 } 1494 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1495 { 1496 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1497 } 1498 RpcEndExcept; 1499 1500 return Status; 1501 } 1502 1503 1504 NTSTATUS 1505 NTAPI 1506 SamOpenGroup(IN SAM_HANDLE DomainHandle, 1507 IN ACCESS_MASK DesiredAccess, 1508 IN ULONG GroupId, 1509 OUT PSAM_HANDLE GroupHandle) 1510 { 1511 NTSTATUS Status; 1512 1513 TRACE("SamOpenGroup(%p 0x%08x %p %p)\n", 1514 DomainHandle, DesiredAccess, GroupId, GroupHandle); 1515 1516 RpcTryExcept 1517 { 1518 Status = SamrOpenGroup((SAMPR_HANDLE)DomainHandle, 1519 DesiredAccess, 1520 GroupId, 1521 (SAMPR_HANDLE *)GroupHandle); 1522 } 1523 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1524 { 1525 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1526 } 1527 RpcEndExcept; 1528 1529 return Status; 1530 } 1531 1532 1533 NTSTATUS 1534 NTAPI 1535 SamOpenUser(IN SAM_HANDLE DomainHandle, 1536 IN ACCESS_MASK DesiredAccess, 1537 IN ULONG UserId, 1538 OUT PSAM_HANDLE UserHandle) 1539 { 1540 NTSTATUS Status; 1541 1542 TRACE("SamOpenUser(%p 0x%08x %lx %p)\n", 1543 DomainHandle, DesiredAccess, UserId, UserHandle); 1544 1545 RpcTryExcept 1546 { 1547 Status = SamrOpenUser((SAMPR_HANDLE)DomainHandle, 1548 DesiredAccess, 1549 UserId, 1550 (SAMPR_HANDLE *)UserHandle); 1551 } 1552 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1553 { 1554 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1555 } 1556 RpcEndExcept; 1557 1558 return Status; 1559 } 1560 1561 1562 NTSTATUS 1563 NTAPI 1564 SamQueryDisplayInformation(IN SAM_HANDLE DomainHandle, 1565 IN DOMAIN_DISPLAY_INFORMATION DisplayInformation, 1566 IN ULONG Index, 1567 IN ULONG EntryCount, 1568 IN ULONG PreferredMaximumLength, 1569 OUT PULONG TotalAvailable, 1570 OUT PULONG TotalReturned, 1571 OUT PULONG ReturnedEntryCount, 1572 OUT PVOID *SortedBuffer) 1573 { 1574 SAMPR_DISPLAY_INFO_BUFFER LocalBuffer; 1575 NTSTATUS Status; 1576 1577 TRACE("SamQueryDisplayInformation(%p %lu %lu %lu %lu %p %p %p %p)\n", 1578 DomainHandle, DisplayInformation, Index, EntryCount, 1579 PreferredMaximumLength, TotalAvailable, TotalReturned, 1580 ReturnedEntryCount, SortedBuffer); 1581 1582 if ((TotalAvailable == NULL) || 1583 (TotalReturned == NULL) || 1584 (ReturnedEntryCount == NULL) || 1585 (SortedBuffer == NULL)) 1586 return STATUS_INVALID_PARAMETER; 1587 1588 RpcTryExcept 1589 { 1590 Status = SamrQueryDisplayInformation3((SAMPR_HANDLE)DomainHandle, 1591 DisplayInformation, 1592 Index, 1593 EntryCount, 1594 PreferredMaximumLength, 1595 TotalAvailable, 1596 TotalReturned, 1597 &LocalBuffer); 1598 if (NT_SUCCESS(Status)) 1599 { 1600 switch (DisplayInformation) 1601 { 1602 case DomainDisplayUser: 1603 *ReturnedEntryCount = LocalBuffer.UserInformation.EntriesRead; 1604 *SortedBuffer = LocalBuffer.UserInformation.Buffer; 1605 break; 1606 1607 case DomainDisplayMachine: 1608 *ReturnedEntryCount = LocalBuffer.MachineInformation.EntriesRead; 1609 *SortedBuffer = LocalBuffer.MachineInformation.Buffer; 1610 break; 1611 1612 case DomainDisplayGroup: 1613 *ReturnedEntryCount = LocalBuffer.GroupInformation.EntriesRead; 1614 *SortedBuffer = LocalBuffer.GroupInformation.Buffer; 1615 break; 1616 1617 case DomainDisplayOemUser: 1618 *ReturnedEntryCount = LocalBuffer.OemUserInformation.EntriesRead; 1619 *SortedBuffer = LocalBuffer.OemUserInformation.Buffer; 1620 break; 1621 1622 case DomainDisplayOemGroup: 1623 *ReturnedEntryCount = LocalBuffer.OemGroupInformation.EntriesRead; 1624 *SortedBuffer = LocalBuffer.OemGroupInformation.Buffer; 1625 break; 1626 1627 case DomainDisplayServer: 1628 /* FIXME */ 1629 break; 1630 } 1631 } 1632 else 1633 { 1634 *ReturnedEntryCount = 0; 1635 *SortedBuffer = NULL; 1636 } 1637 } 1638 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1639 { 1640 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1641 } 1642 RpcEndExcept; 1643 1644 return Status; 1645 } 1646 1647 1648 NTSTATUS 1649 NTAPI 1650 SamQueryInformationAlias(IN SAM_HANDLE AliasHandle, 1651 IN ALIAS_INFORMATION_CLASS AliasInformationClass, 1652 OUT PVOID *Buffer) 1653 { 1654 NTSTATUS Status; 1655 1656 TRACE("SamQueryInformationAlias(%p %lu %p)\n", 1657 AliasHandle, AliasInformationClass, Buffer); 1658 1659 RpcTryExcept 1660 { 1661 Status = SamrQueryInformationAlias((SAMPR_HANDLE)AliasHandle, 1662 AliasInformationClass, 1663 (PSAMPR_ALIAS_INFO_BUFFER *)Buffer); 1664 } 1665 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1666 { 1667 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1668 } 1669 RpcEndExcept; 1670 1671 return Status; 1672 } 1673 1674 1675 NTSTATUS 1676 NTAPI 1677 SamQueryInformationDomain(IN SAM_HANDLE DomainHandle, 1678 IN DOMAIN_INFORMATION_CLASS DomainInformationClass, 1679 OUT PVOID *Buffer) 1680 { 1681 NTSTATUS Status; 1682 1683 TRACE("SamQueryInformationDomain(%p %lu %p)\n", 1684 DomainHandle, DomainInformationClass, Buffer); 1685 1686 RpcTryExcept 1687 { 1688 Status = SamrQueryInformationDomain((SAMPR_HANDLE)DomainHandle, 1689 DomainInformationClass, 1690 (PSAMPR_DOMAIN_INFO_BUFFER *)Buffer); 1691 } 1692 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1693 { 1694 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1695 } 1696 RpcEndExcept; 1697 1698 return Status; 1699 } 1700 1701 1702 NTSTATUS 1703 NTAPI 1704 SamQueryInformationGroup(IN SAM_HANDLE GroupHandle, 1705 IN GROUP_INFORMATION_CLASS GroupInformationClass, 1706 OUT PVOID *Buffer) 1707 { 1708 NTSTATUS Status; 1709 1710 TRACE("SamQueryInformationGroup(%p %lu %p)\n", 1711 GroupHandle, GroupInformationClass, Buffer); 1712 1713 RpcTryExcept 1714 { 1715 Status = SamrQueryInformationGroup((SAMPR_HANDLE)GroupHandle, 1716 GroupInformationClass, 1717 (PSAMPR_GROUP_INFO_BUFFER *)Buffer); 1718 } 1719 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1720 { 1721 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1722 } 1723 RpcEndExcept; 1724 1725 return Status; 1726 } 1727 1728 1729 NTSTATUS 1730 NTAPI 1731 SamQueryInformationUser(IN SAM_HANDLE UserHandle, 1732 IN USER_INFORMATION_CLASS UserInformationClass, 1733 OUT PVOID *Buffer) 1734 { 1735 NTSTATUS Status; 1736 1737 TRACE("SamQueryInformationUser(%p %lu %p)\n", 1738 UserHandle, UserInformationClass, Buffer); 1739 1740 RpcTryExcept 1741 { 1742 Status = SamrQueryInformationUser((SAMPR_HANDLE)UserHandle, 1743 UserInformationClass, 1744 (PSAMPR_USER_INFO_BUFFER *)Buffer); 1745 } 1746 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1747 { 1748 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1749 } 1750 RpcEndExcept; 1751 1752 return Status; 1753 } 1754 1755 1756 NTSTATUS 1757 NTAPI 1758 SamQuerySecurityObject(IN SAM_HANDLE ObjectHandle, 1759 IN SECURITY_INFORMATION SecurityInformation, 1760 OUT PSECURITY_DESCRIPTOR *SecurityDescriptor) 1761 { 1762 PSAMPR_SR_SECURITY_DESCRIPTOR SamSecurityDescriptor = NULL; 1763 NTSTATUS Status; 1764 1765 TRACE("SamQuerySecurityObject(%p %lu %p)\n", 1766 ObjectHandle, SecurityInformation, SecurityDescriptor); 1767 1768 *SecurityDescriptor = NULL; 1769 1770 RpcTryExcept 1771 { 1772 Status = SamrQuerySecurityObject((SAMPR_HANDLE)ObjectHandle, 1773 SecurityInformation, 1774 &SamSecurityDescriptor); 1775 } 1776 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1777 { 1778 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1779 } 1780 RpcEndExcept; 1781 1782 TRACE("SamSecurityDescriptor: %p\n", SamSecurityDescriptor); 1783 1784 if (SamSecurityDescriptor != NULL) 1785 { 1786 TRACE("SamSecurityDescriptor->Length: %lu\n", SamSecurityDescriptor->Length); 1787 TRACE("SamSecurityDescriptor->SecurityDescriptor: %p\n", SamSecurityDescriptor->SecurityDescriptor); 1788 1789 *SecurityDescriptor = SamSecurityDescriptor->SecurityDescriptor; 1790 1791 midl_user_free(SamSecurityDescriptor); 1792 } 1793 1794 return Status; 1795 } 1796 1797 1798 NTSTATUS 1799 NTAPI 1800 SamRemoveMemberFromAlias(IN SAM_HANDLE AliasHandle, 1801 IN PSID MemberId) 1802 { 1803 NTSTATUS Status; 1804 1805 TRACE("SamRemoveMemberFromAlias(%p %ul)\n", 1806 AliasHandle, MemberId); 1807 1808 RpcTryExcept 1809 { 1810 Status = SamrRemoveMemberFromAlias((SAMPR_HANDLE)AliasHandle, 1811 MemberId); 1812 } 1813 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1814 { 1815 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1816 } 1817 RpcEndExcept; 1818 1819 return Status; 1820 } 1821 1822 1823 NTSTATUS 1824 NTAPI 1825 SamRemoveMemberFromForeignDomain(IN SAM_HANDLE DomainHandle, 1826 IN PSID MemberId) 1827 { 1828 NTSTATUS Status; 1829 1830 TRACE("SamRemoveMemberFromForeignDomain(%p %ul)\n", 1831 DomainHandle, MemberId); 1832 1833 RpcTryExcept 1834 { 1835 Status = SamrRemoveMemberFromForeignDomain((SAMPR_HANDLE)DomainHandle, 1836 MemberId); 1837 } 1838 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1839 { 1840 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1841 } 1842 RpcEndExcept; 1843 1844 return Status; 1845 } 1846 1847 1848 NTSTATUS 1849 NTAPI 1850 SamRemoveMemberFromGroup(IN SAM_HANDLE GroupHandle, 1851 IN ULONG MemberId) 1852 { 1853 NTSTATUS Status; 1854 1855 TRACE("SamRemoveMemberFromGroup(%p %ul)\n", 1856 GroupHandle, MemberId); 1857 1858 RpcTryExcept 1859 { 1860 Status = SamrRemoveMemberFromGroup((SAMPR_HANDLE)GroupHandle, 1861 MemberId); 1862 } 1863 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1864 { 1865 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1866 } 1867 RpcEndExcept; 1868 1869 return Status; 1870 } 1871 1872 1873 NTSTATUS 1874 NTAPI 1875 SamRemoveMultipleMembersFromAlias(IN SAM_HANDLE AliasHandle, 1876 IN PSID *MemberIds, 1877 IN ULONG MemberCount) 1878 { 1879 SAMPR_PSID_ARRAY Buffer; 1880 NTSTATUS Status; 1881 1882 TRACE("SamRemoveMultipleMembersFromAlias(%p %p %lu)\n", 1883 AliasHandle, MemberIds, MemberCount); 1884 1885 if (MemberIds == NULL) 1886 return STATUS_INVALID_PARAMETER_2; 1887 1888 Buffer.Count = MemberCount; 1889 Buffer.Sids = (PSAMPR_SID_INFORMATION)MemberIds; 1890 1891 RpcTryExcept 1892 { 1893 Status = SamrRemoveMultipleMembersFromAlias((SAMPR_HANDLE)AliasHandle, 1894 &Buffer); 1895 } 1896 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1897 { 1898 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1899 } 1900 RpcEndExcept; 1901 1902 return Status; 1903 } 1904 1905 1906 NTSTATUS 1907 NTAPI 1908 SamRidToSid(IN SAM_HANDLE ObjectHandle, 1909 IN ULONG Rid, 1910 OUT PSID *Sid) 1911 { 1912 UNIMPLEMENTED; 1913 return STATUS_NOT_IMPLEMENTED; 1914 } 1915 1916 1917 NTSTATUS 1918 NTAPI 1919 SamSetInformationAlias(IN SAM_HANDLE AliasHandle, 1920 IN ALIAS_INFORMATION_CLASS AliasInformationClass, 1921 IN PVOID Buffer) 1922 { 1923 NTSTATUS Status; 1924 1925 TRACE("SamSetInformationAlias(%p %lu %p)\n", 1926 AliasHandle, AliasInformationClass, Buffer); 1927 1928 RpcTryExcept 1929 { 1930 Status = SamrSetInformationAlias((SAMPR_HANDLE)AliasHandle, 1931 AliasInformationClass, 1932 Buffer); 1933 } 1934 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1935 { 1936 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1937 } 1938 RpcEndExcept; 1939 1940 return Status; 1941 } 1942 1943 1944 NTSTATUS 1945 NTAPI 1946 SamSetInformationDomain(IN SAM_HANDLE DomainHandle, 1947 IN DOMAIN_INFORMATION_CLASS DomainInformationClass, 1948 IN PVOID Buffer) 1949 { 1950 NTSTATUS Status; 1951 1952 TRACE("SamSetInformationDomain(%p %lu %p)\n", 1953 DomainHandle, DomainInformationClass, Buffer); 1954 1955 RpcTryExcept 1956 { 1957 Status = SamrSetInformationDomain((SAMPR_HANDLE)DomainHandle, 1958 DomainInformationClass, 1959 Buffer); 1960 } 1961 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1962 { 1963 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1964 } 1965 RpcEndExcept; 1966 1967 return Status; 1968 } 1969 1970 1971 NTSTATUS 1972 NTAPI 1973 SamSetInformationGroup(IN SAM_HANDLE GroupHandle, 1974 IN GROUP_INFORMATION_CLASS GroupInformationClass, 1975 IN PVOID Buffer) 1976 { 1977 NTSTATUS Status; 1978 1979 TRACE("SamSetInformationGroup(%p %lu %p)\n", 1980 GroupHandle, GroupInformationClass, Buffer); 1981 1982 RpcTryExcept 1983 { 1984 Status = SamrSetInformationGroup((SAMPR_HANDLE)GroupHandle, 1985 GroupInformationClass, 1986 Buffer); 1987 } 1988 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1989 { 1990 Status = I_RpcMapWin32Status(RpcExceptionCode()); 1991 } 1992 RpcEndExcept; 1993 1994 return Status; 1995 } 1996 1997 1998 NTSTATUS 1999 NTAPI 2000 SamSetInformationUser(IN SAM_HANDLE UserHandle, 2001 IN USER_INFORMATION_CLASS UserInformationClass, 2002 IN PVOID Buffer) 2003 { 2004 PSAMPR_USER_SET_PASSWORD_INFORMATION PasswordBuffer; 2005 SAMPR_USER_INTERNAL1_INFORMATION Internal1Buffer; 2006 USER_ALL_INFORMATION InternalAllBuffer; 2007 OEM_STRING LmPwdString; 2008 CHAR LmPwdBuffer[15]; 2009 NTSTATUS Status; 2010 2011 TRACE("SamSetInformationUser(%p %lu %p)\n", 2012 UserHandle, UserInformationClass, Buffer); 2013 2014 if (UserInformationClass == UserSetPasswordInformation) 2015 { 2016 PasswordBuffer = (PSAMPR_USER_SET_PASSWORD_INFORMATION)Buffer; 2017 2018 Status = SampCheckPassword(UserHandle, 2019 (PUNICODE_STRING)&PasswordBuffer->Password); 2020 if (!NT_SUCCESS(Status)) 2021 { 2022 TRACE("SampCheckPassword failed (Status 0x%08lx)\n", Status); 2023 return Status; 2024 } 2025 2026 /* Calculate the NT hash value of the password */ 2027 Status = SystemFunction007((PUNICODE_STRING)&PasswordBuffer->Password, 2028 (LPBYTE)&Internal1Buffer.EncryptedNtOwfPassword); 2029 if (!NT_SUCCESS(Status)) 2030 { 2031 TRACE("SystemFunction007 failed (Status 0x%08lx)\n", Status); 2032 return Status; 2033 } 2034 2035 Internal1Buffer.NtPasswordPresent = TRUE; 2036 Internal1Buffer.LmPasswordPresent = FALSE; 2037 2038 /* Build the LM password */ 2039 LmPwdString.Length = 15; 2040 LmPwdString.MaximumLength = 15; 2041 LmPwdString.Buffer = LmPwdBuffer; 2042 ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength); 2043 2044 Status = RtlUpcaseUnicodeStringToOemString(&LmPwdString, 2045 (PUNICODE_STRING)&PasswordBuffer->Password, 2046 FALSE); 2047 if (NT_SUCCESS(Status)) 2048 { 2049 /* Calculate the LM hash value of the password */ 2050 Status = SystemFunction006(LmPwdString.Buffer, 2051 (LPSTR)&Internal1Buffer.EncryptedLmOwfPassword); 2052 if (NT_SUCCESS(Status)) 2053 Internal1Buffer.LmPasswordPresent = TRUE; 2054 } 2055 2056 Internal1Buffer.PasswordExpired = PasswordBuffer->PasswordExpired; 2057 2058 RpcTryExcept 2059 { 2060 Status = SamrSetInformationUser((SAMPR_HANDLE)UserHandle, 2061 UserInternal1Information, 2062 (PVOID)&Internal1Buffer); 2063 } 2064 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 2065 { 2066 Status = I_RpcMapWin32Status(RpcExceptionCode()); 2067 } 2068 RpcEndExcept; 2069 2070 if (!NT_SUCCESS(Status)) 2071 { 2072 TRACE("SamrSetInformation() failed (Status 0x%08lx)\n", Status); 2073 } 2074 2075 return Status; 2076 } 2077 else if (UserInformationClass == UserAllInformation) 2078 { 2079 RtlCopyMemory(&InternalAllBuffer, 2080 Buffer, 2081 sizeof(USER_ALL_INFORMATION)); 2082 2083 if (InternalAllBuffer.WhichFields & (USER_ALL_LMPASSWORDPRESENT | USER_ALL_NTPASSWORDPRESENT)) 2084 { 2085 if (InternalAllBuffer.WhichFields & USER_ALL_OWFPASSWORD) 2086 { 2087 /* Check NT password hash */ 2088 if (InternalAllBuffer.WhichFields & USER_ALL_NTPASSWORDPRESENT) 2089 { 2090 if (InternalAllBuffer.NtPassword.Length != sizeof(ENCRYPTED_NT_OWF_PASSWORD)) 2091 return STATUS_INVALID_PARAMETER; 2092 } 2093 2094 /* Check LM password hash */ 2095 if (InternalAllBuffer.WhichFields & USER_ALL_LMPASSWORDPRESENT) 2096 { 2097 if (InternalAllBuffer.LmPassword.Length != sizeof(ENCRYPTED_LM_OWF_PASSWORD)) 2098 return STATUS_INVALID_PARAMETER; 2099 } 2100 } 2101 else 2102 { 2103 /* 2104 * Only allow the NT password to be set. 2105 * The LM password will be created here. 2106 */ 2107 if (InternalAllBuffer.WhichFields & USER_ALL_LMPASSWORDPRESENT) 2108 { 2109 TRACE("Do not try to set a clear text LM password!\n"); 2110 return STATUS_INVALID_PARAMETER; 2111 } 2112 2113 if (InternalAllBuffer.WhichFields & USER_ALL_NTPASSWORDPRESENT) 2114 { 2115 Status = SampCheckPassword(UserHandle, 2116 &InternalAllBuffer.NtPassword); 2117 if (!NT_SUCCESS(Status)) 2118 { 2119 TRACE("SampCheckPassword failed (Status 0x%08lx)\n", Status); 2120 return Status; 2121 } 2122 2123 /* Calculate the NT password hash */ 2124 Status = SystemFunction007((PUNICODE_STRING)&InternalAllBuffer.NtPassword, 2125 (LPBYTE)&Internal1Buffer.EncryptedNtOwfPassword); 2126 if (!NT_SUCCESS(Status)) 2127 { 2128 TRACE("SystemFunction007 failed (Status 0x%08lx)\n", Status); 2129 return Status; 2130 } 2131 2132 InternalAllBuffer.NtPasswordPresent = TRUE; 2133 InternalAllBuffer.LmPasswordPresent = FALSE; 2134 2135 InternalAllBuffer.NtPassword.Length = sizeof(ENCRYPTED_NT_OWF_PASSWORD); 2136 InternalAllBuffer.NtPassword.MaximumLength = sizeof(ENCRYPTED_NT_OWF_PASSWORD); 2137 InternalAllBuffer.NtPassword.Buffer = (LPWSTR)&Internal1Buffer.EncryptedNtOwfPassword; 2138 2139 /* Build the LM password */ 2140 LmPwdString.Length = 15; 2141 LmPwdString.MaximumLength = 15; 2142 LmPwdString.Buffer = LmPwdBuffer; 2143 ZeroMemory(LmPwdString.Buffer, LmPwdString.MaximumLength); 2144 2145 Status = RtlUpcaseUnicodeStringToOemString(&LmPwdString, 2146 (PUNICODE_STRING)&InternalAllBuffer.NtPassword, 2147 FALSE); 2148 if (NT_SUCCESS(Status)) 2149 { 2150 /* Calculate the LM password hash */ 2151 Status = SystemFunction006(LmPwdString.Buffer, 2152 (LPSTR)&Internal1Buffer.EncryptedLmOwfPassword); 2153 if (NT_SUCCESS(Status)) 2154 { 2155 InternalAllBuffer.WhichFields |= USER_ALL_LMPASSWORDPRESENT; 2156 InternalAllBuffer.LmPasswordPresent = TRUE; 2157 2158 InternalAllBuffer.LmPassword.Length = sizeof(ENCRYPTED_LM_OWF_PASSWORD); 2159 InternalAllBuffer.LmPassword.MaximumLength = sizeof(ENCRYPTED_LM_OWF_PASSWORD); 2160 InternalAllBuffer.LmPassword.Buffer = (LPWSTR)&Internal1Buffer.EncryptedLmOwfPassword; 2161 } 2162 } 2163 } 2164 } 2165 } 2166 2167 RpcTryExcept 2168 { 2169 Status = SamrSetInformationUser((SAMPR_HANDLE)UserHandle, 2170 UserAllInformation, 2171 (PVOID)&InternalAllBuffer); 2172 } 2173 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 2174 { 2175 Status = I_RpcMapWin32Status(RpcExceptionCode()); 2176 } 2177 RpcEndExcept; 2178 2179 if (!NT_SUCCESS(Status)) 2180 { 2181 TRACE("SamrSetInformation() failed (Status 0x%08lx)\n", Status); 2182 } 2183 2184 return Status; 2185 } 2186 2187 RpcTryExcept 2188 { 2189 Status = SamrSetInformationUser((SAMPR_HANDLE)UserHandle, 2190 UserInformationClass, 2191 Buffer); 2192 } 2193 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 2194 { 2195 Status = I_RpcMapWin32Status(RpcExceptionCode()); 2196 } 2197 RpcEndExcept; 2198 2199 return Status; 2200 } 2201 2202 2203 NTSTATUS 2204 NTAPI 2205 SamSetMemberAttributesOfGroup(IN SAM_HANDLE GroupHandle, 2206 IN ULONG MemberId, 2207 IN ULONG Attributes) 2208 { 2209 NTSTATUS Status; 2210 2211 TRACE("SamSetMemberAttributesOfGroup(%p %lu 0x%lx)\n", 2212 GroupHandle, MemberId, Attributes); 2213 2214 RpcTryExcept 2215 { 2216 Status = SamrSetMemberAttributesOfGroup((SAMPR_HANDLE)GroupHandle, 2217 MemberId, 2218 Attributes); 2219 } 2220 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 2221 { 2222 Status = I_RpcMapWin32Status(RpcExceptionCode()); 2223 } 2224 RpcEndExcept; 2225 2226 return Status; 2227 } 2228 2229 2230 NTSTATUS 2231 NTAPI 2232 SamSetSecurityObject(IN SAM_HANDLE ObjectHandle, 2233 IN SECURITY_INFORMATION SecurityInformation, 2234 IN PSECURITY_DESCRIPTOR SecurityDescriptor) 2235 { 2236 SAMPR_SR_SECURITY_DESCRIPTOR DescriptorToPass; 2237 ULONG Length; 2238 NTSTATUS Status; 2239 2240 TRACE("SamSetSecurityObject(%p %lu %p)\n", 2241 ObjectHandle, SecurityInformation, SecurityDescriptor); 2242 2243 /* Retrieve the length of the relative security descriptor */ 2244 Length = 0; 2245 Status = RtlMakeSelfRelativeSD(SecurityDescriptor, 2246 NULL, 2247 &Length); 2248 if (Status != STATUS_BUFFER_TOO_SMALL) 2249 return STATUS_INVALID_PARAMETER; 2250 2251 2252 /* Allocate a buffer for the security descriptor */ 2253 DescriptorToPass.Length = Length; 2254 DescriptorToPass.SecurityDescriptor = MIDL_user_allocate(Length); 2255 if (DescriptorToPass.SecurityDescriptor == NULL) 2256 return STATUS_INSUFFICIENT_RESOURCES; 2257 2258 /* Convert the given security descriptor to a relative security descriptor */ 2259 Status = RtlMakeSelfRelativeSD(SecurityDescriptor, 2260 (PSECURITY_DESCRIPTOR)DescriptorToPass.SecurityDescriptor, 2261 &Length); 2262 if (!NT_SUCCESS(Status)) 2263 goto done; 2264 2265 RpcTryExcept 2266 { 2267 Status = SamrSetSecurityObject((SAMPR_HANDLE)ObjectHandle, 2268 SecurityInformation, 2269 &DescriptorToPass); 2270 } 2271 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 2272 { 2273 Status = I_RpcMapWin32Status(RpcExceptionCode()); 2274 } 2275 RpcEndExcept; 2276 2277 done: 2278 if (DescriptorToPass.SecurityDescriptor != NULL) 2279 MIDL_user_free(DescriptorToPass.SecurityDescriptor); 2280 2281 return Status; 2282 } 2283 2284 2285 NTSTATUS 2286 NTAPI 2287 SamShutdownSamServer(IN SAM_HANDLE ServerHandle) 2288 { 2289 NTSTATUS Status; 2290 2291 TRACE("SamShutdownSamServer(%p)\n", ServerHandle); 2292 2293 RpcTryExcept 2294 { 2295 Status = SamrShutdownSamServer((SAMPR_HANDLE)ServerHandle); 2296 } 2297 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 2298 { 2299 Status = I_RpcMapWin32Status(RpcExceptionCode()); 2300 } 2301 RpcEndExcept; 2302 2303 return Status; 2304 } 2305 2306 2307 NTSTATUS 2308 NTAPI 2309 SamTestPrivateFunctionsDomain( 2310 _In_ SAM_HANDLE DomainHandle) 2311 { 2312 TRACE("SamTestPrivateFunctionsDomain(%p)\n", 2313 DomainHandle); 2314 return STATUS_NOT_IMPLEMENTED; 2315 } 2316 2317 2318 NTSTATUS 2319 NTAPI 2320 SamTestPrivateFunctionsUser( 2321 _In_ SAM_HANDLE UserHandle) 2322 { 2323 TRACE("SamTestPrivateFunctionsUser(%p)\n", 2324 UserHandle); 2325 return STATUS_NOT_IMPLEMENTED; 2326 } 2327 2328 /* EOF */ 2329