mirror of
https://github.com/reactos/reactos.git
synced 2024-06-26 07:51:52 +00:00
Thomas Weidenmueller <w3seek@reactos.com>
- Fix various security structures and constants - Add code to capture quality of service structures and ACLs - Secure buffer access in NtQueryInformationToken, NtSetInformationToken, NtNotifyChangeDirectoryFile and NtQueryDirectoryFile svn path=/trunk/; revision=13984
This commit is contained in:
parent
6830474b06
commit
322dbd6fba
|
@ -98,37 +98,36 @@ typedef struct _SEP_AUDIT_POLICY {
|
|||
} SEP_AUDIT_POLICY, *PSEP_AUDIT_POLICY;
|
||||
|
||||
typedef struct _TOKEN {
|
||||
TOKEN_SOURCE TokenSource; /* 0x00 */
|
||||
LUID TokenId; /* 0x10 */
|
||||
LUID AuthenticationId; /* 0x18 */
|
||||
LUID ParentTokenId; /* 0x20 */
|
||||
LARGE_INTEGER ExpirationTime; /* 0x28 */
|
||||
struct _ERESOURCE *TokenLock; /* 0x30 */
|
||||
ULONG Padding; /* 0x34 */
|
||||
SEP_AUDIT_POLICY AuditPolicy; /* 0x38 */
|
||||
LUID ModifiedId; /* 0x40 */
|
||||
ULONG SessionId; /* 0x48 */
|
||||
ULONG UserAndGroupCount; /* 0x4C */
|
||||
ULONG RestrictedSidCount; /* 0x50 */
|
||||
ULONG PrivilegeCount; /* 0x54 */
|
||||
ULONG VariableLength; /* 0x58 */
|
||||
ULONG DynamicCharged; /* 0x5C */
|
||||
ULONG DynamicAvailable; /* 0x60 */
|
||||
ULONG DefaultOwnerIndex; /* 0x64 */
|
||||
PSID_AND_ATTRIBUTES UserAndGroups; /* 0x68 */
|
||||
PSID_AND_ATTRIBUTES RestrictedSids; /* 0x6C */
|
||||
PSID PrimaryGroup; /* 0x70 */
|
||||
PLUID_AND_ATTRIBUTES Privileges; /* 0x74 */
|
||||
PULONG DynamicPart; /* 0x78 */
|
||||
PACL DefaultDacl; /* 0x7C */
|
||||
TOKEN_TYPE TokenType; /* 0x80 */
|
||||
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; /* 0x84 */
|
||||
ULONG TokenFlags; /* 0x88 */
|
||||
ULONG TokenInUse; /* 0x8C */
|
||||
PVOID ProxyData; /* 0x90 */
|
||||
PVOID AuditData; /* 0x94 */
|
||||
LUID OriginatingLogonSession; /* 0x98 */
|
||||
UCHAR VariablePart[1]; /* 0xA0 */
|
||||
TOKEN_SOURCE TokenSource; /* 0x00 */
|
||||
LUID TokenId; /* 0x10 */
|
||||
LUID AuthenticationId; /* 0x18 */
|
||||
LUID ParentTokenId; /* 0x20 */
|
||||
LARGE_INTEGER ExpirationTime; /* 0x28 */
|
||||
struct _ERESOURCE *TokenLock; /* 0x30 */
|
||||
SEP_AUDIT_POLICY AuditPolicy; /* 0x38 */
|
||||
LUID ModifiedId; /* 0x40 */
|
||||
ULONG SessionId; /* 0x48 */
|
||||
ULONG UserAndGroupCount; /* 0x4C */
|
||||
ULONG RestrictedSidCount; /* 0x50 */
|
||||
ULONG PrivilegeCount; /* 0x54 */
|
||||
ULONG VariableLength; /* 0x58 */
|
||||
ULONG DynamicCharged; /* 0x5C */
|
||||
ULONG DynamicAvailable; /* 0x60 */
|
||||
ULONG DefaultOwnerIndex; /* 0x64 */
|
||||
PSID_AND_ATTRIBUTES UserAndGroups; /* 0x68 */
|
||||
PSID_AND_ATTRIBUTES RestrictedSids; /* 0x6C */
|
||||
PSID PrimaryGroup; /* 0x70 */
|
||||
PLUID_AND_ATTRIBUTES Privileges; /* 0x74 */
|
||||
PULONG DynamicPart; /* 0x78 */
|
||||
PACL DefaultDacl; /* 0x7C */
|
||||
TOKEN_TYPE TokenType; /* 0x80 */
|
||||
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; /* 0x84 */
|
||||
ULONG TokenFlags; /* 0x88 */
|
||||
BOOLEAN TokenInUse; /* 0x8C */
|
||||
PVOID ProxyData; /* 0x90 */
|
||||
PVOID AuditData; /* 0x94 */
|
||||
LUID OriginatingLogonSession; /* 0x98 */
|
||||
ULONG VariablePart; /* 0xA0 */
|
||||
} TOKEN, *PTOKEN;
|
||||
|
||||
typedef PVOID PACCESS_TOKEN;
|
||||
|
|
|
@ -153,13 +153,14 @@ typedef struct _SECURITY_DESCRIPTOR_CONTEXT
|
|||
#define TOKEN_ADJUST_PRIVILEGES (0x0020L)
|
||||
#define TOKEN_ADJUST_GROUPS (0x0040L)
|
||||
#define TOKEN_ADJUST_DEFAULT (0x0080L)
|
||||
#define TOKEN_ADJUST_SESSIONID (0x0100L)
|
||||
|
||||
#define TOKEN_ALL_ACCESS (0xf00ffL)
|
||||
#define TOKEN_ALL_ACCESS (0xf01ffL)
|
||||
#define TOKEN_READ (0x20008L)
|
||||
#define TOKEN_WRITE (0x200e0L)
|
||||
#define TOKEN_EXECUTE (0x20000L)
|
||||
|
||||
typedef BOOL SECURITY_CONTEXT_TRACKING_MODE;
|
||||
typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE, *PSECURITY_CONTEXT_TRACKING_MODE;
|
||||
|
||||
#define SECURITY_STATIC_TRACKING (0)
|
||||
#define SECURITY_DYNAMIC_TRACKING (1)
|
||||
|
@ -192,12 +193,13 @@ typedef enum _TOKEN_INFORMATION_CLASS
|
|||
TokenOrigin
|
||||
} TOKEN_INFORMATION_CLASS;
|
||||
|
||||
typedef ULONG SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL;
|
||||
|
||||
#define SecurityAnonymous ((SECURITY_IMPERSONATION_LEVEL)0)
|
||||
#define SecurityIdentification ((SECURITY_IMPERSONATION_LEVEL)1)
|
||||
#define SecurityImpersonation ((SECURITY_IMPERSONATION_LEVEL)2)
|
||||
#define SecurityDelegation ((SECURITY_IMPERSONATION_LEVEL)3)
|
||||
typedef enum _SECURITY_IMPERSONATION_LEVEL
|
||||
{
|
||||
SecurityAnonymous,
|
||||
SecurityIdentification,
|
||||
SecurityImpersonation,
|
||||
SecurityDelegation
|
||||
} SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL;
|
||||
|
||||
typedef ULONG ACCESS_MASK, *PACCESS_MASK;
|
||||
typedef ULONG TOKEN_TYPE, *PTOKEN_TYPE;
|
||||
|
@ -339,6 +341,20 @@ typedef struct _TOKEN_GROUPS
|
|||
SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY];
|
||||
} TOKEN_GROUPS, *PTOKEN_GROUPS, *LPTOKEN_GROUPS;
|
||||
|
||||
typedef struct _TOKEN_GROUPS_AND_PRIVILEGES
|
||||
{
|
||||
ULONG SidCount;
|
||||
ULONG SidLength;
|
||||
PSID_AND_ATTRIBUTES Sids;
|
||||
ULONG RestrictedSidCount;
|
||||
ULONG RestrictedSidLength;
|
||||
PSID_AND_ATTRIBUTES RestrictedSids;
|
||||
ULONG PrivilegeCount;
|
||||
ULONG PrivilegeLength;
|
||||
PLUID_AND_ATTRIBUTES Privileges;
|
||||
LUID AuthenticationId;
|
||||
} TOKEN_GROUPS_AND_PRIVILEGES, *PTOKEN_GROUPS_AND_PRIVILEGES;
|
||||
|
||||
typedef struct _TOKEN_PRIVILEGES
|
||||
{
|
||||
DWORD PrivilegeCount;
|
||||
|
|
|
@ -200,7 +200,7 @@ RtlCopySidAndAttributesArray(ULONG Count,
|
|||
RtlCopySid(SidLength,
|
||||
SidArea,
|
||||
Src[i].Sid);
|
||||
SidArea = SidArea + SidLength;
|
||||
SidArea = (PVOID)((ULONG_PTR)SidArea + SidLength);
|
||||
}
|
||||
*RemainingSidArea = SidArea;
|
||||
*RemainingSidAreaSize = Length;
|
||||
|
|
|
@ -326,7 +326,7 @@ typedef struct _CAPTURED_OBJECT_ATTRIBUTES
|
|||
HANDLE RootDirectory;
|
||||
ULONG Attributes;
|
||||
PSECURITY_DESCRIPTOR SecurityDescriptor;
|
||||
/* PVOID SecurityQualityOfService; */
|
||||
PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
|
||||
} CAPTURED_OBJECT_ATTRIBUTES, *PCAPTURED_OBJECT_ATTRIBUTES;
|
||||
|
||||
NTSTATUS
|
||||
|
@ -377,10 +377,8 @@ typedef struct _INFORMATION_CLASS_INFO
|
|||
else if(ClassList[Class].RequiredSize##Mode > 0 && \
|
||||
(BufferLen) != ClassList[Class].RequiredSize##Mode) \
|
||||
{ \
|
||||
if((!(ClassList[Class].Flags & ICIF_##Mode##_SIZE_VARIABLE) && \
|
||||
(BufferLen) != ClassList[Class].RequiredSize##Mode) || \
|
||||
((ClassList[Class].Flags & ICIF_##Mode##_SIZE_VARIABLE) && \
|
||||
(BufferLen) < ClassList[Class].RequiredSize##Mode)) \
|
||||
if(!(ClassList[Class].Flags & ICIF_##Mode##_SIZE_VARIABLE) && \
|
||||
(BufferLen) != ClassList[Class].RequiredSize##Mode) \
|
||||
{ \
|
||||
*(StatusVar) = STATUS_INFO_LENGTH_MISMATCH; \
|
||||
} \
|
||||
|
|
|
@ -148,6 +148,60 @@ SepPrivilegeCheck(PTOKEN Token,
|
|||
ULONG PrivilegeControl,
|
||||
KPROCESSOR_MODE PreviousMode);
|
||||
|
||||
NTSTATUS
|
||||
SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
||||
IN KPROCESSOR_MODE AccessMode,
|
||||
IN POOL_TYPE PoolType,
|
||||
IN BOOLEAN CaptureIfKernel,
|
||||
OUT PSECURITY_QUALITY_OF_SERVICE *CapturedSecurityQualityOfService,
|
||||
OUT PBOOLEAN Present);
|
||||
|
||||
VOID
|
||||
SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService OPTIONAL,
|
||||
IN KPROCESSOR_MODE AccessMode,
|
||||
IN BOOLEAN CaptureIfKernel);
|
||||
|
||||
NTSTATUS
|
||||
SepCaptureSid(IN PSID InputSid,
|
||||
IN KPROCESSOR_MODE AccessMode,
|
||||
IN POOL_TYPE PoolType,
|
||||
IN BOOLEAN CaptureIfKernel,
|
||||
OUT PSID *CapturedSid);
|
||||
|
||||
VOID
|
||||
SepReleaseSid(IN PSID CapturedSid,
|
||||
IN KPROCESSOR_MODE AccessMode,
|
||||
IN BOOLEAN CaptureIfKernel);
|
||||
|
||||
NTSTATUS
|
||||
SepCaptureAcl(IN PACL InputAcl,
|
||||
IN KPROCESSOR_MODE AccessMode,
|
||||
IN POOL_TYPE PoolType,
|
||||
IN BOOLEAN CaptureIfKernel,
|
||||
OUT PACL *CapturedAcl);
|
||||
|
||||
VOID
|
||||
SepReleaseAcl(IN PACL CapturedAcl,
|
||||
IN KPROCESSOR_MODE AccessMode,
|
||||
IN BOOLEAN CaptureIfKernel);
|
||||
|
||||
#define SepAcquireTokenLockExclusive(Token) \
|
||||
do { \
|
||||
KeEnterCriticalRegion(); \
|
||||
ExAcquireResourceExclusive(((PTOKEN)Token)->TokenLock, TRUE); \
|
||||
while(0)
|
||||
|
||||
#define SepAcquireTokenLockShared(Token) \
|
||||
do { \
|
||||
KeEnterCriticalRegion(); \
|
||||
ExAcquireResourceShared(((PTOKEN)Token)->TokenLock, TRUE); \
|
||||
while(0)
|
||||
|
||||
#define SepReleaseTokenLock(Token) \
|
||||
do { \
|
||||
ExReleaseResource(((PTOKEN)Token)->TokenLock); \
|
||||
KeLeaveCriticalRegion(); \
|
||||
while(0)
|
||||
|
||||
#endif /* __NTOSKRNL_INCLUDE_INTERNAL_SE_H */
|
||||
|
||||
|
|
|
@ -38,13 +38,41 @@ NtNotifyChangeDirectoryFile (
|
|||
PIRP Irp;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PFILE_OBJECT FileObject;
|
||||
NTSTATUS Status;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
KPROCESSOR_MODE PreviousMode;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
DPRINT("NtNotifyChangeDirectoryFile()\n");
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
PreviousMode = ExGetPreviousMode();
|
||||
|
||||
if(PreviousMode != KernelMode)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
ProbeForWrite(IoStatusBlock,
|
||||
sizeof(IO_STATUS_BLOCK),
|
||||
sizeof(ULONG));
|
||||
if(BufferSize != 0)
|
||||
{
|
||||
ProbeForWrite(Buffer,
|
||||
BufferSize,
|
||||
sizeof(ULONG));
|
||||
}
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
Status = ObReferenceObjectByHandle(FileHandle,
|
||||
FILE_LIST_DIRECTORY,
|
||||
|
@ -155,13 +183,38 @@ NtQueryDirectoryFile(
|
|||
PIRP Irp;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
PFILE_OBJECT FileObject;
|
||||
NTSTATUS Status;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
KPROCESSOR_MODE PreviousMode;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
DPRINT("NtQueryDirectoryFile()\n");
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
PreviousMode = ExGetPreviousMode();
|
||||
|
||||
if(PreviousMode != KernelMode)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
ProbeForWrite(IoStatusBlock,
|
||||
sizeof(IO_STATUS_BLOCK),
|
||||
sizeof(ULONG));
|
||||
ProbeForWrite(FileInformation,
|
||||
Length,
|
||||
sizeof(ULONG));
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
Status = ObReferenceObjectByHandle(FileHandle,
|
||||
FILE_LIST_DIRECTORY,
|
||||
|
|
|
@ -102,6 +102,7 @@ ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
|||
CapturedObjectAttributes->RootDirectory = ObjectAttributes->RootDirectory;
|
||||
CapturedObjectAttributes->Attributes = ObjectAttributes->Attributes;
|
||||
CapturedObjectAttributes->SecurityDescriptor = ObjectAttributes->SecurityDescriptor;
|
||||
CapturedObjectAttributes->SecurityQualityOfService = ObjectAttributes->SecurityQualityOfService;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
@ -147,6 +148,53 @@ ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
|||
{
|
||||
CapturedObjectAttributes->SecurityDescriptor = NULL;
|
||||
}
|
||||
|
||||
if(AttributesCopy.SecurityQualityOfService != NULL)
|
||||
{
|
||||
SECURITY_QUALITY_OF_SERVICE SafeQoS;
|
||||
|
||||
_SEH_TRY
|
||||
{
|
||||
ProbeForRead(AttributesCopy.SecurityQualityOfService,
|
||||
sizeof(SECURITY_QUALITY_OF_SERVICE),
|
||||
sizeof(ULONG));
|
||||
SafeQoS = *(PSECURITY_QUALITY_OF_SERVICE)AttributesCopy.SecurityQualityOfService;
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Unable to capture QoS!!!\n");
|
||||
goto failcleanupsdescriptor;
|
||||
}
|
||||
|
||||
if(SafeQoS.Length != sizeof(SECURITY_QUALITY_OF_SERVICE))
|
||||
{
|
||||
DPRINT1("Unable to capture QoS, wrong size!!!\n");
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
goto failcleanupsdescriptor;
|
||||
}
|
||||
|
||||
CapturedObjectAttributes->SecurityQualityOfService = ExAllocatePool(PoolType,
|
||||
sizeof(SECURITY_QUALITY_OF_SERVICE));
|
||||
if(CapturedObjectAttributes->SecurityQualityOfService != NULL)
|
||||
{
|
||||
*CapturedObjectAttributes->SecurityQualityOfService = SafeQoS;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto failcleanupsdescriptor;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CapturedObjectAttributes->SecurityQualityOfService = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if(ObjectName != NULL)
|
||||
|
@ -259,6 +307,8 @@ ObpCaptureObjectAttributes(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
|||
{
|
||||
ExFreePool(ObjectName->Buffer);
|
||||
}
|
||||
|
||||
failcleanupsdescriptor:
|
||||
if(CapturedObjectAttributes != NULL)
|
||||
{
|
||||
/* cleanup allocated resources */
|
||||
|
@ -293,11 +343,18 @@ ObpReleaseObjectAttributes(IN PCAPTURED_OBJECT_ATTRIBUTES CapturedObjectAttribut
|
|||
to ObpCaptureObjectAttributes() to avoid memory leaks */
|
||||
if(AccessMode != KernelMode || CaptureIfKernel)
|
||||
{
|
||||
if(CapturedObjectAttributes != NULL &&
|
||||
CapturedObjectAttributes->SecurityDescriptor != NULL)
|
||||
if(CapturedObjectAttributes != NULL)
|
||||
{
|
||||
ExFreePool(CapturedObjectAttributes->SecurityDescriptor);
|
||||
CapturedObjectAttributes->SecurityDescriptor = NULL;
|
||||
if(CapturedObjectAttributes->SecurityDescriptor != NULL)
|
||||
{
|
||||
ExFreePool(CapturedObjectAttributes->SecurityDescriptor);
|
||||
CapturedObjectAttributes->SecurityDescriptor = NULL;
|
||||
}
|
||||
if(CapturedObjectAttributes->SecurityQualityOfService != NULL)
|
||||
{
|
||||
ExFreePool(CapturedObjectAttributes->SecurityQualityOfService);
|
||||
CapturedObjectAttributes->SecurityQualityOfService = NULL;
|
||||
}
|
||||
}
|
||||
if(ObjectName != NULL &&
|
||||
ObjectName->Length > 0)
|
||||
|
|
|
@ -263,4 +263,105 @@ SepCreateImpersonationTokenDacl(PTOKEN Token,
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
SepCaptureAcl(IN PACL InputAcl,
|
||||
IN KPROCESSOR_MODE AccessMode,
|
||||
IN POOL_TYPE PoolType,
|
||||
IN BOOLEAN CaptureIfKernel,
|
||||
OUT PACL *CapturedAcl)
|
||||
{
|
||||
PACL NewAcl;
|
||||
ULONG AclSize = 0;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
if(AccessMode != KernelMode)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
ProbeForRead(InputAcl,
|
||||
sizeof(ACL),
|
||||
sizeof(ULONG));
|
||||
AclSize = InputAcl->AclSize;
|
||||
ProbeForRead(InputAcl,
|
||||
AclSize,
|
||||
sizeof(ULONG));
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
if(NT_SUCCESS(Status))
|
||||
{
|
||||
NewAcl = ExAllocatePool(PoolType,
|
||||
AclSize);
|
||||
if(NewAcl != NULL)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
RtlCopyMemory(NewAcl,
|
||||
InputAcl,
|
||||
AclSize);
|
||||
|
||||
*CapturedAcl = NewAcl;
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
ExFreePool(NewAcl);
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(!CaptureIfKernel)
|
||||
{
|
||||
*CapturedAcl = InputAcl;
|
||||
}
|
||||
else
|
||||
{
|
||||
AclSize = InputAcl->AclSize;
|
||||
|
||||
NewAcl = ExAllocatePool(PoolType,
|
||||
AclSize);
|
||||
|
||||
if(NewAcl != NULL)
|
||||
{
|
||||
RtlCopyMemory(NewAcl,
|
||||
InputAcl,
|
||||
AclSize);
|
||||
|
||||
*CapturedAcl = NewAcl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
VOID
|
||||
SepReleaseAcl(IN PACL CapturedAcl,
|
||||
IN KPROCESSOR_MODE AccessMode,
|
||||
IN BOOLEAN CaptureIfKernel)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
if(CapturedAcl != NULL &&
|
||||
(AccessMode == UserMode ||
|
||||
(AccessMode == KernelMode && CaptureIfKernel)))
|
||||
{
|
||||
ExFreePool(CapturedAcl);
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -102,32 +102,4 @@ NtAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId)
|
|||
return Status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID STDCALL
|
||||
RtlCopyLuid(IN PLUID LuidDest,
|
||||
IN PLUID LuidSrc)
|
||||
{
|
||||
PAGED_CODE_RTL();
|
||||
|
||||
LuidDest->LowPart = LuidSrc->LowPart;
|
||||
LuidDest->HighPart = LuidSrc->HighPart;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOLEAN STDCALL
|
||||
RtlEqualLuid(IN PLUID Luid1,
|
||||
IN PLUID Luid2)
|
||||
{
|
||||
PAGED_CODE_RTL();
|
||||
|
||||
return (Luid1->LowPart == Luid2->LowPart &&
|
||||
Luid1->HighPart == Luid2->HighPart);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -108,6 +108,174 @@ SepInitSDs(VOID)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
||||
IN KPROCESSOR_MODE AccessMode,
|
||||
IN POOL_TYPE PoolType,
|
||||
IN BOOLEAN CaptureIfKernel,
|
||||
OUT PSECURITY_QUALITY_OF_SERVICE *CapturedSecurityQualityOfService,
|
||||
OUT PBOOLEAN Present)
|
||||
{
|
||||
PSECURITY_QUALITY_OF_SERVICE CapturedQos;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
ASSERT(CapturedSecurityQualityOfService);
|
||||
ASSERT(Present);
|
||||
|
||||
if(ObjectAttributes != NULL)
|
||||
{
|
||||
if(AccessMode != KernelMode)
|
||||
{
|
||||
SECURITY_QUALITY_OF_SERVICE SafeQos;
|
||||
|
||||
_SEH_TRY
|
||||
{
|
||||
ProbeForRead(ObjectAttributes,
|
||||
sizeof(ObjectAttributes),
|
||||
sizeof(ULONG));
|
||||
if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
|
||||
{
|
||||
if(ObjectAttributes->SecurityQualityOfService != NULL)
|
||||
{
|
||||
ProbeForRead(ObjectAttributes->SecurityQualityOfService,
|
||||
sizeof(SECURITY_QUALITY_OF_SERVICE),
|
||||
sizeof(ULONG));
|
||||
|
||||
if(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length ==
|
||||
sizeof(SECURITY_QUALITY_OF_SERVICE))
|
||||
{
|
||||
/* don't allocate memory here because ExAllocate should bugcheck
|
||||
the system if it's buggy, SEH would catch that! So make a local
|
||||
copy of the qos structure.*/
|
||||
RtlCopyMemory(&SafeQos,
|
||||
ObjectAttributes->SecurityQualityOfService,
|
||||
sizeof(SECURITY_QUALITY_OF_SERVICE));
|
||||
*Present = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*CapturedSecurityQualityOfService = NULL;
|
||||
*Present = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
if(NT_SUCCESS(Status))
|
||||
{
|
||||
if(*Present)
|
||||
{
|
||||
CapturedQos = ExAllocatePool(PoolType,
|
||||
sizeof(SECURITY_QUALITY_OF_SERVICE));
|
||||
if(CapturedQos != NULL)
|
||||
{
|
||||
RtlCopyMemory(CapturedQos,
|
||||
&SafeQos,
|
||||
sizeof(SECURITY_QUALITY_OF_SERVICE));
|
||||
*CapturedSecurityQualityOfService = CapturedQos;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*CapturedSecurityQualityOfService = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
|
||||
{
|
||||
if(CaptureIfKernel)
|
||||
{
|
||||
if(ObjectAttributes->SecurityQualityOfService != NULL)
|
||||
{
|
||||
if(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length ==
|
||||
sizeof(SECURITY_QUALITY_OF_SERVICE))
|
||||
{
|
||||
CapturedQos = ExAllocatePool(PoolType,
|
||||
sizeof(SECURITY_QUALITY_OF_SERVICE));
|
||||
if(CapturedQos != NULL)
|
||||
{
|
||||
RtlCopyMemory(CapturedQos,
|
||||
ObjectAttributes->SecurityQualityOfService,
|
||||
sizeof(SECURITY_QUALITY_OF_SERVICE));
|
||||
*CapturedSecurityQualityOfService = CapturedQos;
|
||||
*Present = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*CapturedSecurityQualityOfService = NULL;
|
||||
*Present = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*CapturedSecurityQualityOfService = (PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService;
|
||||
*Present = (ObjectAttributes->SecurityQualityOfService != NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*CapturedSecurityQualityOfService = NULL;
|
||||
*Present = FALSE;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService OPTIONAL,
|
||||
IN KPROCESSOR_MODE AccessMode,
|
||||
IN BOOLEAN CaptureIfKernel)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
if(CapturedSecurityQualityOfService != NULL &&
|
||||
(AccessMode == UserMode ||
|
||||
(AccessMode == KernelMode && CaptureIfKernel)))
|
||||
{
|
||||
ExFreePool(CapturedSecurityQualityOfService);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
@ -572,6 +740,8 @@ SeReleaseSecurityDescriptor(
|
|||
IN BOOLEAN CaptureIfKernelMode
|
||||
)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
/* WARNING! You need to call this function with the same value for CurrentMode
|
||||
and CaptureIfKernelMode that you previously passed to
|
||||
SeCaptureSecurityDescriptor() in order to avoid memory leaks! */
|
||||
|
|
|
@ -466,4 +466,107 @@ SepInitSecurityIDs(VOID)
|
|||
return(TRUE);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
SepCaptureSid(IN PSID InputSid,
|
||||
IN KPROCESSOR_MODE AccessMode,
|
||||
IN POOL_TYPE PoolType,
|
||||
IN BOOLEAN CaptureIfKernel,
|
||||
OUT PSID *CapturedSid)
|
||||
{
|
||||
ULONG SidSize = 0;
|
||||
PISID NewSid, Sid = (PISID)InputSid;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
if(AccessMode != KernelMode)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
ProbeForRead(Sid,
|
||||
sizeof(*Sid) - sizeof(Sid->SubAuthority),
|
||||
sizeof(UCHAR));
|
||||
SidSize = RtlLengthRequiredSid(Sid->SubAuthorityCount);
|
||||
ProbeForRead(Sid,
|
||||
SidSize,
|
||||
sizeof(UCHAR));
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
if(NT_SUCCESS(Status))
|
||||
{
|
||||
/* allocate a SID and copy it */
|
||||
NewSid = ExAllocatePool(PoolType,
|
||||
SidSize);
|
||||
if(NewSid != NULL)
|
||||
{
|
||||
_SEH_TRY
|
||||
{
|
||||
RtlCopyMemory(NewSid,
|
||||
Sid,
|
||||
SidSize);
|
||||
|
||||
*CapturedSid = NewSid;
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
ExFreePool(NewSid);
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(!CaptureIfKernel)
|
||||
{
|
||||
*CapturedSid = InputSid;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
SidSize = RtlLengthRequiredSid(Sid->SubAuthorityCount);
|
||||
|
||||
/* allocate a SID and copy it */
|
||||
NewSid = ExAllocatePool(PoolType,
|
||||
SidSize);
|
||||
if(NewSid != NULL)
|
||||
{
|
||||
RtlCopyMemory(NewSid,
|
||||
Sid,
|
||||
SidSize);
|
||||
|
||||
*CapturedSid = NewSid;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
VOID
|
||||
SepReleaseSid(IN PSID CapturedSid,
|
||||
IN KPROCESSOR_MODE AccessMode,
|
||||
IN BOOLEAN CaptureIfKernel)
|
||||
{
|
||||
PAGED_CODE();
|
||||
|
||||
if(CapturedSid != NULL &&
|
||||
(AccessMode == UserMode ||
|
||||
(AccessMode == KernelMode && CaptureIfKernel)))
|
||||
{
|
||||
ExFreePool(CapturedSid);
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue