ReactOS 0.4.16-dev-340-g0540c21
sd.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for sd.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

BOOLEAN NTAPI SepInitSDs (VOID)
 Initializes the known security descriptors in the system.
 
NTSTATUS NTAPI SeSetWorldSecurityDescriptor (_In_ SECURITY_INFORMATION SecurityInformation, _In_ PISECURITY_DESCRIPTOR SecurityDescriptor, _In_ PULONG BufferLength)
 Sets a "World" security descriptor.
 
static ULONG DetermineSIDSize (_In_ PISID Sid, _Inout_ PULONG OutSAC, _In_ KPROCESSOR_MODE ProcessorMode)
 Determines the size of a SID.
 
static ULONG DetermineACLSize (_In_ PACL Acl, _In_ KPROCESSOR_MODE ProcessorMode)
 Determines the size of an ACL.
 
NTSTATUS NTAPI SeCaptureSecurityDescriptor (_In_ PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, _In_ KPROCESSOR_MODE CurrentMode, _In_ POOL_TYPE PoolType, _In_ BOOLEAN CaptureIfKernel, _Out_ PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor)
 Captures a security descriptor.
 
 _IRQL_requires_max_ (PASSIVE_LEVEL)
 Queries information details about a security descriptor.
 
NTSTATUS NTAPI SeReleaseSecurityDescriptor (_In_ PSECURITY_DESCRIPTOR CapturedSecurityDescriptor, _In_ KPROCESSOR_MODE CurrentMode, _In_ BOOLEAN CaptureIfKernelMode)
 Releases a captured security descriptor buffer.
 
BOOLEAN NTAPI SeValidSecurityDescriptor (_In_ ULONG Length, _In_ PSECURITY_DESCRIPTOR _SecurityDescriptor)
 Determines if a security descriptor is valid according to the general security requirements and conditions set by the kernel.
 

Variables

PSECURITY_DESCRIPTOR SePublicDefaultSd = NULL
 
PSECURITY_DESCRIPTOR SePublicDefaultUnrestrictedSd = NULL
 
PSECURITY_DESCRIPTOR SePublicOpenSd = NULL
 
PSECURITY_DESCRIPTOR SePublicOpenUnrestrictedSd = NULL
 
PSECURITY_DESCRIPTOR SeSystemDefaultSd = NULL
 
PSECURITY_DESCRIPTOR SeUnrestrictedSd = NULL
 
PSECURITY_DESCRIPTOR SeSystemAnonymousLogonSd = NULL
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 11 of file sd.c.

Function Documentation

◆ _IRQL_requires_max_()

_IRQL_requires_max_ ( PASSIVE_LEVEL  )

Queries information details about a security descriptor.

Computes the quota size of a security descriptor.

Assigns a security descriptor for a new object.

An extended function that assigns a security descriptor for a new object.

Frees a security descriptor.

An extended function that sets new information data to a security descriptor.

Modifies some information data about a security descriptor.

