ReactOS  0.4.15-dev-4916-gd519b11
acl.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for acl.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

BOOLEAN NTAPI SepInitDACLs (VOID)
 Initializes known discretionary access control lists in the system upon kernel and Executive initialization procedure. More...
 
NTSTATUS NTAPI SepCreateImpersonationTokenDacl (_In_ PTOKEN Token, _In_ PTOKEN PrimaryToken, _Out_ PACL *Dacl)
 Allocates a discretionary access control list based on certain properties of a regular and primary access tokens. More...
 
NTSTATUS NTAPI SepCaptureAcl (_In_ PACL InputAcl, _In_ KPROCESSOR_MODE AccessMode, _In_ POOL_TYPE PoolType, _In_ BOOLEAN CaptureIfKernel, _Out_ PACL *CapturedAcl)
 Captures an access control list from an already valid input ACL. More...
 
VOID NTAPI SepReleaseAcl (_In_ PACL CapturedAcl, _In_ KPROCESSOR_MODE AccessMode, _In_ BOOLEAN CaptureIfKernel)
 Releases (frees) a captured ACL from the memory pool. More...
 
BOOLEAN SepShouldPropagateAce (_In_ UCHAR AceFlags, _Out_ PUCHAR NewAceFlags, _In_ BOOLEAN IsInherited, _In_ BOOLEAN IsDirectoryObject)
 Determines if a certain ACE can or cannot be propagated based on ACE inheritation flags and whatnot. More...
 
NTSTATUS SepPropagateAcl (_Out_writes_bytes_opt_(AclLength) PACL AclDest, _Inout_ PULONG AclLength, _In_reads_bytes_(AclSource->AclSize) PACL AclSource, _In_ PSID Owner, _In_ PSID Group, _In_ BOOLEAN IsInherited, _In_ BOOLEAN IsDirectoryObject, _In_ PGENERIC_MAPPING GenericMapping)
 Propagates (copies) an access control list. More...
 
PACL SepSelectAcl (_In_opt_ PACL ExplicitAcl, _In_ BOOLEAN ExplicitPresent, _In_ BOOLEAN ExplicitDefaulted, _In_opt_ PACL ParentAcl, _In_opt_ PACL DefaultAcl, _Out_ PULONG AclLength, _In_ PSID Owner, _In_ PSID Group, _Out_ PBOOLEAN AclPresent, _Out_ PBOOLEAN IsInherited, _In_ BOOLEAN IsDirectoryObject, _In_ PGENERIC_MAPPING GenericMapping)
 Selects an ACL and returns it to the caller. More...
 

Variables

PACL SePublicDefaultDacl = NULL
 
PACL SeSystemDefaultDacl = NULL
 
PACL SePublicDefaultUnrestrictedDacl = NULL
 
PACL SePublicOpenDacl = NULL
 
PACL SePublicOpenUnrestrictedDacl = NULL
 
PACL SeUnrestrictedDacl = NULL
 
PACL SeSystemAnonymousLogonDacl = NULL
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 11 of file acl.c.

Function Documentation

◆ SepCaptureAcl()

NTSTATUS NTAPI SepCaptureAcl ( _In_ PACL  InputAcl,
_In_ KPROCESSOR_MODE  AccessMode,
_In_ POOL_TYPE  PoolType,
_In_ BOOLEAN  CaptureIfKernel,
_Out_ PACL CapturedAcl 
)

Captures an access control list from an already valid input ACL.

Parameters
[in]InputAclA valid ACL.
[in]AccessModeProcessor level access mode. The processor mode determines how the input arguments are probed.
[in]PoolTypePool type for new captured ACL for creation. The pool type determines in which memory pool the ACL data should reside.
[in]CaptureIfKernelIf set to TRUE and the processor access mode being KernelMode, we are capturing an ACL directly in the kernel. Otherwise we are capturing within a kernel mode driver.
[out]CapturedAclThe returned and allocated captured ACL.
Returns
Returns STATUS_SUCCESS if the ACL has been successfully captured. STATUS_INSUFFICIENT_RESOURCES is returned otherwise.

Definition at line 352 of file acl.c.

