Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / drivers / filesystems / npfs / secursup.c
diff --git a/drivers/filesystems/npfs/secursup.c b/drivers/filesystems/npfs/secursup.c
new file mode 100644 (file)
index 0000000..60581e1
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * PROJECT:     ReactOS Named Pipe FileSystem
+ * LICENSE:     BSD - See COPYING.ARM in the top level directory
+ * FILE:        drivers/filesystems/npfs/secursup.c
+ * PURPOSE:     Pipes Security Support
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "npfs.h"
+
+// File ID number for NPFS bugchecking support
+#define NPFS_BUGCHECK_FILE_ID   (NPFS_BUGCHECK_SECURSUP)
+
+/* FUNCTIONS ******************************************************************/
+
+NTSTATUS
+NTAPI
+NpImpersonateClientContext(IN PNP_CCB Ccb)
+{
+    NTSTATUS Status;
+    PSECURITY_CLIENT_CONTEXT ClientContext;
+    PAGED_CODE();
+
+    ClientContext = Ccb->ClientContext;
+    if (ClientContext)
+    {
+        Status = SeImpersonateClientEx(ClientContext, NULL);
+    }
+    else
+    {
+        Status = STATUS_CANNOT_IMPERSONATE;
+    }
+    return Status;
+}
+
+VOID
+NTAPI
+NpFreeClientSecurityContext(IN PSECURITY_CLIENT_CONTEXT ClientContext)
+{
+    TOKEN_TYPE TokenType;
+    PVOID ClientToken;
+
+    if (!ClientContext) return;
+
+    TokenType = SeTokenType(ClientContext->ClientToken);
+    ClientToken = ClientContext->ClientToken;
+    if ((TokenType == TokenPrimary) || (ClientToken))
+    {
+        ObDereferenceObject(ClientToken);
+    }
+    ExFreePool(ClientContext);
+}
+
+VOID
+NTAPI
+NpCopyClientContext(IN PNP_CCB Ccb,
+                    IN PNP_DATA_QUEUE_ENTRY DataQueueEntry)
+{
+    PAGED_CODE();
+
+    if (!DataQueueEntry->ClientSecurityContext) return;
+
+    NpFreeClientSecurityContext(Ccb->ClientContext);
+    Ccb->ClientContext = DataQueueEntry->ClientSecurityContext;
+    DataQueueEntry->ClientSecurityContext = NULL;
+}
+
+VOID
+NTAPI
+NpUninitializeSecurity(IN PNP_CCB Ccb)
+{
+    PAGED_CODE();
+
+    NpFreeClientSecurityContext(Ccb->ClientContext);
+    Ccb->ClientContext = NULL;
+}
+
+NTSTATUS
+NTAPI
+NpInitializeSecurity(IN PNP_CCB Ccb,
+                     IN PSECURITY_QUALITY_OF_SERVICE SecurityQos,
+                     IN PETHREAD Thread)
+{
+    PSECURITY_CLIENT_CONTEXT ClientContext;
+    NTSTATUS Status;
+    PAGED_CODE();
+
+    if (SecurityQos)
+    {
+        Ccb->ClientQos = *SecurityQos;
+    }
+    else
+    {
+        Ccb->ClientQos.Length = sizeof(Ccb->ClientQos);
+        Ccb->ClientQos.ImpersonationLevel = SecurityImpersonation;
+        Ccb->ClientQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
+        Ccb->ClientQos.EffectiveOnly = TRUE;
+    }
+
+    NpUninitializeSecurity(Ccb);
+
+    if (Ccb->ClientQos.ContextTrackingMode == SECURITY_DYNAMIC_TRACKING)
+    {
+        Status = STATUS_SUCCESS;
+        Ccb->ClientContext = NULL;
+        return Status;
+    }
+
+    ClientContext = ExAllocatePoolWithQuotaTag(PagedPool | POOL_QUOTA_FAIL_INSTEAD_OF_RAISE,
+                                               sizeof(*ClientContext),
+                                               NPFS_CLIENT_SEC_CTX_TAG);
+    Ccb->ClientContext = ClientContext;
+    if (!ClientContext) return STATUS_INSUFFICIENT_RESOURCES;
+
+    Status = SeCreateClientSecurity(Thread, &Ccb->ClientQos, 0, ClientContext);
+    if (!NT_SUCCESS(Status))
+    {
+        ExFreePool(Ccb->ClientContext);
+        Ccb->ClientContext = NULL;
+    }
+
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+NpGetClientSecurityContext(IN ULONG NamedPipeEnd,
+                           IN PNP_CCB Ccb,
+                           IN PETHREAD Thread,
+                           IN PSECURITY_CLIENT_CONTEXT *Context)
+{
+    PSECURITY_CLIENT_CONTEXT NewContext;
+    NTSTATUS Status;
+    PAGED_CODE();
+
+    if (NamedPipeEnd == FILE_PIPE_SERVER_END || Ccb->ClientQos.ContextTrackingMode != SECURITY_DYNAMIC_TRACKING)
+    {
+        NewContext = NULL;
+        Status = STATUS_SUCCESS;
+    }
+    else
+    {
+        NewContext = ExAllocatePoolWithQuotaTag(PagedPool | POOL_QUOTA_FAIL_INSTEAD_OF_RAISE,
+                                                sizeof(*NewContext),
+                                                NPFS_CLIENT_SEC_CTX_TAG);
+        if (!NewContext) return STATUS_INSUFFICIENT_RESOURCES;
+
+        Status = SeCreateClientSecurity(Thread, &Ccb->ClientQos, 0, NewContext);
+        if (!NT_SUCCESS(Status))
+        {
+            ExFreePool(NewContext);
+            NewContext = NULL;
+        }
+    }
+    *Context = NewContext;
+    return Status;
+}
+
+/* EOF */