ReactOS 0.4.16-dev-122-g325d74c
security.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define DESKTOP_READ
 
#define DESKTOP_WRITE
 
#define DESKTOP_EXECUTE
 
#define DESKTOP_ALL_ACCESS
 
#define WINSTA_READ
 
#define WINSTA_WRITE
 
#define WINSTA_EXECUTE
 
#define WINSTA_ACCESS_ALL
 

Functions

HANDLE IntCaptureCurrentAccessToken (VOID)
 
PVOID IntAllocateSecurityBuffer (_In_ SIZE_T Length)
 Allocates a buffer within UM (user mode) address space area. Such buffer is reserved for security purposes, such as allocating a buffer for a DACL or a security descriptor.
 
VOID IntFreeSecurityBuffer (_In_ PVOID Buffer)
 Frees an allocated security buffer from UM memory that is been previously allocated by IntAllocateSecurityBuffer function.
 
NTSTATUS IntQueryUserSecurityIdentification (_Out_ PTOKEN_USER *User)
 Queries the authenticated user security identifier (SID) that is associated with the security context of the access token that is being opened.
 
NTSTATUS NTAPI IntAssignDesktopSecurityOnParse (_In_ PWINSTATION_OBJECT WinSta, _In_ PDESKTOP Desktop, _In_ PACCESS_STATE AccessState)
 Assigns a security descriptor to the desktop object during a desktop object parse procedure.
 
NTSTATUS NTAPI IntCreateServiceSecurity (_Out_ PSECURITY_DESCRIPTOR *ServiceSd)
 Creates a security descriptor for the service.
 

Macro Definition Documentation

◆ DESKTOP_ALL_ACCESS

#define DESKTOP_ALL_ACCESS
Value:
#define STANDARD_RIGHTS_REQUIRED
Definition: nt_native.h:63
#define DESKTOP_CREATEWINDOW
Definition: winuser.h:217
#define DESKTOP_ENUMERATE
Definition: winuser.h:218
#define DESKTOP_JOURNALRECORD
Definition: winuser.h:221
#define DESKTOP_JOURNALPLAYBACK
Definition: winuser.h:220
#define DESKTOP_CREATEMENU
Definition: winuser.h:216
#define DESKTOP_WRITEOBJECTS
Definition: winuser.h:224
#define DESKTOP_SWITCHDESKTOP
Definition: winuser.h:223
#define DESKTOP_HOOKCONTROL
Definition: winuser.h:219
#define DESKTOP_READOBJECTS
Definition: winuser.h:222

Definition at line 30 of file security.h.

◆ DESKTOP_EXECUTE

#define DESKTOP_EXECUTE
Value:

Definition at line 27 of file security.h.

◆ DESKTOP_READ

#define DESKTOP_READ
Value:

Definition at line 15 of file security.h.

◆ DESKTOP_WRITE

◆ WINSTA_ACCESS_ALL

#define WINSTA_ACCESS_ALL
Value:
#define WINSTA_ACCESSGLOBALATOMS
Definition: winuser.h:409
#define WINSTA_EXITWINDOWS
Definition: winuser.h:413
#define WINSTA_READATTRIBUTES
Definition: winuser.h:414
#define WINSTA_READSCREEN
Definition: winuser.h:415
#define WINSTA_ENUMERATE
Definition: winuser.h:412
#define WINSTA_ENUMDESKTOPS
Definition: winuser.h:411
#define WINSTA_WRITEATTRIBUTES
Definition: winuser.h:416
#define WINSTA_ACCESSCLIPBOARD
Definition: winuser.h:408
#define WINSTA_CREATEDESKTOP
Definition: winuser.h:410

Definition at line 57 of file security.h.

◆ WINSTA_EXECUTE

#define WINSTA_EXECUTE

◆ WINSTA_READ

#define WINSTA_READ

◆ WINSTA_WRITE

#define WINSTA_WRITE

Function Documentation

◆ IntAllocateSecurityBuffer()

PVOID IntAllocateSecurityBuffer ( _In_ SIZE_T  Length)

Allocates a buffer within UM (user mode) address space area. Such buffer is reserved for security purposes, such as allocating a buffer for a DACL or a security descriptor.

Parameters
[in]LengthThe length of the buffer that has to be allocated, in bytes.
Returns
Returns a pointer to an allocated buffer whose contents are arbitrary. If the function fails, it means no pages are available to reserve for memory allocation for this buffer.

