diff --git a/reactos/dll/win32/samsrv/samrpc.c b/reactos/dll/win32/samsrv/samrpc.c index fd1d4f34684..f239a09411f 100644 --- a/reactos/dll/win32/samsrv/samrpc.c +++ b/reactos/dll/win32/samsrv/samrpc.c @@ -5410,7 +5410,14 @@ SampQueryUserLogon(PSAM_DB_OBJECT UserObject, goto done; } - /* FIXME: LogonHours */ + /* Get the LogonHours attribute */ + Status = SampGetLogonHoursAttrbute(UserObject, + &InfoBuffer->Logon.LogonHours); + if (!NT_SUCCESS(Status)) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } *Buffer = InfoBuffer; @@ -5570,7 +5577,14 @@ SampQueryUserAccount(PSAM_DB_OBJECT UserObject, goto done; } - /* FIXME: LogonHours */ + /* Get the LogonHours attribute */ + Status = SampGetLogonHoursAttrbute(UserObject, + &InfoBuffer->Account.LogonHours); + if (!NT_SUCCESS(Status)) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } *Buffer = InfoBuffer; @@ -5613,7 +5627,51 @@ done: return Status; } -/* FIXME: SampQueryUserLogonHours */ + +static +NTSTATUS +SampQueryUserLogonHours(PSAM_DB_OBJECT UserObject, + PSAMPR_USER_INFO_BUFFER *Buffer) +{ + PSAMPR_USER_INFO_BUFFER InfoBuffer = NULL; + NTSTATUS Status; + + TRACE("(%p %p)\n", UserObject, Buffer); + + *Buffer = NULL; + + InfoBuffer = midl_user_allocate(sizeof(SAMPR_USER_INFO_BUFFER)); + if (InfoBuffer == NULL) + { + TRACE("Failed to allocate InfoBuffer!\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + Status = SampGetLogonHoursAttrbute(UserObject, + &InfoBuffer->LogonHours.LogonHours); + if (!NT_SUCCESS(Status)) + { + TRACE("SampGetLogonHoursAttrbute failed (Status 0x%08lx)\n", Status); + goto done; + } + + *Buffer = InfoBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (InfoBuffer != NULL) + { + if (InfoBuffer->LogonHours.LogonHours.LogonHours != NULL) + midl_user_free(InfoBuffer->LogonHours.LogonHours.LogonHours); + + midl_user_free(InfoBuffer); + } + } + + return Status; +} + static NTSTATUS @@ -6363,14 +6421,21 @@ SampQueryUserAll(PSAM_DB_OBJECT UserObject, goto done; } + /* Get the LogonHours attribute */ + Status = SampGetLogonHoursAttrbute(UserObject, + &InfoBuffer->All.LogonHours); + if (!NT_SUCCESS(Status)) + { + TRACE("Status 0x%08lx\n", Status); + goto done; + } + InfoBuffer->All.LastLogon.LowPart = FixedData.LastLogon.LowPart; InfoBuffer->All.LastLogon.HighPart = FixedData.LastLogon.HighPart; InfoBuffer->All.LastLogoff.LowPart = FixedData.LastLogoff.LowPart; InfoBuffer->All.LastLogoff.HighPart = FixedData.LastLogoff.HighPart; -// USER_ALL_LOGONHOURS - InfoBuffer->All.BadPasswordCount = FixedData.BadPasswordCount; InfoBuffer->All.LogonCount = FixedData.LogonCount; @@ -6385,7 +6450,8 @@ SampQueryUserAll(PSAM_DB_OBJECT UserObject, InfoBuffer->All.PasswordMustChange.LowPart = PasswordMustChange.LowPart; InfoBuffer->All.PasswordMustChange.HighPart = PasswordMustChange.HighPart; - InfoBuffer->All. WhichFields |= /* USER_ALL_READ_LOGON_MASK; */ + InfoBuffer->All. WhichFields |= USER_ALL_READ_LOGON_MASK; +/* USER_ALL_HOMEDIRECTORY | USER_ALL_HOMEDIRECTORYDRIVE | USER_ALL_SCRIPTPATH | @@ -6393,11 +6459,12 @@ SampQueryUserAll(PSAM_DB_OBJECT UserObject, USER_ALL_WORKSTATIONS | USER_ALL_LASTLOGON | USER_ALL_LASTLOGOFF | -// USER_ALL_LOGONHOURS | + USER_ALL_LOGONHOURS | USER_ALL_BADPASSWORDCOUNT | USER_ALL_LOGONCOUNT; USER_ALL_PASSWORDCANCHANGE | USER_ALL_PASSWORDMUSTCHANGE; +*/ } if (UserObject->Access & USER_READ_ACCOUNT) @@ -6575,10 +6642,10 @@ SamrQueryInformationUser(IN SAMPR_HANDLE UserHandle, Buffer); break; -// case UserLogonHoursInformation: -// Status = SampQueryUserLogonHours(UserObject, -// Buffer); -// break; + case UserLogonHoursInformation: + Status = SampQueryUserLogonHours(UserObject, + Buffer); + break; case UserAccountInformation: Status = SampQueryUserAccount(UserObject, diff --git a/reactos/dll/win32/samsrv/samsrv.h b/reactos/dll/win32/samsrv/samsrv.h index 672211b68b4..3c72e692825 100644 --- a/reactos/dll/win32/samsrv/samsrv.h +++ b/reactos/dll/win32/samsrv/samsrv.h @@ -326,4 +326,8 @@ SampSetUserPassword(IN PSAM_DB_OBJECT UserObject, IN PENCRYPTED_LM_OWF_PASSWORD LmPassword, IN BOOLEAN LmPasswordPresent); +NTSTATUS +SampGetLogonHoursAttrbute(IN PSAM_DB_OBJECT UserObject, + IN PSAMPR_LOGON_HOURS LogonHours); + /* EOF */ diff --git a/reactos/dll/win32/samsrv/user.c b/reactos/dll/win32/samsrv/user.c index a80402bd4ab..eeb2cf30720 100644 --- a/reactos/dll/win32/samsrv/user.c +++ b/reactos/dll/win32/samsrv/user.c @@ -581,4 +581,74 @@ done: return Status; } + +NTSTATUS +SampGetLogonHoursAttrbute(IN PSAM_DB_OBJECT UserObject, + IN PSAMPR_LOGON_HOURS LogonHours) +{ + PUCHAR RawBuffer = NULL; + ULONG Length = 0; + ULONG BufferLength = 0; + NTSTATUS Status; + + Status = SampGetObjectAttribute(UserObject, + L"LogonHours", + NULL, + NULL, + &Length); + if (Status != STATUS_BUFFER_OVERFLOW) + { + TRACE("SampGetObjectAttribute failed (Status 0x%08lx)\n", Status); + return Status; + } + + Status = STATUS_SUCCESS; + + if (Length == 0) + { + LogonHours->UnitsPerWeek = 0; + LogonHours->LogonHours = NULL; + } + else + { + RawBuffer = midl_user_allocate(Length); + if (RawBuffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Status = SampGetObjectAttribute(UserObject, + L"LogonHours", + NULL, + (PVOID)RawBuffer, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + LogonHours->UnitsPerWeek = *((PUSHORT)RawBuffer); + + BufferLength = (((ULONG)LogonHours->UnitsPerWeek) + 7) / 8; + + LogonHours->LogonHours = midl_user_allocate(BufferLength); + if (LogonHours->LogonHours == NULL) + { + TRACE("Failed to allocate LogonHours buffer!\n"); + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + memcpy(LogonHours->LogonHours, + &(RawBuffer[2]), + BufferLength); + } + +done: + + if (RawBuffer != NULL) + midl_user_free(RawBuffer); + + return Status; +} + /* EOF */ diff --git a/reactos/include/reactos/idl/sam.idl b/reactos/include/reactos/idl/sam.idl index f4ae902a13f..82c00e11514 100644 --- a/reactos/include/reactos/idl/sam.idl +++ b/reactos/include/reactos/idl/sam.idl @@ -469,8 +469,7 @@ cpp_quote("#endif") typedef struct _SAMPR_LOGON_HOURS { unsigned short UnitsPerWeek; -// [size_is(1260), length_is((UnitsPerWeek + 7) / 8)] unsigned char *LogonHours; // FIXME - [size_is(1260)] unsigned char *LogonHours; + [size_is(1260), length_is((UnitsPerWeek + 7) / 8)] unsigned char *LogonHours; // FIXME } SAMPR_LOGON_HOURS, *PSAMPR_LOGON_HOURS; typedef struct _SAMPR_USER_ALL_INFORMATION