358 {
359  PACL NewAcl;
360  ULONG AclSize;
361 
362  PAGED_CODE();
363 
364  /* If in kernel mode and we do not capture, just
365  * return the given ACL and don't validate it. */
366  if ((AccessMode == KernelMode) && !CaptureIfKernel)
367  {
368  *CapturedAcl = InputAcl;
369  return STATUS_SUCCESS;
370  }
371 
372  /* Otherwise, capture and validate the ACL, depending on the access mode */
373  if (AccessMode != KernelMode)
374  {
375  _SEH2_TRY
376  {
377  ProbeForRead(InputAcl,
378  sizeof(ACL),
379  sizeof(ULONG));
380  AclSize = InputAcl->AclSize;
381  ProbeForRead(InputAcl,
382  AclSize,
383  sizeof(ULONG));
384  }
386  {
387  /* Return the exception code */
389  }
390  _SEH2_END;
391 
392  /* Validate the minimal size an ACL can have */
393  if (AclSize < sizeof(ACL))
394  return STATUS_INVALID_ACL;
395 
397  AclSize,
398  TAG_ACL);
399  if (!NewAcl)
401 
402  _SEH2_TRY
403  {
404  RtlCopyMemory(NewAcl, InputAcl, AclSize);
405  }
407  {
408  /* Free the ACL and return the exception code */
409  ExFreePoolWithTag(NewAcl, TAG_ACL);
411  }
412  _SEH2_END;
413  }
414  else
415  {
416  AclSize = InputAcl->AclSize;
417 
418  /* Validate the minimal size an ACL can have */
419  if (AclSize < sizeof(ACL))
420  return STATUS_INVALID_ACL;
421 
423  AclSize,
424  TAG_ACL);
425  if (!NewAcl)
427 
428  RtlCopyMemory(NewAcl, InputAcl, AclSize);
429  }
430 
431  /* Validate the captured ACL */
432  if (!RtlValidAcl(NewAcl))
433  {
434  /* Free the ACL and fail */
435  ExFreePoolWithTag(NewAcl, TAG_ACL);
436  return STATUS_INVALID_ACL;
437  }
438 
439  /* It's valid, return it */
440  *CapturedAcl = NewAcl;
441  return STATUS_SUCCESS;
442 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_SEH2_TRY
Definition: create.c:4226
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:395
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
BOOLEAN NTAPI RtlValidAcl(IN PACL Acl)
Definition: acl.c:837
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
#define TAG_ACL
Definition: tag.h:148
_SEH2_END
Definition: create.c:4400
#define STATUS_INVALID_ACL
Definition: ntstatus.h:355
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3810
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define PAGED_CODE()

Referenced by NtCreateToken(), and NtSetInformationToken().

◆ SepCreateImpersonationTokenDacl()

NTSTATUS NTAPI SepCreateImpersonationTokenDacl ( _In_ PTOKEN  Token,
_In_ PTOKEN  PrimaryToken,
_Out_ PACL Dacl 
)

Allocates a discretionary access control list based on certain properties of a regular and primary access tokens.

Parameters
[in]TokenAn access token.
[in]PrimaryTokenA primary access token.
[out]DaclThe returned allocated DACL.
Returns
Returns STATUS_SUCCESS if DACL creation from tokens has completed successfully. STATUS_INSUFFICIENT_RESOURCES is returned if DACL allocation from memory pool fails otherwise.

Definition at line 277 of file acl.c.

281 {
283  PACL TokenDacl;
284 
285  PAGED_CODE();
286 
287  *Dacl = NULL;
288 
289  AclLength = sizeof(ACL) +
290  (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) +
291  (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) +
292  (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid)) +
293  (sizeof(ACE) + RtlLengthSid(Token->UserAndGroups->Sid)) +
294  (sizeof(ACE) + RtlLengthSid(PrimaryToken->UserAndGroups->Sid));
295 
297  if (TokenDacl == NULL)
298  {
300  }
301 
302  RtlCreateAcl(TokenDacl, AclLength, ACL_REVISION);
304  Token->UserAndGroups->Sid);
306  PrimaryToken->UserAndGroups->Sid);
311 
312  if (Token->RestrictedSids != NULL || PrimaryToken->RestrictedSids != NULL)
313  {
316  }
317 
318  *Dacl = TokenDacl;
319 
320  return STATUS_SUCCESS;
321 }
#define GENERIC_ALL
Definition: nt_native.h:92
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PSID SeRestrictedCodeSid
Definition: sid.c:40
_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
struct _ACL ACL
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_Out_writes_bytes_to_opt_ AbsoluteSecurityDescriptorSize PSECURITY_DESCRIPTOR _Inout_ PULONG _Out_writes_bytes_to_opt_ DaclSize PACL Dacl
Definition: rtlfuncs.h:1579
PSID SeAliasAdminsSid
Definition: sid.c:41
#define TAG_ACL
Definition: tag.h:148
NTSTATUS NTAPI RtlAddAccessAllowedAce(IN OUT PACL Acl, IN ULONG Revision, IN ACCESS_MASK AccessMask, IN PSID Sid)
Definition: acl.c:262
NTSTATUS NTAPI RtlCreateAcl(IN PACL Acl, IN ULONG AclSize, IN ULONG AclRevision)
Definition: acl.c:677
#define NULL
Definition: types.h:112
#define ACL_REVISION
Definition: setypes.h:39
PSID SeLocalSystemSid
Definition: sid.c:38
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: rtltypes.h:992
_In_ ULONG AclLength
Definition: rtlfuncs.h:1842
#define PAGED_CODE()

