* COPYRIGHT: Copyright 2013 Eric Kohl
*/
-/* INCLUDES ****************************************************************/
-
#include "samsrv.h"
-WINE_DEFAULT_DEBUG_CHANNEL(samsrv);
-
-
/* FUNCTIONS ***************************************************************/
NTSTATUS
ULONG GroupsCount = 0;
ULONG Length = 0;
ULONG i;
- NTSTATUS Status;
+ NTSTATUS Status = STATUS_SUCCESS;
TRACE("(%p %lu)\n",
UserObject, GroupId);
- Status = SampGetObjectAttribute(UserObject,
- L"Groups",
- NULL,
- NULL,
- &Length);
+ SampGetObjectAttribute(UserObject,
+ L"Groups",
+ NULL,
+ NULL,
+ &Length);
- if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
+ if (Length == 0)
return STATUS_MEMBER_NOT_IN_GROUP;
- if (!NT_SUCCESS(Status))
- return Status;
-
GroupsBuffer = midl_user_allocate(Length);
if (GroupsBuffer == NULL)
{
{
Length -= sizeof(GROUP_MEMBERSHIP);
Status = STATUS_SUCCESS;
- break;
- }
- if (Status == STATUS_SUCCESS && i < GroupsCount - 1)
- {
- CopyMemory(&GroupsBuffer[i],
- &GroupsBuffer[i + 1],
- sizeof(GROUP_MEMBERSHIP));
+ if (GroupsCount - i - 1 > 0)
+ {
+ CopyMemory(&GroupsBuffer[i],
+ &GroupsBuffer[i + 1],
+ (GroupsCount - i - 1) * sizeof(GROUP_MEMBERSHIP));
+ }
+
+ break;
}
}
return Status;
}
+
+NTSTATUS
+SampRemoveUserFromAllGroups(IN PSAM_DB_OBJECT UserObject)
+{
+ PGROUP_MEMBERSHIP GroupsBuffer = NULL;
+ PSAM_DB_OBJECT GroupObject;
+ ULONG Length = 0;
+ ULONG i;
+ NTSTATUS Status;
+
+ SampGetObjectAttribute(UserObject,
+ L"Groups",
+ NULL,
+ NULL,
+ &Length);
+
+ if (Length == 0)
+ return STATUS_SUCCESS;
+
+ GroupsBuffer = midl_user_allocate(Length);
+ if (GroupsBuffer == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto done;
+ }
+
+ Status = SampGetObjectAttribute(UserObject,
+ L"Groups",
+ NULL,
+ GroupsBuffer,
+ &Length);
+ if (!NT_SUCCESS(Status))
+ goto done;
+
+ for (i = 0; i < (Length / sizeof(GROUP_MEMBERSHIP)); i++)
+ {
+ Status = SampOpenGroupObject(UserObject->ParentObject,
+ GroupsBuffer[i].RelativeId,
+ 0,
+ &GroupObject);
+ if (!NT_SUCCESS(Status))
+ {
+ goto done;
+ }
+
+ Status = SampRemoveMemberFromGroup(GroupObject,
+ UserObject->RelativeId);
+ if (Status == STATUS_MEMBER_NOT_IN_GROUP)
+ Status = STATUS_SUCCESS;
+
+ SampCloseDbObject(GroupObject);
+
+ if (!NT_SUCCESS(Status))
+ {
+ goto done;
+ }
+ }
+
+ /* Remove all groups from the Groups attribute */
+ Status = SampSetObjectAttribute(UserObject,
+ L"Groups",
+ REG_BINARY,
+ NULL,
+ 0);
+
+done:
+ if (GroupsBuffer != NULL)
+ midl_user_free(GroupsBuffer);
+
+ return Status;
+}
+
+
+NTSTATUS
+SampRemoveUserFromAllAliases(IN PSAM_DB_OBJECT UserObject)
+{
+ FIXME("(%p)\n", UserObject);
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+SampSetUserPassword(IN PSAM_DB_OBJECT UserObject,
+ IN PENCRYPTED_NT_OWF_PASSWORD NtPassword,
+ IN BOOLEAN NtPasswordPresent,
+ IN PENCRYPTED_LM_OWF_PASSWORD LmPassword,
+ IN BOOLEAN LmPasswordPresent)
+{
+ PENCRYPTED_NT_OWF_PASSWORD NtHistory = NULL;
+ PENCRYPTED_LM_OWF_PASSWORD LmHistory = NULL;
+ ULONG NtHistoryLength = 0;
+ ULONG LmHistoryLength = 0;
+ ULONG CurrentHistoryLength;
+ ULONG MaxHistoryLength = 3;
+ ULONG Length = 0;
+ BOOLEAN UseNtPassword;
+ BOOLEAN UseLmPassword;
+ NTSTATUS Status;
+
+ UseNtPassword =
+ ((NtPasswordPresent != FALSE) &&
+ (NtPassword != NULL) &&
+ (memcmp(NtPassword, &EmptyNtHash, sizeof(ENCRYPTED_NT_OWF_PASSWORD)) != 0));
+
+ UseLmPassword =
+ ((LmPasswordPresent != FALSE) &&
+ (LmPassword != NULL) &&
+ (memcmp(LmPassword, &EmptyLmHash, sizeof(ENCRYPTED_LM_OWF_PASSWORD)) != 0));
+
+ /* Update the NT password history only if we have a new non-empty NT password */
+ if (UseNtPassword)
+ {
+ /* Get the size of the NT history */
+ SampGetObjectAttribute(UserObject,
+ L"NTPwdHistory",
+ NULL,
+ NULL,
+ &Length);
+
+ CurrentHistoryLength = Length / sizeof(ENCRYPTED_NT_OWF_PASSWORD);
+ if (CurrentHistoryLength < MaxHistoryLength)
+ {
+ NtHistoryLength = (CurrentHistoryLength + 1) * sizeof(ENCRYPTED_NT_OWF_PASSWORD);
+ }
+ else
+ {
+ NtHistoryLength = MaxHistoryLength * sizeof(ENCRYPTED_NT_OWF_PASSWORD);
+ }
+
+ /* Allocate the history buffer */
+ NtHistory = midl_user_allocate(NtHistoryLength);
+ if (NtHistory == NULL)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ if (Length > 0)
+ {
+ /* Get the history */
+ Status = SampGetObjectAttribute(UserObject,
+ L"NTPwdHistory",
+ NULL,
+ NtHistory,
+ &Length);
+ if (!NT_SUCCESS(Status))
+ goto done;
+ }
+
+ /* Move the old passwords down by one entry */
+ if (NtHistoryLength > sizeof(ENCRYPTED_NT_OWF_PASSWORD))
+ {
+ MoveMemory(&(NtHistory[1]),
+ &(NtHistory[0]),
+ NtHistoryLength - sizeof(ENCRYPTED_NT_OWF_PASSWORD));
+ }
+
+ /* Add the new password to the top of the history */
+ if (NtPasswordPresent)
+ {
+ CopyMemory(&(NtHistory[0]),
+ NtPassword,
+ sizeof(ENCRYPTED_NT_OWF_PASSWORD));
+ }
+ else
+ {
+ ZeroMemory(&(NtHistory[0]),
+ sizeof(ENCRYPTED_NT_OWF_PASSWORD));
+ }
+
+ /* Set the history */
+ Status = SampSetObjectAttribute(UserObject,
+ L"NTPwdHistory",
+ REG_BINARY,
+ (PVOID)NtHistory,
+ NtHistoryLength);
+ if (!NT_SUCCESS(Status))
+ goto done;
+ }
+
+ /* Update the LM password history only if we have a new non-empty LM password */
+ if (UseLmPassword)
+ {
+ /* Get the size of the LM history */
+ Length = 0;
+ SampGetObjectAttribute(UserObject,
+ L"LMPwdHistory",
+ NULL,
+ NULL,
+ &Length);
+
+ CurrentHistoryLength = Length / sizeof(ENCRYPTED_LM_OWF_PASSWORD);
+ if (CurrentHistoryLength < MaxHistoryLength)
+ {
+ LmHistoryLength = (CurrentHistoryLength + 1) * sizeof(ENCRYPTED_LM_OWF_PASSWORD);
+ }
+ else
+ {
+ LmHistoryLength = MaxHistoryLength * sizeof(ENCRYPTED_LM_OWF_PASSWORD);
+ }
+
+ /* Allocate the history buffer */
+ LmHistory = midl_user_allocate(LmHistoryLength);
+ if (LmHistory == NULL)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ if (Length > 0)
+ {
+ /* Get the history */
+ Status = SampGetObjectAttribute(UserObject,
+ L"LMPwdHistory",
+ NULL,
+ LmHistory,
+ &Length);
+ if (!NT_SUCCESS(Status))
+ goto done;
+ }
+
+ /* Move the old passwords down by one entry */
+ if (LmHistoryLength > sizeof(ENCRYPTED_LM_OWF_PASSWORD))
+ {
+ MoveMemory(&(LmHistory[1]),
+ &(LmHistory[0]),
+ LmHistoryLength - sizeof(ENCRYPTED_LM_OWF_PASSWORD));
+ }
+
+ /* Add the new password to the top of the history */
+ if (LmPasswordPresent)
+ {
+ CopyMemory(&(LmHistory[0]),
+ LmPassword,
+ sizeof(ENCRYPTED_LM_OWF_PASSWORD));
+ }
+ else
+ {
+ ZeroMemory(&(LmHistory[0]),
+ sizeof(ENCRYPTED_LM_OWF_PASSWORD));
+ }
+
+ /* Set the LM password history */
+ Status = SampSetObjectAttribute(UserObject,
+ L"LMPwdHistory",
+ REG_BINARY,
+ (PVOID)LmHistory,
+ LmHistoryLength);
+ if (!NT_SUCCESS(Status))
+ goto done;
+ }
+
+ /* Set the new NT password */
+ if (UseNtPassword)
+ {
+ Status = SampSetObjectAttribute(UserObject,
+ L"NTPwd",
+ REG_BINARY,
+ (PVOID)NtPassword,
+ sizeof(ENCRYPTED_NT_OWF_PASSWORD));
+ if (!NT_SUCCESS(Status))
+ goto done;
+ }
+ else
+ {
+ Status = SampSetObjectAttribute(UserObject,
+ L"NTPwd",
+ REG_BINARY,
+ &EmptyNtHash,
+ sizeof(ENCRYPTED_NT_OWF_PASSWORD));
+ if (!NT_SUCCESS(Status))
+ goto done;
+ }
+
+ /* Set the new LM password */
+ if (UseLmPassword)
+ {
+ Status = SampSetObjectAttribute(UserObject,
+ L"LMPwd",
+ REG_BINARY,
+ (PVOID)LmPassword,
+ sizeof(ENCRYPTED_LM_OWF_PASSWORD));
+ if (!NT_SUCCESS(Status))
+ goto done;
+ }
+ else
+ {
+ Status = SampSetObjectAttribute(UserObject,
+ L"LMPwd",
+ REG_BINARY,
+ &EmptyLmHash,
+ sizeof(ENCRYPTED_LM_OWF_PASSWORD));
+ if (!NT_SUCCESS(Status))
+ goto done;
+ }
+
+done:
+ if (NtHistory != NULL)
+ midl_user_free(NtHistory);
+
+ if (LmHistory != NULL)
+ midl_user_free(LmHistory);
+
+ return Status;
+}
+
+
+NTSTATUS
+SampGetLogonHoursAttrbute(IN PSAM_DB_OBJECT UserObject,
+ IN OUT 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;
+}
+
+
+NTSTATUS
+SampSetLogonHoursAttrbute(IN PSAM_DB_OBJECT UserObject,
+ IN PSAMPR_LOGON_HOURS LogonHours)
+{
+ PUCHAR RawBuffer = NULL;
+ ULONG BufferLength;
+ ULONG Length = 0;
+ NTSTATUS Status;
+
+ if (LogonHours->UnitsPerWeek > 0)
+ {
+ BufferLength = (((ULONG)LogonHours->UnitsPerWeek) + 7) / 8;
+
+ Length = BufferLength + sizeof(USHORT);
+
+ RawBuffer = midl_user_allocate(Length);
+ if (RawBuffer == NULL)
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto done;
+ }
+
+ *((PUSHORT)RawBuffer) = LogonHours->UnitsPerWeek;
+
+ memcpy(&(RawBuffer[2]),
+ LogonHours->LogonHours,
+ BufferLength);
+ }
+
+ Status = SampSetObjectAttribute(UserObject,
+ L"LogonHours",
+ REG_BINARY,
+ RawBuffer,
+ Length);
+
+done:
+ if (RawBuffer != NULL)
+ midl_user_free(RawBuffer);
+
+ return Status;
+}
+
/* EOF */