2 * Copyright 2002 Andriy Palamarchuk
4 * netapi32 user functions
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.
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.
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
23 * Implement NetUserGetGroups (WIP)
24 * Implement NetUserSetGroups
25 * NetUserGetLocalGroups does not support LG_INCLUDE_INDIRECT yet.
26 * Add missing information levels.
32 #include <ndk/kefuncs.h>
33 #include <ndk/obfuncs.h>
35 WINE_DEFAULT_DEBUG_CHANNEL(netapi32
);
37 typedef struct _ENUM_CONTEXT
42 SAM_HANDLE ServerHandle
;
43 SAM_HANDLE BuiltinDomainHandle
;
44 SAM_HANDLE AccountDomainHandle
;
45 PSID BuiltinDomainSid
;
46 PSID AccountDomainSid
;
48 SAM_ENUMERATE_HANDLE EnumerationContext
;
49 PSAM_RID_ENUMERATION Buffer
;
54 } ENUM_CONTEXT
, *PENUM_CONTEXT
;
56 LIST_ENTRY g_EnumContextListHead
;
57 CRITICAL_SECTION g_EnumContextListLock
;
58 LONG g_EnumContextHandle
= 0;
62 DeltaTimeToSeconds(LARGE_INTEGER DeltaTime
)
64 LARGE_INTEGER Seconds
;
66 if (DeltaTime
.QuadPart
== 0)
69 Seconds
.QuadPart
= -DeltaTime
.QuadPart
/ 10000000;
71 if (Seconds
.HighPart
!= 0)
74 return Seconds
.LowPart
;
80 GetAllowedWorldAce(IN PACL Acl
,
81 OUT PACCESS_ALLOWED_ACE
*Ace
)
83 SID_IDENTIFIER_AUTHORITY WorldAuthority
= {SECURITY_WORLD_SID_AUTHORITY
};
84 ULONG WorldSid
[sizeof(SID
) / sizeof(ULONG
) + SID_MAX_SUB_AUTHORITIES
];
85 ACL_SIZE_INFORMATION AclSize
;
86 PVOID LocalAce
= NULL
;
92 RtlInitializeSid((PSID
)WorldSid
,
95 *(RtlSubAuthoritySid((PSID
)WorldSid
, 0)) = SECURITY_WORLD_RID
;
97 Status
= RtlQueryInformationAcl(Acl
,
101 if (!NT_SUCCESS(Status
))
104 for (i
= 0; i
< AclSize
.AceCount
; i
++)
106 Status
= RtlGetAce(Acl
, i
, &LocalAce
);
107 if (!NT_SUCCESS(Status
))
110 if (((PACE_HEADER
)LocalAce
)->AceType
!= ACCESS_ALLOWED_ACE_TYPE
)
113 if (RtlEqualSid((PSID
)WorldSid
,
114 (PSID
)&((PACCESS_ALLOWED_ACE
)LocalAce
)->SidStart
))
116 *Ace
= (PACCESS_ALLOWED_ACE
)LocalAce
;
117 return STATUS_SUCCESS
;
121 return STATUS_SUCCESS
;
127 GetAccountFlags(ULONG AccountControl
,
130 PACCESS_ALLOWED_ACE Ace
= NULL
;
131 ULONG Flags
= UF_SCRIPT
;
136 Status
= GetAllowedWorldAce(Dacl
, &Ace
);
137 if (NT_SUCCESS(Status
))
141 Flags
|= UF_PASSWD_CANT_CHANGE
;
143 else if ((Ace
->Mask
& USER_CHANGE_PASSWORD
) == 0)
145 Flags
|= UF_PASSWD_CANT_CHANGE
;
150 if (AccountControl
& USER_ACCOUNT_DISABLED
)
151 Flags
|= UF_ACCOUNTDISABLE
;
153 if (AccountControl
& USER_HOME_DIRECTORY_REQUIRED
)
154 Flags
|= UF_HOMEDIR_REQUIRED
;
156 if (AccountControl
& USER_PASSWORD_NOT_REQUIRED
)
157 Flags
|= UF_PASSWD_NOTREQD
;
159 if (AccountControl
& USER_ACCOUNT_AUTO_LOCKED
)
162 if (AccountControl
& USER_DONT_EXPIRE_PASSWORD
)
163 Flags
|= UF_DONT_EXPIRE_PASSWD
;
166 if (AccountControl & USER_ENCRYPTED_TEXT_PASSWORD_ALLOWED)
167 Flags |= UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED;
169 if (AccountControl & USER_SMARTCARD_REQUIRED)
170 Flags |= UF_SMARTCARD_REQUIRED;
172 if (AccountControl & USER_TRUSTED_FOR_DELEGATION)
173 Flags |= UF_TRUSTED_FOR_DELEGATION;
175 if (AccountControl & USER_NOT_DELEGATED)
176 Flags |= UF_NOT_DELEGATED;
178 if (AccountControl & USER_USE_DES_KEY_ONLY)
179 Flags |= UF_USE_DES_KEY_ONLY;
181 if (AccountControl & USER_DONT_REQUIRE_PREAUTH)
182 Flags |= UF_DONT_REQUIRE_PREAUTH;
184 if (AccountControl & USER_PASSWORD_EXPIRED)
185 Flags |= UF_PASSWORD_EXPIRED;
188 /* Set account type flags */
189 if (AccountControl
& USER_TEMP_DUPLICATE_ACCOUNT
)
190 Flags
|= UF_TEMP_DUPLICATE_ACCOUNT
;
191 else if (AccountControl
& USER_NORMAL_ACCOUNT
)
192 Flags
|= UF_NORMAL_ACCOUNT
;
193 else if (AccountControl
& USER_INTERDOMAIN_TRUST_ACCOUNT
)
194 Flags
|= UF_INTERDOMAIN_TRUST_ACCOUNT
;
195 else if (AccountControl
& USER_WORKSTATION_TRUST_ACCOUNT
)
196 Flags
|= UF_WORKSTATION_TRUST_ACCOUNT
;
197 else if (AccountControl
& USER_SERVER_TRUST_ACCOUNT
)
198 Flags
|= UF_SERVER_TRUST_ACCOUNT
;
206 GetAccountControl(ULONG Flags
)
208 ULONG AccountControl
= 0;
210 if (Flags
& UF_ACCOUNTDISABLE
)
211 AccountControl
|= USER_ACCOUNT_DISABLED
;
213 if (Flags
& UF_HOMEDIR_REQUIRED
)
214 AccountControl
|= USER_HOME_DIRECTORY_REQUIRED
;
216 if (Flags
& UF_PASSWD_NOTREQD
)
217 AccountControl
|= USER_PASSWORD_NOT_REQUIRED
;
219 if (Flags
& UF_LOCKOUT
)
220 AccountControl
|= USER_ACCOUNT_AUTO_LOCKED
;
222 if (Flags
& UF_DONT_EXPIRE_PASSWD
)
223 AccountControl
|= USER_DONT_EXPIRE_PASSWORD
;
225 /* Set account type flags */
226 if (Flags
& UF_TEMP_DUPLICATE_ACCOUNT
)
227 AccountControl
|= USER_TEMP_DUPLICATE_ACCOUNT
;
228 else if (Flags
& UF_NORMAL_ACCOUNT
)
229 AccountControl
|= USER_NORMAL_ACCOUNT
;
230 else if (Flags
& UF_INTERDOMAIN_TRUST_ACCOUNT
)
231 AccountControl
|= USER_INTERDOMAIN_TRUST_ACCOUNT
;
232 else if (Flags
& UF_WORKSTATION_TRUST_ACCOUNT
)
233 AccountControl
|= USER_WORKSTATION_TRUST_ACCOUNT
;
234 else if (Flags
& UF_SERVER_TRUST_ACCOUNT
)
235 AccountControl
|= USER_SERVER_TRUST_ACCOUNT
;
237 return AccountControl
;
243 GetPasswordAge(IN PLARGE_INTEGER PasswordLastSet
)
245 LARGE_INTEGER SystemTime
;
246 ULONG SystemSecondsSince1970
;
247 ULONG PasswordSecondsSince1970
;
250 Status
= NtQuerySystemTime(&SystemTime
);
251 if (!NT_SUCCESS(Status
))
254 RtlTimeToSecondsSince1970(&SystemTime
, &SystemSecondsSince1970
);
255 RtlTimeToSecondsSince1970(PasswordLastSet
, &PasswordSecondsSince1970
);
257 return SystemSecondsSince1970
- PasswordSecondsSince1970
;
263 ChangeUserDacl(IN PACL Dacl
,
266 PACCESS_ALLOWED_ACE Ace
= NULL
;
272 Status
= GetAllowedWorldAce(Dacl
, &Ace
);
273 if (!NT_SUCCESS(Status
))
276 if (Flags
& UF_PASSWD_CANT_CHANGE
)
277 Ace
->Mask
&= ~USER_CHANGE_PASSWORD
;
279 Ace
->Mask
|= USER_CHANGE_PASSWORD
;
285 GetUserDacl(IN SAM_HANDLE UserHandle
,
288 PSECURITY_DESCRIPTOR SecurityDescriptor
= NULL
;
293 ACL_SIZE_INFORMATION AclSize
;
294 NET_API_STATUS ApiStatus
;
297 TRACE("(%p %p)\n", UserHandle
, Dacl
);
301 Status
= SamQuerySecurityObject(UserHandle
,
302 DACL_SECURITY_INFORMATION
,
303 &SecurityDescriptor
);
304 if (!NT_SUCCESS(Status
))
306 TRACE("SamQuerySecurityObject() failed (Status 0x%08lx)\n", Status
);
307 ApiStatus
= NetpNtStatusToApiStatus(Status
);
311 Status
= RtlGetDaclSecurityDescriptor(SecurityDescriptor
,
315 if (!NT_SUCCESS(Status
))
317 TRACE("RtlGetDaclSecurityDescriptor() failed (Status 0x%08lx)\n", Status
);
318 ApiStatus
= NERR_InternalError
;
322 if (Present
== FALSE
)
324 TRACE("No DACL present\n");
325 ApiStatus
= NERR_Success
;
329 Status
= RtlQueryInformationAcl(SamDacl
,
333 if (!NT_SUCCESS(Status
))
335 TRACE("RtlQueryInformationAcl() failed (Status 0x%08lx)\n", Status
);
336 ApiStatus
= NERR_InternalError
;
340 LocalDacl
= HeapAlloc(GetProcessHeap(), 0, AclSize
.AclBytesInUse
);
341 if (LocalDacl
== NULL
)
343 TRACE("Memory allocation failed\n");
344 ApiStatus
= ERROR_NOT_ENOUGH_MEMORY
;
348 RtlCopyMemory(LocalDacl
, SamDacl
, AclSize
.AclBytesInUse
);
352 ApiStatus
= NERR_Success
;
355 if (SecurityDescriptor
!= NULL
)
356 SamFreeMemory(SecurityDescriptor
);
358 TRACE("done (ApiStatus: 0x%08lx)\n", ApiStatus
);
366 FreeUserInfo(PUSER_ALL_INFORMATION UserInfo
)
368 if (UserInfo
->UserName
.Buffer
!= NULL
)
369 SamFreeMemory(UserInfo
->UserName
.Buffer
);
371 if (UserInfo
->FullName
.Buffer
!= NULL
)
372 SamFreeMemory(UserInfo
->FullName
.Buffer
);
374 if (UserInfo
->HomeDirectory
.Buffer
!= NULL
)
375 SamFreeMemory(UserInfo
->HomeDirectory
.Buffer
);
377 if (UserInfo
->HomeDirectoryDrive
.Buffer
!= NULL
)
378 SamFreeMemory(UserInfo
->HomeDirectoryDrive
.Buffer
);
380 if (UserInfo
->ScriptPath
.Buffer
!= NULL
)
381 SamFreeMemory(UserInfo
->ScriptPath
.Buffer
);
383 if (UserInfo
->ProfilePath
.Buffer
!= NULL
)
384 SamFreeMemory(UserInfo
->ProfilePath
.Buffer
);
386 if (UserInfo
->AdminComment
.Buffer
!= NULL
)
387 SamFreeMemory(UserInfo
->AdminComment
.Buffer
);
389 if (UserInfo
->WorkStations
.Buffer
!= NULL
)
390 SamFreeMemory(UserInfo
->WorkStations
.Buffer
);
392 if (UserInfo
->UserComment
.Buffer
!= NULL
)
393 SamFreeMemory(UserInfo
->UserComment
.Buffer
);
395 if (UserInfo
->Parameters
.Buffer
!= NULL
)
396 SamFreeMemory(UserInfo
->Parameters
.Buffer
);
398 if (UserInfo
->PrivateData
.Buffer
!= NULL
)
399 SamFreeMemory(UserInfo
->PrivateData
.Buffer
);
401 if (UserInfo
->LogonHours
.LogonHours
!= NULL
)
402 SamFreeMemory(UserInfo
->LogonHours
.LogonHours
);
404 SamFreeMemory(UserInfo
);
411 _In_ SAM_HANDLE BuiltinDomainHandle
,
412 _In_ SAM_HANDLE UserHandle
,
413 _In_ PSID AccountDomainSid
,
414 _In_ ULONG RelativeId
,
416 _Out_ PDWORD AuthFlags
)
418 PGROUP_MEMBERSHIP GroupMembership
= NULL
;
419 ULONG GroupCount
, SidCount
, AliasCount
, i
;
420 PSID
*SidArray
= NULL
;
421 PULONG AliasArray
= NULL
;
422 BOOL bAdmin
= FALSE
, bUser
= FALSE
;
423 NET_API_STATUS ApiStatus
= NERR_Success
;
426 FIXME("GetUserPrivileges(%p)\n", UserHandle
);
428 /* Get the users group memberships */
429 Status
= SamGetGroupsForUser(UserHandle
,
432 if (!NT_SUCCESS(Status
))
434 ERR("SamGetGroupsForUser() failed (Status 0x%08lx)\n", Status
);
435 ApiStatus
= NetpNtStatusToApiStatus(Status
);
439 /* Allocate the SID array */
440 ApiStatus
= NetApiBufferAllocate((GroupCount
+ 1) * sizeof(PSID
),
442 if (ApiStatus
!= NERR_Success
)
447 /* Add the user to the SID array */
449 ApiStatus
= BuildSidFromSidAndRid(AccountDomainSid
,
452 if (ApiStatus
!= NERR_Success
)
459 /* Add the groups to the SID array */
460 for (i
= 0; i
< GroupCount
; i
++)
462 ApiStatus
= BuildSidFromSidAndRid(AccountDomainSid
,
463 GroupMembership
[i
].RelativeId
,
465 if (ApiStatus
!= NERR_Success
)
473 /* Get aliases for the user and his groups */
474 Status
= SamGetAliasMembership(BuiltinDomainHandle
,
479 if (!NT_SUCCESS(Status
))
481 ERR("SamGetAliasMembership() failed (Status 0x%08lx)\n", Status
);
482 ApiStatus
= NetpNtStatusToApiStatus(Status
);
488 /* Set the AuthFlags */
489 for (i
= 0; i
< AliasCount
; i
++)
491 switch (AliasArray
[i
])
493 case DOMAIN_ALIAS_RID_ADMINS
:
497 case DOMAIN_ALIAS_RID_USERS
:
501 case DOMAIN_ALIAS_RID_ACCOUNT_OPS
:
502 *AuthFlags
|= AF_OP_ACCOUNTS
;
505 case DOMAIN_ALIAS_RID_SYSTEM_OPS
:
506 *AuthFlags
|= AF_OP_SERVER
;
509 case DOMAIN_ALIAS_RID_PRINT_OPS
:
510 *AuthFlags
|= AF_OP_PRINT
;
515 /* Set the prvileges */
518 *Priv
= USER_PRIV_ADMIN
;
522 *Priv
= USER_PRIV_USER
;
526 *Priv
= USER_PRIV_GUEST
;
530 if (AliasArray
!= NULL
)
531 SamFreeMemory(AliasArray
);
533 if (SidArray
!= NULL
)
535 for (i
= 0; i
< SidCount
; i
++)
536 NetApiBufferFree(SidArray
[i
]);
538 NetApiBufferFree(SidArray
);
541 if (GroupMembership
!= NULL
)
542 SamFreeMemory(GroupMembership
);
551 _In_ SAM_HANDLE BuiltinDomainHandle
,
552 _In_ SAM_HANDLE UserHandle
,
553 _In_ PSID AccountDomainSid
,
554 _In_ ULONG RelativeId
,
556 _Out_ LPVOID
*Buffer
)
558 UNICODE_STRING LogonServer
= RTL_CONSTANT_STRING(L
"\\\\*");
559 PUSER_ALL_INFORMATION UserInfo
= NULL
;
560 LPVOID LocalBuffer
= NULL
;
562 DWORD Priv
= 0, AuthFlags
= 0;
563 PUSER_INFO_0 UserInfo0
;
564 PUSER_INFO_1 UserInfo1
;
565 PUSER_INFO_2 UserInfo2
;
566 PUSER_INFO_3 UserInfo3
;
567 PUSER_INFO_4 UserInfo4
;
568 PUSER_INFO_10 UserInfo10
;
569 PUSER_INFO_11 UserInfo11
;
570 PUSER_INFO_20 UserInfo20
;
571 PUSER_INFO_23 UserInfo23
;
575 NET_API_STATUS ApiStatus
= NERR_Success
;
579 Status
= SamQueryInformationUser(UserHandle
,
582 if (!NT_SUCCESS(Status
))
584 ERR("SamQueryInformationUser failed (Status %08lx)\n", Status
);
585 ApiStatus
= NetpNtStatusToApiStatus(Status
);
589 if ((level
== 1) || (level
== 2) || (level
== 3) ||
590 (level
== 4) || (level
== 20) || (level
== 23))
592 ApiStatus
= GetUserDacl(UserHandle
, &Dacl
);
593 if (ApiStatus
!= NERR_Success
)
597 if ((level
== 1) || (level
== 2) || (level
== 3) ||
598 (level
== 4) || (level
== 11))
600 ApiStatus
= GetUserPrivileges(BuiltinDomainHandle
,
606 if (ApiStatus
!= NERR_Success
)
613 Size
= sizeof(USER_INFO_0
) +
614 UserInfo
->UserName
.Length
+ sizeof(WCHAR
);
618 Size
= sizeof(USER_INFO_1
) +
619 UserInfo
->UserName
.Length
+ sizeof(WCHAR
) +
620 UserInfo
->HomeDirectory
.Length
+ sizeof(WCHAR
) +
621 UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
) +
622 UserInfo
->ScriptPath
.Length
+ sizeof(WCHAR
);
626 Size
= sizeof(USER_INFO_2
) +
627 UserInfo
->UserName
.Length
+ sizeof(WCHAR
) +
628 UserInfo
->HomeDirectory
.Length
+ sizeof(WCHAR
) +
629 UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
) +
630 UserInfo
->ScriptPath
.Length
+ sizeof(WCHAR
) +
631 UserInfo
->FullName
.Length
+ sizeof(WCHAR
) +
632 UserInfo
->UserComment
.Length
+ sizeof(WCHAR
) +
633 UserInfo
->Parameters
.Length
+ sizeof(WCHAR
) +
634 UserInfo
->WorkStations
.Length
+ sizeof(WCHAR
) +
635 LogonServer
.Length
+ sizeof(WCHAR
);
637 if (UserInfo
->LogonHours
.UnitsPerWeek
> 0)
638 Size
+= (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8;
642 Size
= sizeof(USER_INFO_3
) +
643 UserInfo
->UserName
.Length
+ sizeof(WCHAR
) +
644 UserInfo
->HomeDirectory
.Length
+ sizeof(WCHAR
) +
645 UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
) +
646 UserInfo
->ScriptPath
.Length
+ sizeof(WCHAR
) +
647 UserInfo
->FullName
.Length
+ sizeof(WCHAR
) +
648 UserInfo
->UserComment
.Length
+ sizeof(WCHAR
) +
649 UserInfo
->Parameters
.Length
+ sizeof(WCHAR
) +
650 UserInfo
->WorkStations
.Length
+ sizeof(WCHAR
) +
651 LogonServer
.Length
+ sizeof(WCHAR
) +
652 UserInfo
->ProfilePath
.Length
+ sizeof(WCHAR
) +
653 UserInfo
->HomeDirectoryDrive
.Length
+ sizeof(WCHAR
);
655 if (UserInfo
->LogonHours
.UnitsPerWeek
> 0)
656 Size
+= (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8;
660 Size
= sizeof(USER_INFO_4
) +
661 UserInfo
->UserName
.Length
+ sizeof(WCHAR
) +
662 UserInfo
->HomeDirectory
.Length
+ sizeof(WCHAR
) +
663 UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
) +
664 UserInfo
->ScriptPath
.Length
+ sizeof(WCHAR
) +
665 UserInfo
->FullName
.Length
+ sizeof(WCHAR
) +
666 UserInfo
->UserComment
.Length
+ sizeof(WCHAR
) +
667 UserInfo
->Parameters
.Length
+ sizeof(WCHAR
) +
668 UserInfo
->WorkStations
.Length
+ sizeof(WCHAR
) +
669 LogonServer
.Length
+ sizeof(WCHAR
) +
670 UserInfo
->ProfilePath
.Length
+ sizeof(WCHAR
) +
671 UserInfo
->HomeDirectoryDrive
.Length
+ sizeof(WCHAR
);
673 if (UserInfo
->LogonHours
.UnitsPerWeek
> 0)
674 Size
+= (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8;
676 Size
+= RtlLengthSid(AccountDomainSid
) + sizeof(ULONG
);
680 Size
= sizeof(USER_INFO_10
) +
681 UserInfo
->UserName
.Length
+ sizeof(WCHAR
) +
682 UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
) +
683 UserInfo
->UserComment
.Length
+ sizeof(WCHAR
) +
684 UserInfo
->FullName
.Length
+ sizeof(WCHAR
);
688 Size
= sizeof(USER_INFO_11
) +
689 UserInfo
->UserName
.Length
+ sizeof(WCHAR
) +
690 UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
) +
691 UserInfo
->UserComment
.Length
+ sizeof(WCHAR
) +
692 UserInfo
->FullName
.Length
+ sizeof(WCHAR
) +
693 UserInfo
->HomeDirectory
.Length
+ sizeof(WCHAR
) +
694 UserInfo
->Parameters
.Length
+ sizeof(WCHAR
) +
695 LogonServer
.Length
+ sizeof(WCHAR
) +
696 UserInfo
->WorkStations
.Length
+ sizeof(WCHAR
);
698 if (UserInfo
->LogonHours
.UnitsPerWeek
> 0)
699 Size
+= (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8;
703 Size
= sizeof(USER_INFO_20
) +
704 UserInfo
->UserName
.Length
+ sizeof(WCHAR
) +
705 UserInfo
->FullName
.Length
+ sizeof(WCHAR
) +
706 UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
);
710 Size
= sizeof(USER_INFO_23
) +
711 UserInfo
->UserName
.Length
+ sizeof(WCHAR
) +
712 UserInfo
->FullName
.Length
+ sizeof(WCHAR
) +
713 UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
);
715 Size
+= RtlLengthSid(AccountDomainSid
) + sizeof(ULONG
);
719 ApiStatus
= ERROR_INVALID_LEVEL
;
723 ApiStatus
= NetApiBufferAllocate(Size
, &LocalBuffer
);
724 if (ApiStatus
!= NERR_Success
)
727 ZeroMemory(LocalBuffer
, Size
);
732 UserInfo0
= (PUSER_INFO_0
)LocalBuffer
;
734 Ptr
= (LPWSTR
)((ULONG_PTR
)UserInfo0
+ sizeof(USER_INFO_0
));
736 UserInfo0
->usri0_name
= Ptr
;
738 memcpy(UserInfo0
->usri0_name
,
739 UserInfo
->UserName
.Buffer
,
740 UserInfo
->UserName
.Length
);
741 UserInfo0
->usri0_name
[UserInfo
->UserName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
745 UserInfo1
= (PUSER_INFO_1
)LocalBuffer
;
747 Ptr
= (LPWSTR
)((ULONG_PTR
)UserInfo1
+ sizeof(USER_INFO_1
));
749 UserInfo1
->usri1_name
= Ptr
;
751 memcpy(UserInfo1
->usri1_name
,
752 UserInfo
->UserName
.Buffer
,
753 UserInfo
->UserName
.Length
);
754 UserInfo1
->usri1_name
[UserInfo
->UserName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
756 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserName
.Length
+ sizeof(WCHAR
));
758 UserInfo1
->usri1_password
= NULL
;
759 UserInfo1
->usri1_password_age
= GetPasswordAge(&UserInfo
->PasswordLastSet
);
761 UserInfo1
->usri1_priv
= Priv
;
763 UserInfo1
->usri1_home_dir
= Ptr
;
764 memcpy(UserInfo1
->usri1_home_dir
,
765 UserInfo
->HomeDirectory
.Buffer
,
766 UserInfo
->HomeDirectory
.Length
);
767 UserInfo1
->usri1_home_dir
[UserInfo
->HomeDirectory
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
768 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->HomeDirectory
.Length
+ sizeof(WCHAR
));
770 UserInfo1
->usri1_comment
= Ptr
;
771 memcpy(UserInfo1
->usri1_comment
,
772 UserInfo
->AdminComment
.Buffer
,
773 UserInfo
->AdminComment
.Length
);
774 UserInfo1
->usri1_comment
[UserInfo
->AdminComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
775 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
));
777 UserInfo1
->usri1_flags
= GetAccountFlags(UserInfo
->UserAccountControl
,
780 UserInfo1
->usri1_script_path
= Ptr
;
781 memcpy(UserInfo1
->usri1_script_path
,
782 UserInfo
->ScriptPath
.Buffer
,
783 UserInfo
->ScriptPath
.Length
);
784 UserInfo1
->usri1_script_path
[UserInfo
->ScriptPath
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
788 UserInfo2
= (PUSER_INFO_2
)LocalBuffer
;
790 Ptr
= (LPWSTR
)((ULONG_PTR
)UserInfo2
+ sizeof(USER_INFO_2
));
792 UserInfo2
->usri2_name
= Ptr
;
794 memcpy(UserInfo2
->usri2_name
,
795 UserInfo
->UserName
.Buffer
,
796 UserInfo
->UserName
.Length
);
797 UserInfo2
->usri2_name
[UserInfo
->UserName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
799 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserName
.Length
+ sizeof(WCHAR
));
801 UserInfo2
->usri2_password
= NULL
;
802 UserInfo2
->usri2_password_age
= GetPasswordAge(&UserInfo
->PasswordLastSet
);
804 UserInfo2
->usri2_priv
= Priv
;
806 UserInfo2
->usri2_home_dir
= Ptr
;
807 memcpy(UserInfo2
->usri2_home_dir
,
808 UserInfo
->HomeDirectory
.Buffer
,
809 UserInfo
->HomeDirectory
.Length
);
810 UserInfo2
->usri2_home_dir
[UserInfo
->HomeDirectory
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
811 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->HomeDirectory
.Length
+ sizeof(WCHAR
));
813 UserInfo2
->usri2_comment
= Ptr
;
814 memcpy(UserInfo2
->usri2_comment
,
815 UserInfo
->AdminComment
.Buffer
,
816 UserInfo
->AdminComment
.Length
);
817 UserInfo2
->usri2_comment
[UserInfo
->AdminComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
818 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
));
820 UserInfo2
->usri2_flags
= GetAccountFlags(UserInfo
->UserAccountControl
,
823 UserInfo2
->usri2_script_path
= Ptr
;
824 memcpy(UserInfo2
->usri2_script_path
,
825 UserInfo
->ScriptPath
.Buffer
,
826 UserInfo
->ScriptPath
.Length
);
827 UserInfo2
->usri2_script_path
[UserInfo
->ScriptPath
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
828 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->ScriptPath
.Length
+ sizeof(WCHAR
));
830 UserInfo2
->usri2_auth_flags
= AuthFlags
;
832 UserInfo2
->usri2_full_name
= Ptr
;
833 memcpy(UserInfo2
->usri2_full_name
,
834 UserInfo
->FullName
.Buffer
,
835 UserInfo
->FullName
.Length
);
836 UserInfo2
->usri2_full_name
[UserInfo
->FullName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
837 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->FullName
.Length
+ sizeof(WCHAR
));
839 UserInfo2
->usri2_usr_comment
= Ptr
;
840 memcpy(UserInfo2
->usri2_usr_comment
,
841 UserInfo
->UserComment
.Buffer
,
842 UserInfo
->UserComment
.Length
);
843 UserInfo2
->usri2_usr_comment
[UserInfo
->UserComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
844 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserComment
.Length
+ sizeof(WCHAR
));
846 UserInfo2
->usri2_parms
= Ptr
;
847 memcpy(UserInfo2
->usri2_parms
,
848 UserInfo
->Parameters
.Buffer
,
849 UserInfo
->Parameters
.Length
);
850 UserInfo2
->usri2_parms
[UserInfo
->Parameters
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
851 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->Parameters
.Length
+ sizeof(WCHAR
));
853 UserInfo2
->usri2_workstations
= Ptr
;
854 memcpy(UserInfo2
->usri2_workstations
,
855 UserInfo
->WorkStations
.Buffer
,
856 UserInfo
->WorkStations
.Length
);
857 UserInfo2
->usri2_workstations
[UserInfo
->WorkStations
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
858 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->WorkStations
.Length
+ sizeof(WCHAR
));
860 if (UserInfo
->LastLogon
.QuadPart
== 0)
861 UserInfo2
->usri2_last_logon
= 0;
863 RtlTimeToSecondsSince1970(&UserInfo
->LastLogon
,
864 &UserInfo2
->usri2_last_logon
);
866 if (UserInfo
->LastLogoff
.QuadPart
== 0)
867 UserInfo2
->usri2_last_logoff
= 0;
869 RtlTimeToSecondsSince1970(&UserInfo
->LastLogoff
,
870 &UserInfo2
->usri2_last_logoff
);
872 if (UserInfo
->AccountExpires
.QuadPart
== MAXLONGLONG
)
873 UserInfo2
->usri2_acct_expires
= TIMEQ_FOREVER
;
875 RtlTimeToSecondsSince1970(&UserInfo
->AccountExpires
,
876 &UserInfo2
->usri2_acct_expires
);
878 UserInfo2
->usri2_max_storage
= USER_MAXSTORAGE_UNLIMITED
;
879 UserInfo2
->usri2_units_per_week
= UserInfo
->LogonHours
.UnitsPerWeek
;
881 if (UserInfo
->LogonHours
.UnitsPerWeek
> 0)
883 UserInfo2
->usri2_logon_hours
= (PVOID
)Ptr
;
885 memcpy(UserInfo2
->usri2_logon_hours
,
886 UserInfo
->LogonHours
.LogonHours
,
887 (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8);
889 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8);
892 UserInfo2
->usri2_bad_pw_count
= UserInfo
->BadPasswordCount
;
893 UserInfo2
->usri2_num_logons
= UserInfo
->LogonCount
;
895 UserInfo2
->usri2_logon_server
= Ptr
;
896 memcpy(UserInfo2
->usri2_logon_server
,
899 UserInfo2
->usri2_logon_server
[LogonServer
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
900 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ LogonServer
.Length
+ sizeof(WCHAR
));
902 UserInfo2
->usri2_country_code
= UserInfo
->CountryCode
;
903 UserInfo2
->usri2_code_page
= UserInfo
->CodePage
;
907 UserInfo3
= (PUSER_INFO_3
)LocalBuffer
;
909 Ptr
= (LPWSTR
)((ULONG_PTR
)UserInfo3
+ sizeof(USER_INFO_3
));
911 UserInfo3
->usri3_name
= Ptr
;
913 memcpy(UserInfo3
->usri3_name
,
914 UserInfo
->UserName
.Buffer
,
915 UserInfo
->UserName
.Length
);
916 UserInfo3
->usri3_name
[UserInfo
->UserName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
918 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserName
.Length
+ sizeof(WCHAR
));
920 UserInfo3
->usri3_password
= NULL
;
921 UserInfo3
->usri3_password_age
= GetPasswordAge(&UserInfo
->PasswordLastSet
);
923 UserInfo3
->usri3_priv
= Priv
;
925 UserInfo3
->usri3_home_dir
= Ptr
;
926 memcpy(UserInfo3
->usri3_home_dir
,
927 UserInfo
->HomeDirectory
.Buffer
,
928 UserInfo
->HomeDirectory
.Length
);
929 UserInfo3
->usri3_home_dir
[UserInfo
->HomeDirectory
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
930 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->HomeDirectory
.Length
+ sizeof(WCHAR
));
932 UserInfo3
->usri3_comment
= Ptr
;
933 memcpy(UserInfo3
->usri3_comment
,
934 UserInfo
->AdminComment
.Buffer
,
935 UserInfo
->AdminComment
.Length
);
936 UserInfo3
->usri3_comment
[UserInfo
->AdminComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
937 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
));
939 UserInfo3
->usri3_flags
= GetAccountFlags(UserInfo
->UserAccountControl
,
942 UserInfo3
->usri3_script_path
= Ptr
;
943 memcpy(UserInfo3
->usri3_script_path
,
944 UserInfo
->ScriptPath
.Buffer
,
945 UserInfo
->ScriptPath
.Length
);
946 UserInfo3
->usri3_script_path
[UserInfo
->ScriptPath
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
947 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->ScriptPath
.Length
+ sizeof(WCHAR
));
949 UserInfo3
->usri3_auth_flags
= AuthFlags
;
951 UserInfo3
->usri3_full_name
= Ptr
;
952 memcpy(UserInfo3
->usri3_full_name
,
953 UserInfo
->FullName
.Buffer
,
954 UserInfo
->FullName
.Length
);
955 UserInfo3
->usri3_full_name
[UserInfo
->FullName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
956 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->FullName
.Length
+ sizeof(WCHAR
));
958 UserInfo3
->usri3_usr_comment
= Ptr
;
959 memcpy(UserInfo3
->usri3_usr_comment
,
960 UserInfo
->UserComment
.Buffer
,
961 UserInfo
->UserComment
.Length
);
962 UserInfo3
->usri3_usr_comment
[UserInfo
->UserComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
963 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserComment
.Length
+ sizeof(WCHAR
));
965 UserInfo3
->usri3_parms
= Ptr
;
966 memcpy(UserInfo3
->usri3_parms
,
967 UserInfo
->Parameters
.Buffer
,
968 UserInfo
->Parameters
.Length
);
969 UserInfo3
->usri3_parms
[UserInfo
->Parameters
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
970 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->Parameters
.Length
+ sizeof(WCHAR
));
972 UserInfo3
->usri3_workstations
= Ptr
;
973 memcpy(UserInfo3
->usri3_workstations
,
974 UserInfo
->WorkStations
.Buffer
,
975 UserInfo
->WorkStations
.Length
);
976 UserInfo3
->usri3_workstations
[UserInfo
->WorkStations
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
977 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->WorkStations
.Length
+ sizeof(WCHAR
));
979 if (UserInfo
->LastLogon
.QuadPart
== 0)
980 UserInfo3
->usri3_last_logon
= 0;
982 RtlTimeToSecondsSince1970(&UserInfo
->LastLogon
,
983 &UserInfo3
->usri3_last_logon
);
985 if (UserInfo
->LastLogoff
.QuadPart
== 0)
986 UserInfo3
->usri3_last_logoff
= 0;
988 RtlTimeToSecondsSince1970(&UserInfo
->LastLogoff
,
989 &UserInfo3
->usri3_last_logoff
);
991 if (UserInfo
->AccountExpires
.QuadPart
== MAXLONGLONG
)
992 UserInfo3
->usri3_acct_expires
= TIMEQ_FOREVER
;
994 RtlTimeToSecondsSince1970(&UserInfo
->AccountExpires
,
995 &UserInfo3
->usri3_acct_expires
);
997 UserInfo3
->usri3_max_storage
= USER_MAXSTORAGE_UNLIMITED
;
998 UserInfo3
->usri3_units_per_week
= UserInfo
->LogonHours
.UnitsPerWeek
;
1000 if (UserInfo
->LogonHours
.UnitsPerWeek
> 0)
1002 UserInfo3
->usri3_logon_hours
= (PVOID
)Ptr
;
1004 memcpy(UserInfo3
->usri3_logon_hours
,
1005 UserInfo
->LogonHours
.LogonHours
,
1006 (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8);
1008 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8);
1011 UserInfo3
->usri3_bad_pw_count
= UserInfo
->BadPasswordCount
;
1012 UserInfo3
->usri3_num_logons
= UserInfo
->LogonCount
;
1014 UserInfo3
->usri3_logon_server
= Ptr
;
1015 memcpy(UserInfo3
->usri3_logon_server
,
1017 LogonServer
.Length
);
1018 UserInfo3
->usri3_logon_server
[LogonServer
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1019 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ LogonServer
.Length
+ sizeof(WCHAR
));
1021 UserInfo3
->usri3_country_code
= UserInfo
->CountryCode
;
1022 UserInfo3
->usri3_code_page
= UserInfo
->CodePage
;
1023 UserInfo3
->usri3_user_id
= RelativeId
;
1024 UserInfo3
->usri3_primary_group_id
= UserInfo
->PrimaryGroupId
;
1026 UserInfo3
->usri3_profile
= Ptr
;
1027 memcpy(UserInfo3
->usri3_profile
,
1028 UserInfo
->ProfilePath
.Buffer
,
1029 UserInfo
->ProfilePath
.Length
);
1030 UserInfo3
->usri3_profile
[UserInfo
->ProfilePath
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1031 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->ProfilePath
.Length
+ sizeof(WCHAR
));
1033 UserInfo3
->usri3_home_dir_drive
= Ptr
;
1034 memcpy(UserInfo3
->usri3_home_dir_drive
,
1035 UserInfo
->HomeDirectoryDrive
.Buffer
,
1036 UserInfo
->HomeDirectoryDrive
.Length
);
1037 UserInfo3
->usri3_home_dir_drive
[UserInfo
->HomeDirectoryDrive
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1038 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->HomeDirectoryDrive
.Length
+ sizeof(WCHAR
));
1040 UserInfo3
->usri3_password_expired
= (UserInfo
->UserAccountControl
& USER_PASSWORD_EXPIRED
);
1044 UserInfo4
= (PUSER_INFO_4
)LocalBuffer
;
1046 Ptr
= (LPWSTR
)((ULONG_PTR
)UserInfo4
+ sizeof(USER_INFO_4
));
1048 UserInfo4
->usri4_name
= Ptr
;
1050 memcpy(UserInfo4
->usri4_name
,
1051 UserInfo
->UserName
.Buffer
,
1052 UserInfo
->UserName
.Length
);
1053 UserInfo4
->usri4_name
[UserInfo
->UserName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1055 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserName
.Length
+ sizeof(WCHAR
));
1057 UserInfo4
->usri4_password
= NULL
;
1058 UserInfo4
->usri4_password_age
= GetPasswordAge(&UserInfo
->PasswordLastSet
);
1060 UserInfo4
->usri4_priv
= Priv
;
1062 UserInfo4
->usri4_home_dir
= Ptr
;
1063 memcpy(UserInfo4
->usri4_home_dir
,
1064 UserInfo
->HomeDirectory
.Buffer
,
1065 UserInfo
->HomeDirectory
.Length
);
1066 UserInfo4
->usri4_home_dir
[UserInfo
->HomeDirectory
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1067 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->HomeDirectory
.Length
+ sizeof(WCHAR
));
1069 UserInfo4
->usri4_comment
= Ptr
;
1070 memcpy(UserInfo4
->usri4_comment
,
1071 UserInfo
->AdminComment
.Buffer
,
1072 UserInfo
->AdminComment
.Length
);
1073 UserInfo4
->usri4_comment
[UserInfo
->AdminComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1074 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
));
1076 UserInfo4
->usri4_flags
= GetAccountFlags(UserInfo
->UserAccountControl
,
1079 UserInfo4
->usri4_script_path
= Ptr
;
1080 memcpy(UserInfo4
->usri4_script_path
,
1081 UserInfo
->ScriptPath
.Buffer
,
1082 UserInfo
->ScriptPath
.Length
);
1083 UserInfo4
->usri4_script_path
[UserInfo
->ScriptPath
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1084 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->ScriptPath
.Length
+ sizeof(WCHAR
));
1086 UserInfo4
->usri4_auth_flags
= AuthFlags
;
1088 UserInfo4
->usri4_full_name
= Ptr
;
1089 memcpy(UserInfo4
->usri4_full_name
,
1090 UserInfo
->FullName
.Buffer
,
1091 UserInfo
->FullName
.Length
);
1092 UserInfo4
->usri4_full_name
[UserInfo
->FullName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1093 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->FullName
.Length
+ sizeof(WCHAR
));
1095 UserInfo4
->usri4_usr_comment
= Ptr
;
1096 memcpy(UserInfo4
->usri4_usr_comment
,
1097 UserInfo
->UserComment
.Buffer
,
1098 UserInfo
->UserComment
.Length
);
1099 UserInfo4
->usri4_usr_comment
[UserInfo
->UserComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1100 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserComment
.Length
+ sizeof(WCHAR
));
1102 UserInfo4
->usri4_parms
= Ptr
;
1103 memcpy(UserInfo4
->usri4_parms
,
1104 UserInfo
->Parameters
.Buffer
,
1105 UserInfo
->Parameters
.Length
);
1106 UserInfo4
->usri4_parms
[UserInfo
->Parameters
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1107 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->Parameters
.Length
+ sizeof(WCHAR
));
1109 UserInfo4
->usri4_workstations
= Ptr
;
1110 memcpy(UserInfo4
->usri4_workstations
,
1111 UserInfo
->WorkStations
.Buffer
,
1112 UserInfo
->WorkStations
.Length
);
1113 UserInfo4
->usri4_workstations
[UserInfo
->WorkStations
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1114 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->WorkStations
.Length
+ sizeof(WCHAR
));
1116 if (UserInfo
->LastLogon
.QuadPart
== 0)
1117 UserInfo4
->usri4_last_logon
= 0;
1119 RtlTimeToSecondsSince1970(&UserInfo
->LastLogon
,
1120 &UserInfo4
->usri4_last_logon
);
1122 if (UserInfo
->LastLogoff
.QuadPart
== 0)
1123 UserInfo4
->usri4_last_logoff
= 0;
1125 RtlTimeToSecondsSince1970(&UserInfo
->LastLogoff
,
1126 &UserInfo4
->usri4_last_logoff
);
1128 if (UserInfo
->AccountExpires
.QuadPart
== MAXLONGLONG
)
1129 UserInfo4
->usri4_acct_expires
= TIMEQ_FOREVER
;
1131 RtlTimeToSecondsSince1970(&UserInfo
->AccountExpires
,
1132 &UserInfo4
->usri4_acct_expires
);
1134 UserInfo4
->usri4_max_storage
= USER_MAXSTORAGE_UNLIMITED
;
1135 UserInfo4
->usri4_units_per_week
= UserInfo
->LogonHours
.UnitsPerWeek
;
1137 if (UserInfo
->LogonHours
.UnitsPerWeek
> 0)
1139 UserInfo4
->usri4_logon_hours
= (PVOID
)Ptr
;
1141 memcpy(UserInfo4
->usri4_logon_hours
,
1142 UserInfo
->LogonHours
.LogonHours
,
1143 (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8);
1145 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8);
1148 UserInfo4
->usri4_bad_pw_count
= UserInfo
->BadPasswordCount
;
1149 UserInfo4
->usri4_num_logons
= UserInfo
->LogonCount
;
1151 UserInfo4
->usri4_logon_server
= Ptr
;
1152 memcpy(UserInfo4
->usri4_logon_server
,
1154 LogonServer
.Length
);
1155 UserInfo4
->usri4_logon_server
[LogonServer
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1156 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ LogonServer
.Length
+ sizeof(WCHAR
));
1158 UserInfo4
->usri4_country_code
= UserInfo
->CountryCode
;
1159 UserInfo4
->usri4_code_page
= UserInfo
->CodePage
;
1161 UserInfo4
->usri4_user_sid
= (PVOID
)Ptr
;
1162 CopySidFromSidAndRid(UserInfo4
->usri4_user_sid
, AccountDomainSid
, RelativeId
);
1163 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RtlLengthSid(AccountDomainSid
) + sizeof(ULONG
));
1165 UserInfo4
->usri4_primary_group_id
= UserInfo
->PrimaryGroupId
;
1167 UserInfo4
->usri4_profile
= Ptr
;
1168 memcpy(UserInfo4
->usri4_profile
,
1169 UserInfo
->ProfilePath
.Buffer
,
1170 UserInfo
->ProfilePath
.Length
);
1171 UserInfo4
->usri4_profile
[UserInfo
->ProfilePath
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1172 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->ProfilePath
.Length
+ sizeof(WCHAR
));
1174 UserInfo4
->usri4_home_dir_drive
= Ptr
;
1175 memcpy(UserInfo4
->usri4_home_dir_drive
,
1176 UserInfo
->HomeDirectoryDrive
.Buffer
,
1177 UserInfo
->HomeDirectoryDrive
.Length
);
1178 UserInfo4
->usri4_home_dir_drive
[UserInfo
->HomeDirectoryDrive
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1179 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->HomeDirectoryDrive
.Length
+ sizeof(WCHAR
));
1181 UserInfo4
->usri4_password_expired
= (UserInfo
->UserAccountControl
& USER_PASSWORD_EXPIRED
);
1185 UserInfo10
= (PUSER_INFO_10
)LocalBuffer
;
1187 Ptr
= (LPWSTR
)((ULONG_PTR
)UserInfo10
+ sizeof(USER_INFO_10
));
1189 UserInfo10
->usri10_name
= Ptr
;
1191 memcpy(UserInfo10
->usri10_name
,
1192 UserInfo
->UserName
.Buffer
,
1193 UserInfo
->UserName
.Length
);
1194 UserInfo10
->usri10_name
[UserInfo
->UserName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1196 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserName
.Length
+ sizeof(WCHAR
));
1198 UserInfo10
->usri10_comment
= Ptr
;
1199 memcpy(UserInfo10
->usri10_comment
,
1200 UserInfo
->AdminComment
.Buffer
,
1201 UserInfo
->AdminComment
.Length
);
1202 UserInfo10
->usri10_comment
[UserInfo
->AdminComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1203 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
));
1205 UserInfo10
->usri10_usr_comment
= Ptr
;
1206 memcpy(UserInfo10
->usri10_usr_comment
,
1207 UserInfo
->UserComment
.Buffer
,
1208 UserInfo
->UserComment
.Length
);
1209 UserInfo10
->usri10_usr_comment
[UserInfo
->UserComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1210 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserComment
.Length
+ sizeof(WCHAR
));
1212 UserInfo10
->usri10_full_name
= Ptr
;
1213 memcpy(UserInfo10
->usri10_full_name
,
1214 UserInfo
->FullName
.Buffer
,
1215 UserInfo
->FullName
.Length
);
1216 UserInfo10
->usri10_full_name
[UserInfo
->FullName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1220 UserInfo11
= (PUSER_INFO_11
)LocalBuffer
;
1222 Ptr
= (LPWSTR
)((ULONG_PTR
)UserInfo11
+ sizeof(USER_INFO_11
));
1224 UserInfo11
->usri11_name
= Ptr
;
1226 memcpy(UserInfo11
->usri11_name
,
1227 UserInfo
->UserName
.Buffer
,
1228 UserInfo
->UserName
.Length
);
1229 UserInfo11
->usri11_name
[UserInfo
->UserName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1231 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserName
.Length
+ sizeof(WCHAR
));
1233 UserInfo11
->usri11_comment
= Ptr
;
1234 memcpy(UserInfo11
->usri11_comment
,
1235 UserInfo
->AdminComment
.Buffer
,
1236 UserInfo
->AdminComment
.Length
);
1237 UserInfo11
->usri11_comment
[UserInfo
->AdminComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1238 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
));
1240 UserInfo11
->usri11_usr_comment
= Ptr
;
1241 memcpy(UserInfo11
->usri11_usr_comment
,
1242 UserInfo
->UserComment
.Buffer
,
1243 UserInfo
->UserComment
.Length
);
1244 UserInfo11
->usri11_usr_comment
[UserInfo
->UserComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1245 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserComment
.Length
+ sizeof(WCHAR
));
1247 UserInfo11
->usri11_full_name
= Ptr
;
1248 memcpy(UserInfo11
->usri11_full_name
,
1249 UserInfo
->FullName
.Buffer
,
1250 UserInfo
->FullName
.Length
);
1251 UserInfo11
->usri11_full_name
[UserInfo
->FullName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1252 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->FullName
.Length
+ sizeof(WCHAR
));
1254 UserInfo11
->usri11_priv
= Priv
;
1255 UserInfo11
->usri11_auth_flags
= AuthFlags
;
1257 UserInfo11
->usri11_password_age
= GetPasswordAge(&UserInfo
->PasswordLastSet
);
1259 UserInfo11
->usri11_home_dir
= Ptr
;
1260 memcpy(UserInfo11
->usri11_home_dir
,
1261 UserInfo
->HomeDirectory
.Buffer
,
1262 UserInfo
->HomeDirectory
.Length
);
1263 UserInfo11
->usri11_home_dir
[UserInfo
->HomeDirectory
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1264 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->HomeDirectory
.Length
+ sizeof(WCHAR
));
1266 UserInfo11
->usri11_parms
= Ptr
;
1267 memcpy(UserInfo11
->usri11_parms
,
1268 UserInfo
->Parameters
.Buffer
,
1269 UserInfo
->Parameters
.Length
);
1270 UserInfo11
->usri11_parms
[UserInfo
->Parameters
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1271 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->Parameters
.Length
+ sizeof(WCHAR
));
1273 if (UserInfo
->LastLogon
.QuadPart
== 0)
1274 UserInfo11
->usri11_last_logon
= 0;
1276 RtlTimeToSecondsSince1970(&UserInfo
->LastLogon
,
1277 &UserInfo11
->usri11_last_logon
);
1279 if (UserInfo
->LastLogoff
.QuadPart
== 0)
1280 UserInfo11
->usri11_last_logoff
= 0;
1282 RtlTimeToSecondsSince1970(&UserInfo
->LastLogoff
,
1283 &UserInfo11
->usri11_last_logoff
);
1285 UserInfo11
->usri11_bad_pw_count
= UserInfo
->BadPasswordCount
;
1286 UserInfo11
->usri11_num_logons
= UserInfo
->LogonCount
;
1288 UserInfo11
->usri11_logon_server
= Ptr
;
1289 memcpy(UserInfo11
->usri11_logon_server
,
1291 LogonServer
.Length
);
1292 UserInfo11
->usri11_logon_server
[LogonServer
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1293 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ LogonServer
.Length
+ sizeof(WCHAR
));
1295 UserInfo11
->usri11_country_code
= UserInfo
->CountryCode
;
1297 UserInfo11
->usri11_workstations
= Ptr
;
1298 memcpy(UserInfo11
->usri11_workstations
,
1299 UserInfo
->WorkStations
.Buffer
,
1300 UserInfo
->WorkStations
.Length
);
1301 UserInfo11
->usri11_workstations
[UserInfo
->WorkStations
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1302 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->WorkStations
.Length
+ sizeof(WCHAR
));
1304 UserInfo11
->usri11_max_storage
= USER_MAXSTORAGE_UNLIMITED
;
1305 UserInfo11
->usri11_units_per_week
= UserInfo
->LogonHours
.UnitsPerWeek
;
1307 if (UserInfo
->LogonHours
.UnitsPerWeek
> 0)
1309 UserInfo11
->usri11_logon_hours
= (PVOID
)Ptr
;
1311 memcpy(UserInfo11
->usri11_logon_hours
,
1312 UserInfo
->LogonHours
.LogonHours
,
1313 (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8);
1315 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ (((ULONG
)UserInfo
->LogonHours
.UnitsPerWeek
) + 7) / 8);
1318 UserInfo11
->usri11_code_page
= UserInfo
->CodePage
;
1322 UserInfo20
= (PUSER_INFO_20
)LocalBuffer
;
1324 Ptr
= (LPWSTR
)((ULONG_PTR
)UserInfo20
+ sizeof(USER_INFO_20
));
1326 UserInfo20
->usri20_name
= Ptr
;
1328 memcpy(UserInfo20
->usri20_name
,
1329 UserInfo
->UserName
.Buffer
,
1330 UserInfo
->UserName
.Length
);
1331 UserInfo20
->usri20_name
[UserInfo
->UserName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1333 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserName
.Length
+ sizeof(WCHAR
));
1335 UserInfo20
->usri20_full_name
= Ptr
;
1336 memcpy(UserInfo20
->usri20_full_name
,
1337 UserInfo
->FullName
.Buffer
,
1338 UserInfo
->FullName
.Length
);
1339 UserInfo20
->usri20_full_name
[UserInfo
->FullName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1340 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->FullName
.Length
+ sizeof(WCHAR
));
1342 UserInfo20
->usri20_comment
= Ptr
;
1343 memcpy(UserInfo20
->usri20_comment
,
1344 UserInfo
->AdminComment
.Buffer
,
1345 UserInfo
->AdminComment
.Length
);
1346 UserInfo20
->usri20_comment
[UserInfo
->AdminComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1347 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
));
1349 UserInfo20
->usri20_flags
= GetAccountFlags(UserInfo
->UserAccountControl
,
1352 UserInfo20
->usri20_user_id
= RelativeId
;
1356 UserInfo23
= (PUSER_INFO_23
)LocalBuffer
;
1358 Ptr
= (LPWSTR
)((ULONG_PTR
)UserInfo23
+ sizeof(USER_INFO_23
));
1360 UserInfo23
->usri23_name
= Ptr
;
1362 memcpy(UserInfo23
->usri23_name
,
1363 UserInfo
->UserName
.Buffer
,
1364 UserInfo
->UserName
.Length
);
1365 UserInfo23
->usri23_name
[UserInfo
->UserName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1367 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->UserName
.Length
+ sizeof(WCHAR
));
1369 UserInfo23
->usri23_full_name
= Ptr
;
1370 memcpy(UserInfo23
->usri23_full_name
,
1371 UserInfo
->FullName
.Buffer
,
1372 UserInfo
->FullName
.Length
);
1373 UserInfo23
->usri23_full_name
[UserInfo
->FullName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1374 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->FullName
.Length
+ sizeof(WCHAR
));
1376 UserInfo23
->usri23_comment
= Ptr
;
1377 memcpy(UserInfo23
->usri23_comment
,
1378 UserInfo
->AdminComment
.Buffer
,
1379 UserInfo
->AdminComment
.Length
);
1380 UserInfo23
->usri23_comment
[UserInfo
->AdminComment
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
1381 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ UserInfo
->AdminComment
.Length
+ sizeof(WCHAR
));
1383 UserInfo23
->usri23_flags
= GetAccountFlags(UserInfo
->UserAccountControl
,
1386 UserInfo23
->usri23_user_sid
= (PVOID
)Ptr
;
1387 CopySidFromSidAndRid(UserInfo23
->usri23_user_sid
, AccountDomainSid
, RelativeId
);
1388 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RtlLengthSid(AccountDomainSid
) + sizeof(ULONG
));
1393 if (UserInfo
!= NULL
)
1394 FreeUserInfo(UserInfo
);
1397 HeapFree(GetProcessHeap(), 0, Dacl
);
1399 if (ApiStatus
== NERR_Success
)
1401 *Buffer
= LocalBuffer
;
1405 if (LocalBuffer
!= NULL
)
1406 NetApiBufferFree(LocalBuffer
);
1415 SetUserInfo(SAM_HANDLE UserHandle
,
1420 USER_ALL_INFORMATION UserAllInfo
;
1421 PUSER_INFO_0 UserInfo0
;
1422 PUSER_INFO_1 UserInfo1
;
1423 PUSER_INFO_2 UserInfo2
;
1424 PUSER_INFO_3 UserInfo3
;
1425 PUSER_INFO_4 UserInfo4
;
1426 PUSER_INFO_22 UserInfo22
;
1427 PUSER_INFO_1003 UserInfo1003
;
1428 PUSER_INFO_1006 UserInfo1006
;
1429 PUSER_INFO_1007 UserInfo1007
;
1430 PUSER_INFO_1008 UserInfo1008
;
1431 PUSER_INFO_1009 UserInfo1009
;
1432 PUSER_INFO_1011 UserInfo1011
;
1433 PUSER_INFO_1012 UserInfo1012
;
1434 PUSER_INFO_1013 UserInfo1013
;
1435 PUSER_INFO_1014 UserInfo1014
;
1436 PUSER_INFO_1017 UserInfo1017
;
1437 PUSER_INFO_1020 UserInfo1020
;
1438 PUSER_INFO_1024 UserInfo1024
;
1439 PUSER_INFO_1025 UserInfo1025
;
1440 PUSER_INFO_1051 UserInfo1051
;
1441 PUSER_INFO_1052 UserInfo1052
;
1442 PUSER_INFO_1053 UserInfo1053
;
1444 NET_API_STATUS ApiStatus
= NERR_Success
;
1445 NTSTATUS Status
= STATUS_SUCCESS
;
1447 ZeroMemory(&UserAllInfo
, sizeof(USER_ALL_INFORMATION
));
1449 if ((Level
== 1) || (Level
== 2) || (Level
== 3) ||
1450 (Level
== 4) || (Level
== 22) || (Level
== 1008))
1452 ApiStatus
= GetUserDacl(UserHandle
, &Dacl
);
1453 if (ApiStatus
!= NERR_Success
)
1460 UserInfo0
= (PUSER_INFO_0
)UserInfo
;
1462 RtlInitUnicodeString(&UserAllInfo
.UserName
,
1463 UserInfo0
->usri0_name
);
1465 UserAllInfo
.WhichFields
|= USER_ALL_USERNAME
;
1469 UserInfo1
= (PUSER_INFO_1
)UserInfo
;
1471 // usri1_name ignored
1473 if (UserInfo1
->usri1_password
!= NULL
)
1475 RtlInitUnicodeString(&UserAllInfo
.NtPassword
,
1476 UserInfo1
->usri1_password
);
1477 UserAllInfo
.NtPasswordPresent
= TRUE
;
1478 UserAllInfo
.WhichFields
|= USER_ALL_NTPASSWORDPRESENT
;
1481 // usri1_password_age ignored
1483 // UserInfo1->usri1_priv
1485 if (UserInfo1
->usri1_home_dir
!= NULL
)
1487 RtlInitUnicodeString(&UserAllInfo
.HomeDirectory
,
1488 UserInfo1
->usri1_home_dir
);
1489 UserAllInfo
.WhichFields
|= USER_ALL_HOMEDIRECTORY
;
1492 if (UserInfo1
->usri1_comment
!= NULL
)
1494 RtlInitUnicodeString(&UserAllInfo
.AdminComment
,
1495 UserInfo1
->usri1_comment
);
1496 UserAllInfo
.WhichFields
|= USER_ALL_ADMINCOMMENT
;
1499 ChangeUserDacl(Dacl
, UserInfo1
->usri1_flags
);
1500 UserAllInfo
.UserAccountControl
= GetAccountControl(UserInfo1
->usri1_flags
);
1501 UserAllInfo
.WhichFields
|= USER_ALL_USERACCOUNTCONTROL
;
1503 if (UserInfo1
->usri1_script_path
!= NULL
)
1505 RtlInitUnicodeString(&UserAllInfo
.ScriptPath
,
1506 UserInfo1
->usri1_script_path
);
1507 UserAllInfo
.WhichFields
|= USER_ALL_SCRIPTPATH
;
1512 UserInfo2
= (PUSER_INFO_2
)UserInfo
;
1514 // usri2_name ignored
1516 if (UserInfo2
->usri2_password
!= NULL
)
1518 RtlInitUnicodeString(&UserAllInfo
.NtPassword
,
1519 UserInfo2
->usri2_password
);
1520 UserAllInfo
.NtPasswordPresent
= TRUE
;
1521 UserAllInfo
.WhichFields
|= USER_ALL_NTPASSWORDPRESENT
;
1524 // usri2_password_age ignored
1526 // UserInfo2->usri2_priv;
1528 if (UserInfo2
->usri2_home_dir
!= NULL
)
1530 RtlInitUnicodeString(&UserAllInfo
.HomeDirectory
,
1531 UserInfo2
->usri2_home_dir
);
1532 UserAllInfo
.WhichFields
|= USER_ALL_HOMEDIRECTORY
;
1535 if (UserInfo2
->usri2_comment
!= NULL
)
1537 RtlInitUnicodeString(&UserAllInfo
.AdminComment
,
1538 UserInfo2
->usri2_comment
);
1539 UserAllInfo
.WhichFields
|= USER_ALL_ADMINCOMMENT
;
1542 ChangeUserDacl(Dacl
, UserInfo2
->usri2_flags
);
1543 UserAllInfo
.UserAccountControl
= GetAccountControl(UserInfo2
->usri2_flags
);
1544 UserAllInfo
.WhichFields
|= USER_ALL_USERACCOUNTCONTROL
;
1546 if (UserInfo2
->usri2_script_path
!= NULL
)
1548 RtlInitUnicodeString(&UserAllInfo
.ScriptPath
,
1549 UserInfo2
->usri2_script_path
);
1550 UserAllInfo
.WhichFields
|= USER_ALL_SCRIPTPATH
;
1553 // UserInfo2->usri2_auth_flags;
1555 if (UserInfo2
->usri2_full_name
!= NULL
)
1557 RtlInitUnicodeString(&UserAllInfo
.FullName
,
1558 UserInfo2
->usri2_full_name
);
1559 UserAllInfo
.WhichFields
|= USER_ALL_FULLNAME
;
1562 if (UserInfo2
->usri2_usr_comment
!= NULL
)
1564 RtlInitUnicodeString(&UserAllInfo
.UserComment
,
1565 UserInfo2
->usri2_usr_comment
);
1566 UserAllInfo
.WhichFields
|= USER_ALL_USERCOMMENT
;
1569 if (UserInfo2
->usri2_parms
!= NULL
)
1571 RtlInitUnicodeString(&UserAllInfo
.Parameters
,
1572 UserInfo2
->usri2_parms
);
1573 UserAllInfo
.WhichFields
|= USER_ALL_PARAMETERS
;
1576 if (UserInfo2
->usri2_workstations
!= NULL
)
1578 RtlInitUnicodeString(&UserAllInfo
.WorkStations
,
1579 UserInfo2
->usri2_workstations
);
1580 UserAllInfo
.WhichFields
|= USER_ALL_WORKSTATIONS
;
1583 // usri2_last_logon ignored
1584 // usri2_last_logoff ignored
1586 if (UserInfo2
->usri2_acct_expires
== TIMEQ_FOREVER
)
1588 UserAllInfo
.AccountExpires
.QuadPart
= MAXLONGLONG
;
1592 RtlSecondsSince1970ToTime(UserInfo2
->usri2_acct_expires
,
1593 &UserAllInfo
.AccountExpires
);
1595 UserAllInfo
.WhichFields
|= USER_ALL_ACCOUNTEXPIRES
;
1597 // usri2_max_storage ignored
1599 if (UserInfo2
->usri2_units_per_week
> USHRT_MAX
)
1601 if (parm_err
!= NULL
)
1602 *parm_err
= USER_UNITS_PER_WEEK_PARMNUM
;
1603 ApiStatus
= ERROR_INVALID_PARAMETER
;
1607 UserAllInfo
.LogonHours
.UnitsPerWeek
= UserInfo2
->usri2_units_per_week
;
1608 UserAllInfo
.LogonHours
.LogonHours
= UserInfo2
->usri2_logon_hours
;
1609 UserAllInfo
.WhichFields
|= USER_ALL_LOGONHOURS
;
1611 // usri2_bad_pw_count ignored
1612 // usri2_num_logons ignored
1613 // usri2_logon_server ignored
1615 UserAllInfo
.CountryCode
= UserInfo2
->usri2_country_code
;
1616 UserAllInfo
.WhichFields
|= USER_ALL_COUNTRYCODE
;
1618 UserAllInfo
.CodePage
= UserInfo2
->usri2_code_page
;
1619 UserAllInfo
.WhichFields
|= USER_ALL_CODEPAGE
;
1623 UserInfo3
= (PUSER_INFO_3
)UserInfo
;
1625 // usri3_name ignored
1627 if (UserInfo3
->usri3_password
!= NULL
)
1629 RtlInitUnicodeString(&UserAllInfo
.NtPassword
,
1630 UserInfo3
->usri3_password
);
1631 UserAllInfo
.NtPasswordPresent
= TRUE
;
1632 UserAllInfo
.WhichFields
|= USER_ALL_NTPASSWORDPRESENT
;
1635 // usri3_password_age ignored
1637 // UserInfo3->usri3_priv;
1639 if (UserInfo3
->usri3_home_dir
!= NULL
)
1641 RtlInitUnicodeString(&UserAllInfo
.HomeDirectory
,
1642 UserInfo3
->usri3_home_dir
);
1643 UserAllInfo
.WhichFields
|= USER_ALL_HOMEDIRECTORY
;
1646 if (UserInfo3
->usri3_comment
!= NULL
)
1648 RtlInitUnicodeString(&UserAllInfo
.AdminComment
,
1649 UserInfo3
->usri3_comment
);
1650 UserAllInfo
.WhichFields
|= USER_ALL_ADMINCOMMENT
;
1653 ChangeUserDacl(Dacl
, UserInfo3
->usri3_flags
);
1654 UserAllInfo
.UserAccountControl
= GetAccountControl(UserInfo3
->usri3_flags
);
1655 UserAllInfo
.WhichFields
|= USER_ALL_USERACCOUNTCONTROL
;
1657 if (UserInfo3
->usri3_script_path
!= NULL
)
1659 RtlInitUnicodeString(&UserAllInfo
.ScriptPath
,
1660 UserInfo3
->usri3_script_path
);
1661 UserAllInfo
.WhichFields
|= USER_ALL_SCRIPTPATH
;
1664 // UserInfo3->usri3_auth_flags;
1666 if (UserInfo3
->usri3_full_name
!= NULL
)
1668 RtlInitUnicodeString(&UserAllInfo
.FullName
,
1669 UserInfo3
->usri3_full_name
);
1670 UserAllInfo
.WhichFields
|= USER_ALL_FULLNAME
;
1673 if (UserInfo3
->usri3_usr_comment
!= NULL
)
1675 RtlInitUnicodeString(&UserAllInfo
.UserComment
,
1676 UserInfo3
->usri3_usr_comment
);
1677 UserAllInfo
.WhichFields
|= USER_ALL_USERCOMMENT
;
1680 if (UserInfo3
->usri3_parms
!= NULL
)
1682 RtlInitUnicodeString(&UserAllInfo
.Parameters
,
1683 UserInfo3
->usri3_parms
);
1684 UserAllInfo
.WhichFields
|= USER_ALL_PARAMETERS
;
1687 if (UserInfo3
->usri3_workstations
!= NULL
)
1689 RtlInitUnicodeString(&UserAllInfo
.WorkStations
,
1690 UserInfo3
->usri3_workstations
);
1691 UserAllInfo
.WhichFields
|= USER_ALL_WORKSTATIONS
;
1694 // usri3_last_logon ignored
1695 // usri3_last_logoff ignored
1697 if (UserInfo3
->usri3_acct_expires
== TIMEQ_FOREVER
)
1699 UserAllInfo
.AccountExpires
.QuadPart
= MAXLONGLONG
;
1703 RtlSecondsSince1970ToTime(UserInfo3
->usri3_acct_expires
,
1704 &UserAllInfo
.AccountExpires
);
1706 UserAllInfo
.WhichFields
|= USER_ALL_ACCOUNTEXPIRES
;
1708 // usri3_max_storage ignored
1710 if (UserInfo3
->usri3_units_per_week
> USHRT_MAX
)
1712 if (parm_err
!= NULL
)
1713 *parm_err
= USER_UNITS_PER_WEEK_PARMNUM
;
1714 ApiStatus
= ERROR_INVALID_PARAMETER
;
1718 UserAllInfo
.LogonHours
.UnitsPerWeek
= UserInfo3
->usri3_units_per_week
;
1719 UserAllInfo
.LogonHours
.LogonHours
= UserInfo3
->usri3_logon_hours
;
1720 UserAllInfo
.WhichFields
|= USER_ALL_LOGONHOURS
;
1722 // usri3_bad_pw_count ignored
1723 // usri3_num_logons ignored
1724 // usri3_logon_server ignored
1726 UserAllInfo
.CountryCode
= UserInfo3
->usri3_country_code
;
1727 UserAllInfo
.WhichFields
|= USER_ALL_COUNTRYCODE
;
1729 UserAllInfo
.CodePage
= UserInfo3
->usri3_code_page
;
1730 UserAllInfo
.WhichFields
|= USER_ALL_CODEPAGE
;
1732 // usri3_user_id ignored
1734 UserAllInfo
.PrimaryGroupId
= UserInfo3
->usri3_primary_group_id
;
1735 UserAllInfo
.WhichFields
|= USER_ALL_PRIMARYGROUPID
;
1737 if (UserInfo3
->usri3_profile
!= NULL
)
1739 RtlInitUnicodeString(&UserAllInfo
.ProfilePath
,
1740 UserInfo3
->usri3_profile
);
1741 UserAllInfo
.WhichFields
|= USER_ALL_PROFILEPATH
;
1744 if (UserInfo3
->usri3_home_dir_drive
!= NULL
)
1746 RtlInitUnicodeString(&UserAllInfo
.HomeDirectoryDrive
,
1747 UserInfo3
->usri3_home_dir_drive
);
1748 UserAllInfo
.WhichFields
|= USER_ALL_HOMEDIRECTORYDRIVE
;
1751 UserAllInfo
.PasswordExpired
= (UserInfo3
->usri3_password_expired
!= 0);
1752 UserAllInfo
.WhichFields
|= USER_ALL_PASSWORDEXPIRED
;
1756 UserInfo4
= (PUSER_INFO_4
)UserInfo
;
1758 // usri4_name ignored
1760 if (UserInfo4
->usri4_password
!= NULL
)
1762 RtlInitUnicodeString(&UserAllInfo
.NtPassword
,
1763 UserInfo4
->usri4_password
);
1764 UserAllInfo
.NtPasswordPresent
= TRUE
;
1765 UserAllInfo
.WhichFields
|= USER_ALL_NTPASSWORDPRESENT
;
1768 // usri4_password_age ignored
1770 // UserInfo3->usri4_priv;
1772 if (UserInfo4
->usri4_home_dir
!= NULL
)
1774 RtlInitUnicodeString(&UserAllInfo
.HomeDirectory
,
1775 UserInfo4
->usri4_home_dir
);
1776 UserAllInfo
.WhichFields
|= USER_ALL_HOMEDIRECTORY
;
1779 if (UserInfo4
->usri4_comment
!= NULL
)
1781 RtlInitUnicodeString(&UserAllInfo
.AdminComment
,
1782 UserInfo4
->usri4_comment
);
1783 UserAllInfo
.WhichFields
|= USER_ALL_ADMINCOMMENT
;
1786 ChangeUserDacl(Dacl
, UserInfo4
->usri4_flags
);
1787 UserAllInfo
.UserAccountControl
= GetAccountControl(UserInfo4
->usri4_flags
);
1788 UserAllInfo
.WhichFields
|= USER_ALL_USERACCOUNTCONTROL
;
1790 if (UserInfo4
->usri4_script_path
!= NULL
)
1792 RtlInitUnicodeString(&UserAllInfo
.ScriptPath
,
1793 UserInfo4
->usri4_script_path
);
1794 UserAllInfo
.WhichFields
|= USER_ALL_SCRIPTPATH
;
1797 // UserInfo4->usri4_auth_flags;
1799 if (UserInfo4
->usri4_full_name
!= NULL
)
1801 RtlInitUnicodeString(&UserAllInfo
.FullName
,
1802 UserInfo4
->usri4_full_name
);
1803 UserAllInfo
.WhichFields
|= USER_ALL_FULLNAME
;
1806 if (UserInfo4
->usri4_usr_comment
!= NULL
)
1808 RtlInitUnicodeString(&UserAllInfo
.UserComment
,
1809 UserInfo4
->usri4_usr_comment
);
1810 UserAllInfo
.WhichFields
|= USER_ALL_USERCOMMENT
;
1813 if (UserInfo4
->usri4_parms
!= NULL
)
1815 RtlInitUnicodeString(&UserAllInfo
.Parameters
,
1816 UserInfo4
->usri4_parms
);
1817 UserAllInfo
.WhichFields
|= USER_ALL_PARAMETERS
;
1820 if (UserInfo4
->usri4_workstations
!= NULL
)
1822 RtlInitUnicodeString(&UserAllInfo
.WorkStations
,
1823 UserInfo4
->usri4_workstations
);
1824 UserAllInfo
.WhichFields
|= USER_ALL_WORKSTATIONS
;
1827 // usri4_last_logon ignored
1828 // usri4_last_logoff ignored
1830 if (UserInfo4
->usri4_acct_expires
== TIMEQ_FOREVER
)
1832 UserAllInfo
.AccountExpires
.QuadPart
= MAXLONGLONG
;
1836 RtlSecondsSince1970ToTime(UserInfo4
->usri4_acct_expires
,
1837 &UserAllInfo
.AccountExpires
);
1839 UserAllInfo
.WhichFields
|= USER_ALL_ACCOUNTEXPIRES
;
1841 // usri4_max_storage ignored
1843 if (UserInfo4
->usri4_units_per_week
> USHRT_MAX
)
1845 if (parm_err
!= NULL
)
1846 *parm_err
= USER_UNITS_PER_WEEK_PARMNUM
;
1847 ApiStatus
= ERROR_INVALID_PARAMETER
;
1851 UserAllInfo
.LogonHours
.UnitsPerWeek
= UserInfo4
->usri4_units_per_week
;
1852 UserAllInfo
.LogonHours
.LogonHours
= UserInfo4
->usri4_logon_hours
;
1853 UserAllInfo
.WhichFields
|= USER_ALL_LOGONHOURS
;
1855 // usri4_bad_pw_count ignored
1856 // usri4_num_logons ignored
1857 // usri4_logon_server ignored
1859 UserAllInfo
.CountryCode
= UserInfo4
->usri4_country_code
;
1860 UserAllInfo
.WhichFields
|= USER_ALL_COUNTRYCODE
;
1862 UserAllInfo
.CodePage
= UserInfo4
->usri4_code_page
;
1863 UserAllInfo
.WhichFields
|= USER_ALL_CODEPAGE
;
1865 // usri4_user_sid ignored
1867 UserAllInfo
.PrimaryGroupId
= UserInfo4
->usri4_primary_group_id
;
1868 UserAllInfo
.WhichFields
|= USER_ALL_PRIMARYGROUPID
;
1870 if (UserInfo4
->usri4_profile
!= NULL
)
1872 RtlInitUnicodeString(&UserAllInfo
.ProfilePath
,
1873 UserInfo4
->usri4_profile
);
1874 UserAllInfo
.WhichFields
|= USER_ALL_PROFILEPATH
;
1877 if (UserInfo4
->usri4_home_dir_drive
!= NULL
)
1879 RtlInitUnicodeString(&UserAllInfo
.HomeDirectoryDrive
,
1880 UserInfo4
->usri4_home_dir_drive
);
1881 UserAllInfo
.WhichFields
|= USER_ALL_HOMEDIRECTORYDRIVE
;
1884 UserAllInfo
.PasswordExpired
= (UserInfo4
->usri4_password_expired
!= 0);
1885 UserAllInfo
.WhichFields
|= USER_ALL_PASSWORDEXPIRED
;
1892 UserInfo22
= (PUSER_INFO_22
)UserInfo
;
1894 // usri22_name ignored
1896 // UserInfo22->usri22_password[ENCRYPTED_PWLEN];
1898 // usri22_password_age ignored
1900 // UserInfo3->usri3_priv;
1902 if (UserInfo22
->usri22_home_dir
!= NULL
)
1904 RtlInitUnicodeString(&UserAllInfo
.HomeDirectory
,
1905 UserInfo22
->usri22_home_dir
);
1906 UserAllInfo
.WhichFields
|= USER_ALL_HOMEDIRECTORY
;
1909 if (UserInfo22
->usri22_comment
!= NULL
)
1911 RtlInitUnicodeString(&UserAllInfo
.AdminComment
,
1912 UserInfo22
->usri22_comment
);
1913 UserAllInfo
.WhichFields
|= USER_ALL_ADMINCOMMENT
;
1916 ChangeUserDacl(Dacl
, UserInfo22
->usri22_flags
);
1917 UserAllInfo
.UserAccountControl
= GetAccountControl(UserInfo22
->usri22_flags
);
1918 UserAllInfo
.WhichFields
|= USER_ALL_USERACCOUNTCONTROL
;
1920 if (UserInfo22
->usri22_script_path
!= NULL
)
1922 RtlInitUnicodeString(&UserAllInfo
.ScriptPath
,
1923 UserInfo22
->usri22_script_path
);
1924 UserAllInfo
.WhichFields
|= USER_ALL_SCRIPTPATH
;
1927 // UserInfo22->usri22_auth_flags;
1929 if (UserInfo22
->usri22_full_name
!= NULL
)
1931 RtlInitUnicodeString(&UserAllInfo
.FullName
,
1932 UserInfo22
->usri22_full_name
);
1933 UserAllInfo
.WhichFields
|= USER_ALL_FULLNAME
;
1936 if (UserInfo22
->usri22_usr_comment
!= NULL
)
1938 RtlInitUnicodeString(&UserAllInfo
.UserComment
,
1939 UserInfo22
->usri22_usr_comment
);
1940 UserAllInfo
.WhichFields
|= USER_ALL_USERCOMMENT
;
1943 if (UserInfo22
->usri22_parms
!= NULL
)
1945 RtlInitUnicodeString(&UserAllInfo
.Parameters
,
1946 UserInfo22
->usri22_parms
);
1947 UserAllInfo
.WhichFields
|= USER_ALL_PARAMETERS
;
1950 if (UserInfo22
->usri22_workstations
!= NULL
)
1952 RtlInitUnicodeString(&UserAllInfo
.WorkStations
,
1953 UserInfo22
->usri22_workstations
);
1954 UserAllInfo
.WhichFields
|= USER_ALL_WORKSTATIONS
;
1957 // usri22_last_logon ignored
1958 // usri22_last_logoff ignored
1960 if (UserInfo22
->usri22_acct_expires
== TIMEQ_FOREVER
)
1962 UserAllInfo
.AccountExpires
.QuadPart
= MAXLONGLONG
;
1966 RtlSecondsSince1970ToTime(UserInfo22
->usri22_acct_expires
,
1967 &UserAllInfo
.AccountExpires
);
1969 UserAllInfo
.WhichFields
|= USER_ALL_ACCOUNTEXPIRES
;
1971 // usri22_max_storage ignored
1973 if (UserInfo22
->usri22_units_per_week
> USHRT_MAX
)
1975 if (parm_err
!= NULL
)
1976 *parm_err
= USER_UNITS_PER_WEEK_PARMNUM
;
1977 ApiStatus
= ERROR_INVALID_PARAMETER
;
1981 UserAllInfo
.LogonHours
.UnitsPerWeek
= UserInfo22
->usri22_units_per_week
;
1982 UserAllInfo
.LogonHours
.LogonHours
= UserInfo22
->usri22_logon_hours
;
1983 UserAllInfo
.WhichFields
|= USER_ALL_LOGONHOURS
;
1985 // usri22_bad_pw_count ignored
1986 // usri22_num_logons ignored
1987 // usri22_logon_server ignored
1989 UserAllInfo
.CountryCode
= UserInfo22
->usri22_country_code
;
1990 UserAllInfo
.WhichFields
|= USER_ALL_COUNTRYCODE
;
1992 UserAllInfo
.CodePage
= UserInfo22
->usri22_code_page
;
1993 UserAllInfo
.WhichFields
|= USER_ALL_CODEPAGE
;
1997 UserInfo1003
= (PUSER_INFO_1003
)UserInfo
;
1999 if (UserInfo1003
->usri1003_password
!= NULL
)
2001 RtlInitUnicodeString(&UserAllInfo
.NtPassword
,
2002 UserInfo1003
->usri1003_password
);
2003 UserAllInfo
.NtPasswordPresent
= TRUE
;
2004 UserAllInfo
.WhichFields
|= USER_ALL_NTPASSWORDPRESENT
;
2012 UserInfo1006
= (PUSER_INFO_1006
)UserInfo
;
2014 if (UserInfo1006
->usri1006_home_dir
!= NULL
)
2016 RtlInitUnicodeString(&UserAllInfo
.HomeDirectory
,
2017 UserInfo1006
->usri1006_home_dir
);
2018 UserAllInfo
.WhichFields
|= USER_ALL_HOMEDIRECTORY
;
2023 UserInfo1007
= (PUSER_INFO_1007
)UserInfo
;
2025 if (UserInfo1007
->usri1007_comment
!= NULL
)
2027 RtlInitUnicodeString(&UserAllInfo
.AdminComment
,
2028 UserInfo1007
->usri1007_comment
);
2029 UserAllInfo
.WhichFields
|= USER_ALL_ADMINCOMMENT
;
2034 UserInfo1008
= (PUSER_INFO_1008
)UserInfo
;
2035 ChangeUserDacl(Dacl
, UserInfo1008
->usri1008_flags
);
2036 UserAllInfo
.UserAccountControl
= GetAccountControl(UserInfo1008
->usri1008_flags
);
2037 UserAllInfo
.WhichFields
|= USER_ALL_USERACCOUNTCONTROL
;
2041 UserInfo1009
= (PUSER_INFO_1009
)UserInfo
;
2043 if (UserInfo1009
->usri1009_script_path
!= NULL
)
2045 RtlInitUnicodeString(&UserAllInfo
.ScriptPath
,
2046 UserInfo1009
->usri1009_script_path
);
2047 UserAllInfo
.WhichFields
|= USER_ALL_SCRIPTPATH
;
2055 UserInfo1011
= (PUSER_INFO_1011
)UserInfo
;
2057 if (UserInfo1011
->usri1011_full_name
!= NULL
)
2059 RtlInitUnicodeString(&UserAllInfo
.FullName
,
2060 UserInfo1011
->usri1011_full_name
);
2061 UserAllInfo
.WhichFields
|= USER_ALL_FULLNAME
;
2066 UserInfo1012
= (PUSER_INFO_1012
)UserInfo
;
2068 if (UserInfo1012
->usri1012_usr_comment
!= NULL
)
2070 RtlInitUnicodeString(&UserAllInfo
.UserComment
,
2071 UserInfo1012
->usri1012_usr_comment
);
2072 UserAllInfo
.WhichFields
|= USER_ALL_USERCOMMENT
;
2077 UserInfo1013
= (PUSER_INFO_1013
)UserInfo
;
2079 if (UserInfo1013
->usri1013_parms
!= NULL
)
2081 RtlInitUnicodeString(&UserAllInfo
.Parameters
,
2082 UserInfo1013
->usri1013_parms
);
2083 UserAllInfo
.WhichFields
|= USER_ALL_PARAMETERS
;
2088 UserInfo1014
= (PUSER_INFO_1014
)UserInfo
;
2090 if (UserInfo1014
->usri1014_workstations
!= NULL
)
2092 RtlInitUnicodeString(&UserAllInfo
.WorkStations
,
2093 UserInfo1014
->usri1014_workstations
);
2094 UserAllInfo
.WhichFields
|= USER_ALL_WORKSTATIONS
;
2099 UserInfo1017
= (PUSER_INFO_1017
)UserInfo
;
2101 if (UserInfo1017
->usri1017_acct_expires
== TIMEQ_FOREVER
)
2103 UserAllInfo
.AccountExpires
.QuadPart
= MAXLONGLONG
;
2107 RtlSecondsSince1970ToTime(UserInfo1017
->usri1017_acct_expires
,
2108 &UserAllInfo
.AccountExpires
);
2110 UserAllInfo
.WhichFields
|= USER_ALL_ACCOUNTEXPIRES
;
2114 // usri1018_max_storage ignored
2118 UserInfo1020
= (PUSER_INFO_1020
)UserInfo
;
2120 if (UserInfo1020
->usri1020_units_per_week
> USHRT_MAX
)
2122 if (parm_err
!= NULL
)
2123 *parm_err
= USER_UNITS_PER_WEEK_PARMNUM
;
2124 ApiStatus
= ERROR_INVALID_PARAMETER
;
2128 UserAllInfo
.LogonHours
.UnitsPerWeek
= UserInfo1020
->usri1020_units_per_week
;
2129 UserAllInfo
.LogonHours
.LogonHours
= UserInfo1020
->usri1020_logon_hours
;
2130 UserAllInfo
.WhichFields
|= USER_ALL_LOGONHOURS
;
2134 UserInfo1024
= (PUSER_INFO_1024
)UserInfo
;
2136 UserAllInfo
.CountryCode
= UserInfo1024
->usri1024_country_code
;
2137 UserAllInfo
.WhichFields
|= USER_ALL_COUNTRYCODE
;
2141 UserInfo1025
= (PUSER_INFO_1025
)UserInfo
;
2143 UserAllInfo
.CodePage
= UserInfo1025
->usri1025_code_page
;
2144 UserAllInfo
.WhichFields
|= USER_ALL_CODEPAGE
;
2148 UserInfo1051
= (PUSER_INFO_1051
)UserInfo
;
2150 UserAllInfo
.PrimaryGroupId
= UserInfo1051
->usri1051_primary_group_id
;
2151 UserAllInfo
.WhichFields
|= USER_ALL_PRIMARYGROUPID
;
2155 UserInfo1052
= (PUSER_INFO_1052
)UserInfo
;
2157 if (UserInfo1052
->usri1052_profile
!= NULL
)
2159 RtlInitUnicodeString(&UserAllInfo
.ProfilePath
,
2160 UserInfo1052
->usri1052_profile
);
2161 UserAllInfo
.WhichFields
|= USER_ALL_PROFILEPATH
;
2166 UserInfo1053
= (PUSER_INFO_1053
)UserInfo
;
2168 if (UserInfo1053
->usri1053_home_dir_drive
!= NULL
)
2170 RtlInitUnicodeString(&UserAllInfo
.HomeDirectoryDrive
,
2171 UserInfo1053
->usri1053_home_dir_drive
);
2172 UserAllInfo
.WhichFields
|= USER_ALL_HOMEDIRECTORYDRIVE
;
2177 if (ApiStatus
!= NERR_Success
)
2180 Status
= SamSetInformationUser(UserHandle
,
2183 if (!NT_SUCCESS(Status
))
2185 ERR("SamSetInformationUser failed (Status %08lx)\n", Status
);
2186 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2192 HeapFree(GetProcessHeap(), 0, Dacl
);
2200 OpenUserByName(SAM_HANDLE DomainHandle
,
2201 PUNICODE_STRING UserName
,
2202 ULONG DesiredAccess
,
2203 PSAM_HANDLE UserHandle
)
2205 PULONG RelativeIds
= NULL
;
2206 PSID_NAME_USE Use
= NULL
;
2207 NET_API_STATUS ApiStatus
= NERR_Success
;
2208 NTSTATUS Status
= STATUS_SUCCESS
;
2210 /* Get the RID for the given user name */
2211 Status
= SamLookupNamesInDomain(DomainHandle
,
2216 if (!NT_SUCCESS(Status
))
2218 ERR("SamLookupNamesInDomain failed (Status %08lx)\n", Status
);
2219 return NetpNtStatusToApiStatus(Status
);
2222 /* Fail, if it is not an alias account */
2223 if (Use
[0] != SidTypeUser
)
2225 ERR("Object is not a user!\n");
2226 ApiStatus
= NERR_GroupNotFound
;
2230 /* Open the alias account */
2231 Status
= SamOpenUser(DomainHandle
,
2235 if (!NT_SUCCESS(Status
))
2237 ERR("SamOpenUser failed (Status %08lx)\n", Status
);
2238 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2243 if (RelativeIds
!= NULL
)
2244 SamFreeMemory(RelativeIds
);
2253 /************************************************************
2254 * NetUserAdd (NETAPI32.@)
2258 NetUserAdd(LPCWSTR servername
,
2263 UNICODE_STRING ServerName
;
2264 UNICODE_STRING UserName
;
2265 SAM_HANDLE ServerHandle
= NULL
;
2266 SAM_HANDLE DomainHandle
= NULL
;
2267 SAM_HANDLE UserHandle
= NULL
;
2268 ULONG GrantedAccess
;
2270 NET_API_STATUS ApiStatus
= NERR_Success
;
2271 NTSTATUS Status
= STATUS_SUCCESS
;
2273 TRACE("(%s, %d, %p, %p)\n", debugstr_w(servername
), level
, bufptr
, parm_err
);
2275 if (parm_err
!= NULL
)
2276 *parm_err
= PARM_ERROR_NONE
;
2278 /* Check the info level */
2288 return ERROR_INVALID_LEVEL
;
2291 if (servername
!= NULL
)
2292 RtlInitUnicodeString(&ServerName
, servername
);
2294 /* Connect to the SAM Server */
2295 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
2297 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
2299 if (!NT_SUCCESS(Status
))
2301 ERR("SamConnect failed (Status %08lx)\n", Status
);
2302 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2306 /* Open the Account Domain */
2307 Status
= OpenAccountDomain(ServerHandle
,
2308 (servername
!= NULL
) ? &ServerName
: NULL
,
2309 DOMAIN_CREATE_USER
| DOMAIN_LOOKUP
| DOMAIN_READ_PASSWORD_PARAMETERS
,
2311 if (!NT_SUCCESS(Status
))
2313 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
2314 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2318 /* Initialize the user name string */
2319 RtlInitUnicodeString(&UserName
,
2320 ((PUSER_INFO_1
)bufptr
)->usri1_name
);
2322 /* Create the user account */
2323 Status
= SamCreateUser2InDomain(DomainHandle
,
2325 USER_NORMAL_ACCOUNT
,
2326 USER_ALL_ACCESS
| DELETE
| WRITE_DAC
,
2330 if (!NT_SUCCESS(Status
))
2332 ERR("SamCreateUser2InDomain failed (Status %08lx)\n", Status
);
2333 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2337 /* Set user information */
2338 ApiStatus
= SetUserInfo(UserHandle
,
2342 if (ApiStatus
!= NERR_Success
)
2344 ERR("SetUserInfo failed (Status %lu)\n", ApiStatus
);
2349 if (UserHandle
!= NULL
)
2351 if (ApiStatus
!= NERR_Success
)
2352 SamDeleteUser(UserHandle
);
2354 SamCloseHandle(UserHandle
);
2357 if (DomainHandle
!= NULL
)
2358 SamCloseHandle(DomainHandle
);
2360 if (ServerHandle
!= NULL
)
2361 SamCloseHandle(ServerHandle
);
2367 /******************************************************************************
2368 * NetUserChangePassword (NETAPI32.@)
2370 * domainname [I] Optional. Domain on which the user resides or the logon
2371 * domain of the current user if NULL.
2372 * username [I] Optional. Username to change the password for or the name
2373 * of the current user if NULL.
2374 * oldpassword [I] The user's current password.
2375 * newpassword [I] The password that the user will be changed to using.
2378 * Success: NERR_Success.
2379 * Failure: NERR_* failure code or win error code.
2384 NetUserChangePassword(LPCWSTR domainname
,
2386 LPCWSTR oldpassword
,
2387 LPCWSTR newpassword
)
2389 PMSV1_0_CHANGEPASSWORD_REQUEST RequestBuffer
= NULL
;
2390 PMSV1_0_CHANGEPASSWORD_RESPONSE ResponseBuffer
= NULL
;
2391 ULONG RequestBufferSize
;
2392 ULONG ResponseBufferSize
= 0;
2394 ANSI_STRING PackageName
;
2395 ULONG AuthenticationPackage
= 0;
2396 HANDLE LsaHandle
= NULL
;
2397 NET_API_STATUS ApiStatus
= NERR_Success
;
2398 NTSTATUS Status
= STATUS_SUCCESS
;
2399 NTSTATUS ProtocolStatus
;
2401 TRACE("(%s, %s, ..., ...)\n", debugstr_w(domainname
), debugstr_w(username
));
2403 /* FIXME: handle null domain or user name */
2405 /* Check the parameters */
2406 if ((oldpassword
== NULL
) ||
2407 (newpassword
== NULL
))
2408 return ERROR_INVALID_PARAMETER
;
2410 /* Connect to the LSA server */
2411 Status
= LsaConnectUntrusted(&LsaHandle
);
2412 if (!NT_SUCCESS(Status
))
2413 return NetpNtStatusToApiStatus(Status
);
2415 /* Get the authentication package ID */
2416 RtlInitAnsiString(&PackageName
,
2417 MSV1_0_PACKAGE_NAME
);
2419 Status
= LsaLookupAuthenticationPackage(LsaHandle
,
2421 &AuthenticationPackage
);
2422 if (!NT_SUCCESS(Status
))
2424 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2428 /* Calculate the request buffer size */
2429 RequestBufferSize
= sizeof(MSV1_0_CHANGEPASSWORD_REQUEST
) +
2430 ((wcslen(domainname
) + 1) * sizeof(WCHAR
)) +
2431 ((wcslen(username
) + 1) * sizeof(WCHAR
)) +
2432 ((wcslen(oldpassword
) + 1) * sizeof(WCHAR
)) +
2433 ((wcslen(newpassword
) + 1) * sizeof(WCHAR
));
2435 /* Allocate the request buffer */
2436 ApiStatus
= NetApiBufferAllocate(RequestBufferSize
,
2437 (PVOID
*)&RequestBuffer
);
2438 if (ApiStatus
!= NERR_Success
)
2441 /* Initialize the request buffer */
2442 RequestBuffer
->MessageType
= MsV1_0ChangePassword
;
2443 RequestBuffer
->Impersonating
= TRUE
;
2445 Ptr
= (LPWSTR
)((ULONG_PTR
)RequestBuffer
+ sizeof(MSV1_0_CHANGEPASSWORD_REQUEST
));
2447 /* Pack the domain name */
2448 RequestBuffer
->DomainName
.Length
= wcslen(domainname
) * sizeof(WCHAR
);
2449 RequestBuffer
->DomainName
.MaximumLength
= RequestBuffer
->DomainName
.Length
+ sizeof(WCHAR
);
2450 RequestBuffer
->DomainName
.Buffer
= Ptr
;
2452 RtlCopyMemory(RequestBuffer
->DomainName
.Buffer
,
2454 RequestBuffer
->DomainName
.MaximumLength
);
2456 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RequestBuffer
->DomainName
.MaximumLength
);
2458 /* Pack the user name */
2459 RequestBuffer
->AccountName
.Length
= wcslen(username
) * sizeof(WCHAR
);
2460 RequestBuffer
->AccountName
.MaximumLength
= RequestBuffer
->AccountName
.Length
+ sizeof(WCHAR
);
2461 RequestBuffer
->AccountName
.Buffer
= Ptr
;
2463 RtlCopyMemory(RequestBuffer
->AccountName
.Buffer
,
2465 RequestBuffer
->AccountName
.MaximumLength
);
2467 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RequestBuffer
->AccountName
.MaximumLength
);
2469 /* Pack the old password */
2470 RequestBuffer
->OldPassword
.Length
= wcslen(oldpassword
) * sizeof(WCHAR
);
2471 RequestBuffer
->OldPassword
.MaximumLength
= RequestBuffer
->OldPassword
.Length
+ sizeof(WCHAR
);
2472 RequestBuffer
->OldPassword
.Buffer
= Ptr
;
2474 RtlCopyMemory(RequestBuffer
->OldPassword
.Buffer
,
2476 RequestBuffer
->OldPassword
.MaximumLength
);
2478 Ptr
= (LPWSTR
)((ULONG_PTR
)Ptr
+ RequestBuffer
->OldPassword
.MaximumLength
);
2480 /* Pack the new password */
2481 RequestBuffer
->NewPassword
.Length
= wcslen(newpassword
) * sizeof(WCHAR
);
2482 RequestBuffer
->NewPassword
.MaximumLength
= RequestBuffer
->NewPassword
.Length
+ sizeof(WCHAR
);
2483 RequestBuffer
->NewPassword
.Buffer
= Ptr
;
2485 RtlCopyMemory(RequestBuffer
->NewPassword
.Buffer
,
2487 RequestBuffer
->NewPassword
.MaximumLength
);
2489 /* Call the authentication package */
2490 Status
= LsaCallAuthenticationPackage(LsaHandle
,
2491 AuthenticationPackage
,
2494 (PVOID
*)&ResponseBuffer
,
2495 &ResponseBufferSize
,
2497 if (!NT_SUCCESS(Status
))
2499 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2503 if (!NT_SUCCESS(ProtocolStatus
))
2505 ApiStatus
= NetpNtStatusToApiStatus(ProtocolStatus
);
2510 if (RequestBuffer
!= NULL
)
2511 NetApiBufferFree(RequestBuffer
);
2513 if (ResponseBuffer
!= NULL
)
2514 LsaFreeReturnBuffer(ResponseBuffer
);
2516 if (LsaHandle
!= NULL
)
2523 /************************************************************
2524 * NetUserDel (NETAPI32.@)
2528 NetUserDel(LPCWSTR servername
,
2531 UNICODE_STRING ServerName
;
2532 UNICODE_STRING UserName
;
2533 SAM_HANDLE ServerHandle
= NULL
;
2534 SAM_HANDLE DomainHandle
= NULL
;
2535 SAM_HANDLE UserHandle
= NULL
;
2536 NET_API_STATUS ApiStatus
= NERR_Success
;
2537 NTSTATUS Status
= STATUS_SUCCESS
;
2539 TRACE("(%s, %s)\n", debugstr_w(servername
), debugstr_w(username
));
2541 if (servername
!= NULL
)
2542 RtlInitUnicodeString(&ServerName
, servername
);
2544 RtlInitUnicodeString(&UserName
, username
);
2546 /* Connect to the SAM Server */
2547 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
2549 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
2551 if (!NT_SUCCESS(Status
))
2553 ERR("SamConnect failed (Status %08lx)\n", Status
);
2554 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2558 /* Open the Builtin Domain */
2559 Status
= OpenBuiltinDomain(ServerHandle
,
2562 if (!NT_SUCCESS(Status
))
2564 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status
);
2565 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2569 /* Open the user account in the builtin domain */
2570 ApiStatus
= OpenUserByName(DomainHandle
,
2574 if (ApiStatus
!= NERR_Success
&& ApiStatus
!= ERROR_NONE_MAPPED
)
2576 TRACE("OpenUserByName failed (ApiStatus %lu)\n", ApiStatus
);
2580 if (UserHandle
== NULL
)
2582 if (DomainHandle
!= NULL
)
2584 SamCloseHandle(DomainHandle
);
2585 DomainHandle
= NULL
;
2588 /* Open the Acount Domain */
2589 Status
= OpenAccountDomain(ServerHandle
,
2590 (servername
!= NULL
) ? &ServerName
: NULL
,
2593 if (!NT_SUCCESS(Status
))
2595 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
2596 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2600 /* Open the user account in the account domain */
2601 ApiStatus
= OpenUserByName(DomainHandle
,
2605 if (ApiStatus
!= NERR_Success
)
2607 ERR("OpenUserByName failed (ApiStatus %lu)\n", ApiStatus
);
2608 if (ApiStatus
== ERROR_NONE_MAPPED
)
2609 ApiStatus
= NERR_UserNotFound
;
2614 /* Delete the user */
2615 Status
= SamDeleteUser(UserHandle
);
2616 if (!NT_SUCCESS(Status
))
2618 ERR("SamDeleteUser failed (Status %08lx)\n", Status
);
2619 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2623 /* A successful delete invalidates the handle */
2627 if (UserHandle
!= NULL
)
2628 SamCloseHandle(UserHandle
);
2630 if (DomainHandle
!= NULL
)
2631 SamCloseHandle(DomainHandle
);
2633 if (ServerHandle
!= NULL
)
2634 SamCloseHandle(ServerHandle
);
2641 AllocateEnumContext(
2642 PENUM_CONTEXT
*AllocatedEnumContext
)
2644 NET_API_STATUS ApiStatus
;
2645 PENUM_CONTEXT EnumContext
;
2647 /* Allocate the context structure */
2648 ApiStatus
= NetApiBufferAllocate(sizeof(ENUM_CONTEXT
), (PVOID
*)&EnumContext
);
2649 if (ApiStatus
!= NERR_Success
)
2652 /* Initialize the fields */
2653 EnumContext
->EnumerationContext
= 0;
2654 EnumContext
->Buffer
= NULL
;
2655 EnumContext
->Count
= 0;
2656 EnumContext
->Index
= 0;
2657 EnumContext
->BuiltinDone
= FALSE
;
2659 /* Set a "unique" handle */
2660 EnumContext
->EnumHandle
= InterlockedIncrement(&g_EnumContextHandle
);
2661 if (EnumContext
->EnumHandle
== 0)
2663 EnumContext
->EnumHandle
= InterlockedIncrement(&g_EnumContextHandle
);
2666 /* Insert the context in the list */
2667 EnterCriticalSection(&g_EnumContextListLock
);
2668 InsertTailList(&g_EnumContextListHead
, &EnumContext
->ListLink
);
2669 LeaveCriticalSection(&g_EnumContextListLock
);
2671 *AllocatedEnumContext
= EnumContext
;
2672 return NERR_Success
;
2678 PENUM_CONTEXT EnumContext
)
2681 /* Remove the context from the list */
2682 EnterCriticalSection(&g_EnumContextListLock
);
2683 RemoveEntryList(&EnumContext
->ListLink
);
2684 LeaveCriticalSection(&g_EnumContextListLock
);
2687 NetApiBufferFree(EnumContext
);
2693 SAM_ENUMERATE_HANDLE EnumerationHandle
)
2695 PENUM_CONTEXT FoundEnumContext
= NULL
;
2696 PLIST_ENTRY ListEntry
;
2698 /* Acquire the list lock */
2699 EnterCriticalSection(&g_EnumContextListLock
);
2701 /* Search the list for the handle */
2702 for (ListEntry
= g_EnumContextListHead
.Flink
;
2703 ListEntry
!= &g_EnumContextListHead
;
2704 ListEntry
= ListEntry
->Flink
)
2706 PENUM_CONTEXT EnumContext
= CONTAINING_RECORD(ListEntry
, ENUM_CONTEXT
, ListLink
);
2707 if (EnumContext
->EnumHandle
== EnumerationHandle
)
2709 FoundEnumContext
= EnumContext
;
2714 /* Release the list lock */
2715 LeaveCriticalSection(&g_EnumContextListLock
);
2717 return FoundEnumContext
;
2720 /************************************************************
2721 * NetUserEnum (NETAPI32.@)
2725 NetUserEnum(LPCWSTR servername
,
2730 LPDWORD entriesread
,
2731 LPDWORD totalentries
,
2732 LPDWORD resume_handle
)
2734 UNICODE_STRING ServerName
;
2735 PSAM_RID_ENUMERATION CurrentUser
;
2736 PENUM_CONTEXT EnumContext
= NULL
;
2737 LPVOID Buffer
= NULL
;
2739 SAM_HANDLE UserHandle
= NULL
;
2740 ACCESS_MASK DesiredAccess
;
2741 NET_API_STATUS ApiStatus
= NERR_Success
;
2742 NTSTATUS Status
= STATUS_SUCCESS
;
2744 TRACE("(%s %d 0x%d %p %d %p %p %p)\n", debugstr_w(servername
), level
,
2745 filter
, bufptr
, prefmaxlen
, entriesread
, totalentries
, resume_handle
);
2751 if (servername
!= NULL
)
2752 RtlInitUnicodeString(&ServerName
, servername
);
2754 if (resume_handle
!= NULL
&& *resume_handle
!= 0)
2756 EnumContext
= LookupEnumContext(*resume_handle
);
2760 ApiStatus
= AllocateEnumContext(&EnumContext
);
2761 if (ApiStatus
!= NERR_Success
)
2764 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
2765 &EnumContext
->ServerHandle
,
2766 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
2768 if (!NT_SUCCESS(Status
))
2770 ERR("SamConnect failed (Status %08lx)\n", Status
);
2771 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2775 /* Get the Account Domain SID */
2776 Status
= GetAccountDomainSid((servername
!= NULL
) ? &ServerName
: NULL
,
2777 &EnumContext
->AccountDomainSid
);
2778 if (!NT_SUCCESS(Status
))
2780 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status
);
2781 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2785 /* Open the Account Domain */
2786 Status
= SamOpenDomain(EnumContext
->ServerHandle
,
2787 DOMAIN_LIST_ACCOUNTS
| DOMAIN_LOOKUP
,
2788 EnumContext
->AccountDomainSid
,
2789 &EnumContext
->AccountDomainHandle
);
2790 if (!NT_SUCCESS(Status
))
2792 ERR("SamOpenDomain failed (Status %08lx)\n", Status
);
2793 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2797 /* Get the Builtin Domain SID */
2798 Status
= GetBuiltinDomainSid(&EnumContext
->BuiltinDomainSid
);
2799 if (!NT_SUCCESS(Status
))
2801 ERR("GetBuiltinDomainSid failed (Status %08lx)\n", Status
);
2802 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2806 DesiredAccess
= DOMAIN_LIST_ACCOUNTS
| DOMAIN_LOOKUP
;
2807 if ((level
== 1) || (level
== 2) || (level
== 3) || (level
== 4) || (level
== 11))
2808 DesiredAccess
|= DOMAIN_GET_ALIAS_MEMBERSHIP
;
2810 /* Open the Builtin Domain */
2811 Status
= SamOpenDomain(EnumContext
->ServerHandle
,
2813 EnumContext
->BuiltinDomainSid
,
2814 &EnumContext
->BuiltinDomainHandle
);
2815 if (!NT_SUCCESS(Status
))
2817 ERR("SamOpenDomain failed (Status %08lx)\n", Status
);
2818 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2825 TRACE("EnumContext->Index: %lu\n", EnumContext
->Index
);
2826 TRACE("EnumContext->Count: %lu\n", EnumContext
->Count
);
2828 if (EnumContext
->Index
>= EnumContext
->Count
)
2830 // if (EnumContext->BuiltinDone != FALSE)
2832 // ApiStatus = NERR_Success;
2836 TRACE("Calling SamEnumerateUsersInDomain\n");
2837 Status
= SamEnumerateUsersInDomain(EnumContext
->AccountDomainHandle
, //BuiltinDomainHandle,
2838 &EnumContext
->EnumerationContext
,
2840 (PVOID
*)&EnumContext
->Buffer
,
2842 &EnumContext
->Count
);
2844 TRACE("SamEnumerateUsersInDomain returned (Status %08lx)\n", Status
);
2845 if (!NT_SUCCESS(Status
))
2847 ERR("SamEnumerateUsersInDomain failed (Status %08lx)\n", Status
);
2848 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2852 if (Status
== STATUS_MORE_ENTRIES
)
2854 ApiStatus
= NERR_BufTooSmall
;
2859 EnumContext
->BuiltinDone
= TRUE
;
2863 TRACE("EnumContext: %lu\n", EnumContext
);
2864 TRACE("EnumContext->Count: %lu\n", EnumContext
->Count
);
2865 TRACE("EnumContext->Buffer: %p\n", EnumContext
->Buffer
);
2867 /* Get a pointer to the current user */
2868 CurrentUser
= &EnumContext
->Buffer
[EnumContext
->Index
];
2870 TRACE("RID: %lu\n", CurrentUser
->RelativeId
);
2872 DesiredAccess
= READ_CONTROL
| USER_READ_GENERAL
| USER_READ_PREFERENCES
| USER_READ_LOGON
| USER_READ_ACCOUNT
;
2873 if ((level
== 1) || (level
== 2) || (level
== 3) || (level
== 4) || (level
== 11))
2874 DesiredAccess
|= USER_LIST_GROUPS
;
2876 Status
= SamOpenUser(EnumContext
->AccountDomainHandle
, //BuiltinDomainHandle,
2878 CurrentUser
->RelativeId
,
2880 if (!NT_SUCCESS(Status
))
2882 ERR("SamOpenUser failed (Status %08lx)\n", Status
);
2883 ApiStatus
= NetpNtStatusToApiStatus(Status
);
2887 ApiStatus
= BuildUserInfoBuffer(EnumContext
->BuiltinDomainHandle
,
2889 EnumContext
->AccountDomainSid
,
2890 CurrentUser
->RelativeId
,
2893 if (ApiStatus
!= NERR_Success
)
2895 ERR("BuildUserInfoBuffer failed (ApiStatus %lu)\n", ApiStatus
);
2899 SamCloseHandle(UserHandle
);
2902 EnumContext
->Index
++;
2908 if (ApiStatus
== NERR_Success
&& EnumContext
!= NULL
&& EnumContext
->Index
< EnumContext
->Count
)
2909 ApiStatus
= ERROR_MORE_DATA
;
2911 if (EnumContext
!= NULL
)
2912 *totalentries
= EnumContext
->Count
;
2914 if (resume_handle
== NULL
|| ApiStatus
!= ERROR_MORE_DATA
)
2916 if (EnumContext
!= NULL
)
2918 if (EnumContext
->BuiltinDomainHandle
!= NULL
)
2919 SamCloseHandle(EnumContext
->BuiltinDomainHandle
);
2921 if (EnumContext
->AccountDomainHandle
!= NULL
)
2922 SamCloseHandle(EnumContext
->AccountDomainHandle
);
2924 if (EnumContext
->BuiltinDomainSid
!= NULL
)
2925 RtlFreeHeap(RtlGetProcessHeap(), 0, EnumContext
->BuiltinDomainSid
);
2927 if (EnumContext
->AccountDomainSid
!= NULL
)
2928 RtlFreeHeap(RtlGetProcessHeap(), 0, EnumContext
->AccountDomainSid
);
2930 if (EnumContext
->ServerHandle
!= NULL
)
2931 SamCloseHandle(EnumContext
->ServerHandle
);
2933 if (EnumContext
->Buffer
!= NULL
)
2935 for (i
= 0; i
< EnumContext
->Count
; i
++)
2937 SamFreeMemory(EnumContext
->Buffer
[i
].Name
.Buffer
);
2940 SamFreeMemory(EnumContext
->Buffer
);
2943 FreeEnumContext(EnumContext
);
2948 if (UserHandle
!= NULL
)
2949 SamCloseHandle(UserHandle
);
2951 if (resume_handle
!= NULL
)
2952 *resume_handle
= EnumContext
? EnumContext
->EnumHandle
: 0;
2954 *bufptr
= (LPBYTE
)Buffer
;
2956 TRACE("return %lu\n", ApiStatus
);
2962 /************************************************************
2963 * NetUserGetGroups (NETAPI32.@)
2967 NetUserGetGroups(LPCWSTR servername
,
2972 LPDWORD entriesread
,
2973 LPDWORD totalentries
)
2975 UNICODE_STRING ServerName
;
2976 UNICODE_STRING UserName
;
2977 SAM_HANDLE ServerHandle
= NULL
;
2978 SAM_HANDLE AccountDomainHandle
= NULL
;
2979 SAM_HANDLE UserHandle
= NULL
;
2980 PSID AccountDomainSid
= NULL
;
2981 PULONG RelativeIds
= NULL
;
2982 PSID_NAME_USE Use
= NULL
;
2983 PGROUP_MEMBERSHIP GroupMembership
= NULL
;
2986 NET_API_STATUS ApiStatus
= NERR_Success
;
2987 NTSTATUS Status
= STATUS_SUCCESS
;
2989 TRACE("%s %s %d %p %d %p %p stub\n", debugstr_w(servername
),
2990 debugstr_w(username
), level
, bufptr
, prefixmaxlen
, entriesread
,
2993 if (servername
!= NULL
)
2994 RtlInitUnicodeString(&ServerName
, servername
);
2996 RtlInitUnicodeString(&UserName
, username
);
2998 /* Connect to the SAM Server */
2999 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
3001 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
3003 if (!NT_SUCCESS(Status
))
3005 ERR("SamConnect failed (Status %08lx)\n", Status
);
3006 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3010 /* Get the Account Domain SID */
3011 Status
= GetAccountDomainSid((servername
!= NULL
) ? &ServerName
: NULL
,
3013 if (!NT_SUCCESS(Status
))
3015 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status
);
3016 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3020 /* Open the Account Domain */
3021 Status
= SamOpenDomain(ServerHandle
,
3022 DOMAIN_LOOKUP
| DOMAIN_GET_ALIAS_MEMBERSHIP
,
3024 &AccountDomainHandle
);
3025 if (!NT_SUCCESS(Status
))
3027 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
3028 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3032 /* Get the RID for the given user name */
3033 Status
= SamLookupNamesInDomain(AccountDomainHandle
,
3038 if (!NT_SUCCESS(Status
))
3040 ERR("SamLookupNamesInDomain failed (Status %08lx)\n", Status
);
3041 if (Status
== STATUS_NONE_MAPPED
)
3042 ApiStatus
= NERR_UserNotFound
;
3044 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3048 /* Fail, if it is not a user account */
3049 if (Use
[0] != SidTypeUser
)
3051 ERR("Account is not a User!\n");
3052 ApiStatus
= NERR_UserNotFound
;
3056 /* Open the user object */
3057 Status
= SamOpenUser(AccountDomainHandle
,
3061 if (!NT_SUCCESS(Status
))
3063 ERR("SamOpenUser failed (Status %08lx)\n", Status
);
3064 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3068 /* Get the group memberships of this user */
3069 Status
= SamGetGroupsForUser(UserHandle
,
3072 if (!NT_SUCCESS(Status
))
3074 ERR("SamGetGroupsForUser failed (Status %08lx)\n", Status
);
3075 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3079 /* If there is no group membership, we're done */
3080 if (GroupCount
== 0)
3082 ApiStatus
= NERR_Success
;
3089 if (GroupMembership
!= NULL
)
3090 SamFreeMemory(GroupMembership
);
3092 if (UserHandle
!= NULL
)
3093 SamCloseHandle(UserHandle
);
3095 if (RelativeIds
!= NULL
)
3096 SamFreeMemory(RelativeIds
);
3101 if (AccountDomainSid
!= NULL
)
3102 RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid
);
3104 if (AccountDomainHandle
!= NULL
)
3105 SamCloseHandle(AccountDomainHandle
);
3107 if (ServerHandle
!= NULL
)
3108 SamCloseHandle(ServerHandle
);
3110 if (ApiStatus
!= NERR_Success
&& ApiStatus
!= ERROR_MORE_DATA
)
3117 // *entriesread = Count;
3118 // *totalentries = Count;
3121 // *bufptr = (LPBYTE)Buffer;
3127 /************************************************************
3128 * NetUserGetInfo (NETAPI32.@)
3132 NetUserGetInfo(LPCWSTR servername
,
3137 UNICODE_STRING ServerName
;
3138 UNICODE_STRING UserName
;
3139 SAM_HANDLE ServerHandle
= NULL
;
3140 SAM_HANDLE AccountDomainHandle
= NULL
;
3141 SAM_HANDLE BuiltinDomainHandle
= NULL
;
3142 SAM_HANDLE UserHandle
= NULL
;
3143 PULONG RelativeIds
= NULL
;
3144 PSID_NAME_USE Use
= NULL
;
3145 LPVOID Buffer
= NULL
;
3146 PSID AccountDomainSid
= NULL
;
3147 PSID BuiltinDomainSid
= NULL
;
3148 ACCESS_MASK DesiredAccess
;
3149 NET_API_STATUS ApiStatus
= NERR_Success
;
3150 NTSTATUS Status
= STATUS_SUCCESS
;
3152 TRACE("(%s, %s, %d, %p)\n", debugstr_w(servername
),
3153 debugstr_w(username
), level
, bufptr
);
3155 if (servername
!= NULL
)
3156 RtlInitUnicodeString(&ServerName
, servername
);
3158 RtlInitUnicodeString(&UserName
, username
);
3160 /* Connect to the SAM Server */
3161 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
3163 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
3165 if (!NT_SUCCESS(Status
))
3167 ERR("SamConnect failed (Status %08lx)\n", Status
);
3168 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3172 /* Get the Builtin Domain SID */
3173 Status
= GetBuiltinDomainSid(&BuiltinDomainSid
);
3174 if (!NT_SUCCESS(Status
))
3176 ERR("GetBuiltinDomainSid failed (Status %08lx)\n", Status
);
3177 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3181 DesiredAccess
= DOMAIN_LIST_ACCOUNTS
| DOMAIN_LOOKUP
;
3182 if ((level
== 1) || (level
== 2) || (level
== 3) || (level
== 4) || (level
== 11))
3183 DesiredAccess
|= DOMAIN_GET_ALIAS_MEMBERSHIP
;
3185 /* Open the Builtin Domain */
3186 Status
= SamOpenDomain(ServerHandle
,
3189 &BuiltinDomainHandle
);
3190 if (!NT_SUCCESS(Status
))
3192 ERR("SamOpenDomain failed (Status %08lx)\n", Status
);
3193 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3197 /* Get the Account Domain SID */
3198 Status
= GetAccountDomainSid((servername
!= NULL
) ? &ServerName
: NULL
,
3200 if (!NT_SUCCESS(Status
))
3202 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status
);
3203 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3207 /* Open the Account Domain */
3208 Status
= SamOpenDomain(ServerHandle
,
3209 DOMAIN_LIST_ACCOUNTS
| DOMAIN_LOOKUP
,
3211 &AccountDomainHandle
);
3212 if (!NT_SUCCESS(Status
))
3214 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
3215 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3219 /* Get the RID for the given user name */
3220 Status
= SamLookupNamesInDomain(AccountDomainHandle
,
3225 if (!NT_SUCCESS(Status
))
3227 ERR("SamOpenDomain failed (Status %08lx)\n", Status
);
3228 if (Status
== STATUS_NONE_MAPPED
)
3229 ApiStatus
= NERR_UserNotFound
;
3231 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3235 /* Check if the account is a user account */
3236 if (Use
[0] != SidTypeUser
)
3238 ERR("No user found!\n");
3239 ApiStatus
= NERR_UserNotFound
;
3243 TRACE("RID: %lu\n", RelativeIds
[0]);
3245 DesiredAccess
= READ_CONTROL
| USER_READ_GENERAL
| USER_READ_PREFERENCES
| USER_READ_LOGON
| USER_READ_ACCOUNT
;
3246 if ((level
== 1) || (level
== 2) || (level
== 3) || (level
== 4) || (level
== 11))
3247 DesiredAccess
|= USER_LIST_GROUPS
;
3249 /* Open the user object */
3250 Status
= SamOpenUser(AccountDomainHandle
,
3254 if (!NT_SUCCESS(Status
))
3256 ERR("SamOpenUser failed (Status %08lx)\n", Status
);
3257 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3261 ApiStatus
= BuildUserInfoBuffer(BuiltinDomainHandle
,
3267 if (ApiStatus
!= NERR_Success
)
3269 ERR("BuildUserInfoBuffer failed (ApiStatus %08lu)\n", ApiStatus
);
3274 if (UserHandle
!= NULL
)
3275 SamCloseHandle(UserHandle
);
3277 if (RelativeIds
!= NULL
)
3278 SamFreeMemory(RelativeIds
);
3283 if (AccountDomainHandle
!= NULL
)
3284 SamCloseHandle(AccountDomainHandle
);
3286 if (AccountDomainSid
!= NULL
)
3287 RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid
);
3289 if (BuiltinDomainHandle
!= NULL
)
3290 SamCloseHandle(BuiltinDomainHandle
);
3292 if (BuiltinDomainSid
!= NULL
)
3293 RtlFreeHeap(RtlGetProcessHeap(), 0, BuiltinDomainSid
);
3295 if (ServerHandle
!= NULL
)
3296 SamCloseHandle(ServerHandle
);
3298 *bufptr
= (LPBYTE
)Buffer
;
3304 /************************************************************
3305 * NetUserGetLocalGroups (NETAPI32.@)
3309 NetUserGetLocalGroups(LPCWSTR servername
,
3315 LPDWORD entriesread
,
3316 LPDWORD totalentries
)
3318 UNICODE_STRING ServerName
;
3319 UNICODE_STRING UserName
;
3320 SAM_HANDLE ServerHandle
= NULL
;
3321 SAM_HANDLE BuiltinDomainHandle
= NULL
;
3322 SAM_HANDLE AccountDomainHandle
= NULL
;
3323 PSID AccountDomainSid
= NULL
;
3324 PSID UserSid
= NULL
;
3325 PULONG RelativeIds
= NULL
;
3326 PSID_NAME_USE Use
= NULL
;
3327 ULONG BuiltinMemberCount
= 0;
3328 ULONG AccountMemberCount
= 0;
3329 PULONG BuiltinAliases
= NULL
;
3330 PULONG AccountAliases
= NULL
;
3331 PUNICODE_STRING BuiltinNames
= NULL
;
3332 PUNICODE_STRING AccountNames
= NULL
;
3333 PLOCALGROUP_USERS_INFO_0 Buffer
= NULL
;
3339 NET_API_STATUS ApiStatus
= NERR_Success
;
3340 NTSTATUS Status
= STATUS_SUCCESS
;
3342 TRACE("(%s, %s, %d, %08x, %p %d, %p, %p) stub!\n",
3343 debugstr_w(servername
), debugstr_w(username
), level
, flags
, bufptr
,
3344 prefmaxlen
, entriesread
, totalentries
);
3347 return ERROR_INVALID_LEVEL
;
3349 if (flags
& ~LG_INCLUDE_INDIRECT
)
3350 return ERROR_INVALID_PARAMETER
;
3352 if (flags
& LG_INCLUDE_INDIRECT
)
3354 WARN("The flag LG_INCLUDE_INDIRECT is not supported yet!\n");
3357 if (servername
!= NULL
)
3358 RtlInitUnicodeString(&ServerName
, servername
);
3360 RtlInitUnicodeString(&UserName
, username
);
3362 /* Connect to the SAM Server */
3363 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
3365 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
3367 if (!NT_SUCCESS(Status
))
3369 ERR("SamConnect failed (Status %08lx)\n", Status
);
3370 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3374 /* Open the Builtin Domain */
3375 Status
= OpenBuiltinDomain(ServerHandle
,
3376 DOMAIN_LOOKUP
| DOMAIN_GET_ALIAS_MEMBERSHIP
,
3377 &BuiltinDomainHandle
);
3378 if (!NT_SUCCESS(Status
))
3380 ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status
);
3381 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3385 /* Get the Account Domain SID */
3386 Status
= GetAccountDomainSid((servername
!= NULL
) ? &ServerName
: NULL
,
3388 if (!NT_SUCCESS(Status
))
3390 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status
);
3391 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3395 /* Open the Account Domain */
3396 Status
= SamOpenDomain(ServerHandle
,
3397 DOMAIN_LOOKUP
| DOMAIN_GET_ALIAS_MEMBERSHIP
,
3399 &AccountDomainHandle
);
3400 if (!NT_SUCCESS(Status
))
3402 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
3403 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3407 /* Get the RID for the given user name */
3408 Status
= SamLookupNamesInDomain(AccountDomainHandle
,
3413 if (!NT_SUCCESS(Status
))
3415 ERR("SamLookupNamesInDomain failed (Status %08lx)\n", Status
);
3416 if (Status
== STATUS_NONE_MAPPED
)
3417 ApiStatus
= NERR_UserNotFound
;
3419 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3423 /* Fail, if it is not a user account */
3424 if (Use
[0] != SidTypeUser
)
3426 ERR("Account is not a User!\n");
3427 ApiStatus
= NERR_UserNotFound
;
3431 /* Build the User SID from the Account Domain SID and the users RID */
3432 ApiStatus
= BuildSidFromSidAndRid(AccountDomainSid
,
3435 if (ApiStatus
!= NERR_Success
)
3437 ERR("BuildSidFromSidAndRid failed!\n");
3441 /* Get alias memberships in the Builtin Domain */
3442 Status
= SamGetAliasMembership(BuiltinDomainHandle
,
3445 &BuiltinMemberCount
,
3447 if (!NT_SUCCESS(Status
))
3449 ERR("SamGetAliasMembership failed (Status %08lx)\n", Status
);
3450 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3454 if (BuiltinMemberCount
> 0)
3456 /* Get the Names of the builtin alias members */
3457 Status
= SamLookupIdsInDomain(BuiltinDomainHandle
,
3462 if (!NT_SUCCESS(Status
))
3464 ERR("SamLookupIdsInDomain failed (Status %08lx)\n", Status
);
3465 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3470 /* Get alias memberships in the Account Domain */
3471 Status
= SamGetAliasMembership(AccountDomainHandle
,
3474 &AccountMemberCount
,
3476 if (!NT_SUCCESS(Status
))
3478 ERR("SamGetAliasMembership failed (Status %08lx)\n", Status
);
3479 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3483 if (AccountMemberCount
> 0)
3485 /* Get the Names of the builtin alias members */
3486 Status
= SamLookupIdsInDomain(AccountDomainHandle
,
3491 if (!NT_SUCCESS(Status
))
3493 ERR("SamLookupIdsInDomain failed (Status %08lx)\n", Status
);
3494 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3499 /* Calculate the required buffer size */
3502 for (i
= 0; i
< BuiltinMemberCount
; i
++)
3504 if (BuiltinNames
[i
].Length
> 0)
3506 Size
+= (sizeof(LOCALGROUP_USERS_INFO_0
) + BuiltinNames
[i
].Length
+ sizeof(UNICODE_NULL
));
3511 for (i
= 0; i
< AccountMemberCount
; i
++)
3513 if (AccountNames
[i
].Length
> 0)
3515 Size
+= (sizeof(LOCALGROUP_USERS_INFO_0
) + AccountNames
[i
].Length
+ sizeof(UNICODE_NULL
));
3522 ApiStatus
= NERR_Success
;
3526 /* Allocate buffer */
3527 ApiStatus
= NetApiBufferAllocate(Size
, (LPVOID
*)&Buffer
);
3528 if (ApiStatus
!= NERR_Success
)
3531 ZeroMemory(Buffer
, Size
);
3533 StrPtr
= (LPWSTR
)((INT_PTR
)Buffer
+ Count
* sizeof(LOCALGROUP_USERS_INFO_0
));
3535 /* Copy data to the allocated buffer */
3537 for (i
= 0; i
< BuiltinMemberCount
; i
++)
3539 if (BuiltinNames
[i
].Length
> 0)
3542 BuiltinNames
[i
].Buffer
,
3543 BuiltinNames
[i
].Length
);
3544 Buffer
[Index
].lgrui0_name
= StrPtr
;
3546 StrPtr
= (LPWSTR
)((INT_PTR
)StrPtr
+ BuiltinNames
[i
].Length
+ sizeof(UNICODE_NULL
));
3551 for (i
= 0; i
< AccountMemberCount
; i
++)
3553 if (AccountNames
[i
].Length
> 0)
3556 AccountNames
[i
].Buffer
,
3557 AccountNames
[i
].Length
);
3558 Buffer
[Index
].lgrui0_name
= StrPtr
;
3560 StrPtr
= (LPWSTR
)((INT_PTR
)StrPtr
+ AccountNames
[i
].Length
+ sizeof(UNICODE_NULL
));
3566 if (AccountNames
!= NULL
)
3567 SamFreeMemory(AccountNames
);
3569 if (BuiltinNames
!= NULL
)
3570 SamFreeMemory(BuiltinNames
);
3572 if (AccountAliases
!= NULL
)
3573 SamFreeMemory(AccountAliases
);
3575 if (BuiltinAliases
!= NULL
)
3576 SamFreeMemory(BuiltinAliases
);
3578 if (RelativeIds
!= NULL
)
3579 SamFreeMemory(RelativeIds
);
3584 if (UserSid
!= NULL
)
3585 NetApiBufferFree(UserSid
);
3587 if (AccountDomainSid
!= NULL
)
3588 RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid
);
3590 if (AccountDomainHandle
!= NULL
)
3591 SamCloseHandle(AccountDomainHandle
);
3593 if (BuiltinDomainHandle
!= NULL
)
3594 SamCloseHandle(BuiltinDomainHandle
);
3596 if (ServerHandle
!= NULL
)
3597 SamCloseHandle(ServerHandle
);
3599 if (ApiStatus
!= NERR_Success
&& ApiStatus
!= ERROR_MORE_DATA
)
3606 *entriesread
= Count
;
3607 *totalentries
= Count
;
3610 *bufptr
= (LPBYTE
)Buffer
;
3616 /******************************************************************************
3617 * NetUserModalsGet (NETAPI32.@)
3619 * Retrieves global information for all users and global groups in the security
3623 * servername [I] Specifies the DNS or the NetBIOS name of the remote server
3624 * on which the function is to execute.
3625 * level [I] Information level of the data.
3626 * 0 Return global passwords parameters. bufptr points to a
3627 * USER_MODALS_INFO_0 struct.
3628 * 1 Return logon server and domain controller information. bufptr
3629 * points to a USER_MODALS_INFO_1 struct.
3630 * 2 Return domain name and identifier. bufptr points to a
3631 * USER_MODALS_INFO_2 struct.
3632 * 3 Return lockout information. bufptr points to a USER_MODALS_INFO_3
3634 * bufptr [O] Buffer that receives the data.
3637 * Success: NERR_Success.
3639 * ERROR_ACCESS_DENIED - the user does not have access to the info.
3640 * NERR_InvalidComputer - computer name is invalid.
3644 NetUserModalsGet(LPCWSTR servername
,
3648 UNICODE_STRING ServerName
;
3649 SAM_HANDLE ServerHandle
= NULL
;
3650 SAM_HANDLE DomainHandle
= NULL
;
3651 PSID DomainSid
= NULL
;
3652 PDOMAIN_PASSWORD_INFORMATION PasswordInfo
= NULL
;
3653 PDOMAIN_LOGOFF_INFORMATION LogoffInfo
= NULL
;
3654 PDOMAIN_SERVER_ROLE_INFORMATION ServerRoleInfo
= NULL
;
3655 PDOMAIN_REPLICATION_INFORMATION ReplicationInfo
= NULL
;
3656 PDOMAIN_NAME_INFORMATION NameInfo
= NULL
;
3657 PDOMAIN_LOCKOUT_INFORMATION LockoutInfo
= NULL
;
3658 ULONG DesiredAccess
;
3660 PUSER_MODALS_INFO_0 umi0
;
3661 PUSER_MODALS_INFO_1 umi1
;
3662 PUSER_MODALS_INFO_2 umi2
;
3663 PUSER_MODALS_INFO_3 umi3
;
3664 NET_API_STATUS ApiStatus
= NERR_Success
;
3665 NTSTATUS Status
= STATUS_SUCCESS
;
3667 TRACE("(%s %d %p)\n", debugstr_w(servername
), level
, bufptr
);
3671 if (servername
!= NULL
)
3672 RtlInitUnicodeString(&ServerName
, servername
);
3674 /* Connect to the SAM Server */
3675 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
3677 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
3679 if (!NT_SUCCESS(Status
))
3681 ERR("SamConnect failed (Status %08lx)\n", Status
);
3682 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3686 /* Get the Account Domain SID */
3687 Status
= GetAccountDomainSid((servername
!= NULL
) ? &ServerName
: NULL
,
3689 if (!NT_SUCCESS(Status
))
3691 ERR("GetAccountDomainSid failed (Status %08lx)\n", Status
);
3692 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3699 DesiredAccess
= DOMAIN_READ_OTHER_PARAMETERS
| DOMAIN_READ_PASSWORD_PARAMETERS
;
3703 DesiredAccess
= DOMAIN_READ_OTHER_PARAMETERS
;
3707 DesiredAccess
= DOMAIN_READ_OTHER_PARAMETERS
;
3711 DesiredAccess
= DOMAIN_READ_PASSWORD_PARAMETERS
;
3715 ApiStatus
= ERROR_INVALID_LEVEL
;
3719 /* Open the Account Domain */
3720 Status
= SamOpenDomain(ServerHandle
,
3724 if (!NT_SUCCESS(Status
))
3726 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
3727 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3734 /* return global passwords parameters */
3735 Status
= SamQueryInformationDomain(DomainHandle
,
3736 DomainPasswordInformation
,
3737 (PVOID
*)&PasswordInfo
);
3738 if (!NT_SUCCESS(Status
))
3740 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3744 Status
= SamQueryInformationDomain(DomainHandle
,
3745 DomainLogoffInformation
,
3746 (PVOID
*)&LogoffInfo
);
3747 if (!NT_SUCCESS(Status
))
3749 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3753 BufferSize
= sizeof(USER_MODALS_INFO_0
);
3757 /* return logon server and domain controller info */
3758 Status
= SamQueryInformationDomain(DomainHandle
,
3759 DomainServerRoleInformation
,
3760 (PVOID
*)&ServerRoleInfo
);
3761 if (!NT_SUCCESS(Status
))
3763 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3767 Status
= SamQueryInformationDomain(DomainHandle
,
3768 DomainReplicationInformation
,
3769 (PVOID
*)&ReplicationInfo
);
3770 if (!NT_SUCCESS(Status
))
3772 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3776 BufferSize
= sizeof(USER_MODALS_INFO_1
) +
3777 ReplicationInfo
->ReplicaSourceNodeName
.Length
+ sizeof(WCHAR
);
3781 /* return domain name and identifier */
3782 Status
= SamQueryInformationDomain(DomainHandle
,
3783 DomainNameInformation
,
3785 if (!NT_SUCCESS(Status
))
3787 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3791 BufferSize
= sizeof( USER_MODALS_INFO_2
) +
3792 NameInfo
->DomainName
.Length
+ sizeof(WCHAR
) +
3793 RtlLengthSid(DomainSid
);
3797 /* return lockout information */
3798 Status
= SamQueryInformationDomain(DomainHandle
,
3799 DomainLockoutInformation
,
3800 (PVOID
*)&LockoutInfo
);
3801 if (!NT_SUCCESS(Status
))
3803 ApiStatus
= NetpNtStatusToApiStatus(Status
);
3807 BufferSize
= sizeof(USER_MODALS_INFO_3
);
3811 TRACE("Invalid level %d is specified\n", level
);
3812 ApiStatus
= ERROR_INVALID_LEVEL
;
3817 ApiStatus
= NetApiBufferAllocate(BufferSize
,
3819 if (ApiStatus
!= NERR_Success
)
3821 WARN("NetApiBufferAllocate() failed\n");
3828 umi0
= (PUSER_MODALS_INFO_0
)*bufptr
;
3830 umi0
->usrmod0_min_passwd_len
= PasswordInfo
->MinPasswordLength
;
3831 umi0
->usrmod0_max_passwd_age
= (ULONG
)(-PasswordInfo
->MaxPasswordAge
.QuadPart
/ 10000000);
3832 umi0
->usrmod0_min_passwd_age
=
3833 DeltaTimeToSeconds(PasswordInfo
->MinPasswordAge
);
3834 umi0
->usrmod0_force_logoff
=
3835 DeltaTimeToSeconds(LogoffInfo
->ForceLogoff
);
3836 umi0
->usrmod0_password_hist_len
= PasswordInfo
->PasswordHistoryLength
;
3840 umi1
= (PUSER_MODALS_INFO_1
)*bufptr
;
3842 switch (ServerRoleInfo
->DomainServerRole
)
3844 case DomainServerRolePrimary
:
3845 umi1
->usrmod1_role
= UAS_ROLE_PRIMARY
;
3848 case DomainServerRoleBackup
:
3849 umi1
->usrmod1_role
= UAS_ROLE_BACKUP
;
3853 ApiStatus
= NERR_InternalError
;
3857 umi1
->usrmod1_primary
= (LPWSTR
)(*bufptr
+ sizeof(USER_MODALS_INFO_1
));
3858 RtlCopyMemory(umi1
->usrmod1_primary
,
3859 ReplicationInfo
->ReplicaSourceNodeName
.Buffer
,
3860 ReplicationInfo
->ReplicaSourceNodeName
.Length
);
3861 umi1
->usrmod1_primary
[ReplicationInfo
->ReplicaSourceNodeName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
3865 umi2
= (PUSER_MODALS_INFO_2
)*bufptr
;
3867 umi2
->usrmod2_domain_name
= (LPWSTR
)(*bufptr
+ sizeof(USER_MODALS_INFO_2
));
3868 RtlCopyMemory(umi2
->usrmod2_domain_name
,
3869 NameInfo
->DomainName
.Buffer
,
3870 NameInfo
->DomainName
.Length
);
3871 umi2
->usrmod2_domain_name
[NameInfo
->DomainName
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
3873 umi2
->usrmod2_domain_id
= *bufptr
+
3874 sizeof(USER_MODALS_INFO_2
) +
3875 NameInfo
->DomainName
.Length
+ sizeof(WCHAR
);
3876 RtlCopyMemory(umi2
->usrmod2_domain_id
,
3878 RtlLengthSid(DomainSid
));
3882 umi3
= (PUSER_MODALS_INFO_3
)*bufptr
;
3883 umi3
->usrmod3_lockout_duration
=
3884 DeltaTimeToSeconds(LockoutInfo
->LockoutDuration
);
3885 umi3
->usrmod3_lockout_observation_window
=
3886 DeltaTimeToSeconds(LockoutInfo
->LockoutObservationWindow
);
3887 umi3
->usrmod3_lockout_threshold
= LockoutInfo
->LockoutThreshold
;
3892 if (LockoutInfo
!= NULL
)
3893 SamFreeMemory(LockoutInfo
);
3895 if (NameInfo
!= NULL
)
3896 SamFreeMemory(NameInfo
);
3898 if (ReplicationInfo
!= NULL
)
3899 SamFreeMemory(ReplicationInfo
);
3901 if (ServerRoleInfo
!= NULL
)
3902 SamFreeMemory(ServerRoleInfo
);
3904 if (LogoffInfo
!= NULL
)
3905 SamFreeMemory(LogoffInfo
);
3907 if (PasswordInfo
!= NULL
)
3908 SamFreeMemory(PasswordInfo
);
3910 if (DomainSid
!= NULL
)
3911 RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid
);
3913 if (DomainHandle
!= NULL
)
3914 SamCloseHandle(DomainHandle
);
3916 if (ServerHandle
!= NULL
)
3917 SamCloseHandle(ServerHandle
);
3923 /******************************************************************************
3924 * NetUserModalsSet (NETAPI32.@)
3928 NetUserModalsSet(IN LPCWSTR servername
,
3931 OUT LPDWORD parm_err
)
3933 FIXME("(%s %d %p %p)\n", debugstr_w(servername
), level
, buf
, parm_err
);
3934 return ERROR_ACCESS_DENIED
;
3938 /******************************************************************************
3939 * NetUserSetGroups (NETAPI32.@)
3943 NetUserSetGroups(LPCWSTR servername
,
3949 FIXME("(%s %s %lu %p %lu)\n",
3950 debugstr_w(servername
), debugstr_w(username
), level
, buf
, num_entries
);
3951 return ERROR_ACCESS_DENIED
;
3955 /******************************************************************************
3956 * NetUserSetInfo (NETAPI32.@)
3960 NetUserSetInfo(LPCWSTR servername
,
3966 UNICODE_STRING ServerName
;
3967 UNICODE_STRING UserName
;
3968 SAM_HANDLE ServerHandle
= NULL
;
3969 SAM_HANDLE AccountDomainHandle
= NULL
;
3970 SAM_HANDLE UserHandle
= NULL
;
3971 NET_API_STATUS ApiStatus
= NERR_Success
;
3972 NTSTATUS Status
= STATUS_SUCCESS
;
3974 TRACE("(%s %s %lu %p %p)\n",
3975 debugstr_w(servername
), debugstr_w(username
), level
, buf
, parm_err
);
3977 if (parm_err
!= NULL
)
3978 *parm_err
= PARM_ERROR_NONE
;
3980 /* Check the info level */
4012 return ERROR_INVALID_LEVEL
;
4015 if (servername
!= NULL
)
4016 RtlInitUnicodeString(&ServerName
, servername
);
4018 RtlInitUnicodeString(&UserName
, username
);
4020 /* Connect to the SAM Server */
4021 Status
= SamConnect((servername
!= NULL
) ? &ServerName
: NULL
,
4023 SAM_SERVER_CONNECT
| SAM_SERVER_LOOKUP_DOMAIN
,
4025 if (!NT_SUCCESS(Status
))
4027 ERR("SamConnect failed (Status %08lx)\n", Status
);
4028 ApiStatus
= NetpNtStatusToApiStatus(Status
);
4032 /* Open the Account Domain */
4033 Status
= OpenAccountDomain(ServerHandle
,
4034 (servername
!= NULL
) ? &ServerName
: NULL
,
4035 DOMAIN_LIST_ACCOUNTS
| DOMAIN_LOOKUP
| DOMAIN_READ_PASSWORD_PARAMETERS
,
4036 &AccountDomainHandle
);
4037 if (!NT_SUCCESS(Status
))
4039 ERR("OpenAccountDomain failed (Status %08lx)\n", Status
);
4040 ApiStatus
= NetpNtStatusToApiStatus(Status
);
4044 /* Open the User Account */
4045 ApiStatus
= OpenUserByName(AccountDomainHandle
,
4049 if (ApiStatus
!= NERR_Success
)
4051 ERR("OpenUserByName failed (ApiStatus %lu)\n", ApiStatus
);
4055 /* Set user information */
4056 ApiStatus
= SetUserInfo(UserHandle
,
4060 if (ApiStatus
!= NERR_Success
)
4062 ERR("SetUserInfo failed (Status %lu)\n", ApiStatus
);
4066 if (UserHandle
!= NULL
)
4067 SamCloseHandle(UserHandle
);
4069 if (AccountDomainHandle
!= NULL
)
4070 SamCloseHandle(AccountDomainHandle
);
4072 if (ServerHandle
!= NULL
)
4073 SamCloseHandle(ServerHandle
);