/*
* TODO:
- * Implement NetUserGetGroups
+ * Implement NetUserGetGroups (WIP)
* Implement NetUserSetGroups
* NetUserGetLocalGroups does not support LG_INCLUDE_INDIRECT yet.
* Add missing information levels.
#include "netapi32.h"
-WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
+#include <ndk/kefuncs.h>
+#include <ndk/obfuncs.h>
+WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
typedef struct _ENUM_CONTEXT
{
SAM_HANDLE ServerHandle;
SAM_HANDLE BuiltinDomainHandle;
SAM_HANDLE AccountDomainHandle;
+ PSID BuiltinDomainSid;
+ PSID AccountDomainSid;
SAM_ENUMERATE_HANDLE EnumerationContext;
PSAM_RID_ENUMERATION Buffer;
static
ULONG
-GetAccountFlags(ULONG AccountControl)
+DeltaTimeToSeconds(LARGE_INTEGER DeltaTime)
+{
+ LARGE_INTEGER Seconds;
+
+ if (DeltaTime.QuadPart == 0)
+ return 0;
+
+ Seconds.QuadPart = -DeltaTime.QuadPart / 10000000;
+
+ if (Seconds.HighPart != 0)
+ return TIMEQ_FOREVER;
+
+ return Seconds.LowPart;
+}
+
+
+static
+NTSTATUS
+GetAllowedWorldAce(IN PACL Acl,
+ OUT PACCESS_ALLOWED_ACE *Ace)
+{
+ SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
+ ULONG WorldSid[sizeof(SID) / sizeof(ULONG) + SID_MAX_SUB_AUTHORITIES];
+ ACL_SIZE_INFORMATION AclSize;
+ PVOID LocalAce = NULL;
+ ULONG i;
+ NTSTATUS Status;
+
+ *Ace = NULL;
+
+ RtlInitializeSid((PSID)WorldSid,
+ &WorldAuthority,
+ 1);
+ *(RtlSubAuthoritySid((PSID)WorldSid, 0)) = SECURITY_WORLD_RID;
+
+ Status = RtlQueryInformationAcl(Acl,
+ &AclSize,
+ sizeof(AclSize),
+ AclSizeInformation);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ for (i = 0; i < AclSize.AceCount; i++)
+ {
+ Status = RtlGetAce(Acl, i, &LocalAce);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ if (((PACE_HEADER)LocalAce)->AceType != ACCESS_ALLOWED_ACE_TYPE)
+ continue;
+
+ if (RtlEqualSid((PSID)WorldSid,
+ (PSID)&((PACCESS_ALLOWED_ACE)LocalAce)->SidStart))
+ {
+ *Ace = (PACCESS_ALLOWED_ACE)LocalAce;
+ return STATUS_SUCCESS;
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
+
+static
+ULONG
+GetAccountFlags(ULONG AccountControl,
+ PACL Dacl)
{
+ PACCESS_ALLOWED_ACE Ace = NULL;
ULONG Flags = UF_SCRIPT;
+ NTSTATUS Status;
+
+ if (Dacl != NULL)
+ {
+ Status = GetAllowedWorldAce(Dacl, &Ace);
+ if (NT_SUCCESS(Status))
+ {
+ if (Ace == NULL)
+ {
+ Flags |= UF_PASSWD_CANT_CHANGE;
+ }
+ else if ((Ace->Mask & USER_CHANGE_PASSWORD) == 0)
+ {
+ Flags |= UF_PASSWD_CANT_CHANGE;
+ }
+ }
+ }
if (AccountControl & USER_ACCOUNT_DISABLED)
Flags |= UF_ACCOUNTDISABLE;
if (AccountControl & USER_PASSWORD_NOT_REQUIRED)
Flags |= UF_PASSWD_NOTREQD;
-// UF_PASSWD_CANT_CHANGE
-
if (AccountControl & USER_ACCOUNT_AUTO_LOCKED)
Flags |= UF_LOCKOUT;
}
+static
+VOID
+ChangeUserDacl(IN PACL Dacl,
+ IN ULONG Flags)
+{
+ PACCESS_ALLOWED_ACE Ace = NULL;
+ NTSTATUS Status;
+
+ if (Dacl == NULL)
+ return;
+
+ Status = GetAllowedWorldAce(Dacl, &Ace);
+ if (!NT_SUCCESS(Status))
+ return;
+
+ if (Flags & UF_PASSWD_CANT_CHANGE)
+ Ace->Mask &= ~USER_CHANGE_PASSWORD;
+ else
+ Ace->Mask |= USER_CHANGE_PASSWORD;
+}
+
+
+static
+NET_API_STATUS
+GetUserDacl(IN SAM_HANDLE UserHandle,
+ OUT PACL *Dacl)
+{
+ PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
+ PACL SamDacl;
+ PACL LocalDacl;
+ BOOLEAN Defaulted;
+ BOOLEAN Present;
+ ACL_SIZE_INFORMATION AclSize;
+ NET_API_STATUS ApiStatus;
+ NTSTATUS Status;
+
+ TRACE("(%p %p)\n", UserHandle, Dacl);
+
+ *Dacl = NULL;
+
+ Status = SamQuerySecurityObject(UserHandle,
+ DACL_SECURITY_INFORMATION,
+ &SecurityDescriptor);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("SamQuerySecurityObject() failed (Status 0x%08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor,
+ &Present,
+ &SamDacl,
+ &Defaulted);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("RtlGetDaclSecurityDescriptor() failed (Status 0x%08lx)\n", Status);
+ ApiStatus = NERR_InternalError;
+ goto done;
+ }
+
+ if (Present == FALSE)
+ {
+ TRACE("No DACL present\n");
+ ApiStatus = NERR_Success;
+ goto done;
+ }
+
+ Status = RtlQueryInformationAcl(SamDacl,
+ &AclSize,
+ sizeof(AclSize),
+ AclSizeInformation);
+ if (!NT_SUCCESS(Status))
+ {
+ TRACE("RtlQueryInformationAcl() failed (Status 0x%08lx)\n", Status);
+ ApiStatus = NERR_InternalError;
+ goto done;
+ }
+
+ LocalDacl = HeapAlloc(GetProcessHeap(), 0, AclSize.AclBytesInUse);
+ if (LocalDacl == NULL)
+ {
+ TRACE("Memory allocation failed\n");
+ ApiStatus = ERROR_NOT_ENOUGH_MEMORY;
+ goto done;
+ }
+
+ RtlCopyMemory(LocalDacl, SamDacl, AclSize.AclBytesInUse);
+
+ *Dacl = LocalDacl;
+
+ ApiStatus = NERR_Success;
+
+done:
+ if (SecurityDescriptor != NULL)
+ SamFreeMemory(SecurityDescriptor);
+
+ TRACE("done (ApiStatus: 0x%08lx)\n", ApiStatus);
+
+ return ApiStatus;
+}
+
+
+static
+VOID
+FreeUserInfo(PUSER_ALL_INFORMATION UserInfo)
+{
+ if (UserInfo->UserName.Buffer != NULL)
+ SamFreeMemory(UserInfo->UserName.Buffer);
+
+ if (UserInfo->FullName.Buffer != NULL)
+ SamFreeMemory(UserInfo->FullName.Buffer);
+
+ if (UserInfo->HomeDirectory.Buffer != NULL)
+ SamFreeMemory(UserInfo->HomeDirectory.Buffer);
+
+ if (UserInfo->HomeDirectoryDrive.Buffer != NULL)
+ SamFreeMemory(UserInfo->HomeDirectoryDrive.Buffer);
+
+ if (UserInfo->ScriptPath.Buffer != NULL)
+ SamFreeMemory(UserInfo->ScriptPath.Buffer);
+
+ if (UserInfo->ProfilePath.Buffer != NULL)
+ SamFreeMemory(UserInfo->ProfilePath.Buffer);
+
+ if (UserInfo->AdminComment.Buffer != NULL)
+ SamFreeMemory(UserInfo->AdminComment.Buffer);
+
+ if (UserInfo->WorkStations.Buffer != NULL)
+ SamFreeMemory(UserInfo->WorkStations.Buffer);
+
+ if (UserInfo->UserComment.Buffer != NULL)
+ SamFreeMemory(UserInfo->UserComment.Buffer);
+
+ if (UserInfo->Parameters.Buffer != NULL)
+ SamFreeMemory(UserInfo->Parameters.Buffer);
+
+ if (UserInfo->PrivateData.Buffer != NULL)
+ SamFreeMemory(UserInfo->PrivateData.Buffer);
+
+ if (UserInfo->LogonHours.LogonHours != NULL)
+ SamFreeMemory(UserInfo->LogonHours.LogonHours);
+
+ SamFreeMemory(UserInfo);
+}
+
+
+static
+NET_API_STATUS
+GetUserPrivileges(
+ _In_ SAM_HANDLE BuiltinDomainHandle,
+ _In_ SAM_HANDLE UserHandle,
+ _In_ PSID AccountDomainSid,
+ _In_ ULONG RelativeId,
+ _Out_ PDWORD Priv,
+ _Out_ PDWORD AuthFlags)
+{
+ PGROUP_MEMBERSHIP GroupMembership = NULL;
+ ULONG GroupCount, SidCount, AliasCount, i;
+ PSID *SidArray = NULL;
+ PULONG AliasArray = NULL;
+ BOOL bAdmin = FALSE, bUser = FALSE;
+ NET_API_STATUS ApiStatus = NERR_Success;
+ NTSTATUS Status;
+
+ FIXME("GetUserPrivileges(%p)\n", UserHandle);
+
+ /* Get the users group memberships */
+ Status = SamGetGroupsForUser(UserHandle,
+ &GroupMembership,
+ &GroupCount);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("SamGetGroupsForUser() failed (Status 0x%08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ /* Allocate the SID array */
+ ApiStatus = NetApiBufferAllocate((GroupCount + 1) * sizeof(PSID),
+ (PVOID*)&SidArray);
+ if (ApiStatus != NERR_Success)
+ {
+ goto done;
+ }
+
+ /* Add the user to the SID array */
+ SidCount = 0;
+ ApiStatus = BuildSidFromSidAndRid(AccountDomainSid,
+ RelativeId,
+ &SidArray[0]);
+ if (ApiStatus != NERR_Success)
+ {
+ goto done;
+ }
+
+ SidCount++;
+
+ /* Add the groups to the SID array */
+ for (i = 0; i < GroupCount; i++)
+ {
+ ApiStatus = BuildSidFromSidAndRid(AccountDomainSid,
+ GroupMembership[i].RelativeId,
+ &SidArray[i + 1]);
+ if (ApiStatus != NERR_Success)
+ {
+ goto done;
+ }
+
+ SidCount++;
+ }
+
+ /* Get aliases for the user and his groups */
+ Status = SamGetAliasMembership(BuiltinDomainHandle,
+ SidCount,
+ SidArray,
+ &AliasCount,
+ &AliasArray);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("SamGetAliasMembership() failed (Status 0x%08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ *AuthFlags = 0;
+
+ /* Set the AuthFlags */
+ for (i = 0; i < AliasCount; i++)
+ {
+ switch (AliasArray[i])
+ {
+ case DOMAIN_ALIAS_RID_ADMINS:
+ bAdmin = TRUE;
+ break;
+
+ case DOMAIN_ALIAS_RID_USERS:
+ bUser = TRUE;
+ break;
+
+ case DOMAIN_ALIAS_RID_ACCOUNT_OPS:
+ *AuthFlags |= AF_OP_ACCOUNTS;
+ break;
+
+ case DOMAIN_ALIAS_RID_SYSTEM_OPS:
+ *AuthFlags |= AF_OP_SERVER;
+ break;
+
+ case DOMAIN_ALIAS_RID_PRINT_OPS:
+ *AuthFlags |= AF_OP_PRINT;
+ break;
+ }
+ }
+
+ /* Set the prvileges */
+ if (bAdmin)
+ {
+ *Priv = USER_PRIV_ADMIN;
+ }
+ else if (bUser)
+ {
+ *Priv = USER_PRIV_USER;
+ }
+ else
+ {
+ *Priv = USER_PRIV_GUEST;
+ }
+
+done:
+ if (AliasArray != NULL)
+ SamFreeMemory(AliasArray);
+
+ if (SidArray != NULL)
+ {
+ for (i = 0; i < SidCount; i++)
+ NetApiBufferFree(SidArray[i]);
+
+ NetApiBufferFree(SidArray);
+ }
+
+ if (GroupMembership != NULL)
+ SamFreeMemory(GroupMembership);
+
+ return ApiStatus;
+}
+
+
static
NET_API_STATUS
-BuildUserInfoBuffer(PUSER_ALL_INFORMATION UserInfo,
- DWORD level,
- ULONG RelativeId,
- LPVOID *Buffer)
+BuildUserInfoBuffer(
+ _In_ SAM_HANDLE BuiltinDomainHandle,
+ _In_ SAM_HANDLE UserHandle,
+ _In_ PSID AccountDomainSid,
+ _In_ ULONG RelativeId,
+ _In_ DWORD level,
+ _Out_ LPVOID *Buffer)
{
UNICODE_STRING LogonServer = RTL_CONSTANT_STRING(L"\\\\*");
+ PUSER_ALL_INFORMATION UserInfo = NULL;
LPVOID LocalBuffer = NULL;
+ PACL Dacl = NULL;
+ DWORD Priv = 0, AuthFlags = 0;
PUSER_INFO_0 UserInfo0;
PUSER_INFO_1 UserInfo1;
PUSER_INFO_2 UserInfo2;
PUSER_INFO_23 UserInfo23;
LPWSTR Ptr;
ULONG Size = 0;
+ NTSTATUS Status;
NET_API_STATUS ApiStatus = NERR_Success;
*Buffer = NULL;
+ Status = SamQueryInformationUser(UserHandle,
+ UserAllInformation,
+ (PVOID *)&UserInfo);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("SamQueryInformationUser failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ if ((level == 1) || (level == 2) || (level == 3) ||
+ (level == 4) || (level == 20) || (level == 23))
+ {
+ ApiStatus = GetUserDacl(UserHandle, &Dacl);
+ if (ApiStatus != NERR_Success)
+ goto done;
+ }
+
+ if ((level == 1) || (level == 2) || (level == 3) ||
+ (level == 4) || (level == 11))
+ {
+ ApiStatus = GetUserPrivileges(BuiltinDomainHandle,
+ UserHandle,
+ AccountDomainSid,
+ RelativeId,
+ &Priv,
+ &AuthFlags);
+ if (ApiStatus != NERR_Success)
+ goto done;
+ }
+
switch (level)
{
case 0:
case 1:
Size = sizeof(USER_INFO_1) +
- UserInfo->UserName.Length + sizeof(WCHAR);
-
- if (UserInfo->HomeDirectory.Length > 0)
- Size += UserInfo->HomeDirectory.Length + sizeof(WCHAR);
-
- if (UserInfo->AdminComment.Length > 0)
- Size += UserInfo->AdminComment.Length + sizeof(WCHAR);
-
- if (UserInfo->ScriptPath.Length > 0)
- Size += UserInfo->ScriptPath.Length + sizeof(WCHAR);
+ UserInfo->UserName.Length + sizeof(WCHAR) +
+ UserInfo->HomeDirectory.Length + sizeof(WCHAR) +
+ UserInfo->AdminComment.Length + sizeof(WCHAR) +
+ UserInfo->ScriptPath.Length + sizeof(WCHAR);
break;
case 2:
Size = sizeof(USER_INFO_2) +
- UserInfo->UserName.Length + sizeof(WCHAR);
-
- if (UserInfo->HomeDirectory.Length > 0)
- Size += UserInfo->HomeDirectory.Length + sizeof(WCHAR);
-
- if (UserInfo->AdminComment.Length > 0)
- Size += UserInfo->AdminComment.Length + sizeof(WCHAR);
-
- if (UserInfo->ScriptPath.Length > 0)
- Size += UserInfo->ScriptPath.Length + sizeof(WCHAR);
-
- if (UserInfo->FullName.Length > 0)
- Size += UserInfo->FullName.Length + sizeof(WCHAR);
-
- if (UserInfo->UserComment.Length > 0)
- Size += UserInfo->UserComment.Length + sizeof(WCHAR);
-
- if (UserInfo->Parameters.Length > 0)
- Size += UserInfo->Parameters.Length + sizeof(WCHAR);
-
- if (UserInfo->WorkStations.Length > 0)
- Size += UserInfo->WorkStations.Length + sizeof(WCHAR);
+ UserInfo->UserName.Length + sizeof(WCHAR) +
+ UserInfo->HomeDirectory.Length + sizeof(WCHAR) +
+ UserInfo->AdminComment.Length + sizeof(WCHAR) +
+ UserInfo->ScriptPath.Length + sizeof(WCHAR) +
+ UserInfo->FullName.Length + sizeof(WCHAR) +
+ UserInfo->UserComment.Length + sizeof(WCHAR) +
+ UserInfo->Parameters.Length + sizeof(WCHAR) +
+ UserInfo->WorkStations.Length + sizeof(WCHAR) +
+ LogonServer.Length + sizeof(WCHAR);
if (UserInfo->LogonHours.UnitsPerWeek > 0)
Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8;
-
- if (LogonServer.Length > 0)
- Size += LogonServer.Length + sizeof(WCHAR);
break;
case 3:
Size = sizeof(USER_INFO_3) +
- UserInfo->UserName.Length + sizeof(WCHAR);
-
- if (UserInfo->HomeDirectory.Length > 0)
- Size += UserInfo->HomeDirectory.Length + sizeof(WCHAR);
-
- if (UserInfo->AdminComment.Length > 0)
- Size += UserInfo->AdminComment.Length + sizeof(WCHAR);
-
- if (UserInfo->ScriptPath.Length > 0)
- Size += UserInfo->ScriptPath.Length + sizeof(WCHAR);
-
- if (UserInfo->FullName.Length > 0)
- Size += UserInfo->FullName.Length + sizeof(WCHAR);
-
- if (UserInfo->UserComment.Length > 0)
- Size += UserInfo->UserComment.Length + sizeof(WCHAR);
-
- if (UserInfo->Parameters.Length > 0)
- Size += UserInfo->Parameters.Length + sizeof(WCHAR);
-
- if (UserInfo->WorkStations.Length > 0)
- Size += UserInfo->WorkStations.Length + sizeof(WCHAR);
+ UserInfo->UserName.Length + sizeof(WCHAR) +
+ UserInfo->HomeDirectory.Length + sizeof(WCHAR) +
+ UserInfo->AdminComment.Length + sizeof(WCHAR) +
+ UserInfo->ScriptPath.Length + sizeof(WCHAR) +
+ UserInfo->FullName.Length + sizeof(WCHAR) +
+ UserInfo->UserComment.Length + sizeof(WCHAR) +
+ UserInfo->Parameters.Length + sizeof(WCHAR) +
+ UserInfo->WorkStations.Length + sizeof(WCHAR) +
+ LogonServer.Length + sizeof(WCHAR) +
+ UserInfo->ProfilePath.Length + sizeof(WCHAR) +
+ UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR);
if (UserInfo->LogonHours.UnitsPerWeek > 0)
Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8;
-
- if (LogonServer.Length > 0)
- Size += LogonServer.Length + sizeof(WCHAR);
-
- if (UserInfo->ProfilePath.Length > 0)
- Size += UserInfo->ProfilePath.Length + sizeof(WCHAR);
-
- if (UserInfo->HomeDirectoryDrive.Length > 0)
- Size += UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR);
break;
case 4:
Size = sizeof(USER_INFO_4) +
- UserInfo->UserName.Length + sizeof(WCHAR);
-
- if (UserInfo->HomeDirectory.Length > 0)
- Size += UserInfo->HomeDirectory.Length + sizeof(WCHAR);
-
- if (UserInfo->AdminComment.Length > 0)
- Size += UserInfo->AdminComment.Length + sizeof(WCHAR);
-
- if (UserInfo->ScriptPath.Length > 0)
- Size += UserInfo->ScriptPath.Length + sizeof(WCHAR);
-
- if (UserInfo->FullName.Length > 0)
- Size += UserInfo->FullName.Length + sizeof(WCHAR);
-
- if (UserInfo->UserComment.Length > 0)
- Size += UserInfo->UserComment.Length + sizeof(WCHAR);
-
- if (UserInfo->Parameters.Length > 0)
- Size += UserInfo->Parameters.Length + sizeof(WCHAR);
-
- if (UserInfo->WorkStations.Length > 0)
- Size += UserInfo->WorkStations.Length + sizeof(WCHAR);
+ UserInfo->UserName.Length + sizeof(WCHAR) +
+ UserInfo->HomeDirectory.Length + sizeof(WCHAR) +
+ UserInfo->AdminComment.Length + sizeof(WCHAR) +
+ UserInfo->ScriptPath.Length + sizeof(WCHAR) +
+ UserInfo->FullName.Length + sizeof(WCHAR) +
+ UserInfo->UserComment.Length + sizeof(WCHAR) +
+ UserInfo->Parameters.Length + sizeof(WCHAR) +
+ UserInfo->WorkStations.Length + sizeof(WCHAR) +
+ LogonServer.Length + sizeof(WCHAR) +
+ UserInfo->ProfilePath.Length + sizeof(WCHAR) +
+ UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR);
if (UserInfo->LogonHours.UnitsPerWeek > 0)
Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8;
- if (LogonServer.Length > 0)
- Size += LogonServer.Length + sizeof(WCHAR);
-
- /* FIXME: usri4_user_sid */
-
- if (UserInfo->ProfilePath.Length > 0)
- Size += UserInfo->ProfilePath.Length + sizeof(WCHAR);
-
- if (UserInfo->HomeDirectoryDrive.Length > 0)
- Size += UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR);
+ Size += RtlLengthSid(AccountDomainSid) + sizeof(ULONG);
break;
case 10:
Size = sizeof(USER_INFO_10) +
- UserInfo->UserName.Length + sizeof(WCHAR);
-
- if (UserInfo->AdminComment.Length > 0)
- Size += UserInfo->AdminComment.Length + sizeof(WCHAR);
-
- if (UserInfo->UserComment.Length > 0)
- Size += UserInfo->UserComment.Length + sizeof(WCHAR);
-
- if (UserInfo->FullName.Length > 0)
- Size += UserInfo->FullName.Length + sizeof(WCHAR);
+ UserInfo->UserName.Length + sizeof(WCHAR) +
+ UserInfo->AdminComment.Length + sizeof(WCHAR) +
+ UserInfo->UserComment.Length + sizeof(WCHAR) +
+ UserInfo->FullName.Length + sizeof(WCHAR);
break;
case 11:
Size = sizeof(USER_INFO_11) +
- UserInfo->UserName.Length + sizeof(WCHAR);
-
- if (UserInfo->AdminComment.Length > 0)
- Size += UserInfo->AdminComment.Length + sizeof(WCHAR);
-
- if (UserInfo->UserComment.Length > 0)
- Size += UserInfo->UserComment.Length + sizeof(WCHAR);
-
- if (UserInfo->FullName.Length > 0)
- Size += UserInfo->FullName.Length + sizeof(WCHAR);
-
- if (UserInfo->HomeDirectory.Length > 0)
- Size += UserInfo->HomeDirectory.Length + sizeof(WCHAR);
-
- if (UserInfo->Parameters.Length > 0)
- Size += UserInfo->Parameters.Length + sizeof(WCHAR);
-
- if (LogonServer.Length > 0)
- Size += LogonServer.Length + sizeof(WCHAR);
-
- if (UserInfo->WorkStations.Length > 0)
- Size += UserInfo->WorkStations.Length + sizeof(WCHAR);
+ UserInfo->UserName.Length + sizeof(WCHAR) +
+ UserInfo->AdminComment.Length + sizeof(WCHAR) +
+ UserInfo->UserComment.Length + sizeof(WCHAR) +
+ UserInfo->FullName.Length + sizeof(WCHAR) +
+ UserInfo->HomeDirectory.Length + sizeof(WCHAR) +
+ UserInfo->Parameters.Length + sizeof(WCHAR) +
+ LogonServer.Length + sizeof(WCHAR) +
+ UserInfo->WorkStations.Length + sizeof(WCHAR);
if (UserInfo->LogonHours.UnitsPerWeek > 0)
Size += (((ULONG)UserInfo->LogonHours.UnitsPerWeek) + 7) / 8;
case 20:
Size = sizeof(USER_INFO_20) +
- UserInfo->UserName.Length + sizeof(WCHAR);
-
- if (UserInfo->FullName.Length > 0)
- Size += UserInfo->FullName.Length + sizeof(WCHAR);
-
- if (UserInfo->AdminComment.Length > 0)
- Size += UserInfo->AdminComment.Length + sizeof(WCHAR);
+ UserInfo->UserName.Length + sizeof(WCHAR) +
+ UserInfo->FullName.Length + sizeof(WCHAR) +
+ UserInfo->AdminComment.Length + sizeof(WCHAR);
break;
case 23:
Size = sizeof(USER_INFO_23) +
- UserInfo->UserName.Length + sizeof(WCHAR);
-
- if (UserInfo->FullName.Length > 0)
- Size += UserInfo->FullName.Length + sizeof(WCHAR);
-
- if (UserInfo->AdminComment.Length > 0)
- Size += UserInfo->AdminComment.Length + sizeof(WCHAR);
+ UserInfo->UserName.Length + sizeof(WCHAR) +
+ UserInfo->FullName.Length + sizeof(WCHAR) +
+ UserInfo->AdminComment.Length + sizeof(WCHAR);
- /* FIXME: usri23_user_sid */
+ Size += RtlLengthSid(AccountDomainSid) + sizeof(ULONG);
break;
default:
UserInfo0 = (PUSER_INFO_0)LocalBuffer;
Ptr = (LPWSTR)((ULONG_PTR)UserInfo0 + sizeof(USER_INFO_0));
+
UserInfo0->usri0_name = Ptr;
memcpy(UserInfo0->usri0_name,
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
UserInfo1->usri1_password = NULL;
-
UserInfo1->usri1_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
- /* FIXME: UserInfo1->usri1_priv */
-
- if (UserInfo->HomeDirectory.Length > 0)
- {
- UserInfo1->usri1_home_dir = Ptr;
-
- memcpy(UserInfo1->usri1_home_dir,
- UserInfo->HomeDirectory.Buffer,
- UserInfo->HomeDirectory.Length);
- UserInfo1->usri1_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
- }
-
- if (UserInfo->AdminComment.Length > 0)
- {
- UserInfo1->usri1_comment = Ptr;
-
- memcpy(UserInfo1->usri1_comment,
- UserInfo->AdminComment.Buffer,
- UserInfo->AdminComment.Length);
- UserInfo1->usri1_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
- }
-
- UserInfo1->usri1_flags = GetAccountFlags(UserInfo->UserAccountControl);
-
- if (UserInfo->ScriptPath.Length > 0)
- {
- UserInfo1->usri1_script_path = Ptr;
-
- memcpy(UserInfo1->usri1_script_path,
- UserInfo->ScriptPath.Buffer,
- UserInfo->ScriptPath.Length);
- UserInfo1->usri1_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL;
- }
+ UserInfo1->usri1_priv = Priv;
+
+ UserInfo1->usri1_home_dir = Ptr;
+ memcpy(UserInfo1->usri1_home_dir,
+ UserInfo->HomeDirectory.Buffer,
+ UserInfo->HomeDirectory.Length);
+ UserInfo1->usri1_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
+
+ UserInfo1->usri1_comment = Ptr;
+ memcpy(UserInfo1->usri1_comment,
+ UserInfo->AdminComment.Buffer,
+ UserInfo->AdminComment.Length);
+ UserInfo1->usri1_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
+
+ UserInfo1->usri1_flags = GetAccountFlags(UserInfo->UserAccountControl,
+ Dacl);
+
+ UserInfo1->usri1_script_path = Ptr;
+ memcpy(UserInfo1->usri1_script_path,
+ UserInfo->ScriptPath.Buffer,
+ UserInfo->ScriptPath.Length);
+ UserInfo1->usri1_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL;
break;
- case 2:
- UserInfo2 = (PUSER_INFO_2)LocalBuffer;
-
- Ptr = (LPWSTR)((ULONG_PTR)UserInfo2 + sizeof(USER_INFO_2));
-
- UserInfo2->usri2_name = Ptr;
-
- memcpy(UserInfo2->usri2_name,
- UserInfo->UserName.Buffer,
- UserInfo->UserName.Length);
- UserInfo2->usri2_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
-
- UserInfo2->usri2_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
-
- /* FIXME: usri2_priv */
-
- if (UserInfo->HomeDirectory.Length > 0)
- {
- UserInfo2->usri2_home_dir = Ptr;
-
- memcpy(UserInfo2->usri2_home_dir,
- UserInfo->HomeDirectory.Buffer,
- UserInfo->HomeDirectory.Length);
- UserInfo2->usri2_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
- }
-
- if (UserInfo->AdminComment.Length > 0)
- {
- UserInfo2->usri2_comment = Ptr;
-
- memcpy(UserInfo2->usri2_comment,
- UserInfo->AdminComment.Buffer,
- UserInfo->AdminComment.Length);
- UserInfo2->usri2_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
- }
-
- UserInfo2->usri2_flags = GetAccountFlags(UserInfo->UserAccountControl);
-
- if (UserInfo->ScriptPath.Length > 0)
- {
- UserInfo2->usri2_script_path = Ptr;
-
- memcpy(UserInfo2->usri2_script_path,
- UserInfo->ScriptPath.Buffer,
- UserInfo->ScriptPath.Length);
- UserInfo2->usri2_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ScriptPath.Length + sizeof(WCHAR));
- }
-
- /* FIXME: usri2_auth_flags */
-
- if (UserInfo->FullName.Length > 0)
- {
- UserInfo2->usri2_full_name = Ptr;
-
- memcpy(UserInfo2->usri2_full_name,
- UserInfo->FullName.Buffer,
- UserInfo->FullName.Length);
- UserInfo2->usri2_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
- }
-
- if (UserInfo->UserComment.Length > 0)
- {
- UserInfo2->usri2_usr_comment = Ptr;
-
- memcpy(UserInfo2->usri2_usr_comment,
- UserInfo->UserComment.Buffer,
- UserInfo->UserComment.Length);
- UserInfo2->usri2_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
- }
-
- if (UserInfo->Parameters.Length > 0)
- {
- UserInfo2->usri2_parms = Ptr;
+ case 2:
+ UserInfo2 = (PUSER_INFO_2)LocalBuffer;
- memcpy(UserInfo2->usri2_parms,
- UserInfo->Parameters.Buffer,
- UserInfo->Parameters.Length);
- UserInfo2->usri2_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)UserInfo2 + sizeof(USER_INFO_2));
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
- }
+ UserInfo2->usri2_name = Ptr;
- if (UserInfo->WorkStations.Length > 0)
- {
- UserInfo2->usri2_workstations = Ptr;
+ memcpy(UserInfo2->usri2_name,
+ UserInfo->UserName.Buffer,
+ UserInfo->UserName.Length);
+ UserInfo2->usri2_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL;
- memcpy(UserInfo2->usri2_workstations,
- UserInfo->WorkStations.Buffer,
- UserInfo->WorkStations.Length);
- UserInfo2->usri2_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
- }
+ UserInfo2->usri2_password = NULL;
+ UserInfo2->usri2_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
- RtlTimeToSecondsSince1970(&UserInfo->LastLogon,
- &UserInfo2->usri2_last_logon);
+ UserInfo2->usri2_priv = Priv;
+
+ UserInfo2->usri2_home_dir = Ptr;
+ memcpy(UserInfo2->usri2_home_dir,
+ UserInfo->HomeDirectory.Buffer,
+ UserInfo->HomeDirectory.Length);
+ UserInfo2->usri2_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
+
+ UserInfo2->usri2_comment = Ptr;
+ memcpy(UserInfo2->usri2_comment,
+ UserInfo->AdminComment.Buffer,
+ UserInfo->AdminComment.Length);
+ UserInfo2->usri2_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
+
+ UserInfo2->usri2_flags = GetAccountFlags(UserInfo->UserAccountControl,
+ Dacl);
+
+ UserInfo2->usri2_script_path = Ptr;
+ memcpy(UserInfo2->usri2_script_path,
+ UserInfo->ScriptPath.Buffer,
+ UserInfo->ScriptPath.Length);
+ UserInfo2->usri2_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ScriptPath.Length + sizeof(WCHAR));
+
+ UserInfo2->usri2_auth_flags = AuthFlags;
+
+ UserInfo2->usri2_full_name = Ptr;
+ memcpy(UserInfo2->usri2_full_name,
+ UserInfo->FullName.Buffer,
+ UserInfo->FullName.Length);
+ UserInfo2->usri2_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
+
+ UserInfo2->usri2_usr_comment = Ptr;
+ memcpy(UserInfo2->usri2_usr_comment,
+ UserInfo->UserComment.Buffer,
+ UserInfo->UserComment.Length);
+ UserInfo2->usri2_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
+
+ UserInfo2->usri2_parms = Ptr;
+ memcpy(UserInfo2->usri2_parms,
+ UserInfo->Parameters.Buffer,
+ UserInfo->Parameters.Length);
+ UserInfo2->usri2_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
+
+ UserInfo2->usri2_workstations = Ptr;
+ memcpy(UserInfo2->usri2_workstations,
+ UserInfo->WorkStations.Buffer,
+ UserInfo->WorkStations.Length);
+ UserInfo2->usri2_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
+
+ if (UserInfo->LastLogon.QuadPart == 0)
+ UserInfo2->usri2_last_logon = 0;
+ else
+ RtlTimeToSecondsSince1970(&UserInfo->LastLogon,
+ &UserInfo2->usri2_last_logon);
- RtlTimeToSecondsSince1970(&UserInfo->LastLogoff,
- &UserInfo2->usri2_last_logoff);
+ if (UserInfo->LastLogoff.QuadPart == 0)
+ UserInfo2->usri2_last_logoff = 0;
+ else
+ RtlTimeToSecondsSince1970(&UserInfo->LastLogoff,
+ &UserInfo2->usri2_last_logoff);
- RtlTimeToSecondsSince1970(&UserInfo->AccountExpires,
- &UserInfo2->usri2_acct_expires);
+ if (UserInfo->AccountExpires.QuadPart == MAXLONGLONG)
+ UserInfo2->usri2_acct_expires = TIMEQ_FOREVER;
+ else
+ RtlTimeToSecondsSince1970(&UserInfo->AccountExpires,
+ &UserInfo2->usri2_acct_expires);
UserInfo2->usri2_max_storage = USER_MAXSTORAGE_UNLIMITED;
UserInfo2->usri2_units_per_week = UserInfo->LogonHours.UnitsPerWeek;
UserInfo2->usri2_bad_pw_count = UserInfo->BadPasswordCount;
UserInfo2->usri2_num_logons = UserInfo->LogonCount;
- if (LogonServer.Length > 0)
- {
- UserInfo2->usri2_logon_server = Ptr;
-
- memcpy(UserInfo2->usri2_logon_server,
- LogonServer.Buffer,
- LogonServer.Length);
- UserInfo2->usri2_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
- }
+ UserInfo2->usri2_logon_server = Ptr;
+ memcpy(UserInfo2->usri2_logon_server,
+ LogonServer.Buffer,
+ LogonServer.Length);
+ UserInfo2->usri2_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
UserInfo2->usri2_country_code = UserInfo->CountryCode;
UserInfo2->usri2_code_page = UserInfo->CodePage;
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
+ UserInfo3->usri3_password = NULL;
UserInfo3->usri3_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
- /* FIXME: usri3_priv */
-
- if (UserInfo->HomeDirectory.Length > 0)
- {
- UserInfo3->usri3_home_dir = Ptr;
-
- memcpy(UserInfo3->usri3_home_dir,
- UserInfo->HomeDirectory.Buffer,
- UserInfo->HomeDirectory.Length);
- UserInfo3->usri3_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
- }
-
- if (UserInfo->AdminComment.Length > 0)
- {
- UserInfo3->usri3_comment = Ptr;
-
- memcpy(UserInfo3->usri3_comment,
- UserInfo->AdminComment.Buffer,
- UserInfo->AdminComment.Length);
- UserInfo3->usri3_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
- }
-
- UserInfo3->usri3_flags = GetAccountFlags(UserInfo->UserAccountControl);
-
- if (UserInfo->ScriptPath.Length > 0)
- {
- UserInfo3->usri3_script_path = Ptr;
-
- memcpy(UserInfo3->usri3_script_path,
- UserInfo->ScriptPath.Buffer,
- UserInfo->ScriptPath.Length);
- UserInfo3->usri3_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ScriptPath.Length + sizeof(WCHAR));
- }
-
- /* FIXME: usri3_auth_flags */
-
- if (UserInfo->FullName.Length > 0)
- {
- UserInfo3->usri3_full_name = Ptr;
-
- memcpy(UserInfo3->usri3_full_name,
- UserInfo->FullName.Buffer,
- UserInfo->FullName.Length);
- UserInfo3->usri3_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
- }
-
- if (UserInfo->UserComment.Length > 0)
- {
- UserInfo3->usri3_usr_comment = Ptr;
-
- memcpy(UserInfo3->usri3_usr_comment,
- UserInfo->UserComment.Buffer,
- UserInfo->UserComment.Length);
- UserInfo3->usri3_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
- }
-
- if (UserInfo->Parameters.Length > 0)
- {
- UserInfo3->usri3_parms = Ptr;
-
- memcpy(UserInfo3->usri3_parms,
- UserInfo->Parameters.Buffer,
- UserInfo->Parameters.Length);
- UserInfo3->usri3_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
- }
-
- if (UserInfo->WorkStations.Length > 0)
- {
- UserInfo3->usri3_workstations = Ptr;
-
- memcpy(UserInfo3->usri3_workstations,
- UserInfo->WorkStations.Buffer,
- UserInfo->WorkStations.Length);
- UserInfo3->usri3_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
- }
-
- RtlTimeToSecondsSince1970(&UserInfo->LastLogon,
- &UserInfo3->usri3_last_logon);
+ UserInfo3->usri3_priv = Priv;
+
+ UserInfo3->usri3_home_dir = Ptr;
+ memcpy(UserInfo3->usri3_home_dir,
+ UserInfo->HomeDirectory.Buffer,
+ UserInfo->HomeDirectory.Length);
+ UserInfo3->usri3_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
+
+ UserInfo3->usri3_comment = Ptr;
+ memcpy(UserInfo3->usri3_comment,
+ UserInfo->AdminComment.Buffer,
+ UserInfo->AdminComment.Length);
+ UserInfo3->usri3_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
+
+ UserInfo3->usri3_flags = GetAccountFlags(UserInfo->UserAccountControl,
+ Dacl);
+
+ UserInfo3->usri3_script_path = Ptr;
+ memcpy(UserInfo3->usri3_script_path,
+ UserInfo->ScriptPath.Buffer,
+ UserInfo->ScriptPath.Length);
+ UserInfo3->usri3_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ScriptPath.Length + sizeof(WCHAR));
+
+ UserInfo3->usri3_auth_flags = AuthFlags;
+
+ UserInfo3->usri3_full_name = Ptr;
+ memcpy(UserInfo3->usri3_full_name,
+ UserInfo->FullName.Buffer,
+ UserInfo->FullName.Length);
+ UserInfo3->usri3_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
+
+ UserInfo3->usri3_usr_comment = Ptr;
+ memcpy(UserInfo3->usri3_usr_comment,
+ UserInfo->UserComment.Buffer,
+ UserInfo->UserComment.Length);
+ UserInfo3->usri3_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
+
+ UserInfo3->usri3_parms = Ptr;
+ memcpy(UserInfo3->usri3_parms,
+ UserInfo->Parameters.Buffer,
+ UserInfo->Parameters.Length);
+ UserInfo3->usri3_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
+
+ UserInfo3->usri3_workstations = Ptr;
+ memcpy(UserInfo3->usri3_workstations,
+ UserInfo->WorkStations.Buffer,
+ UserInfo->WorkStations.Length);
+ UserInfo3->usri3_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
+
+ if (UserInfo->LastLogon.QuadPart == 0)
+ UserInfo3->usri3_last_logon = 0;
+ else
+ RtlTimeToSecondsSince1970(&UserInfo->LastLogon,
+ &UserInfo3->usri3_last_logon);
- RtlTimeToSecondsSince1970(&UserInfo->LastLogoff,
- &UserInfo3->usri3_last_logoff);
+ if (UserInfo->LastLogoff.QuadPart == 0)
+ UserInfo3->usri3_last_logoff = 0;
+ else
+ RtlTimeToSecondsSince1970(&UserInfo->LastLogoff,
+ &UserInfo3->usri3_last_logoff);
- RtlTimeToSecondsSince1970(&UserInfo->AccountExpires,
- &UserInfo3->usri3_acct_expires);
+ if (UserInfo->AccountExpires.QuadPart == MAXLONGLONG)
+ UserInfo3->usri3_acct_expires = TIMEQ_FOREVER;
+ else
+ RtlTimeToSecondsSince1970(&UserInfo->AccountExpires,
+ &UserInfo3->usri3_acct_expires);
UserInfo3->usri3_max_storage = USER_MAXSTORAGE_UNLIMITED;
UserInfo3->usri3_units_per_week = UserInfo->LogonHours.UnitsPerWeek;
UserInfo3->usri3_bad_pw_count = UserInfo->BadPasswordCount;
UserInfo3->usri3_num_logons = UserInfo->LogonCount;
- if (LogonServer.Length > 0)
- {
- UserInfo3->usri3_logon_server = Ptr;
-
- memcpy(UserInfo3->usri3_logon_server,
- LogonServer.Buffer,
- LogonServer.Length);
- UserInfo3->usri3_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
- }
+ UserInfo3->usri3_logon_server = Ptr;
+ memcpy(UserInfo3->usri3_logon_server,
+ LogonServer.Buffer,
+ LogonServer.Length);
+ UserInfo3->usri3_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
UserInfo3->usri3_country_code = UserInfo->CountryCode;
UserInfo3->usri3_code_page = UserInfo->CodePage;
UserInfo3->usri3_user_id = RelativeId;
UserInfo3->usri3_primary_group_id = UserInfo->PrimaryGroupId;
- if (UserInfo->ProfilePath.Length > 0)
- {
- UserInfo3->usri3_profile = Ptr;
-
- memcpy(UserInfo3->usri3_profile,
- UserInfo->ProfilePath.Buffer,
- UserInfo->ProfilePath.Length);
- UserInfo3->usri3_profile[UserInfo->ProfilePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ProfilePath.Length + sizeof(WCHAR));
- }
-
- if (UserInfo->HomeDirectoryDrive.Length > 0)
- {
- UserInfo3->usri3_home_dir_drive = Ptr;
-
- memcpy(UserInfo3->usri3_home_dir_drive,
- UserInfo->HomeDirectoryDrive.Buffer,
- UserInfo->HomeDirectoryDrive.Length);
- UserInfo3->usri3_home_dir_drive[UserInfo->HomeDirectoryDrive.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ UserInfo3->usri3_profile = Ptr;
+ memcpy(UserInfo3->usri3_profile,
+ UserInfo->ProfilePath.Buffer,
+ UserInfo->ProfilePath.Length);
+ UserInfo3->usri3_profile[UserInfo->ProfilePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ProfilePath.Length + sizeof(WCHAR));
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR));
- }
+ UserInfo3->usri3_home_dir_drive = Ptr;
+ memcpy(UserInfo3->usri3_home_dir_drive,
+ UserInfo->HomeDirectoryDrive.Buffer,
+ UserInfo->HomeDirectoryDrive.Length);
+ UserInfo3->usri3_home_dir_drive[UserInfo->HomeDirectoryDrive.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR));
UserInfo3->usri3_password_expired = (UserInfo->UserAccountControl & USER_PASSWORD_EXPIRED);
break;
UserInfo4->usri4_password = NULL;
UserInfo4->usri4_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
- /* FIXME: usri4_priv */
-
- if (UserInfo->HomeDirectory.Length > 0)
- {
- UserInfo4->usri4_home_dir = Ptr;
-
- memcpy(UserInfo4->usri4_home_dir,
- UserInfo->HomeDirectory.Buffer,
- UserInfo->HomeDirectory.Length);
- UserInfo4->usri4_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
- }
-
- if (UserInfo->AdminComment.Length > 0)
- {
- UserInfo4->usri4_comment = Ptr;
-
- memcpy(UserInfo4->usri4_comment,
- UserInfo->AdminComment.Buffer,
- UserInfo->AdminComment.Length);
- UserInfo4->usri4_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
- }
-
- UserInfo4->usri4_flags = GetAccountFlags(UserInfo->UserAccountControl);
-
- if (UserInfo->ScriptPath.Length > 0)
- {
- UserInfo4->usri4_script_path = Ptr;
-
- memcpy(UserInfo4->usri4_script_path,
- UserInfo->ScriptPath.Buffer,
- UserInfo->ScriptPath.Length);
- UserInfo4->usri4_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ScriptPath.Length + sizeof(WCHAR));
- }
-
- /* FIXME: usri4_auth_flags */
-
- if (UserInfo->FullName.Length > 0)
- {
- UserInfo4->usri4_full_name = Ptr;
-
- memcpy(UserInfo4->usri4_full_name,
- UserInfo->FullName.Buffer,
- UserInfo->FullName.Length);
- UserInfo4->usri4_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
- }
-
- if (UserInfo->UserComment.Length > 0)
- {
- UserInfo4->usri4_usr_comment = Ptr;
-
- memcpy(UserInfo4->usri4_usr_comment,
- UserInfo->UserComment.Buffer,
- UserInfo->UserComment.Length);
- UserInfo4->usri4_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
- }
-
- if (UserInfo->Parameters.Length > 0)
- {
- UserInfo4->usri4_parms = Ptr;
-
- memcpy(UserInfo4->usri4_parms,
- UserInfo->Parameters.Buffer,
- UserInfo->Parameters.Length);
- UserInfo4->usri4_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
- }
-
- if (UserInfo->WorkStations.Length > 0)
- {
- UserInfo4->usri4_workstations = Ptr;
-
- memcpy(UserInfo4->usri4_workstations,
- UserInfo->WorkStations.Buffer,
- UserInfo->WorkStations.Length);
- UserInfo4->usri4_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
- }
-
- RtlTimeToSecondsSince1970(&UserInfo->LastLogon,
- &UserInfo4->usri4_last_logon);
+ UserInfo4->usri4_priv = Priv;
+
+ UserInfo4->usri4_home_dir = Ptr;
+ memcpy(UserInfo4->usri4_home_dir,
+ UserInfo->HomeDirectory.Buffer,
+ UserInfo->HomeDirectory.Length);
+ UserInfo4->usri4_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
+
+ UserInfo4->usri4_comment = Ptr;
+ memcpy(UserInfo4->usri4_comment,
+ UserInfo->AdminComment.Buffer,
+ UserInfo->AdminComment.Length);
+ UserInfo4->usri4_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
+
+ UserInfo4->usri4_flags = GetAccountFlags(UserInfo->UserAccountControl,
+ Dacl);
+
+ UserInfo4->usri4_script_path = Ptr;
+ memcpy(UserInfo4->usri4_script_path,
+ UserInfo->ScriptPath.Buffer,
+ UserInfo->ScriptPath.Length);
+ UserInfo4->usri4_script_path[UserInfo->ScriptPath.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ScriptPath.Length + sizeof(WCHAR));
+
+ UserInfo4->usri4_auth_flags = AuthFlags;
+
+ UserInfo4->usri4_full_name = Ptr;
+ memcpy(UserInfo4->usri4_full_name,
+ UserInfo->FullName.Buffer,
+ UserInfo->FullName.Length);
+ UserInfo4->usri4_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
+
+ UserInfo4->usri4_usr_comment = Ptr;
+ memcpy(UserInfo4->usri4_usr_comment,
+ UserInfo->UserComment.Buffer,
+ UserInfo->UserComment.Length);
+ UserInfo4->usri4_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
+
+ UserInfo4->usri4_parms = Ptr;
+ memcpy(UserInfo4->usri4_parms,
+ UserInfo->Parameters.Buffer,
+ UserInfo->Parameters.Length);
+ UserInfo4->usri4_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
+
+ UserInfo4->usri4_workstations = Ptr;
+ memcpy(UserInfo4->usri4_workstations,
+ UserInfo->WorkStations.Buffer,
+ UserInfo->WorkStations.Length);
+ UserInfo4->usri4_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
+
+ if (UserInfo->LastLogon.QuadPart == 0)
+ UserInfo4->usri4_last_logon = 0;
+ else
+ RtlTimeToSecondsSince1970(&UserInfo->LastLogon,
+ &UserInfo4->usri4_last_logon);
- RtlTimeToSecondsSince1970(&UserInfo->LastLogoff,
- &UserInfo4->usri4_last_logoff);
+ if (UserInfo->LastLogoff.QuadPart == 0)
+ UserInfo4->usri4_last_logoff = 0;
+ else
+ RtlTimeToSecondsSince1970(&UserInfo->LastLogoff,
+ &UserInfo4->usri4_last_logoff);
- RtlTimeToSecondsSince1970(&UserInfo->AccountExpires,
- &UserInfo4->usri4_acct_expires);
+ if (UserInfo->AccountExpires.QuadPart == MAXLONGLONG)
+ UserInfo4->usri4_acct_expires = TIMEQ_FOREVER;
+ else
+ RtlTimeToSecondsSince1970(&UserInfo->AccountExpires,
+ &UserInfo4->usri4_acct_expires);
UserInfo4->usri4_max_storage = USER_MAXSTORAGE_UNLIMITED;
UserInfo4->usri4_units_per_week = UserInfo->LogonHours.UnitsPerWeek;
UserInfo4->usri4_bad_pw_count = UserInfo->BadPasswordCount;
UserInfo4->usri4_num_logons = UserInfo->LogonCount;
- if (LogonServer.Length > 0)
- {
- UserInfo4->usri4_logon_server = Ptr;
-
- memcpy(UserInfo4->usri4_logon_server,
- LogonServer.Buffer,
- LogonServer.Length);
- UserInfo4->usri4_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
- }
+ UserInfo4->usri4_logon_server = Ptr;
+ memcpy(UserInfo4->usri4_logon_server,
+ LogonServer.Buffer,
+ LogonServer.Length);
+ UserInfo4->usri4_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
UserInfo4->usri4_country_code = UserInfo->CountryCode;
UserInfo4->usri4_code_page = UserInfo->CodePage;
- /* FIXME: usri4_user_sid */
+ UserInfo4->usri4_user_sid = (PVOID)Ptr;
+ CopySidFromSidAndRid(UserInfo4->usri4_user_sid, AccountDomainSid, RelativeId);
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + RtlLengthSid(AccountDomainSid) + sizeof(ULONG));
UserInfo4->usri4_primary_group_id = UserInfo->PrimaryGroupId;
- if (UserInfo->ProfilePath.Length > 0)
- {
- UserInfo4->usri4_profile = Ptr;
-
- memcpy(UserInfo4->usri4_profile,
- UserInfo->ProfilePath.Buffer,
- UserInfo->ProfilePath.Length);
- UserInfo4->usri4_profile[UserInfo->ProfilePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ UserInfo4->usri4_profile = Ptr;
+ memcpy(UserInfo4->usri4_profile,
+ UserInfo->ProfilePath.Buffer,
+ UserInfo->ProfilePath.Length);
+ UserInfo4->usri4_profile[UserInfo->ProfilePath.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ProfilePath.Length + sizeof(WCHAR));
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->ProfilePath.Length + sizeof(WCHAR));
- }
-
- if (UserInfo->HomeDirectoryDrive.Length > 0)
- {
- UserInfo4->usri4_home_dir_drive = Ptr;
-
- memcpy(UserInfo4->usri4_home_dir_drive,
- UserInfo->HomeDirectoryDrive.Buffer,
- UserInfo->HomeDirectoryDrive.Length);
- UserInfo4->usri4_home_dir_drive[UserInfo->HomeDirectoryDrive.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR));
- }
+ UserInfo4->usri4_home_dir_drive = Ptr;
+ memcpy(UserInfo4->usri4_home_dir_drive,
+ UserInfo->HomeDirectoryDrive.Buffer,
+ UserInfo->HomeDirectoryDrive.Length);
+ UserInfo4->usri4_home_dir_drive[UserInfo->HomeDirectoryDrive.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectoryDrive.Length + sizeof(WCHAR));
UserInfo4->usri4_password_expired = (UserInfo->UserAccountControl & USER_PASSWORD_EXPIRED);
break;
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
- if (UserInfo->AdminComment.Length > 0)
- {
- UserInfo10->usri10_comment = Ptr;
-
- memcpy(UserInfo10->usri10_comment,
- UserInfo->AdminComment.Buffer,
- UserInfo->AdminComment.Length);
- UserInfo10->usri10_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
- }
-
- if (UserInfo->UserComment.Length > 0)
- {
- UserInfo10->usri10_usr_comment = Ptr;
-
- memcpy(UserInfo10->usri10_usr_comment,
- UserInfo->UserComment.Buffer,
- UserInfo->UserComment.Length);
- UserInfo10->usri10_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
- }
-
- if (UserInfo->FullName.Length > 0)
- {
- UserInfo10->usri10_full_name = Ptr;
-
- memcpy(UserInfo10->usri10_full_name,
- UserInfo->FullName.Buffer,
- UserInfo->FullName.Length);
- UserInfo10->usri10_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
- }
+ UserInfo10->usri10_comment = Ptr;
+ memcpy(UserInfo10->usri10_comment,
+ UserInfo->AdminComment.Buffer,
+ UserInfo->AdminComment.Length);
+ UserInfo10->usri10_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
+
+ UserInfo10->usri10_usr_comment = Ptr;
+ memcpy(UserInfo10->usri10_usr_comment,
+ UserInfo->UserComment.Buffer,
+ UserInfo->UserComment.Length);
+ UserInfo10->usri10_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
+
+ UserInfo10->usri10_full_name = Ptr;
+ memcpy(UserInfo10->usri10_full_name,
+ UserInfo->FullName.Buffer,
+ UserInfo->FullName.Length);
+ UserInfo10->usri10_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
break;
case 11:
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
- if (UserInfo->AdminComment.Length > 0)
- {
- UserInfo11->usri11_comment = Ptr;
-
- memcpy(UserInfo11->usri11_comment,
- UserInfo->AdminComment.Buffer,
- UserInfo->AdminComment.Length);
- UserInfo11->usri11_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
- }
-
- if (UserInfo->UserComment.Length > 0)
- {
- UserInfo11->usri11_usr_comment = Ptr;
-
- memcpy(UserInfo11->usri11_usr_comment,
- UserInfo->UserComment.Buffer,
- UserInfo->UserComment.Length);
- UserInfo11->usri11_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
- }
-
- if (UserInfo->FullName.Length > 0)
- {
- UserInfo11->usri11_full_name = Ptr;
-
- memcpy(UserInfo11->usri11_full_name,
- UserInfo->FullName.Buffer,
- UserInfo->FullName.Length);
- UserInfo11->usri11_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
- }
-
- /* FIXME: usri11_priv */
- /* FIXME: usri11_auth_flags */
+ UserInfo11->usri11_comment = Ptr;
+ memcpy(UserInfo11->usri11_comment,
+ UserInfo->AdminComment.Buffer,
+ UserInfo->AdminComment.Length);
+ UserInfo11->usri11_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
+
+ UserInfo11->usri11_usr_comment = Ptr;
+ memcpy(UserInfo11->usri11_usr_comment,
+ UserInfo->UserComment.Buffer,
+ UserInfo->UserComment.Length);
+ UserInfo11->usri11_usr_comment[UserInfo->UserComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserComment.Length + sizeof(WCHAR));
+
+ UserInfo11->usri11_full_name = Ptr;
+ memcpy(UserInfo11->usri11_full_name,
+ UserInfo->FullName.Buffer,
+ UserInfo->FullName.Length);
+ UserInfo11->usri11_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
+
+ UserInfo11->usri11_priv = Priv;
+ UserInfo11->usri11_auth_flags = AuthFlags;
UserInfo11->usri11_password_age = GetPasswordAge(&UserInfo->PasswordLastSet);
- if (UserInfo->HomeDirectory.Length > 0)
- {
- UserInfo11->usri11_home_dir = Ptr;
-
- memcpy(UserInfo11->usri11_home_dir,
- UserInfo->HomeDirectory.Buffer,
- UserInfo->HomeDirectory.Length);
- UserInfo11->usri11_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
- }
-
- if (UserInfo->Parameters.Length > 0)
- {
- UserInfo11->usri11_parms = Ptr;
-
- memcpy(UserInfo11->usri11_parms,
- UserInfo->Parameters.Buffer,
- UserInfo->Parameters.Length);
- UserInfo11->usri11_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
- }
-
- RtlTimeToSecondsSince1970(&UserInfo->LastLogon,
- &UserInfo11->usri11_last_logon);
+ UserInfo11->usri11_home_dir = Ptr;
+ memcpy(UserInfo11->usri11_home_dir,
+ UserInfo->HomeDirectory.Buffer,
+ UserInfo->HomeDirectory.Length);
+ UserInfo11->usri11_home_dir[UserInfo->HomeDirectory.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->HomeDirectory.Length + sizeof(WCHAR));
+
+ UserInfo11->usri11_parms = Ptr;
+ memcpy(UserInfo11->usri11_parms,
+ UserInfo->Parameters.Buffer,
+ UserInfo->Parameters.Length);
+ UserInfo11->usri11_parms[UserInfo->Parameters.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->Parameters.Length + sizeof(WCHAR));
+
+ if (UserInfo->LastLogon.QuadPart == 0)
+ UserInfo11->usri11_last_logon = 0;
+ else
+ RtlTimeToSecondsSince1970(&UserInfo->LastLogon,
+ &UserInfo11->usri11_last_logon);
- RtlTimeToSecondsSince1970(&UserInfo->LastLogoff,
- &UserInfo11->usri11_last_logoff);
+ if (UserInfo->LastLogoff.QuadPart == 0)
+ UserInfo11->usri11_last_logoff = 0;
+ else
+ RtlTimeToSecondsSince1970(&UserInfo->LastLogoff,
+ &UserInfo11->usri11_last_logoff);
UserInfo11->usri11_bad_pw_count = UserInfo->BadPasswordCount;
UserInfo11->usri11_num_logons = UserInfo->LogonCount;
- if (LogonServer.Length > 0)
- {
- UserInfo11->usri11_logon_server = Ptr;
-
- memcpy(UserInfo11->usri11_logon_server,
- LogonServer.Buffer,
- LogonServer.Length);
- UserInfo11->usri11_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
- }
+ UserInfo11->usri11_logon_server = Ptr;
+ memcpy(UserInfo11->usri11_logon_server,
+ LogonServer.Buffer,
+ LogonServer.Length);
+ UserInfo11->usri11_logon_server[LogonServer.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + LogonServer.Length + sizeof(WCHAR));
UserInfo11->usri11_country_code = UserInfo->CountryCode;
- if (UserInfo->WorkStations.Length > 0)
- {
- UserInfo11->usri11_workstations = Ptr;
-
- memcpy(UserInfo11->usri11_workstations,
- UserInfo->WorkStations.Buffer,
- UserInfo->WorkStations.Length);
- UserInfo11->usri11_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
- }
+ UserInfo11->usri11_workstations = Ptr;
+ memcpy(UserInfo11->usri11_workstations,
+ UserInfo->WorkStations.Buffer,
+ UserInfo->WorkStations.Length);
+ UserInfo11->usri11_workstations[UserInfo->WorkStations.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->WorkStations.Length + sizeof(WCHAR));
UserInfo11->usri11_max_storage = USER_MAXSTORAGE_UNLIMITED;
UserInfo11->usri11_units_per_week = UserInfo->LogonHours.UnitsPerWeek;
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
- if (UserInfo->FullName.Length > 0)
- {
- UserInfo20->usri20_full_name = Ptr;
-
- memcpy(UserInfo20->usri20_full_name,
- UserInfo->FullName.Buffer,
- UserInfo->FullName.Length);
- UserInfo20->usri20_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
- }
-
- if (UserInfo->AdminComment.Length > 0)
- {
- UserInfo20->usri20_comment = Ptr;
-
- memcpy(UserInfo20->usri20_comment,
- UserInfo->AdminComment.Buffer,
- UserInfo->AdminComment.Length);
- UserInfo20->usri20_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ UserInfo20->usri20_full_name = Ptr;
+ memcpy(UserInfo20->usri20_full_name,
+ UserInfo->FullName.Buffer,
+ UserInfo->FullName.Length);
+ UserInfo20->usri20_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
- }
+ UserInfo20->usri20_comment = Ptr;
+ memcpy(UserInfo20->usri20_comment,
+ UserInfo->AdminComment.Buffer,
+ UserInfo->AdminComment.Length);
+ UserInfo20->usri20_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
- UserInfo20->usri20_flags = GetAccountFlags(UserInfo->UserAccountControl);
+ UserInfo20->usri20_flags = GetAccountFlags(UserInfo->UserAccountControl,
+ Dacl);
UserInfo20->usri20_user_id = RelativeId;
break;
Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR));
- if (UserInfo->FullName.Length > 0)
- {
- UserInfo23->usri23_full_name = Ptr;
-
- memcpy(UserInfo23->usri23_full_name,
- UserInfo->FullName.Buffer,
- UserInfo->FullName.Length);
- UserInfo23->usri23_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
- }
-
- if (UserInfo->AdminComment.Length > 0)
- {
- UserInfo23->usri23_comment = Ptr;
-
- memcpy(UserInfo23->usri23_comment,
- UserInfo->AdminComment.Buffer,
- UserInfo->AdminComment.Length);
- UserInfo23->usri23_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
-
- Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
- }
-
- UserInfo23->usri23_flags = GetAccountFlags(UserInfo->UserAccountControl);
-
- /* FIXME: usri23_user_sid */
- break;
+ UserInfo23->usri23_full_name = Ptr;
+ memcpy(UserInfo23->usri23_full_name,
+ UserInfo->FullName.Buffer,
+ UserInfo->FullName.Length);
+ UserInfo23->usri23_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR));
+
+ UserInfo23->usri23_comment = Ptr;
+ memcpy(UserInfo23->usri23_comment,
+ UserInfo->AdminComment.Buffer,
+ UserInfo->AdminComment.Length);
+ UserInfo23->usri23_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR));
+
+ UserInfo23->usri23_flags = GetAccountFlags(UserInfo->UserAccountControl,
+ Dacl);
+
+ UserInfo23->usri23_user_sid = (PVOID)Ptr;
+ CopySidFromSidAndRid(UserInfo23->usri23_user_sid, AccountDomainSid, RelativeId);
+ Ptr = (LPWSTR)((ULONG_PTR)Ptr + RtlLengthSid(AccountDomainSid) + sizeof(ULONG));
+ break;
}
done:
+ if (UserInfo != NULL)
+ FreeUserInfo(UserInfo);
+
+ if (Dacl != NULL)
+ HeapFree(GetProcessHeap(), 0, Dacl);
+
if (ApiStatus == NERR_Success)
{
*Buffer = LocalBuffer;
}
-static
-VOID
-FreeUserInfo(PUSER_ALL_INFORMATION UserInfo)
-{
- if (UserInfo->UserName.Buffer != NULL)
- SamFreeMemory(UserInfo->UserName.Buffer);
-
- if (UserInfo->FullName.Buffer != NULL)
- SamFreeMemory(UserInfo->FullName.Buffer);
-
- if (UserInfo->HomeDirectory.Buffer != NULL)
- SamFreeMemory(UserInfo->HomeDirectory.Buffer);
-
- if (UserInfo->HomeDirectoryDrive.Buffer != NULL)
- SamFreeMemory(UserInfo->HomeDirectoryDrive.Buffer);
-
- if (UserInfo->ScriptPath.Buffer != NULL)
- SamFreeMemory(UserInfo->ScriptPath.Buffer);
-
- if (UserInfo->ProfilePath.Buffer != NULL)
- SamFreeMemory(UserInfo->ProfilePath.Buffer);
-
- if (UserInfo->AdminComment.Buffer != NULL)
- SamFreeMemory(UserInfo->AdminComment.Buffer);
-
- if (UserInfo->WorkStations.Buffer != NULL)
- SamFreeMemory(UserInfo->WorkStations.Buffer);
-
- if (UserInfo->UserComment.Buffer != NULL)
- SamFreeMemory(UserInfo->UserComment.Buffer);
-
- if (UserInfo->Parameters.Buffer != NULL)
- SamFreeMemory(UserInfo->Parameters.Buffer);
-
- if (UserInfo->PrivateData.Buffer != NULL)
- SamFreeMemory(UserInfo->PrivateData.Buffer);
-
- if (UserInfo->LogonHours.LogonHours != NULL)
- SamFreeMemory(UserInfo->LogonHours.LogonHours);
-
- SamFreeMemory(UserInfo);
-}
-
-
static
NET_API_STATUS
SetUserInfo(SAM_HANDLE UserHandle,
LPBYTE UserInfo,
- DWORD Level)
+ DWORD Level,
+ PDWORD parm_err)
{
USER_ALL_INFORMATION UserAllInfo;
PUSER_INFO_0 UserInfo0;
PUSER_INFO_2 UserInfo2;
PUSER_INFO_3 UserInfo3;
PUSER_INFO_4 UserInfo4;
+ PUSER_INFO_22 UserInfo22;
PUSER_INFO_1003 UserInfo1003;
PUSER_INFO_1006 UserInfo1006;
PUSER_INFO_1007 UserInfo1007;
PUSER_INFO_1014 UserInfo1014;
PUSER_INFO_1017 UserInfo1017;
PUSER_INFO_1018 UserInfo1018;
+ PUSER_INFO_1020 UserInfo1020;
PUSER_INFO_1024 UserInfo1024;
PUSER_INFO_1025 UserInfo1025;
PUSER_INFO_1051 UserInfo1051;
PUSER_INFO_1052 UserInfo1052;
PUSER_INFO_1053 UserInfo1053;
+ PACL Dacl = NULL;
NET_API_STATUS ApiStatus = NERR_Success;
NTSTATUS Status = STATUS_SUCCESS;
ZeroMemory(&UserAllInfo, sizeof(USER_ALL_INFORMATION));
+ if ((Level == 1) || (Level == 2) || (Level == 3) ||
+ (Level == 4) || (Level == 22) || (Level == 1008))
+ {
+ ApiStatus = GetUserDacl(UserHandle, &Dacl);
+ if (ApiStatus != NERR_Success)
+ goto done;
+ }
+
switch (Level)
{
case 0:
UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
}
+ ChangeUserDacl(Dacl, UserInfo1->usri1_flags);
UserAllInfo.UserAccountControl = GetAccountControl(UserInfo1->usri1_flags);
UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
}
+ ChangeUserDacl(Dacl, UserInfo2->usri2_flags);
UserAllInfo.UserAccountControl = GetAccountControl(UserInfo2->usri2_flags);
UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
if (UserInfo2->usri2_acct_expires == TIMEQ_FOREVER)
{
- UserAllInfo.AccountExpires.LowPart = 0;
- UserAllInfo.AccountExpires.HighPart = 0;
+ UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG;
}
else
{
}
UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
- // usri2_max_storage ignored
+ if (UserInfo2->usri2_max_storage != USER_MAXSTORAGE_UNLIMITED)
+ {
+ if (parm_err != NULL)
+ *parm_err = USER_MAX_STORAGE_PARMNUM;
+ ApiStatus = ERROR_INVALID_PARAMETER;
+ break;
+ }
+
+ if (UserInfo2->usri2_units_per_week > USHRT_MAX)
+ {
+ if (parm_err != NULL)
+ *parm_err = USER_UNITS_PER_WEEK_PARMNUM;
+ ApiStatus = ERROR_INVALID_PARAMETER;
+ break;
+ }
-// UserInfo2->usri2_units_per_week;
-// UserInfo2->usri2_logon_hours;
+ UserAllInfo.LogonHours.UnitsPerWeek = UserInfo2->usri2_units_per_week;
+ UserAllInfo.LogonHours.LogonHours = UserInfo2->usri2_logon_hours;
+ UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS;
// usri2_bad_pw_count ignored
// usri2_num_logons ignored
UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
}
+ ChangeUserDacl(Dacl, UserInfo3->usri3_flags);
UserAllInfo.UserAccountControl = GetAccountControl(UserInfo3->usri3_flags);
UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
if (UserInfo3->usri3_acct_expires == TIMEQ_FOREVER)
{
- UserAllInfo.AccountExpires.LowPart = 0;
- UserAllInfo.AccountExpires.HighPart = 0;
+ UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG;
}
else
{
}
UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
- // usri3_max_storage ignored
+ if (UserInfo3->usri3_max_storage != USER_MAXSTORAGE_UNLIMITED)
+ {
+ if (parm_err != NULL)
+ *parm_err = USER_MAX_STORAGE_PARMNUM;
+ ApiStatus = ERROR_INVALID_PARAMETER;
+ break;
+ }
+
+ if (UserInfo3->usri3_units_per_week > USHRT_MAX)
+ {
+ if (parm_err != NULL)
+ *parm_err = USER_UNITS_PER_WEEK_PARMNUM;
+ ApiStatus = ERROR_INVALID_PARAMETER;
+ break;
+ }
-// UserInfo3->usri3_units_per_week;
-// UserInfo3->usri3_logon_hours;
+ UserAllInfo.LogonHours.UnitsPerWeek = UserInfo3->usri3_units_per_week;
+ UserAllInfo.LogonHours.LogonHours = UserInfo3->usri3_logon_hours;
+ UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS;
// usri3_bad_pw_count ignored
// usri3_num_logons ignored
UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
}
+ ChangeUserDacl(Dacl, UserInfo4->usri4_flags);
UserAllInfo.UserAccountControl = GetAccountControl(UserInfo4->usri4_flags);
UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
if (UserInfo4->usri4_acct_expires == TIMEQ_FOREVER)
{
- UserAllInfo.AccountExpires.LowPart = 0;
- UserAllInfo.AccountExpires.HighPart = 0;
+ UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG;
}
else
{
}
UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
- // usri4_max_storage ignored
+ if (UserInfo4->usri4_max_storage != USER_MAXSTORAGE_UNLIMITED)
+ {
+ if (parm_err != NULL)
+ *parm_err = USER_MAX_STORAGE_PARMNUM;
+ ApiStatus = ERROR_INVALID_PARAMETER;
+ break;
+ }
+
+ if (UserInfo4->usri4_units_per_week > USHRT_MAX)
+ {
+ if (parm_err != NULL)
+ *parm_err = USER_UNITS_PER_WEEK_PARMNUM;
+ ApiStatus = ERROR_INVALID_PARAMETER;
+ break;
+ }
-// UserInfo3->usri4_units_per_week;
-// UserInfo3->usri4_logon_hours;
+ UserAllInfo.LogonHours.UnitsPerWeek = UserInfo4->usri4_units_per_week;
+ UserAllInfo.LogonHours.LogonHours = UserInfo4->usri4_logon_hours;
+ UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS;
// usri4_bad_pw_count ignored
// usri4_num_logons ignored
break;
// case 21:
-// case 22:
+// break;
+
+ case 22:
+ UserInfo22 = (PUSER_INFO_22)UserInfo;
+
+ // usri22_name ignored
+
+// UserInfo22->usri22_password[ENCRYPTED_PWLEN];
+
+ // usri22_password_age ignored
+
+// UserInfo3->usri3_priv;
+
+ if (UserInfo22->usri22_home_dir != NULL)
+ {
+ RtlInitUnicodeString(&UserAllInfo.HomeDirectory,
+ UserInfo22->usri22_home_dir);
+ UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORY;
+ }
+
+ if (UserInfo22->usri22_comment != NULL)
+ {
+ RtlInitUnicodeString(&UserAllInfo.AdminComment,
+ UserInfo22->usri22_comment);
+ UserAllInfo.WhichFields |= USER_ALL_ADMINCOMMENT;
+ }
+
+ ChangeUserDacl(Dacl, UserInfo22->usri22_flags);
+ UserAllInfo.UserAccountControl = GetAccountControl(UserInfo22->usri22_flags);
+ UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
+
+ if (UserInfo22->usri22_script_path != NULL)
+ {
+ RtlInitUnicodeString(&UserAllInfo.ScriptPath,
+ UserInfo22->usri22_script_path);
+ UserAllInfo.WhichFields |= USER_ALL_SCRIPTPATH;
+ }
+
+// UserInfo22->usri22_auth_flags;
+
+ if (UserInfo22->usri22_full_name != NULL)
+ {
+ RtlInitUnicodeString(&UserAllInfo.FullName,
+ UserInfo22->usri22_full_name);
+ UserAllInfo.WhichFields |= USER_ALL_FULLNAME;
+ }
+
+ if (UserInfo22->usri22_usr_comment != NULL)
+ {
+ RtlInitUnicodeString(&UserAllInfo.UserComment,
+ UserInfo22->usri22_usr_comment);
+ UserAllInfo.WhichFields |= USER_ALL_USERCOMMENT;
+ }
+
+ if (UserInfo22->usri22_parms != NULL)
+ {
+ RtlInitUnicodeString(&UserAllInfo.Parameters,
+ UserInfo22->usri22_parms);
+ UserAllInfo.WhichFields |= USER_ALL_PARAMETERS;
+ }
+
+ if (UserInfo22->usri22_workstations != NULL)
+ {
+ RtlInitUnicodeString(&UserAllInfo.WorkStations,
+ UserInfo22->usri22_workstations);
+ UserAllInfo.WhichFields |= USER_ALL_WORKSTATIONS;
+ }
+
+ // usri22_last_logon ignored
+ // usri22_last_logoff ignored
+
+ if (UserInfo22->usri22_acct_expires == TIMEQ_FOREVER)
+ {
+ UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG;
+ }
+ else
+ {
+ RtlSecondsSince1970ToTime(UserInfo22->usri22_acct_expires,
+ &UserAllInfo.AccountExpires);
+ }
+ UserAllInfo.WhichFields |= USER_ALL_ACCOUNTEXPIRES;
+
+ if (UserInfo22->usri22_max_storage != USER_MAXSTORAGE_UNLIMITED)
+ {
+ if (parm_err != NULL)
+ *parm_err = USER_MAX_STORAGE_PARMNUM;
+ ApiStatus = ERROR_INVALID_PARAMETER;
+ break;
+ }
+
+ if (UserInfo22->usri22_units_per_week > USHRT_MAX)
+ {
+ if (parm_err != NULL)
+ *parm_err = USER_UNITS_PER_WEEK_PARMNUM;
+ ApiStatus = ERROR_INVALID_PARAMETER;
+ break;
+ }
+
+ UserAllInfo.LogonHours.UnitsPerWeek = UserInfo22->usri22_units_per_week;
+ UserAllInfo.LogonHours.LogonHours = UserInfo22->usri22_logon_hours;
+ UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS;
+
+ // usri22_bad_pw_count ignored
+ // usri22_num_logons ignored
+ // usri22_logon_server ignored
+
+ UserAllInfo.CountryCode = UserInfo22->usri22_country_code;
+ UserAllInfo.WhichFields |= USER_ALL_COUNTRYCODE;
+
+ UserAllInfo.CodePage = UserInfo22->usri22_code_page;
+ UserAllInfo.WhichFields |= USER_ALL_CODEPAGE;
+ break;
case 1003:
UserInfo1003 = (PUSER_INFO_1003)UserInfo;
break;
// case 1005:
+// break;
case 1006:
UserInfo1006 = (PUSER_INFO_1006)UserInfo;
case 1008:
UserInfo1008 = (PUSER_INFO_1008)UserInfo;
+ ChangeUserDacl(Dacl, UserInfo1008->usri1008_flags);
UserAllInfo.UserAccountControl = GetAccountControl(UserInfo1008->usri1008_flags);
UserAllInfo.WhichFields |= USER_ALL_USERACCOUNTCONTROL;
break;
break;
// case 1010:
+// break;
case 1011:
UserInfo1011 = (PUSER_INFO_1011)UserInfo;
if (UserInfo1017->usri1017_acct_expires == TIMEQ_FOREVER)
{
- UserAllInfo.AccountExpires.LowPart = 0;
- UserAllInfo.AccountExpires.HighPart = 0;
+ UserAllInfo.AccountExpires.QuadPart = MAXLONGLONG;
}
else
{
if (UserInfo1018->usri1018_max_storage != USER_MAXSTORAGE_UNLIMITED)
{
- // FIXME: Report error
- return ERROR_INVALID_PARAMETER;
+ if (parm_err != NULL)
+ *parm_err = USER_MAX_STORAGE_PARMNUM;
+ ApiStatus = ERROR_INVALID_PARAMETER;
}
break;
-// case 1020:
+ case 1020:
+ UserInfo1020 = (PUSER_INFO_1020)UserInfo;
+
+ if (UserInfo1020->usri1020_units_per_week > USHRT_MAX)
+ {
+ if (parm_err != NULL)
+ *parm_err = USER_UNITS_PER_WEEK_PARMNUM;
+ ApiStatus = ERROR_INVALID_PARAMETER;
+ break;
+ }
+
+ UserAllInfo.LogonHours.UnitsPerWeek = UserInfo1020->usri1020_units_per_week;
+ UserAllInfo.LogonHours.LogonHours = UserInfo1020->usri1020_logon_hours;
+ UserAllInfo.WhichFields |= USER_ALL_LOGONHOURS;
+ break;
case 1024:
UserInfo1024 = (PUSER_INFO_1024)UserInfo;
UserAllInfo.WhichFields |= USER_ALL_HOMEDIRECTORYDRIVE;
}
break;
-
- default:
- ERR("Unsupported level %lu!\n", Level);
- return ERROR_INVALID_PARAMETER;
}
+ if (ApiStatus != NERR_Success)
+ goto done;
+
Status = SamSetInformationUser(UserHandle,
UserAllInformation,
&UserAllInfo);
}
done:
+ if (Dacl != NULL)
+ HeapFree(GetProcessHeap(), 0, Dacl);
+
return ApiStatus;
}
TRACE("(%s, %d, %p, %p)\n", debugstr_w(servername), level, bufptr, parm_err);
+ if (parm_err != NULL)
+ *parm_err = PARM_ERROR_NONE;
+
/* Check the info level */
switch (level)
{
/* Open the Account Domain */
Status = OpenAccountDomain(ServerHandle,
(servername != NULL) ? &ServerName : NULL,
- DOMAIN_CREATE_USER | DOMAIN_LOOKUP,
+ DOMAIN_CREATE_USER | DOMAIN_LOOKUP | DOMAIN_READ_PASSWORD_PARAMETERS,
&DomainHandle);
if (!NT_SUCCESS(Status))
{
/* Set user information */
ApiStatus = SetUserInfo(UserHandle,
bufptr,
- level);
+ level,
+ parm_err);
if (ApiStatus != NERR_Success)
{
ERR("SetUserInfo failed (Status %lu)\n", ApiStatus);
done:
if (UserHandle != NULL)
- SamCloseHandle(UserHandle);
+ {
+ if (ApiStatus != NERR_Success)
+ SamDeleteUser(UserHandle);
+ else
+ SamCloseHandle(UserHandle);
+ }
if (DomainHandle != NULL)
SamCloseHandle(DomainHandle);
{
ERR("OpenUserByName failed (ApiStatus %lu)\n", ApiStatus);
if (ApiStatus == ERROR_NONE_MAPPED)
- ApiStatus = NERR_GroupNotFound;
+ ApiStatus = NERR_UserNotFound;
goto done;
}
}
goto done;
}
+ /* A successful delete invalidates the handle */
+ UserHandle = NULL;
+
done:
if (UserHandle != NULL)
SamCloseHandle(UserHandle);
LPVOID Buffer = NULL;
ULONG i;
SAM_HANDLE UserHandle = NULL;
- PUSER_ALL_INFORMATION UserInfo = NULL;
-
+ ACCESS_MASK DesiredAccess;
NET_API_STATUS ApiStatus = NERR_Success;
NTSTATUS Status = STATUS_SUCCESS;
goto done;
}
- Status = OpenAccountDomain(EnumContext->ServerHandle,
- (servername != NULL) ? &ServerName : NULL,
- DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
- &EnumContext->AccountDomainHandle);
+ /* Get the Account Domain SID */
+ Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL,
+ &EnumContext->AccountDomainSid);
if (!NT_SUCCESS(Status))
{
- ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
+ ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
ApiStatus = NetpNtStatusToApiStatus(Status);
goto done;
}
- Status = OpenBuiltinDomain(EnumContext->ServerHandle,
- DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
- &EnumContext->BuiltinDomainHandle);
+ /* Open the Account Domain */
+ Status = SamOpenDomain(EnumContext->ServerHandle,
+ DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
+ EnumContext->AccountDomainSid,
+ &EnumContext->AccountDomainHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("SamOpenDomain failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ /* Get the Builtin Domain SID */
+ Status = GetBuiltinDomainSid(&EnumContext->BuiltinDomainSid);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("GetBuiltinDomainSid failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ DesiredAccess = DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP;
+ if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11))
+ DesiredAccess |= DOMAIN_GET_ALIAS_MEMBERSHIP;
+
+ /* Open the Builtin Domain */
+ Status = SamOpenDomain(EnumContext->ServerHandle,
+ DesiredAccess,
+ EnumContext->BuiltinDomainSid,
+ &EnumContext->BuiltinDomainHandle);
if (!NT_SUCCESS(Status))
{
- ERR("OpenBuiltinDomain failed (Status %08lx)\n", Status);
+ ERR("SamOpenDomain failed (Status %08lx)\n", Status);
ApiStatus = NetpNtStatusToApiStatus(Status);
goto done;
}
if (EnumContext->Index >= EnumContext->Count)
{
-// if (EnumContext->BuiltinDone == TRUE)
+// if (EnumContext->BuiltinDone != FALSE)
// {
// ApiStatus = NERR_Success;
// goto done;
TRACE("RID: %lu\n", CurrentUser->RelativeId);
+ DesiredAccess = READ_CONTROL | USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT;
+ if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11))
+ DesiredAccess |= USER_LIST_GROUPS;
+
Status = SamOpenUser(EnumContext->AccountDomainHandle, //BuiltinDomainHandle,
- USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT,
+ DesiredAccess,
CurrentUser->RelativeId,
&UserHandle);
if (!NT_SUCCESS(Status))
goto done;
}
- Status = SamQueryInformationUser(UserHandle,
- UserAllInformation,
- (PVOID *)&UserInfo);
- if (!NT_SUCCESS(Status))
- {
- ERR("SamQueryInformationUser failed (Status %08lx)\n", Status);
- ApiStatus = NetpNtStatusToApiStatus(Status);
- goto done;
- }
-
- SamCloseHandle(UserHandle);
- UserHandle = NULL;
-
- ApiStatus = BuildUserInfoBuffer(UserInfo,
- level,
+ ApiStatus = BuildUserInfoBuffer(EnumContext->BuiltinDomainHandle,
+ UserHandle,
+ EnumContext->AccountDomainSid,
CurrentUser->RelativeId,
+ level,
&Buffer);
if (ApiStatus != NERR_Success)
{
goto done;
}
- if (UserInfo != NULL)
- {
- FreeUserInfo(UserInfo);
- UserInfo = NULL;
- }
+ SamCloseHandle(UserHandle);
+ UserHandle = NULL;
EnumContext->Index++;
// }
done:
- if (ApiStatus == NERR_Success && EnumContext->Index < EnumContext->Count)
+ if (ApiStatus == NERR_Success && EnumContext != NULL && EnumContext->Index < EnumContext->Count)
ApiStatus = ERROR_MORE_DATA;
if (EnumContext != NULL)
if (EnumContext->AccountDomainHandle != NULL)
SamCloseHandle(EnumContext->AccountDomainHandle);
+ if (EnumContext->BuiltinDomainSid != NULL)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, EnumContext->BuiltinDomainSid);
+
+ if (EnumContext->AccountDomainSid != NULL)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, EnumContext->AccountDomainSid);
+
if (EnumContext->ServerHandle != NULL)
SamCloseHandle(EnumContext->ServerHandle);
if (UserHandle != NULL)
SamCloseHandle(UserHandle);
- if (UserInfo != NULL)
- FreeUserInfo(UserInfo);
-
if (resume_handle != NULL)
*resume_handle = (DWORD_PTR)EnumContext;
LPDWORD entriesread,
LPDWORD totalentries)
{
- FIXME("%s %s %d %p %d %p %p stub\n", debugstr_w(servername),
+ UNICODE_STRING ServerName;
+ UNICODE_STRING UserName;
+ SAM_HANDLE ServerHandle = NULL;
+ SAM_HANDLE AccountDomainHandle = NULL;
+ SAM_HANDLE UserHandle = NULL;
+ PSID AccountDomainSid = NULL;
+ PULONG RelativeIds = NULL;
+ PSID_NAME_USE Use = NULL;
+ PGROUP_MEMBERSHIP GroupMembership = NULL;
+ ULONG GroupCount;
+
+ NET_API_STATUS ApiStatus = NERR_Success;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ TRACE("%s %s %d %p %d %p %p stub\n", debugstr_w(servername),
debugstr_w(username), level, bufptr, prefixmaxlen, entriesread,
totalentries);
- *bufptr = NULL;
- *entriesread = 0;
- *totalentries = 0;
+ if (servername != NULL)
+ RtlInitUnicodeString(&ServerName, servername);
+
+ RtlInitUnicodeString(&UserName, username);
+
+ /* Connect to the SAM Server */
+ Status = SamConnect((servername != NULL) ? &ServerName : NULL,
+ &ServerHandle,
+ SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("SamConnect failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ /* Get the Account Domain SID */
+ Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL,
+ &AccountDomainSid);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ /* Open the Account Domain */
+ Status = SamOpenDomain(ServerHandle,
+ DOMAIN_LOOKUP | DOMAIN_GET_ALIAS_MEMBERSHIP,
+ AccountDomainSid,
+ &AccountDomainHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ /* Get the RID for the given user name */
+ Status = SamLookupNamesInDomain(AccountDomainHandle,
+ 1,
+ &UserName,
+ &RelativeIds,
+ &Use);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("SamLookupNamesInDomain failed (Status %08lx)\n", Status);
+ if (Status == STATUS_NONE_MAPPED)
+ ApiStatus = NERR_UserNotFound;
+ else
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ /* Fail, if it is not a user account */
+ if (Use[0] != SidTypeUser)
+ {
+ ERR("Account is not a User!\n");
+ ApiStatus = NERR_UserNotFound;
+ goto done;
+ }
+
+ /* Open the user object */
+ Status = SamOpenUser(AccountDomainHandle,
+ USER_LIST_GROUPS,
+ RelativeIds[0],
+ &UserHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("SamOpenUser failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ /* Get the group memberships of this user */
+ Status = SamGetGroupsForUser(UserHandle,
+ &GroupMembership,
+ &GroupCount);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("SamGetGroupsForUser failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ /* If there is no group membership, we're done */
+ if (GroupCount == 0)
+ {
+ ApiStatus = NERR_Success;
+ goto done;
+ }
+
+
+done:
+
+ if (GroupMembership != NULL)
+ SamFreeMemory(GroupMembership);
+
+ if (UserHandle != NULL)
+ SamCloseHandle(UserHandle);
+
+ if (RelativeIds != NULL)
+ SamFreeMemory(RelativeIds);
+
+ if (Use != NULL)
+ SamFreeMemory(Use);
+
+ if (AccountDomainSid != NULL)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid);
+
+ if (AccountDomainHandle != NULL)
+ SamCloseHandle(AccountDomainHandle);
+
+ if (ServerHandle != NULL)
+ SamCloseHandle(ServerHandle);
+
+ if (ApiStatus != NERR_Success && ApiStatus != ERROR_MORE_DATA)
+ {
+ *entriesread = 0;
+ *totalentries = 0;
+ }
+ else
+ {
+// *entriesread = Count;
+// *totalentries = Count;
+ }
+
+// *bufptr = (LPBYTE)Buffer;
- return ERROR_INVALID_LEVEL;
+ return ApiStatus;
}
UNICODE_STRING UserName;
SAM_HANDLE ServerHandle = NULL;
SAM_HANDLE AccountDomainHandle = NULL;
+ SAM_HANDLE BuiltinDomainHandle = NULL;
SAM_HANDLE UserHandle = NULL;
PULONG RelativeIds = NULL;
PSID_NAME_USE Use = NULL;
- PUSER_ALL_INFORMATION UserInfo = NULL;
LPVOID Buffer = NULL;
+ PSID AccountDomainSid = NULL;
+ PSID BuiltinDomainSid = NULL;
+ ACCESS_MASK DesiredAccess;
NET_API_STATUS ApiStatus = NERR_Success;
NTSTATUS Status = STATUS_SUCCESS;
goto done;
}
+ /* Get the Builtin Domain SID */
+ Status = GetBuiltinDomainSid(&BuiltinDomainSid);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("GetBuiltinDomainSid failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ DesiredAccess = DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP;
+ if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11))
+ DesiredAccess |= DOMAIN_GET_ALIAS_MEMBERSHIP;
+
+ /* Open the Builtin Domain */
+ Status = SamOpenDomain(ServerHandle,
+ DesiredAccess,
+ BuiltinDomainSid,
+ &BuiltinDomainHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("SamOpenDomain failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ /* Get the Account Domain SID */
+ Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL,
+ &AccountDomainSid);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
/* Open the Account Domain */
- Status = OpenAccountDomain(ServerHandle,
- (servername != NULL) ? &ServerName : NULL,
- DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
- &AccountDomainHandle);
+ Status = SamOpenDomain(ServerHandle,
+ DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
+ AccountDomainSid,
+ &AccountDomainHandle);
if (!NT_SUCCESS(Status))
{
ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
if (!NT_SUCCESS(Status))
{
ERR("SamOpenDomain failed (Status %08lx)\n", Status);
- ApiStatus = NetpNtStatusToApiStatus(Status);
+ if (Status == STATUS_NONE_MAPPED)
+ ApiStatus = NERR_UserNotFound;
+ else
+ ApiStatus = NetpNtStatusToApiStatus(Status);
goto done;
}
TRACE("RID: %lu\n", RelativeIds[0]);
+ DesiredAccess = READ_CONTROL | USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT;
+ if ((level == 1) || (level == 2) || (level == 3) || (level == 4) || (level == 11))
+ DesiredAccess |= USER_LIST_GROUPS;
+
/* Open the user object */
Status = SamOpenUser(AccountDomainHandle,
- USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT,
+ DesiredAccess,
RelativeIds[0],
&UserHandle);
if (!NT_SUCCESS(Status))
goto done;
}
- Status = SamQueryInformationUser(UserHandle,
- UserAllInformation,
- (PVOID *)&UserInfo);
- if (!NT_SUCCESS(Status))
- {
- ERR("SamQueryInformationUser failed (Status %08lx)\n", Status);
- ApiStatus = NetpNtStatusToApiStatus(Status);
- goto done;
- }
-
- ApiStatus = BuildUserInfoBuffer(UserInfo,
- level,
+ ApiStatus = BuildUserInfoBuffer(BuiltinDomainHandle,
+ UserHandle,
+ AccountDomainSid,
RelativeIds[0],
+ level,
&Buffer);
if (ApiStatus != NERR_Success)
{
}
done:
- if (UserInfo != NULL)
- FreeUserInfo(UserInfo);
-
if (UserHandle != NULL)
SamCloseHandle(UserHandle);
if (AccountDomainHandle != NULL)
SamCloseHandle(AccountDomainHandle);
+ if (AccountDomainSid != NULL)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, AccountDomainSid);
+
+ if (BuiltinDomainHandle != NULL)
+ SamCloseHandle(BuiltinDomainHandle);
+
+ if (BuiltinDomainSid != NULL)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, BuiltinDomainSid);
+
if (ServerHandle != NULL)
SamCloseHandle(ServerHandle);
if (!NT_SUCCESS(Status))
{
ERR("SamLookupNamesInDomain failed (Status %08lx)\n", Status);
- ApiStatus = NetpNtStatusToApiStatus(Status);
+ if (Status == STATUS_NONE_MAPPED)
+ ApiStatus = NERR_UserNotFound;
+ else
+ ApiStatus = NetpNtStatusToApiStatus(Status);
goto done;
}
for (i = 0; i < AccountMemberCount; i++)
{
- if (BuiltinNames[i].Length > 0)
+ if (AccountNames[i].Length > 0)
{
Size += (sizeof(LOCALGROUP_USERS_INFO_0) + AccountNames[i].Length + sizeof(UNICODE_NULL));
Count++;
}
+/******************************************************************************
+ * NetUserModalsGet (NETAPI32.@)
+ *
+ * Retrieves global information for all users and global groups in the security
+ * database.
+ *
+ * PARAMS
+ * servername [I] Specifies the DNS or the NetBIOS name of the remote server
+ * on which the function is to execute.
+ * level [I] Information level of the data.
+ * 0 Return global passwords parameters. bufptr points to a
+ * USER_MODALS_INFO_0 struct.
+ * 1 Return logon server and domain controller information. bufptr
+ * points to a USER_MODALS_INFO_1 struct.
+ * 2 Return domain name and identifier. bufptr points to a
+ * USER_MODALS_INFO_2 struct.
+ * 3 Return lockout information. bufptr points to a USER_MODALS_INFO_3
+ * struct.
+ * bufptr [O] Buffer that receives the data.
+ *
+ * RETURNS
+ * Success: NERR_Success.
+ * Failure:
+ * ERROR_ACCESS_DENIED - the user does not have access to the info.
+ * NERR_InvalidComputer - computer name is invalid.
+ */
+NET_API_STATUS
+WINAPI
+NetUserModalsGet(LPCWSTR servername,
+ DWORD level,
+ LPBYTE *bufptr)
+{
+ UNICODE_STRING ServerName;
+ SAM_HANDLE ServerHandle = NULL;
+ SAM_HANDLE DomainHandle = NULL;
+ PSID DomainSid = NULL;
+ PDOMAIN_PASSWORD_INFORMATION PasswordInfo = NULL;
+ PDOMAIN_LOGOFF_INFORMATION LogoffInfo = NULL;
+ PDOMAIN_SERVER_ROLE_INFORMATION ServerRoleInfo = NULL;
+ PDOMAIN_REPLICATION_INFORMATION ReplicationInfo = NULL;
+ PDOMAIN_NAME_INFORMATION NameInfo = NULL;
+ PDOMAIN_LOCKOUT_INFORMATION LockoutInfo = NULL;
+ ULONG DesiredAccess;
+ ULONG BufferSize;
+ PUSER_MODALS_INFO_0 umi0;
+ PUSER_MODALS_INFO_1 umi1;
+ PUSER_MODALS_INFO_2 umi2;
+ PUSER_MODALS_INFO_3 umi3;
+ NET_API_STATUS ApiStatus = NERR_Success;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ TRACE("(%s %d %p)\n", debugstr_w(servername), level, bufptr);
+
+ *bufptr = NULL;
+
+ if (servername != NULL)
+ RtlInitUnicodeString(&ServerName, servername);
+
+ /* Connect to the SAM Server */
+ Status = SamConnect((servername != NULL) ? &ServerName : NULL,
+ &ServerHandle,
+ SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("SamConnect failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ /* Get the Account Domain SID */
+ Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL,
+ &DomainSid);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("GetAccountDomainSid failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ switch (level)
+ {
+ case 0:
+ DesiredAccess = DOMAIN_READ_OTHER_PARAMETERS | DOMAIN_READ_PASSWORD_PARAMETERS;
+ break;
+
+ case 1:
+ DesiredAccess = DOMAIN_READ_OTHER_PARAMETERS;
+ break;
+
+ case 2:
+ DesiredAccess = DOMAIN_READ_OTHER_PARAMETERS;
+ break;
+
+ case 3:
+ DesiredAccess = DOMAIN_READ_PASSWORD_PARAMETERS;
+ break;
+
+ default:
+ ApiStatus = ERROR_INVALID_LEVEL;
+ goto done;
+ }
+
+ /* Open the Account Domain */
+ Status = SamOpenDomain(ServerHandle,
+ DesiredAccess,
+ DomainSid,
+ &DomainHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("OpenAccountDomain failed (Status %08lx)\n", Status);
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ switch (level)
+ {
+ case 0:
+ /* return global passwords parameters */
+ Status = SamQueryInformationDomain(DomainHandle,
+ DomainPasswordInformation,
+ (PVOID*)&PasswordInfo);
+ if (!NT_SUCCESS(Status))
+ {
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ Status = SamQueryInformationDomain(DomainHandle,
+ DomainLogoffInformation,
+ (PVOID*)&LogoffInfo);
+ if (!NT_SUCCESS(Status))
+ {
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ BufferSize = sizeof(USER_MODALS_INFO_0);
+ break;
+
+ case 1:
+ /* return logon server and domain controller info */
+ Status = SamQueryInformationDomain(DomainHandle,
+ DomainServerRoleInformation,
+ (PVOID*)&ServerRoleInfo);
+ if (!NT_SUCCESS(Status))
+ {
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ Status = SamQueryInformationDomain(DomainHandle,
+ DomainReplicationInformation,
+ (PVOID*)&ReplicationInfo);
+ if (!NT_SUCCESS(Status))
+ {
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ BufferSize = sizeof(USER_MODALS_INFO_1) +
+ ReplicationInfo->ReplicaSourceNodeName.Length + sizeof(WCHAR);
+ break;
+
+ case 2:
+ /* return domain name and identifier */
+ Status = SamQueryInformationDomain(DomainHandle,
+ DomainNameInformation,
+ (PVOID*)&NameInfo);
+ if (!NT_SUCCESS(Status))
+ {
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ BufferSize = sizeof( USER_MODALS_INFO_2 ) +
+ NameInfo->DomainName.Length + sizeof(WCHAR) +
+ RtlLengthSid(DomainSid);
+ break;
+
+ case 3:
+ /* return lockout information */
+ Status = SamQueryInformationDomain(DomainHandle,
+ DomainLockoutInformation,
+ (PVOID*)&LockoutInfo);
+ if (!NT_SUCCESS(Status))
+ {
+ ApiStatus = NetpNtStatusToApiStatus(Status);
+ goto done;
+ }
+
+ BufferSize = sizeof(USER_MODALS_INFO_3);
+ break;
+
+ default:
+ TRACE("Invalid level %d is specified\n", level);
+ ApiStatus = ERROR_INVALID_LEVEL;
+ goto done;
+ }
+
+
+ ApiStatus = NetApiBufferAllocate(BufferSize,
+ (LPVOID *)bufptr);
+ if (ApiStatus != NERR_Success)
+ {
+ WARN("NetApiBufferAllocate() failed\n");
+ goto done;
+ }
+
+ switch (level)
+ {
+ case 0:
+ umi0 = (PUSER_MODALS_INFO_0)*bufptr;
+
+ umi0->usrmod0_min_passwd_len = PasswordInfo->MinPasswordLength;
+ umi0->usrmod0_max_passwd_age = (ULONG)(-PasswordInfo->MaxPasswordAge.QuadPart / 10000000);
+ umi0->usrmod0_min_passwd_age =
+ DeltaTimeToSeconds(PasswordInfo->MinPasswordAge);
+ umi0->usrmod0_force_logoff =
+ DeltaTimeToSeconds(LogoffInfo->ForceLogoff);
+ umi0->usrmod0_password_hist_len = PasswordInfo->PasswordHistoryLength;
+ break;
+
+ case 1:
+ umi1 = (PUSER_MODALS_INFO_1)*bufptr;
+
+ switch (ServerRoleInfo->DomainServerRole)
+ {
+ case DomainServerRolePrimary:
+ umi1->usrmod1_role = UAS_ROLE_PRIMARY;
+ break;
+
+ case DomainServerRoleBackup:
+ umi1->usrmod1_role = UAS_ROLE_BACKUP;
+ break;
+
+ default:
+ ApiStatus = NERR_InternalError;
+ goto done;
+ }
+
+ umi1->usrmod1_primary = (LPWSTR)(*bufptr + sizeof(USER_MODALS_INFO_1));
+ RtlCopyMemory(umi1->usrmod1_primary,
+ ReplicationInfo->ReplicaSourceNodeName.Buffer,
+ ReplicationInfo->ReplicaSourceNodeName.Length);
+ umi1->usrmod1_primary[ReplicationInfo->ReplicaSourceNodeName.Length / sizeof(WCHAR)] = UNICODE_NULL;
+ break;
+
+ case 2:
+ umi2 = (PUSER_MODALS_INFO_2)*bufptr;
+
+ umi2->usrmod2_domain_name = (LPWSTR)(*bufptr + sizeof(USER_MODALS_INFO_2));
+ RtlCopyMemory(umi2->usrmod2_domain_name,
+ NameInfo->DomainName.Buffer,
+ NameInfo->DomainName.Length);
+ umi2->usrmod2_domain_name[NameInfo->DomainName.Length / sizeof(WCHAR)] = UNICODE_NULL;
+
+ umi2->usrmod2_domain_id = *bufptr +
+ sizeof(USER_MODALS_INFO_2) +
+ NameInfo->DomainName.Length + sizeof(WCHAR);
+ RtlCopyMemory(umi2->usrmod2_domain_id,
+ DomainSid,
+ RtlLengthSid(DomainSid));
+ break;
+
+ case 3:
+ umi3 = (PUSER_MODALS_INFO_3)*bufptr;
+ umi3->usrmod3_lockout_duration =
+ DeltaTimeToSeconds(LockoutInfo->LockoutDuration);
+ umi3->usrmod3_lockout_observation_window =
+ DeltaTimeToSeconds(LockoutInfo->LockoutObservationWindow );
+ umi3->usrmod3_lockout_threshold = LockoutInfo->LockoutThreshold;
+ break;
+ }
+
+done:
+ if (LockoutInfo != NULL)
+ SamFreeMemory(LockoutInfo);
+
+ if (NameInfo != NULL)
+ SamFreeMemory(NameInfo);
+
+ if (ReplicationInfo != NULL)
+ SamFreeMemory(ReplicationInfo);
+
+ if (ServerRoleInfo != NULL)
+ SamFreeMemory(ServerRoleInfo);
+
+ if (LogoffInfo != NULL)
+ SamFreeMemory(LogoffInfo);
+
+ if (PasswordInfo != NULL)
+ SamFreeMemory(PasswordInfo);
+
+ if (DomainSid != NULL)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid);
+
+ if (DomainHandle != NULL)
+ SamCloseHandle(DomainHandle);
+
+ if (ServerHandle != NULL)
+ SamCloseHandle(ServerHandle);
+
+ return ApiStatus;
+}
+
+
+/******************************************************************************
+ * NetUserModalsSet (NETAPI32.@)
+ */
+NET_API_STATUS
+WINAPI
+NetUserModalsSet(IN LPCWSTR servername,
+ IN DWORD level,
+ IN LPBYTE buf,
+ OUT LPDWORD parm_err)
+{
+ FIXME("(%s %d %p %p)\n", debugstr_w(servername), level, buf, parm_err);
+ return ERROR_ACCESS_DENIED;
+}
+
+
/******************************************************************************
* NetUserSetGroups (NETAPI32.@)
*/
case 1:
case 2:
case 3:
-// case 4:
+ case 4:
// case 21:
-// case 22:
+ case 22:
case 1003:
// case 1005:
case 1006:
case 1012:
case 1013:
case 1014:
-// case 1017:
-// case 1018:
-// case 1020:
+ case 1017:
+ case 1018:
+ case 1020:
case 1024:
case 1025:
case 1051:
/* Open the Account Domain */
Status = OpenAccountDomain(ServerHandle,
(servername != NULL) ? &ServerName : NULL,
- DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP,
+ DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP | DOMAIN_READ_PASSWORD_PARAMETERS,
&AccountDomainHandle);
if (!NT_SUCCESS(Status))
{
/* Set user information */
ApiStatus = SetUserInfo(UserHandle,
buf,
- level);
+ level,
+ parm_err);
if (ApiStatus != NERR_Success)
{
ERR("SetUserInfo failed (Status %lu)\n", ApiStatus);