Parameters
[in]SecurityInformationSecurity information details to be queried from a security descriptor.
[out]SecurityDescriptorThe returned security descriptor with security information data.
[in,out]LengthThe returned length of a security descriptor.
[in,out]ObjectsSecurityDescriptorThe returned object security descriptor.
Returns
Returns STATUS_SUCCESS if the operations have been completed successfully and that the specific information about the security descriptor has been queried. STATUS_BUFFER_TOO_SMALL is returned if the buffer size is too small to contain the queried info about the security descriptor.
Parameters
[in]ObjectIf specified, the function will use this arbitrary object that points to an object security descriptor.
[in]SecurityInformationSecurity information details to be set.
[in]SecurityDescriptorA security descriptor where its info is to be changed.
[in,out]ObjectsSecurityDescriptorThe returned pointer to security descriptor objects.
[in]PoolTypePool type for the new security descriptor to allocate.
[in]GenericMappingThe generic mapping of access rights masks.
Returns
See SeSetSecurityDescriptorInfoEx.
Parameters
[in]ObjectIf specified, the function will use this arbitrary object that points to an object security descriptor.
[in]SecurityInformationSecurity information details to be set.
[in]SecurityDescriptorA security descriptor where its info is to be changed.
[in,out]ObjectsSecurityDescriptorThe returned pointer to security descriptor objects.
[in]AutoInheritFlagsFlags bitmask inheritation, influencing how the security descriptor can be inherited and if it can be in the first place.
[in]PoolTypePool type for the new security descriptor to allocate.
[in]GenericMappingThe generic mapping of access rights masks.
Returns
Returns STATUS_SUCCESS if the operations have been completed without problems and that new info has been set to the security descriptor. STATUS_NO_SECURITY_ON_OBJECT is returned if the object does not have a security descriptor. STATUS_INSUFFICIENT_RESOURCES is returned if memory pool allocation for the new security descriptor with new info set has failed.
Parameters
[in]SecurityDescriptorA security descriptor to be freed from memory.
Returns
Returns STATUS_SUCCESS.
Parameters
[in]_ParentDescriptorA security descriptor of the parent object that is being created.
[in]_ExplicitDescriptorAn explicit security descriptor that is applied to a new object.
[out]NewDescriptorThe new allocated security descriptor.
[in]ObjectTypeThe type of the new object.
[in]IsDirectoryObjectSet this to TRUE if the newly created object is a directory object, otherwise set this to FALSE.
[in]AutoInheritFlagsAutomatic inheritance flags that influence how access control entries within ACLs from security descriptors are inherited.
[in]SubjectContextSecurity subject context of the new object.
[in]GenericMappingGeneric mapping of access mask rights.
[in]PoolTypeThis parameter is unused.
Returns
Returns STATUS_SUCCESS if the operations have been completed successfully and that the security descriptor has been assigned to the new object. STATUS_NO_TOKEN is returned if the caller hasn't supplied a valid argument to a security subject context. STATUS_INVALID_OWNER is returned if the caller hasn't supplied a parent descriptor that belongs to the main user (owner). STATUS_INVALID_PRIMARY_GROUP is returned by the same reason as with the previous NTSTATUS code. The two NTSTATUS codes are returned if the calling thread stated that the owner and/or group is defaulted to the parent descriptor (SEF_DEFAULT_OWNER_FROM_PARENT and/or SEF_DEFAULT_GROUP_FROM_PARENT respectively). STATUS_INSUFFICIENT_RESOURCES is returned if memory pool allocation for the descriptor buffer has failed. A failure NTSTATUS is returned otherwise.
Parameters
[in]ParentDescriptorA security descriptor of the parent object that is being created.
[in]ExplicitDescriptorAn explicit security descriptor that is applied to a new object.
[out]NewDescriptorThe new allocated security descriptor.
[in]IsDirectoryObjectSet this to TRUE if the newly created object is a directory object, otherwise set this to FALSE.
[in]SubjectContextSecurity subject context of the new object.
[in]GenericMappingGeneric mapping of access mask rights.
[in]PoolTypeThis parameter is unused.
Returns
See SeAssignSecurityEx.
Parameters
[in]SecurityDescriptorA security descriptor.
[out]QuotaInfoSizeThe returned quota size of the given security descriptor to the caller. The function may return 0 to this parameter if the descriptor doesn't have a group or a discretionary access control list (DACL) even.
Returns
Returns STATUS_SUCCESS if the quota size of a security descriptor has been computed successfully. STATUS_UNKNOWN_REVISION is returned if the security descriptor has an invalid revision.

Definition at line 596 of file sd.c.

