xref: /reactos/drivers/filesystems/npfs/secursup.c (revision c2c66aff)
1 /*
2  * PROJECT:     ReactOS Named Pipe FileSystem
3  * LICENSE:     BSD - See COPYING.ARM in the top level directory
4  * FILE:        drivers/filesystems/npfs/secursup.c
5  * PURPOSE:     Pipes Security Support
6  * PROGRAMMERS: ReactOS Portable Systems Group
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include "npfs.h"
12 
13 // File ID number for NPFS bugchecking support
14 #define NPFS_BUGCHECK_FILE_ID   (NPFS_BUGCHECK_SECURSUP)
15 
16 /* FUNCTIONS ******************************************************************/
17 
18 NTSTATUS
19 NTAPI
NpImpersonateClientContext(IN PNP_CCB Ccb)20 NpImpersonateClientContext(IN PNP_CCB Ccb)
21 {
22     NTSTATUS Status;
23     PSECURITY_CLIENT_CONTEXT ClientContext;
24     PAGED_CODE();
25 
26     ClientContext = Ccb->ClientContext;
27     if (ClientContext)
28     {
29         Status = SeImpersonateClientEx(ClientContext, NULL);
30     }
31     else
32     {
33         Status = STATUS_CANNOT_IMPERSONATE;
34     }
35     return Status;
36 }
37 
38 VOID
39 NTAPI
NpFreeClientSecurityContext(IN PSECURITY_CLIENT_CONTEXT ClientContext)40 NpFreeClientSecurityContext(IN PSECURITY_CLIENT_CONTEXT ClientContext)
41 {
42     TOKEN_TYPE TokenType;
43     PVOID ClientToken;
44 
45     if (!ClientContext) return;
46 
47     TokenType = SeTokenType(ClientContext->ClientToken);
48     ClientToken = ClientContext->ClientToken;
49     if ((TokenType == TokenPrimary) || (ClientToken))
50     {
51         ObDereferenceObject(ClientToken);
52     }
53     ExFreePool(ClientContext);
54 }
55 
56 VOID
57 NTAPI
NpCopyClientContext(IN PNP_CCB Ccb,IN PNP_DATA_QUEUE_ENTRY DataQueueEntry)58 NpCopyClientContext(IN PNP_CCB Ccb,
59                     IN PNP_DATA_QUEUE_ENTRY DataQueueEntry)
60 {
61     PAGED_CODE();
62 
63     if (!DataQueueEntry->ClientSecurityContext) return;
64 
65     NpFreeClientSecurityContext(Ccb->ClientContext);
66     Ccb->ClientContext = DataQueueEntry->ClientSecurityContext;
67     DataQueueEntry->ClientSecurityContext = NULL;
68 }
69 
70 VOID
71 NTAPI
NpUninitializeSecurity(IN PNP_CCB Ccb)72 NpUninitializeSecurity(IN PNP_CCB Ccb)
73 {
74     PAGED_CODE();
75 
76     NpFreeClientSecurityContext(Ccb->ClientContext);
77     Ccb->ClientContext = NULL;
78 }
79 
80 NTSTATUS
81 NTAPI
NpInitializeSecurity(IN PNP_CCB Ccb,IN PSECURITY_QUALITY_OF_SERVICE SecurityQos,IN PETHREAD Thread)82 NpInitializeSecurity(IN PNP_CCB Ccb,
83                      IN PSECURITY_QUALITY_OF_SERVICE SecurityQos,
84                      IN PETHREAD Thread)
85 {
86     PSECURITY_CLIENT_CONTEXT ClientContext;
87     NTSTATUS Status;
88     PAGED_CODE();
89 
90     if (SecurityQos)
91     {
92         Ccb->ClientQos = *SecurityQos;
93     }
94     else
95     {
96         Ccb->ClientQos.Length = sizeof(Ccb->ClientQos);
97         Ccb->ClientQos.ImpersonationLevel = SecurityImpersonation;
98         Ccb->ClientQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
99         Ccb->ClientQos.EffectiveOnly = TRUE;
100     }
101 
102     NpUninitializeSecurity(Ccb);
103 
104     if (Ccb->ClientQos.ContextTrackingMode == SECURITY_DYNAMIC_TRACKING)
105     {
106         Status = STATUS_SUCCESS;
107         Ccb->ClientContext = NULL;
108         return Status;
109     }
110 
111     ClientContext = ExAllocatePoolWithQuotaTag(PagedPool | POOL_QUOTA_FAIL_INSTEAD_OF_RAISE,
112                                                sizeof(*ClientContext),
113                                                NPFS_CLIENT_SEC_CTX_TAG);
114     Ccb->ClientContext = ClientContext;
115     if (!ClientContext) return STATUS_INSUFFICIENT_RESOURCES;
116 
117     Status = SeCreateClientSecurity(Thread, &Ccb->ClientQos, 0, ClientContext);
118     if (!NT_SUCCESS(Status))
119     {
120         ExFreePool(Ccb->ClientContext);
121         Ccb->ClientContext = NULL;
122     }
123 
124     return Status;
125 }
126 
127 NTSTATUS
128 NTAPI
NpGetClientSecurityContext(IN ULONG NamedPipeEnd,IN PNP_CCB Ccb,IN PETHREAD Thread,IN PSECURITY_CLIENT_CONTEXT * Context)129 NpGetClientSecurityContext(IN ULONG NamedPipeEnd,
130                            IN PNP_CCB Ccb,
131                            IN PETHREAD Thread,
132                            IN PSECURITY_CLIENT_CONTEXT *Context)
133 {
134     PSECURITY_CLIENT_CONTEXT NewContext;
135     NTSTATUS Status;
136     PAGED_CODE();
137 
138     if (NamedPipeEnd == FILE_PIPE_SERVER_END || Ccb->ClientQos.ContextTrackingMode != SECURITY_DYNAMIC_TRACKING)
139     {
140         NewContext = NULL;
141         Status = STATUS_SUCCESS;
142     }
143     else
144     {
145         NewContext = ExAllocatePoolWithQuotaTag(PagedPool | POOL_QUOTA_FAIL_INSTEAD_OF_RAISE,
146                                                 sizeof(*NewContext),
147                                                 NPFS_CLIENT_SEC_CTX_TAG);
148         if (!NewContext) return STATUS_INSUFFICIENT_RESOURCES;
149 
150         Status = SeCreateClientSecurity(Thread, &Ccb->ClientQos, 0, NewContext);
151         if (!NT_SUCCESS(Status))
152         {
153             ExFreePool(NewContext);
154             NewContext = NULL;
155         }
156     }
157     *Context = NewContext;
158     return Status;
159 }
160 
161 /* EOF */
162