2005-01-04 22:44:50 +00:00
|
|
|
/* $Id$
|
1999-12-26 17:22:19 +00:00
|
|
|
*
|
2005-01-26 13:58:37 +00:00
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS kernel
|
|
|
|
* FILE: ntoskrnl/se/sd.c
|
|
|
|
* PURPOSE: Security manager
|
2005-05-09 01:38:29 +00:00
|
|
|
*
|
2005-01-26 13:58:37 +00:00
|
|
|
* PROGRAMMERS: David Welch <welch@cwcom.net>
|
1999-12-26 15:50:53 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
|
2004-08-15 16:39:12 +00:00
|
|
|
#include <ntoskrnl.h>
|
1999-12-26 15:50:53 +00:00
|
|
|
#include <internal/debug.h>
|
|
|
|
|
2005-11-28 23:25:31 +00:00
|
|
|
#if defined (ALLOC_PRAGMA)
|
|
|
|
#pragma alloc_text(INIT, SepInitSDs)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2003-02-15 21:07:49 +00:00
|
|
|
/* GLOBALS ******************************************************************/
|
|
|
|
|
|
|
|
PSECURITY_DESCRIPTOR SePublicDefaultSd = NULL;
|
|
|
|
PSECURITY_DESCRIPTOR SePublicDefaultUnrestrictedSd = NULL;
|
|
|
|
PSECURITY_DESCRIPTOR SePublicOpenSd = NULL;
|
|
|
|
PSECURITY_DESCRIPTOR SePublicOpenUnrestrictedSd = NULL;
|
|
|
|
PSECURITY_DESCRIPTOR SeSystemDefaultSd = NULL;
|
|
|
|
PSECURITY_DESCRIPTOR SeUnrestrictedSd = NULL;
|
2002-02-20 20:16:49 +00:00
|
|
|
|
1999-12-26 15:50:53 +00:00
|
|
|
/* FUNCTIONS ***************************************************************/
|
|
|
|
|
2005-09-13 23:28:21 +00:00
|
|
|
BOOLEAN
|
|
|
|
INIT_FUNCTION
|
|
|
|
NTAPI
|
2002-02-20 20:16:49 +00:00
|
|
|
SepInitSDs(VOID)
|
|
|
|
{
|
2003-02-15 21:07:49 +00:00
|
|
|
/* Create PublicDefaultSd */
|
2005-05-25 04:16:56 +00:00
|
|
|
SePublicDefaultSd = ExAllocatePoolWithTag(PagedPool,
|
|
|
|
sizeof(SECURITY_DESCRIPTOR), TAG_SD);
|
2003-02-15 21:07:49 +00:00
|
|
|
if (SePublicDefaultSd == NULL)
|
2004-07-31 12:21:19 +00:00
|
|
|
return FALSE;
|
2003-02-15 21:07:49 +00:00
|
|
|
|
|
|
|
RtlCreateSecurityDescriptor(SePublicDefaultSd,
|
|
|
|
SECURITY_DESCRIPTOR_REVISION);
|
|
|
|
RtlSetDaclSecurityDescriptor(SePublicDefaultSd,
|
|
|
|
TRUE,
|
|
|
|
SePublicDefaultDacl,
|
|
|
|
FALSE);
|
|
|
|
|
|
|
|
/* Create PublicDefaultUnrestrictedSd */
|
2005-05-25 04:16:56 +00:00
|
|
|
SePublicDefaultUnrestrictedSd = ExAllocatePoolWithTag(PagedPool,
|
|
|
|
sizeof(SECURITY_DESCRIPTOR), TAG_SD);
|
2003-02-15 21:07:49 +00:00
|
|
|
if (SePublicDefaultUnrestrictedSd == NULL)
|
2004-07-31 12:21:19 +00:00
|
|
|
return FALSE;
|
2003-02-15 21:07:49 +00:00
|
|
|
|
|
|
|
RtlCreateSecurityDescriptor(SePublicDefaultUnrestrictedSd,
|
|
|
|
SECURITY_DESCRIPTOR_REVISION);
|
|
|
|
RtlSetDaclSecurityDescriptor(SePublicDefaultUnrestrictedSd,
|
|
|
|
TRUE,
|
|
|
|
SePublicDefaultUnrestrictedDacl,
|
|
|
|
FALSE);
|
|
|
|
|
|
|
|
/* Create PublicOpenSd */
|
2005-05-25 04:16:56 +00:00
|
|
|
SePublicOpenSd = ExAllocatePoolWithTag(PagedPool,
|
|
|
|
sizeof(SECURITY_DESCRIPTOR), TAG_SD);
|
2003-02-15 21:07:49 +00:00
|
|
|
if (SePublicOpenSd == NULL)
|
2004-07-31 12:21:19 +00:00
|
|
|
return FALSE;
|
2003-02-15 21:07:49 +00:00
|
|
|
|
|
|
|
RtlCreateSecurityDescriptor(SePublicOpenSd,
|
|
|
|
SECURITY_DESCRIPTOR_REVISION);
|
|
|
|
RtlSetDaclSecurityDescriptor(SePublicOpenSd,
|
|
|
|
TRUE,
|
|
|
|
SePublicOpenDacl,
|
|
|
|
FALSE);
|
|
|
|
|
|
|
|
/* Create PublicOpenUnrestrictedSd */
|
2005-05-25 04:16:56 +00:00
|
|
|
SePublicOpenUnrestrictedSd = ExAllocatePoolWithTag(PagedPool,
|
|
|
|
sizeof(SECURITY_DESCRIPTOR), TAG_SD);
|
2003-02-15 21:07:49 +00:00
|
|
|
if (SePublicOpenUnrestrictedSd == NULL)
|
2004-07-31 12:21:19 +00:00
|
|
|
return FALSE;
|
2003-02-15 21:07:49 +00:00
|
|
|
|
|
|
|
RtlCreateSecurityDescriptor(SePublicOpenUnrestrictedSd,
|
|
|
|
SECURITY_DESCRIPTOR_REVISION);
|
|
|
|
RtlSetDaclSecurityDescriptor(SePublicOpenUnrestrictedSd,
|
|
|
|
TRUE,
|
|
|
|
SePublicOpenUnrestrictedDacl,
|
|
|
|
FALSE);
|
|
|
|
|
|
|
|
/* Create SystemDefaultSd */
|
2005-05-25 04:16:56 +00:00
|
|
|
SeSystemDefaultSd = ExAllocatePoolWithTag(PagedPool,
|
|
|
|
sizeof(SECURITY_DESCRIPTOR), TAG_SD);
|
2003-02-15 21:07:49 +00:00
|
|
|
if (SeSystemDefaultSd == NULL)
|
2004-07-31 12:21:19 +00:00
|
|
|
return FALSE;
|
2003-02-15 21:07:49 +00:00
|
|
|
|
|
|
|
RtlCreateSecurityDescriptor(SeSystemDefaultSd,
|
|
|
|
SECURITY_DESCRIPTOR_REVISION);
|
|
|
|
RtlSetDaclSecurityDescriptor(SeSystemDefaultSd,
|
|
|
|
TRUE,
|
|
|
|
SeSystemDefaultDacl,
|
|
|
|
FALSE);
|
|
|
|
|
|
|
|
/* Create UnrestrictedSd */
|
2005-05-25 04:16:56 +00:00
|
|
|
SeUnrestrictedSd = ExAllocatePoolWithTag(PagedPool,
|
|
|
|
sizeof(SECURITY_DESCRIPTOR), TAG_SD);
|
2003-02-15 21:07:49 +00:00
|
|
|
if (SeUnrestrictedSd == NULL)
|
2004-07-31 12:21:19 +00:00
|
|
|
return FALSE;
|
2003-02-15 21:07:49 +00:00
|
|
|
|
|
|
|
RtlCreateSecurityDescriptor(SeUnrestrictedSd,
|
|
|
|
SECURITY_DESCRIPTOR_REVISION);
|
|
|
|
RtlSetDaclSecurityDescriptor(SeUnrestrictedSd,
|
|
|
|
TRUE,
|
|
|
|
SeUnrestrictedDacl,
|
|
|
|
FALSE);
|
|
|
|
|
2004-07-31 12:21:19 +00:00
|
|
|
return TRUE;
|
2002-02-20 20:16:49 +00:00
|
|
|
}
|
|
|
|
|
2005-05-09 03:58:35 +00:00
|
|
|
NTSTATUS
|
2006-07-05 20:36:56 +00:00
|
|
|
NTAPI
|
2005-05-09 03:58:35 +00:00
|
|
|
SeSetWorldSecurityDescriptor(SECURITY_INFORMATION SecurityInformation,
|
2005-11-28 21:40:21 +00:00
|
|
|
PISECURITY_DESCRIPTOR SecurityDescriptor,
|
2005-05-09 03:58:35 +00:00
|
|
|
PULONG BufferLength)
|
|
|
|
{
|
|
|
|
ULONG_PTR Current;
|
|
|
|
ULONG SidSize;
|
|
|
|
ULONG SdSize;
|
|
|
|
NTSTATUS Status;
|
2006-01-14 14:52:50 +00:00
|
|
|
PISECURITY_DESCRIPTOR_RELATIVE SdRel = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor;
|
2005-05-09 03:58:35 +00:00
|
|
|
|
|
|
|
DPRINT("SeSetWorldSecurityDescriptor() called\n");
|
|
|
|
|
|
|
|
if (SecurityInformation == 0)
|
|
|
|
{
|
|
|
|
return STATUS_ACCESS_DENIED;
|
|
|
|
}
|
|
|
|
|
2006-01-14 14:52:50 +00:00
|
|
|
/* calculate the minimum size of the buffer */
|
2005-05-09 03:58:35 +00:00
|
|
|
SidSize = RtlLengthSid(SeWorldSid);
|
2006-01-14 14:52:50 +00:00
|
|
|
SdSize = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
|
|
|
|
if (SecurityInformation & OWNER_SECURITY_INFORMATION)
|
|
|
|
SdSize += SidSize;
|
|
|
|
if (SecurityInformation & GROUP_SECURITY_INFORMATION)
|
|
|
|
SdSize += SidSize;
|
|
|
|
if (SecurityInformation & DACL_SECURITY_INFORMATION)
|
|
|
|
{
|
|
|
|
SdSize += sizeof(ACL) + sizeof(ACE) + SidSize;
|
|
|
|
}
|
2005-05-09 03:58:35 +00:00
|
|
|
|
|
|
|
if (*BufferLength < SdSize)
|
|
|
|
{
|
|
|
|
*BufferLength = SdSize;
|
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
|
|
|
}
|
|
|
|
|
|
|
|
*BufferLength = SdSize;
|
|
|
|
|
2006-01-14 14:52:50 +00:00
|
|
|
Status = RtlCreateSecurityDescriptorRelative(SdRel,
|
|
|
|
SECURITY_DESCRIPTOR_REVISION);
|
2005-05-09 03:58:35 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
2006-01-14 14:52:50 +00:00
|
|
|
Current = (ULONG_PTR)(SdRel + 1);
|
2005-05-09 03:58:35 +00:00
|
|
|
|
|
|
|
if (SecurityInformation & OWNER_SECURITY_INFORMATION)
|
|
|
|
{
|
|
|
|
RtlCopyMemory((PVOID)Current,
|
2006-01-14 14:52:50 +00:00
|
|
|
SeWorldSid,
|
|
|
|
SidSize);
|
2006-09-07 05:07:34 +00:00
|
|
|
SdRel->Owner = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)SdRel);
|
2005-05-09 03:58:35 +00:00
|
|
|
Current += SidSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (SecurityInformation & GROUP_SECURITY_INFORMATION)
|
|
|
|
{
|
|
|
|
RtlCopyMemory((PVOID)Current,
|
2006-01-14 14:52:50 +00:00
|
|
|
SeWorldSid,
|
|
|
|
SidSize);
|
2006-09-07 05:07:34 +00:00
|
|
|
SdRel->Group = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)SdRel);
|
2005-05-09 03:58:35 +00:00
|
|
|
Current += SidSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (SecurityInformation & DACL_SECURITY_INFORMATION)
|
|
|
|
{
|
2006-01-14 14:52:50 +00:00
|
|
|
PACL Dacl = (PACL)Current;
|
|
|
|
SdRel->Control |= SE_DACL_PRESENT;
|
|
|
|
|
|
|
|
Status = RtlCreateAcl(Dacl,
|
|
|
|
sizeof(ACL) + sizeof(ACE) + SidSize,
|
|
|
|
ACL_REVISION);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
return Status;
|
|
|
|
|
|
|
|
Status = RtlAddAccessAllowedAce(Dacl,
|
|
|
|
ACL_REVISION,
|
|
|
|
GENERIC_ALL,
|
|
|
|
SeWorldSid);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
return Status;
|
|
|
|
|
2006-09-07 05:07:34 +00:00
|
|
|
SdRel->Dacl = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)SdRel);
|
2005-05-09 03:58:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (SecurityInformation & SACL_SECURITY_INFORMATION)
|
|
|
|
{
|
2006-01-14 14:52:50 +00:00
|
|
|
/* FIXME - SdRel->Control |= SE_SACL_PRESENT; */
|
2005-05-09 03:58:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2005-03-12 22:16:02 +00:00
|
|
|
|
|
|
|
NTSTATUS
|
2005-09-13 23:28:21 +00:00
|
|
|
NTAPI
|
2005-03-12 22:16:02 +00:00
|
|
|
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
|
2005-09-13 23:28:21 +00:00
|
|
|
NTAPI
|
2005-03-12 22:16:02 +00:00
|
|
|
SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService OPTIONAL,
|
|
|
|
IN KPROCESSOR_MODE AccessMode,
|
|
|
|
IN BOOLEAN CaptureIfKernel)
|
|
|
|
{
|
|
|
|
PAGED_CODE();
|
|
|
|
|
|
|
|
if(CapturedSecurityQualityOfService != NULL &&
|
2006-01-22 23:28:05 +00:00
|
|
|
(AccessMode != KernelMode || CaptureIfKernel))
|
2005-03-12 22:16:02 +00:00
|
|
|
{
|
|
|
|
ExFreePool(CapturedSecurityQualityOfService);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-08-03 19:20:39 +00:00
|
|
|
/*
|
2005-01-21 02:14:52 +00:00
|
|
|
* @implemented
|
2004-08-03 19:20:39 +00:00
|
|
|
*/
|
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
|
|
|
SeCaptureSecurityDescriptor(
|
2005-11-28 21:40:21 +00:00
|
|
|
IN PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor,
|
2004-08-03 19:20:39 +00:00
|
|
|
IN KPROCESSOR_MODE CurrentMode,
|
|
|
|
IN POOL_TYPE PoolType,
|
|
|
|
IN BOOLEAN CaptureIfKernel,
|
|
|
|
OUT PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor
|
|
|
|
)
|
|
|
|
{
|
2005-11-28 21:40:21 +00:00
|
|
|
PISECURITY_DESCRIPTOR OriginalSecurityDescriptor = _OriginalSecurityDescriptor;
|
2005-01-21 02:14:52 +00:00
|
|
|
SECURITY_DESCRIPTOR DescriptorCopy;
|
2005-11-28 21:40:21 +00:00
|
|
|
PISECURITY_DESCRIPTOR NewDescriptor;
|
2005-01-21 02:14:52 +00:00
|
|
|
ULONG OwnerSAC = 0, GroupSAC = 0;
|
|
|
|
ULONG OwnerSize = 0, GroupSize = 0;
|
|
|
|
ULONG SaclSize = 0, DaclSize = 0;
|
2005-02-12 11:47:03 +00:00
|
|
|
ULONG DescriptorSize = 0;
|
2005-01-21 02:14:52 +00:00
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-01-21 02:14:52 +00:00
|
|
|
if(OriginalSecurityDescriptor != NULL)
|
|
|
|
{
|
|
|
|
if(CurrentMode != KernelMode)
|
|
|
|
{
|
2005-05-01 19:30:06 +00:00
|
|
|
RtlZeroMemory(&DescriptorCopy, sizeof(DescriptorCopy));
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-01-21 02:14:52 +00:00
|
|
|
_SEH_TRY
|
|
|
|
{
|
2005-02-12 11:47:03 +00:00
|
|
|
/* first only probe and copy until the control field of the descriptor
|
|
|
|
to determine whether it's a self-relative descriptor */
|
|
|
|
DescriptorSize = (ULONG)((ULONG_PTR)&OriginalSecurityDescriptor->Control -
|
|
|
|
(ULONG_PTR)OriginalSecurityDescriptor) +
|
|
|
|
sizeof(OriginalSecurityDescriptor->Control);
|
2005-01-21 02:14:52 +00:00
|
|
|
ProbeForRead(OriginalSecurityDescriptor,
|
2005-02-12 11:47:03 +00:00
|
|
|
DescriptorSize,
|
2005-01-21 02:14:52 +00:00
|
|
|
sizeof(ULONG));
|
|
|
|
|
2005-02-12 11:47:03 +00:00
|
|
|
if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
|
|
|
|
{
|
|
|
|
Status = STATUS_UNKNOWN_REVISION;
|
|
|
|
_SEH_LEAVE;
|
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-01-21 02:14:52 +00:00
|
|
|
/* make a copy on the stack */
|
2005-02-12 11:47:03 +00:00
|
|
|
DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision;
|
|
|
|
DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1;
|
|
|
|
DescriptorCopy.Control = OriginalSecurityDescriptor->Control;
|
|
|
|
DescriptorSize = ((DescriptorCopy.Control & SE_SELF_RELATIVE) ?
|
|
|
|
sizeof(SECURITY_DESCRIPTOR_RELATIVE) : sizeof(SECURITY_DESCRIPTOR));
|
|
|
|
|
|
|
|
/* probe and copy the entire security descriptor structure. The SIDs
|
|
|
|
and ACLs will be probed and copied later though */
|
|
|
|
ProbeForRead(OriginalSecurityDescriptor,
|
|
|
|
DescriptorSize,
|
|
|
|
sizeof(ULONG));
|
|
|
|
if(DescriptorCopy.Control & SE_SELF_RELATIVE)
|
|
|
|
{
|
2005-07-26 14:00:45 +00:00
|
|
|
PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-02-12 11:47:03 +00:00
|
|
|
DescriptorCopy.Owner = (PSID)RelSD->Owner;
|
|
|
|
DescriptorCopy.Group = (PSID)RelSD->Group;
|
|
|
|
DescriptorCopy.Sacl = (PACL)RelSD->Sacl;
|
|
|
|
DescriptorCopy.Dacl = (PACL)RelSD->Dacl;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DescriptorCopy.Owner = OriginalSecurityDescriptor->Owner;
|
|
|
|
DescriptorCopy.Group = OriginalSecurityDescriptor->Group;
|
|
|
|
DescriptorCopy.Sacl = OriginalSecurityDescriptor->Sacl;
|
|
|
|
DescriptorCopy.Dacl = OriginalSecurityDescriptor->Dacl;
|
|
|
|
}
|
2005-01-21 02:14:52 +00:00
|
|
|
}
|
|
|
|
_SEH_HANDLE
|
|
|
|
{
|
|
|
|
Status = _SEH_GetExceptionCode();
|
|
|
|
}
|
|
|
|
_SEH_END;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-01-21 02:14:52 +00:00
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
}
|
2005-01-24 00:09:04 +00:00
|
|
|
else if(!CaptureIfKernel)
|
|
|
|
{
|
|
|
|
if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
|
|
|
|
{
|
|
|
|
return STATUS_UNKNOWN_REVISION;
|
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-01-24 00:09:04 +00:00
|
|
|
*CapturedSecurityDescriptor = OriginalSecurityDescriptor;
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
2005-01-21 02:14:52 +00:00
|
|
|
else
|
|
|
|
{
|
2005-02-12 11:47:03 +00:00
|
|
|
if(OriginalSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
|
|
|
|
{
|
|
|
|
return STATUS_UNKNOWN_REVISION;
|
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-01-21 02:14:52 +00:00
|
|
|
/* make a copy on the stack */
|
2005-02-12 11:47:03 +00:00
|
|
|
DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision;
|
|
|
|
DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1;
|
|
|
|
DescriptorCopy.Control = OriginalSecurityDescriptor->Control;
|
|
|
|
DescriptorSize = ((DescriptorCopy.Control & SE_SELF_RELATIVE) ?
|
|
|
|
sizeof(SECURITY_DESCRIPTOR_RELATIVE) : sizeof(SECURITY_DESCRIPTOR));
|
|
|
|
if(DescriptorCopy.Control & SE_SELF_RELATIVE)
|
|
|
|
{
|
2005-07-26 14:00:45 +00:00
|
|
|
PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor;
|
2005-02-12 11:47:03 +00:00
|
|
|
|
|
|
|
DescriptorCopy.Owner = (PSID)RelSD->Owner;
|
|
|
|
DescriptorCopy.Group = (PSID)RelSD->Group;
|
|
|
|
DescriptorCopy.Sacl = (PACL)RelSD->Sacl;
|
|
|
|
DescriptorCopy.Dacl = (PACL)RelSD->Dacl;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DescriptorCopy.Owner = OriginalSecurityDescriptor->Owner;
|
|
|
|
DescriptorCopy.Group = OriginalSecurityDescriptor->Group;
|
|
|
|
DescriptorCopy.Sacl = OriginalSecurityDescriptor->Sacl;
|
|
|
|
DescriptorCopy.Dacl = OriginalSecurityDescriptor->Dacl;
|
|
|
|
}
|
2005-01-21 02:14:52 +00:00
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-01-21 02:14:52 +00:00
|
|
|
if(DescriptorCopy.Control & SE_SELF_RELATIVE)
|
|
|
|
{
|
|
|
|
/* in case we're dealing with a self-relative descriptor, do a basic convert
|
|
|
|
to an absolute descriptor. We do this so we can simply access the data
|
|
|
|
using the pointers without calculating them again. */
|
|
|
|
DescriptorCopy.Control &= ~SE_SELF_RELATIVE;
|
|
|
|
if(DescriptorCopy.Owner != NULL)
|
|
|
|
{
|
|
|
|
DescriptorCopy.Owner = (PSID)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Owner);
|
|
|
|
}
|
|
|
|
if(DescriptorCopy.Group != NULL)
|
|
|
|
{
|
|
|
|
DescriptorCopy.Group = (PSID)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Group);
|
|
|
|
}
|
|
|
|
if(DescriptorCopy.Dacl != NULL)
|
|
|
|
{
|
|
|
|
DescriptorCopy.Dacl = (PACL)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Dacl);
|
|
|
|
}
|
|
|
|
if(DescriptorCopy.Sacl != NULL)
|
|
|
|
{
|
|
|
|
DescriptorCopy.Sacl = (PACL)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Sacl);
|
|
|
|
}
|
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-01-21 02:14:52 +00:00
|
|
|
/* determine the size of the SIDs */
|
|
|
|
#define DetermineSIDSize(SidType) \
|
|
|
|
do { \
|
|
|
|
if(DescriptorCopy.SidType != NULL) \
|
|
|
|
{ \
|
|
|
|
SID *SidType = (SID*)DescriptorCopy.SidType; \
|
|
|
|
\
|
|
|
|
if(CurrentMode != KernelMode) \
|
|
|
|
{ \
|
|
|
|
/* securely access the buffers! */ \
|
|
|
|
_SEH_TRY \
|
|
|
|
{ \
|
|
|
|
ProbeForRead(&SidType->SubAuthorityCount, \
|
|
|
|
sizeof(SidType->SubAuthorityCount), \
|
|
|
|
1); \
|
|
|
|
SidType##SAC = SidType->SubAuthorityCount; \
|
|
|
|
SidType##Size = RtlLengthRequiredSid(SidType##SAC); \
|
2005-01-21 02:39:59 +00:00
|
|
|
DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \
|
2005-01-21 02:14:52 +00:00
|
|
|
ProbeForRead(SidType, \
|
|
|
|
SidType##Size, \
|
|
|
|
sizeof(ULONG)); \
|
|
|
|
} \
|
|
|
|
_SEH_HANDLE \
|
|
|
|
{ \
|
|
|
|
Status = _SEH_GetExceptionCode(); \
|
|
|
|
} \
|
|
|
|
_SEH_END; \
|
|
|
|
\
|
|
|
|
if(!NT_SUCCESS(Status)) \
|
|
|
|
{ \
|
|
|
|
return Status; \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
else \
|
|
|
|
{ \
|
|
|
|
SidType##SAC = SidType->SubAuthorityCount; \
|
|
|
|
SidType##Size = RtlLengthRequiredSid(SidType##SAC); \
|
2005-01-21 02:39:59 +00:00
|
|
|
DescriptorSize += ROUND_UP(SidType##Size, sizeof(ULONG)); \
|
2005-01-21 02:14:52 +00:00
|
|
|
} \
|
|
|
|
} \
|
|
|
|
} while(0)
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-01-21 02:14:52 +00:00
|
|
|
DetermineSIDSize(Owner);
|
|
|
|
DetermineSIDSize(Group);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-01-21 02:14:52 +00:00
|
|
|
/* determine the size of the ACLs */
|
|
|
|
#define DetermineACLSize(AclType, AclFlag) \
|
|
|
|
do { \
|
|
|
|
if((DescriptorCopy.Control & SE_##AclFlag##_PRESENT) && \
|
|
|
|
DescriptorCopy.AclType != NULL) \
|
|
|
|
{ \
|
|
|
|
PACL AclType = (PACL)DescriptorCopy.AclType; \
|
|
|
|
\
|
|
|
|
if(CurrentMode != KernelMode) \
|
|
|
|
{ \
|
|
|
|
/* securely access the buffers! */ \
|
|
|
|
_SEH_TRY \
|
|
|
|
{ \
|
|
|
|
ProbeForRead(&AclType->AclSize, \
|
|
|
|
sizeof(AclType->AclSize), \
|
|
|
|
1); \
|
|
|
|
AclType##Size = AclType->AclSize; \
|
2005-01-21 02:39:59 +00:00
|
|
|
DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \
|
2005-01-21 02:14:52 +00:00
|
|
|
ProbeForRead(AclType, \
|
|
|
|
AclType##Size, \
|
|
|
|
sizeof(ULONG)); \
|
|
|
|
} \
|
|
|
|
_SEH_HANDLE \
|
|
|
|
{ \
|
|
|
|
Status = _SEH_GetExceptionCode(); \
|
|
|
|
} \
|
|
|
|
_SEH_END; \
|
|
|
|
\
|
|
|
|
if(!NT_SUCCESS(Status)) \
|
|
|
|
{ \
|
|
|
|
return Status; \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
else \
|
|
|
|
{ \
|
|
|
|
AclType##Size = AclType->AclSize; \
|
2005-01-21 02:39:59 +00:00
|
|
|
DescriptorSize += ROUND_UP(AclType##Size, sizeof(ULONG)); \
|
2005-01-21 02:14:52 +00:00
|
|
|
} \
|
|
|
|
} \
|
|
|
|
else \
|
|
|
|
{ \
|
|
|
|
DescriptorCopy.AclType = NULL; \
|
|
|
|
} \
|
|
|
|
} while(0)
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-01-21 02:14:52 +00:00
|
|
|
DetermineACLSize(Sacl, SACL);
|
|
|
|
DetermineACLSize(Dacl, DACL);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-01-21 02:14:52 +00:00
|
|
|
/* allocate enough memory to store a complete copy of a self-relative
|
|
|
|
security descriptor */
|
2005-01-21 02:19:13 +00:00
|
|
|
NewDescriptor = ExAllocatePool(PoolType,
|
2005-01-21 02:14:52 +00:00
|
|
|
DescriptorSize);
|
|
|
|
if(NewDescriptor != NULL)
|
|
|
|
{
|
|
|
|
ULONG_PTR Offset = sizeof(SECURITY_DESCRIPTOR);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
Object Manager Patch. This patch continues the work done in the previous patch and makes the following changes in order to support OB 2.0 (it basically temporarily fixes a highly incorrect implementation so that caller code will be ready to work with the OB 2.0 without change):
1) The documented Object Create Information Structure and semantics implemented. All Object Attributes and passed data from user-mode is now probed and saved into this object create structure when ObCreateObject is called.
2) ObCreateObject does NOT PERFORM ANY OTHER OPERATION EXCEPT CREATING THE OBJECT ANYMORE. ObCreateObject will NOT insert the Object into the tree and other operations. These are now done correctly by ObInsertObject. Therefore, the biggest hurdle was changing pieces of code which assumed ObCreateObject would be enough.
3) ObInsertObject uses the captured create info for all operations isntead of the Object Attributes.
4) ObFindObject now uses the captured info as well.
5) The OBject name and directory are now stored in the documented Object Name Information, always allocated and freed from non paged pool.
HACKS:
5) Because the registry code is horribly broken and doesn't use ObFindObjectByName, the old ObFindObject had to be temporarily duplicated into CmpFindObject.
7) Win32k used ObInsertObject in CsrInsertObject as a way to create a handle inside csrss. However, OBInsertObject now does more then this. As a temporary hack, ObpCreateHandle is exported from the kernel and called from win32k. A fix needs to be done for this, but I don't know the design of win32k+csrss well enough to find a solution.
8) SEH has been commented out in some places of the new probing code because it breaks smss and explorer. These need to be investigated (seh did not exist in the previous code, so this is not really a hack)
9) Named objects with a parent directory are NOT allowed. However because of bugs in kernel32, the new check has been temporarily disabled. (this check did not exist in the previous code, so this is not really a hack)
The next patch will add a proper ObFindObject which will support a more complete Parse Procedure with context and security information. This is needed for proper registry access (requested by Eric Kohl) and for proper functionality of the Desktop/File creation, which should use the Parse routine, and not the Create Handle Routine. This will also make it possible to remove some previous hacks and pave the way for a fixed Iop/IoCreateFile
svn path=/trunk/; revision=15395
2005-05-18 19:26:47 +00:00
|
|
|
RtlZeroMemory(NewDescriptor, DescriptorSize);
|
2005-01-21 02:14:52 +00:00
|
|
|
NewDescriptor->Revision = DescriptorCopy.Revision;
|
|
|
|
NewDescriptor->Sbz1 = DescriptorCopy.Sbz1;
|
|
|
|
NewDescriptor->Control = DescriptorCopy.Control | SE_SELF_RELATIVE;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-01-21 02:14:52 +00:00
|
|
|
_SEH_TRY
|
|
|
|
{
|
2005-01-21 02:39:59 +00:00
|
|
|
/* setup the offsets and copy the SIDs and ACLs to the new
|
|
|
|
self-relative security descriptor. Probing the pointers is not
|
2006-01-22 23:28:05 +00:00
|
|
|
neccessary anymore as we did that when collecting the sizes!
|
|
|
|
Make sure to validate the SIDs and ACLs *again* as they could have
|
|
|
|
been modified in the meanwhile! */
|
|
|
|
#define CopySID(Type) \
|
2005-01-21 02:39:59 +00:00
|
|
|
do { \
|
|
|
|
if(DescriptorCopy.Type != NULL) \
|
|
|
|
{ \
|
|
|
|
NewDescriptor->Type = (PVOID)Offset; \
|
|
|
|
RtlCopyMemory((PVOID)((ULONG_PTR)NewDescriptor + \
|
|
|
|
(ULONG_PTR)NewDescriptor->Type), \
|
|
|
|
DescriptorCopy.Type, \
|
|
|
|
Type##Size); \
|
2006-01-22 23:28:05 +00:00
|
|
|
if (!RtlValidSid((PSID)((ULONG_PTR)NewDescriptor + \
|
|
|
|
(ULONG_PTR)NewDescriptor->Type))) \
|
|
|
|
{ \
|
|
|
|
RtlRaiseStatus(STATUS_INVALID_SID); \
|
|
|
|
} \
|
|
|
|
Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \
|
|
|
|
} \
|
|
|
|
} while(0)
|
|
|
|
|
|
|
|
CopySID(Owner);
|
|
|
|
CopySID(Group);
|
|
|
|
|
|
|
|
#define CopyACL(Type) \
|
|
|
|
do { \
|
|
|
|
if(DescriptorCopy.Type != NULL) \
|
|
|
|
{ \
|
|
|
|
NewDescriptor->Type = (PVOID)Offset; \
|
|
|
|
RtlCopyMemory((PVOID)((ULONG_PTR)NewDescriptor + \
|
|
|
|
(ULONG_PTR)NewDescriptor->Type), \
|
|
|
|
DescriptorCopy.Type, \
|
|
|
|
Type##Size); \
|
|
|
|
if (!RtlValidAcl((PACL)((ULONG_PTR)NewDescriptor + \
|
|
|
|
(ULONG_PTR)NewDescriptor->Type))) \
|
|
|
|
{ \
|
|
|
|
RtlRaiseStatus(STATUS_INVALID_ACL); \
|
|
|
|
} \
|
2005-01-21 02:39:59 +00:00
|
|
|
Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \
|
|
|
|
} \
|
|
|
|
} while(0)
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-01-22 23:28:05 +00:00
|
|
|
CopyACL(Sacl);
|
|
|
|
CopyACL(Dacl);
|
2005-01-21 02:14:52 +00:00
|
|
|
}
|
|
|
|
_SEH_HANDLE
|
|
|
|
{
|
|
|
|
Status = _SEH_GetExceptionCode();
|
|
|
|
}
|
|
|
|
_SEH_END;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-01-21 02:14:52 +00:00
|
|
|
if(NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* we're finally done! copy the pointer to the captured descriptor to
|
|
|
|
to the caller */
|
|
|
|
*CapturedSecurityDescriptor = NewDescriptor;
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* we failed to copy the data to the new descriptor */
|
|
|
|
ExFreePool(NewDescriptor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* nothing to do... */
|
|
|
|
*CapturedSecurityDescriptor = NULL;
|
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-01-21 02:14:52 +00:00
|
|
|
return Status;
|
2004-08-03 19:20:39 +00:00
|
|
|
}
|
2002-02-20 20:16:49 +00:00
|
|
|
|
2004-05-20 12:42:51 +00:00
|
|
|
/*
|
2004-07-31 12:21:19 +00:00
|
|
|
* @implemented
|
2004-05-20 12:42:51 +00:00
|
|
|
*/
|
|
|
|
NTSTATUS STDCALL
|
|
|
|
SeQuerySecurityDescriptorInfo(IN PSECURITY_INFORMATION SecurityInformation,
|
2004-07-31 12:21:19 +00:00
|
|
|
IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
|
2004-05-20 12:42:51 +00:00
|
|
|
IN OUT PULONG Length,
|
2004-07-31 12:21:19 +00:00
|
|
|
IN PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor OPTIONAL)
|
2004-05-20 12:42:51 +00:00
|
|
|
{
|
2005-11-28 21:40:21 +00:00
|
|
|
PISECURITY_DESCRIPTOR ObjectSd;
|
2005-07-26 14:00:45 +00:00
|
|
|
PISECURITY_DESCRIPTOR_RELATIVE RelSD;
|
2005-02-12 11:47:03 +00:00
|
|
|
PSID Owner = NULL;
|
|
|
|
PSID Group = NULL;
|
|
|
|
PACL Dacl = NULL;
|
|
|
|
PACL Sacl = NULL;
|
2004-07-31 12:21:19 +00:00
|
|
|
ULONG OwnerLength = 0;
|
|
|
|
ULONG GroupLength = 0;
|
|
|
|
ULONG DaclLength = 0;
|
|
|
|
ULONG SaclLength = 0;
|
|
|
|
ULONG Control = 0;
|
|
|
|
ULONG_PTR Current;
|
|
|
|
ULONG SdLength;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-07-26 14:00:45 +00:00
|
|
|
RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor;
|
2004-07-31 12:21:19 +00:00
|
|
|
|
|
|
|
if (*ObjectsSecurityDescriptor == NULL)
|
|
|
|
{
|
2005-02-12 11:47:03 +00:00
|
|
|
if (*Length < sizeof(SECURITY_DESCRIPTOR_RELATIVE))
|
2004-07-31 12:21:19 +00:00
|
|
|
{
|
2005-02-12 11:47:03 +00:00
|
|
|
*Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
|
2004-07-31 12:21:19 +00:00
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
|
|
|
}
|
|
|
|
|
2005-02-12 11:47:03 +00:00
|
|
|
*Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
|
|
|
|
RtlCreateSecurityDescriptorRelative(RelSD,
|
|
|
|
SECURITY_DESCRIPTOR_REVISION);
|
2004-07-31 12:21:19 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
ObjectSd = *ObjectsSecurityDescriptor;
|
|
|
|
|
|
|
|
/* Calculate the required security descriptor length */
|
|
|
|
Control = SE_SELF_RELATIVE;
|
|
|
|
if ((*SecurityInformation & OWNER_SECURITY_INFORMATION) &&
|
|
|
|
(ObjectSd->Owner != NULL))
|
|
|
|
{
|
|
|
|
Owner = (PSID)((ULONG_PTR)ObjectSd->Owner + (ULONG_PTR)ObjectSd);
|
|
|
|
OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
|
|
|
|
Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((*SecurityInformation & GROUP_SECURITY_INFORMATION) &&
|
|
|
|
(ObjectSd->Group != NULL))
|
|
|
|
{
|
|
|
|
Group = (PSID)((ULONG_PTR)ObjectSd->Group + (ULONG_PTR)ObjectSd);
|
|
|
|
GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
|
|
|
|
Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((*SecurityInformation & DACL_SECURITY_INFORMATION) &&
|
|
|
|
(ObjectSd->Control & SE_DACL_PRESENT))
|
|
|
|
{
|
|
|
|
if (ObjectSd->Dacl != NULL)
|
|
|
|
{
|
|
|
|
Dacl = (PACL)((ULONG_PTR)ObjectSd->Dacl + (ULONG_PTR)ObjectSd);
|
|
|
|
DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4);
|
|
|
|
}
|
|
|
|
Control |= (ObjectSd->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT));
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((*SecurityInformation & SACL_SECURITY_INFORMATION) &&
|
|
|
|
(ObjectSd->Control & SE_SACL_PRESENT))
|
|
|
|
{
|
|
|
|
if (ObjectSd->Sacl != NULL)
|
|
|
|
{
|
|
|
|
Sacl = (PACL)((ULONG_PTR)ObjectSd->Sacl + (ULONG_PTR)ObjectSd);
|
|
|
|
SaclLength = ROUND_UP(Sacl->AclSize, 4);
|
|
|
|
}
|
|
|
|
Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT));
|
|
|
|
}
|
|
|
|
|
|
|
|
SdLength = OwnerLength + GroupLength + DaclLength +
|
2005-02-12 11:47:03 +00:00
|
|
|
SaclLength + sizeof(SECURITY_DESCRIPTOR_RELATIVE);
|
|
|
|
if (*Length < SdLength)
|
2004-07-31 12:21:19 +00:00
|
|
|
{
|
|
|
|
*Length = SdLength;
|
|
|
|
return STATUS_BUFFER_TOO_SMALL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Build the new security descrtiptor */
|
2005-02-12 11:47:03 +00:00
|
|
|
RtlCreateSecurityDescriptorRelative(RelSD,
|
|
|
|
SECURITY_DESCRIPTOR_REVISION);
|
|
|
|
RelSD->Control = Control;
|
2004-07-31 12:21:19 +00:00
|
|
|
|
2005-02-12 11:47:03 +00:00
|
|
|
Current = (ULONG_PTR)(RelSD + 1);
|
2004-07-31 12:21:19 +00:00
|
|
|
|
|
|
|
if (OwnerLength != 0)
|
|
|
|
{
|
|
|
|
RtlCopyMemory((PVOID)Current,
|
|
|
|
Owner,
|
|
|
|
OwnerLength);
|
2005-02-12 11:47:03 +00:00
|
|
|
RelSD->Owner = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
|
2004-07-31 12:21:19 +00:00
|
|
|
Current += OwnerLength;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GroupLength != 0)
|
|
|
|
{
|
|
|
|
RtlCopyMemory((PVOID)Current,
|
|
|
|
Group,
|
|
|
|
GroupLength);
|
2005-02-12 11:47:03 +00:00
|
|
|
RelSD->Group = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
|
2004-07-31 12:21:19 +00:00
|
|
|
Current += GroupLength;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (DaclLength != 0)
|
|
|
|
{
|
|
|
|
RtlCopyMemory((PVOID)Current,
|
|
|
|
Dacl,
|
|
|
|
DaclLength);
|
2005-02-12 11:47:03 +00:00
|
|
|
RelSD->Dacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
|
2004-07-31 12:21:19 +00:00
|
|
|
Current += DaclLength;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (SaclLength != 0)
|
|
|
|
{
|
|
|
|
RtlCopyMemory((PVOID)Current,
|
|
|
|
Sacl,
|
|
|
|
SaclLength);
|
2005-02-12 11:47:03 +00:00
|
|
|
RelSD->Sacl = (ULONG)(Current - (ULONG_PTR)SecurityDescriptor);
|
2004-07-31 12:21:19 +00:00
|
|
|
Current += SaclLength;
|
|
|
|
}
|
|
|
|
|
|
|
|
*Length = SdLength;
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
2004-05-20 12:42:51 +00:00
|
|
|
}
|
|
|
|
|
2004-08-03 19:20:39 +00:00
|
|
|
/*
|
2005-01-21 02:14:52 +00:00
|
|
|
* @implemented
|
2004-08-03 19:20:39 +00:00
|
|
|
*/
|
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
|
|
|
SeReleaseSecurityDescriptor(
|
|
|
|
IN PSECURITY_DESCRIPTOR CapturedSecurityDescriptor,
|
|
|
|
IN KPROCESSOR_MODE CurrentMode,
|
|
|
|
IN BOOLEAN CaptureIfKernelMode
|
|
|
|
)
|
|
|
|
{
|
2005-03-12 22:16:02 +00:00
|
|
|
PAGED_CODE();
|
|
|
|
|
2005-01-21 02:14:52 +00:00
|
|
|
/* 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! */
|
|
|
|
if(CapturedSecurityDescriptor != NULL &&
|
2005-08-21 19:04:23 +00:00
|
|
|
(CurrentMode != KernelMode ||
|
2005-01-21 02:14:52 +00:00
|
|
|
(CurrentMode == KernelMode && CaptureIfKernelMode)))
|
|
|
|
{
|
|
|
|
/* only delete the descriptor when SeCaptureSecurityDescriptor() allocated one! */
|
|
|
|
ExFreePool(CapturedSecurityDescriptor);
|
|
|
|
}
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
2004-08-03 19:20:39 +00:00
|
|
|
}
|
2004-05-20 12:42:51 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
|
|
|
NTSTATUS STDCALL
|
|
|
|
SeSetSecurityDescriptorInfo(IN PVOID Object OPTIONAL,
|
|
|
|
IN PSECURITY_INFORMATION SecurityInformation,
|
|
|
|
IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
|
|
|
IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
|
|
|
|
IN POOL_TYPE PoolType,
|
|
|
|
IN PGENERIC_MAPPING GenericMapping)
|
|
|
|
{
|
|
|
|
UNIMPLEMENTED;
|
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
2004-08-03 19:20:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
|
|
|
NTSTATUS
|
|
|
|
STDCALL
|
|
|
|
SeSetSecurityDescriptorInfoEx(
|
|
|
|
IN PVOID Object OPTIONAL,
|
|
|
|
IN PSECURITY_INFORMATION SecurityInformation,
|
|
|
|
IN PSECURITY_DESCRIPTOR ModificationDescriptor,
|
|
|
|
IN OUT PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
|
|
|
|
IN ULONG AutoInheritFlags,
|
|
|
|
IN POOL_TYPE PoolType,
|
|
|
|
IN PGENERIC_MAPPING GenericMapping
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UNIMPLEMENTED;
|
|
|
|
return STATUS_NOT_IMPLEMENTED;
|
2004-05-20 12:42:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2004-07-26 12:44:40 +00:00
|
|
|
* @implemented
|
2004-05-20 12:42:51 +00:00
|
|
|
*/
|
|
|
|
BOOLEAN STDCALL
|
|
|
|
SeValidSecurityDescriptor(IN ULONG Length,
|
2005-11-28 21:40:21 +00:00
|
|
|
IN PSECURITY_DESCRIPTOR _SecurityDescriptor)
|
2004-05-20 12:42:51 +00:00
|
|
|
{
|
2004-07-26 12:44:40 +00:00
|
|
|
ULONG SdLength;
|
2005-01-04 22:44:50 +00:00
|
|
|
PISID Sid;
|
2004-07-26 12:44:40 +00:00
|
|
|
PACL Acl;
|
2005-11-28 21:40:21 +00:00
|
|
|
PISECURITY_DESCRIPTOR SecurityDescriptor = _SecurityDescriptor;
|
2004-07-26 12:44:40 +00:00
|
|
|
|
|
|
|
if (Length < SECURITY_DESCRIPTOR_MIN_LENGTH)
|
|
|
|
{
|
|
|
|
DPRINT1("Invalid Security Descriptor revision\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (SecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION1)
|
|
|
|
{
|
|
|
|
DPRINT1("Invalid Security Descriptor revision\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(SecurityDescriptor->Control & SE_SELF_RELATIVE))
|
|
|
|
{
|
|
|
|
DPRINT1("No self-relative Security Descriptor\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
SdLength = sizeof(SECURITY_DESCRIPTOR);
|
|
|
|
|
|
|
|
/* Check Owner SID */
|
|
|
|
if (SecurityDescriptor->Owner == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1("No Owner SID\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((ULONG_PTR)SecurityDescriptor->Owner % sizeof(ULONG))
|
|
|
|
{
|
|
|
|
DPRINT1("Invalid Owner SID alignment\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2005-01-04 22:44:50 +00:00
|
|
|
Sid = (PISID)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Owner);
|
2004-07-26 12:44:40 +00:00
|
|
|
if (Sid->Revision != SID_REVISION)
|
|
|
|
{
|
|
|
|
DPRINT1("Invalid Owner SID revision\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG));
|
|
|
|
if (Length < SdLength)
|
|
|
|
{
|
|
|
|
DPRINT1("Invalid Owner SID size\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check Group SID */
|
|
|
|
if (SecurityDescriptor->Group != NULL)
|
|
|
|
{
|
|
|
|
if ((ULONG_PTR)SecurityDescriptor->Group % sizeof(ULONG))
|
|
|
|
{
|
|
|
|
DPRINT1("Invalid Group SID alignment\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Sid = (PSID)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Group);
|
|
|
|
if (Sid->Revision != SID_REVISION)
|
|
|
|
{
|
|
|
|
DPRINT1("Invalid Group SID revision\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
SdLength += (sizeof(SID) + (Sid->SubAuthorityCount - 1) * sizeof(ULONG));
|
|
|
|
if (Length < SdLength)
|
|
|
|
{
|
|
|
|
DPRINT1("Invalid Group SID size\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check DACL */
|
|
|
|
if (SecurityDescriptor->Dacl != NULL)
|
|
|
|
{
|
|
|
|
if ((ULONG_PTR)SecurityDescriptor->Dacl % sizeof(ULONG))
|
|
|
|
{
|
|
|
|
DPRINT1("Invalid DACL alignment\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Acl = (PACL)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Dacl);
|
|
|
|
if ((Acl->AclRevision < MIN_ACL_REVISION) &&
|
|
|
|
(Acl->AclRevision > MAX_ACL_REVISION))
|
|
|
|
{
|
|
|
|
DPRINT1("Invalid DACL revision\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
SdLength += Acl->AclSize;
|
|
|
|
if (Length < SdLength)
|
|
|
|
{
|
|
|
|
DPRINT1("Invalid DACL size\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check SACL */
|
|
|
|
if (SecurityDescriptor->Sacl != NULL)
|
|
|
|
{
|
|
|
|
if ((ULONG_PTR)SecurityDescriptor->Sacl % sizeof(ULONG))
|
|
|
|
{
|
|
|
|
DPRINT1("Invalid SACL alignment\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Acl = (PACL)((ULONG_PTR)SecurityDescriptor + (ULONG_PTR)SecurityDescriptor->Sacl);
|
|
|
|
if ((Acl->AclRevision < MIN_ACL_REVISION) ||
|
|
|
|
(Acl->AclRevision > MAX_ACL_REVISION))
|
|
|
|
{
|
|
|
|
DPRINT1("Invalid SACL revision\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
SdLength += Acl->AclSize;
|
|
|
|
if (Length < SdLength)
|
|
|
|
{
|
|
|
|
DPRINT1("Invalid SACL size\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
2004-05-20 12:42:51 +00:00
|
|
|
}
|
|
|
|
|
1999-12-26 17:22:19 +00:00
|
|
|
/* EOF */
|