604{
605 PISECURITY_DESCRIPTOR ObjectSd;
607 PSID Owner = NULL;
608 PSID Group = NULL;
609 PACL Dacl = NULL;
610 PACL Sacl = NULL;
611 ULONG OwnerLength = 0;
612 ULONG GroupLength = 0;
613 ULONG DaclLength = 0;
614 ULONG SaclLength = 0;
616 ULONG_PTR Current;
617 ULONG SdLength;
618
619 PAGED_CODE();
620
622
623 if (*ObjectsSecurityDescriptor == NULL)
624 {
626 {
629 }
630
634 return STATUS_SUCCESS;
635 }
636
637 ObjectSd = *ObjectsSecurityDescriptor;
638
639 /* Calculate the required security descriptor length */
642 {
644 if (Owner != NULL)
645 {
646 OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
647 Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED);
648 }
649 }
650
652 {
654 if (Group != NULL)
655 {
657 Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED);
658 }
659 }
660
662 (ObjectSd->Control & SE_DACL_PRESENT))
663 {
664 Dacl = SepGetDaclFromDescriptor(ObjectSd);
665 if (Dacl != NULL)
666 {
667 DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4);
668 }
669
671 }
672
674 (ObjectSd->Control & SE_SACL_PRESENT))
675 {
676 Sacl = SepGetSaclFromDescriptor(ObjectSd);
677 if (Sacl != NULL)
678 {
679 SaclLength = ROUND_UP(Sacl->AclSize, 4);
680 }
681
683 }
684
685 SdLength = OwnerLength + GroupLength + DaclLength +
686 SaclLength + sizeof(SECURITY_DESCRIPTOR_RELATIVE);
687 if (*Length < SdLength)
688 {
689 *Length = SdLength;
691 }
692
693 /* Build the new security descrtiptor */
696 RelSD->Control = Control;
697
698 Current = (ULONG_PTR)(RelSD + 1);
699
700 if (OwnerLength != 0)
701 {
702 RtlCopyMemory((PVOID)Current,
703 Owner,
704 OwnerLength);
705 RelSD->Owner = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
706 Current += OwnerLength;
707 }
708
709 if (GroupLength != 0)
710 {
711 RtlCopyMemory((PVOID)Current,
712 Group,
714 RelSD->Group = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
715 Current += GroupLength;
716 }
717
718 if (DaclLength != 0)
719 {
720 RtlCopyMemory((PVOID)Current,
721 Dacl,
722 DaclLength);
723 RelSD->Dacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
724 Current += DaclLength;
725 }
726
727 if (SaclLength != 0)
728 {
729 RtlCopyMemory((PVOID)Current,
730 Sacl,
731 SaclLength);
732 RelSD->Sacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
733 Current += SaclLength;
734 }
735
736 *Length = SdLength;
737
738 return STATUS_SUCCESS;
739}
#define PAGED_CODE()
#define NULL
Definition: types.h:112
#define ULONG_PTR
Definition: config.h:101
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ SECURITY_INFORMATION SecurityInformation
Definition: fltkernel.h:1340
WORD SECURITY_DESCRIPTOR_CONTROL
Definition: lsa.idl:37
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1605
_In_opt_ PSID Group
Definition: rtlfuncs.h:1658
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID Owner
Definition: rtlfuncs.h:1609
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL Sacl
Definition: rtlfuncs.h:1607
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptorRelative(_Out_ PISECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor, _In_ ULONG Revision)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
FORCEINLINE PSID SepGetOwnerFromDescriptor(_Inout_ PSECURITY_DESCRIPTOR _Descriptor)
Definition: se.h:109
FORCEINLINE PSID SepGetGroupFromDescriptor(_Inout_ PSECURITY_DESCRIPTOR _Descriptor)
Definition: se.h:89
FORCEINLINE PACL SepGetDaclFromDescriptor(_Inout_ PSECURITY_DESCRIPTOR _Descriptor)
Definition: se.h:129
FORCEINLINE PACL SepGetSaclFromDescriptor(_Inout_ PSECURITY_DESCRIPTOR _Descriptor)
Definition: se.h:151
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
SECURITY_DESCRIPTOR_CONTROL Control
Definition: setypes.h:839
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDF_WMI_PROVIDER_CONTROL Control
Definition: wdfwmi.h:166
_In_ ULONG _In_ CONST SOCKADDR _In_ int GroupLength
Definition: ws2tcpip.h:712
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:191
#define SE_OWNER_DEFAULTED
Definition: setypes.h:819
#define DACL_SECURITY_INFORMATION
Definition: setypes.h:125
#define SE_DACL_DEFAULTED
Definition: setypes.h:822
#define OWNER_SECURITY_INFORMATION
Definition: setypes.h:123
struct _SECURITY_DESCRIPTOR_RELATIVE * PISECURITY_DESCRIPTOR_RELATIVE
#define SE_SELF_RELATIVE
Definition: setypes.h:834
#define SE_SACL_DEFAULTED
Definition: setypes.h:824
struct _SECURITY_DESCRIPTOR_RELATIVE SECURITY_DESCRIPTOR_RELATIVE
#define SE_SACL_PRESENT
Definition: setypes.h:823
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define GROUP_SECURITY_INFORMATION
Definition: setypes.h:124
#define SE_GROUP_DEFAULTED
Definition: setypes.h:820
#define SACL_SECURITY_INFORMATION
Definition: setypes.h:126
#define SE_DACL_PRESENT
Definition: setypes.h:821

◆ DetermineACLSize()

static ULONG DetermineACLSize ( _In_ PACL  Acl,
_In_ KPROCESSOR_MODE  ProcessorMode 
)
static

Determines the size of an ACL.

Parameters
[in]AclAn access control list where its size is to be determined.
[in]ProcessorModeProcessor level access mode.
Returns
Returns the size length of a an access control list (ACL).

Definition at line 336 of file sd.c.

339{
340 ULONG Size;
341
342 if (!Acl) return 0;
343
344 if (ProcessorMode == KernelMode) return Acl->AclSize;
345
346 /* Probe the buffers! */
347 Size = ProbeForReadUshort(&Acl->AclSize);
348 ProbeForRead(Acl, Size, sizeof(ULONG));
349
350 return Size;
351}
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
#define KernelMode
Definition: asm.h:34
#define ProbeForReadUshort(Ptr)
Definition: probe.h:63
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533

Referenced by SeCaptureSecurityDescriptor().

◆ DetermineSIDSize()

static ULONG DetermineSIDSize ( _In_ PISID  Sid,
_Inout_ PULONG  OutSAC,
_In_ KPROCESSOR_MODE  ProcessorMode 
)
static

Determines the size of a SID.

Parameters
[in]SidA security identifier where its size is to be determined.
[in,out]OutSACThe returned sub authority count of the security identifier.
[in]ProcessorModeProcessor level access mode.
Returns
Returns the size length of a security identifier (SID).

Definition at line 290 of file sd.c.

294{
295 ULONG Size;
296
297 if (!Sid)
298 {
299 *OutSAC = 0;
300 return 0;
301 }
302
303 if (ProcessorMode != KernelMode)
304 {
305 /* Securely access the buffers! */
307 Size = RtlLengthRequiredSid(*OutSAC);
308 ProbeForRead(Sid, Size, sizeof(ULONG));
309 }
310 else
311 {
312 *OutSAC = Sid->SubAuthorityCount;
313 Size = RtlLengthRequiredSid(*OutSAC);
314 }
315
316 return Size;
317}
NTSYSAPI ULONG NTAPI RtlLengthRequiredSid(IN ULONG SubAuthorityCount)
Definition: sid.c:54
_In_ ULONG _In_ ACCESS_MASK _In_ PSID Sid
Definition: rtlfuncs.h:1145
#define ProbeForReadUchar(Ptr)
Definition: probe.h:61
BYTE SubAuthorityCount
Definition: ms-dtyp.idl:200

