[NTOSKRNL] Implement SeGetLogonIdDeviceMap
[reactos.git] / ntoskrnl / se / srm.c
index 0bbf017..f0cc734 100644 (file)
@@ -5,6 +5,7 @@
  * PURPOSE:         Security Reference Monitor Server
  *
  * PROGRAMMERS:     Timo Kreuzer (timo.kreuzer@reactos.org)
+ *                  Pierre Schweitzer (pierre@reactos.org)
  */
 
 /* INCLUDES *******************************************************************/
@@ -687,3 +688,198 @@ SepRmCommandServerThread(
     ObCloseHandle(SepRmCommandMessagePort, KernelMode);
     ObCloseHandle(SeRmCommandPort, KernelMode);
 }
+
+
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+SeGetLogonIdDeviceMap(
+    IN PLUID LogonId,
+    OUT PDEVICE_MAP * DeviceMap
+    )
+{
+    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;
+}
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+SeMarkLogonSessionForTerminationNotification(
+    IN PLUID LogonId)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+SeRegisterLogonSessionTerminatedRoutine(
+    IN PSE_LOGON_SESSION_TERMINATED_ROUTINE CallbackRoutine)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+
+/*
+ * @unimplemented
+ */
+NTSTATUS
+NTAPI
+SeUnregisterLogonSessionTerminatedRoutine(
+    IN PSE_LOGON_SESSION_TERMINATED_ROUTINE CallbackRoutine)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}