Referenced by NtOpenThreadTokenEx().

◆ SepInitDACLs()

BOOLEAN NTAPI SepInitDACLs ( VOID  )

Initializes known discretionary access control lists in the system upon kernel and Executive initialization procedure.

Returns
Returns TRUE if all the DACLs have been successfully initialized, FALSE otherwise.

Definition at line 38 of file acl.c.

39 {
41 
42  /* create PublicDefaultDacl */
43  AclLength = sizeof(ACL) +
44  (sizeof(ACE) + RtlLengthSid(SeWorldSid)) +
45  (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) +
46  (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid));
47 
49  AclLength,
50  TAG_ACL);
52  return FALSE;
53 
55  AclLength,
56  ACL_REVISION);
57 
61  SeWorldSid);
62 
67 
72 
73  /* create PublicDefaultUnrestrictedDacl */
74  AclLength = sizeof(ACL) +
75  (sizeof(ACE) + RtlLengthSid(SeWorldSid)) +
76  (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) +
77  (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) +
79 
81  AclLength,
82  TAG_ACL);
84  return FALSE;
85 
87  AclLength,
88  ACL_REVISION);
89 
93  SeWorldSid);
94 
99 
101  ACL_REVISION,
102  GENERIC_ALL,
104 
106  ACL_REVISION,
109 
110  /* create PublicOpenDacl */
111  AclLength = sizeof(ACL) +
112  (sizeof(ACE) + RtlLengthSid(SeWorldSid)) +
113  (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) +
114  (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid));
115 
117  AclLength,
118  TAG_ACL);
119  if (SePublicOpenDacl == NULL)
120  return FALSE;
121 
123  AclLength,
124  ACL_REVISION);
125 
127  ACL_REVISION,
129  SeWorldSid);
130 
132  ACL_REVISION,
133  GENERIC_ALL,
135 
137  ACL_REVISION,
138  GENERIC_ALL,
140 
141  /* create PublicOpenUnrestrictedDacl */
142  AclLength = sizeof(ACL) +
143  (sizeof(ACE) + RtlLengthSid(SeWorldSid)) +
144  (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) +
145  (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid)) +
146  (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid));
147 
149  AclLength,
150  TAG_ACL);
152  return FALSE;
153 
155  AclLength,
156  ACL_REVISION);
157 
159  ACL_REVISION,
160  GENERIC_ALL,
161  SeWorldSid);
162 
164  ACL_REVISION,
165  GENERIC_ALL,
167 
169  ACL_REVISION,
170  GENERIC_ALL,
172 
174  ACL_REVISION,
177 
178  /* create SystemDefaultDacl */
179  AclLength = sizeof(ACL) +
180  (sizeof(ACE) + RtlLengthSid(SeLocalSystemSid)) +
181  (sizeof(ACE) + RtlLengthSid(SeAliasAdminsSid));
182 
184  AclLength,
185  TAG_ACL);
186  if (SeSystemDefaultDacl == NULL)
187  return FALSE;
188 
190  AclLength,
191  ACL_REVISION);
192 
194  ACL_REVISION,
195  GENERIC_ALL,
197 
199  ACL_REVISION,
202 
203  /* create UnrestrictedDacl */
204  AclLength = sizeof(ACL) +
205  (sizeof(ACE) + RtlLengthSid(SeWorldSid)) +
206  (sizeof(ACE) + RtlLengthSid(SeRestrictedCodeSid));
207 
209  AclLength,
210  TAG_ACL);
211  if (SeUnrestrictedDacl == NULL)
212  return FALSE;
213 
215  AclLength,
216  ACL_REVISION);
217 
219  ACL_REVISION,
220  GENERIC_ALL,
221  SeWorldSid);
222 
224  ACL_REVISION,
227 
228  /* create SystemAnonymousLogonDacl */
229  AclLength = sizeof(ACL) +
230  (sizeof(ACE) + RtlLengthSid(SeWorldSid)) +
231  (sizeof(ACE) + RtlLengthSid(SeAnonymousLogonSid));
232 
234  AclLength,
235  TAG_ACL);
237  return FALSE;
238 
240  AclLength,
241  ACL_REVISION);
242 
244  ACL_REVISION,
245  GENERIC_ALL,
246  SeWorldSid);
247 
249  ACL_REVISION,
250  GENERIC_ALL,
252 
253  return TRUE;
254 }
#define GENERIC_ALL
Definition: nt_native.h:92
PSID SeRestrictedCodeSid
Definition: sid.c:40
#define TRUE
Definition: types.h:120
PACL SeSystemDefaultDacl
Definition: acl.c:17
PACL SePublicOpenDacl
Definition: acl.c:19
PACL SeSystemAnonymousLogonDacl
Definition: acl.c:22
PACL SePublicOpenUnrestrictedDacl
Definition: acl.c:20
#define FALSE
Definition: types.h:117
PACL SeUnrestrictedDacl
Definition: acl.c:21
#define GENERIC_WRITE
Definition: nt_native.h:90
struct _ACL ACL
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
#define READ_CONTROL
Definition: nt_native.h:58
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
PSID SeAliasAdminsSid
Definition: sid.c:41
PACL SePublicDefaultUnrestrictedDacl
Definition: acl.c:18
#define GENERIC_READ
Definition: compat.h:135
PSID SeWorldSid
Definition: sid.c:25
#define TAG_ACL
Definition: tag.h:148
PACL SePublicDefaultDacl
Definition: acl.c:16
NTSTATUS NTAPI RtlAddAccessAllowedAce(IN OUT PACL Acl, IN ULONG Revision, IN ACCESS_MASK AccessMask, IN PSID Sid)
Definition: acl.c:262
NTSTATUS NTAPI RtlCreateAcl(IN PACL Acl, IN ULONG AclSize, IN ULONG AclRevision)
Definition: acl.c:677
#define NULL
Definition: types.h:112
#define ACL_REVISION
Definition: setypes.h:39
PSID SeLocalSystemSid
Definition: sid.c:38
unsigned int ULONG
Definition: retypes.h:1
PSID SeAnonymousLogonSid
Definition: se.h:203
#define GENERIC_EXECUTE
Definition: nt_native.h:91
Definition: rtltypes.h:992
_In_ ULONG AclLength
Definition: rtlfuncs.h:1842

Referenced by SepInitializationPhase0().

◆ SepPropagateAcl()

NTSTATUS SepPropagateAcl ( _Out_writes_bytes_opt_(AclLength) PACL  AclDest,
_Inout_ PULONG  AclLength,
_In_reads_bytes_(AclSource->AclSize) PACL  AclSource,
_In_ PSID  Owner,
_In_ PSID  Group,
_In_ BOOLEAN  IsInherited,
_In_ BOOLEAN  IsDirectoryObject,
_In_ PGENERIC_MAPPING  GenericMapping 
)

Propagates (copies) an access control list.

Parameters
[out]AclDestThe destination parameter with propagated ACL.
[in,out]AclLengthThe length of the ACL that we propagate.
[in]AclSourceThe source instance of a valid ACL.
[in]OwnerA SID that represents the main user that identifies the ACL.
[in]GroupA SID that represents a group that identifies the ACL.
[in]IsInheritedIf set to TRUE, that means the ACL is directly inherited.
[in]IsDirectoryObjectIf set to TRUE, that means the ACL is directly inherited because of the object that inherits it.
[in]GenericMappingGeneric mapping of access rights to map only certain effective ACEs.
Returns
Returns STATUS_SUCCESS if ACL has been propagated successfully. STATUS_BUFFER_TOO_SMALL is returned if the ACL length is not greater than the maximum written size of the buffer for ACL propagation otherwise.

Definition at line 587 of file acl.c.

596 {
598  PACCESS_ALLOWED_ACE AceSource;
599  PACCESS_ALLOWED_ACE AceDest;
600  PUCHAR CurrentDest;
601  PUCHAR CurrentSource;
602  ULONG i;
603  ULONG Written;
604  UCHAR AceFlags;
605  USHORT AceSize;
606  USHORT AceCount = 0;
607  PSID Sid;
608  BOOLEAN WriteTwoAces;
609 
610  ASSERT(RtlValidAcl(AclSource));
611  ASSERT(AclSource->AclSize % sizeof(ULONG) == 0);
612  ASSERT(AclSource->Sbz1 == 0);
613  ASSERT(AclSource->Sbz2 == 0);
614 
615  Written = 0;
616  if (*AclLength >= Written + sizeof(ACL))
617  {
618  RtlCopyMemory(AclDest,
619  AclSource,
620  sizeof(ACL));
621  }
622  Written += sizeof(ACL);
623 
624  CurrentDest = (PUCHAR)(AclDest + 1);
625  CurrentSource = (PUCHAR)(AclSource + 1);
626  for (i = 0; i < AclSource->AceCount; i++)
627  {
628  ASSERT((ULONG_PTR)CurrentDest % sizeof(ULONG) == 0);
629  ASSERT((ULONG_PTR)CurrentSource % sizeof(ULONG) == 0);
630  AceDest = (PACCESS_ALLOWED_ACE)CurrentDest;
631  AceSource = (PACCESS_ALLOWED_ACE)CurrentSource;
632 
633  if (AceSource->Header.AceType > ACCESS_MAX_MS_V2_ACE_TYPE)
634  {
635  /* FIXME: handle object & compound ACEs */
636  AceSize = AceSource->Header.AceSize;
637 
638  if (*AclLength >= Written + AceSize)
639  {
640  RtlCopyMemory(AceDest, AceSource, AceSize);
641  }
642  CurrentDest += AceSize;
643  CurrentSource += AceSize;
644  Written += AceSize;
645  AceCount++;
646  continue;
647  }
648 
649  /* These all have the same structure */
651  AceSource->Header.AceType == ACCESS_DENIED_ACE_TYPE ||
652  AceSource->Header.AceType == SYSTEM_AUDIT_ACE_TYPE ||
653  AceSource->Header.AceType == SYSTEM_ALARM_ACE_TYPE);
654 
655  ASSERT(AceSource->Header.AceSize % sizeof(ULONG) == 0);
656  ASSERT(AceSource->Header.AceSize >= sizeof(*AceSource));
657  if (!SepShouldPropagateAce(AceSource->Header.AceFlags,
658  &AceFlags,
659  IsInherited,
661  {
662  CurrentSource += AceSource->Header.AceSize;
663  continue;
664  }
665 
666  /* FIXME: filter out duplicate ACEs */
667  AceSize = AceSource->Header.AceSize;
668  Mask = AceSource->Mask;
669  Sid = (PSID)&AceSource->SidStart;
670  ASSERT(AceSize >= FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + RtlLengthSid(Sid));
671 
672  WriteTwoAces = FALSE;
673  /* Map effective ACE to specific rights */
674  if (!(AceFlags & INHERIT_ONLY_ACE))
675  {
678 
679  if (IsInherited)
680  {
682  Sid = Owner;
683  else if (RtlEqualSid(Sid, SeCreatorGroupSid))
684  Sid = Group;
685  AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + RtlLengthSid(Sid);
686 
687  /*
688  * A generic container ACE becomes two ACEs:
689  * - a specific effective ACE with no inheritance flags
690  * - an inherit-only ACE that keeps the generic rights
691  */
692  if (IsDirectoryObject &&
694  (Mask != AceSource->Mask || Sid != (PSID)&AceSource->SidStart))
695  {
696  WriteTwoAces = TRUE;
697  }
698  }
699  }
700 
701  while (1)
702  {
703  if (*AclLength >= Written + AceSize)
704  {
705  AceDest->Header.AceType = AceSource->Header.AceType;
706  AceDest->Header.AceFlags = WriteTwoAces ? AceFlags & ~VALID_INHERIT_FLAGS
707  : AceFlags;
708  AceDest->Header.AceSize = AceSize;
709  AceDest->Mask = Mask;
710  RtlCopySid(AceSize - FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart),
711  (PSID)&AceDest->SidStart,
712  Sid);
713  }
714  Written += AceSize;
715 
716  AceCount++;
717  CurrentDest += AceSize;
718 
719  if (!WriteTwoAces)
720  break;
721 
722  /* Second ACE keeps all the generics from the source ACE */
723  WriteTwoAces = FALSE;
724  AceDest = (PACCESS_ALLOWED_ACE)CurrentDest;
725  AceSize = AceSource->Header.AceSize;
726  Mask = AceSource->Mask;
727  Sid = (PSID)&AceSource->SidStart;
729  }
730 
731  CurrentSource += AceSource->Header.AceSize;
732  }
733 
734  if (*AclLength >= sizeof(ACL))
735  {
736  AclDest->AceCount = AceCount;
737  AclDest->AclSize = Written;
738  }
739 
740  if (Written > *AclLength)
741  {
742  *AclLength = Written;
744  }
745  *AclLength = Written;
746  return STATUS_SUCCESS;
747 }
UCHAR AceFlags
Definition: ms-dtyp.idl:211
#define ACCESS_MAX_MS_V2_ACE_TYPE
Definition: setypes.h:721
#define VALID_INHERIT_FLAGS
Definition: setypes.h:751
#define TRUE
Definition: types.h:120
_In_opt_ PSECURITY_DESCRIPTOR _Out_ PSECURITY_DESCRIPTOR _In_ BOOLEAN IsDirectoryObject
Definition: sefuncs.h:29
_In_opt_ PSID Group
Definition: rtlfuncs.h:1632
unsigned char * PUCHAR
Definition: retypes.h:3
ACE_HEADER Header
Definition: ms-dtyp.idl:216
BOOLEAN SepShouldPropagateAce(_In_ UCHAR AceFlags, _Out_ PUCHAR NewAceFlags, _In_ BOOLEAN IsInherited, _In_ BOOLEAN IsDirectoryObject)
Determines if a certain ACE can or cannot be propagated based on ACE inheritation flags and whatnot.
Definition: acl.c:503
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
uint32_t ULONG_PTR
Definition: typedefs.h:65
USHORT AceSize
Definition: ms-dtyp.idl:212
#define FALSE
Definition: types.h:117
PSID SeCreatorGroupSid
Definition: sid.c:28
unsigned char BOOLEAN
struct _ACL ACL
_In_ ULONG _In_ ACCESS_MASK _In_ PSID Sid
Definition: rtlfuncs.h:1130
NTSYSAPI ULONG NTAPI RtlLengthSid(IN PSID Sid)
Definition: sid.c:150
#define CONTAINER_INHERIT_ACE
Definition: setypes.h:747
#define ASSERT(a)
Definition: mode.c:44
BOOLEAN NTAPI RtlValidAcl(IN PACL Acl)
Definition: acl.c:837
#define ACCESS_ALLOWED_ACE_TYPE
Definition: setypes.h:717
#define ACCESS_DENIED_ACE_TYPE
Definition: setypes.h:718
struct _SID * PSID
Definition: eventlog.c:35
unsigned char UCHAR
Definition: xmlstorage.h:181
UCHAR AceType
Definition: ms-dtyp.idl:210
PSID SeCreatorOwnerSid
Definition: sid.c:27
NTSYSAPI BOOLEAN WINAPI RtlCopySid(DWORD, PSID, PSID)
processorSet Mask
static GENERIC_MAPPING GenericMapping
Definition: SeInheritance.c:11
#define SYSTEM_ALARM_ACE_TYPE
Definition: setypes.h:720
struct _ACCESS_ALLOWED_ACE * PACCESS_ALLOWED_ACE
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
ACCESS_MASK Mask
Definition: ms-dtyp.idl:217
unsigned short USHORT
Definition: pedump.c:61
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
_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:1583
unsigned int ULONG
Definition: retypes.h:1
#define SYSTEM_AUDIT_ACE_TYPE
Definition: setypes.h:719
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define INHERIT_ONLY_ACE
Definition: setypes.h:749
#define STATUS_SUCCESS
Definition: shellext.h:65
ACCESS_MASK GenericAll
Definition: nt_native.h:568
ULONG ACCESS_MASK
Definition: nt_native.h:40
_In_ ULONG AclLength
Definition: rtlfuncs.h:1842
NTSYSAPI VOID NTAPI RtlMapGenericMask(PACCESS_MASK AccessMask, PGENERIC_MAPPING GenericMapping)
NTSYSAPI BOOLEAN NTAPI RtlEqualSid(_In_ PSID Sid1, _In_ PSID Sid2)
static const ACEFLAG AceFlags[]
Definition: security.c:2423

Referenced by SepSelectAcl().

◆ SepReleaseAcl()

VOID NTAPI SepReleaseAcl ( _In_ PACL  CapturedAcl,
_In_ KPROCESSOR_MODE  AccessMode,
_In_ BOOLEAN  CaptureIfKernel 
)

Releases (frees) a captured ACL from the memory pool.

Parameters
[in]CapturedAclA valid captured ACL to free.
[in]AccessModeProcessor level access mode.
[in]CaptureIfKernelIf set to TRUE and the processor access mode being KernelMode, we're releasing an ACL directly in the kernel. Otherwise we're releasing within a kernel mode driver.
Returns
Nothing.

Definition at line 464 of file acl.c.

468 {
469  PAGED_CODE();
470 
471  if (CapturedAcl != NULL &&
472  (AccessMode != KernelMode ||
473  (AccessMode == KernelMode && CaptureIfKernel)))
474  {
475  ExFreePoolWithTag(CapturedAcl, TAG_ACL);
476  }
477 }
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:395
#define TAG_ACL
Definition: tag.h:148
#define NULL
Definition: types.h:112
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define PAGED_CODE()

Referenced by NtCreateToken(), and NtSetInformationToken().

◆ SepSelectAcl()

PACL SepSelectAcl ( _In_opt_ PACL  ExplicitAcl,
_In_ BOOLEAN  ExplicitPresent,
_In_ BOOLEAN  ExplicitDefaulted,
_In_opt_ PACL  ParentAcl,
_In_opt_ PACL  DefaultAcl,
_Out_ PULONG  AclLength,
_In_ PSID  Owner,
_In_ PSID  Group,
_Out_ PBOOLEAN  AclPresent,
_Out_ PBOOLEAN  IsInherited,
_In_ BOOLEAN  IsDirectoryObject,
_In_ PGENERIC_MAPPING  GenericMapping 
)

