https://git.reactos.org/?p=reactos.git;a=commitdiff;h=06b0d2e380183c3c76f49…
commit 06b0d2e380183c3c76f49fd166efdf91ab5b79c2
Author:     George Bișoc <george.bisoc(a)reactos.org>
AuthorDate: Sun May 23 12:21:47 2021 +0200
Commit:     George Bișoc <george.bisoc(a)reactos.org>
CommitDate: Wed Jun 2 11:09:01 2021 +0200
    [NTOS:SE] Implement logon session deletion
    And declare a prototype for SepCleanupLUIDDeviceMapDirectory and annotate it with SAL.
---
 ntoskrnl/se/srm.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 107 insertions(+), 6 deletions(-)
diff --git a/ntoskrnl/se/srm.c b/ntoskrnl/se/srm.c
index ffd5547fa32..6033e07d631 100644
--- a/ntoskrnl/se/srm.c
+++ b/ntoskrnl/se/srm.c
@@ -33,6 +33,11 @@ NTAPI
 SepRmCommandServerThread(
     PVOID StartContext);
+static
+NTSTATUS
+SepCleanupLUIDDeviceMapDirectory(
+    _In_ PLUID LogonLuid);
+
 static
 NTSTATUS
 SepRmCreateLogonSession(
@@ -376,17 +381,113 @@ Leave:
     return Status;
 }
+/**
+ * @brief
+ * Deletes a logon session from the logon sessions database.
+ *
+ * @param[in] LogonLuid
+ * A logon ID represented as a LUID. This LUID is used to point
+ * the exact logon session saved within the database.
+ *
+ * @return
+ * STATUS_SUCCESS is returned if the logon session has been deleted successfully.
+ * STATUS_NO_SUCH_LOGON_SESSION is returned if the logon session with the submitted
+ * LUID doesn't exist. STATUS_BAD_LOGON_SESSION_STATE is returned if the logon
session
+ * is still in use and we're not allowed to delete it, or if a system or anonymous
session
+ * is submitted and we're not allowed to delete them as they're internal parts of
the system.
+ * Otherwise a failure NTSTATUS code is returned.
+ */
 static
 NTSTATUS
 SepRmDeleteLogonSession(
-    PLUID LogonLuid)
+    _In_ PLUID LogonLuid)
 {
+    PSEP_LOGON_SESSION_REFERENCES SessionToDelete;
+    NTSTATUS Status;
+    PAGED_CODE();
+
     DPRINT("SepRmDeleteLogonSession(%08lx:%08lx)\n",
            LogonLuid->HighPart, LogonLuid->LowPart);
-    UNIMPLEMENTED;
-    NT_ASSERT(FALSE);
-    return STATUS_NOT_IMPLEMENTED;
+    /* Acquire the database lock */
+    KeAcquireGuardedMutex(&SepRmDbLock);
+
+    /* Loop over the existing logon sessions */
+    for (SessionToDelete = SepLogonSessions;
+         SessionToDelete != NULL;
+         SessionToDelete = SessionToDelete->Next)
+    {
+        /*
+         * Does the actual logon session exist in the
+         * saved logon sessions database with the LUID
+         * provided?
+         */
+        if (RtlEqualLuid(&SessionToDelete->LogonId, LogonLuid))
+        {
+            /* Did the caller supply one of these internal sessions? */
+            if (RtlEqualLuid(&SessionToDelete->LogonId,
&SeSystemAuthenticationId) ||
+                RtlEqualLuid(&SessionToDelete->LogonId,
&SeAnonymousAuthenticationId))
+            {
+                /* These logons are critical stuff, we can't delete them */
+                DPRINT1("SepRmDeleteLogonSession(): We're not allowed to delete
anonymous/system sessions!\n");
+                Status = STATUS_BAD_LOGON_SESSION_STATE;
+                goto Leave;
+            }
+            else
+            {
+                /* We found the logon as exactly as we wanted, break the loop */
+                break;
+            }
+        }
+    }
+
+    /*
+     * If we reach this then that means we've exhausted all the logon
+     * sessions and couldn't find one with the desired LUID.
+     */
+    if (SessionToDelete == NULL)
+    {
+        DPRINT1("SepRmDeleteLogonSession(): The logon session with this LUID
doesn't exist!\n");
+        Status = STATUS_NO_SUCH_LOGON_SESSION;
+        goto Leave;
+    }
+
+    /* Is somebody still using this logon session? */
+    if (SessionToDelete->ReferenceCount != 0)
+    {
+        /* The logon session is still in use, we cannot delete it... */
+        DPRINT1("SepRmDeleteLogonSession(): The logon session is still in
use!\n");
+        Status = STATUS_BAD_LOGON_SESSION_STATE;
+        goto Leave;
+    }
+
+    /* If we have a LUID device map, clean it */
+    if (SessionToDelete->pDeviceMap != NULL)
+    {
+        Status = SepCleanupLUIDDeviceMapDirectory(LogonLuid);
+        if (!NT_SUCCESS(Status))
+        {
+            /*
+             * We had one job on cleaning the device map directory
+             * of the logon session but we failed, quit...
+             */
+            DPRINT1("SepRmDeleteLogonSession(): Failed to clean the LUID device map
directory of the logon (Status: 0x%lx)\n", Status);
+            goto Leave;
+        }
+
+        /* And dereference the device map of the logon */
+        ObfDereferenceDeviceMap(SessionToDelete->pDeviceMap);
+    }
+
+    /* If we're here then we've deleted the logon session successfully */
+    DPRINT("SepRmDeleteLogonSession(): Logon session deleted with success!\n");
+    Status = STATUS_SUCCESS;
+    ExFreePoolWithTag(SessionToDelete, SEP_LOGON_SESSION_TAG);
+
+Leave:
+    /* Release the database lock */
+    KeReleaseGuardedMutex(&SepRmDbLock);
+    return Status;
 }
@@ -429,10 +530,10 @@ SepRmReferenceLogonSession(
     return STATUS_NO_SUCH_LOGON_SESSION;
 }
-
+static
 NTSTATUS
 SepCleanupLUIDDeviceMapDirectory(
-    PLUID LogonLuid)
+    _In_ PLUID LogonLuid)
 {
     BOOLEAN UseCurrentProc;
     KAPC_STATE ApcState;