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.txt?rev=58161&r1=58160&r2=58161&view=diff
==============================================================================
--- 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?rev=58161&r1=58160&r2=58161&view=diff
==============================================================================
--- 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?rev=58161&r1=58160&r2=58161&view=diff
==============================================================================
--- 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=58161&view=auto
==============================================================================
--- 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


Reply via email to