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