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;