Referenced by SeCaptureSecurityDescriptor().

◆ SeCaptureSecurityDescriptor()

NTSTATUS NTAPI SeCaptureSecurityDescriptor ( _In_ PSECURITY_DESCRIPTOR  _OriginalSecurityDescriptor,
_In_ KPROCESSOR_MODE  CurrentMode,
_In_ POOL_TYPE  PoolType,
_In_ BOOLEAN  CaptureIfKernel,
_Out_ PSECURITY_DESCRIPTOR CapturedSecurityDescriptor 
)

Captures a security descriptor.

Parameters
[in]_OriginalSecurityDescriptorAn already existing and valid security descriptor to be captured.
[in]CurrentModeProcessor level access mode.
[in]PoolTypePool type to be used when allocating the captured buffer.
[in]CaptureIfKernelSet this to TRUE if capturing is done within the kernel.
[out]CapturedSecurityDescriptorThe captured security descriptor.
Returns
Returns STATUS_SUCCESS if the operations have been completed successfully and that the security descriptor has been captured. STATUS_UNKNOWN_REVISION is returned if the security descriptor has an unknown revision. STATUS_INSUFFICIENT_RESOURCES is returned if memory pool allocation for the captured buffer has failed. A failure NTSTATUS code is returned otherwise.

Definition at line 386 of file sd.c.

