2008-03-09 14:11:42 +00:00
/*
2023-03-07 17:39:46 +00:00
* PROJECT : ReactOS Kernel
* LICENSE : GPL - 2.0 - or - later ( https : //spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE : Security Identifier ( SID ) implementation support and handling
* COPYRIGHT : Copyright David Welch < welch @ cwcom . net >
1999-12-26 15:50:53 +00:00
*/
2008-04-23 20:38:37 +00:00
/* INCLUDES *******************************************************************/
1999-12-26 15:50:53 +00:00
2005-01-04 22:44:50 +00:00
# include <ntoskrnl.h>
# define NDEBUG
2008-04-23 20:38:37 +00:00
# include <debug.h>
1999-12-26 15:50:53 +00:00
2008-04-23 20:38:37 +00:00
/* GLOBALS ********************************************************************/
2002-02-20 20:16:49 +00:00
2021-09-26 09:42:00 +00:00
# define SE_MAXIMUM_GROUP_LIMIT 0x1000
2002-02-20 20:16:49 +00:00
SID_IDENTIFIER_AUTHORITY SeNullSidAuthority = { SECURITY_NULL_SID_AUTHORITY } ;
SID_IDENTIFIER_AUTHORITY SeWorldSidAuthority = { SECURITY_WORLD_SID_AUTHORITY } ;
SID_IDENTIFIER_AUTHORITY SeLocalSidAuthority = { SECURITY_LOCAL_SID_AUTHORITY } ;
SID_IDENTIFIER_AUTHORITY SeCreatorSidAuthority = { SECURITY_CREATOR_SID_AUTHORITY } ;
SID_IDENTIFIER_AUTHORITY SeNtSidAuthority = { SECURITY_NT_AUTHORITY } ;
PSID SeNullSid = NULL ;
PSID SeWorldSid = NULL ;
PSID SeLocalSid = NULL ;
PSID SeCreatorOwnerSid = NULL ;
PSID SeCreatorGroupSid = NULL ;
PSID SeCreatorOwnerServerSid = NULL ;
PSID SeCreatorGroupServerSid = NULL ;
PSID SeNtAuthoritySid = NULL ;
PSID SeDialupSid = NULL ;
PSID SeNetworkSid = NULL ;
PSID SeBatchSid = NULL ;
PSID SeInteractiveSid = NULL ;
PSID SeServiceSid = NULL ;
PSID SePrincipalSelfSid = NULL ;
PSID SeLocalSystemSid = NULL ;
PSID SeAuthenticatedUserSid = NULL ;
PSID SeRestrictedCodeSid = NULL ;
PSID SeAliasAdminsSid = NULL ;
PSID SeAliasUsersSid = NULL ;
PSID SeAliasGuestsSid = NULL ;
PSID SeAliasPowerUsersSid = NULL ;
PSID SeAliasAccountOpsSid = NULL ;
PSID SeAliasSystemOpsSid = NULL ;
PSID SeAliasPrintOpsSid = NULL ;
PSID SeAliasBackupOpsSid = NULL ;
2005-08-01 09:05:20 +00:00
PSID SeAuthenticatedUsersSid = NULL ;
PSID SeRestrictedSid = NULL ;
PSID SeAnonymousLogonSid = NULL ;
2014-02-18 17:51:45 +00:00
PSID SeLocalServiceSid = NULL ;
PSID SeNetworkServiceSid = NULL ;
2002-02-20 20:16:49 +00:00
2021-11-09 20:34:36 +00:00
typedef struct _SID_VALIDATE
{
UCHAR SubAuthorityCount ;
PISID ProbeSid ;
} SID_VALIDATE , * PSID_VALIDATE ;
2008-04-23 20:38:37 +00:00
/* FUNCTIONS ******************************************************************/
2002-02-20 20:16:49 +00:00
2021-08-11 14:24:45 +00:00
/**
* @ brief
* Frees all the known initialized SIDs in the system from the memory .
*
* @ return
* Nothing .
*/
2009-09-02 13:07:12 +00:00
VOID
NTAPI
FreeInitializedSids ( VOID )
{
2011-06-01 13:39:36 +00:00
if ( SeNullSid ) ExFreePoolWithTag ( SeNullSid , TAG_SID ) ;
if ( SeWorldSid ) ExFreePoolWithTag ( SeWorldSid , TAG_SID ) ;
if ( SeLocalSid ) ExFreePoolWithTag ( SeLocalSid , TAG_SID ) ;
if ( SeCreatorOwnerSid ) ExFreePoolWithTag ( SeCreatorOwnerSid , TAG_SID ) ;
if ( SeCreatorGroupSid ) ExFreePoolWithTag ( SeCreatorGroupSid , TAG_SID ) ;
if ( SeCreatorOwnerServerSid ) ExFreePoolWithTag ( SeCreatorOwnerServerSid , TAG_SID ) ;
if ( SeCreatorGroupServerSid ) ExFreePoolWithTag ( SeCreatorGroupServerSid , TAG_SID ) ;
if ( SeNtAuthoritySid ) ExFreePoolWithTag ( SeNtAuthoritySid , TAG_SID ) ;
if ( SeDialupSid ) ExFreePoolWithTag ( SeDialupSid , TAG_SID ) ;
if ( SeNetworkSid ) ExFreePoolWithTag ( SeNetworkSid , TAG_SID ) ;
if ( SeBatchSid ) ExFreePoolWithTag ( SeBatchSid , TAG_SID ) ;
if ( SeInteractiveSid ) ExFreePoolWithTag ( SeInteractiveSid , TAG_SID ) ;
if ( SeServiceSid ) ExFreePoolWithTag ( SeServiceSid , TAG_SID ) ;
if ( SePrincipalSelfSid ) ExFreePoolWithTag ( SePrincipalSelfSid , TAG_SID ) ;
if ( SeLocalSystemSid ) ExFreePoolWithTag ( SeLocalSystemSid , TAG_SID ) ;
if ( SeAuthenticatedUserSid ) ExFreePoolWithTag ( SeAuthenticatedUserSid , TAG_SID ) ;
if ( SeRestrictedCodeSid ) ExFreePoolWithTag ( SeRestrictedCodeSid , TAG_SID ) ;
if ( SeAliasAdminsSid ) ExFreePoolWithTag ( SeAliasAdminsSid , TAG_SID ) ;
if ( SeAliasUsersSid ) ExFreePoolWithTag ( SeAliasUsersSid , TAG_SID ) ;
if ( SeAliasGuestsSid ) ExFreePoolWithTag ( SeAliasGuestsSid , TAG_SID ) ;
if ( SeAliasPowerUsersSid ) ExFreePoolWithTag ( SeAliasPowerUsersSid , TAG_SID ) ;
if ( SeAliasAccountOpsSid ) ExFreePoolWithTag ( SeAliasAccountOpsSid , TAG_SID ) ;
if ( SeAliasSystemOpsSid ) ExFreePoolWithTag ( SeAliasSystemOpsSid , TAG_SID ) ;
if ( SeAliasPrintOpsSid ) ExFreePoolWithTag ( SeAliasPrintOpsSid , TAG_SID ) ;
if ( SeAliasBackupOpsSid ) ExFreePoolWithTag ( SeAliasBackupOpsSid , TAG_SID ) ;
if ( SeAuthenticatedUsersSid ) ExFreePoolWithTag ( SeAuthenticatedUsersSid , TAG_SID ) ;
if ( SeRestrictedSid ) ExFreePoolWithTag ( SeRestrictedSid , TAG_SID ) ;
if ( SeAnonymousLogonSid ) ExFreePoolWithTag ( SeAnonymousLogonSid , TAG_SID ) ;
2009-09-02 13:07:12 +00:00
}
2021-08-11 14:24:45 +00:00
/**
* @ brief
* Initializes all the SIDs known in the system .
*
* @ return
* Returns TRUE if all the SIDs have been initialized ,
* FALSE otherwise .
*/
2020-10-06 19:44:01 +00:00
CODE_SEG ( " INIT " )
2020-05-23 13:56:10 +00:00
BOOLEAN
2005-09-13 23:28:21 +00:00
NTAPI
2002-02-20 20:16:49 +00:00
SepInitSecurityIDs ( VOID )
{
2008-04-23 20:38:37 +00:00
ULONG SidLength0 ;
ULONG SidLength1 ;
ULONG SidLength2 ;
PULONG SubAuthority ;
2010-05-28 16:28:27 +00:00
2008-04-23 20:38:37 +00:00
SidLength0 = RtlLengthRequiredSid ( 0 ) ;
SidLength1 = RtlLengthRequiredSid ( 1 ) ;
SidLength2 = RtlLengthRequiredSid ( 2 ) ;
2010-05-28 16:28:27 +00:00
2008-04-23 20:38:37 +00:00
/* create NullSid */
SeNullSid = ExAllocatePoolWithTag ( PagedPool , SidLength1 , TAG_SID ) ;
SeWorldSid = ExAllocatePoolWithTag ( PagedPool , SidLength1 , TAG_SID ) ;
SeLocalSid = ExAllocatePoolWithTag ( PagedPool , SidLength1 , TAG_SID ) ;
SeCreatorOwnerSid = ExAllocatePoolWithTag ( PagedPool , SidLength1 , TAG_SID ) ;
SeCreatorGroupSid = ExAllocatePoolWithTag ( PagedPool , SidLength1 , TAG_SID ) ;
SeCreatorOwnerServerSid = ExAllocatePoolWithTag ( PagedPool , SidLength1 , TAG_SID ) ;
SeCreatorGroupServerSid = ExAllocatePoolWithTag ( PagedPool , SidLength1 , TAG_SID ) ;
SeNtAuthoritySid = ExAllocatePoolWithTag ( PagedPool , SidLength0 , TAG_SID ) ;
SeDialupSid = ExAllocatePoolWithTag ( PagedPool , SidLength1 , TAG_SID ) ;
SeNetworkSid = ExAllocatePoolWithTag ( PagedPool , SidLength1 , TAG_SID ) ;
SeBatchSid = ExAllocatePoolWithTag ( PagedPool , SidLength1 , TAG_SID ) ;
SeInteractiveSid = ExAllocatePoolWithTag ( PagedPool , SidLength1 , TAG_SID ) ;
SeServiceSid = ExAllocatePoolWithTag ( PagedPool , SidLength1 , TAG_SID ) ;
SePrincipalSelfSid = ExAllocatePoolWithTag ( PagedPool , SidLength1 , TAG_SID ) ;
SeLocalSystemSid = ExAllocatePoolWithTag ( PagedPool , SidLength1 , TAG_SID ) ;
SeAuthenticatedUserSid = ExAllocatePoolWithTag ( PagedPool , SidLength1 , TAG_SID ) ;
SeRestrictedCodeSid = ExAllocatePoolWithTag ( PagedPool , SidLength1 , TAG_SID ) ;
SeAliasAdminsSid = ExAllocatePoolWithTag ( PagedPool , SidLength2 , TAG_SID ) ;
SeAliasUsersSid = ExAllocatePoolWithTag ( PagedPool , SidLength2 , TAG_SID ) ;
SeAliasGuestsSid = ExAllocatePoolWithTag ( PagedPool , SidLength2 , TAG_SID ) ;
SeAliasPowerUsersSid = ExAllocatePoolWithTag ( PagedPool , SidLength2 , TAG_SID ) ;
SeAliasAccountOpsSid = ExAllocatePoolWithTag ( PagedPool , SidLength2 , TAG_SID ) ;
SeAliasSystemOpsSid = ExAllocatePoolWithTag ( PagedPool , SidLength2 , TAG_SID ) ;
SeAliasPrintOpsSid = ExAllocatePoolWithTag ( PagedPool , SidLength2 , TAG_SID ) ;
SeAliasBackupOpsSid = ExAllocatePoolWithTag ( PagedPool , SidLength2 , TAG_SID ) ;
SeAuthenticatedUsersSid = ExAllocatePoolWithTag ( PagedPool , SidLength1 , TAG_SID ) ;
SeRestrictedSid = ExAllocatePoolWithTag ( PagedPool , SidLength1 , TAG_SID ) ;
SeAnonymousLogonSid = ExAllocatePoolWithTag ( PagedPool , SidLength1 , TAG_SID ) ;
2014-02-18 17:51:45 +00:00
SeLocalServiceSid = ExAllocatePoolWithTag ( PagedPool , SidLength1 , TAG_SID ) ;
SeNetworkServiceSid = ExAllocatePoolWithTag ( PagedPool , SidLength1 , TAG_SID ) ;
2009-09-02 13:07:12 +00:00
2008-04-23 20:38:37 +00:00
if ( SeNullSid = = NULL | | SeWorldSid = = NULL | |
SeLocalSid = = NULL | | SeCreatorOwnerSid = = NULL | |
SeCreatorGroupSid = = NULL | | SeCreatorOwnerServerSid = = NULL | |
SeCreatorGroupServerSid = = NULL | | SeNtAuthoritySid = = NULL | |
SeDialupSid = = NULL | | SeNetworkSid = = NULL | | SeBatchSid = = NULL | |
SeInteractiveSid = = NULL | | SeServiceSid = = NULL | |
SePrincipalSelfSid = = NULL | | SeLocalSystemSid = = NULL | |
SeAuthenticatedUserSid = = NULL | | SeRestrictedCodeSid = = NULL | |
SeAliasAdminsSid = = NULL | | SeAliasUsersSid = = NULL | |
SeAliasGuestsSid = = NULL | | SeAliasPowerUsersSid = = NULL | |
SeAliasAccountOpsSid = = NULL | | SeAliasSystemOpsSid = = NULL | |
SeAliasPrintOpsSid = = NULL | | SeAliasBackupOpsSid = = NULL | |
SeAuthenticatedUsersSid = = NULL | | SeRestrictedSid = = NULL | |
2014-02-18 17:51:45 +00:00
SeAnonymousLogonSid = = NULL | | SeLocalServiceSid = = NULL | |
SeNetworkServiceSid = = NULL )
2008-04-23 20:38:37 +00:00
{
2009-09-02 13:07:12 +00:00
FreeInitializedSids ( ) ;
2010-05-28 16:28:27 +00:00
return FALSE ;
2008-04-23 20:38:37 +00:00
}
2010-05-28 16:28:27 +00:00
2008-04-23 20:38:37 +00:00
RtlInitializeSid ( SeNullSid , & SeNullSidAuthority , 1 ) ;
RtlInitializeSid ( SeWorldSid , & SeWorldSidAuthority , 1 ) ;
RtlInitializeSid ( SeLocalSid , & SeLocalSidAuthority , 1 ) ;
RtlInitializeSid ( SeCreatorOwnerSid , & SeCreatorSidAuthority , 1 ) ;
RtlInitializeSid ( SeCreatorGroupSid , & SeCreatorSidAuthority , 1 ) ;
RtlInitializeSid ( SeCreatorOwnerServerSid , & SeCreatorSidAuthority , 1 ) ;
RtlInitializeSid ( SeCreatorGroupServerSid , & SeCreatorSidAuthority , 1 ) ;
RtlInitializeSid ( SeNtAuthoritySid , & SeNtSidAuthority , 0 ) ;
RtlInitializeSid ( SeDialupSid , & SeNtSidAuthority , 1 ) ;
RtlInitializeSid ( SeNetworkSid , & SeNtSidAuthority , 1 ) ;
RtlInitializeSid ( SeBatchSid , & SeNtSidAuthority , 1 ) ;
RtlInitializeSid ( SeInteractiveSid , & SeNtSidAuthority , 1 ) ;
RtlInitializeSid ( SeServiceSid , & SeNtSidAuthority , 1 ) ;
RtlInitializeSid ( SePrincipalSelfSid , & SeNtSidAuthority , 1 ) ;
RtlInitializeSid ( SeLocalSystemSid , & SeNtSidAuthority , 1 ) ;
RtlInitializeSid ( SeAuthenticatedUserSid , & SeNtSidAuthority , 1 ) ;
RtlInitializeSid ( SeRestrictedCodeSid , & SeNtSidAuthority , 1 ) ;
RtlInitializeSid ( SeAliasAdminsSid , & SeNtSidAuthority , 2 ) ;
RtlInitializeSid ( SeAliasUsersSid , & SeNtSidAuthority , 2 ) ;
RtlInitializeSid ( SeAliasGuestsSid , & SeNtSidAuthority , 2 ) ;
RtlInitializeSid ( SeAliasPowerUsersSid , & SeNtSidAuthority , 2 ) ;
RtlInitializeSid ( SeAliasAccountOpsSid , & SeNtSidAuthority , 2 ) ;
RtlInitializeSid ( SeAliasSystemOpsSid , & SeNtSidAuthority , 2 ) ;
RtlInitializeSid ( SeAliasPrintOpsSid , & SeNtSidAuthority , 2 ) ;
RtlInitializeSid ( SeAliasBackupOpsSid , & SeNtSidAuthority , 2 ) ;
RtlInitializeSid ( SeAuthenticatedUsersSid , & SeNtSidAuthority , 1 ) ;
RtlInitializeSid ( SeRestrictedSid , & SeNtSidAuthority , 1 ) ;
RtlInitializeSid ( SeAnonymousLogonSid , & SeNtSidAuthority , 1 ) ;
2014-02-18 17:51:45 +00:00
RtlInitializeSid ( SeLocalServiceSid , & SeNtSidAuthority , 1 ) ;
RtlInitializeSid ( SeNetworkServiceSid , & SeNtSidAuthority , 1 ) ;
2010-05-28 16:28:27 +00:00
2008-04-23 20:38:37 +00:00
SubAuthority = RtlSubAuthoritySid ( SeNullSid , 0 ) ;
* SubAuthority = SECURITY_NULL_RID ;
SubAuthority = RtlSubAuthoritySid ( SeWorldSid , 0 ) ;
* SubAuthority = SECURITY_WORLD_RID ;
SubAuthority = RtlSubAuthoritySid ( SeLocalSid , 0 ) ;
* SubAuthority = SECURITY_LOCAL_RID ;
SubAuthority = RtlSubAuthoritySid ( SeCreatorOwnerSid , 0 ) ;
* SubAuthority = SECURITY_CREATOR_OWNER_RID ;
SubAuthority = RtlSubAuthoritySid ( SeCreatorGroupSid , 0 ) ;
* SubAuthority = SECURITY_CREATOR_GROUP_RID ;
SubAuthority = RtlSubAuthoritySid ( SeCreatorOwnerServerSid , 0 ) ;
* SubAuthority = SECURITY_CREATOR_OWNER_SERVER_RID ;
SubAuthority = RtlSubAuthoritySid ( SeCreatorGroupServerSid , 0 ) ;
* SubAuthority = SECURITY_CREATOR_GROUP_SERVER_RID ;
SubAuthority = RtlSubAuthoritySid ( SeDialupSid , 0 ) ;
* SubAuthority = SECURITY_DIALUP_RID ;
SubAuthority = RtlSubAuthoritySid ( SeNetworkSid , 0 ) ;
* SubAuthority = SECURITY_NETWORK_RID ;
SubAuthority = RtlSubAuthoritySid ( SeBatchSid , 0 ) ;
* SubAuthority = SECURITY_BATCH_RID ;
SubAuthority = RtlSubAuthoritySid ( SeInteractiveSid , 0 ) ;
* SubAuthority = SECURITY_INTERACTIVE_RID ;
SubAuthority = RtlSubAuthoritySid ( SeServiceSid , 0 ) ;
* SubAuthority = SECURITY_SERVICE_RID ;
SubAuthority = RtlSubAuthoritySid ( SePrincipalSelfSid , 0 ) ;
* SubAuthority = SECURITY_PRINCIPAL_SELF_RID ;
SubAuthority = RtlSubAuthoritySid ( SeLocalSystemSid , 0 ) ;
* SubAuthority = SECURITY_LOCAL_SYSTEM_RID ;
SubAuthority = RtlSubAuthoritySid ( SeAuthenticatedUserSid , 0 ) ;
* SubAuthority = SECURITY_AUTHENTICATED_USER_RID ;
SubAuthority = RtlSubAuthoritySid ( SeRestrictedCodeSid , 0 ) ;
* SubAuthority = SECURITY_RESTRICTED_CODE_RID ;
SubAuthority = RtlSubAuthoritySid ( SeAliasAdminsSid , 0 ) ;
* SubAuthority = SECURITY_BUILTIN_DOMAIN_RID ;
SubAuthority = RtlSubAuthoritySid ( SeAliasAdminsSid , 1 ) ;
* SubAuthority = DOMAIN_ALIAS_RID_ADMINS ;
SubAuthority = RtlSubAuthoritySid ( SeAliasUsersSid , 0 ) ;
* SubAuthority = SECURITY_BUILTIN_DOMAIN_RID ;
SubAuthority = RtlSubAuthoritySid ( SeAliasUsersSid , 1 ) ;
* SubAuthority = DOMAIN_ALIAS_RID_USERS ;
SubAuthority = RtlSubAuthoritySid ( SeAliasGuestsSid , 0 ) ;
* SubAuthority = SECURITY_BUILTIN_DOMAIN_RID ;
SubAuthority = RtlSubAuthoritySid ( SeAliasGuestsSid , 1 ) ;
* SubAuthority = DOMAIN_ALIAS_RID_GUESTS ;
SubAuthority = RtlSubAuthoritySid ( SeAliasPowerUsersSid , 0 ) ;
* SubAuthority = SECURITY_BUILTIN_DOMAIN_RID ;
SubAuthority = RtlSubAuthoritySid ( SeAliasPowerUsersSid , 1 ) ;
* SubAuthority = DOMAIN_ALIAS_RID_POWER_USERS ;
SubAuthority = RtlSubAuthoritySid ( SeAliasAccountOpsSid , 0 ) ;
* SubAuthority = SECURITY_BUILTIN_DOMAIN_RID ;
SubAuthority = RtlSubAuthoritySid ( SeAliasAccountOpsSid , 1 ) ;
* SubAuthority = DOMAIN_ALIAS_RID_ACCOUNT_OPS ;
SubAuthority = RtlSubAuthoritySid ( SeAliasSystemOpsSid , 0 ) ;
* SubAuthority = SECURITY_BUILTIN_DOMAIN_RID ;
SubAuthority = RtlSubAuthoritySid ( SeAliasSystemOpsSid , 1 ) ;
* SubAuthority = DOMAIN_ALIAS_RID_SYSTEM_OPS ;
SubAuthority = RtlSubAuthoritySid ( SeAliasPrintOpsSid , 0 ) ;
* SubAuthority = SECURITY_BUILTIN_DOMAIN_RID ;
SubAuthority = RtlSubAuthoritySid ( SeAliasPrintOpsSid , 1 ) ;
* SubAuthority = DOMAIN_ALIAS_RID_PRINT_OPS ;
SubAuthority = RtlSubAuthoritySid ( SeAliasBackupOpsSid , 0 ) ;
* SubAuthority = SECURITY_BUILTIN_DOMAIN_RID ;
SubAuthority = RtlSubAuthoritySid ( SeAliasBackupOpsSid , 1 ) ;
* SubAuthority = DOMAIN_ALIAS_RID_BACKUP_OPS ;
SubAuthority = RtlSubAuthoritySid ( SeAuthenticatedUsersSid , 0 ) ;
* SubAuthority = SECURITY_AUTHENTICATED_USER_RID ;
SubAuthority = RtlSubAuthoritySid ( SeRestrictedSid , 0 ) ;
* SubAuthority = SECURITY_RESTRICTED_CODE_RID ;
SubAuthority = RtlSubAuthoritySid ( SeAnonymousLogonSid , 0 ) ;
* SubAuthority = SECURITY_ANONYMOUS_LOGON_RID ;
2014-02-18 17:51:45 +00:00
SubAuthority = RtlSubAuthoritySid ( SeLocalServiceSid , 0 ) ;
* SubAuthority = SECURITY_LOCAL_SERVICE_RID ;
SubAuthority = RtlSubAuthoritySid ( SeNetworkServiceSid , 0 ) ;
* SubAuthority = SECURITY_NETWORK_SERVICE_RID ;
2010-05-28 16:28:27 +00:00
return TRUE ;
2002-02-20 20:16:49 +00:00
}
2021-08-11 14:24:45 +00:00
/**
* @ brief
* Captures a SID .
2021-09-13 01:33:14 +00:00
*
2021-08-11 14:24:45 +00:00
* @ param [ in ] InputSid
* A valid security identifier to be captured .
2021-09-13 01:33:14 +00:00
*
2021-08-11 14:24:45 +00:00
* @ param [ in ] AccessMode
* Processor level access mode .
2021-09-13 01:33:14 +00:00
*
2021-08-11 14:24:45 +00:00
* @ param [ in ] PoolType
* Pool memory type for the captured SID to assign upon
* allocation .
2021-09-13 01:33:14 +00:00
*
2021-08-11 14:24:45 +00:00
* @ param [ in ] CaptureIfKernel
* If set to TRUE , the capturing is done within the kernel .
* Otherwise the capturing is done in a kernel mode driver .
2021-09-13 01:33:14 +00:00
*
2021-08-11 14:24:45 +00:00
* @ param [ out ] CapturedSid
* The captured security identifier , returned to the caller .
*
* @ return
* Returns STATUS_SUCCESS if the SID was captured . STATUS_INSUFFICIENT_RESOURCES
* is returned if memory pool allocation for the captured SID has failed .
*/
2005-03-12 22:16:02 +00:00
NTSTATUS
2005-09-13 23:28:21 +00:00
NTAPI
2021-08-20 09:48:19 +00:00
SepCaptureSid (
_In_ PSID InputSid ,
_In_ KPROCESSOR_MODE AccessMode ,
_In_ POOL_TYPE PoolType ,
_In_ BOOLEAN CaptureIfKernel ,
_Out_ PSID * CapturedSid )
2005-03-12 22:16:02 +00:00
{
2008-04-23 20:38:37 +00:00
ULONG SidSize = 0 ;
PISID NewSid , Sid = ( PISID ) InputSid ;
2010-05-28 16:28:27 +00:00
2008-04-23 20:38:37 +00:00
PAGED_CODE ( ) ;
2010-05-28 16:28:27 +00:00
2009-08-26 17:31:02 +00:00
if ( AccessMode ! = KernelMode )
2005-03-12 22:16:02 +00:00
{
2008-11-24 13:40:26 +00:00
_SEH2_TRY
2005-03-12 22:16:02 +00:00
{
2012-01-23 20:49:08 +00:00
ProbeForRead ( Sid , FIELD_OFFSET ( SID , SubAuthority ) , sizeof ( UCHAR ) ) ;
2008-04-23 20:38:37 +00:00
SidSize = RtlLengthRequiredSid ( Sid - > SubAuthorityCount ) ;
2012-01-23 20:49:08 +00:00
ProbeForRead ( Sid , SidSize , sizeof ( UCHAR ) ) ;
2005-03-12 22:16:02 +00:00
}
2008-11-24 13:40:26 +00:00
_SEH2_EXCEPT ( EXCEPTION_EXECUTE_HANDLER )
2005-03-12 22:16:02 +00:00
{
2009-08-26 17:31:02 +00:00
/* Return the exception code */
_SEH2_YIELD ( return _SEH2_GetExceptionCode ( ) ) ;
2005-03-12 22:16:02 +00:00
}
2008-11-24 13:40:26 +00:00
_SEH2_END ;
2010-05-28 16:28:27 +00:00
2016-11-04 17:52:32 +00:00
/* Allocate a SID and copy it */
2012-06-26 07:21:45 +00:00
NewSid = ExAllocatePoolWithTag ( PoolType , SidSize , TAG_SID ) ;
2012-01-23 20:49:08 +00:00
if ( ! NewSid )
return STATUS_INSUFFICIENT_RESOURCES ;
_SEH2_TRY
2008-04-23 20:38:37 +00:00
{
2012-01-23 20:49:08 +00:00
RtlCopyMemory ( NewSid , Sid , SidSize ) ;
2009-08-26 17:31:02 +00:00
2012-01-23 20:49:08 +00:00
* CapturedSid = NewSid ;
2009-08-26 17:31:02 +00:00
}
2012-01-23 20:49:08 +00:00
_SEH2_EXCEPT ( EXCEPTION_EXECUTE_HANDLER )
2009-08-26 17:31:02 +00:00
{
2012-01-23 20:49:08 +00:00
/* Free the SID and return the exception code */
ExFreePoolWithTag ( NewSid , TAG_SID ) ;
_SEH2_YIELD ( return _SEH2_GetExceptionCode ( ) ) ;
2008-04-23 20:38:37 +00:00
}
2012-01-23 20:49:08 +00:00
_SEH2_END ;
2005-03-12 22:16:02 +00:00
}
2010-05-28 16:28:27 +00:00
else if ( ! CaptureIfKernel )
2005-03-12 22:16:02 +00:00
{
2008-04-23 20:38:37 +00:00
* CapturedSid = InputSid ;
2005-03-12 22:16:02 +00:00
}
else
{
2008-04-23 20:38:37 +00:00
SidSize = RtlLengthRequiredSid ( Sid - > SubAuthorityCount ) ;
2010-05-28 16:28:27 +00:00
2016-11-04 17:52:32 +00:00
/* Allocate a SID and copy it */
2012-06-26 07:21:45 +00:00
NewSid = ExAllocatePoolWithTag ( PoolType , SidSize , TAG_SID ) ;
2012-01-23 20:49:08 +00:00
if ( NewSid = = NULL )
return STATUS_INSUFFICIENT_RESOURCES ;
2010-05-28 16:28:27 +00:00
2012-01-23 20:49:08 +00:00
RtlCopyMemory ( NewSid , Sid , SidSize ) ;
* CapturedSid = NewSid ;
2005-03-12 22:16:02 +00:00
}
2010-05-28 16:28:27 +00:00
2012-01-23 20:49:08 +00:00
return STATUS_SUCCESS ;
2005-03-12 22:16:02 +00:00
}
2021-08-11 14:24:45 +00:00
/**
* @ brief
* Releases a captured SID .
2021-09-13 01:33:14 +00:00
*
2021-08-11 14:24:45 +00:00
* @ param [ in ] CapturedSid
* The captured SID to be released .
2021-09-13 01:33:14 +00:00
*
2021-08-11 14:24:45 +00:00
* @ param [ in ] AccessMode
* Processor level access mode .
2021-09-13 01:33:14 +00:00
*
2021-08-11 14:24:45 +00:00
* @ param [ in ] CaptureIfKernel
* If set to TRUE , the releasing is done within the kernel .
* Otherwise the releasing is done in a kernel mode driver .
*
* @ return
* Nothing .
*/
2005-03-12 22:16:02 +00:00
VOID
2005-09-13 23:28:21 +00:00
NTAPI
2021-08-20 09:48:19 +00:00
SepReleaseSid (
_In_ PSID CapturedSid ,
_In_ KPROCESSOR_MODE AccessMode ,
_In_ BOOLEAN CaptureIfKernel )
2005-03-12 22:16:02 +00:00
{
2008-04-23 20:38:37 +00:00
PAGED_CODE ( ) ;
2010-05-28 16:28:27 +00:00
if ( CapturedSid ! = NULL & &
( AccessMode ! = KernelMode | |
( AccessMode = = KernelMode & & CaptureIfKernel ) ) )
2008-04-23 20:38:37 +00:00
{
2011-06-01 13:39:36 +00:00
ExFreePoolWithTag ( CapturedSid , TAG_SID ) ;
2008-04-23 20:38:37 +00:00
}
2005-03-12 22:16:02 +00:00
}
2022-05-28 19:14:04 +00:00
/**
* @ brief
* Checks if a SID is present in a token .
*
* @ param [ in ] _Token
* A valid token object .
*
* @ param [ in ] PrincipalSelfSid
* A principal self SID .
*
* @ param [ in ] _Sid
* A regular SID .
*
* @ param [ in ] Deny
* If set to TRUE , the caller expected that a SID in a token
* must be a deny - only SID , that is , access checks are performed
* only for deny - only ACEs of the said SID .
*
* @ param [ in ] Restricted
* If set to TRUE , the caller expects that a SID in a token is
* restricted ( by the general definition , a token is restricted ) .
*
* @ return
* Returns TRUE if the specified SID in the call is present in the token ,
* FALSE otherwise .
*/
BOOLEAN
NTAPI
SepSidInTokenEx (
_In_ PACCESS_TOKEN _Token ,
_In_ PSID PrincipalSelfSid ,
_In_ PSID _Sid ,
_In_ BOOLEAN Deny ,
_In_ BOOLEAN Restricted )
{
ULONG SidIndex ;
PTOKEN Token = ( PTOKEN ) _Token ;
PISID TokenSid , Sid = ( PISID ) _Sid ;
PSID_AND_ATTRIBUTES SidAndAttributes ;
ULONG SidCount , SidLength ;
USHORT SidMetadata ;
PAGED_CODE ( ) ;
/* Check if a principal SID was given, and this is our current SID already */
if ( ( PrincipalSelfSid ) & & ( RtlEqualSid ( SePrincipalSelfSid , Sid ) ) )
{
/* Just use the principal SID in this case */
Sid = PrincipalSelfSid ;
}
/* Check if this is a restricted token or not */
if ( Restricted )
{
/* Use the restricted SIDs and count */
SidAndAttributes = Token - > RestrictedSids ;
SidCount = Token - > RestrictedSidCount ;
}
else
{
/* Use the normal SIDs and count */
SidAndAttributes = Token - > UserAndGroups ;
SidCount = Token - > UserAndGroupCount ;
}
/* Do checks here by hand instead of the usual 4 function calls */
SidLength = FIELD_OFFSET ( SID ,
SubAuthority [ Sid - > SubAuthorityCount ] ) ;
SidMetadata = * ( PUSHORT ) & Sid - > Revision ;
/* Loop every SID */
for ( SidIndex = 0 ; SidIndex < SidCount ; SidIndex + + )
{
TokenSid = ( PISID ) SidAndAttributes - > Sid ;
# if SE_SID_DEBUG
UNICODE_STRING sidString ;
RtlConvertSidToUnicodeString ( & sidString , TokenSid , TRUE ) ;
DPRINT1 ( " SID in Token: %wZ \n " , & sidString ) ;
RtlFreeUnicodeString ( & sidString ) ;
# endif
/* Check if the SID metadata matches */
if ( * ( PUSHORT ) & TokenSid - > Revision = = SidMetadata )
{
/* Check if the SID data matches */
if ( RtlEqualMemory ( Sid , TokenSid , SidLength ) )
{
/*
* Check if the group is enabled , or used for deny only .
* Otherwise we have to check if this is the first user .
* We understand that by looking if this SID is not
* restricted , this is the first element we are iterating
* and that it doesn ' t have SE_GROUP_USE_FOR_DENY_ONLY
* attribute .
*/
if ( ( ! Restricted & & ( SidIndex = = 0 ) & & ! ( SidAndAttributes - > Attributes & SE_GROUP_USE_FOR_DENY_ONLY ) ) | |
( SidAndAttributes - > Attributes & SE_GROUP_ENABLED ) | |
( ( Deny ) & & ( SidAndAttributes - > Attributes & SE_GROUP_USE_FOR_DENY_ONLY ) ) )
{
/* SID is present */
return TRUE ;
}
else
{
/* SID is not present */
return FALSE ;
}
}
}
/* Move to the next SID */
SidAndAttributes + + ;
}
/* SID is not present */
return FALSE ;
}
/**
* @ brief
* Checks if a SID is present in a token .
*
* @ param [ in ] _Token
* A valid token object .
*
* @ param [ in ] _Sid
* A regular SID .
*
* @ return
* Returns TRUE if the specified SID in the call is present in the token ,
* FALSE otherwise .
*/
BOOLEAN
NTAPI
SepSidInToken (
_In_ PACCESS_TOKEN _Token ,
_In_ PSID Sid )
{
/* Call extended API */
return SepSidInTokenEx ( _Token , NULL , Sid , FALSE , FALSE ) ;
}
2022-02-05 21:01:39 +00:00
/**
* @ brief
* Captures a security identifier from a
* given access control entry . This identifier
* is valid for the whole of its lifetime .
*
* @ param [ in ] Ace
* A pointer to an access control entry , which
* can be obtained from a DACL .
*
* @ return
* Returns a pointer to a security identifier ( SID ) ,
* otherwise NULL is returned if an unsupported ACE
* type was given to the function .
*/
PSID
NTAPI
SepGetSidFromAce (
_In_ PACE Ace )
{
2023-07-16 18:45:13 +00:00
PULONG Flags ;
ULONG GuidSize = 0 ;
PSID Sid = NULL ;
2022-02-05 21:01:39 +00:00
PAGED_CODE ( ) ;
/* Sanity check */
ASSERT ( Ace ) ;
/* Obtain the SID based upon ACE type */
2023-08-22 20:21:13 +00:00
switch ( Ace - > Header . AceType )
2022-02-05 21:01:39 +00:00
{
case ACCESS_DENIED_ACE_TYPE :
case ACCESS_ALLOWED_ACE_TYPE :
2023-07-16 18:45:13 +00:00
case SYSTEM_AUDIT_ACE_TYPE :
case SYSTEM_ALARM_ACE_TYPE :
2022-02-05 21:01:39 +00:00
{
2023-07-16 18:45:13 +00:00
Sid = ( PSID ) & ( ( PKNOWN_ACE ) Ace ) - > SidStart ;
2022-02-05 21:01:39 +00:00
break ;
}
case ACCESS_DENIED_OBJECT_ACE_TYPE :
case ACCESS_ALLOWED_OBJECT_ACE_TYPE :
{
2023-07-16 18:45:13 +00:00
Flags = ( PULONG ) & ( ( PKNOWN_OBJECT_ACE ) Ace ) - > Flags ;
if ( * Flags & ACE_OBJECT_TYPE_PRESENT )
{
GuidSize + = sizeof ( GUID ) ;
}
2022-02-05 21:01:39 +00:00
2023-07-16 18:45:13 +00:00
if ( * Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT )
{
GuidSize + = sizeof ( GUID ) ;
}
2022-11-06 16:46:04 +00:00
2023-07-16 18:45:13 +00:00
Sid = ( PSID ) ( ( ULONG_PTR ) & ( ( PKNOWN_OBJECT_ACE ) Ace ) - > SidStart + GuidSize ) ;
2022-11-06 16:46:04 +00:00
break ;
}
2022-02-05 21:01:39 +00:00
default :
2022-11-06 16:46:04 +00:00
{
2023-08-22 20:21:13 +00:00
DPRINT1 ( " SepGetSidFromAce(): Unknown ACE type (Ace 0x%p, Type %u) \n " , Ace , Ace - > Header . AceType ) ;
2022-02-05 21:01:39 +00:00
break ;
2022-11-06 16:46:04 +00:00
}
2022-02-05 21:01:39 +00:00
}
return Sid ;
}
2021-08-11 14:24:45 +00:00
/**
* @ brief
* Captures a SID with attributes .
2021-09-13 01:33:14 +00:00
*
2021-08-11 14:24:45 +00:00
* @ param [ in ] SrcSidAndAttributes
* Source of the SID with attributes to be captured .
2021-09-13 01:33:14 +00:00
*
2021-08-11 14:24:45 +00:00
* @ param [ in ] AttributeCount
* The number count of attributes , in total .
2021-09-13 01:33:14 +00:00
*
2021-08-11 14:24:45 +00:00
* @ param [ in ] PreviousMode
* Processor access level mode .
2021-09-13 01:33:14 +00:00
*
2021-08-11 14:24:45 +00:00
* @ param [ in ] AllocatedMem
* The allocated memory buffer for the captured SID . If the caller
* supplies no allocated block of memory then the function will
* allocate some buffer block of memory for the captured SID
* automatically .
2021-09-13 01:33:14 +00:00
*
2021-08-11 14:24:45 +00:00
* @ param [ in ] AllocatedLength
* The length of the buffer that points to the allocated memory ,
* in bytes .
2021-09-13 01:33:14 +00:00
*
2021-08-11 14:24:45 +00:00
* @ param [ in ] PoolType
* The pool type for the captured SID and attributes to assign .
2021-09-13 01:33:14 +00:00
*
2021-08-11 14:24:45 +00:00
* @ param [ in ] CaptureIfKernel
* If set to TRUE , the capturing is done within the kernel .
* Otherwise the capturing is done in a kernel mode driver .
2021-09-13 01:33:14 +00:00
*
2021-08-11 14:24:45 +00:00
* @ param [ out ] CapturedSidAndAttributes
* The captured SID and attributes .
2021-09-13 01:33:14 +00:00
*
2021-08-11 14:24:45 +00:00
* @ param [ out ] ResultLength
* The length of the captured SID and attributes , in bytes .
*
* @ return
* Returns STATUS_SUCCESS if SID and attributes capturing
* has been completed successfully . STATUS_INVALID_PARAMETER
* is returned if the count of attributes exceeds the maximum
2021-09-26 09:42:00 +00:00
* threshold that the kernel can permit , with the purpose of
* avoiding integer overflows . STATUS_INSUFFICIENT_RESOURCES
2021-08-11 14:24:45 +00:00
* is returned if memory pool allocation for the captured SID has failed .
* STATUS_BUFFER_TOO_SMALL is returned if the length of the allocated
2021-11-09 20:34:36 +00:00
* buffer is less than the required size . STATUS_INVALID_SID is returned
* if a SID doesn ' t meet certain requirements to be considered a valid
* SID by the security manager . A failure NTSTATUS code is returned
* otherwise .
*
* @ remarks
* A security identifier ( SID ) is a variable - length data structure that
* can change in size over time , depending on the factors that influence
* this effect in question . An attacker can take advantage of this fact
* and can potentially modify certain properties of a SID making it
* different in size than it was originally before . This is what we ' d
* call , a TOCTOU vulnerability .
*
* For this reason , the logic of copying the SIDs and their attributes
* into a new buffer goes like this : first , allocate a buffer array
* that just holds the lengths and subauthority count of each SID .
* Such information is copied in the first loop . Then in a second loop ,
* iterate over the array with SID provided and copy them into the final
* array . The moment we ' re doing this , validate the lengths of each SID
* basing upon the captured lengths we ' ve got before . In this way we
* ensure that the SIDs have remained intact . The validation checks are
* done in user mode as a general rule that we just cannot trust UM and
* whatever data is coming from it .
2021-08-11 14:24:45 +00:00
*/
2014-01-17 21:58:28 +00:00
NTSTATUS
NTAPI
SeCaptureSidAndAttributesArray (
_In_ PSID_AND_ATTRIBUTES SrcSidAndAttributes ,
_In_ ULONG AttributeCount ,
_In_ KPROCESSOR_MODE PreviousMode ,
_In_opt_ PVOID AllocatedMem ,
_In_ ULONG AllocatedLength ,
_In_ POOL_TYPE PoolType ,
_In_ BOOLEAN CaptureIfKernel ,
_Out_ PSID_AND_ATTRIBUTES * CapturedSidAndAttributes ,
_Out_ PULONG ResultLength )
{
ULONG ArraySize , RequiredLength , SidLength , i ;
2021-11-09 20:34:36 +00:00
ULONG TempArrayValidate , TempLengthValidate ;
2014-01-17 21:58:28 +00:00
PSID_AND_ATTRIBUTES SidAndAttributes ;
2021-11-09 20:34:36 +00:00
_SEH2_VOLATILE PSID_VALIDATE ValidateArray ;
2014-01-17 21:58:28 +00:00
PUCHAR CurrentDest ;
PISID Sid ;
NTSTATUS Status ;
PAGED_CODE ( ) ;
2021-11-09 20:34:36 +00:00
ValidateArray = NULL ;
SidAndAttributes = NULL ;
2014-01-17 21:58:28 +00:00
* CapturedSidAndAttributes = NULL ;
* ResultLength = 0 ;
if ( AttributeCount = = 0 )
{
return STATUS_SUCCESS ;
}
2021-09-26 09:42:00 +00:00
if ( AttributeCount > SE_MAXIMUM_GROUP_LIMIT )
2014-01-17 21:58:28 +00:00
{
2021-11-09 20:34:36 +00:00
DPRINT1 ( " SeCaptureSidAndAttributesArray(): Maximum group limit exceeded! \n " ) ;
2014-01-17 21:58:28 +00:00
return STATUS_INVALID_PARAMETER ;
}
if ( ( PreviousMode = = KernelMode ) & & ! CaptureIfKernel )
{
* CapturedSidAndAttributes = SrcSidAndAttributes ;
return STATUS_SUCCESS ;
}
ArraySize = AttributeCount * sizeof ( SID_AND_ATTRIBUTES ) ;
RequiredLength = ALIGN_UP_BY ( ArraySize , sizeof ( ULONG ) ) ;
if ( PreviousMode ! = KernelMode )
{
2021-11-09 20:34:36 +00:00
/* Check for user mode data */
2014-01-17 21:58:28 +00:00
_SEH2_TRY
{
/* First probe the whole array */
ProbeForRead ( SrcSidAndAttributes , ArraySize , sizeof ( ULONG ) ) ;
2021-11-09 20:34:36 +00:00
/* We're in user mode, set up the size for the temporary array */
TempArrayValidate = AttributeCount * sizeof ( SID_VALIDATE ) ;
TempLengthValidate = ALIGN_UP_BY ( TempArrayValidate , sizeof ( ULONG ) ) ;
/*
* Allocate a buffer for the array that we ' re going to
* temporarily hold the subauthority count and the SID
* elements . We ' ll be going to use this array to perform
* validation checks later .
*/
ValidateArray = ExAllocatePoolWithTag ( PoolType | POOL_RAISE_IF_ALLOCATION_FAILURE ,
TempLengthValidate ,
TAG_SID_VALIDATE ) ;
2014-01-17 21:58:28 +00:00
/* Loop the array elements */
for ( i = 0 ; i < AttributeCount ; i + + )
{
/* Get the SID and probe the minimal structure */
Sid = SrcSidAndAttributes [ i ] . Sid ;
ProbeForRead ( Sid , sizeof ( * Sid ) , sizeof ( ULONG ) ) ;
2021-11-09 20:34:36 +00:00
/*
* Capture the subauthority count and hold it
* into the temporary array for later validation .
* This way we ensure that the said count of each
* SID has remained the same .
*/
ValidateArray [ i ] . SubAuthorityCount = Sid - > SubAuthorityCount ;
/* Capture the SID */
ValidateArray [ i ] . ProbeSid = Sid ;
2014-01-17 21:58:28 +00:00
/* Calculate the SID length and probe the full SID */
2021-11-09 20:34:36 +00:00
SidLength = RtlLengthRequiredSid ( ValidateArray [ i ] . SubAuthorityCount ) ;
ProbeForRead ( ValidateArray [ i ] . ProbeSid , SidLength , sizeof ( ULONG ) ) ;
2014-01-17 21:58:28 +00:00
/* Add the aligned length to the required length */
RequiredLength + = ALIGN_UP_BY ( SidLength , sizeof ( ULONG ) ) ;
}
}
_SEH2_EXCEPT ( EXCEPTION_EXECUTE_HANDLER )
{
2021-11-09 20:34:36 +00:00
Status = _SEH2_GetExceptionCode ( ) ;
_SEH2_YIELD ( goto Cleanup ) ;
2014-01-17 21:58:28 +00:00
}
_SEH2_END ;
}
else
{
/* Loop the array elements */
for ( i = 0 ; i < AttributeCount ; i + + )
{
/* Get the SID and it's length */
Sid = SrcSidAndAttributes [ i ] . Sid ;
SidLength = RtlLengthRequiredSid ( Sid - > SubAuthorityCount ) ;
/* Add the aligned length to the required length */
RequiredLength + = ALIGN_UP_BY ( SidLength , sizeof ( ULONG ) ) ;
}
}
/* Assume success */
Status = STATUS_SUCCESS ;
* ResultLength = RequiredLength ;
/* Check if we have no buffer */
if ( AllocatedMem = = NULL )
{
/* Allocate a new buffer */
SidAndAttributes = ExAllocatePoolWithTag ( PoolType ,
RequiredLength ,
TAG_SID_AND_ATTRIBUTES ) ;
if ( SidAndAttributes = = NULL )
{
2021-11-09 20:34:36 +00:00
DPRINT1 ( " SeCaptureSidAndAttributesArray(): Failed to allocate memory for SID and attributes array (requested size -> %lu)! \n " , RequiredLength ) ;
Status = STATUS_INSUFFICIENT_RESOURCES ;
goto Cleanup ;
2014-01-17 21:58:28 +00:00
}
}
/* Otherwise check if the buffer is large enough */
else if ( AllocatedLength > = RequiredLength )
{
/* Buffer is large enough, use it */
SidAndAttributes = AllocatedMem ;
}
else
{
/* Buffer is too small, fail */
2021-11-09 20:34:36 +00:00
DPRINT1 ( " SeCaptureSidAndAttributesArray(): The provided buffer is small (expected size -> %lu || current size -> %lu)! \n " , RequiredLength , AllocatedLength ) ;
Status = STATUS_BUFFER_TOO_SMALL ;
goto Cleanup ;
2014-01-17 21:58:28 +00:00
}
* CapturedSidAndAttributes = SidAndAttributes ;
/* Check again for user mode */
if ( PreviousMode ! = KernelMode )
{
_SEH2_TRY
{
/* The rest of the data starts after the array */
CurrentDest = ( PUCHAR ) SidAndAttributes ;
CurrentDest + = ALIGN_UP_BY ( ArraySize , sizeof ( ULONG ) ) ;
/* Loop the array elements */
for ( i = 0 ; i < AttributeCount ; i + + )
{
2021-11-09 20:34:36 +00:00
/*
* Get the SID length from the subauthority
* count we ' ve captured before .
*/
SidLength = RtlLengthRequiredSid ( ValidateArray [ i ] . SubAuthorityCount ) ;
2014-01-17 21:58:28 +00:00
/* Copy attributes */
SidAndAttributes [ i ] . Attributes = SrcSidAndAttributes [ i ] . Attributes ;
/* Copy the SID to the current destination address */
SidAndAttributes [ i ] . Sid = ( PSID ) CurrentDest ;
2021-11-09 20:34:36 +00:00
RtlCopyMemory ( CurrentDest , ValidateArray [ i ] . ProbeSid , SidLength ) ;
2014-01-17 21:58:28 +00:00
2021-11-09 20:34:36 +00:00
/* Obtain the SID we've captured before for validation */
Sid = SidAndAttributes [ i ] . Sid ;
/* Validate that the subauthority count hasn't changed */
if ( ValidateArray [ i ] . SubAuthorityCount ! =
Sid - > SubAuthorityCount )
{
/* It's changed, bail out */
DPRINT1 ( " SeCaptureSidAndAttributesArray(): The subauthority counts have changed (captured count -> %u || current count -> %u) \n " ,
ValidateArray [ i ] . SubAuthorityCount , Sid - > SubAuthorityCount ) ;
Status = STATUS_INVALID_SID ;
goto Cleanup ;
}
/* Validate that the SID length is the same */
if ( SidLength ! = RtlLengthSid ( Sid ) )
{
/* They're no longer the same, bail out */
DPRINT1 ( " SeCaptureSidAndAttributesArray(): The SID lengths have changed (captured length -> %lu || current length -> %lu) \n " ,
SidLength , RtlLengthSid ( Sid ) ) ;
Status = STATUS_INVALID_SID ;
goto Cleanup ;
}
/* Check that the SID is valid */
if ( ! RtlValidSid ( Sid ) )
{
DPRINT1 ( " SeCaptureSidAndAttributesArray(): The SID is not valid! \n " ) ;
Status = STATUS_INVALID_SID ;
goto Cleanup ;
}
2014-01-17 21:58:28 +00:00
/* Update the current destination address */
CurrentDest + = ALIGN_UP_BY ( SidLength , sizeof ( ULONG ) ) ;
}
}
_SEH2_EXCEPT ( EXCEPTION_EXECUTE_HANDLER )
{
Status = _SEH2_GetExceptionCode ( ) ;
}
_SEH2_END ;
}
else
{
/* The rest of the data starts after the array */
CurrentDest = ( PUCHAR ) SidAndAttributes ;
CurrentDest + = ALIGN_UP_BY ( ArraySize , sizeof ( ULONG ) ) ;
/* Loop the array elements */
for ( i = 0 ; i < AttributeCount ; i + + )
{
/* Get the SID and it's length */
Sid = SrcSidAndAttributes [ i ] . Sid ;
SidLength = RtlLengthRequiredSid ( Sid - > SubAuthorityCount ) ;
2014-01-17 23:13:38 +00:00
/* Copy attributes */
SidAndAttributes [ i ] . Attributes = SrcSidAndAttributes [ i ] . Attributes ;
2014-01-17 21:58:28 +00:00
/* Copy the SID to the current destination address */
SidAndAttributes [ i ] . Sid = ( PSID ) CurrentDest ;
RtlCopyMemory ( CurrentDest , SrcSidAndAttributes [ i ] . Sid , SidLength ) ;
/* Update the current destination address */
CurrentDest + = ALIGN_UP_BY ( SidLength , sizeof ( ULONG ) ) ;
}
}
2021-11-09 20:34:36 +00:00
Cleanup :
2014-01-17 21:58:28 +00:00
/* Check for failure */
if ( ! NT_SUCCESS ( Status ) )
{
/* Check if we allocated a new array */
2021-11-09 20:34:36 +00:00
if ( ( SidAndAttributes ! = AllocatedMem ) & & ( SidAndAttributes ! = NULL ) )
2014-01-17 21:58:28 +00:00
{
/* Free the array */
ExFreePoolWithTag ( SidAndAttributes , TAG_SID_AND_ATTRIBUTES ) ;
}
/* Set returned address to NULL */
2021-11-09 20:34:36 +00:00
* CapturedSidAndAttributes = NULL ;
}
/* Free the temporary validation array */
if ( ( PreviousMode ! = KernelMode ) & & ( ValidateArray ! = NULL ) )
{
ExFreePoolWithTag ( ValidateArray , TAG_SID_VALIDATE ) ;
2014-01-17 21:58:28 +00:00
}
return Status ;
}
2021-08-11 14:24:45 +00:00
/**
* @ brief
* Releases a captured SID with attributes .
2021-09-13 01:33:14 +00:00
*
2021-08-11 14:24:45 +00:00
* @ param [ in ] CapturedSidAndAttributes
* The captured SID with attributes to be released .
2021-09-13 01:33:14 +00:00
*
2021-08-11 14:24:45 +00:00
* @ param [ in ] AccessMode
* Processor access level mode .
2021-09-13 01:33:14 +00:00
*
2021-08-11 14:24:45 +00:00
* @ param [ in ] CaptureIfKernel
* If set to TRUE , the releasing is done within the kernel .
* Otherwise the releasing is done in a kernel mode driver .
*
* @ return
* Nothing .
*/
2014-01-17 21:58:28 +00:00
VOID
NTAPI
SeReleaseSidAndAttributesArray (
_In_ _Post_invalid_ PSID_AND_ATTRIBUTES CapturedSidAndAttributes ,
_In_ KPROCESSOR_MODE AccessMode ,
_In_ BOOLEAN CaptureIfKernel )
{
PAGED_CODE ( ) ;
if ( ( CapturedSidAndAttributes ! = NULL ) & &
( ( AccessMode ! = KernelMode ) | | CaptureIfKernel ) )
{
ExFreePoolWithTag ( CapturedSidAndAttributes , TAG_SID_AND_ATTRIBUTES ) ;
}
}
1999-12-26 17:22:19 +00:00
/* EOF */