Selects an ACL and returns it to the caller.

Parameters
[in]ExplicitAclIf specified, the specified ACL to the call will be the selected ACL for the caller.
[in]ExplicitPresentIf set to TRUE and with specific ACL filled to the call, the function will immediately return the specific ACL as the selected ACL for the caller.
[in]ExplicitDefaultedIf set to FALSE and with specific ACL filled to the call, the ACL is not a default ACL. Otherwise it's a default ACL that we cannot select it as is.
[in]ParentAclIf specified, the parent ACL will be used to determine the exact ACL length to check if the ACL in question is not empty. If the list is not empty then the function will select such ACL to the caller.
[in]DefaultAclIf specified, the default ACL will be the selected one for the caller.
[out]AclLengthThe size length of an ACL.
[in]OwnerA SID that represents the main user that identifies the ACL.
[in]GroupA SID that represents a group that identifies the ACL.
[out]AclPresentThe returned boolean value, indicating if the ACL that we want to select does actually exist.
[out]IsInheritedThe returned boolean value, indicating if the ACL we want to select it is actually inherited or not.
[in]IsDirectoryObjectIf set to TRUE, the object inherits this ACL.
[in]GenericMappingGeneric mapping of access rights to map only certain effective ACEs of an ACL that we want to select it.
Returns
Returns the selected access control list (ACL) to the caller, NULL otherwise.

Definition at line 804 of file acl.c.

817 {
818  PACL Acl;
820 
821  *AclPresent = TRUE;
822  if (ExplicitPresent && !ExplicitDefaulted)
823  {
824  Acl = ExplicitAcl;
825  }
826  else
827  {
828  if (ParentAcl)
829  {
830  *IsInherited = TRUE;
831  *AclLength = 0;
833  AclLength,
834  ParentAcl,
835  Owner,
836  Group,
837  *IsInherited,
841 
842  /* Use the parent ACL only if it's not empty */
843  if (*AclLength != sizeof(ACL))
844  return ParentAcl;
845  }
846 
847  if (ExplicitPresent)
848  {
849  Acl = ExplicitAcl;
850  }
851  else if (DefaultAcl)
852  {
853  Acl = DefaultAcl;
854  }
855  else
856  {
857  *AclPresent = FALSE;
858  Acl = NULL;
859  }
860  }
861 
862  *IsInherited = FALSE;
863  *AclLength = 0;
864  if (Acl)
865  {
866  /* Get the length */
868  AclLength,
869  Acl,
870  Owner,
871  Group,
872  *IsInherited,
876  }
877  return Acl;
878 }
#define TRUE
Definition: types.h:120
_In_opt_ PSECURITY_DESCRIPTOR _Out_ PSECURITY_DESCRIPTOR _In_ BOOLEAN IsDirectoryObject
Definition: sefuncs.h:29
_In_opt_ PSID Group
Definition: rtlfuncs.h:1632
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define FALSE
Definition: types.h:117
Status
Definition: gdiplustypes.h:24
#define ASSERT(a)
Definition: mode.c:44
NTSTATUS SepPropagateAcl(_Out_writes_bytes_opt_(AclLength) PACL AclDest, _Inout_ PULONG AclLength, _In_reads_bytes_(AclSource->AclSize) PACL AclSource, _In_ PSID Owner, _In_ PSID Group, _In_ BOOLEAN IsInherited, _In_ BOOLEAN IsDirectoryObject, _In_ PGENERIC_MAPPING GenericMapping)
Propagates (copies) an access control list.
Definition: acl.c:587
static GENERIC_MAPPING GenericMapping
Definition: SeInheritance.c:11
_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:1583
#define NULL
Definition: types.h:112
_In_ ULONG AclLength
Definition: rtlfuncs.h:1842

