1 /* 2 * Copyright 2002 Andriy Palamarchuk 3 * 4 * netapi32 user functions 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 /* 22 * TODO: 23 * Implement NetUserGetGroups (WIP) 24 * Implement NetUserSetGroups 25 * NetUserGetLocalGroups does not support LG_INCLUDE_INDIRECT yet. 26 * Add missing information levels. 27 * ... 28 */ 29 30 #include "netapi32.h" 31 32 #include <ndk/kefuncs.h> 33 #include <ndk/obfuncs.h> 34 35 WINE_DEFAULT_DEBUG_CHANNEL(netapi32); 36 37 typedef struct _ENUM_CONTEXT 38 { 39 LIST_ENTRY ListLink; 40 ULONG EnumHandle; 41 42 SAM_HANDLE ServerHandle; 43 SAM_HANDLE BuiltinDomainHandle; 44 SAM_HANDLE AccountDomainHandle; 45 PSID BuiltinDomainSid; 46 PSID AccountDomainSid; 47 48 SAM_ENUMERATE_HANDLE EnumerationContext; 49 PSAM_RID_ENUMERATION Buffer; 50 ULONG Count; 51 ULONG Index; 52 BOOLEAN BuiltinDone; 53 54 } ENUM_CONTEXT, *PENUM_CONTEXT; 55 56 LIST_ENTRY g_EnumContextListHead; 57 CRITICAL_SECTION g_EnumContextListLock; 58 LONG g_EnumContextHandle = 0; 59 60 static 61 ULONG 62 DeltaTimeToSeconds(LARGE_INTEGER DeltaTime) 63 { 64 LARGE_INTEGER Seconds; 65 66 if (DeltaTime.QuadPart == 0) 67 return 0; 68 69 Seconds.QuadPart = -DeltaTime.QuadPart / 10000000; 70 71 if (Seconds.HighPart != 0) 72 return TIMEQ_FOREVER; 73 74 return Seconds.LowPart; 75 } 76 77 78 static 79 NTSTATUS 80 GetAllowedWorldAce(IN PACL Acl, 81 OUT PACCESS_ALLOWED_ACE *Ace) 82 { 83 SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY}; 84 ULONG WorldSid[sizeof(SID) / sizeof(ULONG) + SID_MAX_SUB_AUTHORITIES]; 85 ACL_SIZE_INFORMATION AclSize; 86 PVOID LocalAce = NULL; 87 ULONG i; 88 NTSTATUS Status; 89 90 *Ace = NULL; 91 92 RtlInitializeSid((PSID)WorldSid, 93 &WorldAuthority, 94 1); 95 *(RtlSubAuthoritySid((PSID)WorldSid, 0)) = SECURITY_WORLD_RID; 96 97 Status = RtlQueryInformationAcl(Acl, 98 &AclSize, 99 sizeof(AclSize), 100 AclSizeInformation); 101 if (!NT_SUCCESS(Status)) 102 return Status; 103 104 for (i = 0; i < AclSize.AceCount; i++) 105 { 106 Status = RtlGetAce(Acl, i, &LocalAce); 107 if (!NT_SUCCESS(Status)) 108 return Status; 109 110 if (((PACE_HEADER)LocalAce)->AceType != ACCESS_ALLOWED_ACE_TYPE) 111 continue; 112 113 if (RtlEqualSid((PSID)WorldSid, 114 (PSID)&((PACCESS_ALLOWED_ACE)LocalAce)->SidStart)) 115 { 116 *Ace = (PACCESS_ALLOWED_ACE)LocalAce; 117 return STATUS_SUCCESS; 118 } 119 } 120 121 return STATUS_SUCCESS; 122 } 123 124 125 static 126 ULONG 127 GetAccountFlags(ULONG AccountControl, 128 PACL Dacl) 129 { 130 PACCESS_ALLOWED_ACE Ace = NULL; 131 ULONG Flags = UF_SCRIPT; 132 NTSTATUS Status; 133 134 if (Dacl != NULL) 135 { 136 Status = GetAllowedWorldAce(Dacl, &Ace); 137 if (NT_SUCCESS(Status)) 138 { 139 if (Ace == NULL) 140 { 141 Flags |= UF_PASSWD_CANT_CHANGE; 142 } 143 else if ((Ace->Mask & USER_CHANGE_PASSWORD) == 0) 144 { 145 Flags |= UF_PASSWD_CANT_CHANGE; 146 } 147 } 148 } 149 150 if (AccountControl & USER_ACCOUNT_DISABLED) 151 Flags |= UF_ACCOUNTDISABLE; 152 153 if (AccountControl & USER_HOME_DIRECTORY_REQUIRED) 154 Flags |= UF_HOMEDIR_REQUIRED; 155 156 if (AccountControl & USER_PASSWORD_NOT_REQUIRED) 157 Flags |= UF_PASSWD_NOTREQD; 158 159 if (AccountControl & USER_ACCOUNT_AUTO_LOCKED) 160 Flags |= UF_LOCKOUT; 161 162 if (AccountControl & USER_DONT_EXPIRE_PASSWORD) 163 Flags |= UF_DONT_EXPIRE_PASSWD; 164 165 /* 166 if (AccountControl & USER_ENCRYPTED_TEXT_PASSWORD_ALLOWED) 167 Flags |= UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED; 168 169 if (AccountControl & USER_SMARTCARD_REQUIRED) 170 Flags |= UF_SMARTCARD_REQUIRED; 171 172 if (AccountControl & USER_TRUSTED_FOR_DELEGATION) 173 Flags |= UF_TRUSTED_FOR_DELEGATION; 174 175 if (AccountControl & USER_NOT_DELEGATED) 176 Flags |= UF_NOT_DELEGATED; 177 178 if (AccountControl & USER_USE_DES_KEY_ONLY) 179 Flags |= UF_USE_DES_KEY_ONLY; 180 181 if (AccountControl & USER_DONT_REQUIRE_PREAUTH) 182 Flags |= UF_DONT_REQUIRE_PREAUTH; 183 184 if (AccountControl & USER_PASSWORD_EXPIRED) 185 Flags |= UF_PASSWORD_EXPIRED; 186 */ 187 188 /* Set account type flags */ 189 if (AccountControl & USER_TEMP_DUPLICATE_ACCOUNT) 190 Flags |= UF_TEMP_DUPLICATE_ACCOUNT; 191 else if (AccountControl & USER_NORMAL_ACCOUNT) 192 Flags |= UF_NORMAL_ACCOUNT; 193 else if (AccountControl & USER_INTERDOMAIN_TRUST_ACCOUNT) 194 Flags |= UF_INTERDOMAIN_TRUST_ACCOUNT; 195 else if (AccountControl & USER_WORKSTATION_TRUST_ACCOUNT) 196 Flags |= UF_WORKSTATION_TRUST_ACCOUNT; 197 else if (AccountControl & USER_SERVER_TRUST_ACCOUNT) 198 Flags |= UF_SERVER_TRUST_ACCOUNT; 199 200 return Flags; 201 } 202 203 204 static 205 ULONG 206 GetAccountControl(ULONG Flags) 207 { 208 ULONG AccountControl = 0; 209 210 if (Flags & UF_ACCOUNTDISABLE) 211 AccountControl |= USER_ACCOUNT_DISABLED; 212 213 if (Flags & UF_HOMEDIR_REQUIRED) 214 AccountControl |= USER_HOME_DIRECTORY_REQUIRED; 215 216 if (Flags & UF_PASSWD_NOTREQD) 217 AccountControl |= USER_PASSWORD_NOT_REQUIRED; 218 219 if (Flags & UF_LOCKOUT) 220 AccountControl |= USER_ACCOUNT_AUTO_LOCKED; 221 222 if (Flags & UF_DONT_EXPIRE_PASSWD) 223 AccountControl |= USER_DONT_EXPIRE_PASSWORD; 224 225 /* Set account type flags */ 226 if (Flags & UF_TEMP_DUPLICATE_ACCOUNT) 227 AccountControl |= USER_TEMP_DUPLICATE_ACCOUNT; 228 else if (Flags & UF_NORMAL_ACCOUNT) 229 AccountControl |= USER_NORMAL_ACCOUNT; 230 else if (Flags & UF_INTERDOMAIN_TRUST_ACCOUNT) 231 AccountControl |= USER_INTERDOMAIN_TRUST_ACCOUNT; 232 else if (Flags & UF_WORKSTATION_TRUST_ACCOUNT) 233 AccountControl |= USER_WORKSTATION_TRUST_ACCOUNT; 234 else if (Flags & UF_SERVER_TRUST_ACCOUNT) 235 AccountControl |= USER_SERVER_TRUST_ACCOUNT; 236 237 return AccountControl; 238 } 239 240 241 static 242 DWORD 243 GetPasswordAge(IN PLARGE_INTEGER PasswordLastSet) 244 { 245 LARGE_INTEGER SystemTime; 246 ULONG SystemSecondsSince1970; 247 ULONG PasswordSecondsSince1970; 248 NTSTATUS Status; 249 250 Status = NtQuerySystemTime(&SystemTime); 251 if (!NT_SUCCESS(Status)) 252 return 0; 253 254 RtlTimeToSecondsSince1970(&SystemTime, &SystemSecondsSince1970); 255 RtlTimeToSecondsSince1970(PasswordLastSet, &PasswordSecondsSince1970); 256 257 return SystemSecondsSince1970 - PasswordSecondsSince1970; 258 } 259 260 261 static 262 VOID 263 ChangeUserDacl(IN PACL Dacl, 264 IN ULONG Flags) 265 { 266 PACCESS_ALLOWED_ACE Ace = NULL; 267 NTSTATUS Status; 268 269 if (Dacl == NULL) 270 return; 271 272 Status = GetAllowedWorldAce(Dacl, &Ace); 273 if (!NT_SUCCESS(Status)) 274 return; 275 276 if (Flags & UF_PASSWD_CANT_CHANGE) 277 Ace->Mask &= ~USER_CHANGE_PASSWORD; 278 else 279 Ace->Mask |= USER_CHANGE_PASSWORD; 280 } 281 282 283 static 284 NET_API_STATUS 285 GetUserDacl(IN SAM_HANDLE UserHandle, 286 OUT PACL *Dacl) 287 { 288 PSECURITY_DESCRIPTOR SecurityDescriptor = NULL; 289 PACL SamDacl; 290 PACL LocalDacl; 291 BOOLEAN Defaulted; 292 BOOLEAN Present; 293 ACL_SIZE_INFORMATION AclSize; 294 NET_API_STATUS ApiStatus; 295 NTSTATUS Status; 296 297 TRACE("(%p %p)\n", UserHandle, Dacl); 298 299 *Dacl = NULL; 300 301 Status = SamQuerySecurityObject(UserHandle, 302 DACL_SECURITY_INFORMATION, 303 &SecurityDescriptor); 304 if (!NT_SUCCESS(Status)) 305 { 306 TRACE("SamQuerySecurityObject() failed (Status 0x%08lx)\n", Status); 307 ApiStatus = NetpNtStatusToApiStatus(Status); 308 goto done; 309 } 310 311 Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor, 312 &Present, 313 &SamDacl, 314 &Defaulted); 315 if (!NT_SUCCESS(Status)) 316 { 317 TRACE("RtlGetDaclSecurityDescriptor() failed (Status 0x%08lx)\n", Status); 318 ApiStatus = NERR_InternalError; 319 goto done; 320 } 321 322 if (Present == FALSE) 323 { 324 TRACE("No DACL present\n"); 325 ApiStatus = NERR_Success; 326 goto done; 327 } 328 329 Status = RtlQueryInformationAcl(SamDacl, 330 &AclSize, 331 sizeof(AclSize), 332 AclSizeInformation); 333 if (!NT_SUCCESS(Status)) 334 { 335 TRACE("RtlQueryInformationAcl() failed (Status 0x%08lx)\n", Status); 336 ApiStatus = NERR_InternalError; 337 goto done; 338 } 339 340 LocalDacl = HeapAlloc(GetProcessHeap(), 0, AclSize.AclBytesInUse); 341 if (LocalDacl == NULL) 342 { 343 TRACE("Memory allocation failed\n"); 344 ApiStatus = ERROR_NOT_ENOUGH_MEMORY; 345 goto done; 346 } 347 348 RtlCopyMemory(LocalDacl, SamDacl, AclSize.AclBytesInUse); 349 350 *Dacl = LocalDacl; 351 352 ApiStatus = NERR_Success; 353 354 done: 355 if (SecurityDescriptor != NULL) 356 SamFreeMemory(SecurityDescriptor); 357 358 TRACE("done (ApiStatus: 0x%08lx)\n", ApiStatus); 359 360 return ApiStatus; 361 } 362 363 364 static 365 VOID 366 FreeUserInfo(PUSER_ALL_INFORMATION UserInfo) 367 { 368 if (UserInfo->UserName.Buffer != NULL) 369 SamFreeMemory(UserInfo->UserName.Buffer); 370 371 if (UserInfo->FullName.Buffer != NULL) 372 SamFreeMemory(UserInfo->FullName.Buffer); 373 374 if (UserInfo->HomeDirectory.Buffer != NULL) 375 SamFreeMemory(UserInfo->HomeDirectory.Buffer); 376 377 if (UserInfo->HomeDirectoryDrive.Buffer != NULL) 378 SamFreeMemory(UserInfo->HomeDirectoryDrive.Buffer); 379 380 if (UserInfo->ScriptPath.Buffer != NULL) 381 SamFreeMemory(UserInfo->ScriptPath.Buffer); 382 383 if (UserInfo->ProfilePath.Buffer != NULL) 384 SamFreeMemory(UserInfo->ProfilePath.Buffer); 385 386 if (UserInfo->AdminComment.Buffer != NULL) 387 SamFreeMemory(UserInfo->AdminComment.Buffer); 388 389 if (UserInfo->WorkStations.Buffer != NULL) 390 SamFreeMemory(UserInfo->WorkStations.Buffer); 391 392 if (UserInfo->UserComment.Buffer != NULL) 393 SamFreeMemory(UserInfo->UserComment.Buffer); 394 395 if (UserInfo->Parameters.Buffer != NULL) 396 SamFreeMemory(UserInfo->Parameters.Buffer); 397 398 if (UserInfo->PrivateData.Buffer != NULL) 399 SamFreeMemory(UserInfo->PrivateData.Buffer); 400 401 if (UserInfo->LogonHours.LogonHours != NULL) 402 SamFreeMemory(UserInfo->LogonHours.LogonHours); 403 404 SamFreeMemory(UserInfo); 405 } 406 407 408 static 409 NET_API_STATUS 410 GetUserPrivileges( 411 _In_ SAM_HANDLE BuiltinDomainHandle, 412 _In_ SAM_HANDLE UserHandle, 413 _In_ PSID AccountDomainSid, 414 _In_ ULONG RelativeId, 415 _Out_ PDWORD Priv, 416 _Out_ PDWORD AuthFlags) 417 { 418 PGROUP_MEMBERSHIP GroupMembership = NULL; 419 ULONG GroupCount, SidCount, AliasCount, i; 420 PSID *SidArray = NULL; 421 PULONG AliasArray = NULL; 422 BOOL bAdmin = FALSE, bUser = FALSE; 423 NET_API_STATUS ApiStatus = NERR_Success; 424 NTSTATUS Status; 425 426 FIXME("GetUserPrivileges(%p)\n", UserHandle); 427 428 /* Get the users group memberships */ 429 Status = SamGetGroupsForUser(UserHandle, 430 &GroupMembership, 431 &GroupCount); 432 if (!NT_SUCCESS(Status)) 433 { 434 ERR("SamGetGroupsForUser() failed (Status 0x%08lx)\n", Status); 435 ApiStatus = NetpNtStatusToApiStatus(Status); 436 goto done; 437 } 438 439 /* Allocate the SID array */ 440 ApiStatus = NetApiBufferAllocate((GroupCount + 1) * sizeof(PSID), 441 (PVOID*)&SidArray); 442 if (ApiStatus != NERR_Success) 443 { 444 goto done; 445 } 446 447 /* Add the user to the SID array */ 448 SidCount = 0; 449 ApiStatus = BuildSidFromSidAndRid(AccountDomainSid, 450 RelativeId, 451 &SidArray[0]); 452 if (ApiStatus != NERR_Success) 453 { 454 goto done; 455 } 456 457 SidCount++; 458 459 /* Add the groups to the SID array */ 460 for (i = 0; i < GroupCount; i++) 461 { 462 ApiStatus = BuildSidFromSidAndRid(AccountDomainSid, 463 GroupMembership[i].RelativeId, 464 &SidArray[i + 1]); 465 if (ApiStatus != NERR_Success) 466 { 467 goto done; 468 } 469 470 SidCount++; 471 } 472 473 /* Get aliases for the user and his groups */ 474 Status = SamGetAliasMembership(BuiltinDomainHandle, 475 SidCount, 476 SidArray, 477 &AliasCount, 478 &AliasArray); 479 if (!NT_SUCCESS(Status)) 480 { 481 ERR("SamGetAliasMembership() failed (Status 0x%08lx)\n", Status); 482 ApiStatus = NetpNtStatusToApiStatus(Status); 483 goto done; 484 } 485 486 *AuthFlags = 0; 487 488 /* Set the AuthFlags */ 489 for (i = 0; i < AliasCount; i++) 490 { 491 switch (AliasArray[i]) 492 { 493 case DOMAIN_ALIAS_RID_ADMINS: 494 bAdmin = TRUE; 495 break; 496 497 case DOMAIN_ALIAS_RID_USERS: 498 bUser = TRUE; 499 break; 500 501 case DOMAIN_ALIAS_RID_ACCOUNT_OPS: 502 *AuthFlags |= AF_OP_ACCOUNTS; 503 break; 504 505 case DOMAIN_ALIAS_RID_SYSTEM_OPS: 506 *AuthFlags |= AF_OP_SERVER; 507 break; 508 509 case DOMAIN_ALIAS_RID_PRINT_OPS: 510 *AuthFlags |= AF_OP_PRINT; 511 break; 512 } 513 } 514 515 /* Set the prvileges */ 516 if (bAdmin) 517 { 518 *Priv = USER_PRIV_ADMIN; 519 } 520 else if (bUser) 521 { 522 *Priv = USER_PRIV_USER; 523 } 524 else 525 { 526 *Priv = USER_PRIV_GUEST; 527 } 528 529 done: 530 if (AliasArray != NULL) 531 SamFreeMemory(AliasArray); 532 533 if (SidArray != NULL) 534 { 535 for (i = 0; i < SidCount; i++) 536 NetApiBufferFree(SidArray[i]); 537 538 NetApiBufferFree(SidArray); 539 } 540 541 if (GroupMembership != NULL) 542 SamFreeMemory(GroupMembership); 543 544 return ApiStatus; 545 } 546 547 548 static 549 NET_API_STATUS 550 BuildUserInfoBuffer( 551 _In_ SAM_HANDLE BuiltinDomainHandle, 552 _In_ SAM_HANDLE UserHandle, 553 _In_ PSID AccountDomainSid, 554 _In_ ULONG RelativeId, 555 _In_ DWORD level, 556 _Out_ LPVOID *Buffer) 557 { 558 UNICODE_STRING LogonServer = RTL_CONSTANT_STRING(L"\\\\*"); 559 PUSER_ALL_INFORMATION UserInfo = NULL; 560 LPVOID LocalBuffer = NULL; 561 PACL Dacl = NULL; 562 DWORD Priv = 0, AuthFlags = 0; 563 PUSER_INFO_0 UserInfo0; 564 PUSER_INFO_1 UserInfo1; 565 PUSER_INFO_2 UserInfo2; 566 PUSER_INFO_3 UserInfo3; 567 PUSER_INFO_4 UserInfo4; 568 PUSER_INFO_10 UserInfo10; 569 PUSER_INFO_11 UserInfo11; 570 PUSER_INFO_20 UserInfo20; 571 PUSER_INFO_23 UserInfo23; 572 LPWSTR Ptr; 573 ULONG Size = 0; 574 NTSTATUS Status; 575 NET_API_STATUS ApiStatus = NERR_Success; 576 577 *Buffer = NULL; 578 579 Status = SamQueryInformationUser(UserHandle, 580 UserAllInformation, 581 (PVOID *)&UserInfo); 582 if (!NT_SUCCESS(Status)) 583 { 584 ERR("SamQueryInformationUser failed (Status %08lx)\n", Status); 585 ApiStatus = NetpNtStatusToApiStatus(Status); 586 goto done; 587 } 588 589 if ((level == 1) || (level == 2) || (level == 3) || 590 (level == 4) || (level == 20) || (level == 23)) 591 { 592 ApiStatus = GetUserDacl(UserHandle, &Dacl); 593 if (ApiStatus != NERR_Success) 594 goto done; 595 } 596 597 if ((level == 1) || (level == 2) || (level == 3) || 598 (level == 4) || (level == 11)) 599 { 600 ApiStatus = GetUserPrivileges(BuiltinDomainHandle, 601 UserHandle, 602 AccountDomainSid, 603 RelativeId, 604 &Priv, 605 &AuthFlags); 606 if (ApiStatus != NERR_Success) 607 goto done; 608 } 609 610 switch (level) 611 { 612 case 0: 613 Size = sizeof(USER_INFO_0) + 614 UserInfo->UserName.Length + sizeof(WCHAR); 615 break; 616 617 case 1: 618 Size = sizeof(USER_INFO_1) + 619 UserInfo->UserName.Length + sizeof(WCHAR) + 620 UserInfo->HomeDirectory.Length + sizeof(WCHAR) + 621 UserInfo->AdminComment.Length + sizeof(WCHAR) + 622 UserInfo->ScriptPath.Length + sizeof(WCHAR); 623 break; 624 625 case 2: 626 Size = sizeof(USER_INFO_2) + 627 UserInfo->UserName.Length + sizeof(WCHAR) + 628 UserInfo->HomeDirectory.Length + sizeof(WCHAR) + 629 UserInfo->AdminComment.Length + sizeof(WCHAR) + 630 UserInfo->ScriptPath.Length + sizeof(WCHAR) + 631 UserInfo->FullName.Length + sizeof(WCHAR) + 632 UserInfo->UserComment.Length + sizeof(WCHAR) + 633 UserInfo->Parameters.Length + sizeof(WCHAR) + 634 UserInfo->WorkStations.Length + sizeof(WCHAR) + 635 LogonServer.Length + sizeof(WCHAR); 636 637 if (UserInfo->LogonHours.UnitsPerWeek > 0) 638 Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8; 639 break; 640 641 case 3: 642 Size = sizeof(USER_INFO_3) + 643 UserInfo->UserName.Length + sizeof(WCHAR) + 644 UserInfo->HomeDirectory.Length + sizeof(WCHAR) + 645 UserInfo->AdminComment.Length + sizeof(WCHAR) + 646 UserInfo->ScriptPath.Length + sizeof(WCHAR) + 647 UserInfo->FullName.Length + sizeof(WCHAR) + 648 UserInfo->UserComment.Length + sizeof(WCHAR) + 649 UserInfo->Parameters.Length + sizeof(WCHAR) + 650 UserInfo->WorkStations.Length + sizeof(WCHAR) + 651 LogonServer.Length + sizeof(WCHAR) + 652 UserInfo->ProfilePath.Length + sizeof(WCHAR) + 653 UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR); 654 655 if (UserInfo->LogonHours.UnitsPerWeek > 0) 656 Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8; 657 break; 658 659 case 4: 660 Size = sizeof(USER_INFO_4) + 661 UserInfo->UserName.Length + sizeof(WCHAR) + 662 UserInfo->HomeDirectory.Length + sizeof(WCHAR) + 663 UserInfo->AdminComment.Length + sizeof(WCHAR) + 664 UserInfo->ScriptPath.Length + sizeof(WCHAR) + 665 UserInfo->FullName.Length + sizeof(WCHAR) + 666 UserInfo->UserComment.Length + sizeof(WCHAR) + 667 UserInfo->Parameters.Length + sizeof(WCHAR) + 668 UserInfo->WorkStations.Length + sizeof(WCHAR) + 669 LogonServer.Length + sizeof(WCHAR) + 670 UserInfo->ProfilePath.Length + sizeof(WCHAR) + 671 UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR); 672 673 if (UserInfo->LogonHours.UnitsPerWeek > 0) 674 Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8; 675 676 Size += RtlLengthSid(AccountDomainSid) + sizeof(ULONG); 677 break; 678 679 case 10: 680 Size = sizeof(USER_INFO_10) + 681 UserInfo->UserName.Length + sizeof(WCHAR) + 682 UserInfo->AdminComment.Length + sizeof(WCHAR) + 683 UserInfo->UserComment.Length + sizeof(WCHAR) + 684 UserInfo->FullName.Length + sizeof(WCHAR); 685 break; 686 687 case 11: 688 Size = sizeof(USER_INFO_11) + 689 UserInfo->UserName.Length + sizeof(WCHAR) + 690 UserInfo->AdminComment.Length + sizeof(WCHAR) + 691 UserInfo->UserComment.Length + sizeof(WCHAR) + 692 UserInfo->FullName.Length + sizeof(WCHAR) + 693 UserInfo->HomeDirectory.Length + sizeof(WCHAR) + 694 UserInfo->Parameters.Length + sizeof(WCHAR) + 695 LogonServer.Length + sizeof(WCHAR) + 696 UserInfo->WorkStations.Length + sizeof(WCHAR); 697 698 if (UserInfo->LogonHours.UnitsPerWeek > 0) 699 Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8; 700 break; 701 702 case 20: 703 Size = sizeof(USER_INFO_20) + 704 UserInfo->UserName.Length + sizeof(WCHAR) + 705 UserInfo->FullName.Length + sizeof(WCHAR) + 706 UserInfo->AdminComment.Length + sizeof(WCHAR); 707 break; 708 709 case 23: 710 Size = sizeof(USER_INFO_23) + 711 UserInfo->UserName.Length + sizeof(WCHAR) + 712 UserInfo->FullName.Length + sizeof(WCHAR) + 713 UserInfo->AdminComment.Length + sizeof(WCHAR); 714 715 Size += RtlLengthSid(AccountDomainSid) + sizeof(ULONG); 716 break; 717 718 default: 719 ApiStatus = ERROR_INVALID_LEVEL; 720 goto done; 721 } 722 723 ApiStatus = NetApiBufferAllocate(Size, &LocalBuffer); 724 if (ApiStatus != NERR_Success) 725 goto done; 726 727 ZeroMemory(LocalBuffer, Size); 728 729 switch (level) 730 { 731 case 0: 732 UserInfo0 = (PUSER_INFO_0)LocalBuffer; 733 734 Ptr = (LPWSTR)((ULONG_PTR)UserInfo0 + sizeof(USER_INFO_0)); 735 736 UserInfo0->usri0_name = Ptr; 737 738 memcpy(UserInfo0->usri0_name, 739 UserInfo->UserName.Buffer, 740 UserInfo->UserName.Length); 741 UserInfo0->usri0_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL; 742 break; 743 744 case 1: 745 UserInfo1 = (PUSER_INFO_1)LocalBuffer; 746 747 Ptr = (LPWSTR)((ULONG_PTR)UserInfo1 + sizeof(USER_INFO_1)); 748 749 UserInfo1->usri1_name = Ptr; 750 751 memcpy(UserInfo1->usri1_name, 752 UserInfo->UserName.Buffer, 753 UserInfo->UserName.Length); 754 UserInfo1->usri1_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL; 755 756 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR)); 757 758 UserInfo1->usri1_password = NULL; 759 UserInfo1->usri1_password_age = GetPasswordAge(&UserInfo->PasswordLastSet); 760 761 UserInfo1->usri1_priv = Priv; 762 763 UserInfo1->usri1_home_dir = Ptr; 764 memcpy(UserInfo1->usri1_home_dir, 765 UserInfo->HomeDirectory.Buffer, 766 UserInfo->HomeDirectory.Length); 767 UserInfo1->usri1_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL; 768 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR)); 769 770 UserInfo1->usri1_comment = Ptr; 771 memcpy(UserInfo1->usri1_comment, 772 UserInfo->AdminComment.Buffer, 773 UserInfo->AdminComment.Length); 774 UserInfo1->usri1_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL; 775 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR)); 776 777 UserInfo1->usri1_flags = GetAccountFlags(UserInfo->UserAccountControl, 778 Dacl); 779 780 UserInfo1->usri1_script_path = Ptr; 781 memcpy(UserInfo1->usri1_script_path, 782 UserInfo->ScriptPath.Buffer, 783 UserInfo->ScriptPath.Length); 784 UserInfo1->usri1_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL; 785 break; 786 787 case 2: 788 UserInfo2 = (PUSER_INFO_2)LocalBuffer; 789 790 Ptr = (LPWSTR)((ULONG_PTR)UserInfo2 + sizeof(USER_INFO_2)); 791 792 UserInfo2->usri2_name = Ptr; 793 794 memcpy(UserInfo2->usri2_name, 795 UserInfo->UserName.Buffer, 796 UserInfo->UserName.Length); 797 UserInfo2->usri2_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL; 798 799 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR)); 800 801 UserInfo2->usri2_password = NULL; 802 UserInfo2->usri2_password_age = GetPasswordAge(&UserInfo->PasswordLastSet); 803 804 UserInfo2->usri2_priv = Priv; 805 806 UserInfo2->usri2_home_dir = Ptr; 807 memcpy(UserInfo2->usri2_home_dir, 808 UserInfo->HomeDirectory.Buffer, 809 UserInfo->HomeDirectory.Length); 810 UserInfo2->usri2_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL; 811 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR)); 812 813 UserInfo2->usri2_comment = Ptr; 814 memcpy(UserInfo2->usri2_comment, 815 UserInfo->AdminComment.Buffer, 816 UserInfo->AdminComment.Length); 817 UserInfo2->usri2_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL; 818 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR)); 819 820 UserInfo2->usri2_flags = GetAccountFlags(UserInfo->UserAccountControl, 821 Dacl); 822 823 UserInfo2->usri2_script_path = Ptr; 824 memcpy(UserInfo2->usri2_script_path, 825 UserInfo->ScriptPath.Buffer, 826 UserInfo->ScriptPath.Length); 827 UserInfo2->usri2_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL; 828 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ScriptPath.Length + sizeof(WCHAR)); 829 830 UserInfo2->usri2_auth_flags = AuthFlags; 831 832 UserInfo2->usri2_full_name = Ptr; 833 memcpy(UserInfo2->usri2_full_name, 834 UserInfo->FullName.Buffer, 835 UserInfo->FullName.Length); 836 UserInfo2->usri2_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL; 837 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR)); 838 839 UserInfo2->usri2_usr_comment = Ptr; 840 memcpy(UserInfo2->usri2_usr_comment, 841 UserInfo->UserComment.Buffer, 842 UserInfo->UserComment.Length); 843 UserInfo2->usri2_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL; 844 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR)); 845 846 UserInfo2->usri2_parms = Ptr; 847 memcpy(UserInfo2->usri2_parms, 848 UserInfo->Parameters.Buffer, 849 UserInfo->Parameters.Length); 850 UserInfo2->usri2_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL; 851 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR)); 852 853 UserInfo2->usri2_workstations = Ptr; 854 memcpy(UserInfo2->usri2_workstations, 855 UserInfo->WorkStations.Buffer, 856 UserInfo->WorkStations.Length); 857 UserInfo2->usri2_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL; 858 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR)); 859 860 if (UserInfo->LastLogon.QuadPart == 0) 861 UserInfo2->usri2_last_logon = 0; 862 else 863 RtlTimeToSecondsSince1970(&UserInfo->LastLogon, 864 &UserInfo2->usri2_last_logon); 865 866 if (UserInfo->LastLogoff.QuadPart == 0) 867 UserInfo2->usri2_last_logoff = 0; 868 else 869 RtlTimeToSecondsSince1970(&UserInfo->LastLogoff, 870 &UserInfo2->usri2_last_logoff); 871 872 if (UserInfo->AccountExpires.QuadPart == MAXLONGLONG) 873 UserInfo2->usri2_acct_expires = TIMEQ_FOREVER; 874 else 875 RtlTimeToSecondsSince1970(&UserInfo->AccountExpires, 876 &UserInfo2->usri2_acct_expires); 877 878 UserInfo2->usri2_max_storage = USER_MAXSTORAGE_UNLIMITED; 879 UserInfo2->usri2_units_per_week = UserInfo->LogonHours.UnitsPerWeek; 880 881 if (UserInfo->LogonHours.UnitsPerWeek > 0) 882 { 883 UserInfo2->usri2_logon_hours = (PVOID)Ptr; 884 885 memcpy(UserInfo2->usri2_logon_hours, 886 UserInfo->LogonHours.LogonHours, 887 (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8); 888 889 Ptr = (LPWSTR)((ULONG_PTR)Ptr + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8); 890 } 891 892 UserInfo2->usri2_bad_pw_count = UserInfo->BadPasswordCount; 893 UserInfo2->usri2_num_logons = UserInfo->LogonCount; 894 895 UserInfo2->usri2_logon_server = Ptr; 896 memcpy(UserInfo2->usri2_logon_server, 897 LogonServer.Buffer, 898 LogonServer.Length); 899 UserInfo2->usri2_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL; 900 Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR)); 901 902 UserInfo2->usri2_country_code = UserInfo->CountryCode; 903 UserInfo2->usri2_code_page = UserInfo->CodePage; 904 break; 905 906 case 3: 907 UserInfo3 = (PUSER_INFO_3)LocalBuffer; 908 909 Ptr = (LPWSTR)((ULONG_PTR)UserInfo3 + sizeof(USER_INFO_3)); 910 911 UserInfo3->usri3_name = Ptr; 912 913 memcpy(UserInfo3->usri3_name, 914 UserInfo->UserName.Buffer, 915 UserInfo->UserName.Length); 916 UserInfo3->usri3_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL; 917 918 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR)); 919 920 UserInfo3->usri3_password = NULL; 921 UserInfo3->usri3_password_age = GetPasswordAge(&UserInfo->PasswordLastSet); 922 923 UserInfo3->usri3_priv = Priv; 924 925 UserInfo3->usri3_home_dir = Ptr; 926 memcpy(UserInfo3->usri3_home_dir, 927 UserInfo->HomeDirectory.Buffer, 928 UserInfo->HomeDirectory.Length); 929 UserInfo3->usri3_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL; 930 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR)); 931 932 UserInfo3->usri3_comment = Ptr; 933 memcpy(UserInfo3->usri3_comment, 934 UserInfo->AdminComment.Buffer, 935 UserInfo->AdminComment.Length); 936 UserInfo3->usri3_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL; 937 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR)); 938 939 UserInfo3->usri3_flags = GetAccountFlags(UserInfo->UserAccountControl, 940 Dacl); 941 942 UserInfo3->usri3_script_path = Ptr; 943 memcpy(UserInfo3->usri3_script_path, 944 UserInfo->ScriptPath.Buffer, 945 UserInfo->ScriptPath.Length); 946 UserInfo3->usri3_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL; 947 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ScriptPath.Length + sizeof(WCHAR)); 948 949 UserInfo3->usri3_auth_flags = AuthFlags; 950 951 UserInfo3->usri3_full_name = Ptr; 952 memcpy(UserInfo3->usri3_full_name, 953 UserInfo->FullName.Buffer, 954 UserInfo->FullName.Length); 955 UserInfo3->usri3_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL; 956 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR)); 957 958 UserInfo3->usri3_usr_comment = Ptr; 959 memcpy(UserInfo3->usri3_usr_comment, 960 UserInfo->UserComment.Buffer, 961 UserInfo->UserComment.Length); 962 UserInfo3->usri3_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL; 963 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR)); 964 965 UserInfo3->usri3_parms = Ptr; 966 memcpy(UserInfo3->usri3_parms, 967 UserInfo->Parameters.Buffer, 968 UserInfo->Parameters.Length); 969 UserInfo3->usri3_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL; 970 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR)); 971 972 UserInfo3->usri3_workstations = Ptr; 973 memcpy(UserInfo3->usri3_workstations, 974 UserInfo->WorkStations.Buffer, 975 UserInfo->WorkStations.Length); 976 UserInfo3->usri3_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL; 977 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR)); 978 979 if (UserInfo->LastLogon.QuadPart == 0) 980 UserInfo3->usri3_last_logon = 0; 981 else 982 RtlTimeToSecondsSince1970(&UserInfo->LastLogon, 983 &UserInfo3->usri3_last_logon); 984 985 if (UserInfo->LastLogoff.QuadPart == 0) 986 UserInfo3->usri3_last_logoff = 0; 987 else 988 RtlTimeToSecondsSince1970(&UserInfo->LastLogoff, 989 &UserInfo3->usri3_last_logoff); 990 991 if (UserInfo->AccountExpires.QuadPart == MAXLONGLONG) 992 UserInfo3->usri3_acct_expires = TIMEQ_FOREVER; 993 else 994 RtlTimeToSecondsSince1970(&UserInfo->AccountExpires, 995 &UserInfo3->usri3_acct_expires); 996 997 UserInfo3->usri3_max_storage = USER_MAXSTORAGE_UNLIMITED; 998 UserInfo3->usri3_units_per_week = UserInfo->LogonHours.UnitsPerWeek; 999 1000 if (UserInfo->LogonHours.UnitsPerWeek > 0) 1001 { 1002 UserInfo3->usri3_logon_hours = (PVOID)Ptr; 1003 1004 memcpy(UserInfo3->usri3_logon_hours, 1005 UserInfo->LogonHours.LogonHours, 1006 (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8); 1007 1008 Ptr = (LPWSTR)((ULONG_PTR)Ptr + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8); 1009 } 1010 1011 UserInfo3->usri3_bad_pw_count = UserInfo->BadPasswordCount; 1012 UserInfo3->usri3_num_logons = UserInfo->LogonCount; 1013 1014 UserInfo3->usri3_logon_server = Ptr; 1015 memcpy(UserInfo3->usri3_logon_server, 1016 LogonServer.Buffer, 1017 LogonServer.Length); 1018 UserInfo3->usri3_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL; 1019 Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR)); 1020 1021 UserInfo3->usri3_country_code = UserInfo->CountryCode; 1022 UserInfo3->usri3_code_page = UserInfo->CodePage; 1023 UserInfo3->usri3_user_id = RelativeId; 1024 UserInfo3->usri3_primary_group_id = UserInfo->PrimaryGroupId; 1025 1026 UserInfo3->usri3_profile = Ptr; 1027 memcpy(UserInfo3->usri3_profile, 1028 UserInfo->ProfilePath.Buffer, 1029 UserInfo->ProfilePath.Length); 1030 UserInfo3->usri3_profile[UserInfo->ProfilePath.Length / sizeof(WCHAR)] = UNICODE_NULL; 1031 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ProfilePath.Length + sizeof(WCHAR)); 1032 1033 UserInfo3->usri3_home_dir_drive = Ptr; 1034 memcpy(UserInfo3->usri3_home_dir_drive, 1035 UserInfo->HomeDirectoryDrive.Buffer, 1036 UserInfo->HomeDirectoryDrive.Length); 1037 UserInfo3->usri3_home_dir_drive[UserInfo->HomeDirectoryDrive.Length / sizeof(WCHAR)] = UNICODE_NULL; 1038 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR)); 1039 1040 UserInfo3->usri3_password_expired = (UserInfo->UserAccountControl & USER_PASSWORD_EXPIRED); 1041 break; 1042 1043 case 4: 1044 UserInfo4 = (PUSER_INFO_4)LocalBuffer; 1045 1046 Ptr = (LPWSTR)((ULONG_PTR)UserInfo4 + sizeof(USER_INFO_4)); 1047 1048 UserInfo4->usri4_name = Ptr; 1049 1050 memcpy(UserInfo4->usri4_name, 1051 UserInfo->UserName.Buffer, 1052 UserInfo->UserName.Length); 1053 UserInfo4->usri4_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL; 1054 1055 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR)); 1056 1057 UserInfo4->usri4_password = NULL; 1058 UserInfo4->usri4_password_age = GetPasswordAge(&UserInfo->PasswordLastSet); 1059 1060 UserInfo4->usri4_priv = Priv; 1061 1062 UserInfo4->usri4_home_dir = Ptr; 1063 memcpy(UserInfo4->usri4_home_dir, 1064 UserInfo->HomeDirectory.Buffer, 1065 UserInfo->HomeDirectory.Length); 1066 UserInfo4->usri4_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL; 1067 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR)); 1068 1069 UserInfo4->usri4_comment = Ptr; 1070 memcpy(UserInfo4->usri4_comment, 1071 UserInfo->AdminComment.Buffer, 1072 UserInfo->AdminComment.Length); 1073 UserInfo4->usri4_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL; 1074 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR)); 1075 1076 UserInfo4->usri4_flags = GetAccountFlags(UserInfo->UserAccountControl, 1077 Dacl); 1078 1079 UserInfo4->usri4_script_path = Ptr; 1080 memcpy(UserInfo4->usri4_script_path, 1081 UserInfo->ScriptPath.Buffer, 1082 UserInfo->ScriptPath.Length); 1083 UserInfo4->usri4_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL; 1084 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ScriptPath.Length + sizeof(WCHAR)); 1085 1086 UserInfo4->usri4_auth_flags = AuthFlags; 1087 1088 UserInfo4->usri4_full_name = Ptr; 1089 memcpy(UserInfo4->usri4_full_name, 1090 UserInfo->FullName.Buffer, 1091 UserInfo->FullName.Length); 1092 UserInfo4->usri4_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL; 1093 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR)); 1094 1095 UserInfo4->usri4_usr_comment = Ptr; 1096 memcpy(UserInfo4->usri4_usr_comment, 1097 UserInfo->UserComment.Buffer, 1098 UserInfo->UserComment.Length); 1099 UserInfo4->usri4_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL; 1100 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR)); 1101 1102 UserInfo4->usri4_parms = Ptr; 1103 memcpy(UserInfo4->usri4_parms, 1104 UserInfo->Parameters.Buffer, 1105 UserInfo->Parameters.Length); 1106 UserInfo4->usri4_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL; 1107 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR)); 1108 1109 UserInfo4->usri4_workstations = Ptr; 1110 memcpy(UserInfo4->usri4_workstations, 1111 UserInfo->WorkStations.Buffer, 1112 UserInfo->WorkStations.Length); 1113 UserInfo4->usri4_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL; 1114 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR)); 1115 1116 if (UserInfo->LastLogon.QuadPart == 0) 1117 UserInfo4->usri4_last_logon = 0; 1118 else 1119 RtlTimeToSecondsSince1970(&UserInfo->LastLogon, 1120 &UserInfo4->usri4_last_logon); 1121 1122 if (UserInfo->LastLogoff.QuadPart == 0) 1123 UserInfo4->usri4_last_logoff = 0; 1124 else 1125 RtlTimeToSecondsSince1970(&UserInfo->LastLogoff, 1126 &UserInfo4->usri4_last_logoff); 1127 1128 if (UserInfo->AccountExpires.QuadPart == MAXLONGLONG) 1129 UserInfo4->usri4_acct_expires = TIMEQ_FOREVER; 1130 else 1131 RtlTimeToSecondsSince1970(&UserInfo->AccountExpires, 1132 &UserInfo4->usri4_acct_expires); 1133 1134 UserInfo4->usri4_max_storage = USER_MAXSTORAGE_UNLIMITED; 1135 UserInfo4->usri4_units_per_week = UserInfo->LogonHours.UnitsPerWeek; 1136 1137 if (UserInfo->LogonHours.UnitsPerWeek > 0) 1138 { 1139 UserInfo4->usri4_logon_hours = (PVOID)Ptr; 1140 1141 memcpy(UserInfo4->usri4_logon_hours, 1142 UserInfo->LogonHours.LogonHours, 1143 (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8); 1144 1145 Ptr = (LPWSTR)((ULONG_PTR)Ptr + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8); 1146 } 1147 1148 UserInfo4->usri4_bad_pw_count = UserInfo->BadPasswordCount; 1149 UserInfo4->usri4_num_logons = UserInfo->LogonCount; 1150 1151 UserInfo4->usri4_logon_server = Ptr; 1152 memcpy(UserInfo4->usri4_logon_server, 1153 LogonServer.Buffer, 1154 LogonServer.Length); 1155 UserInfo4->usri4_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL; 1156 Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR)); 1157 1158 UserInfo4->usri4_country_code = UserInfo->CountryCode; 1159 UserInfo4->usri4_code_page = UserInfo->CodePage; 1160 1161 UserInfo4->usri4_user_sid = (PVOID)Ptr; 1162 CopySidFromSidAndRid(UserInfo4->usri4_user_sid, AccountDomainSid, RelativeId); 1163 Ptr = (LPWSTR)((ULONG_PTR)Ptr + RtlLengthSid(AccountDomainSid) + sizeof(ULONG)); 1164 1165 UserInfo4->usri4_primary_group_id = UserInfo->PrimaryGroupId; 1166 1167 UserInfo4->usri4_profile = Ptr; 1168 memcpy(UserInfo4->usri4_profile, 1169 UserInfo->ProfilePath.Buffer, 1170 UserInfo->ProfilePath.Length); 1171 UserInfo4->usri4_profile[UserInfo->ProfilePath.Length / sizeof(WCHAR)] = UNICODE_NULL; 1172 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ProfilePath.Length + sizeof(WCHAR)); 1173 1174 UserInfo4->usri4_home_dir_drive = Ptr; 1175 memcpy(UserInfo4->usri4_home_dir_drive, 1176 UserInfo->HomeDirectoryDrive.Buffer, 1177 UserInfo->HomeDirectoryDrive.Length); 1178 UserInfo4->usri4_home_dir_drive[UserInfo->HomeDirectoryDrive.Length / sizeof(WCHAR)] = UNICODE_NULL; 1179 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR)); 1180 1181 UserInfo4->usri4_password_expired = (UserInfo->UserAccountControl & USER_PASSWORD_EXPIRED); 1182 break; 1183 1184 case 10: 1185 UserInfo10 = (PUSER_INFO_10)LocalBuffer; 1186 1187 Ptr = (LPWSTR)((ULONG_PTR)UserInfo10 + sizeof(USER_INFO_10)); 1188 1189 UserInfo10->usri10_name = Ptr; 1190 1191 memcpy(UserInfo10->usri10_name, 1192 UserInfo->UserName.Buffer, 1193 UserInfo->UserName.Length); 1194 UserInfo10->usri10_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL; 1195 1196 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR)); 1197 1198 UserInfo10->usri10_comment = Ptr; 1199 memcpy(UserInfo10->usri10_comment, 1200 UserInfo->AdminComment.Buffer, 1201 UserInfo->AdminComment.Length); 1202 UserInfo10->usri10_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL; 1203 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR)); 1204 1205 UserInfo10->usri10_usr_comment = Ptr; 1206 memcpy(UserInfo10->usri10_usr_comment, 1207 UserInfo->UserComment.Buffer, 1208 UserInfo->UserComment.Length); 1209 UserInfo10->usri10_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL; 1210 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR)); 1211 1212 UserInfo10->usri10_full_name = Ptr; 1213 memcpy(UserInfo10->usri10_full_name, 1214 UserInfo->FullName.Buffer, 1215 UserInfo->FullName.Length); 1216 UserInfo10->usri10_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL; 1217 break; 1218 1219 case 11: 1220 UserInfo11 = (PUSER_INFO_11)LocalBuffer; 1221 1222 Ptr = (LPWSTR)((ULONG_PTR)UserInfo11 + sizeof(USER_INFO_11)); 1223 1224 UserInfo11->usri11_name = Ptr; 1225 1226 memcpy(UserInfo11->usri11_name, 1227 UserInfo->UserName.Buffer, 1228 UserInfo->UserName.Length); 1229 UserInfo11->usri11_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL; 1230 1231 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR)); 1232 1233 UserInfo11->usri11_comment = Ptr; 1234 memcpy(UserInfo11->usri11_comment, 1235 UserInfo->AdminComment.Buffer, 1236 UserInfo->AdminComment.Length); 1237 UserInfo11->usri11_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL; 1238 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR)); 1239 1240 UserInfo11->usri11_usr_comment = Ptr; 1241 memcpy(UserInfo11->usri11_usr_comment, 1242 UserInfo->UserComment.Buffer, 1243 UserInfo->UserComment.Length); 1244 UserInfo11->usri11_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL; 1245 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR)); 1246 1247 UserInfo11->usri11_full_name = Ptr; 1248 memcpy(UserInfo11->usri11_full_name, 1249 UserInfo->FullName.Buffer, 1250 UserInfo->FullName.Length); 1251 UserInfo11->usri11_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL; 1252 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR)); 1253 1254 UserInfo11->usri11_priv = Priv; 1255 UserInfo11->usri11_auth_flags = AuthFlags; 1256 1257 UserInfo11->usri11_password_age = GetPasswordAge(&UserInfo->PasswordLastSet); 1258 1259 UserInfo11->usri11_home_dir = Ptr; 1260 memcpy(UserInfo11->usri11_home_dir, 1261 UserInfo->HomeDirectory.Buffer, 1262 UserInfo->HomeDirectory.Length); 1263 UserInfo11->usri11_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL; 1264 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR)); 1265 1266 UserInfo11->usri11_parms = Ptr; 1267 memcpy(UserInfo11->usri11_parms, 1268 UserInfo->Parameters.Buffer, 1269 UserInfo->Parameters.Length); 1270 UserInfo11->usri11_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL; 1271 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR)); 1272 1273 if (UserInfo->LastLogon.QuadPart == 0) 1274 UserInfo11->usri11_last_logon = 0; 1275 else 1276 RtlTimeToSecondsSince1970(&UserInfo->LastLogon, 1277 &UserInfo11->usri11_last_logon); 1278 1279 if (UserInfo->LastLogoff.QuadPart == 0) 1280 UserInfo11->usri11_last_logoff = 0; 1281 else 1282 RtlTimeToSecondsSince1970(&UserInfo->LastLogoff, 1283 &UserInfo11->usri11_last_logoff); 1284 1285 UserInfo11->usri11_bad_pw_count = UserInfo->BadPasswordCount; 1286 UserInfo11->usri11_num_logons = UserInfo->LogonCount; 1287 1288 UserInfo11->usri11_logon_server = Ptr; 1289 memcpy(UserInfo11->usri11_logon_server, 1290 LogonServer.Buffer, 1291 LogonServer.Length); 1292 UserInfo11->usri11_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL; 1293 Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR)); 1294 1295 UserInfo11->usri11_country_code = UserInfo->CountryCode; 1296 1297 UserInfo11->usri11_workstations = Ptr; 1298 memcpy(UserInfo11->usri11_workstations, 1299 UserInfo->WorkStations.Buffer, 1300 UserInfo->WorkStations.Length); 1301 UserInfo11->usri11_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL; 1302 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR)); 1303 1304 UserInfo11->usri11_max_storage = USER_MAXSTORAGE_UNLIMITED; 1305 UserInfo11->usri11_units_per_week = UserInfo->LogonHours.UnitsPerWeek; 1306 1307 if (UserInfo->LogonHours.UnitsPerWeek > 0) 1308 { 1309 UserInfo11->usri11_logon_hours = (PVOID)Ptr; 1310 1311 memcpy(UserInfo11->usri11_logon_hours, 1312 UserInfo->LogonHours.LogonHours, 1313 (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8); 1314 1315 Ptr = (LPWSTR)((ULONG_PTR)Ptr + (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8); 1316 } 1317 1318 UserInfo11->usri11_code_page = UserInfo->CodePage; 1319 break; 1320 1321 case 20: 1322 UserInfo20 = (PUSER_INFO_20)LocalBuffer; 1323 1324 Ptr = (LPWSTR)((ULONG_PTR)UserInfo20 + sizeof(USER_INFO_20)); 1325 1326 UserInfo20->usri20_name = Ptr; 1327 1328 memcpy(UserInfo20->usri20_name, 1329 UserInfo->UserName.Buffer, 1330 UserInfo->UserName.Length); 1331 UserInfo20->usri20_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL; 1332 1333 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR)); 1334 1335 UserInfo20->usri20_full_name = Ptr; 1336 memcpy(UserInfo20->usri20_full_name, 1337 UserInfo->FullName.Buffer, 1338 UserInfo->FullName.Length); 1339 UserInfo20->usri20_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL; 1340 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR)); 1341 1342 UserInfo20->usri20_comment = Ptr; 1343 memcpy(UserInfo20->usri20_comment, 1344 UserInfo->AdminComment.Buffer, 1345 UserInfo->AdminComment.Length); 1346 UserInfo20->usri20_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL; 1347 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR)); 1348 1349 UserInfo20->usri20_flags = GetAccountFlags(UserInfo->UserAccountControl, 1350 Dacl); 1351 1352 UserInfo20->usri20_user_id = RelativeId; 1353 break; 1354 1355 case 23: 1356 UserInfo23 = (PUSER_INFO_23)LocalBuffer; 1357 1358 Ptr = (LPWSTR)((ULONG_PTR)UserInfo23 + sizeof(USER_INFO_23)); 1359 1360 UserInfo23->usri23_name = Ptr; 1361 1362 memcpy(UserInfo23->usri23_name, 1363 UserInfo->UserName.Buffer, 1364 UserInfo->UserName.Length); 1365 UserInfo23->usri23_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL; 1366 1367 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR)); 1368 1369 UserInfo23->usri23_full_name = Ptr; 1370 memcpy(UserInfo23->usri23_full_name, 1371 UserInfo->FullName.Buffer, 1372 UserInfo->FullName.Length); 1373 UserInfo23->usri23_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL; 1374 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR)); 1375 1376 UserInfo23->usri23_comment = Ptr; 1377 memcpy(UserInfo23->usri23_comment, 1378 UserInfo->AdminComment.Buffer, 1379 UserInfo->AdminComment.Length); 1380 UserInfo23->usri23_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL; 1381 Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR)); 1382 1383 UserInfo23->usri23_flags = GetAccountFlags(UserInfo->UserAccountControl, 1384 Dacl); 1385 1386 UserInfo23->usri23_user_sid = (PVOID)Ptr; 1387 CopySidFromSidAndRid(UserInfo23->usri23_user_sid, AccountDomainSid, RelativeId); 1388 Ptr = (LPWSTR)((ULONG_PTR)Ptr + RtlLengthSid(AccountDomainSid) + sizeof(ULONG)); 1389 break; 1390 } 1391 1392 done: 1393 if (UserInfo != NULL) 1394 FreeUserInfo(UserInfo); 1395 1396 if (Dacl != NULL) 1397 HeapFree(GetProcessHeap(), 0, Dacl); 1398 1399 if (ApiStatus == NERR_Success) 1400 { 1401 *Buffer = LocalBuffer; 1402 } 1403 else 1404 { 1405 if (LocalBuffer != NULL) 1406 NetApiBufferFree(LocalBuffer); 1407 } 1408 1409 return ApiStatus; 1410 } 1411 1412 1413 static 1414 NET_API_STATUS 1415 SetUserInfo(SAM_HANDLE UserHandle, 1416 LPBYTE UserInfo, 1417 DWORD Level, 1418 PDWORD parm_err) 1419 { 1420 USER_ALL_INFORMATION UserAllInfo; 1421 PUSER_INFO_0 UserInfo0; 1422 PUSER_INFO_1 UserInfo1; 1423 PUSER_INFO_2 UserInfo2; 1424 PUSER_INFO_3 UserInfo3; 1425 PUSER_INFO_4 UserInfo4; 1426 PUSER_INFO_22 UserInfo22; 1427 PUSER_INFO_1003 UserInfo1003; 1428 PUSER_INFO_1006 UserInfo1006; 1429 PUSER_INFO_1007 UserInfo1007; 1430 PUSER_INFO_1008 UserInfo1008; 1431 PUSER_INFO_1009 UserInfo1009; 1432 PUSER_INFO_1011 UserInfo1011; 1433 PUSER_INFO_1012 UserInfo1012; 1434 PUSER_INFO_1013 UserInfo1013; 1435 PUSER_INFO_1014 UserInfo1014; 1436 PUSER_INFO_1017 UserInfo1017; 1437 PUSER_INFO_1020 UserInfo1020; 1438 PUSER_INFO_1024 UserInfo1024; 1439 PUSER_INFO_1025 UserInfo1025; 1440 PUSER_INFO_1051 UserInfo1051; 1441 PUSER_INFO_1052 UserInfo1052; 1442 PUSER_INFO_1053 UserInfo1053; 1443 PACL Dacl = NULL; 1444 NET_API_STATUS ApiStatus = NERR_Success; 1445 NTSTATUS Status = STATUS_SUCCESS; 1446 1447 ZeroMemory(&UserAllInfo, sizeof(USER_ALL_INFORMATION)); 1448 1449 if ((Level == 1) || (Level == 2) || (Level == 3) || 1450 (Level == 4) || (Level == 22) || (Level == 1008)) 1451 { 1452 ApiStatus = GetUserDacl(UserHandle, &Dacl); 1453 if (ApiStatus != NERR_Success) 1454 goto done; 1455 } 1456 1457 switch (Level) 1458 { 1459 case 0: 1460 UserInfo0 = (PUSER_INFO_0)UserInfo; 1461 1462 RtlInitUnicodeString(&UserAllInfo.UserName, 1463 UserInfo0->usri0_name); 1464 1465 UserAllInfo.WhichFields |= USER_ALL_USERNAME; 1466 break; 1467 1468 case 1: 1469 UserInfo1 = (PUSER_INFO_1)UserInfo; 1470 1471 // usri1_name ignored 1472 1473 if (UserInfo1->usri1_password != NULL) 1474 { 1475 RtlInitUnicodeString(&UserAllInfo.NtPassword, 1476 UserInfo1->usri1_password); 1477 UserAllInfo.NtPasswordPresent = TRUE; 1478 UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT; 1479 } 1480 1481 // usri1_password_age ignored 1482 1483 // UserInfo1->usri1_priv 1484 1485 if (UserInfo1->usri1_home_dir != NULL) 1486 { 1487 RtlInitUnicodeString(&UserAllInfo.HomeDirectory, 1488 UserInfo1->usri1_home_dir); 1489 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY; 1490 } 1491 1492 if (UserInfo1->usri1_comment != NULL) 1493 { 1494 RtlInitUnicodeString(&UserAllInfo.AdminComment, 1495 UserInfo1->usri1_comment); 1496 UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT; 1497 } 1498 1499 ChangeUserDacl(Dacl, UserInfo1->usri1_flags); 1500 UserAllInfo.UserAccountControl = GetAccountControl(UserInfo1->usri1_flags); 1501 UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL; 1502 1503 if (UserInfo1->usri1_script_path != NULL) 1504 { 1505 RtlInitUnicodeString(&UserAllInfo.ScriptPath, 1506 UserInfo1->usri1_script_path); 1507 UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH; 1508 } 1509 break; 1510 1511 case 2: 1512 UserInfo2 = (PUSER_INFO_2)UserInfo; 1513 1514 // usri2_name ignored 1515 1516 if (UserInfo2->usri2_password != NULL) 1517 { 1518 RtlInitUnicodeString(&UserAllInfo.NtPassword, 1519 UserInfo2->usri2_password); 1520 UserAllInfo.NtPasswordPresent = TRUE; 1521 UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT; 1522 } 1523 1524 // usri2_password_age ignored 1525 1526 // UserInfo2->usri2_priv; 1527 1528 if (UserInfo2->usri2_home_dir != NULL) 1529 { 1530 RtlInitUnicodeString(&UserAllInfo.HomeDirectory, 1531 UserInfo2->usri2_home_dir); 1532 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY; 1533 } 1534 1535 if (UserInfo2->usri2_comment != NULL) 1536 { 1537 RtlInitUnicodeString(&UserAllInfo.AdminComment, 1538 UserInfo2->usri2_comment); 1539 UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT; 1540 } 1541 1542 ChangeUserDacl(Dacl, UserInfo2->usri2_flags); 1543 UserAllInfo.UserAccountControl = GetAccountControl(UserInfo2->usri2_flags); 1544 UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL; 1545 1546 if (UserInfo2->usri2_script_path != NULL) 1547 { 1548 RtlInitUnicodeString(&UserAllInfo.ScriptPath, 1549 UserInfo2->usri2_script_path); 1550 UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH; 1551 } 1552 1553 // UserInfo2->usri2_auth_flags; 1554 1555 if (UserInfo2->usri2_full_name != NULL) 1556 { 1557 RtlInitUnicodeString(&UserAllInfo.FullName, 1558 UserInfo2->usri2_full_name); 1559 UserAllInfo.WhichFields |= USER_ALL_FULLNAME; 1560 } 1561 1562 if (UserInfo2->usri2_usr_comment != NULL) 1563 { 1564 RtlInitUnicodeString(&UserAllInfo.UserComment, 1565 UserInfo2->usri2_usr_comment); 1566 UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT; 1567 } 1568 1569 if (UserInfo2->usri2_parms != NULL) 1570 { 1571 RtlInitUnicodeString(&UserAllInfo.Parameters, 1572 UserInfo2->usri2_parms); 1573 UserAllInfo.WhichFields |= USER_ALL_PARAMETERS; 1574 } 1575 1576 if (UserInfo2->usri2_workstations != NULL) 1577 { 1578 RtlInitUnicodeString(&UserAllInfo.WorkStations, 1579 UserInfo2->usri2_workstations); 1580 UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS; 1581 } 1582 1583 // usri2_last_logon ignored 1584 // usri2_last_logoff ignored 1585 1586 if (UserInfo2->usri2_acct_expires == TIMEQ_FOREVER) 1587 { 1588 UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG; 1589 } 1590 else 1591 { 1592 RtlSecondsSince1970ToTime(UserInfo2->usri2_acct_expires, 1593 &UserAllInfo.AccountExpires); 1594 } 1595 UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES; 1596 1597 // usri2_max_storage ignored 1598 1599 if (UserInfo2->usri2_logon_hours != NULL) 1600 { 1601 if (UserInfo2->usri2_units_per_week > USHRT_MAX) 1602 { 1603 if (parm_err != NULL) 1604 *parm_err = USER_UNITS_PER_WEEK_PARMNUM; 1605 ApiStatus = ERROR_INVALID_PARAMETER; 1606 break; 1607 } 1608 1609 UserAllInfo.LogonHours.UnitsPerWeek = UserInfo2->usri2_units_per_week; 1610 UserAllInfo.LogonHours.LogonHours = UserInfo2->usri2_logon_hours; 1611 UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS; 1612 } 1613 1614 // usri2_bad_pw_count ignored 1615 // usri2_num_logons ignored 1616 // usri2_logon_server ignored 1617 1618 UserAllInfo.CountryCode = UserInfo2->usri2_country_code; 1619 UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE; 1620 1621 UserAllInfo.CodePage = UserInfo2->usri2_code_page; 1622 UserAllInfo.WhichFields |= USER_ALL_CODEPAGE; 1623 break; 1624 1625 case 3: 1626 UserInfo3 = (PUSER_INFO_3)UserInfo; 1627 1628 // usri3_name ignored 1629 1630 if (UserInfo3->usri3_password != NULL) 1631 { 1632 RtlInitUnicodeString(&UserAllInfo.NtPassword, 1633 UserInfo3->usri3_password); 1634 UserAllInfo.NtPasswordPresent = TRUE; 1635 UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT; 1636 } 1637 1638 // usri3_password_age ignored 1639 1640 // UserInfo3->usri3_priv; 1641 1642 if (UserInfo3->usri3_home_dir != NULL) 1643 { 1644 RtlInitUnicodeString(&UserAllInfo.HomeDirectory, 1645 UserInfo3->usri3_home_dir); 1646 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY; 1647 } 1648 1649 if (UserInfo3->usri3_comment != NULL) 1650 { 1651 RtlInitUnicodeString(&UserAllInfo.AdminComment, 1652 UserInfo3->usri3_comment); 1653 UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT; 1654 } 1655 1656 ChangeUserDacl(Dacl, UserInfo3->usri3_flags); 1657 UserAllInfo.UserAccountControl = GetAccountControl(UserInfo3->usri3_flags); 1658 UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL; 1659 1660 if (UserInfo3->usri3_script_path != NULL) 1661 { 1662 RtlInitUnicodeString(&UserAllInfo.ScriptPath, 1663 UserInfo3->usri3_script_path); 1664 UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH; 1665 } 1666 1667 // UserInfo3->usri3_auth_flags; 1668 1669 if (UserInfo3->usri3_full_name != NULL) 1670 { 1671 RtlInitUnicodeString(&UserAllInfo.FullName, 1672 UserInfo3->usri3_full_name); 1673 UserAllInfo.WhichFields |= USER_ALL_FULLNAME; 1674 } 1675 1676 if (UserInfo3->usri3_usr_comment != NULL) 1677 { 1678 RtlInitUnicodeString(&UserAllInfo.UserComment, 1679 UserInfo3->usri3_usr_comment); 1680 UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT; 1681 } 1682 1683 if (UserInfo3->usri3_parms != NULL) 1684 { 1685 RtlInitUnicodeString(&UserAllInfo.Parameters, 1686 UserInfo3->usri3_parms); 1687 UserAllInfo.WhichFields |= USER_ALL_PARAMETERS; 1688 } 1689 1690 if (UserInfo3->usri3_workstations != NULL) 1691 { 1692 RtlInitUnicodeString(&UserAllInfo.WorkStations, 1693 UserInfo3->usri3_workstations); 1694 UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS; 1695 } 1696 1697 // usri3_last_logon ignored 1698 // usri3_last_logoff ignored 1699 1700 if (UserInfo3->usri3_acct_expires == TIMEQ_FOREVER) 1701 { 1702 UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG; 1703 } 1704 else 1705 { 1706 RtlSecondsSince1970ToTime(UserInfo3->usri3_acct_expires, 1707 &UserAllInfo.AccountExpires); 1708 } 1709 UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES; 1710 1711 // usri3_max_storage ignored 1712 1713 if (UserInfo3->usri3_logon_hours != NULL) 1714 { 1715 if (UserInfo3->usri3_units_per_week > USHRT_MAX) 1716 { 1717 if (parm_err != NULL) 1718 *parm_err = USER_UNITS_PER_WEEK_PARMNUM; 1719 ApiStatus = ERROR_INVALID_PARAMETER; 1720 break; 1721 } 1722 1723 UserAllInfo.LogonHours.UnitsPerWeek = UserInfo3->usri3_units_per_week; 1724 UserAllInfo.LogonHours.LogonHours = UserInfo3->usri3_logon_hours; 1725 UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS; 1726 } 1727 1728 // usri3_bad_pw_count ignored 1729 // usri3_num_logons ignored 1730 // usri3_logon_server ignored 1731 1732 UserAllInfo.CountryCode = UserInfo3->usri3_country_code; 1733 UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE; 1734 1735 UserAllInfo.CodePage = UserInfo3->usri3_code_page; 1736 UserAllInfo.WhichFields |= USER_ALL_CODEPAGE; 1737 1738 // usri3_user_id ignored 1739 1740 UserAllInfo.PrimaryGroupId = UserInfo3->usri3_primary_group_id; 1741 UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID; 1742 1743 if (UserInfo3->usri3_profile != NULL) 1744 { 1745 RtlInitUnicodeString(&UserAllInfo.ProfilePath, 1746 UserInfo3->usri3_profile); 1747 UserAllInfo.WhichFields |= USER_ALL_PROFILEPATH; 1748 } 1749 1750 if (UserInfo3->usri3_home_dir_drive != NULL) 1751 { 1752 RtlInitUnicodeString(&UserAllInfo.HomeDirectoryDrive, 1753 UserInfo3->usri3_home_dir_drive); 1754 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORYDRIVE; 1755 } 1756 1757 UserAllInfo.PasswordExpired = (UserInfo3->usri3_password_expired != 0); 1758 UserAllInfo.WhichFields |= USER_ALL_PASSWORDEXPIRED; 1759 break; 1760 1761 case 4: 1762 UserInfo4 = (PUSER_INFO_4)UserInfo; 1763 1764 // usri4_name ignored 1765 1766 if (UserInfo4->usri4_password != NULL) 1767 { 1768 RtlInitUnicodeString(&UserAllInfo.NtPassword, 1769 UserInfo4->usri4_password); 1770 UserAllInfo.NtPasswordPresent = TRUE; 1771 UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT; 1772 } 1773 1774 // usri4_password_age ignored 1775 1776 // UserInfo3->usri4_priv; 1777 1778 if (UserInfo4->usri4_home_dir != NULL) 1779 { 1780 RtlInitUnicodeString(&UserAllInfo.HomeDirectory, 1781 UserInfo4->usri4_home_dir); 1782 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY; 1783 } 1784 1785 if (UserInfo4->usri4_comment != NULL) 1786 { 1787 RtlInitUnicodeString(&UserAllInfo.AdminComment, 1788 UserInfo4->usri4_comment); 1789 UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT; 1790 } 1791 1792 ChangeUserDacl(Dacl, UserInfo4->usri4_flags); 1793 UserAllInfo.UserAccountControl = GetAccountControl(UserInfo4->usri4_flags); 1794 UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL; 1795 1796 if (UserInfo4->usri4_script_path != NULL) 1797 { 1798 RtlInitUnicodeString(&UserAllInfo.ScriptPath, 1799 UserInfo4->usri4_script_path); 1800 UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH; 1801 } 1802 1803 // UserInfo4->usri4_auth_flags; 1804 1805 if (UserInfo4->usri4_full_name != NULL) 1806 { 1807 RtlInitUnicodeString(&UserAllInfo.FullName, 1808 UserInfo4->usri4_full_name); 1809 UserAllInfo.WhichFields |= USER_ALL_FULLNAME; 1810 } 1811 1812 if (UserInfo4->usri4_usr_comment != NULL) 1813 { 1814 RtlInitUnicodeString(&UserAllInfo.UserComment, 1815 UserInfo4->usri4_usr_comment); 1816 UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT; 1817 } 1818 1819 if (UserInfo4->usri4_parms != NULL) 1820 { 1821 RtlInitUnicodeString(&UserAllInfo.Parameters, 1822 UserInfo4->usri4_parms); 1823 UserAllInfo.WhichFields |= USER_ALL_PARAMETERS; 1824 } 1825 1826 if (UserInfo4->usri4_workstations != NULL) 1827 { 1828 RtlInitUnicodeString(&UserAllInfo.WorkStations, 1829 UserInfo4->usri4_workstations); 1830 UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS; 1831 } 1832 1833 // usri4_last_logon ignored 1834 // usri4_last_logoff ignored 1835 1836 if (UserInfo4->usri4_acct_expires == TIMEQ_FOREVER) 1837 { 1838 UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG; 1839 } 1840 else 1841 { 1842 RtlSecondsSince1970ToTime(UserInfo4->usri4_acct_expires, 1843 &UserAllInfo.AccountExpires); 1844 } 1845 UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES; 1846 1847 // usri4_max_storage ignored 1848 1849 if (UserInfo4->usri4_logon_hours != NULL) 1850 { 1851 if (UserInfo4->usri4_units_per_week > USHRT_MAX) 1852 { 1853 if (parm_err != NULL) 1854 *parm_err = USER_UNITS_PER_WEEK_PARMNUM; 1855 ApiStatus = ERROR_INVALID_PARAMETER; 1856 break; 1857 } 1858 1859 UserAllInfo.LogonHours.UnitsPerWeek = UserInfo4->usri4_units_per_week; 1860 UserAllInfo.LogonHours.LogonHours = UserInfo4->usri4_logon_hours; 1861 UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS; 1862 } 1863 1864 // usri4_bad_pw_count ignored 1865 // usri4_num_logons ignored 1866 // usri4_logon_server ignored 1867 1868 UserAllInfo.CountryCode = UserInfo4->usri4_country_code; 1869 UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE; 1870 1871 UserAllInfo.CodePage = UserInfo4->usri4_code_page; 1872 UserAllInfo.WhichFields |= USER_ALL_CODEPAGE; 1873 1874 // usri4_user_sid ignored 1875 1876 UserAllInfo.PrimaryGroupId = UserInfo4->usri4_primary_group_id; 1877 UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID; 1878 1879 if (UserInfo4->usri4_profile != NULL) 1880 { 1881 RtlInitUnicodeString(&UserAllInfo.ProfilePath, 1882 UserInfo4->usri4_profile); 1883 UserAllInfo.WhichFields |= USER_ALL_PROFILEPATH; 1884 } 1885 1886 if (UserInfo4->usri4_home_dir_drive != NULL) 1887 { 1888 RtlInitUnicodeString(&UserAllInfo.HomeDirectoryDrive, 1889 UserInfo4->usri4_home_dir_drive); 1890 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORYDRIVE; 1891 } 1892 1893 UserAllInfo.PasswordExpired = (UserInfo4->usri4_password_expired != 0); 1894 UserAllInfo.WhichFields |= USER_ALL_PASSWORDEXPIRED; 1895 break; 1896 1897 // case 21: 1898 // break; 1899 1900 case 22: 1901 UserInfo22 = (PUSER_INFO_22)UserInfo; 1902 1903 // usri22_name ignored 1904 1905 // UserInfo22->usri22_password[ENCRYPTED_PWLEN]; 1906 1907 // usri22_password_age ignored 1908 1909 // UserInfo3->usri3_priv; 1910 1911 if (UserInfo22->usri22_home_dir != NULL) 1912 { 1913 RtlInitUnicodeString(&UserAllInfo.HomeDirectory, 1914 UserInfo22->usri22_home_dir); 1915 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY; 1916 } 1917 1918 if (UserInfo22->usri22_comment != NULL) 1919 { 1920 RtlInitUnicodeString(&UserAllInfo.AdminComment, 1921 UserInfo22->usri22_comment); 1922 UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT; 1923 } 1924 1925 ChangeUserDacl(Dacl, UserInfo22->usri22_flags); 1926 UserAllInfo.UserAccountControl = GetAccountControl(UserInfo22->usri22_flags); 1927 UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL; 1928 1929 if (UserInfo22->usri22_script_path != NULL) 1930 { 1931 RtlInitUnicodeString(&UserAllInfo.ScriptPath, 1932 UserInfo22->usri22_script_path); 1933 UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH; 1934 } 1935 1936 // UserInfo22->usri22_auth_flags; 1937 1938 if (UserInfo22->usri22_full_name != NULL) 1939 { 1940 RtlInitUnicodeString(&UserAllInfo.FullName, 1941 UserInfo22->usri22_full_name); 1942 UserAllInfo.WhichFields |= USER_ALL_FULLNAME; 1943 } 1944 1945 if (UserInfo22->usri22_usr_comment != NULL) 1946 { 1947 RtlInitUnicodeString(&UserAllInfo.UserComment, 1948 UserInfo22->usri22_usr_comment); 1949 UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT; 1950 } 1951 1952 if (UserInfo22->usri22_parms != NULL) 1953 { 1954 RtlInitUnicodeString(&UserAllInfo.Parameters, 1955 UserInfo22->usri22_parms); 1956 UserAllInfo.WhichFields |= USER_ALL_PARAMETERS; 1957 } 1958 1959 if (UserInfo22->usri22_workstations != NULL) 1960 { 1961 RtlInitUnicodeString(&UserAllInfo.WorkStations, 1962 UserInfo22->usri22_workstations); 1963 UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS; 1964 } 1965 1966 // usri22_last_logon ignored 1967 // usri22_last_logoff ignored 1968 1969 if (UserInfo22->usri22_acct_expires == TIMEQ_FOREVER) 1970 { 1971 UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG; 1972 } 1973 else 1974 { 1975 RtlSecondsSince1970ToTime(UserInfo22->usri22_acct_expires, 1976 &UserAllInfo.AccountExpires); 1977 } 1978 UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES; 1979 1980 // usri22_max_storage ignored 1981 1982 if (UserInfo22->usri22_logon_hours != NULL) 1983 { 1984 if (UserInfo22->usri22_units_per_week > USHRT_MAX) 1985 { 1986 if (parm_err != NULL) 1987 *parm_err = USER_UNITS_PER_WEEK_PARMNUM; 1988 ApiStatus = ERROR_INVALID_PARAMETER; 1989 break; 1990 } 1991 1992 UserAllInfo.LogonHours.UnitsPerWeek = UserInfo22->usri22_units_per_week; 1993 UserAllInfo.LogonHours.LogonHours = UserInfo22->usri22_logon_hours; 1994 UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS; 1995 } 1996 1997 // usri22_bad_pw_count ignored 1998 // usri22_num_logons ignored 1999 // usri22_logon_server ignored 2000 2001 UserAllInfo.CountryCode = UserInfo22->usri22_country_code; 2002 UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE; 2003 2004 UserAllInfo.CodePage = UserInfo22->usri22_code_page; 2005 UserAllInfo.WhichFields |= USER_ALL_CODEPAGE; 2006 break; 2007 2008 case 1003: 2009 UserInfo1003 = (PUSER_INFO_1003)UserInfo; 2010 2011 if (UserInfo1003->usri1003_password != NULL) 2012 { 2013 RtlInitUnicodeString(&UserAllInfo.NtPassword, 2014 UserInfo1003->usri1003_password); 2015 UserAllInfo.NtPasswordPresent = TRUE; 2016 UserAllInfo.WhichFields |= USER_ALL_NTPASSWORDPRESENT; 2017 } 2018 break; 2019 2020 // case 1005: 2021 // break; 2022 2023 case 1006: 2024 UserInfo1006 = (PUSER_INFO_1006)UserInfo; 2025 2026 if (UserInfo1006->usri1006_home_dir != NULL) 2027 { 2028 RtlInitUnicodeString(&UserAllInfo.HomeDirectory, 2029 UserInfo1006->usri1006_home_dir); 2030 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY; 2031 } 2032 break; 2033 2034 case 1007: 2035 UserInfo1007 = (PUSER_INFO_1007)UserInfo; 2036 2037 if (UserInfo1007->usri1007_comment != NULL) 2038 { 2039 RtlInitUnicodeString(&UserAllInfo.AdminComment, 2040 UserInfo1007->usri1007_comment); 2041 UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT; 2042 } 2043 break; 2044 2045 case 1008: 2046 UserInfo1008 = (PUSER_INFO_1008)UserInfo; 2047 ChangeUserDacl(Dacl, UserInfo1008->usri1008_flags); 2048 UserAllInfo.UserAccountControl = GetAccountControl(UserInfo1008->usri1008_flags); 2049 UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL; 2050 break; 2051 2052 case 1009: 2053 UserInfo1009 = (PUSER_INFO_1009)UserInfo; 2054 2055 if (UserInfo1009->usri1009_script_path != NULL) 2056 { 2057 RtlInitUnicodeString(&UserAllInfo.ScriptPath, 2058 UserInfo1009->usri1009_script_path); 2059 UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH; 2060 } 2061 break; 2062 2063 // case 1010: 2064 // break; 2065 2066 case 1011: 2067 UserInfo1011 = (PUSER_INFO_1011)UserInfo; 2068 2069 if (UserInfo1011->usri1011_full_name != NULL) 2070 { 2071 RtlInitUnicodeString(&UserAllInfo.FullName, 2072 UserInfo1011->usri1011_full_name); 2073 UserAllInfo.WhichFields |= USER_ALL_FULLNAME; 2074 } 2075 break; 2076 2077 case 1012: 2078 UserInfo1012 = (PUSER_INFO_1012)UserInfo; 2079 2080 if (UserInfo1012->usri1012_usr_comment != NULL) 2081 { 2082 RtlInitUnicodeString(&UserAllInfo.UserComment, 2083 UserInfo1012->usri1012_usr_comment); 2084 UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT; 2085 } 2086 break; 2087 2088 case 1013: 2089 UserInfo1013 = (PUSER_INFO_1013)UserInfo; 2090 2091 if (UserInfo1013->usri1013_parms != NULL) 2092 { 2093 RtlInitUnicodeString(&UserAllInfo.Parameters, 2094 UserInfo1013->usri1013_parms); 2095 UserAllInfo.WhichFields |= USER_ALL_PARAMETERS; 2096 } 2097 break; 2098 2099 case 1014: 2100 UserInfo1014 = (PUSER_INFO_1014)UserInfo; 2101 2102 if (UserInfo1014->usri1014_workstations != NULL) 2103 { 2104 RtlInitUnicodeString(&UserAllInfo.WorkStations, 2105 UserInfo1014->usri1014_workstations); 2106 UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS; 2107 } 2108 break; 2109 2110 case 1017: 2111 UserInfo1017 = (PUSER_INFO_1017)UserInfo; 2112 2113 if (UserInfo1017->usri1017_acct_expires == TIMEQ_FOREVER) 2114 { 2115 UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG; 2116 } 2117 else 2118 { 2119 RtlSecondsSince1970ToTime(UserInfo1017->usri1017_acct_expires, 2120 &UserAllInfo.AccountExpires); 2121 } 2122 UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES; 2123 break; 2124 2125 case 1018: 2126 // usri1018_max_storage ignored 2127 break; 2128 2129 case 1020: 2130 UserInfo1020 = (PUSER_INFO_1020)UserInfo; 2131 2132 if (UserInfo1020->usri1020_logon_hours != NULL) 2133 { 2134 if (UserInfo1020->usri1020_units_per_week > USHRT_MAX) 2135 { 2136 if (parm_err != NULL) 2137 *parm_err = USER_UNITS_PER_WEEK_PARMNUM; 2138 ApiStatus = ERROR_INVALID_PARAMETER; 2139 break; 2140 } 2141 2142 UserAllInfo.LogonHours.UnitsPerWeek = UserInfo1020->usri1020_units_per_week; 2143 UserAllInfo.LogonHours.LogonHours = UserInfo1020->usri1020_logon_hours; 2144 UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS; 2145 } 2146 break; 2147 2148 case 1024: 2149 UserInfo1024 = (PUSER_INFO_1024)UserInfo; 2150 2151 UserAllInfo.CountryCode = UserInfo1024->usri1024_country_code; 2152 UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE; 2153 break; 2154 2155 case 1025: 2156 UserInfo1025 = (PUSER_INFO_1025)UserInfo; 2157 2158 UserAllInfo.CodePage = UserInfo1025->usri1025_code_page; 2159 UserAllInfo.WhichFields |= USER_ALL_CODEPAGE; 2160 break; 2161 2162 case 1051: 2163 UserInfo1051 = (PUSER_INFO_1051)UserInfo; 2164 2165 UserAllInfo.PrimaryGroupId = UserInfo1051->usri1051_primary_group_id; 2166 UserAllInfo.WhichFields |= USER_ALL_PRIMARYGROUPID; 2167 break; 2168 2169 case 1052: 2170 UserInfo1052 = (PUSER_INFO_1052)UserInfo; 2171 2172 if (UserInfo1052->usri1052_profile != NULL) 2173 { 2174 RtlInitUnicodeString(&UserAllInfo.ProfilePath, 2175 UserInfo1052->usri1052_profile); 2176 UserAllInfo.WhichFields |= USER_ALL_PROFILEPATH; 2177 } 2178 break; 2179 2180 case 1053: 2181 UserInfo1053 = (PUSER_INFO_1053)UserInfo; 2182 2183 if (UserInfo1053->usri1053_home_dir_drive != NULL) 2184 { 2185 RtlInitUnicodeString(&UserAllInfo.HomeDirectoryDrive, 2186 UserInfo1053->usri1053_home_dir_drive); 2187 UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORYDRIVE; 2188 } 2189 break; 2190 } 2191 2192 if (ApiStatus != NERR_Success) 2193 goto done; 2194 2195 Status = SamSetInformationUser(UserHandle, 2196 UserAllInformation, 2197 &UserAllInfo); 2198 if (!NT_SUCCESS(Status)) 2199 { 2200 ERR("SamSetInformationUser failed (Status %08lx)\n", Status); 2201 ApiStatus = NetpNtStatusToApiStatus(Status); 2202 goto done; 2203 } 2204 2205 done: 2206 if (Dacl != NULL) 2207 HeapFree(GetProcessHeap(), 0, Dacl); 2208 2209 return ApiStatus; 2210 } 2211 2212 2213 static 2214 NET_API_STATUS 2215 OpenUserByName(SAM_HANDLE DomainHandle, 2216 PUNICODE_STRING UserName, 2217 ULONG DesiredAccess, 2218 PSAM_HANDLE UserHandle) 2219 { 2220 PULONG RelativeIds = NULL; 2221 PSID_NAME_USE Use = NULL; 2222 NET_API_STATUS ApiStatus = NERR_Success; 2223 NTSTATUS Status = STATUS_SUCCESS; 2224 2225 /* Get the RID for the given user name */ 2226 Status = SamLookupNamesInDomain(DomainHandle, 2227 1, 2228 UserName, 2229 &RelativeIds, 2230 &Use); 2231 if (!NT_SUCCESS(Status)) 2232 { 2233 ERR("SamLookupNamesInDomain(%wZ) failed (Status %08lx)\n", UserName, Status); 2234 return NetpNtStatusToApiStatus(Status); 2235 } 2236 2237 /* Fail, if it is not an alias account */ 2238 if (Use[0] != SidTypeUser) 2239 { 2240 ERR("Object is not a user!\n"); 2241 ApiStatus = NERR_GroupNotFound; 2242 goto done; 2243 } 2244 2245 /* Open the alias account */ 2246 Status = SamOpenUser(DomainHandle, 2247 DesiredAccess, 2248 RelativeIds[0], 2249 UserHandle); 2250 if (!NT_SUCCESS(Status)) 2251 { 2252 ERR("SamOpenUser failed (Status %08lx)\n", Status); 2253 ApiStatus = NetpNtStatusToApiStatus(Status); 2254 goto done; 2255 } 2256 2257 done: 2258 if (RelativeIds != NULL) 2259 SamFreeMemory(RelativeIds); 2260 2261 if (Use != NULL) 2262 SamFreeMemory(Use); 2263 2264 return ApiStatus; 2265 } 2266 2267 2268 /************************************************************ 2269 * NetUserAdd (NETAPI32.@) 2270 */ 2271 NET_API_STATUS 2272 WINAPI 2273 NetUserAdd(LPCWSTR servername, 2274 DWORD level, 2275 LPBYTE bufptr, 2276 LPDWORD parm_err) 2277 { 2278 UNICODE_STRING ServerName; 2279 UNICODE_STRING UserName; 2280 SAM_HANDLE ServerHandle = NULL; 2281 SAM_HANDLE DomainHandle = NULL; 2282 SAM_HANDLE UserHandle = NULL; 2283 ULONG GrantedAccess; 2284 ULONG RelativeId; 2285 NET_API_STATUS ApiStatus = NERR_Success; 2286 NTSTATUS Status = STATUS_SUCCESS; 2287 2288 TRACE("(%s, %d, %p, %p)\n", debugstr_w(servername), level, bufptr, parm_err); 2289 2290 if (parm_err != NULL) 2291 *parm_err = PARM_ERROR_NONE; 2292 2293 /* Check the info level */ 2294 switch (level) 2295 { 2296 case 1: 2297 case 2: 2298 case 3: 2299 case 4: 2300 break; 2301 2302 default: 2303 return ERROR_INVALID_LEVEL; 2304 } 2305 2306 if (servername != NULL) 2307 RtlInitUnicodeString(&ServerName, servername); 2308 2309 /* Connect to the SAM Server */ 2310 Status = SamConnect((servername != NULL) ? &ServerName : NULL, 2311 &ServerHandle, 2312 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, 2313 NULL); 2314 if (!NT_SUCCESS(Status)) 2315 { 2316 ERR("SamConnect failed (Status %08lx)\n", Status); 2317 ApiStatus = NetpNtStatusToApiStatus(Status); 2318 goto done; 2319 } 2320 2321 /* Open the Account Domain */ 2322 Status = OpenAccountDomain(ServerHandle, 2323 (servername != NULL) ? &ServerName : NULL, 2324 DOMAIN_CREATE_USER | DOMAIN_LOOKUP | DOMAIN_READ_PASSWORD_PARAMETERS, 2325 &DomainHandle); 2326 if (!NT_SUCCESS(Status)) 2327 { 2328 ERR("OpenAccountDomain failed (Status %08lx)\n", Status); 2329 ApiStatus = NetpNtStatusToApiStatus(Status); 2330 goto done; 2331 } 2332 2333 /* Initialize the user name string */ 2334 RtlInitUnicodeString(&UserName, 2335 ((PUSER_INFO_1)bufptr)->usri1_name); 2336 2337 /* Create the user account */ 2338 Status = SamCreateUser2InDomain(DomainHandle, 2339 &UserName, 2340 USER_NORMAL_ACCOUNT, 2341 USER_ALL_ACCESS | DELETE | WRITE_DAC, 2342 &UserHandle, 2343 &GrantedAccess, 2344 &RelativeId); 2345 if (!NT_SUCCESS(Status)) 2346 { 2347 ERR("SamCreateUser2InDomain failed (Status %08lx)\n", Status); 2348 ApiStatus = NetpNtStatusToApiStatus(Status); 2349 goto done; 2350 } 2351 2352 /* Set user information */ 2353 ApiStatus = SetUserInfo(UserHandle, 2354 bufptr, 2355 level, 2356 parm_err); 2357 if (ApiStatus != NERR_Success) 2358 { 2359 ERR("SetUserInfo failed (Status %lu)\n", ApiStatus); 2360 goto done; 2361 } 2362 2363 done: 2364 if (UserHandle != NULL) 2365 { 2366 if (ApiStatus != NERR_Success) 2367 SamDeleteUser(UserHandle); 2368 else 2369 SamCloseHandle(UserHandle); 2370 } 2371 2372 if (DomainHandle != NULL) 2373 SamCloseHandle(DomainHandle); 2374 2375 if (ServerHandle != NULL) 2376 SamCloseHandle(ServerHandle); 2377 2378 return ApiStatus; 2379 } 2380 2381 2382 /****************************************************************************** 2383 * NetUserChangePassword (NETAPI32.@) 2384 * PARAMS 2385 * domainname [I] Optional. Domain on which the user resides or the logon 2386 * domain of the current user if NULL. 2387 * username [I] Optional. Username to change the password for or the name 2388 * of the current user if NULL. 2389 * oldpassword [I] The user's current password. 2390 * newpassword [I] The password that the user will be changed to using. 2391 * 2392 * RETURNS 2393 * Success: NERR_Success. 2394 * Failure: NERR_* failure code or win error code. 2395 * 2396 */ 2397 NET_API_STATUS 2398 WINAPI 2399 NetUserChangePassword(LPCWSTR domainname, 2400 LPCWSTR username, 2401 LPCWSTR oldpassword, 2402 LPCWSTR newpassword) 2403 { 2404 PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer = NULL; 2405 PMSV1_0_CHANGEPASSWORD_RESPONSE ResponseBuffer = NULL; 2406 ULONG RequestBufferSize; 2407 ULONG ResponseBufferSize = 0; 2408 LPWSTR Ptr; 2409 ANSI_STRING PackageName; 2410 ULONG AuthenticationPackage = 0; 2411 HANDLE LsaHandle = NULL; 2412 NET_API_STATUS ApiStatus = NERR_Success; 2413 NTSTATUS Status = STATUS_SUCCESS; 2414 NTSTATUS ProtocolStatus; 2415 2416 TRACE("(%s, %s, ..., ...)\n", debugstr_w(domainname), debugstr_w(username)); 2417 2418 /* FIXME: handle null domain or user name */ 2419 2420 /* Check the parameters */ 2421 if ((oldpassword == NULL) || 2422 (newpassword == NULL)) 2423 return ERROR_INVALID_PARAMETER; 2424 2425 /* Connect to the LSA server */ 2426 Status = LsaConnectUntrusted(&LsaHandle); 2427 if (!NT_SUCCESS(Status)) 2428 return NetpNtStatusToApiStatus(Status); 2429 2430 /* Get the authentication package ID */ 2431 RtlInitAnsiString(&PackageName, 2432 MSV1_0_PACKAGE_NAME); 2433 2434 Status = LsaLookupAuthenticationPackage(LsaHandle, 2435 &PackageName, 2436 &AuthenticationPackage); 2437 if (!NT_SUCCESS(Status)) 2438 { 2439 ApiStatus = NetpNtStatusToApiStatus(Status); 2440 goto done; 2441 } 2442 2443 /* Calculate the request buffer size */ 2444 RequestBufferSize = sizeof(MSV1_0_CHANGEPASSWORD_REQUEST) + 2445 ((wcslen(domainname) + 1) * sizeof(WCHAR)) + 2446 ((wcslen(username) + 1) * sizeof(WCHAR)) + 2447 ((wcslen(oldpassword) + 1) * sizeof(WCHAR)) + 2448 ((wcslen(newpassword) + 1) * sizeof(WCHAR)); 2449 2450 /* Allocate the request buffer */ 2451 ApiStatus = NetApiBufferAllocate(RequestBufferSize, 2452 (PVOID*)&RequestBuffer); 2453 if (ApiStatus != NERR_Success) 2454 goto done; 2455 2456 /* Initialize the request buffer */ 2457 RequestBuffer->MessageType = MsV1_0ChangePassword; 2458 RequestBuffer->Impersonating = TRUE; 2459 2460 Ptr = (LPWSTR)((ULONG_PTR)RequestBuffer + sizeof(MSV1_0_CHANGEPASSWORD_REQUEST)); 2461 2462 /* Pack the domain name */ 2463 RequestBuffer->DomainName.Length = wcslen(domainname) * sizeof(WCHAR); 2464 RequestBuffer->DomainName.MaximumLength = RequestBuffer->DomainName.Length + sizeof(WCHAR); 2465 RequestBuffer->DomainName.Buffer = Ptr; 2466 2467 RtlCopyMemory(RequestBuffer->DomainName.Buffer, 2468 domainname, 2469 RequestBuffer->DomainName.MaximumLength); 2470 2471 Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->DomainName.MaximumLength); 2472 2473 /* Pack the user name */ 2474 RequestBuffer->AccountName.Length = wcslen(username) * sizeof(WCHAR); 2475 RequestBuffer->AccountName.MaximumLength = RequestBuffer->AccountName.Length + sizeof(WCHAR); 2476 RequestBuffer->AccountName.Buffer = Ptr; 2477 2478 RtlCopyMemory(RequestBuffer->AccountName.Buffer, 2479 username, 2480 RequestBuffer->AccountName.MaximumLength); 2481 2482 Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->AccountName.MaximumLength); 2483 2484 /* Pack the old password */ 2485 RequestBuffer->OldPassword.Length = wcslen(oldpassword) * sizeof(WCHAR); 2486 RequestBuffer->OldPassword.MaximumLength = RequestBuffer->OldPassword.Length + sizeof(WCHAR); 2487 RequestBuffer->OldPassword.Buffer = Ptr; 2488 2489 RtlCopyMemory(RequestBuffer->OldPassword.Buffer, 2490 oldpassword, 2491 RequestBuffer->OldPassword.MaximumLength); 2492 2493 Ptr = (LPWSTR)((ULONG_PTR)Ptr + RequestBuffer->OldPassword.MaximumLength); 2494 2495 /* Pack the new password */ 2496 RequestBuffer->NewPassword.Length = wcslen(newpassword) * sizeof(WCHAR); 2497 RequestBuffer->NewPassword.MaximumLength = RequestBuffer->NewPassword.Length + sizeof(WCHAR); 2498 RequestBuffer->NewPassword.Buffer = Ptr; 2499 2500 RtlCopyMemory(RequestBuffer->NewPassword.Buffer, 2501 newpassword, 2502 RequestBuffer->NewPassword.MaximumLength); 2503 2504 /* Call the authentication package */ 2505 Status = LsaCallAuthenticationPackage(LsaHandle, 2506 AuthenticationPackage, 2507 RequestBuffer, 2508 RequestBufferSize, 2509 (PVOID*)&ResponseBuffer, 2510 &ResponseBufferSize, 2511 &ProtocolStatus); 2512 if (!NT_SUCCESS(Status)) 2513 { 2514 ApiStatus = NetpNtStatusToApiStatus(Status); 2515 goto done; 2516 } 2517 2518 if (!NT_SUCCESS(ProtocolStatus)) 2519 { 2520 ApiStatus = NetpNtStatusToApiStatus(ProtocolStatus); 2521 goto done; 2522 } 2523 2524 done: 2525 if (RequestBuffer != NULL) 2526 NetApiBufferFree(RequestBuffer); 2527 2528 if (ResponseBuffer != NULL) 2529 LsaFreeReturnBuffer(ResponseBuffer); 2530 2531 if (LsaHandle != NULL) 2532 NtClose(LsaHandle); 2533 2534 return ApiStatus; 2535 } 2536 2537 2538 /************************************************************ 2539 * NetUserDel (NETAPI32.@) 2540 */ 2541 NET_API_STATUS 2542 WINAPI 2543 NetUserDel(LPCWSTR servername, 2544 LPCWSTR username) 2545 { 2546 UNICODE_STRING ServerName; 2547 UNICODE_STRING UserName; 2548 SAM_HANDLE ServerHandle = NULL; 2549 SAM_HANDLE DomainHandle = NULL; 2550 SAM_HANDLE UserHandle = NULL; 2551 NET_API_STATUS ApiStatus = NERR_Success; 2552 NTSTATUS Status = STATUS_SUCCESS; 2553 2554 TRACE("(%s, %s)\n", debugstr_w(servername), debugstr_w(username)); 2555 2556 if (servername != NULL) 2557 RtlInitUnicodeString(&ServerName, servername); 2558 2559 RtlInitUnicodeString(&UserName, username); 2560 2561 /* Connect to the SAM Server */ 2562 Status = SamConnect((servername != NULL) ? &ServerName : NULL, 2563 &ServerHandle, 2564 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, 2565 NULL); 2566 if (!NT_SUCCESS(Status)) 2567 { 2568 ERR("SamConnect failed (Status %08lx)\n", Status); 2569 ApiStatus = NetpNtStatusToApiStatus(Status); 2570 goto done; 2571 } 2572 2573 /* Open the Builtin Domain */ 2574 Status = OpenBuiltinDomain(ServerHandle, 2575 DOMAIN_LOOKUP, 2576 &DomainHandle); 2577 if (!NT_SUCCESS(Status)) 2578 { 2579 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status); 2580 ApiStatus = NetpNtStatusToApiStatus(Status); 2581 goto done; 2582 } 2583 2584 /* Open the user account in the builtin domain */ 2585 ApiStatus = OpenUserByName(DomainHandle, 2586 &UserName, 2587 DELETE, 2588 &UserHandle); 2589 if (ApiStatus != NERR_Success && ApiStatus != ERROR_NONE_MAPPED) 2590 { 2591 TRACE("OpenUserByName(%wZ) failed (ApiStatus %lu)\n", &UserName, ApiStatus); 2592 goto done; 2593 } 2594 2595 if (UserHandle == NULL) 2596 { 2597 if (DomainHandle != NULL) 2598 { 2599 SamCloseHandle(DomainHandle); 2600 DomainHandle = NULL; 2601 } 2602 2603 /* Open the Acount Domain */ 2604 Status = OpenAccountDomain(ServerHandle, 2605 (servername != NULL) ? &ServerName : NULL, 2606 DOMAIN_LOOKUP, 2607 &DomainHandle); 2608 if (!NT_SUCCESS(Status)) 2609 { 2610 ERR("OpenAccountDomain failed (Status %08lx)\n", Status); 2611 ApiStatus = NetpNtStatusToApiStatus(Status); 2612 goto done; 2613 } 2614 2615 /* Open the user account in the account domain */ 2616 ApiStatus = OpenUserByName(DomainHandle, 2617 &UserName, 2618 DELETE, 2619 &UserHandle); 2620 if (ApiStatus != NERR_Success) 2621 { 2622 ERR("OpenUserByName(%wZ) failed (ApiStatus %lu)\n", &UserName, ApiStatus); 2623 if (ApiStatus == ERROR_NONE_MAPPED) 2624 ApiStatus = NERR_UserNotFound; 2625 goto done; 2626 } 2627 } 2628 2629 /* Delete the user */ 2630 Status = SamDeleteUser(UserHandle); 2631 if (!NT_SUCCESS(Status)) 2632 { 2633 ERR("SamDeleteUser failed (Status %08lx)\n", Status); 2634 ApiStatus = NetpNtStatusToApiStatus(Status); 2635 goto done; 2636 } 2637 2638 /* A successful delete invalidates the handle */ 2639 UserHandle = NULL; 2640 2641 done: 2642 if (UserHandle != NULL) 2643 SamCloseHandle(UserHandle); 2644 2645 if (DomainHandle != NULL) 2646 SamCloseHandle(DomainHandle); 2647 2648 if (ServerHandle != NULL) 2649 SamCloseHandle(ServerHandle); 2650 2651 return ApiStatus; 2652 } 2653 2654 static 2655 NET_API_STATUS 2656 AllocateEnumContext( 2657 PENUM_CONTEXT *AllocatedEnumContext) 2658 { 2659 NET_API_STATUS ApiStatus; 2660 PENUM_CONTEXT EnumContext; 2661 2662 /* Allocate the context structure */ 2663 ApiStatus = NetApiBufferAllocate(sizeof(ENUM_CONTEXT), (PVOID*)&EnumContext); 2664 if (ApiStatus != NERR_Success) 2665 return ApiStatus; 2666 2667 /* Initialize the fields */ 2668 EnumContext->EnumerationContext = 0; 2669 EnumContext->Buffer = NULL; 2670 EnumContext->Count = 0; 2671 EnumContext->Index = 0; 2672 EnumContext->BuiltinDone = FALSE; 2673 2674 /* Set a "unique" handle */ 2675 EnumContext->EnumHandle = InterlockedIncrement(&g_EnumContextHandle); 2676 if (EnumContext->EnumHandle == 0) 2677 { 2678 EnumContext->EnumHandle = InterlockedIncrement(&g_EnumContextHandle); 2679 } 2680 2681 /* Insert the context in the list */ 2682 EnterCriticalSection(&g_EnumContextListLock); 2683 InsertTailList(&g_EnumContextListHead, &EnumContext->ListLink); 2684 LeaveCriticalSection(&g_EnumContextListLock); 2685 2686 *AllocatedEnumContext = EnumContext; 2687 return NERR_Success; 2688 } 2689 2690 static 2691 VOID 2692 FreeEnumContext( 2693 PENUM_CONTEXT EnumContext) 2694 2695 { 2696 /* Remove the context from the list */ 2697 EnterCriticalSection(&g_EnumContextListLock); 2698 RemoveEntryList(&EnumContext->ListLink); 2699 LeaveCriticalSection(&g_EnumContextListLock); 2700 2701 /* Free it */ 2702 NetApiBufferFree(EnumContext); 2703 } 2704 2705 static 2706 PENUM_CONTEXT 2707 LookupEnumContext( 2708 SAM_ENUMERATE_HANDLE EnumerationHandle) 2709 { 2710 PENUM_CONTEXT FoundEnumContext = NULL; 2711 PLIST_ENTRY ListEntry; 2712 2713 /* Acquire the list lock */ 2714 EnterCriticalSection(&g_EnumContextListLock); 2715 2716 /* Search the list for the handle */ 2717 for (ListEntry = g_EnumContextListHead.Flink; 2718 ListEntry != &g_EnumContextListHead; 2719 ListEntry = ListEntry->Flink) 2720 { 2721 PENUM_CONTEXT EnumContext = CONTAINING_RECORD(ListEntry, ENUM_CONTEXT, ListLink); 2722 if (EnumContext->EnumHandle == EnumerationHandle) 2723 { 2724 FoundEnumContext = EnumContext; 2725 break; 2726 } 2727 } 2728 2729 /* Release the list lock */ 2730 LeaveCriticalSection(&g_EnumContextListLock); 2731 2732 return FoundEnumContext; 2733 } 2734 2735 /************************************************************ 2736 * NetUserEnum (NETAPI32.@) 2737 */ 2738 NET_API_STATUS 2739 WINAPI 2740 NetUserEnum(LPCWSTR servername, 2741 DWORD level, 2742 DWORD filter, 2743 LPBYTE* bufptr, 2744 DWORD prefmaxlen, 2745 LPDWORD entriesread, 2746 LPDWORD totalentries, 2747 LPDWORD resume_handle) 2748 { 2749 UNICODE_STRING ServerName; 2750 PSAM_RID_ENUMERATION CurrentUser; 2751 PENUM_CONTEXT EnumContext = NULL; 2752 LPVOID Buffer = NULL; 2753 ULONG i; 2754 SAM_HANDLE UserHandle = NULL; 2755 ACCESS_MASK DesiredAccess; 2756 NET_API_STATUS ApiStatus = NERR_Success; 2757 NTSTATUS Status = STATUS_SUCCESS; 2758 2759 TRACE("(%s %d 0x%d %p %d %p %p %p)\n", debugstr_w(servername), level, 2760 filter, bufptr, prefmaxlen, entriesread, totalentries, resume_handle); 2761 2762 *entriesread = 0; 2763 *totalentries = 0; 2764 *bufptr = NULL; 2765 2766 if (servername != NULL) 2767 RtlInitUnicodeString(&ServerName, servername); 2768 2769 if (resume_handle != NULL && *resume_handle != 0) 2770 { 2771 EnumContext = LookupEnumContext(*resume_handle); 2772 } 2773 else 2774 { 2775 ApiStatus = AllocateEnumContext(&EnumContext); 2776 if (ApiStatus != NERR_Success) 2777 goto done; 2778 2779 Status = SamConnect((servername != NULL) ? &ServerName : NULL, 2780 &EnumContext->ServerHandle, 2781 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, 2782 NULL); 2783 if (!NT_SUCCESS(Status)) 2784 { 2785 ERR("SamConnect failed (Status %08lx)\n", Status); 2786 ApiStatus = NetpNtStatusToApiStatus(Status); 2787 goto done; 2788 } 2789 2790 /* Get the Account Domain SID */ 2791 Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL, 2792 &EnumContext->AccountDomainSid); 2793 if (!NT_SUCCESS(Status)) 2794 { 2795 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status); 2796 ApiStatus = NetpNtStatusToApiStatus(Status); 2797 goto done; 2798 } 2799 2800 /* Open the Account Domain */ 2801 Status = SamOpenDomain(EnumContext->ServerHandle, 2802 DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP, 2803 EnumContext->AccountDomainSid, 2804 &EnumContext->AccountDomainHandle); 2805 if (!NT_SUCCESS(Status)) 2806 { 2807 ERR("SamOpenDomain failed (Status %08lx)\n", Status); 2808 ApiStatus = NetpNtStatusToApiStatus(Status); 2809 goto done; 2810 } 2811 2812 /* Get the Builtin Domain SID */ 2813 Status = GetBuiltinDomainSid(&EnumContext->BuiltinDomainSid); 2814 if (!NT_SUCCESS(Status)) 2815 { 2816 ERR("GetBuiltinDomainSid failed (Status %08lx)\n", Status); 2817 ApiStatus = NetpNtStatusToApiStatus(Status); 2818 goto done; 2819 } 2820 2821 DesiredAccess = DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP; 2822 if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11)) 2823 DesiredAccess |= DOMAIN_GET_ALIAS_MEMBERSHIP; 2824 2825 /* Open the Builtin Domain */ 2826 Status = SamOpenDomain(EnumContext->ServerHandle, 2827 DesiredAccess, 2828 EnumContext->BuiltinDomainSid, 2829 &EnumContext->BuiltinDomainHandle); 2830 if (!NT_SUCCESS(Status)) 2831 { 2832 ERR("SamOpenDomain failed (Status %08lx)\n", Status); 2833 ApiStatus = NetpNtStatusToApiStatus(Status); 2834 goto done; 2835 } 2836 } 2837 2838 // while (TRUE) 2839 // { 2840 TRACE("EnumContext->Index: %lu\n", EnumContext->Index); 2841 TRACE("EnumContext->Count: %lu\n", EnumContext->Count); 2842 2843 if (EnumContext->Index >= EnumContext->Count) 2844 { 2845 // if (EnumContext->BuiltinDone != FALSE) 2846 // { 2847 // ApiStatus = NERR_Success; 2848 // goto done; 2849 // } 2850 2851 TRACE("Calling SamEnumerateUsersInDomain\n"); 2852 Status = SamEnumerateUsersInDomain(EnumContext->AccountDomainHandle, //BuiltinDomainHandle, 2853 &EnumContext->EnumerationContext, 2854 0, 2855 (PVOID *)&EnumContext->Buffer, 2856 prefmaxlen, 2857 &EnumContext->Count); 2858 2859 TRACE("SamEnumerateUsersInDomain returned (Status %08lx)\n", Status); 2860 if (!NT_SUCCESS(Status)) 2861 { 2862 ERR("SamEnumerateUsersInDomain failed (Status %08lx)\n", Status); 2863 ApiStatus = NetpNtStatusToApiStatus(Status); 2864 goto done; 2865 } 2866 2867 if (Status == STATUS_MORE_ENTRIES) 2868 { 2869 ApiStatus = NERR_BufTooSmall; 2870 goto done; 2871 } 2872 else 2873 { 2874 EnumContext->BuiltinDone = TRUE; 2875 } 2876 } 2877 2878 TRACE("EnumContext: %lu\n", EnumContext); 2879 TRACE("EnumContext->Count: %lu\n", EnumContext->Count); 2880 TRACE("EnumContext->Buffer: %p\n", EnumContext->Buffer); 2881 2882 /* Get a pointer to the current user */ 2883 CurrentUser = &EnumContext->Buffer[EnumContext->Index]; 2884 2885 TRACE("RID: %lu\n", CurrentUser->RelativeId); 2886 2887 DesiredAccess = READ_CONTROL | USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT; 2888 if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11)) 2889 DesiredAccess |= USER_LIST_GROUPS; 2890 2891 Status = SamOpenUser(EnumContext->AccountDomainHandle, //BuiltinDomainHandle, 2892 DesiredAccess, 2893 CurrentUser->RelativeId, 2894 &UserHandle); 2895 if (!NT_SUCCESS(Status)) 2896 { 2897 ERR("SamOpenUser failed (Status %08lx)\n", Status); 2898 ApiStatus = NetpNtStatusToApiStatus(Status); 2899 goto done; 2900 } 2901 2902 ApiStatus = BuildUserInfoBuffer(EnumContext->BuiltinDomainHandle, 2903 UserHandle, 2904 EnumContext->AccountDomainSid, 2905 CurrentUser->RelativeId, 2906 level, 2907 &Buffer); 2908 if (ApiStatus != NERR_Success) 2909 { 2910 ERR("BuildUserInfoBuffer failed (ApiStatus %lu)\n", ApiStatus); 2911 goto done; 2912 } 2913 2914 SamCloseHandle(UserHandle); 2915 UserHandle = NULL; 2916 2917 EnumContext->Index++; 2918 2919 (*entriesread)++; 2920 // } 2921 2922 done: 2923 if (ApiStatus == NERR_Success && EnumContext != NULL && EnumContext->Index < EnumContext->Count) 2924 ApiStatus = ERROR_MORE_DATA; 2925 2926 if (EnumContext != NULL) 2927 *totalentries = EnumContext->Count; 2928 2929 if (resume_handle == NULL || ApiStatus != ERROR_MORE_DATA) 2930 { 2931 if (EnumContext != NULL) 2932 { 2933 if (EnumContext->BuiltinDomainHandle != NULL) 2934 SamCloseHandle(EnumContext->BuiltinDomainHandle); 2935 2936 if (EnumContext->AccountDomainHandle != NULL) 2937 SamCloseHandle(EnumContext->AccountDomainHandle); 2938 2939 if (EnumContext->BuiltinDomainSid != NULL) 2940 RtlFreeHeap(RtlGetProcessHeap(), 0, EnumContext->BuiltinDomainSid); 2941 2942 if (EnumContext->AccountDomainSid != NULL) 2943 RtlFreeHeap(RtlGetProcessHeap(), 0, EnumContext->AccountDomainSid); 2944 2945 if (EnumContext->ServerHandle != NULL) 2946 SamCloseHandle(EnumContext->ServerHandle); 2947 2948 if (EnumContext->Buffer != NULL) 2949 { 2950 for (i = 0; i < EnumContext->Count; i++) 2951 { 2952 SamFreeMemory(EnumContext->Buffer[i].Name.Buffer); 2953 } 2954 2955 SamFreeMemory(EnumContext->Buffer); 2956 } 2957 2958 FreeEnumContext(EnumContext); 2959 EnumContext = NULL; 2960 } 2961 } 2962 2963 if (UserHandle != NULL) 2964 SamCloseHandle(UserHandle); 2965 2966 if (resume_handle != NULL) 2967 *resume_handle = EnumContext ? EnumContext->EnumHandle : 0; 2968 2969 *bufptr = (LPBYTE)Buffer; 2970 2971 TRACE("return %lu\n", ApiStatus); 2972 2973 return ApiStatus; 2974 } 2975 2976 2977 /************************************************************ 2978 * NetUserGetGroups (NETAPI32.@) 2979 */ 2980 NET_API_STATUS 2981 WINAPI 2982 NetUserGetGroups(LPCWSTR servername, 2983 LPCWSTR username, 2984 DWORD level, 2985 LPBYTE *bufptr, 2986 DWORD prefixmaxlen, 2987 LPDWORD entriesread, 2988 LPDWORD totalentries) 2989 { 2990 UNICODE_STRING ServerName; 2991 UNICODE_STRING UserName; 2992 SAM_HANDLE ServerHandle = NULL; 2993 SAM_HANDLE AccountDomainHandle = NULL; 2994 SAM_HANDLE UserHandle = NULL; 2995 PSID AccountDomainSid = NULL; 2996 PULONG RelativeIds = NULL; 2997 PSID_NAME_USE Use = NULL; 2998 PGROUP_MEMBERSHIP GroupMembership = NULL; 2999 ULONG GroupCount; 3000 3001 NET_API_STATUS ApiStatus = NERR_Success; 3002 NTSTATUS Status = STATUS_SUCCESS; 3003 3004 TRACE("%s %s %d %p %d %p %p stub\n", debugstr_w(servername), 3005 debugstr_w(username), level, bufptr, prefixmaxlen, entriesread, 3006 totalentries); 3007 3008 if (servername != NULL) 3009 RtlInitUnicodeString(&ServerName, servername); 3010 3011 RtlInitUnicodeString(&UserName, username); 3012 3013 /* Connect to the SAM Server */ 3014 Status = SamConnect((servername != NULL) ? &ServerName : NULL, 3015 &ServerHandle, 3016 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, 3017 NULL); 3018 if (!NT_SUCCESS(Status)) 3019 { 3020 ERR("SamConnect failed (Status %08lx)\n", Status); 3021 ApiStatus = NetpNtStatusToApiStatus(Status); 3022 goto done; 3023 } 3024 3025 /* Get the Account Domain SID */ 3026 Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL, 3027 &AccountDomainSid); 3028 if (!NT_SUCCESS(Status)) 3029 { 3030 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status); 3031 ApiStatus = NetpNtStatusToApiStatus(Status); 3032 goto done; 3033 } 3034 3035 /* Open the Account Domain */ 3036 Status = SamOpenDomain(ServerHandle, 3037 DOMAIN_LOOKUP | DOMAIN_GET_ALIAS_MEMBERSHIP, 3038 AccountDomainSid, 3039 &AccountDomainHandle); 3040 if (!NT_SUCCESS(Status)) 3041 { 3042 ERR("SamOpenDomain failed (Status %08lx)\n", Status); 3043 ApiStatus = NetpNtStatusToApiStatus(Status); 3044 goto done; 3045 } 3046 3047 /* Get the RID for the given user name */ 3048 Status = SamLookupNamesInDomain(AccountDomainHandle, 3049 1, 3050 &UserName, 3051 &RelativeIds, 3052 &Use); 3053 if (!NT_SUCCESS(Status)) 3054 { 3055 ERR("SamLookupNamesInDomain(%wZ) failed (Status %08lx)\n", &UserName, Status); 3056 if (Status == STATUS_NONE_MAPPED) 3057 ApiStatus = NERR_UserNotFound; 3058 else 3059 ApiStatus = NetpNtStatusToApiStatus(Status); 3060 goto done; 3061 } 3062 3063 /* Fail, if it is not a user account */ 3064 if (Use[0] != SidTypeUser) 3065 { 3066 ERR("Account is not a User!\n"); 3067 ApiStatus = NERR_UserNotFound; 3068 goto done; 3069 } 3070 3071 /* Open the user object */ 3072 Status = SamOpenUser(AccountDomainHandle, 3073 USER_LIST_GROUPS, 3074 RelativeIds[0], 3075 &UserHandle); 3076 if (!NT_SUCCESS(Status)) 3077 { 3078 ERR("SamOpenUser failed (Status %08lx)\n", Status); 3079 ApiStatus = NetpNtStatusToApiStatus(Status); 3080 goto done; 3081 } 3082 3083 /* Get the group memberships of this user */ 3084 Status = SamGetGroupsForUser(UserHandle, 3085 &GroupMembership, 3086 &GroupCount); 3087 if (!NT_SUCCESS(Status)) 3088 { 3089 ERR("SamGetGroupsForUser failed (Status %08lx)\n", Status); 3090 ApiStatus = NetpNtStatusToApiStatus(Status); 3091 goto done; 3092 } 3093 3094 /* If there is no group membership, we're done */ 3095 if (GroupCount == 0) 3096 { 3097 ApiStatus = NERR_Success; 3098 goto done; 3099 } 3100 3101 3102 done: 3103 3104 if (GroupMembership != NULL) 3105 SamFreeMemory(GroupMembership); 3106 3107 if (UserHandle != NULL) 3108 SamCloseHandle(UserHandle); 3109 3110 if (RelativeIds != NULL) 3111 SamFreeMemory(RelativeIds); 3112 3113 if (Use != NULL) 3114 SamFreeMemory(Use); 3115 3116 if (AccountDomainSid != NULL) 3117 RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid); 3118 3119 if (AccountDomainHandle != NULL) 3120 SamCloseHandle(AccountDomainHandle); 3121 3122 if (ServerHandle != NULL) 3123 SamCloseHandle(ServerHandle); 3124 3125 if (ApiStatus != NERR_Success && ApiStatus != ERROR_MORE_DATA) 3126 { 3127 *entriesread = 0; 3128 *totalentries = 0; 3129 } 3130 else 3131 { 3132 // *entriesread = Count; 3133 // *totalentries = Count; 3134 } 3135 3136 // *bufptr = (LPBYTE)Buffer; 3137 3138 return ApiStatus; 3139 } 3140 3141 3142 /************************************************************ 3143 * NetUserGetInfo (NETAPI32.@) 3144 */ 3145 NET_API_STATUS 3146 WINAPI 3147 NetUserGetInfo(LPCWSTR servername, 3148 LPCWSTR username, 3149 DWORD level, 3150 LPBYTE* bufptr) 3151 { 3152 UNICODE_STRING ServerName; 3153 UNICODE_STRING UserName; 3154 SAM_HANDLE ServerHandle = NULL; 3155 SAM_HANDLE AccountDomainHandle = NULL; 3156 SAM_HANDLE BuiltinDomainHandle = NULL; 3157 SAM_HANDLE UserHandle = NULL; 3158 PULONG RelativeIds = NULL; 3159 PSID_NAME_USE Use = NULL; 3160 LPVOID Buffer = NULL; 3161 PSID AccountDomainSid = NULL; 3162 PSID BuiltinDomainSid = NULL; 3163 ACCESS_MASK DesiredAccess; 3164 NET_API_STATUS ApiStatus = NERR_Success; 3165 NTSTATUS Status = STATUS_SUCCESS; 3166 3167 TRACE("(%s, %s, %d, %p)\n", debugstr_w(servername), 3168 debugstr_w(username), level, bufptr); 3169 3170 if (servername != NULL) 3171 RtlInitUnicodeString(&ServerName, servername); 3172 3173 RtlInitUnicodeString(&UserName, username); 3174 3175 /* Connect to the SAM Server */ 3176 Status = SamConnect((servername != NULL) ? &ServerName : NULL, 3177 &ServerHandle, 3178 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, 3179 NULL); 3180 if (!NT_SUCCESS(Status)) 3181 { 3182 ERR("SamConnect failed (Status %08lx)\n", Status); 3183 ApiStatus = NetpNtStatusToApiStatus(Status); 3184 goto done; 3185 } 3186 3187 /* Get the Builtin Domain SID */ 3188 Status = GetBuiltinDomainSid(&BuiltinDomainSid); 3189 if (!NT_SUCCESS(Status)) 3190 { 3191 ERR("GetBuiltinDomainSid failed (Status %08lx)\n", Status); 3192 ApiStatus = NetpNtStatusToApiStatus(Status); 3193 goto done; 3194 } 3195 3196 DesiredAccess = DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP; 3197 if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11)) 3198 DesiredAccess |= DOMAIN_GET_ALIAS_MEMBERSHIP; 3199 3200 /* Open the Builtin Domain */ 3201 Status = SamOpenDomain(ServerHandle, 3202 DesiredAccess, 3203 BuiltinDomainSid, 3204 &BuiltinDomainHandle); 3205 if (!NT_SUCCESS(Status)) 3206 { 3207 ERR("SamOpenDomain failed (Status %08lx)\n", Status); 3208 ApiStatus = NetpNtStatusToApiStatus(Status); 3209 goto done; 3210 } 3211 3212 /* Get the Account Domain SID */ 3213 Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL, 3214 &AccountDomainSid); 3215 if (!NT_SUCCESS(Status)) 3216 { 3217 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status); 3218 ApiStatus = NetpNtStatusToApiStatus(Status); 3219 goto done; 3220 } 3221 3222 /* Open the Account Domain */ 3223 Status = SamOpenDomain(ServerHandle, 3224 DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP, 3225 AccountDomainSid, 3226 &AccountDomainHandle); 3227 if (!NT_SUCCESS(Status)) 3228 { 3229 ERR("SamOpenDomain failed (Status %08lx)\n", Status); 3230 ApiStatus = NetpNtStatusToApiStatus(Status); 3231 goto done; 3232 } 3233 3234 /* Get the RID for the given user name */ 3235 Status = SamLookupNamesInDomain(AccountDomainHandle, 3236 1, 3237 &UserName, 3238 &RelativeIds, 3239 &Use); 3240 if (!NT_SUCCESS(Status)) 3241 { 3242 ERR("SamLookupNamesInDomain(%wZ) failed (Status %08lx)\n", &UserName, Status); 3243 if (Status == STATUS_NONE_MAPPED) 3244 ApiStatus = NERR_UserNotFound; 3245 else 3246 ApiStatus = NetpNtStatusToApiStatus(Status); 3247 goto done; 3248 } 3249 3250 /* Check if the account is a user account */ 3251 if (Use[0] != SidTypeUser) 3252 { 3253 ERR("No user found!\n"); 3254 ApiStatus = NERR_UserNotFound; 3255 goto done; 3256 } 3257 3258 TRACE("RID: %lu\n", RelativeIds[0]); 3259 3260 DesiredAccess = READ_CONTROL | USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT; 3261 if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11)) 3262 DesiredAccess |= USER_LIST_GROUPS; 3263 3264 /* Open the user object */ 3265 Status = SamOpenUser(AccountDomainHandle, 3266 DesiredAccess, 3267 RelativeIds[0], 3268 &UserHandle); 3269 if (!NT_SUCCESS(Status)) 3270 { 3271 ERR("SamOpenUser failed (Status %08lx)\n", Status); 3272 ApiStatus = NetpNtStatusToApiStatus(Status); 3273 goto done; 3274 } 3275 3276 ApiStatus = BuildUserInfoBuffer(BuiltinDomainHandle, 3277 UserHandle, 3278 AccountDomainSid, 3279 RelativeIds[0], 3280 level, 3281 &Buffer); 3282 if (ApiStatus != NERR_Success) 3283 { 3284 ERR("BuildUserInfoBuffer failed (ApiStatus %08lu)\n", ApiStatus); 3285 goto done; 3286 } 3287 3288 done: 3289 if (UserHandle != NULL) 3290 SamCloseHandle(UserHandle); 3291 3292 if (RelativeIds != NULL) 3293 SamFreeMemory(RelativeIds); 3294 3295 if (Use != NULL) 3296 SamFreeMemory(Use); 3297 3298 if (AccountDomainHandle != NULL) 3299 SamCloseHandle(AccountDomainHandle); 3300 3301 if (AccountDomainSid != NULL) 3302 RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid); 3303 3304 if (BuiltinDomainHandle != NULL) 3305 SamCloseHandle(BuiltinDomainHandle); 3306 3307 if (BuiltinDomainSid != NULL) 3308 RtlFreeHeap(RtlGetProcessHeap(), 0, BuiltinDomainSid); 3309 3310 if (ServerHandle != NULL) 3311 SamCloseHandle(ServerHandle); 3312 3313 *bufptr = (LPBYTE)Buffer; 3314 3315 return ApiStatus; 3316 } 3317 3318 3319 /************************************************************ 3320 * NetUserGetLocalGroups (NETAPI32.@) 3321 */ 3322 NET_API_STATUS 3323 WINAPI 3324 NetUserGetLocalGroups(LPCWSTR servername, 3325 LPCWSTR username, 3326 DWORD level, 3327 DWORD flags, 3328 LPBYTE* bufptr, 3329 DWORD prefmaxlen, 3330 LPDWORD entriesread, 3331 LPDWORD totalentries) 3332 { 3333 UNICODE_STRING ServerName; 3334 UNICODE_STRING UserName; 3335 SAM_HANDLE ServerHandle = NULL; 3336 SAM_HANDLE BuiltinDomainHandle = NULL; 3337 SAM_HANDLE AccountDomainHandle = NULL; 3338 PSID AccountDomainSid = NULL; 3339 PSID UserSid = NULL; 3340 PULONG RelativeIds = NULL; 3341 PSID_NAME_USE Use = NULL; 3342 ULONG BuiltinMemberCount = 0; 3343 ULONG AccountMemberCount = 0; 3344 PULONG BuiltinAliases = NULL; 3345 PULONG AccountAliases = NULL; 3346 PUNICODE_STRING BuiltinNames = NULL; 3347 PUNICODE_STRING AccountNames = NULL; 3348 PLOCALGROUP_USERS_INFO_0 Buffer = NULL; 3349 ULONG Size; 3350 ULONG Count = 0; 3351 ULONG Index; 3352 ULONG i; 3353 LPWSTR StrPtr; 3354 NET_API_STATUS ApiStatus = NERR_Success; 3355 NTSTATUS Status = STATUS_SUCCESS; 3356 3357 TRACE("(%s, %s, %d, %08x, %p %d, %p, %p) stub!\n", 3358 debugstr_w(servername), debugstr_w(username), level, flags, bufptr, 3359 prefmaxlen, entriesread, totalentries); 3360 3361 if (level != 0) 3362 return ERROR_INVALID_LEVEL; 3363 3364 if (flags & ~LG_INCLUDE_INDIRECT) 3365 return ERROR_INVALID_PARAMETER; 3366 3367 if (flags & LG_INCLUDE_INDIRECT) 3368 { 3369 WARN("The flag LG_INCLUDE_INDIRECT is not supported yet!\n"); 3370 } 3371 3372 if (servername != NULL) 3373 RtlInitUnicodeString(&ServerName, servername); 3374 3375 RtlInitUnicodeString(&UserName, username); 3376 3377 /* Connect to the SAM Server */ 3378 Status = SamConnect((servername != NULL) ? &ServerName : NULL, 3379 &ServerHandle, 3380 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, 3381 NULL); 3382 if (!NT_SUCCESS(Status)) 3383 { 3384 ERR("SamConnect failed (Status %08lx)\n", Status); 3385 ApiStatus = NetpNtStatusToApiStatus(Status); 3386 goto done; 3387 } 3388 3389 /* Open the Builtin Domain */ 3390 Status = OpenBuiltinDomain(ServerHandle, 3391 DOMAIN_LOOKUP | DOMAIN_GET_ALIAS_MEMBERSHIP, 3392 &BuiltinDomainHandle); 3393 if (!NT_SUCCESS(Status)) 3394 { 3395 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status); 3396 ApiStatus = NetpNtStatusToApiStatus(Status); 3397 goto done; 3398 } 3399 3400 /* Get the Account Domain SID */ 3401 Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL, 3402 &AccountDomainSid); 3403 if (!NT_SUCCESS(Status)) 3404 { 3405 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status); 3406 ApiStatus = NetpNtStatusToApiStatus(Status); 3407 goto done; 3408 } 3409 3410 /* Open the Account Domain */ 3411 Status = SamOpenDomain(ServerHandle, 3412 DOMAIN_LOOKUP | DOMAIN_GET_ALIAS_MEMBERSHIP, 3413 AccountDomainSid, 3414 &AccountDomainHandle); 3415 if (!NT_SUCCESS(Status)) 3416 { 3417 ERR("SamOpenDomain failed (Status %08lx)\n", Status); 3418 ApiStatus = NetpNtStatusToApiStatus(Status); 3419 goto done; 3420 } 3421 3422 /* Get the RID for the given user name */ 3423 Status = SamLookupNamesInDomain(AccountDomainHandle, 3424 1, 3425 &UserName, 3426 &RelativeIds, 3427 &Use); 3428 if (!NT_SUCCESS(Status)) 3429 { 3430 ERR("SamLookupNamesInDomain(%wZ) failed (Status %08lx)\n", &UserName, Status); 3431 if (Status == STATUS_NONE_MAPPED) 3432 ApiStatus = NERR_UserNotFound; 3433 else 3434 ApiStatus = NetpNtStatusToApiStatus(Status); 3435 goto done; 3436 } 3437 3438 /* Fail, if it is not a user account */ 3439 if (Use[0] != SidTypeUser) 3440 { 3441 ERR("Account is not a User!\n"); 3442 ApiStatus = NERR_UserNotFound; 3443 goto done; 3444 } 3445 3446 /* Build the User SID from the Account Domain SID and the users RID */ 3447 ApiStatus = BuildSidFromSidAndRid(AccountDomainSid, 3448 RelativeIds[0], 3449 &UserSid); 3450 if (ApiStatus != NERR_Success) 3451 { 3452 ERR("BuildSidFromSidAndRid failed!\n"); 3453 goto done; 3454 } 3455 3456 /* Get alias memberships in the Builtin Domain */ 3457 Status = SamGetAliasMembership(BuiltinDomainHandle, 3458 1, 3459 &UserSid, 3460 &BuiltinMemberCount, 3461 &BuiltinAliases); 3462 if (!NT_SUCCESS(Status)) 3463 { 3464 ERR("SamGetAliasMembership failed (Status %08lx)\n", Status); 3465 ApiStatus = NetpNtStatusToApiStatus(Status); 3466 goto done; 3467 } 3468 3469 if (BuiltinMemberCount > 0) 3470 { 3471 /* Get the Names of the builtin alias members */ 3472 Status = SamLookupIdsInDomain(BuiltinDomainHandle, 3473 BuiltinMemberCount, 3474 BuiltinAliases, 3475 &BuiltinNames, 3476 NULL); 3477 if (!NT_SUCCESS(Status)) 3478 { 3479 ERR("SamLookupIdsInDomain failed (Status %08lx)\n", Status); 3480 ApiStatus = NetpNtStatusToApiStatus(Status); 3481 goto done; 3482 } 3483 } 3484 3485 /* Get alias memberships in the Account Domain */ 3486 Status = SamGetAliasMembership(AccountDomainHandle, 3487 1, 3488 &UserSid, 3489 &AccountMemberCount, 3490 &AccountAliases); 3491 if (!NT_SUCCESS(Status)) 3492 { 3493 ERR("SamGetAliasMembership failed (Status %08lx)\n", Status); 3494 ApiStatus = NetpNtStatusToApiStatus(Status); 3495 goto done; 3496 } 3497 3498 if (AccountMemberCount > 0) 3499 { 3500 /* Get the Names of the builtin alias members */ 3501 Status = SamLookupIdsInDomain(AccountDomainHandle, 3502 AccountMemberCount, 3503 AccountAliases, 3504 &AccountNames, 3505 NULL); 3506 if (!NT_SUCCESS(Status)) 3507 { 3508 ERR("SamLookupIdsInDomain failed (Status %08lx)\n", Status); 3509 ApiStatus = NetpNtStatusToApiStatus(Status); 3510 goto done; 3511 } 3512 } 3513 3514 /* Calculate the required buffer size */ 3515 Size = 0; 3516 3517 for (i = 0; i < BuiltinMemberCount; i++) 3518 { 3519 if (BuiltinNames[i].Length > 0) 3520 { 3521 Size += (sizeof(LOCALGROUP_USERS_INFO_0) + BuiltinNames[i].Length + sizeof(UNICODE_NULL)); 3522 Count++; 3523 } 3524 } 3525 3526 for (i = 0; i < AccountMemberCount; i++) 3527 { 3528 if (AccountNames[i].Length > 0) 3529 { 3530 Size += (sizeof(LOCALGROUP_USERS_INFO_0) + AccountNames[i].Length + sizeof(UNICODE_NULL)); 3531 Count++; 3532 } 3533 } 3534 3535 if (Size == 0) 3536 { 3537 ApiStatus = NERR_Success; 3538 goto done; 3539 } 3540 3541 /* Allocate buffer */ 3542 ApiStatus = NetApiBufferAllocate(Size, (LPVOID*)&Buffer); 3543 if (ApiStatus != NERR_Success) 3544 goto done; 3545 3546 ZeroMemory(Buffer, Size); 3547 3548 StrPtr = (LPWSTR)((INT_PTR)Buffer + Count * sizeof(LOCALGROUP_USERS_INFO_0)); 3549 3550 /* Copy data to the allocated buffer */ 3551 Index = 0; 3552 for (i = 0; i < BuiltinMemberCount; i++) 3553 { 3554 if (BuiltinNames[i].Length > 0) 3555 { 3556 CopyMemory(StrPtr, 3557 BuiltinNames[i].Buffer, 3558 BuiltinNames[i].Length); 3559 Buffer[Index].lgrui0_name = StrPtr; 3560 3561 StrPtr = (LPWSTR)((INT_PTR)StrPtr + BuiltinNames[i].Length + sizeof(UNICODE_NULL)); 3562 Index++; 3563 } 3564 } 3565 3566 for (i = 0; i < AccountMemberCount; i++) 3567 { 3568 if (AccountNames[i].Length > 0) 3569 { 3570 CopyMemory(StrPtr, 3571 AccountNames[i].Buffer, 3572 AccountNames[i].Length); 3573 Buffer[Index].lgrui0_name = StrPtr; 3574 3575 StrPtr = (LPWSTR)((INT_PTR)StrPtr + AccountNames[i].Length + sizeof(UNICODE_NULL)); 3576 Index++; 3577 } 3578 } 3579 3580 done: 3581 if (AccountNames != NULL) 3582 SamFreeMemory(AccountNames); 3583 3584 if (BuiltinNames != NULL) 3585 SamFreeMemory(BuiltinNames); 3586 3587 if (AccountAliases != NULL) 3588 SamFreeMemory(AccountAliases); 3589 3590 if (BuiltinAliases != NULL) 3591 SamFreeMemory(BuiltinAliases); 3592 3593 if (RelativeIds != NULL) 3594 SamFreeMemory(RelativeIds); 3595 3596 if (Use != NULL) 3597 SamFreeMemory(Use); 3598 3599 if (UserSid != NULL) 3600 NetApiBufferFree(UserSid); 3601 3602 if (AccountDomainSid != NULL) 3603 RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid); 3604 3605 if (AccountDomainHandle != NULL) 3606 SamCloseHandle(AccountDomainHandle); 3607 3608 if (BuiltinDomainHandle != NULL) 3609 SamCloseHandle(BuiltinDomainHandle); 3610 3611 if (ServerHandle != NULL) 3612 SamCloseHandle(ServerHandle); 3613 3614 if (ApiStatus != NERR_Success && ApiStatus != ERROR_MORE_DATA) 3615 { 3616 *entriesread = 0; 3617 *totalentries = 0; 3618 } 3619 else 3620 { 3621 *entriesread = Count; 3622 *totalentries = Count; 3623 } 3624 3625 *bufptr = (LPBYTE)Buffer; 3626 3627 return ApiStatus; 3628 } 3629 3630 3631 /****************************************************************************** 3632 * NetUserModalsGet (NETAPI32.@) 3633 * 3634 * Retrieves global information for all users and global groups in the security 3635 * database. 3636 * 3637 * PARAMS 3638 * servername [I] Specifies the DNS or the NetBIOS name of the remote server 3639 * on which the function is to execute. 3640 * level [I] Information level of the data. 3641 * 0 Return global passwords parameters. bufptr points to a 3642 * USER_MODALS_INFO_0 struct. 3643 * 1 Return logon server and domain controller information. bufptr 3644 * points to a USER_MODALS_INFO_1 struct. 3645 * 2 Return domain name and identifier. bufptr points to a 3646 * USER_MODALS_INFO_2 struct. 3647 * 3 Return lockout information. bufptr points to a USER_MODALS_INFO_3 3648 * struct. 3649 * bufptr [O] Buffer that receives the data. 3650 * 3651 * RETURNS 3652 * Success: NERR_Success. 3653 * Failure: 3654 * ERROR_ACCESS_DENIED - the user does not have access to the info. 3655 * NERR_InvalidComputer - computer name is invalid. 3656 */ 3657 NET_API_STATUS 3658 WINAPI 3659 NetUserModalsGet(LPCWSTR servername, 3660 DWORD level, 3661 LPBYTE *bufptr) 3662 { 3663 UNICODE_STRING ServerName; 3664 SAM_HANDLE ServerHandle = NULL; 3665 SAM_HANDLE DomainHandle = NULL; 3666 PSID DomainSid = NULL; 3667 PDOMAIN_PASSWORD_INFORMATION PasswordInfo = NULL; 3668 PDOMAIN_LOGOFF_INFORMATION LogoffInfo = NULL; 3669 PDOMAIN_SERVER_ROLE_INFORMATION ServerRoleInfo = NULL; 3670 PDOMAIN_REPLICATION_INFORMATION ReplicationInfo = NULL; 3671 PDOMAIN_NAME_INFORMATION NameInfo = NULL; 3672 PDOMAIN_LOCKOUT_INFORMATION LockoutInfo = NULL; 3673 ULONG DesiredAccess; 3674 ULONG BufferSize; 3675 PUSER_MODALS_INFO_0 umi0; 3676 PUSER_MODALS_INFO_1 umi1; 3677 PUSER_MODALS_INFO_2 umi2; 3678 PUSER_MODALS_INFO_3 umi3; 3679 NET_API_STATUS ApiStatus = NERR_Success; 3680 NTSTATUS Status = STATUS_SUCCESS; 3681 3682 TRACE("(%s %d %p)\n", debugstr_w(servername), level, bufptr); 3683 3684 *bufptr = NULL; 3685 3686 if (servername != NULL) 3687 RtlInitUnicodeString(&ServerName, servername); 3688 3689 /* Connect to the SAM Server */ 3690 Status = SamConnect((servername != NULL) ? &ServerName : NULL, 3691 &ServerHandle, 3692 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, 3693 NULL); 3694 if (!NT_SUCCESS(Status)) 3695 { 3696 ERR("SamConnect failed (Status %08lx)\n", Status); 3697 ApiStatus = NetpNtStatusToApiStatus(Status); 3698 goto done; 3699 } 3700 3701 /* Get the Account Domain SID */ 3702 Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL, 3703 &DomainSid); 3704 if (!NT_SUCCESS(Status)) 3705 { 3706 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status); 3707 ApiStatus = NetpNtStatusToApiStatus(Status); 3708 goto done; 3709 } 3710 3711 switch (level) 3712 { 3713 case 0: 3714 DesiredAccess = DOMAIN_READ_OTHER_PARAMETERS | DOMAIN_READ_PASSWORD_PARAMETERS; 3715 break; 3716 3717 case 1: 3718 DesiredAccess = DOMAIN_READ_OTHER_PARAMETERS; 3719 break; 3720 3721 case 2: 3722 DesiredAccess = DOMAIN_READ_OTHER_PARAMETERS; 3723 break; 3724 3725 case 3: 3726 DesiredAccess = DOMAIN_READ_PASSWORD_PARAMETERS; 3727 break; 3728 3729 default: 3730 ApiStatus = ERROR_INVALID_LEVEL; 3731 goto done; 3732 } 3733 3734 /* Open the Account Domain */ 3735 Status = SamOpenDomain(ServerHandle, 3736 DesiredAccess, 3737 DomainSid, 3738 &DomainHandle); 3739 if (!NT_SUCCESS(Status)) 3740 { 3741 ERR("OpenAccountDomain failed (Status %08lx)\n", Status); 3742 ApiStatus = NetpNtStatusToApiStatus(Status); 3743 goto done; 3744 } 3745 3746 switch (level) 3747 { 3748 case 0: 3749 /* return global passwords parameters */ 3750 Status = SamQueryInformationDomain(DomainHandle, 3751 DomainPasswordInformation, 3752 (PVOID*)&PasswordInfo); 3753 if (!NT_SUCCESS(Status)) 3754 { 3755 ApiStatus = NetpNtStatusToApiStatus(Status); 3756 goto done; 3757 } 3758 3759 Status = SamQueryInformationDomain(DomainHandle, 3760 DomainLogoffInformation, 3761 (PVOID*)&LogoffInfo); 3762 if (!NT_SUCCESS(Status)) 3763 { 3764 ApiStatus = NetpNtStatusToApiStatus(Status); 3765 goto done; 3766 } 3767 3768 BufferSize = sizeof(USER_MODALS_INFO_0); 3769 break; 3770 3771 case 1: 3772 /* return logon server and domain controller info */ 3773 Status = SamQueryInformationDomain(DomainHandle, 3774 DomainServerRoleInformation, 3775 (PVOID*)&ServerRoleInfo); 3776 if (!NT_SUCCESS(Status)) 3777 { 3778 ApiStatus = NetpNtStatusToApiStatus(Status); 3779 goto done; 3780 } 3781 3782 Status = SamQueryInformationDomain(DomainHandle, 3783 DomainReplicationInformation, 3784 (PVOID*)&ReplicationInfo); 3785 if (!NT_SUCCESS(Status)) 3786 { 3787 ApiStatus = NetpNtStatusToApiStatus(Status); 3788 goto done; 3789 } 3790 3791 BufferSize = sizeof(USER_MODALS_INFO_1) + 3792 ReplicationInfo->ReplicaSourceNodeName.Length + sizeof(WCHAR); 3793 break; 3794 3795 case 2: 3796 /* return domain name and identifier */ 3797 Status = SamQueryInformationDomain(DomainHandle, 3798 DomainNameInformation, 3799 (PVOID*)&NameInfo); 3800 if (!NT_SUCCESS(Status)) 3801 { 3802 ApiStatus = NetpNtStatusToApiStatus(Status); 3803 goto done; 3804 } 3805 3806 BufferSize = sizeof( USER_MODALS_INFO_2 ) + 3807 NameInfo->DomainName.Length + sizeof(WCHAR) + 3808 RtlLengthSid(DomainSid); 3809 break; 3810 3811 case 3: 3812 /* return lockout information */ 3813 Status = SamQueryInformationDomain(DomainHandle, 3814 DomainLockoutInformation, 3815 (PVOID*)&LockoutInfo); 3816 if (!NT_SUCCESS(Status)) 3817 { 3818 ApiStatus = NetpNtStatusToApiStatus(Status); 3819 goto done; 3820 } 3821 3822 BufferSize = sizeof(USER_MODALS_INFO_3); 3823 break; 3824 3825 default: 3826 TRACE("Invalid level %d is specified\n", level); 3827 ApiStatus = ERROR_INVALID_LEVEL; 3828 goto done; 3829 } 3830 3831 3832 ApiStatus = NetApiBufferAllocate(BufferSize, 3833 (LPVOID *)bufptr); 3834 if (ApiStatus != NERR_Success) 3835 { 3836 WARN("NetApiBufferAllocate() failed\n"); 3837 goto done; 3838 } 3839 3840 switch (level) 3841 { 3842 case 0: 3843 umi0 = (PUSER_MODALS_INFO_0)*bufptr; 3844 3845 umi0->usrmod0_min_passwd_len = PasswordInfo->MinPasswordLength; 3846 umi0->usrmod0_max_passwd_age = (ULONG)(-PasswordInfo->MaxPasswordAge.QuadPart / 10000000); 3847 umi0->usrmod0_min_passwd_age = 3848 DeltaTimeToSeconds(PasswordInfo->MinPasswordAge); 3849 umi0->usrmod0_force_logoff = 3850 DeltaTimeToSeconds(LogoffInfo->ForceLogoff); 3851 umi0->usrmod0_password_hist_len = PasswordInfo->PasswordHistoryLength; 3852 break; 3853 3854 case 1: 3855 umi1 = (PUSER_MODALS_INFO_1)*bufptr; 3856 3857 switch (ServerRoleInfo->DomainServerRole) 3858 { 3859 case DomainServerRolePrimary: 3860 umi1->usrmod1_role = UAS_ROLE_PRIMARY; 3861 break; 3862 3863 case DomainServerRoleBackup: 3864 umi1->usrmod1_role = UAS_ROLE_BACKUP; 3865 break; 3866 3867 default: 3868 ApiStatus = NERR_InternalError; 3869 goto done; 3870 } 3871 3872 umi1->usrmod1_primary = (LPWSTR)(*bufptr + sizeof(USER_MODALS_INFO_1)); 3873 RtlCopyMemory(umi1->usrmod1_primary, 3874 ReplicationInfo->ReplicaSourceNodeName.Buffer, 3875 ReplicationInfo->ReplicaSourceNodeName.Length); 3876 umi1->usrmod1_primary[ReplicationInfo->ReplicaSourceNodeName.Length / sizeof(WCHAR)] = UNICODE_NULL; 3877 break; 3878 3879 case 2: 3880 umi2 = (PUSER_MODALS_INFO_2)*bufptr; 3881 3882 umi2->usrmod2_domain_name = (LPWSTR)(*bufptr + sizeof(USER_MODALS_INFO_2)); 3883 RtlCopyMemory(umi2->usrmod2_domain_name, 3884 NameInfo->DomainName.Buffer, 3885 NameInfo->DomainName.Length); 3886 umi2->usrmod2_domain_name[NameInfo->DomainName.Length / sizeof(WCHAR)] = UNICODE_NULL; 3887 3888 umi2->usrmod2_domain_id = *bufptr + 3889 sizeof(USER_MODALS_INFO_2) + 3890 NameInfo->DomainName.Length + sizeof(WCHAR); 3891 RtlCopyMemory(umi2->usrmod2_domain_id, 3892 DomainSid, 3893 RtlLengthSid(DomainSid)); 3894 break; 3895 3896 case 3: 3897 umi3 = (PUSER_MODALS_INFO_3)*bufptr; 3898 umi3->usrmod3_lockout_duration = 3899 DeltaTimeToSeconds(LockoutInfo->LockoutDuration); 3900 umi3->usrmod3_lockout_observation_window = 3901 DeltaTimeToSeconds(LockoutInfo->LockoutObservationWindow ); 3902 umi3->usrmod3_lockout_threshold = LockoutInfo->LockoutThreshold; 3903 break; 3904 } 3905 3906 done: 3907 if (LockoutInfo != NULL) 3908 SamFreeMemory(LockoutInfo); 3909 3910 if (NameInfo != NULL) 3911 SamFreeMemory(NameInfo); 3912 3913 if (ReplicationInfo != NULL) 3914 SamFreeMemory(ReplicationInfo); 3915 3916 if (ServerRoleInfo != NULL) 3917 SamFreeMemory(ServerRoleInfo); 3918 3919 if (LogoffInfo != NULL) 3920 SamFreeMemory(LogoffInfo); 3921 3922 if (PasswordInfo != NULL) 3923 SamFreeMemory(PasswordInfo); 3924 3925 if (DomainSid != NULL) 3926 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid); 3927 3928 if (DomainHandle != NULL) 3929 SamCloseHandle(DomainHandle); 3930 3931 if (ServerHandle != NULL) 3932 SamCloseHandle(ServerHandle); 3933 3934 return ApiStatus; 3935 } 3936 3937 3938 /****************************************************************************** 3939 * NetUserModalsSet (NETAPI32.@) 3940 */ 3941 NET_API_STATUS 3942 WINAPI 3943 NetUserModalsSet(IN LPCWSTR servername, 3944 IN DWORD level, 3945 IN LPBYTE buf, 3946 OUT LPDWORD parm_err) 3947 { 3948 FIXME("(%s %d %p %p)\n", debugstr_w(servername), level, buf, parm_err); 3949 return ERROR_ACCESS_DENIED; 3950 } 3951 3952 3953 /****************************************************************************** 3954 * NetUserSetGroups (NETAPI32.@) 3955 */ 3956 NET_API_STATUS 3957 WINAPI 3958 NetUserSetGroups(LPCWSTR servername, 3959 LPCWSTR username, 3960 DWORD level, 3961 LPBYTE buf, 3962 DWORD num_entries) 3963 { 3964 FIXME("(%s %s %lu %p %lu)\n", 3965 debugstr_w(servername), debugstr_w(username), level, buf, num_entries); 3966 return ERROR_ACCESS_DENIED; 3967 } 3968 3969 3970 /****************************************************************************** 3971 * NetUserSetInfo (NETAPI32.@) 3972 */ 3973 NET_API_STATUS 3974 WINAPI 3975 NetUserSetInfo(LPCWSTR servername, 3976 LPCWSTR username, 3977 DWORD level, 3978 LPBYTE buf, 3979 LPDWORD parm_err) 3980 { 3981 UNICODE_STRING ServerName; 3982 UNICODE_STRING UserName; 3983 SAM_HANDLE ServerHandle = NULL; 3984 SAM_HANDLE AccountDomainHandle = NULL; 3985 SAM_HANDLE UserHandle = NULL; 3986 NET_API_STATUS ApiStatus = NERR_Success; 3987 NTSTATUS Status = STATUS_SUCCESS; 3988 3989 TRACE("(%s %s %lu %p %p)\n", 3990 debugstr_w(servername), debugstr_w(username), level, buf, parm_err); 3991 3992 if (parm_err != NULL) 3993 *parm_err = PARM_ERROR_NONE; 3994 3995 /* Check the info level */ 3996 switch (level) 3997 { 3998 case 0: 3999 case 1: 4000 case 2: 4001 case 3: 4002 case 4: 4003 // case 21: 4004 case 22: 4005 case 1003: 4006 // case 1005: 4007 case 1006: 4008 case 1007: 4009 case 1008: 4010 case 1009: 4011 // case 1010: 4012 case 1011: 4013 case 1012: 4014 case 1013: 4015 case 1014: 4016 case 1017: 4017 case 1018: 4018 case 1020: 4019 case 1024: 4020 case 1025: 4021 case 1051: 4022 case 1052: 4023 case 1053: 4024 break; 4025 4026 default: 4027 return ERROR_INVALID_LEVEL; 4028 } 4029 4030 if (servername != NULL) 4031 RtlInitUnicodeString(&ServerName, servername); 4032 4033 RtlInitUnicodeString(&UserName, username); 4034 4035 /* Connect to the SAM Server */ 4036 Status = SamConnect((servername != NULL) ? &ServerName : NULL, 4037 &ServerHandle, 4038 SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, 4039 NULL); 4040 if (!NT_SUCCESS(Status)) 4041 { 4042 ERR("SamConnect failed (Status %08lx)\n", Status); 4043 ApiStatus = NetpNtStatusToApiStatus(Status); 4044 goto done; 4045 } 4046 4047 /* Open the Account Domain */ 4048 Status = OpenAccountDomain(ServerHandle, 4049 (servername != NULL) ? &ServerName : NULL, 4050 DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP | DOMAIN_READ_PASSWORD_PARAMETERS, 4051 &AccountDomainHandle); 4052 if (!NT_SUCCESS(Status)) 4053 { 4054 ERR("OpenAccountDomain failed (Status %08lx)\n", Status); 4055 ApiStatus = NetpNtStatusToApiStatus(Status); 4056 goto done; 4057 } 4058 4059 /* Open the User Account */ 4060 ApiStatus = OpenUserByName(AccountDomainHandle, 4061 &UserName, 4062 USER_ALL_ACCESS, 4063 &UserHandle); 4064 if (ApiStatus != NERR_Success) 4065 { 4066 ERR("OpenUserByName(%wZ) failed (ApiStatus %lu)\n", &UserName, ApiStatus); 4067 goto done; 4068 } 4069 4070 /* Set user information */ 4071 ApiStatus = SetUserInfo(UserHandle, 4072 buf, 4073 level, 4074 parm_err); 4075 if (ApiStatus != NERR_Success) 4076 { 4077 ERR("SetUserInfo failed (Status %lu)\n", ApiStatus); 4078 } 4079 4080 done: 4081 if (UserHandle != NULL) 4082 SamCloseHandle(UserHandle); 4083 4084 if (AccountDomainHandle != NULL) 4085 SamCloseHandle(AccountDomainHandle); 4086 4087 if (ServerHandle != NULL) 4088 SamCloseHandle(ServerHandle); 4089 4090 return ApiStatus; 4091 } 4092 4093 /* EOF */ 4094