diff --git a/reactos/dll/win32/samsrv/CMakeLists.txt b/reactos/dll/win32/samsrv/CMakeLists.txt index 101748a9f2f..0639b26f9e2 100644 --- a/reactos/dll/win32/samsrv/CMakeLists.txt +++ b/reactos/dll/win32/samsrv/CMakeLists.txt @@ -8,6 +8,7 @@ add_rpc_files(server ${REACTOS_SOURCE_DIR}/include/reactos/idl/sam.idl) spec2def(samsrv.dll samsrv.spec ADD_IMPORTLIB) list(APPEND SOURCE + alias.c database.c domain.c group.c diff --git a/reactos/dll/win32/samsrv/alias.c b/reactos/dll/win32/samsrv/alias.c new file mode 100644 index 00000000000..96e70c854a8 --- /dev/null +++ b/reactos/dll/win32/samsrv/alias.c @@ -0,0 +1,42 @@ +/* + * PROJECT: Local Security Authority Server DLL + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll/win32/samsrv/alias.c + * PURPOSE: Alias specific helper functions + * COPYRIGHT: Copyright 2013 Eric Kohl + */ + +/* INCLUDES ****************************************************************/ + +#include "samsrv.h" + +WINE_DEFAULT_DEBUG_CHANNEL(samsrv); + + +/* FUNCTIONS ***************************************************************/ + +NTSTATUS +SampOpenAliasObject(IN PSAM_DB_OBJECT DomainObject, + IN ULONG AliasId, + IN ACCESS_MASK DesiredAccess, + OUT PSAM_DB_OBJECT *AliasObject) +{ + WCHAR szRid[9]; + + TRACE("(%p %lu %lx %p)\n", + DomainObject, AliasId, DesiredAccess, AliasObject); + + /* Convert the RID into a string (hex) */ + swprintf(szRid, L"%08lX", AliasId); + + /* Create the user object */ + return SampOpenDbObject(DomainObject, + L"Aliases", + szRid, + AliasId, + SamDbAliasObject, + DesiredAccess, + AliasObject); +} + +/* EOF */ diff --git a/reactos/dll/win32/samsrv/group.c b/reactos/dll/win32/samsrv/group.c index 4b1ab718a3d..9bf0c86168e 100644 --- a/reactos/dll/win32/samsrv/group.c +++ b/reactos/dll/win32/samsrv/group.c @@ -15,6 +15,30 @@ WINE_DEFAULT_DEBUG_CHANNEL(samsrv); /* FUNCTIONS ***************************************************************/ +NTSTATUS +SampOpenGroupObject(IN PSAM_DB_OBJECT DomainObject, + IN ULONG GroupId, + IN ACCESS_MASK DesiredAccess, + OUT PSAM_DB_OBJECT *GroupObject) +{ + WCHAR szRid[9]; + + TRACE("(%p %lu %lx %p)\n", + DomainObject, GroupId, DesiredAccess, GroupObject); + + /* Convert the RID into a string (hex) */ + swprintf(szRid, L"%08lX", GroupId); + + /* Create the user object */ + return SampOpenDbObject(DomainObject, + L"Groups", + szRid, + GroupId, + SamDbGroupObject, + DesiredAccess, + GroupObject); +} + NTSTATUS SampAddMemberToGroup(IN PSAM_DB_OBJECT GroupObject, diff --git a/reactos/dll/win32/samsrv/samsrv.h b/reactos/dll/win32/samsrv/samsrv.h index e95e78fe22e..9e838b572e7 100644 --- a/reactos/dll/win32/samsrv/samsrv.h +++ b/reactos/dll/win32/samsrv/samsrv.h @@ -117,6 +117,15 @@ typedef struct _SAM_USER_FIXED_DATA extern PGENERIC_MAPPING pServerMapping; +/* alias.c */ + +NTSTATUS +SampOpenAliasObject(IN PSAM_DB_OBJECT DomainObject, + IN ULONG AliasId, + IN ACCESS_MASK DesiredAccess, + OUT PSAM_DB_OBJECT *AliasObject); + + /* database.c */ NTSTATUS @@ -192,6 +201,12 @@ SampCheckAccountNameInDomain(IN PSAM_DB_OBJECT DomainObject, /* group.h */ +NTSTATUS +SampOpenGroupObject(IN PSAM_DB_OBJECT DomainObject, + IN ULONG GroupId, + IN ACCESS_MASK DesiredAccess, + OUT PSAM_DB_OBJECT *GroupObject); + NTSTATUS SampAddMemberToGroup(IN PSAM_DB_OBJECT GroupObject, IN ULONG MemberId); @@ -301,6 +316,9 @@ SampSetUserGroupAttributes(IN PSAM_DB_OBJECT DomainObject, IN ULONG GroupId, IN ULONG GroupAttributes); +NTSTATUS +SampRemoveUserFromAllGroups(IN PSAM_DB_OBJECT UserObject); + NTSTATUS SampSetUserPassword(IN PSAM_DB_OBJECT UserObject, IN PENCRYPTED_NT_OWF_PASSWORD NtPassword, diff --git a/reactos/dll/win32/samsrv/user.c b/reactos/dll/win32/samsrv/user.c index 0aa392a4a4d..a80402bd4ab 100644 --- a/reactos/dll/win32/samsrv/user.c +++ b/reactos/dll/win32/samsrv/user.c @@ -320,6 +320,69 @@ done: } +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); + + SampCloseDbObject(GroupObject); + + if (!NT_SUCCESS(Status)) + { + goto done; + } + } + +done: + if (GroupsBuffer != NULL) + midl_user_free(GroupsBuffer); + + return Status; +} + + NTSTATUS SampSetUserPassword(IN PSAM_DB_OBJECT UserObject, IN PENCRYPTED_NT_OWF_PASSWORD NtPassword,