◆ SepShouldPropagateAce()

BOOLEAN SepShouldPropagateAce ( _In_ UCHAR  AceFlags,
_Out_ PUCHAR  NewAceFlags,
_In_ BOOLEAN  IsInherited,
_In_ BOOLEAN  IsDirectoryObject 
)

Determines if a certain ACE can or cannot be propagated based on ACE inheritation flags and whatnot.

Parameters
[in]AceFlagsBit flags of an ACE to perform propagation checks.
[out]NewAceFlagsNew ACE bit blags based on the specific ACE flags of the first argument parameter.
[in]IsInheritedIf set to TRUE, an ACE is deemed as directly inherited from another instance. In that case we're allowed to propagate.
[in]IsDirectoryObjectIf set to TRUE, an object directly inherits this ACE so we can propagate it.
Returns
Returns TRUE if an ACE can be propagated, FALSE otherwise.

Definition at line 503 of file acl.c.

508 {
509  if (!IsInherited)
510  {
511  *NewAceFlags = AceFlags;
512  return TRUE;
513  }
514 
515  if (!IsDirectoryObject)
516  {
518  {
519  *NewAceFlags = AceFlags & ~VALID_INHERIT_FLAGS;
520  return TRUE;
521  }
522  return FALSE;
523  }
524 
526  {
528  {
529  *NewAceFlags = AceFlags & ~VALID_INHERIT_FLAGS;
530  return TRUE;
531  }
532  return FALSE;
533  }
534 
536  {
538  return TRUE;
539  }
540 
542  {
544  return TRUE;
545  }
546 
547  return FALSE;
548 }
#define VALID_INHERIT_FLAGS
Definition: setypes.h:751
#define TRUE
Definition: types.h:120
_In_opt_ PSECURITY_DESCRIPTOR _Out_ PSECURITY_DESCRIPTOR _In_ BOOLEAN IsDirectoryObject
Definition: sefuncs.h:29
#define NO_PROPAGATE_INHERIT_ACE
Definition: setypes.h:748
#define FALSE
Definition: types.h:117
#define CONTAINER_INHERIT_ACE
Definition: setypes.h:747
#define INHERIT_ONLY_ACE
Definition: setypes.h:749
#define OBJECT_INHERIT_ACE
Definition: setypes.h:746
static const ACEFLAG AceFlags[]
Definition: security.c:2423

Referenced by SepPropagateAcl().

Variable Documentation

◆ SePublicDefaultDacl

PACL SePublicDefaultDacl = NULL

Definition at line 16 of file acl.c.

Referenced by IopCreateSecurityDescriptorPerType(), SepInitDACLs(), and SepInitSDs().

◆ SePublicDefaultUnrestrictedDacl

PACL SePublicDefaultUnrestrictedDacl = NULL

◆ SePublicOpenDacl

PACL SePublicOpenDacl = NULL

Definition at line 19 of file acl.c.

Referenced by IopCreateSecurityDescriptorPerType(), SepInitDACLs(), and SepInitSDs().

◆ SePublicOpenUnrestrictedDacl

PACL SePublicOpenUnrestrictedDacl = NULL

Definition at line 20 of file acl.c.

Referenced by IopCreateSecurityDescriptorPerType(), SepInitDACLs(), and SepInitSDs().

◆ SeSystemAnonymousLogonDacl

PACL SeSystemAnonymousLogonDacl = NULL

◆ SeSystemDefaultDacl

PACL SeSystemDefaultDacl = NULL

◆ SeUnrestrictedDacl

PACL SeUnrestrictedDacl = NULL

Definition at line 21 of file acl.c.

Referenced by SepInitDACLs(), and SepInitSDs().