392{
393 PISECURITY_DESCRIPTOR OriginalDescriptor = _OriginalSecurityDescriptor;
394 SECURITY_DESCRIPTOR DescriptorCopy;
396 ULONG OwnerSAC = 0, GroupSAC = 0;
397 ULONG OwnerSize = 0, GroupSize = 0;
398 ULONG SaclSize = 0, DaclSize = 0;
401
402 if (!OriginalDescriptor)
403 {
404 /* Nothing to do... */
405 *CapturedSecurityDescriptor = NULL;
406 return STATUS_SUCCESS;
407 }
408
409 /* Quick path */
410 if (CurrentMode == KernelMode && !CaptureIfKernel)
411 {
412 /* Check descriptor version */
413 if (OriginalDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
414 {
416 }
417
418 *CapturedSecurityDescriptor = _OriginalSecurityDescriptor;
419 return STATUS_SUCCESS;
420 }
421
423 {
424 if (CurrentMode != KernelMode)
425 {
426 ProbeForRead(OriginalDescriptor,
428 sizeof(ULONG));
429 }
430
431 /* Check the descriptor version */
432 if (OriginalDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
433 {
435 }
436
437 if (CurrentMode != KernelMode)
438 {
439 /* Get the size of the descriptor */
440 DescriptorSize = (OriginalDescriptor->Control & SE_SELF_RELATIVE) ?
442
443 /* Probe the entire security descriptor structure. The SIDs
444 * and ACLs will be probed and copied later though */
445 ProbeForRead(OriginalDescriptor, DescriptorSize, sizeof(ULONG));
446 }
447
448 /* Now capture all fields and convert to an absolute descriptor */
449 DescriptorCopy.Revision = OriginalDescriptor->Revision;
450 DescriptorCopy.Sbz1 = OriginalDescriptor->Sbz1;
451 DescriptorCopy.Control = OriginalDescriptor->Control & ~SE_SELF_RELATIVE;
452 DescriptorCopy.Owner = SepGetOwnerFromDescriptor(OriginalDescriptor);
453 DescriptorCopy.Group = SepGetGroupFromDescriptor(OriginalDescriptor);
454 DescriptorCopy.Sacl = SepGetSaclFromDescriptor(OriginalDescriptor);
455 DescriptorCopy.Dacl = SepGetDaclFromDescriptor(OriginalDescriptor);
457
458 /* Determine owner and group sizes */
459 OwnerSize = DetermineSIDSize(DescriptorCopy.Owner, &OwnerSAC, CurrentMode);
461 GroupSize = DetermineSIDSize(DescriptorCopy.Group, &GroupSAC, CurrentMode);
462 DescriptorSize += ROUND_UP(GroupSize, sizeof(ULONG));
463
464 /* Determine the size of the ACLs */
465 if (DescriptorCopy.Control & SE_SACL_PRESENT)
466 {
467 /* Get the size and probe if user mode */
468 SaclSize = DetermineACLSize(DescriptorCopy.Sacl, CurrentMode);
470 }
471
472 if (DescriptorCopy.Control & SE_DACL_PRESENT)
473 {
474 /* Get the size and probe if user mode */
475 DaclSize = DetermineACLSize(DescriptorCopy.Dacl, CurrentMode);
477 }
478 }
480 {
482 }
483 _SEH2_END;
484
485 /*
486 * Allocate enough memory to store a complete copy of a self-relative
487 * security descriptor
488 */
491 TAG_SD);
493
495 NewDescriptor->Revision = DescriptorCopy.Revision;
496 NewDescriptor->Sbz1 = DescriptorCopy.Sbz1;
497 NewDescriptor->Control = DescriptorCopy.Control | SE_SELF_RELATIVE;
498
500 {
501 /*
502 * Setup the offsets and copy the SIDs and ACLs to the new
503 * self-relative security descriptor. Probing the pointers is not
504 * neccessary anymore as we did that when collecting the sizes!
505 * Make sure to validate the SIDs and ACLs *again* as they could have
506 * been modified in the meanwhile!
507 */
509
510 if (DescriptorCopy.Owner)
511 {
512 if (!RtlValidSid(DescriptorCopy.Owner)) RtlRaiseStatus(STATUS_INVALID_SID);
515 DescriptorCopy.Owner,
516 OwnerSize);
517 Offset += ROUND_UP(OwnerSize, sizeof(ULONG));
518 }
519
520 if (DescriptorCopy.Group)
521 {
522 if (!RtlValidSid(DescriptorCopy.Group)) RtlRaiseStatus(STATUS_INVALID_SID);
525 DescriptorCopy.Group,
526 GroupSize);
527 Offset += ROUND_UP(GroupSize, sizeof(ULONG));
528 }
529
530 if (DescriptorCopy.Sacl)
531 {
532 if (!RtlValidAcl(DescriptorCopy.Sacl)) RtlRaiseStatus(STATUS_INVALID_ACL);
535 DescriptorCopy.Sacl,
536 SaclSize);
537 Offset += ROUND_UP(SaclSize, sizeof(ULONG));
538 }
539
540 if (DescriptorCopy.Dacl)
541 {
542 if (!RtlValidAcl(DescriptorCopy.Dacl)) RtlRaiseStatus(STATUS_INVALID_ACL);
545 DescriptorCopy.Dacl,
546 DaclSize);
547 Offset += ROUND_UP(DaclSize, sizeof(ULONG));
548 }
549
550 /* Make sure the size was correct */
552 }
554 {
555 /* We failed to copy the data to the new descriptor */
558 }
559 _SEH2_END;
560
561 /*
562 * We're finally done!
563 * Copy the pointer to the captured descriptor to to the caller.
564 */
565 *CapturedSecurityDescriptor = NewDescriptor;
566 return STATUS_SUCCESS;
567}
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
struct _SECURITY_DESCRIPTOR SECURITY_DESCRIPTOR
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ OwnerSize PSID _Inout_ PULONG OwnerSize
Definition: rtlfuncs.h:1610
NTSYSAPI BOOLEAN NTAPI RtlValidAcl(PACL Acl)
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG _Out_writes_bytes_to_opt_ SaclSize PACL _Inout_ PULONG SaclSize
Definition: rtlfuncs.h:1608
NTSYSAPI BOOLEAN NTAPI RtlValidSid(IN PSID Sid)
Definition: sid.c:21
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL _Inout_ PULONG DaclSize
Definition: rtlfuncs.h:1606
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
static ULONG DetermineSIDSize(_In_ PISID Sid, _Inout_ PULONG OutSAC, _In_ KPROCESSOR_MODE ProcessorMode)
Determines the size of a SID.
Definition: sd.c:290
static ULONG DetermineACLSize(_In_ PACL Acl, _In_ KPROCESSOR_MODE ProcessorMode)
Determines the size of an ACL.
Definition: sd.c:336
#define STATUS_UNKNOWN_REVISION
Definition: ntstatus.h:324
#define STATUS_INVALID_ACL
Definition: ntstatus.h:355
#define STATUS_INVALID_SID
Definition: ntstatus.h:356
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
_In_ SIZE_T DescriptorSize
Definition: nls.c:40
#define TAG_SD
Definition: tag.h:153
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
unsigned char * PUCHAR
Definition: typedefs.h:53
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3815
_In_opt_ PSECURITY_DESCRIPTOR _Out_ PSECURITY_DESCRIPTOR * NewDescriptor
Definition: sefuncs.h:30
#define SECURITY_DESCRIPTOR_REVISION1
Definition: setypes.h:59

Referenced by NtOpenObjectAuditAlarm(), NtSetSecurityObject(), ObpCaptureObjectCreateInformation(), ProbeAndCaptureObjectAttributes(), SepAccessCheck(), and SepAccessCheckAndAuditAlarm().

◆ SepInitSDs()

BOOLEAN NTAPI SepInitSDs ( VOID  )

Initializes the known security descriptors in the system.

Returns
Returns TRUE if all the security descriptors have been initialized, FALSE otherwise.

Definition at line 37 of file sd.c.

