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