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