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