38{
39 /* Create PublicDefaultSd */
43 return FALSE;
44
48 TRUE,
50 FALSE);
51
52 /* Create PublicDefaultUnrestrictedSd */
56 return FALSE;
57
61 TRUE,
63 FALSE);
64
65 /* Create PublicOpenSd */
68 if (SePublicOpenSd == NULL)
69 return FALSE;
70
74 TRUE,
76 FALSE);
77
78 /* Create PublicOpenUnrestrictedSd */
82 return FALSE;
83
87 TRUE,
89 FALSE);
90
91 /* Create SystemDefaultSd */
95 return FALSE;
96
100 TRUE,
102 FALSE);
103
104 /* Create UnrestrictedSd */
106 sizeof(SECURITY_DESCRIPTOR), TAG_SD);
107 if (SeUnrestrictedSd == NULL)
108 return FALSE;
109
113 TRUE,
115 FALSE);
116
117 /* Create SystemAnonymousLogonSd */
119 sizeof(SECURITY_DESCRIPTOR), TAG_SD);
121 return FALSE;
122
126 TRUE,
128 FALSE);
129
130 return TRUE;
131}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define PagedPool
Definition: env_spec_w32.h:308
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
PACL SePublicOpenDacl
Definition: acl.c:19
PACL SePublicDefaultUnrestrictedDacl
Definition: acl.c:18
PACL SeSystemAnonymousLogonDacl
Definition: acl.c:22
PACL SePublicOpenUnrestrictedDacl
Definition: acl.c:20
PACL SeUnrestrictedDacl
Definition: acl.c:21
PACL SePublicDefaultDacl
Definition: acl.c:16
PACL SeSystemDefaultDacl
Definition: acl.c:17
PSECURITY_DESCRIPTOR SeSystemDefaultSd
Definition: sd.c:20
PSECURITY_DESCRIPTOR SePublicOpenUnrestrictedSd
Definition: sd.c:19
PSECURITY_DESCRIPTOR SePublicOpenSd
Definition: sd.c:18
PSECURITY_DESCRIPTOR SeUnrestrictedSd
Definition: sd.c:21
PSECURITY_DESCRIPTOR SePublicDefaultSd
Definition: sd.c:16
PSECURITY_DESCRIPTOR SeSystemAnonymousLogonSd
Definition: sd.c:22
PSECURITY_DESCRIPTOR SePublicDefaultUnrestrictedSd
Definition: sd.c:17

Referenced by SepInitializationPhase0().

◆ SeReleaseSecurityDescriptor()

NTSTATUS NTAPI SeReleaseSecurityDescriptor ( _In_ PSECURITY_DESCRIPTOR  CapturedSecurityDescriptor,
_In_ KPROCESSOR_MODE  CurrentMode,
_In_ BOOLEAN  CaptureIfKernelMode 
)

Releases a captured security descriptor buffer.

Parameters
[in]CapturedSecurityDescriptorThe captured security descriptor to be freed.
[in]CurrentModeProcessor level access mode.
[in]CaptureIfKernelModeSet this to TRUE if the releasing is to be done within the kernel.
Returns
Returns STATUS_SUCCESS.

Definition at line 760 of file sd.c.

764{
765 PAGED_CODE();
766
767 /*
768 * WARNING! You need to call this function with the same value for CurrentMode
769 * and CaptureIfKernelMode that you previously passed to
770 * SeCaptureSecurityDescriptor() in order to avoid memory leaks!
771 */
772 if (CapturedSecurityDescriptor != NULL &&
773 (CurrentMode != KernelMode ||
774 (CurrentMode == KernelMode && CaptureIfKernelMode)))
775 {
776 /* Only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */
777 ExFreePoolWithTag(CapturedSecurityDescriptor, TAG_SD);
778 }
779
780 return STATUS_SUCCESS;
781}

Referenced by NtOpenObjectAuditAlarm(), NtSetSecurityObject(), ObInsertObject(), ObpReleaseObjectCreateInformation(), ReleaseCapturedObjectAttributes(), SepAccessCheck(), and SepAccessCheckAndAuditAlarm().

◆ SeSetWorldSecurityDescriptor()

NTSTATUS NTAPI SeSetWorldSecurityDescriptor ( _In_ SECURITY_INFORMATION  SecurityInformation,
_In_ PISECURITY_DESCRIPTOR  SecurityDescriptor,
_In_ PULONG  BufferLength 
)

Sets a "World" security descriptor.

Parameters
[in]SecurityInformationSecurity information details, alongside with the security descriptor to set the World SD.
[in]SecurityDescriptorA security descriptor buffer.
[in]BufferLengthLength size of the buffer.
Returns
Returns STATUS_SUCCESS if the World security descriptor has been set. STATUS_ACCESS_DENIED is returned if the caller hasn't provided security information details thus the SD cannot be set.

Definition at line 155 of file sd.c.

