From 2f6a92ccd0399f0dc072745aacb713427856d548 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Mon, 2 Jul 2012 23:09:20 +0000 Subject: [PATCH] [SAMSRV] - Store all fixed size user attributes in the registry value "F". - Initialize fixed size domain attributes in SampCreateUserAccount and SamrCreateUserInDomain. - Implement most information classes of SamrQueryInformationUser. - Disable all informationclasses of SamrSetInformationUser that store fixed size attributes. svn path=/trunk/; revision=56820 --- reactos/dll/win32/samsrv/samrpc.c | 815 +++++++++++++++++++++++++++++- reactos/dll/win32/samsrv/samsrv.h | 20 + reactos/dll/win32/samsrv/setup.c | 14 + 3 files changed, 846 insertions(+), 3 deletions(-) diff --git a/reactos/dll/win32/samsrv/samrpc.c b/reactos/dll/win32/samsrv/samrpc.c index fa1ea3cda9d..3a2f94eb09f 100644 --- a/reactos/dll/win32/samsrv/samrpc.c +++ b/reactos/dll/win32/samsrv/samrpc.c @@ -1712,6 +1712,7 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle, OUT unsigned long *RelativeId) { SAM_DOMAIN_FIXED_DATA FixedDomainData; + SAM_USER_FIXED_DATA FixedUserData; PSAM_DB_OBJECT DomainObject; PSAM_DB_OBJECT UserObject; ULONG ulSize; @@ -1809,6 +1810,24 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle, return Status; } + /* Initialize fixed user data */ + memset(&FixedUserData, 0, sizeof(SAM_USER_FIXED_DATA)); + FixedUserData.Version = 1; + + FixedUserData.UserId = ulRid; + + /* Set fixed user data attribute */ + Status = SampSetObjectAttribute(UserObject, + L"F", + REG_BINARY, + (LPVOID)&FixedUserData, + sizeof(SAM_USER_FIXED_DATA)); + if (!NT_SUCCESS(Status)) + { + TRACE("failed with status 0x%08lx\n", Status); + return Status; + } + /* Set the name attribute */ Status = SampSetObjectAttribute(UserObject, L"Name", @@ -3158,15 +3177,720 @@ SamrDeleteUser(IN OUT SAMPR_HANDLE *UserHandle) return STATUS_NOT_IMPLEMENTED; } + static NTSTATUS SampQueryUserName(PSAM_DB_OBJECT UserObject, PSAMPR_USER_INFO_BUFFER *Buffer) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PSAMPR_USER_INFO_BUFFER InfoBuffer = NULL; + ULONG Length = 0; + NTSTATUS Status; + + *Buffer = NULL; + + InfoBuffer = midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER)); + if (InfoBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Status = SampGetObjectAttribute(UserObject, + L"Name", + NULL, + NULL, + &Length); + if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } + + InfoBuffer->Name.UserName.Length = Length - sizeof(WCHAR); + InfoBuffer->Name.UserName.MaximumLength = Length; + InfoBuffer->Name.UserName.Buffer = midl_user_allocate(Length); + if (InfoBuffer->Name.UserName.Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + TRACE("Length: %lu\n", Length); + Status = SampGetObjectAttribute(UserObject, + L"Name", + NULL, + (PVOID)InfoBuffer->Name.UserName.Buffer, + &Length); + if (!NT_SUCCESS(Status)) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } + + Length = 0; + Status = SampGetObjectAttribute(UserObject, + L"FullName", + NULL, + NULL, + &Length); + if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } + + InfoBuffer->Name.FullName.Length = Length - sizeof(WCHAR); + InfoBuffer->Name.FullName.MaximumLength = Length; + InfoBuffer->Name.FullName.Buffer = midl_user_allocate(Length); + if (InfoBuffer->Name.FullName.Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + TRACE("Length: %lu\n", Length); + Status = SampGetObjectAttribute(UserObject, + L"FullName", + NULL, + (PVOID)InfoBuffer->Name.FullName.Buffer, + &Length); + if (!NT_SUCCESS(Status)) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + if (InfoBuffer->Name.UserName.Buffer != NULL) + midl_user_free(InfoBuffer->Name.UserName.Buffer); + + if (InfoBuffer->Name.FullName.Buffer != NULL) + midl_user_free(InfoBuffer->Name.FullName.Buffer); + + midl_user_free(InfoBuffer); + } + } + + return Status; } + +static NTSTATUS +SampQueryUserAccountName(PSAM_DB_OBJECT UserObject, + PSAMPR_USER_INFO_BUFFER *Buffer) +{ + PSAMPR_USER_INFO_BUFFER InfoBuffer = NULL; + ULONG Length = 0; + NTSTATUS Status; + + *Buffer = NULL; + + InfoBuffer = midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER)); + if (InfoBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Status = SampGetObjectAttribute(UserObject, + L"Name", + NULL, + NULL, + &Length); + if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } + + InfoBuffer->AccountName.UserName.Length = Length - sizeof(WCHAR); + InfoBuffer->AccountName.UserName.MaximumLength = Length; + InfoBuffer->AccountName.UserName.Buffer = midl_user_allocate(Length); + if (InfoBuffer->AccountName.UserName.Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + TRACE("Length: %lu\n", Length); + Status = SampGetObjectAttribute(UserObject, + L"Name", + NULL, + (PVOID)InfoBuffer->AccountName.UserName.Buffer, + &Length); + if (!NT_SUCCESS(Status)) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + if (InfoBuffer->AccountName.UserName.Buffer != NULL) + midl_user_free(InfoBuffer->AccountName.UserName.Buffer); + + midl_user_free(InfoBuffer); + } + } + + return Status; +} + + +static NTSTATUS +SampQueryUserFullName(PSAM_DB_OBJECT UserObject, + PSAMPR_USER_INFO_BUFFER *Buffer) +{ + PSAMPR_USER_INFO_BUFFER InfoBuffer = NULL; + ULONG Length = 0; + NTSTATUS Status; + + *Buffer = NULL; + + InfoBuffer = midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER)); + if (InfoBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Status = SampGetObjectAttribute(UserObject, + L"FullName", + NULL, + NULL, + &Length); + if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } + + InfoBuffer->FullName.FullName.Length = Length - sizeof(WCHAR); + InfoBuffer->FullName.FullName.MaximumLength = Length; + InfoBuffer->FullName.FullName.Buffer = midl_user_allocate(Length); + if (InfoBuffer->FullName.FullName.Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + TRACE("Length: %lu\n", Length); + Status = SampGetObjectAttribute(UserObject, + L"FullName", + NULL, + (PVOID)InfoBuffer->FullName.FullName.Buffer, + &Length); + if (!NT_SUCCESS(Status)) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + if (InfoBuffer->FullName.FullName.Buffer != NULL) + midl_user_free(InfoBuffer->FullName.FullName.Buffer); + + midl_user_free(InfoBuffer); + } + } + + return Status; +} + + +static +NTSTATUS +SampQueryUserPrimaryGroup(PSAM_DB_OBJECT UserObject, + PSAMPR_USER_INFO_BUFFER *Buffer) +{ + PSAMPR_USER_INFO_BUFFER InfoBuffer = NULL; + SAM_USER_FIXED_DATA FixedData; + ULONG Length = 0; + NTSTATUS Status; + + *Buffer = NULL; + + InfoBuffer = midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER)); + if (InfoBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Length = sizeof(SAM_USER_FIXED_DATA); + Status = SampGetObjectAttribute(UserObject, + L"F", + NULL, + (PVOID)&FixedData, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + InfoBuffer->PrimaryGroup.PrimaryGroupId = FixedData.PrimaryGroupId; + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + midl_user_free(InfoBuffer); + } + } + + return Status; +} + + +static NTSTATUS +SampQueryUserHome(PSAM_DB_OBJECT UserObject, + PSAMPR_USER_INFO_BUFFER *Buffer) +{ + PSAMPR_USER_INFO_BUFFER InfoBuffer = NULL; + ULONG Length = 0; + NTSTATUS Status; + + *Buffer = NULL; + + InfoBuffer = midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER)); + if (InfoBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Status = SampGetObjectAttribute(UserObject, + L"HomeDirectory", + NULL, + NULL, + &Length); + if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } + + InfoBuffer->Home.HomeDirectory.Length = Length - sizeof(WCHAR); + InfoBuffer->Home.HomeDirectory.MaximumLength = Length; + InfoBuffer->Home.HomeDirectory.Buffer = midl_user_allocate(Length); + if (InfoBuffer->Home.HomeDirectory.Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + TRACE("Length: %lu\n", Length); + Status = SampGetObjectAttribute(UserObject, + L"HomeDirectory", + NULL, + (PVOID)InfoBuffer->Home.HomeDirectory.Buffer, + &Length); + if (!NT_SUCCESS(Status)) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } + + Length = 0; + Status = SampGetObjectAttribute(UserObject, + L"HomeDirectoryDrive", + NULL, + NULL, + &Length); + if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } + + InfoBuffer->Home.HomeDirectoryDrive.Length = Length - sizeof(WCHAR); + InfoBuffer->Home.HomeDirectoryDrive.MaximumLength = Length; + InfoBuffer->Home.HomeDirectoryDrive.Buffer = midl_user_allocate(Length); + if (InfoBuffer->Home.HomeDirectoryDrive.Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + TRACE("Length: %lu\n", Length); + Status = SampGetObjectAttribute(UserObject, + L"HomeDirectoryDrive", + NULL, + (PVOID)InfoBuffer->Home.HomeDirectoryDrive.Buffer, + &Length); + if (!NT_SUCCESS(Status)) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + if (InfoBuffer->Home.HomeDirectory.Buffer != NULL) + midl_user_free(InfoBuffer->Home.HomeDirectory.Buffer); + + if (InfoBuffer->Home.HomeDirectoryDrive.Buffer != NULL) + midl_user_free(InfoBuffer->Home.HomeDirectoryDrive.Buffer); + + midl_user_free(InfoBuffer); + } + } + + return Status; +} + + +static NTSTATUS +SampQueryUserScript(PSAM_DB_OBJECT UserObject, + PSAMPR_USER_INFO_BUFFER *Buffer) +{ + PSAMPR_USER_INFO_BUFFER InfoBuffer = NULL; + ULONG Length = 0; + NTSTATUS Status; + + *Buffer = NULL; + + InfoBuffer = midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER)); + if (InfoBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Status = SampGetObjectAttribute(UserObject, + L"ScriptPath", + NULL, + NULL, + &Length); + if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } + + InfoBuffer->Script.ScriptPath.Length = Length - sizeof(WCHAR); + InfoBuffer->Script.ScriptPath.MaximumLength = Length; + InfoBuffer->Script.ScriptPath.Buffer = midl_user_allocate(Length); + if (InfoBuffer->Script.ScriptPath.Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + TRACE("Length: %lu\n", Length); + Status = SampGetObjectAttribute(UserObject, + L"ScriptPath", + NULL, + (PVOID)InfoBuffer->Script.ScriptPath.Buffer, + &Length); + if (!NT_SUCCESS(Status)) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + if (InfoBuffer->Script.ScriptPath.Buffer != NULL) + midl_user_free(InfoBuffer->Script.ScriptPath.Buffer); + + midl_user_free(InfoBuffer); + } + } + + return Status; +} + + +static NTSTATUS +SampQueryUserProfile(PSAM_DB_OBJECT UserObject, + PSAMPR_USER_INFO_BUFFER *Buffer) +{ + PSAMPR_USER_INFO_BUFFER InfoBuffer = NULL; + ULONG Length = 0; + NTSTATUS Status; + + *Buffer = NULL; + + InfoBuffer = midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER)); + if (InfoBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Status = SampGetObjectAttribute(UserObject, + L"ProfilePath", + NULL, + NULL, + &Length); + if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } + + InfoBuffer->Profile.ProfilePath.Length = Length - sizeof(WCHAR); + InfoBuffer->Profile.ProfilePath.MaximumLength = Length; + InfoBuffer->Profile.ProfilePath.Buffer = midl_user_allocate(Length); + if (InfoBuffer->Profile.ProfilePath.Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + TRACE("Length: %lu\n", Length); + Status = SampGetObjectAttribute(UserObject, + L"ProfilePath", + NULL, + (PVOID)InfoBuffer->Profile.ProfilePath.Buffer, + &Length); + if (!NT_SUCCESS(Status)) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + if (InfoBuffer->Profile.ProfilePath.Buffer != NULL) + midl_user_free(InfoBuffer->Profile.ProfilePath.Buffer); + + midl_user_free(InfoBuffer); + } + } + + return Status; +} + + +static NTSTATUS +SampQueryUserAdminComment(PSAM_DB_OBJECT UserObject, + PSAMPR_USER_INFO_BUFFER *Buffer) +{ + PSAMPR_USER_INFO_BUFFER InfoBuffer = NULL; + ULONG Length = 0; + NTSTATUS Status; + + *Buffer = NULL; + + InfoBuffer = midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER)); + if (InfoBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Status = SampGetObjectAttribute(UserObject, + L"AdminComment", + NULL, + NULL, + &Length); + if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } + + InfoBuffer->AdminComment.AdminComment.Length = Length - sizeof(WCHAR); + InfoBuffer->AdminComment.AdminComment.MaximumLength = Length; + InfoBuffer->AdminComment.AdminComment.Buffer = midl_user_allocate(Length); + if (InfoBuffer->AdminComment.AdminComment.Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + TRACE("Length: %lu\n", Length); + Status = SampGetObjectAttribute(UserObject, + L"AdminComment", + NULL, + (PVOID)InfoBuffer->AdminComment.AdminComment.Buffer, + &Length); + if (!NT_SUCCESS(Status)) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + if (InfoBuffer->AdminComment.AdminComment.Buffer != NULL) + midl_user_free(InfoBuffer->AdminComment.AdminComment.Buffer); + + midl_user_free(InfoBuffer); + } + } + + return Status; +} + + + +static NTSTATUS +SampQueryUserWorkStations(PSAM_DB_OBJECT UserObject, + PSAMPR_USER_INFO_BUFFER *Buffer) +{ + PSAMPR_USER_INFO_BUFFER InfoBuffer = NULL; + ULONG Length = 0; + NTSTATUS Status; + + *Buffer = NULL; + + InfoBuffer = midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER)); + if (InfoBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Status = SampGetObjectAttribute(UserObject, + L"WorkStations", + NULL, + NULL, + &Length); + if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } + + InfoBuffer->WorkStations.WorkStations.Length = Length - sizeof(WCHAR); + InfoBuffer->WorkStations.WorkStations.MaximumLength = Length; + InfoBuffer->WorkStations.WorkStations.Buffer = midl_user_allocate(Length); + if (InfoBuffer->WorkStations.WorkStations.Buffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + TRACE("Length: %lu\n", Length); + Status = SampGetObjectAttribute(UserObject, + L"WorkStations", + NULL, + (PVOID)InfoBuffer->WorkStations.WorkStations.Buffer, + &Length); + if (!NT_SUCCESS(Status)) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + if (InfoBuffer->WorkStations.WorkStations.Buffer != NULL) + midl_user_free(InfoBuffer->WorkStations.WorkStations.Buffer); + + midl_user_free(InfoBuffer); + } + } + + return Status; +} + + +static +NTSTATUS +SampQueryUserControl(PSAM_DB_OBJECT UserObject, + PSAMPR_USER_INFO_BUFFER *Buffer) +{ + PSAMPR_USER_INFO_BUFFER InfoBuffer = NULL; + SAM_USER_FIXED_DATA FixedData; + ULONG Length = 0; + NTSTATUS Status; + + *Buffer = NULL; + + InfoBuffer = midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER)); + if (InfoBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Length = sizeof(SAM_USER_FIXED_DATA); + Status = SampGetObjectAttribute(UserObject, + L"F", + NULL, + (PVOID)&FixedData, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + InfoBuffer->Control.UserAccountControl = FixedData.UserAccountControl; + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + midl_user_free(InfoBuffer); + } + } + + return Status; +} + + +static +NTSTATUS +SampQueryUserExpires(PSAM_DB_OBJECT UserObject, + PSAMPR_USER_INFO_BUFFER *Buffer) +{ + PSAMPR_USER_INFO_BUFFER InfoBuffer = NULL; + SAM_USER_FIXED_DATA FixedData; + ULONG Length = 0; + NTSTATUS Status; + + *Buffer = NULL; + + InfoBuffer = midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER)); + if (InfoBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + Length = sizeof(SAM_USER_FIXED_DATA); + Status = SampGetObjectAttribute(UserObject, + L"F", + NULL, + (PVOID)&FixedData, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + InfoBuffer->Expires.AccountExpires.LowPart = FixedData.AccountExpires.LowPart; + InfoBuffer->Expires.AccountExpires.HighPart = FixedData.AccountExpires.HighPart; + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + midl_user_free(InfoBuffer); + } + } + + return Status; +} + + /* Function 36 */ NTSTATUS NTAPI @@ -3192,6 +3916,31 @@ SamrQueryInformationUser(IN SAMPR_HANDLE UserHandle, DesiredAccess = USER_READ_GENERAL; break; + case UserLogonHoursInformation: + case UserHomeInformation: + case UserScriptInformation: + case UserProfileInformation: + case UserWorkStationsInformation: + DesiredAccess = USER_READ_LOGON; + break; + + case UserControlInformation: + case UserExpiresInformation: + DesiredAccess = USER_READ_ACCOUNT; + break; + + case UserPreferencesInformation: + DesiredAccess = USER_READ_GENERAL | + USER_READ_PREFERENCES; + break; + + case UserLogonInformation: + case UserAccountInformation: + DesiredAccess = USER_READ_GENERAL | + USER_READ_PREFERENCES | + USER_READ_LOGON | + USER_READ_ACCOUNT; + break; default: return STATUS_INVALID_INFO_CLASS; @@ -3210,11 +3959,66 @@ SamrQueryInformationUser(IN SAMPR_HANDLE UserHandle, switch (UserInformationClass) { +// case UserGeneralInformation: +// case UserPreferencesInformation: +// case UserLogonInformation: +// case UserLogonHoursInformation: +// case UserAccountInformation: + case UserNameInformation: Status = SampQueryUserName(UserObject, Buffer); break; + case UserAccountNameInformation: + Status = SampQueryUserAccountName(UserObject, + Buffer); + break; + + case UserFullNameInformation: + Status = SampQueryUserFullName(UserObject, + Buffer); + break; + + case UserPrimaryGroupInformation: + Status = SampQueryUserPrimaryGroup(UserObject, + Buffer); + break; + + case UserHomeInformation: + Status = SampQueryUserHome(UserObject, + Buffer); + + case UserScriptInformation: + Status = SampQueryUserScript(UserObject, + Buffer); + break; + + case UserProfileInformation: + Status = SampQueryUserProfile(UserObject, + Buffer); + break; + + case UserAdminCommentInformation: + Status = SampQueryUserAdminComment(UserObject, + Buffer); + break; + + case UserWorkStationsInformation: + Status = SampQueryUserWorkStations(UserObject, + Buffer); + break; + + case UserControlInformation: + Status = SampQueryUserControl(UserObject, + Buffer); + break; + + case UserExpiresInformation: + Status = SampQueryUserExpires(UserObject, + Buffer); + break; + default: Status = STATUS_INVALID_INFO_CLASS; } @@ -3309,6 +4113,7 @@ SamrSetInformationUser(IN SAMPR_HANDLE UserHandle, Buffer->FullName.FullName.MaximumLength); break; +/* case UserPrimaryGroupInformation: Status = SampSetObjectAttribute(UserObject, L"PrimaryGroupId", @@ -3316,6 +4121,7 @@ SamrSetInformationUser(IN SAMPR_HANDLE UserHandle, &Buffer->PrimaryGroup.PrimaryGroupId, sizeof(ULONG)); break; +*/ case UserHomeInformation: Status = SampSetObjectAttribute(UserObject, @@ -3376,6 +4182,7 @@ SamrSetInformationUser(IN SAMPR_HANDLE UserHandle, Buffer->SetPassword.Password.MaximumLength); break; +/* case UserControlInformation: Status = SampSetObjectAttribute(UserObject, L"UserAccountControl", @@ -3383,7 +4190,8 @@ SamrSetInformationUser(IN SAMPR_HANDLE UserHandle, &Buffer->Control.UserAccountControl, sizeof(ULONG)); break; - +*/ +/* case UserExpiresInformation: Status = SampSetObjectAttribute(UserObject, L"AccountExpires", @@ -3391,6 +4199,7 @@ SamrSetInformationUser(IN SAMPR_HANDLE UserHandle, &Buffer->Expires.AccountExpires, sizeof(OLD_LARGE_INTEGER)); break; +*/ // case UserInternal1Information: // case UserParametersInformation: diff --git a/reactos/dll/win32/samsrv/samsrv.h b/reactos/dll/win32/samsrv/samsrv.h index ff734c270ab..edde478c0bc 100644 --- a/reactos/dll/win32/samsrv/samsrv.h +++ b/reactos/dll/win32/samsrv/samsrv.h @@ -73,6 +73,26 @@ typedef struct _SAM_DOMAIN_FIXED_DATA BOOLEAN UasCompatibilityRequired; } SAM_DOMAIN_FIXED_DATA, *PSAM_DOMAIN_FIXED_DATA; +typedef struct _SAM_USER_FIXED_DATA +{ + ULONG Version; + ULONG Reserved; + LARGE_INTEGER LastLogon; + LARGE_INTEGER LastLogoff; + LARGE_INTEGER PasswordLastSet; + LARGE_INTEGER AccountExpires; + LARGE_INTEGER LastBadPasswordTime; + ULONG UserId; + ULONG PrimaryGroupId; + ULONG UserAccountControl; + USHORT CountryCode; + USHORT CodePage; + USHORT BadPasswordCount; + USHORT LogonCount; + USHORT AdminCount; + USHORT OperatorCount; +} SAM_USER_FIXED_DATA, *PSAM_USER_FIXED_DATA; + /* database.c */ NTSTATUS diff --git a/reactos/dll/win32/samsrv/setup.c b/reactos/dll/win32/samsrv/setup.c index fc420130df7..c3438bc24b6 100644 --- a/reactos/dll/win32/samsrv/setup.c +++ b/reactos/dll/win32/samsrv/setup.c @@ -223,11 +223,18 @@ SampCreateUserAccount(HKEY hDomainKey, LPCWSTR lpAccountName, ULONG ulRelativeId) { + SAM_USER_FIXED_DATA FixedUserData; DWORD dwDisposition; WCHAR szAccountKeyName[32]; HKEY hAccountKey = NULL; HKEY hNamesKey = NULL; + /* Initialize fixed user data */ + memset(&FixedUserData, 0, sizeof(SAM_USER_FIXED_DATA)); + FixedUserData.Version = 1; + + FixedUserData.UserId = ulRelativeId; + swprintf(szAccountKeyName, L"Users\\%08lX", ulRelativeId); if (!RegCreateKeyExW(hDomainKey, @@ -240,6 +247,13 @@ SampCreateUserAccount(HKEY hDomainKey, &hAccountKey, &dwDisposition)) { + RegSetValueEx(hAccountKey, + L"F", + 0, + REG_BINARY, + (LPVOID)&FixedUserData, + sizeof(SAM_USER_FIXED_DATA)); + RegSetValueEx(hAccountKey, L"Name", 0,