Author: ekohl Date: Sat Jan 12 21:32:26 2013 New Revision: 58161
URL: http://svn.reactos.org/svn/reactos?rev=58161&view=rev Log: [SAMSRV] - SamrAddMemberToGroup: Add the group membership to the user object. - SamrRemoveMemberFromGroup: Remove the group membership from the user object.
Added: trunk/reactos/dll/win32/samsrv/user.c (with props) Modified: trunk/reactos/dll/win32/samsrv/CMakeLists.txt trunk/reactos/dll/win32/samsrv/samrpc.c trunk/reactos/dll/win32/samsrv/samsrv.h
Modified: trunk/reactos/dll/win32/samsrv/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/CMakeLists... ============================================================================== --- trunk/reactos/dll/win32/samsrv/CMakeLists.txt [iso-8859-1] (original) +++ trunk/reactos/dll/win32/samsrv/CMakeLists.txt [iso-8859-1] Sat Jan 12 21:32:26 2013 @@ -15,6 +15,7 @@ samrpc.c samsrv.c setup.c + user.c samsrv.rc ${CMAKE_CURRENT_BINARY_DIR}/samsrv_stubs.c ${CMAKE_CURRENT_BINARY_DIR}/samsrv.def
Modified: trunk/reactos/dll/win32/samsrv/samrpc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/samrpc.c?r... ============================================================================== --- trunk/reactos/dll/win32/samsrv/samrpc.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/samsrv/samrpc.c [iso-8859-1] Sat Jan 12 21:32:26 2013 @@ -3931,6 +3931,7 @@ IN unsigned long Attributes) { PSAM_DB_OBJECT GroupObject; + PSAM_DB_OBJECT UserObject = NULL; NTSTATUS Status;
TRACE("(%p %lu %lx)\n", @@ -3944,10 +3945,38 @@ if (!NT_SUCCESS(Status)) return Status;
- /* FIXME: Add group membership to the user object */ - + /* Open the user object in the same domain */ + Status = SampOpenUserObject(GroupObject->ParentObject, + MemberId, + 0, + &UserObject); + if (!NT_SUCCESS(Status)) + { + ERR("SampOpenUserObject() failed (Status 0x%08lx)\n", Status); + goto done; + } + + /* Add group membership to the user object */ + Status = SampAddGroupMembershipToUser(UserObject, + GroupObject->RelativeId, + Attributes); + if (!NT_SUCCESS(Status)) + { + ERR("SampAddGroupMembershipToUser() failed (Status 0x%08lx)\n", Status); + goto done; + } + + /* Add the member to the group object */ Status = SampAddMemberToGroup(GroupObject, MemberId); + if (!NT_SUCCESS(Status)) + { + ERR("SampAddMemberToGroup() failed (Status 0x%08lx)\n", Status); + } + +done: + if (UserObject) + SampCloseDbObject(UserObject);
return Status; } @@ -3970,6 +3999,7 @@ IN unsigned long MemberId) { PSAM_DB_OBJECT GroupObject; + PSAM_DB_OBJECT UserObject = NULL; NTSTATUS Status;
TRACE("(%p %lu)\n", @@ -3983,10 +4013,37 @@ if (!NT_SUCCESS(Status)) return Status;
- /* FIXME: Remove group membership from the user object */ - + /* Open the user object in the same domain */ + Status = SampOpenUserObject(GroupObject->ParentObject, + MemberId, + 0, + &UserObject); + if (!NT_SUCCESS(Status)) + { + ERR("SampOpenUserObject() failed (Status 0x%08lx)\n", Status); + goto done; + } + + /* Remove group membership from the user object */ + Status = SampRemoveGroupMembershipFromUser(UserObject, + GroupObject->RelativeId); + if (!NT_SUCCESS(Status)) + { + ERR("SampAddGroupMembershipToUser() failed (Status 0x%08lx)\n", Status); + goto done; + } + + /* Remove the member from the group object */ Status = SampRemoveMemberFromGroup(GroupObject, MemberId); + if (!NT_SUCCESS(Status)) + { + ERR("SampRemoveMemberFromGroup() failed (Status 0x%08lx)\n", Status); + } + +done: + if (UserObject) + SampCloseDbObject(UserObject);
return Status; }
Modified: trunk/reactos/dll/win32/samsrv/samsrv.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/samsrv.h?r... ============================================================================== --- trunk/reactos/dll/win32/samsrv/samsrv.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/samsrv/samsrv.h [iso-8859-1] Sat Jan 12 21:32:26 2013 @@ -261,4 +261,22 @@ BOOL SampIsSetupRunning(VOID); BOOL SampInitializeSAM(VOID);
+ +/* user.c */ + +NTSTATUS +SampOpenUserObject(IN PSAM_DB_OBJECT DomainObject, + IN ULONG UserId, + IN ACCESS_MASK DesiredAccess, + OUT PSAM_DB_OBJECT *UserObject); + +NTSTATUS +SampAddGroupMembershipToUser(PSAM_DB_OBJECT UserObject, + ULONG GroupId, + ULONG Attributes); + +NTSTATUS +SampRemoveGroupMembershipFromUser(PSAM_DB_OBJECT UserObject, + ULONG GroupId); + /* EOF */
Added: trunk/reactos/dll/win32/samsrv/user.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/samsrv/user.c?rev... ============================================================================== --- trunk/reactos/dll/win32/samsrv/user.c (added) +++ trunk/reactos/dll/win32/samsrv/user.c [iso-8859-1] Sat Jan 12 21:32:26 2013 @@ -1,0 +1,188 @@ +/* + * PROJECT: Local Security Authority Server DLL + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll/win32/samsrv/user.c + * PURPOSE: User specific helper functions + * COPYRIGHT: Copyright 2013 Eric Kohl + */ + +/* INCLUDES ****************************************************************/ + +#include "samsrv.h" + +WINE_DEFAULT_DEBUG_CHANNEL(samsrv); + + +/* FUNCTIONS ***************************************************************/ + +NTSTATUS +SampOpenUserObject(IN PSAM_DB_OBJECT DomainObject, + IN ULONG UserId, + IN ACCESS_MASK DesiredAccess, + OUT PSAM_DB_OBJECT *UserObject) +{ + WCHAR szRid[9]; + + TRACE("(%p %lu %lx %p)\n", + DomainObject, UserId, DesiredAccess, UserObject); + + /* Convert the RID into a string (hex) */ + swprintf(szRid, L"%08lX", UserId); + + /* Create the user object */ + return SampOpenDbObject(DomainObject, + L"Users", + szRid, + UserId, + SamDbUserObject, + DesiredAccess, + UserObject); +} + + +NTSTATUS +SampAddGroupMembershipToUser(IN PSAM_DB_OBJECT UserObject, + IN ULONG GroupId, + IN ULONG Attributes) +{ + PGROUP_MEMBERSHIP GroupsBuffer = NULL; + ULONG GroupsCount = 0; + ULONG Length = 0; + ULONG i; + NTSTATUS Status; + + TRACE("(%p %lu %lx)\n", + UserObject, GroupId, Attributes); + + Status = SampGetObjectAttribute(UserObject, + L"Groups", + NULL, + NULL, + &Length); + if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_NOT_FOUND) + goto done; + + GroupsBuffer = midl_user_allocate(Length + sizeof(GROUP_MEMBERSHIP)); + if (GroupsBuffer == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + if (Status != STATUS_OBJECT_NAME_NOT_FOUND) + { + Status = SampGetObjectAttribute(UserObject, + L"Groups", + NULL, + GroupsBuffer, + &Length); + if (!NT_SUCCESS(Status)) + goto done; + + GroupsCount = Length / sizeof(GROUP_MEMBERSHIP); + } + + for (i = 0; i < GroupsCount; i++) + { + if (GroupsBuffer[i].RelativeId == GroupId) + { + Status = STATUS_MEMBER_IN_GROUP; + goto done; + } + } + + GroupsBuffer[GroupsCount].RelativeId = GroupId; + GroupsBuffer[GroupsCount].Attributes = Attributes; + Length += sizeof(GROUP_MEMBERSHIP); + + Status = SampSetObjectAttribute(UserObject, + L"Groups", + REG_BINARY, + GroupsBuffer, + Length); + +done: + if (GroupsBuffer != NULL) + midl_user_free(GroupsBuffer); + + return Status; +} + + +NTSTATUS +SampRemoveGroupMembershipFromUser(IN PSAM_DB_OBJECT UserObject, + IN ULONG GroupId) +{ + PGROUP_MEMBERSHIP GroupsBuffer = NULL; + ULONG GroupsCount = 0; + ULONG Length = 0; + ULONG i; + NTSTATUS Status; + + TRACE("(%p %lu)\n", + UserObject, GroupId); + + Status = SampGetObjectAttribute(UserObject, + L"Groups", + NULL, + NULL, + &Length); + + if (Status == STATUS_OBJECT_NAME_NOT_FOUND) + return STATUS_MEMBER_NOT_IN_GROUP; + + if (!NT_SUCCESS(Status)) + return Status; + + 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; + + Status = STATUS_MEMBER_NOT_IN_GROUP; + + GroupsCount = Length / sizeof(GROUP_MEMBERSHIP); + for (i = 0; i < GroupsCount; i++) + { + if (GroupsBuffer[i].RelativeId == GroupId) + { + 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 (!NT_SUCCESS(Status)) + goto done; + + Status = SampSetObjectAttribute(UserObject, + L"Groups", + REG_BINARY, + GroupsBuffer, + Length); + +done: + if (GroupsBuffer != NULL) + midl_user_free(GroupsBuffer); + + return Status; +} + +/* EOF */
Propchange: trunk/reactos/dll/win32/samsrv/user.c ------------------------------------------------------------------------------ svn:eol-style = native
Propchange: trunk/reactos/dll/win32/samsrv/user.c ------------------------------------------------------------------------------ svn:keywords = author date id revision