https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7c618faa326bde0337ca7…
commit 7c618faa326bde0337ca74f50b02215576e8a397
Author: Pierre Schweitzer <pierre(a)reactos.org>
AuthorDate: Sat Jun 1 21:05:14 2019 +0200
Commit: Pierre Schweitzer <pierre(a)reactos.org>
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 (timo.kreuzer(a)reactos.org)
+ * Pierre Schweitzer (pierre(a)reactos.org)
*/
/* 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;
}
/*