159{
160 ULONG Current;
161 ULONG SidSize;
162 ULONG SdSize;
165
166 DPRINT("SeSetWorldSecurityDescriptor() called\n");
167
168 if (SecurityInformation == 0)
169 {
171 }
172
173 /* calculate the minimum size of the buffer */
174 SidSize = RtlLengthSid(SeWorldSid);
175 SdSize = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
177 SdSize += SidSize;
179 SdSize += SidSize;
181 {
182 SdSize += sizeof(ACL) + sizeof(ACE) + SidSize;
183 }
185 {
186 SdSize += sizeof(ACL) + sizeof(ACE) + SidSize;
187 }
188
189 if (*BufferLength < SdSize)
190 {
191 *BufferLength = SdSize;
193 }
194
195 *BufferLength = SdSize;
196
199 if (!NT_SUCCESS(Status))
200 {
201 return Status;
202 }
203
204 Current = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
205
207 {
208 RtlCopyMemory((PUCHAR)SdRel + Current, SeWorldSid, SidSize);
209 SdRel->Owner = Current;
210 Current += SidSize;
211 }
212
214 {
215 RtlCopyMemory((PUCHAR)SdRel + Current, SeWorldSid, SidSize);
216 SdRel->Group = Current;
217 Current += SidSize;
218 }
219
221 {
222 PACL Dacl = (PACL)((PUCHAR)SdRel + Current);
223
225 sizeof(ACL) + sizeof(ACE) + SidSize,
227 if (!NT_SUCCESS(Status))
228 return Status;
229
233 SeWorldSid);
234 if (!NT_SUCCESS(Status))
235 return Status;
236
237 SdRel->Control |= SE_DACL_PRESENT;
238 SdRel->Dacl = Current;
239 Current += SidSize;
240 }
241
243 {
244 PACL Sacl = (PACL)((PUCHAR)SdRel + Current);
245
247 sizeof(ACL) + sizeof(ACE) + SidSize,
249 if (!NT_SUCCESS(Status))
250 return Status;
251
256 TRUE,
257 TRUE);
258 if (!NT_SUCCESS(Status))
259 return Status;
260
261 SdRel->Control |= SE_SACL_PRESENT;
262 SdRel->Sacl = Current;
263 Current += SidSize;
264 }
265
266 return STATUS_SUCCESS;
267}
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:25
NTSYSAPI NTSTATUS WINAPI RtlAddAccessAllowedAce(PACL, DWORD, DWORD, PSID)
struct _ACL ACL
struct _ACL * PACL
Definition: security.c:105
NTSYSAPI NTSTATUS NTAPI RtlCreateAcl(PACL Acl, ULONG AclSize, ULONG AclRevision)
NTSYSAPI NTSTATUS NTAPI RtlAddAuditAccessAce(_Inout_ PACL Acl, _In_ ULONG Revision, _In_ ACCESS_MASK AccessMask, _In_ PSID Sid, _In_ BOOLEAN Success, _In_ BOOLEAN Failure)
#define ACCESS_SYSTEM_SECURITY
Definition: nt_native.h:77
#define STANDARD_RIGHTS_ALL
Definition: nt_native.h:69
#define GENERIC_ALL
Definition: nt_native.h:92
PSID SeWorldSid
Definition: sid.c:25
#define DPRINT
Definition: sndvol32.h:73
Definition: rtltypes.h:993
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
#define ACL_REVISION
Definition: setypes.h:39

Referenced by IopGetSetSecurityObject().

◆ SeValidSecurityDescriptor()

BOOLEAN NTAPI SeValidSecurityDescriptor ( _In_ ULONG  Length,
_In_ PSECURITY_DESCRIPTOR  _SecurityDescriptor 
)

Determines if a security descriptor is valid according to the general security requirements and conditions set by the kernel.

Parameters
[in]LengthThe length of a security descriptor.
[in]_SecurityDescriptorA security descriptor where its properties are to be checked for validity.
Returns
Returns TRUE if the given security descriptor is valid, FALSE otherwise.

Definition at line 1027 of file sd.c.

