ReactOS  0.4.15-dev-4916-gd519b11
client.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE: Security client support routines
5  * COPYRIGHT: Copyright Alex Ionescu <alex@relsoft.net>
6  */
7 
8 /* INCLUDES *******************************************************************/
9 
10 #include <ntoskrnl.h>
11 #define NDEBUG
12 #include <debug.h>
13 
14 /* PRIVATE FUNCTIONS **********************************************************/
15 
52 NTAPI
55  _In_ PSECURITY_QUALITY_OF_SERVICE ClientSecurityQos,
56  _In_ BOOLEAN ServerIsRemote,
58  _In_ BOOLEAN ThreadEffectiveOnly,
61 {
63  PACCESS_TOKEN NewToken;
64  PAGED_CODE();
65 
66  /* Check for bogus impersonation level */
67  if (!VALID_IMPERSONATION_LEVEL(ClientSecurityQos->ImpersonationLevel))
68  {
69  /* Fail the call */
71  }
72 
73  /* Check what kind of token this is */
75  {
76  /* On a primary token, if we do direct access, copy the flag from the QOS */
77  ClientContext->DirectAccessEffectiveOnly = ClientSecurityQos->EffectiveOnly;
78  }
79  else
80  {
81  /* This is an impersonation token, is the level ok? */
82  if (ClientSecurityQos->ImpersonationLevel > ImpersonationLevel)
83  {
84  /* Nope, fail */
86  }
87 
88  /* Is the level too low, or are we doing something other than delegation remotely */
91  ((ServerIsRemote) && (ImpersonationLevel != SecurityDelegation)))
92  {
93  /* Fail the call */
95  }
96 
97  /* Pick either the thread setting or the QOS setting */
98  ClientContext->DirectAccessEffectiveOnly =
99  ((ThreadEffectiveOnly) || (ClientSecurityQos->EffectiveOnly)) ? TRUE : FALSE;
100  }
101 
102  /* Is this static tracking */
103  if (ClientSecurityQos->ContextTrackingMode == SECURITY_STATIC_TRACKING)
104  {
105  /* Do not use direct access and make a copy */
106  ClientContext->DirectlyAccessClientToken = FALSE;
108  ClientSecurityQos->ImpersonationLevel,
109  KernelMode,
110  &NewToken);
111  if (!NT_SUCCESS(Status))
112  return Status;
113  }
114  else
115  {
116  /* Use direct access and check if this is local */
117  ClientContext->DirectlyAccessClientToken = TRUE;
118  if (ServerIsRemote)
119  {
120  /* We are doing delegation, so make a copy of the control data */
122  &ClientContext->ClientTokenControl);
123  }
124 
125  /* Keep the same token */
126  NewToken = Token;
127  }
128 
129  /* Fill out the context and return success */
130  ClientContext->SecurityQos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
131  ClientContext->SecurityQos.ImpersonationLevel = ClientSecurityQos->ImpersonationLevel;
132  ClientContext->SecurityQos.ContextTrackingMode = ClientSecurityQos->ContextTrackingMode;
133  ClientContext->SecurityQos.EffectiveOnly = ClientSecurityQos->EffectiveOnly;
134  ClientContext->ServerIsRemote = ServerIsRemote;
135  ClientContext->ClientToken = NewToken;
136  return STATUS_SUCCESS;
137 }
138 
139 /* PUBLIC FUNCTIONS ***********************************************************/
140 
160 NTSTATUS
161 NTAPI
165  _In_ BOOLEAN RemoteClient,
167 {
169  BOOLEAN ThreadEffectiveOnly;
173  PAGED_CODE();
174 
175  /* Reference the correct token */
177  &TokenType,
178  &ThreadEffectiveOnly,
180 
181  /* Create client security from it */
183  Qos,
184  RemoteClient,
185  TokenType,
186  ThreadEffectiveOnly,
188  ClientContext);
189 
190  /* Check if we failed or static tracking was used */
191  if (!(NT_SUCCESS(Status)) || (Qos->ContextTrackingMode == SECURITY_STATIC_TRACKING))
192  {
193  /* Dereference our copy since it's not being used */
195  }
196 
197  /* Return status */
198  return Status;
199 }
200 
222 NTSTATUS
223 NTAPI
226  _In_ PSECURITY_QUALITY_OF_SERVICE ClientSecurityQos,
227  _In_ BOOLEAN ServerIsRemote,
229 {
232  PAGED_CODE();
233 
234  /* Get the right token and reference it */
237 
238  /* Create the context */
240  ClientSecurityQos,
241  ServerIsRemote,
242  SubjectContext->ClientToken ?
244  FALSE,
245  SubjectContext->ImpersonationLevel,
246  ClientContext);
247 
248  /* Check if we failed or static tracking was used */
249  if (!(NT_SUCCESS(Status)) ||
250  (ClientSecurityQos->ContextTrackingMode == SECURITY_STATIC_TRACKING))
251  {
252  /* Dereference our copy since it's not being used */
254  }
255 
256  /* Return status */
257  return Status;
258 }
259 
274 NTSTATUS
275 NTAPI
279 {
281  PAGED_CODE();
282 
283  /* Check if direct access is requested */
284  if (!ClientContext->DirectlyAccessClientToken)
285  {
286  /* No, so get the flag from QOS */
287  EffectiveOnly = ClientContext->SecurityQos.EffectiveOnly;
288  }
289  else
290  {
291  /* Yes, so see if direct access should be effective only */
292  EffectiveOnly = ClientContext->DirectAccessEffectiveOnly;
293  }
294 
295  /* Use the current thread if one was not passed */
297 
298  /* Call the lower layer routine */
300  ClientContext->ClientToken,
301  TRUE,
303  ClientContext->SecurityQos.ImpersonationLevel);
304 }
305 
319 VOID
320 NTAPI
324 {
325  PAGED_CODE();
326 
327  /* Call the new API */
329 }
330 
331 /* EOF */
NTSTATUS NTAPI PsImpersonateClient(IN PETHREAD Thread, IN PACCESS_TOKEN Token, IN BOOLEAN CopyOnOpen, IN BOOLEAN EffectiveOnly, IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
Definition: security.c:610
_Inout_ PLIST_ENTRY _In_ PVOID _In_ PSTRING _In_ BOOLEAN _In_ BOOLEAN _In_ ULONG _In_ PFLT_CALLBACK_DATA _In_opt_ PCHECK_FOR_TRAVERSE_ACCESS _In_opt_ PSECURITY_SUBJECT_CONTEXT SubjectContext
Definition: fltkernel.h:2238
#define STATUS_BAD_IMPERSONATION_LEVEL
Definition: ntstatus.h:401
NTSTATUS NTAPI SeCreateClientSecurityFromSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, _In_ PSECURITY_QUALITY_OF_SERVICE ClientSecurityQos, _In_ BOOLEAN ServerIsRemote, _Out_ PSECURITY_CLIENT_CONTEXT ClientContext)
Creates a client security context based upon the captured security subject context.
Definition: client.c:224
#define VALID_IMPERSONATION_LEVEL(Level)
Definition: setypes.h:101
#define _In_opt_
Definition: ms_sal.h:309
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define _Out_
Definition: ms_sal.h:345
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG _Inout_ PLUID _Out_ PHANDLE Token
NTSTATUS NTAPI SeImpersonateClientEx(_In_ PSECURITY_CLIENT_CONTEXT ClientContext, _In_opt_ PETHREAD ServerThread)
Extended function that impersonates a client.
Definition: client.c:276
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
enum _SECURITY_IMPERSONATION_LEVEL SECURITY_IMPERSONATION_LEVEL
unsigned char BOOLEAN
UINT CALLBACK ServerThread(_Inout_ PVOID Parameter)
#define _In_
Definition: ms_sal.h:308
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ PVOID ClientContext
Definition: netioddk.h:55
USHORT Length
Definition: ntsecapi.h:172
_Out_ PBOOLEAN _Out_ PBOOLEAN _Out_ PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: psfuncs.h:154
#define ObDereferenceObject
Definition: obfuncs.h:203
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2652
PACCESS_TOKEN NTAPI PsReferenceEffectiveToken(IN PETHREAD Thread, OUT IN PTOKEN_TYPE TokenType, OUT PBOOLEAN EffectiveOnly, OUT PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
Definition: security.c:780
#define SeQuerySubjectContextToken(SubjectContext)
Definition: sefuncs.h:583
VOID NTAPI SeImpersonateClient(_In_ PSECURITY_CLIENT_CONTEXT ClientContext, _In_opt_ PETHREAD ServerThread)
Impersonates a client user.
Definition: client.c:321
enum _TOKEN_TYPE TOKEN_TYPE
NTSTATUS NTAPI SeCopyClientToken(_In_ PACCESS_TOKEN Token, _In_ SECURITY_IMPERSONATION_LEVEL Level, _In_ KPROCESSOR_MODE PreviousMode, _Out_ PACCESS_TOKEN *NewToken)
Copies an existing access token (technically duplicating a new one).
Definition: token.c:1296
NTSTATUS NTAPI SepCreateClientSecurity(_In_ PACCESS_TOKEN Token, _In_ PSECURITY_QUALITY_OF_SERVICE ClientSecurityQos, _In_ BOOLEAN ServerIsRemote, _In_ TOKEN_TYPE TokenType, _In_ BOOLEAN ThreadEffectiveOnly, _In_ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, _Out_ PSECURITY_CLIENT_CONTEXT ClientContext)
Creates a client security context based upon an access token.
Definition: client.c:53
#define SECURITY_STATIC_TRACKING
Definition: setypes.h:104
VOID NTAPI SeGetTokenControlInformation(_In_ PACCESS_TOKEN _Token, _Out_ PTOKEN_CONTROL TokenControl)
Retrieves token control information.
Definition: token.c:1474
struct _SECURITY_QUALITY_OF_SERVICE SECURITY_QUALITY_OF_SERVICE
#define ObReferenceObject
Definition: obfuncs.h:204
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_ BOOLEAN EffectiveOnly
Definition: sefuncs.h:401
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_ BOOLEAN _In_ TOKEN_TYPE TokenType
Definition: sefuncs.h:401
#define PAGED_CODE()
NTSTATUS NTAPI SeCreateClientSecurity(_In_ PETHREAD Thread, _In_ PSECURITY_QUALITY_OF_SERVICE Qos, _In_ BOOLEAN RemoteClient, _Out_ PSECURITY_CLIENT_CONTEXT ClientContext)
Creates a client security context.
Definition: client.c:162