https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7c618faa326bde0337ca74f50b02215576e8a397

commit 7c618faa326bde0337ca74f50b02215576e8a397
Author:     Pierre Schweitzer <[email protected]>
AuthorDate: Sat Jun 1 21:05:14 2019 +0200
Commit:     Pierre Schweitzer <[email protected]>
CommitDate: Sat Jun 1 21:09:20 2019 +0200

    [NTOSKRNL] Implement SeGetLogonIdDeviceMap
---
 ntoskrnl/include/internal/ob.h |   9 ++-
 ntoskrnl/ob/devicemap.c        |  10 +++
 ntoskrnl/se/srm.c              | 145 ++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 161 insertions(+), 3 deletions(-)

diff --git a/ntoskrnl/include/internal/ob.h b/ntoskrnl/include/internal/ob.h
index 23f54cefefd..266c4dd668c 100644
--- a/ntoskrnl/include/internal/ob.h
+++ b/ntoskrnl/include/internal/ob.h
@@ -402,7 +402,14 @@ NTSTATUS
 NTAPI
 ObSetDeviceMap(
     IN PEPROCESS Process,
-    IN HANDLE DirectoryHandle);
+    IN HANDLE DirectoryHandle
+);
+
+NTSTATUS
+NTAPI
+ObSetDirectoryDeviceMap(OUT PDEVICE_MAP * DeviceMap,
+                        IN HANDLE DirectoryHandle
+);
 
 VOID
 NTAPI
diff --git a/ntoskrnl/ob/devicemap.c b/ntoskrnl/ob/devicemap.c
index 8a471446919..5dfe1994dd8 100644
--- a/ntoskrnl/ob/devicemap.c
+++ b/ntoskrnl/ob/devicemap.c
@@ -144,6 +144,16 @@ ObSetDeviceMap(IN PEPROCESS Process,
 }
 
 
+NTSTATUS
+NTAPI
+ObSetDirectoryDeviceMap(OUT PDEVICE_MAP * DeviceMap,
+                        IN HANDLE DirectoryHandle)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
 NTSTATUS
 NTAPI
 ObpSetCurrentProcessDeviceMap(VOID)
diff --git a/ntoskrnl/se/srm.c b/ntoskrnl/se/srm.c
index 7d1526623c6..f0cc7341093 100644
--- a/ntoskrnl/se/srm.c
+++ b/ntoskrnl/se/srm.c
@@ -5,6 +5,7 @@
  * PURPOSE:         Security Reference Monitor Server
  *
  * PROGRAMMERS:     Timo Kreuzer ([email protected])
+ *                  Pierre Schweitzer ([email protected])
  */
 
 /* INCLUDES 
*******************************************************************/
@@ -701,8 +702,148 @@ SeGetLogonIdDeviceMap(
     OUT PDEVICE_MAP * DeviceMap
     )
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    NTSTATUS Status;
+    WCHAR Buffer[63];
+    PDEVICE_MAP LocalMap;
+    HANDLE DirectoryHandle, LinkHandle;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    PSEP_LOGON_SESSION_REFERENCES CurrentSession;
+    UNICODE_STRING DirectoryName, LinkName, TargetName;
+
+    PAGED_CODE();
+
+    if  (LogonId == NULL ||
+         DeviceMap == NULL)
+    {
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    /* Acquire the database lock */
+    KeAcquireGuardedMutex(&SepRmDbLock);
+
+    /* Loop all existing sessions */
+    for (CurrentSession = SepLogonSessions;
+         CurrentSession != NULL;
+         CurrentSession = CurrentSession->Next)
+    {
+        /* Check if the LUID matches the provided one */
+        if (RtlEqualLuid(&CurrentSession->LogonId, LogonId))
+        {
+            break;
+        }
+    }
+
+    /* No session found, fail */
+    if (CurrentSession == NULL)
+    {
+        /* Release the database lock */
+        KeReleaseGuardedMutex(&SepRmDbLock);
+
+        return STATUS_NO_SUCH_LOGON_SESSION;
+    }
+
+    /* The found session has a device map, return it! */
+    if (CurrentSession->pDeviceMap != NULL)
+    {
+        *DeviceMap = CurrentSession->pDeviceMap;
+
+        /* Release the database lock */
+        KeReleaseGuardedMutex(&SepRmDbLock);
+
+        return STATUS_SUCCESS;
+    }
+
+    /* At that point, we'll setup a new device map for the session */
+    LocalMap = NULL;
+
+    /* Reference the session so that it doesn't go away */
+    CurrentSession->ReferenceCount += 1;
+
+    /* Release the database lock */
+    KeReleaseGuardedMutex(&SepRmDbLock);
+
+    /* Create our object directory given the LUID */
+    _snwprintf(Buffer,
+               sizeof(Buffer) / sizeof(WCHAR),
+               L"\\Sessions\\0\\DosDevices\\%08x-%08x",
+               LogonId->HighPart,
+               LogonId->LowPart);
+    RtlInitUnicodeString(&DirectoryName, Buffer);
+
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &DirectoryName,
+                               OBJ_KERNEL_HANDLE | OBJ_OPENIF | 
OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+    Status = ZwCreateDirectoryObject(&DirectoryHandle,
+                                     DIRECTORY_ALL_ACCESS,
+                                     &ObjectAttributes);
+    if (NT_SUCCESS(Status))
+    {
+        /* Create the associated device map */
+        Status = ObSetDirectoryDeviceMap(&LocalMap, DirectoryHandle);
+        if (NT_SUCCESS(Status))
+        {
+            /* Make Global point to \Global?? in the directory */
+            RtlInitUnicodeString(&LinkName, L"Global");
+            RtlInitUnicodeString(&TargetName, L"\\Global??");
+
+            InitializeObjectAttributes(&ObjectAttributes,
+                                       &LinkName,
+                                       OBJ_KERNEL_HANDLE | OBJ_OPENIF | 
OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
+                                       DirectoryHandle,
+                                       NULL);
+            Status = ZwCreateSymbolicLinkObject(&LinkHandle,
+                                                SYMBOLIC_LINK_ALL_ACCESS,
+                                                &ObjectAttributes,
+                                                &TargetName);
+            if (!NT_SUCCESS(Status))
+            {
+                ObfDereferenceDeviceMap(LocalMap);
+            }
+            else
+            {
+                ZwClose(LinkHandle);
+            }
+        }
+
+        ZwClose(DirectoryHandle);
+    }
+
+    /* Acquire the database lock */
+    KeAcquireGuardedMutex(&SepRmDbLock);
+
+    /* If we succeed... */
+    if (NT_SUCCESS(Status))
+    {
+        /* The session now has a device map? We raced with someone else */
+        if (CurrentSession->pDeviceMap != NULL)
+        {
+            /* Give up on our new device map */
+            ObfDereferenceDeviceMap(LocalMap);
+        }
+        /* Otherwise use our newly allocated device map */
+        else
+        {
+            CurrentSession->pDeviceMap = LocalMap;
+        }
+
+        /* Return the device map */
+        *DeviceMap = CurrentSession->pDeviceMap;
+    }
+    /* Zero output */
+    else
+    {
+        *DeviceMap = NULL;
+    }
+
+    /* Release the database lock */
+    KeReleaseGuardedMutex(&SepRmDbLock);
+
+    /* We're done with the session */
+    SepRmDereferenceLogonSession(&CurrentSession->LogonId);
+
+    return Status;
 }
 
 /*

Reply via email to