From ce07958bd918312a57ab3dcf9e9eeb2ac8ea7631 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Sun, 13 Jan 2013 19:51:33 +0000 Subject: [PATCH] [SAMSRV] Implement SamrGetMembersInGroup. svn path=/trunk/; revision=58170 --- reactos/dll/win32/samsrv/samrpc.c | 96 ++++++++++++++++++++++++++++++- reactos/dll/win32/samsrv/samsrv.h | 16 ++++-- reactos/dll/win32/samsrv/user.c | 68 ++++++++++++++++++++++ 3 files changed, 173 insertions(+), 7 deletions(-) diff --git a/reactos/dll/win32/samsrv/samrpc.c b/reactos/dll/win32/samsrv/samrpc.c index 27516bbab80..6d7a257a1ed 100644 --- a/reactos/dll/win32/samsrv/samrpc.c +++ b/reactos/dll/win32/samsrv/samrpc.c @@ -4055,10 +4055,102 @@ NTAPI SamrGetMembersInGroup(IN SAMPR_HANDLE GroupHandle, OUT PSAMPR_GET_MEMBERS_BUFFER *Members) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + PSAMPR_GET_MEMBERS_BUFFER MembersBuffer = NULL; + PSAM_DB_OBJECT GroupObject; + ULONG Length = 0; + ULONG i; + NTSTATUS Status; + + /* Validate the group handle */ + Status = SampValidateDbObject(GroupHandle, + SamDbGroupObject, + GROUP_LIST_MEMBERS, + &GroupObject); + if (!NT_SUCCESS(Status)) + return Status; + + MembersBuffer = midl_user_allocate(sizeof(SAMPR_GET_MEMBERS_BUFFER)); + if (MembersBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + SampGetObjectAttribute(GroupObject, + L"Members", + NULL, + NULL, + &Length); + + if (Length == 0) + { + MembersBuffer->MemberCount = 0; + MembersBuffer->Members = NULL; + MembersBuffer->Attributes = NULL; + + *Members = MembersBuffer; + + return STATUS_SUCCESS; + } + + MembersBuffer->Members = midl_user_allocate(Length); + if (MembersBuffer->Members == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + MembersBuffer->Attributes = midl_user_allocate(Length); + if (MembersBuffer->Attributes == NULL) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto done; + } + + Status = SampGetObjectAttribute(GroupObject, + L"Members", + NULL, + MembersBuffer->Members, + &Length); + if (!NT_SUCCESS(Status)) + { + TRACE("SampGetObjectAttributes() failed (Status 0x%08lx)\n", Status); + goto done; + } + + MembersBuffer->MemberCount = Length / sizeof(ULONG); + + for (i = 0; i < MembersBuffer->MemberCount; i++) + { + Status = SampGetUserGroupAttributes(GroupObject->ParentObject, + MembersBuffer->Members[i], + GroupObject->RelativeId, + &(MembersBuffer->Attributes[i])); + if (!NT_SUCCESS(Status)) + { + TRACE("SampGetUserGroupAttributes() failed (Status 0x%08lx)\n", Status); + goto done; + } + } + + *Members = MembersBuffer; + +done: + if (!NT_SUCCESS(Status)) + { + if (MembersBuffer != NULL) + { + if (MembersBuffer->Members != NULL) + midl_user_free(MembersBuffer->Members); + + if (MembersBuffer->Attributes != NULL) + midl_user_free(MembersBuffer->Attributes); + + midl_user_free(MembersBuffer); + } + } + + return Status; } + /* Function 26 */ NTSTATUS NTAPI diff --git a/reactos/dll/win32/samsrv/samsrv.h b/reactos/dll/win32/samsrv/samsrv.h index eab66474d3e..7de5ce15cfb 100644 --- a/reactos/dll/win32/samsrv/samsrv.h +++ b/reactos/dll/win32/samsrv/samsrv.h @@ -271,12 +271,18 @@ SampOpenUserObject(IN PSAM_DB_OBJECT DomainObject, OUT PSAM_DB_OBJECT *UserObject); NTSTATUS -SampAddGroupMembershipToUser(PSAM_DB_OBJECT UserObject, - ULONG GroupId, - ULONG Attributes); +SampAddGroupMembershipToUser(IN PSAM_DB_OBJECT UserObject, + IN ULONG GroupId, + IN ULONG Attributes); NTSTATUS -SampRemoveGroupMembershipFromUser(PSAM_DB_OBJECT UserObject, - ULONG GroupId); +SampRemoveGroupMembershipFromUser(IN PSAM_DB_OBJECT UserObject, + IN ULONG GroupId); + +NTSTATUS +SampGetUserGroupAttributes(IN PSAM_DB_OBJECT DomainObject, + IN ULONG UserId, + IN ULONG GroupId, + OUT PULONG GroupAttributes); /* EOF */ diff --git a/reactos/dll/win32/samsrv/user.c b/reactos/dll/win32/samsrv/user.c index be7042ee4bf..f3174c627a5 100644 --- a/reactos/dll/win32/samsrv/user.c +++ b/reactos/dll/win32/samsrv/user.c @@ -185,4 +185,72 @@ done: return Status; } + +NTSTATUS +SampGetUserGroupAttributes(IN PSAM_DB_OBJECT DomainObject, + IN ULONG UserId, + IN ULONG GroupId, + OUT PULONG GroupAttributes) +{ + PSAM_DB_OBJECT UserObject = NULL; + PGROUP_MEMBERSHIP GroupsBuffer = NULL; + ULONG Length = 0; + ULONG i; + NTSTATUS Status; + + Status = SampOpenUserObject(DomainObject, + UserId, + 0, + &UserObject); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + SampGetObjectAttribute(UserObject, + L"Groups", + NULL, + NULL, + &Length); + + if (Length == 0) + { + *GroupAttributes = 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++) + { + if (GroupsBuffer[i].RelativeId == GroupId) + { + *GroupAttributes = GroupsBuffer[i].Attributes; + goto done; + } + } + +done: + if (GroupsBuffer != NULL) + midl_user_free(GroupsBuffer); + + if (UserObject != NULL) + SampCloseDbObject(UserObject); + + return Status; +} + /* EOF */