Definition at line 97 of file security.c.

99{
101 PVOID Buffer = NULL;
102
103 /* Allocate the buffer in UM memory space */
104 Status = ZwAllocateVirtualMemory(ZwCurrentProcess(),
105 &Buffer,
106 0,
107 &Length,
110 if (!NT_SUCCESS(Status))
111 {
112 ERR("IntAllocateSecurityBuffer(): Failed to allocate the buffer (Status 0x%08lx)\n", Status);
113 return NULL;
114 }
115
116 return Buffer;
117}
LONG NTSTATUS
Definition: precomp.h:26
#define ERR(fmt,...)
Definition: precomp.h:57
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:25
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define MEM_COMMIT
Definition: nt_native.h:1313
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define ZwCurrentProcess()

Referenced by IntCreateServiceSecurity(), and IntQueryUserSecurityIdentification().

◆ IntAssignDesktopSecurityOnParse()

NTSTATUS NTAPI IntAssignDesktopSecurityOnParse ( _In_ PWINSTATION_OBJECT  WinSta,
_In_ PDESKTOP  Desktop,
_In_ PACCESS_STATE  AccessState 
)

Assigns a security descriptor to the desktop object during a desktop object parse procedure.

Parameters
[in]WinStaA pointer to a window station object, of which such object contains its own security descriptor that will be captured.
[in]DesktopA pointer to a desktop object that is created during a parse procedure.
[in]AccessStateA pointer to an access state structure that describes the progress state of an access in action.
Returns
Returns STATUS_SUCCESS if the function has successfully assigned new security descriptor to the desktop object. A NTSTATUS failure code is returned otherwise.

Definition at line 270 of file security.c.

274{
276 PSECURITY_DESCRIPTOR CapturedDescriptor;
278
279 /*
280 * Capture the security descriptor from
281 * the window station. The window station
282 * in question has a descriptor that is
283 * inheritable and contains desktop access
284 * rights as well.
285 */
287 &CapturedDescriptor,
289 if (!NT_SUCCESS(Status))
290 {
291 ERR("IntAssignDesktopSecurityOnParse(): Failed to capture the security descriptor from window station (Status 0x%08lx)\n", Status);
292 return Status;
293 }
294
295 /* Assign new security to the desktop */
297 CapturedDescriptor,
298 Desktop,
300 if (!NT_SUCCESS(Status))
301 {
302 ERR("IntAssignDesktopSecurityOnParse(): Failed to assign security information to the desktop object (Status 0x%08lx)\n", Status);
303 }
304
305 /* Release the descriptor that we have captured */
306 ObReleaseObjectSecurity(CapturedDescriptor, MemoryAllocated);
307 return Status;
308}
unsigned char BOOLEAN
NTSTATUS NTAPI ObGetObjectSecurity(IN PVOID Object, OUT PSECURITY_DESCRIPTOR *SecurityDescriptor, OUT PBOOLEAN MemoryAllocated)
Definition: obsecure.c:611
VOID NTAPI ObReleaseObjectSecurity(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN BOOLEAN MemoryAllocated)
Definition: obsecure.c:709
NTSTATUS NTAPI ObAssignSecurity(IN PACCESS_STATE AccessState, IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN PVOID Object, IN POBJECT_TYPE Type)
Definition: obsecure.c:550
POBJECT_TYPE ExDesktopObjectType
Definition: win32k.c:22
_Out_ PSECURITY_DESCRIPTOR _Out_ PBOOLEAN MemoryAllocated
Definition: obfuncs.h:24
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:417

Referenced by IntDesktopObjectParse().

◆ IntCaptureCurrentAccessToken()

HANDLE IntCaptureCurrentAccessToken ( VOID  )

◆ IntCreateServiceSecurity()

NTSTATUS NTAPI IntCreateServiceSecurity ( _Out_ PSECURITY_DESCRIPTOR ServiceSd)

Creates a security descriptor for the service.

Parameters
[out]ServiceSdA pointer to a newly allocated and created security descriptor for the service.
Returns
Returns STATUS_SUCCESS if the function has successfully queried created the security descriptor. STATUS_NO_MEMORY is returned if memory allocation for security buffers because of a lack of needed pages to reserve for such allocation. A failure NTSTATUS code is returned otherwise.

Definition at line 327 of file security.c.

329{
331 PACL ServiceDacl;
333 ULONG RelSDSize;
337
338 /* Initialize our local variables */
339 RelSDSize = 0;
340 TokenUser = NULL;
341 RelSD = NULL;
342 ServiceDacl = NULL;
343
344 /* Query the logged in user of the current security context (aka token) */
346 if (!TokenUser)
347 {
348 ERR("IntCreateServiceSecurity(): Failed to query the token user (Status 0x%08lx)\n", Status);
349 return Status;
350 }
351
352 /* Initialize the absolute security descriptor */
354 if (!NT_SUCCESS(Status))
355 {
356 ERR("IntCreateServiceSecurity(): Failed to initialize absolute SD (Status 0x%08lx)\n", Status);
357 goto Quit;
358 }
359
360 /*
361 * Build up the size of access control
362 * list (the DACL) necessary to initialize
363 * our ACL. The first two entry members
364 * of ACL field are the authenticated user
365 * that is associated with the security
366 * context of the token. Then here come
367 * the last two entries which are admins.
368 * Why the ACL contains two ACEs of the
369 * same SID is because of service access
370 * rights and ACE inheritance.
371 *
372 * A service is composed of a default
373 * desktop and window station upon
374 * booting the system. On Windows connection
375 * to such service is being made if no
376 * default window station and desktop handles
377 * were created before. The desktop and winsta
378 * objects grant access on a separate type basis.
379 * The user is granted full access to the window
380 * station first and then full access to the desktop.
381 * After that admins are granted specific rights
382 * separately, just like the user. Ultimately the
383 * ACEs that handle desktop rights management are
384 * inherited to the default desktop object so
385 * that there's no need to have a separate security
386 * descriptor for the desktop object alone.
387 */
388 DaclSize = sizeof(ACL) +
389 sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(TokenUser->User.Sid) +
390 sizeof(ACCESS_ALLOWED_ACE) + RtlLengthSid(TokenUser->User.Sid) +
393
394 /* Allocate memory for service DACL */
395 ServiceDacl = IntAllocateSecurityBuffer(DaclSize);
396 if (!ServiceDacl)
397 {
398 ERR("IntCreateServiceSecurity(): Failed to allocate memory for service DACL!\n");
400 goto Quit;
401 }
402
403 /* Now create the DACL */
404 Status = RtlCreateAcl(ServiceDacl,
405 DaclSize,
407 if (!NT_SUCCESS(Status))
408 {
409 ERR("IntCreateServiceSecurity(): Failed to create service DACL (Status 0x%08lx)\n", Status);
410 goto Quit;
411 }
412
413 /*
414 * The authenticated user is the ultimate and absolute
415 * king in charge of the created (or opened, whatever that is)
416 * window station object.
417 */
418 Status = RtlAddAccessAllowedAceEx(ServiceDacl,
420 0,
422 TokenUser->User.Sid);
423 if (!NT_SUCCESS(Status))
424 {
425 ERR("IntCreateServiceSecurity(): Failed to set up window station ACE for authenticated user (Status 0x%08lx)\n", Status);
426 goto Quit;
427 }
428
429 /*
430 * The authenticated user also has the ultimate power
431 * over the desktop object as well. This ACE cannot
432 * be propagated but inherited. See the comment
433 * above regarding ACL size for further explanation.
434 */
435 Status = RtlAddAccessAllowedAceEx(ServiceDacl,
439 TokenUser->User.Sid);
440 if (!NT_SUCCESS(Status))
441 {
442 ERR("IntCreateServiceSecurity(): Failed to set up desktop ACE for authenticated user (Status 0x%08lx)\n", Status);
443 goto Quit;
444 }
445
446 /*
447 * Administrators can only enumerate window
448 * stations within a desktop.
449 */
450 Status = RtlAddAccessAllowedAceEx(ServiceDacl,
452 0,
455 if (!NT_SUCCESS(Status))
456 {
457 ERR("IntCreateServiceSecurity(): Failed to set up window station ACE for admins (Status 0x%08lx)\n", Status);
458 goto Quit;
459 }
460
461 /*
462 * Administrators have some share of power over
463 * the desktop object. They can enumerate desktops,
464 * write and read upon the object itself.
465 */
466 Status = RtlAddAccessAllowedAceEx(ServiceDacl,
471 if (!NT_SUCCESS(Status))
472 {
473 ERR("IntCreateServiceSecurity(): Failed to set up desktop ACE for admins (Status 0x%08lx)\n", Status);
474 goto Quit;
475 }
476
477 /* Set the DACL to absolute SD */
479 TRUE,
480 ServiceDacl,
481 FALSE);
482 if (!NT_SUCCESS(Status))
483 {
484 ERR("IntCreateServiceSecurity(): Failed to set up service DACL to absolute SD (Status 0x%08lx)\n", Status);
485 goto Quit;
486 }
487
488 /* This descriptor is ownerless */
490 NULL,
491 FALSE);
492 if (!NT_SUCCESS(Status))
493 {
494 ERR("IntCreateServiceSecurity(): Failed to make the absolute SD as ownerless (Status 0x%08lx)\n", Status);
495 goto Quit;
496 }
497
498 /* This descriptor has no primary group */
500 NULL,
501 FALSE);
502 if (!NT_SUCCESS(Status))
503 {
504 ERR("IntCreateServiceSecurity(): Failed to make the absolute SD as having no primary group (Status 0x%08lx)\n", Status);
505 goto Quit;
506 }
507
508 /*
509 * Determine how much size is needed to allocate
510 * memory space for our relative security descriptor.
511 */
513 NULL,
514 &RelSDSize);
516 {
517 ERR("IntCreateServiceSecurity(): Unexpected status code, must be STATUS_BUFFER_TOO_SMALL (Status 0x%08lx)\n", Status);
518 goto Quit;
519 }
520
521 /* Allocate memory for this */
522 RelSD = IntAllocateSecurityBuffer(RelSDSize);
523 if (!RelSD)
524 {
525 ERR("IntCreateServiceSecurity(): Failed to allocate memory pool for relative SD!\n");
527 goto Quit;
528 }
529
530 /* Convert the absolute SD into a relative one now */
532 RelSD,
533 &RelSDSize);
534 if (!NT_SUCCESS(Status))
535 {
536 ERR("IntCreateServiceSecurity(): Failed to convert absolute SD to a relative one (Status 0x%08lx)\n", Status);
537 goto Quit;
538 }
539
540 /* All good, give the SD to the caller */
541 *ServiceSd = RelSD;
542
543Quit:
544 if (ServiceDacl)
545 {
546 IntFreeSecurityBuffer(ServiceDacl);
547 }
548
549 if (TokenUser)
550 {
552 }
553
554 if (!NT_SUCCESS(Status))
555 {
556 if (RelSD)
557 {
559 }
560 }
561
562 return Status;
563}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAceEx(PACL, DWORD, DWORD, DWORD, PSID)
NTSYSAPI NTSTATUS WINAPI RtlSetOwnerSecurityDescriptor(PSECURITY_DESCRIPTOR, PSID, BOOLEAN)
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
#define DESKTOP_ALL_ACCESS
Definition: precomp.h:22
struct _ACL ACL
struct _ACCESS_ALLOWED_ACE ACCESS_ALLOWED_ACE
NTSYSAPI NTSTATUS NTAPI RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG DaclSize
Definition: rtlfuncs.h:1606
NTSYSAPI NTSTATUS NTAPI RtlSetGroupSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN PSID Group, IN BOOLEAN GroupDefaulted)
Definition: sd.c:410
NTSYSAPI NTSTATUS NTAPI RtlAbsoluteToSelfRelativeSD(IN PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor, IN OUT PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor, IN PULONG BufferLength)
Definition: sd.c:626
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
PSE_EXPORTS SeExports
Definition: semgr.c:21
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
PSID SeAliasAdminsSid
Definition: setypes.h:1229
uint32_t ULONG
Definition: typedefs.h:59
NTSTATUS IntQueryUserSecurityIdentification(_Out_ PTOKEN_USER *User)
Queries the authenticated user security identifier (SID) that is associated with the security context...
Definition: security.c:169
PVOID IntAllocateSecurityBuffer(_In_ SIZE_T Length)
Allocates a buffer within UM (user mode) address space area. Such buffer is reserved for security pur...
Definition: security.c:97
VOID IntFreeSecurityBuffer(_In_ PVOID Buffer)
Frees an allocated security buffer from UM memory that is been previously allocated by IntAllocateSec...
Definition: security.c:133
#define WINSTA_ACCESS_ALL
Definition: security.h:57
#define INHERIT_ONLY_ACE
Definition: setypes.h:749
#define OBJECT_INHERIT_ACE
Definition: setypes.h:746
@ TokenUser
Definition: setypes.h:966
#define NO_PROPAGATE_INHERIT_ACE
Definition: setypes.h:748
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define ACL_REVISION
Definition: setypes.h:39