1030{
1031 ULONG SdLength;
1032 PISID Sid;
1033 PACL Acl;
1035
1037 {
1038 DPRINT1("Invalid Security Descriptor revision\n");
1039 return FALSE;
1040 }
1041
1043 {
1044 DPRINT1("Invalid Security Descriptor revision\n");
1045 return FALSE;
1046 }
1047
1048 if (!(SecurityDescriptor->Control & SE_SELF_RELATIVE))
1049 {
1050 DPRINT1("No self-relative Security Descriptor\n");
1051 return FALSE;
1052 }
1053
1054 SdLength = sizeof(SECURITY_DESCRIPTOR);
1055
1056 /* Check Owner SID */
1057 if (!SecurityDescriptor->Owner)
1058 {
1059 DPRINT1("No Owner SID\n");
1060 return FALSE;
1061 }
1062
1063 if (SecurityDescriptor->Owner % sizeof(ULONG))
1064 {
1065 DPRINT1("Invalid Owner SID alignment\n");
1066 return FALSE;
1067 }
1068
1069 /* Ensure the Owner SID is within the bounds of the security descriptor */
1070 if ((SecurityDescriptor->Owner > Length) ||
1071 (Length - SecurityDescriptor->Owner < sizeof(SID)))
1072 {
1073 DPRINT1("Owner SID not within bounds\n");
1074 return FALSE;
1075 }
1076
1077 /* Reference it */
1079 if (Sid->Revision != SID_REVISION)
1080 {
1081 DPRINT1("Invalid Owner SID revision\n");
1082 return FALSE;
1083 }
1084
1085 // NOTE: Same as SeLengthSid(Sid); but doesn't use hardcoded values.
1086 SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG));
1087 if (Length < SdLength)
1088 {
1089 DPRINT1("Invalid Owner SID size\n");
1090 return FALSE;
1091 }
1092
1093 /* Check Group SID */
1094 if (SecurityDescriptor->Group)
1095 {
1096 if (SecurityDescriptor->Group % sizeof(ULONG))
1097 {
1098 DPRINT1("Invalid Group SID alignment\n");
1099 return FALSE;
1100 }
1101
1102 /* Ensure the Group SID is within the bounds of the security descriptor */
1103 if ((SecurityDescriptor->Group > Length) ||
1104 (Length - SecurityDescriptor->Group < sizeof(SID)))
1105 {
1106 DPRINT1("Group SID not within bounds\n");
1107 return FALSE;
1108 }
1109
1110 /* Reference it */
1112 if (Sid->Revision != SID_REVISION)
1113 {
1114 DPRINT1("Invalid Group SID revision\n");
1115 return FALSE;
1116 }
1117
1118 // NOTE: Same as SeLengthSid(Sid); but doesn't use hardcoded values.
1119 SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG));
1120 if (Length < SdLength)
1121 {
1122 DPRINT1("Invalid Group SID size\n");
1123 return FALSE;
1124 }
1125 }
1126
1127 /* Check DACL */
1128 if (SecurityDescriptor->Dacl)
1129 {
1130 if (SecurityDescriptor->Dacl % sizeof(ULONG))
1131 {
1132 DPRINT1("Invalid DACL alignment\n");
1133 return FALSE;
1134 }
1135
1136 /* Ensure the DACL is within the bounds of the security descriptor */
1137 if ((SecurityDescriptor->Dacl > Length) ||
1138 (Length - SecurityDescriptor->Dacl < sizeof(ACL)))
1139 {
1140 DPRINT1("DACL not within bounds\n");
1141 return FALSE;
1142 }
1143
1144 /* Reference it */
1146
1147 SdLength += Acl->AclSize;
1148 if (Length < SdLength)
1149 {
1150 DPRINT1("Invalid DACL size\n");
1151 return FALSE;
1152 }
1153
1154 if (!RtlValidAcl(Acl))
1155 {
1156 DPRINT1("Invalid DACL\n");
1157 return FALSE;
1158 }
1159 }
1160
1161 /* Check SACL */
1162 if (SecurityDescriptor->Sacl)
1163 {
1164 if (SecurityDescriptor->Sacl % sizeof(ULONG))
1165 {
1166 DPRINT1("Invalid SACL alignment\n");
1167 return FALSE;
1168 }
1169
1170 /* Ensure the SACL is within the bounds of the security descriptor */
1171 if ((SecurityDescriptor->Sacl > Length) ||
1172 (Length - SecurityDescriptor->Sacl < sizeof(ACL)))
1173 {
1174 DPRINT1("SACL not within bounds\n");
1175 return FALSE;
1176 }
1177
1178 /* Reference it */
1180
1181 SdLength += Acl->AclSize;
1182 if (Length < SdLength)
1183 {
1184 DPRINT1("Invalid SACL size\n");
1185 return FALSE;
1186 }
1187
1188 if (!RtlValidAcl(Acl))
1189 {
1190 DPRINT1("Invalid SACL\n");
1191 return FALSE;
1192 }
1193 }
1194
1195 return TRUE;
1196}
#define DPRINT1
Definition: precomp.h:8
struct _SID * PSID
Definition: eventlog.c:35
struct _SID SID
USHORT AclSize
Definition: ms-dtyp.idl:296
BYTE Revision
Definition: ms-dtyp.idl:199
#define SECURITY_DESCRIPTOR_MIN_LENGTH
Definition: setypes.h:815
struct _SID * PISID
#define SID_REVISION
Definition: setypes.h:481

Variable Documentation

◆ SePublicDefaultSd

PSECURITY_DESCRIPTOR SePublicDefaultSd = NULL

◆ SePublicDefaultUnrestrictedSd

PSECURITY_DESCRIPTOR SePublicDefaultUnrestrictedSd = NULL

Definition at line 17 of file sd.c.

Referenced by ExpCreateSystemRootLink(), ObInitSystem(), and SepInitSDs().

◆ SePublicOpenSd

PSECURITY_DESCRIPTOR SePublicOpenSd = NULL

Definition at line 18 of file sd.c.

Referenced by SepInitSDs().

◆ SePublicOpenUnrestrictedSd

PSECURITY_DESCRIPTOR SePublicOpenUnrestrictedSd = NULL

Definition at line 19 of file sd.c.

Referenced by SepInitSDs().

◆ SeSystemAnonymousLogonSd

PSECURITY_DESCRIPTOR SeSystemAnonymousLogonSd = NULL

Definition at line 22 of file sd.c.

Referenced by SepInitSDs().

◆ SeSystemDefaultSd

PSECURITY_DESCRIPTOR SeSystemDefaultSd = NULL

Definition at line 20 of file sd.c.

Referenced by SepInitSDs().

◆ SeUnrestrictedSd

PSECURITY_DESCRIPTOR SeUnrestrictedSd = NULL

Definition at line 21 of file sd.c.

Referenced by SepInitSDs().