- SamrAddMemberToGroup: Add the group membership to the user object.
- SamrRemoveMemberFromGroup: Remove the group membership from the user object.

svn path=/trunk/; revision=58161
This commit is contained in:
Eric Kohl
2013-01-12 21:32:26 +00:00
parent 23174045bf
commit b9272a3090
4 changed files with 266 additions and 2 deletions
+1
View File
@@ -15,6 +15,7 @@ list(APPEND SOURCE
samrpc.c
samsrv.c
setup.c
user.c
samsrv.rc
${CMAKE_CURRENT_BINARY_DIR}/samsrv_stubs.c
${CMAKE_CURRENT_BINARY_DIR}/samsrv.def
+59 -2
View File
@@ -3931,6 +3931,7 @@ SamrAddMemberToGroup(IN SAMPR_HANDLE GroupHandle,
IN unsigned long Attributes)
{
PSAM_DB_OBJECT GroupObject;
PSAM_DB_OBJECT UserObject = NULL;
NTSTATUS Status;
TRACE("(%p %lu %lx)\n",
@@ -3944,10 +3945,38 @@ SamrAddMemberToGroup(IN SAMPR_HANDLE GroupHandle,
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 @@ SamrRemoveMemberFromGroup(IN SAMPR_HANDLE GroupHandle,
IN unsigned long MemberId)
{
PSAM_DB_OBJECT GroupObject;
PSAM_DB_OBJECT UserObject = NULL;
NTSTATUS Status;
TRACE("(%p %lu)\n",
@@ -3983,10 +4013,37 @@ SamrRemoveMemberFromGroup(IN SAMPR_HANDLE GroupHandle,
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;
}
+18
View File
@@ -261,4 +261,22 @@ VOID SampStartRpcServer(VOID);
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 */
+188
View File
@@ -0,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 */