Referenced by IntResolveDesktop().

◆ IntFreeSecurityBuffer()

VOID IntFreeSecurityBuffer ( _In_ PVOID  Buffer)

Frees an allocated security buffer from UM memory that is been previously allocated by IntAllocateSecurityBuffer function.

Parameters
[in]BufferA pointer to a buffer whose contents are arbitrary, to be freed from UM memory space.
Returns
Nothing.

Definition at line 133 of file security.c.

135{
136 SIZE_T Size = 0;
137
138 ZwFreeVirtualMemory(ZwCurrentProcess(),
139 &Buffer,
140 &Size,
142}
#define MEM_RELEASE
Definition: nt_native.h:1316
ULONG_PTR SIZE_T
Definition: typedefs.h:80
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533

Referenced by IntCreateServiceSecurity(), IntQueryUserSecurityIdentification(), and IntResolveDesktop().

◆ IntQueryUserSecurityIdentification()

NTSTATUS IntQueryUserSecurityIdentification ( _Out_ PTOKEN_USER User)

Queries the authenticated user security identifier (SID) that is associated with the security context of the access token that is being opened.

Parameters
[out]UserA pointer to the token user that contains the security identifier of the authenticated user.
Returns
Returns STATUS_SUCCESS if the function has successfully queried the token user. STATUS_UNSUCCESSFUL is returned if the effective token of the caller couldn't be opened. STATUS_NO_MEMORY is returned if memory allocation for token user buffer has failed because of lack of necessary pages reserved for such allocation. A failure NTSTATUS code is returned otherwise.
Remarks
!!!WARNING!!! – THE CALLER WHO QUERIES THE TOKEN USER IS RESPONSIBLE TO FREE THE ALLOCATED TOKEN USER BUFFER THAT IS BEING GIVEN.

Definition at line 169 of file security.c.

171{
173 PTOKEN_USER UserToken = NULL;
176
177 /* Initialize the parameter */
178 *User = NULL;
179
180 /* Open the current token of the caller */
182 if (!Token)
183 {
184 ERR("IntQueryUserSecurityIdentification(): Couldn't capture the token!\n");
185 return STATUS_UNSUCCESSFUL;
186 }
187
188 /*
189 * Since we do not know what the length
190 * of the buffer size should be exactly to
191 * hold the user data, let the function
192 * tell us the size.
193 */
194 Status = ZwQueryInformationToken(Token,
195 TokenUser,
196 NULL,
197 0,
198 &BufferLength);
200 {
201 /*
202 * Allocate some memory for the buffer
203 * based on the size that the function
204 * gave us.
205 */
207 if (!UserToken)
208 {
209 /* Bail out if we failed */
210 ERR("IntQueryUserSecurityIdentification(): Couldn't allocate memory for the token user!\n");
211 ZwClose(Token);
212 return STATUS_NO_MEMORY;
213 }
214 }
215 else if (!NT_SUCCESS(Status))
216 {
217 ERR("IntQueryUserSecurityIdentification(): Failed to query the necessary length for the buffer (Status 0x%08lx)!\n", Status);
218 ZwClose(Token);
219 return Status;
220 }
221
222 /* Query the user now as we have plenty of space to hold it */
223 Status = ZwQueryInformationToken(Token,
224 TokenUser,
225 UserToken,
227 &BufferLength);
228 if (!NT_SUCCESS(Status))
229 {
230 /* We failed, bail out */
231 ERR("IntQueryUserSecurityIdentification(): Failed to query token user (Status 0x%08lx)\n", Status);
232 IntFreeSecurityBuffer(UserToken);
233 ZwClose(Token);
234 return Status;
235 }
236
237 /* All good, give the buffer to the caller and close the captured token */
238 *User = UserToken;
239 ZwClose(Token);
240
241 return STATUS_SUCCESS;
242}
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
HANDLE IntGetCurrentAccessToken(VOID)
Opens an access token that represents the effective security context of the caller....
Definition: security.c:27

Referenced by IntCreateServiceSecurity().