- Initialize more fields when creating an Object Type

- Correct the Pool Charge for Object Types, select a Default Object, always use a security procedure, read global flag for maintaing type lists, set the pool type
- Initialize a Default Wait Object.
- Fix security callback for objects.
- Implement SeDefaultObjectMethod for security callbacks of objects which don't have a custom one.

svn path=/trunk/; revision=17176
This commit is contained in:
Alex Ionescu 2005-08-07 18:38:37 +00:00
parent c8e0c7ed3e
commit b1b87307bb
10 changed files with 339 additions and 224 deletions

View file

@ -95,13 +95,17 @@ typedef PVOID
ULONG Attributes ULONG Attributes
); );
typedef NTSTATUS typedef NTSTATUS
(STDCALL *OB_SECURITY_METHOD)( (STDCALL *OB_SECURITY_METHOD)(
PVOID ObjectBody, PVOID Object,
SECURITY_OPERATION_CODE OperationCode, SECURITY_OPERATION_CODE OperationType,
SECURITY_INFORMATION SecurityInformation, SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor, PSECURITY_DESCRIPTOR NewSecurityDescriptor,
PULONG BufferLength PULONG ReturnLength,
PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
POOL_TYPE PoolType,
PGENERIC_MAPPING GenericMapping
); );
/* FIXME: TEMPORARY HACK */ /* FIXME: TEMPORARY HACK */

View file

@ -497,7 +497,10 @@ CmiObjectSecurity(PVOID ObjectBody,
SECURITY_OPERATION_CODE OperationCode, SECURITY_OPERATION_CODE OperationCode,
SECURITY_INFORMATION SecurityInformation, SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor, PSECURITY_DESCRIPTOR SecurityDescriptor,
PULONG BufferLength); PULONG BufferLength,
PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
POOL_TYPE PoolType,
PGENERIC_MAPPING GenericMapping);
NTSTATUS STDCALL NTSTATUS STDCALL
CmiObjectQueryName (PVOID ObjectBody, CmiObjectQueryName (PVOID ObjectBody,

View file

@ -450,7 +450,10 @@ CmiObjectSecurity(PVOID ObjectBody,
SECURITY_OPERATION_CODE OperationCode, SECURITY_OPERATION_CODE OperationCode,
SECURITY_INFORMATION SecurityInformation, SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor, PSECURITY_DESCRIPTOR SecurityDescriptor,
PULONG BufferLength) PULONG BufferLength,
PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
POOL_TYPE PoolType,
PGENERIC_MAPPING GenericMapping)
{ {
DPRINT("CmiObjectSecurity() called\n"); DPRINT("CmiObjectSecurity() called\n");

View file

@ -400,7 +400,10 @@ IopSecurityFile(
SECURITY_OPERATION_CODE OperationCode, SECURITY_OPERATION_CODE OperationCode,
SECURITY_INFORMATION SecurityInformation, SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor, PSECURITY_DESCRIPTOR SecurityDescriptor,
PULONG BufferLength PULONG BufferLength,
PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
POOL_TYPE PoolType,
PGENERIC_MAPPING GenericMapping
); );
NTSTATUS NTSTATUS

View file

@ -181,6 +181,17 @@ SepReleaseAcl(IN PACL CapturedAcl,
IN KPROCESSOR_MODE AccessMode, IN KPROCESSOR_MODE AccessMode,
IN BOOLEAN CaptureIfKernel); IN BOOLEAN CaptureIfKernel);
NTSTATUS
STDCALL
SeDefaultObjectMethod(PVOID Object,
SECURITY_OPERATION_CODE OperationType,
SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR NewSecurityDescriptor,
PULONG ReturnLength,
PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
POOL_TYPE PoolType,
PGENERIC_MAPPING GenericMapping);
#define SepAcquireTokenLockExclusive(Token) \ #define SepAcquireTokenLockExclusive(Token) \
do { \ do { \
KeEnterCriticalRegion(); \ KeEnterCriticalRegion(); \

View file

@ -239,7 +239,10 @@ IopSecurityFile(PVOID ObjectBody,
SECURITY_OPERATION_CODE OperationCode, SECURITY_OPERATION_CODE OperationCode,
SECURITY_INFORMATION SecurityInformation, SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor, PSECURITY_DESCRIPTOR SecurityDescriptor,
PULONG BufferLength) PULONG BufferLength,
PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
POOL_TYPE PoolType,
PGENERIC_MAPPING GenericMapping)
{ {
IO_STATUS_BLOCK IoStatusBlock; IO_STATUS_BLOCK IoStatusBlock;
PIO_STACK_LOCATION StackPtr; PIO_STACK_LOCATION StackPtr;

View file

@ -1109,6 +1109,9 @@ ObInsertObject(IN PVOID Object,
AssignSecurityDescriptor, AssignSecurityDescriptor,
0, 0,
NewSecurityDescriptor, NewSecurityDescriptor,
NULL,
NULL,
NonPagedPool,
NULL); NULL);
} }
else else

View file

@ -14,6 +14,7 @@
#define NDEBUG #define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
extern ULONG NtGlobalFlag;
/* GLOBALS ****************************************************************/ /* GLOBALS ****************************************************************/
@ -24,7 +25,7 @@ PDIRECTORY_OBJECT NameSpaceRoot = NULL;
PDIRECTORY_OBJECT ObpTypeDirectoryObject = NULL; PDIRECTORY_OBJECT ObpTypeDirectoryObject = NULL;
/* FIXME: Move this somewhere else once devicemap support is in */ /* FIXME: Move this somewhere else once devicemap support is in */
PDEVICE_MAP ObSystemDeviceMap = NULL; PDEVICE_MAP ObSystemDeviceMap = NULL;
KEVENT ObpDefaultObject;
static GENERIC_MAPPING ObpDirectoryMapping = { static GENERIC_MAPPING ObpDirectoryMapping = {
STANDARD_RIGHTS_READ|DIRECTORY_QUERY|DIRECTORY_TRAVERSE, STANDARD_RIGHTS_READ|DIRECTORY_QUERY|DIRECTORY_TRAVERSE,
@ -430,6 +431,9 @@ ObInit(VOID)
/* Initialize the security descriptor cache */ /* Initialize the security descriptor cache */
ObpInitSdCache(); ObpInitSdCache();
/* Initialize the Default Event */
KeInitializeEvent(&ObpDefaultObject, NotificationEvent, TRUE );
/* Create the Type Type */ /* Create the Type Type */
DPRINT("Creating Type Type\n"); DPRINT("Creating Type Type\n");
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
@ -538,6 +542,7 @@ ObpCreateTypeObject(POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
{ {
POBJECT_HEADER Header; POBJECT_HEADER Header;
POBJECT_TYPE LocalObjectType; POBJECT_TYPE LocalObjectType;
ULONG HeaderSize;
NTSTATUS Status; NTSTATUS Status;
DPRINT("ObpCreateTypeObject(ObjectType: %wZ)\n", TypeName); DPRINT("ObpCreateTypeObject(ObjectType: %wZ)\n", TypeName);
@ -580,14 +585,71 @@ ObpCreateTypeObject(POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
/* Set it up */ /* Set it up */
LocalObjectType->TypeInfo = *ObjectTypeInitializer; LocalObjectType->TypeInfo = *ObjectTypeInitializer;
LocalObjectType->Name = *TypeName; LocalObjectType->Name = *TypeName;
LocalObjectType->TypeInfo.PoolType = ObjectTypeInitializer->PoolType;
/* These two flags need to be manually set up */
Header->Flags |= OB_FLAG_KERNEL_MODE | OB_FLAG_PERMANENT;
/* Check if we have to maintain a type list */
if (NtGlobalFlag & FLG_MAINTAIN_OBJECT_TYPELIST)
{
/* Enable support */
LocalObjectType->TypeInfo.MaintainTypeList = TRUE;
}
/* Calculate how much space our header'll take up */
HeaderSize = sizeof(OBJECT_HEADER) + sizeof(OBJECT_HEADER_NAME_INFO) +
(ObjectTypeInitializer->MaintainHandleCount ?
sizeof(OBJECT_HEADER_HANDLE_INFO) : 0);
/* Update the Pool Charges */
if (ObjectTypeInitializer->PoolType == NonPagedPool)
{
LocalObjectType->TypeInfo.DefaultNonPagedPoolCharge += HeaderSize;
}
else
{
LocalObjectType->TypeInfo.DefaultPagedPoolCharge += HeaderSize;
}
/* All objects types need a security procedure */
if (!ObjectTypeInitializer->SecurityProcedure)
{
LocalObjectType->TypeInfo.SecurityProcedure = SeDefaultObjectMethod;
}
/* Select the Wait Object */
if (LocalObjectType->TypeInfo.UseDefaultObject)
{
/* Add the SYNCHRONIZE access mask since it's waitable */
LocalObjectType->TypeInfo.ValidAccessMask |= SYNCHRONIZE;
/* Use the "Default Object", a simple event */
LocalObjectType->DefaultObject = &ObpDefaultObject;
}
/* Special system objects get an optimized hack so they can be waited on */
else if (TypeName->Length == 8 && !wcscmp(TypeName->Buffer, L"File"))
{
LocalObjectType->DefaultObject = (PVOID)FIELD_OFFSET(FILE_OBJECT, Event);
}
/* FIXME: When LPC stops sucking, add a hack for Waitable Ports */
else
{
/* No default Object */
LocalObjectType->DefaultObject = NULL;
}
/* Initialize Object Type components */
ExInitializeResourceLite(&LocalObjectType->Mutex);
InitializeListHead(&LocalObjectType->TypeList);
/* Insert it into the Object Directory */ /* Insert it into the Object Directory */
if (ObpTypeDirectoryObject) if (ObpTypeDirectoryObject)
{ {
ObpAddEntryDirectory(ObpTypeDirectoryObject, Header, TypeName->Buffer); ObpAddEntryDirectory(ObpTypeDirectoryObject, Header, TypeName->Buffer);
ObReferenceObject(ObpTypeDirectoryObject); ObReferenceObject(ObpTypeDirectoryObject);
} }
*ObjectType = LocalObjectType; *ObjectType = LocalObjectType;
return Status; return Status;
} }

View file

@ -41,21 +41,15 @@ ObAssignSecurity(IN PACCESS_STATE AccessState,
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
return Status; return Status;
if (Type->TypeInfo.SecurityProcedure != NULL)
{
/* Call the security method */ /* Call the security method */
Status = Type->TypeInfo.SecurityProcedure(Object, Status = Type->TypeInfo.SecurityProcedure(Object,
AssignSecurityDescriptor, AssignSecurityDescriptor,
0, 0,
NewDescriptor, NewDescriptor,
NULL); NULL,
} NULL,
else NonPagedPool,
{ NULL);
/* Assign the security descriptor to the object header */
Status = ObpAddSecurityDescriptor(NewDescriptor,
&(BODY_TO_HEADER(Object)->SecurityDescriptor));
}
/* Release the new security descriptor */ /* Release the new security descriptor */
SeDeassignSecurity(&NewDescriptor); SeDeassignSecurity(&NewDescriptor);
@ -97,7 +91,10 @@ ObGetObjectSecurity(IN PVOID Object,
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION, DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
NULL, NULL,
&Length); &Length,
NULL,
NonPagedPool,
NULL);
if (Status != STATUS_BUFFER_TOO_SMALL) if (Status != STATUS_BUFFER_TOO_SMALL)
return Status; return Status;
@ -113,7 +110,10 @@ ObGetObjectSecurity(IN PVOID Object,
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION, DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
*SecurityDescriptor, *SecurityDescriptor,
&Length); &Length,
NULL,
NonPagedPool,
NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ExFreePool(*SecurityDescriptor); ExFreePool(*SecurityDescriptor);
@ -187,23 +187,15 @@ NtQuerySecurityObject(IN HANDLE Handle,
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
if (Header->Type->TypeInfo.SecurityProcedure != NULL)
{
*ResultLength = Length; *ResultLength = Length;
Status = Header->Type->TypeInfo.SecurityProcedure(Object, Status = Header->Type->TypeInfo.SecurityProcedure(Object,
QuerySecurityDescriptor, QuerySecurityDescriptor,
SecurityInformation, SecurityInformation,
SecurityDescriptor, SecurityDescriptor,
ResultLength); ResultLength,
} NULL,
else NonPagedPool,
{ NULL);
*ResultLength = Length;
Status = SeQuerySecurityDescriptorInfo(&SecurityInformation,
SecurityDescriptor,
ResultLength,
&Header->SecurityDescriptor);
}
ObDereferenceObject(Object); ObDereferenceObject(Object);
@ -219,20 +211,8 @@ NtSetSecurityObject(IN HANDLE Handle,
IN SECURITY_INFORMATION SecurityInformation, IN SECURITY_INFORMATION SecurityInformation,
IN PSECURITY_DESCRIPTOR SecurityDescriptor) IN PSECURITY_DESCRIPTOR SecurityDescriptor)
{ {
PSECURITY_DESCRIPTOR ObjectSd;
PSECURITY_DESCRIPTOR NewSd;
POBJECT_HEADER Header; POBJECT_HEADER Header;
PVOID Object; PVOID Object;
PSID Owner = 0;
PSID Group = 0;
PACL Dacl = 0;
PACL Sacl = 0;
ULONG OwnerLength = 0;
ULONG GroupLength = 0;
ULONG DaclLength = 0;
ULONG SaclLength = 0;
ULONG Control = 0;
ULONG_PTR Current;
NTSTATUS Status; NTSTATUS Status;
PAGED_CODE(); PAGED_CODE();
@ -259,187 +239,14 @@ NtSetSecurityObject(IN HANDLE Handle,
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
if (Header->Type->TypeInfo.SecurityProcedure != NULL)
{
Status = Header->Type->TypeInfo.SecurityProcedure(Object, Status = Header->Type->TypeInfo.SecurityProcedure(Object,
SetSecurityDescriptor, SetSecurityDescriptor,
SecurityInformation, SecurityInformation,
SecurityDescriptor, SecurityDescriptor,
NULL); NULL,
} NULL,
else NonPagedPool,
{ NULL);
ObjectSd = Header->SecurityDescriptor;
/* Get owner and owner size */
if (SecurityInformation & OWNER_SECURITY_INFORMATION)
{
if (SecurityDescriptor->Owner != NULL)
{
if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
Owner = (PSID)((ULONG_PTR)SecurityDescriptor->Owner +
(ULONG_PTR)SecurityDescriptor);
else
Owner = (PSID)SecurityDescriptor->Owner;
OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
}
Control |= (SecurityDescriptor->Control & SE_OWNER_DEFAULTED);
}
else
{
if (ObjectSd->Owner != NULL)
{
Owner = (PSID)((ULONG_PTR)ObjectSd->Owner + (ULONG_PTR)ObjectSd);
OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
}
Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED);
}
/* Get group and group size */
if (SecurityInformation & GROUP_SECURITY_INFORMATION)
{
if (SecurityDescriptor->Group != NULL)
{
if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
Group = (PSID)((ULONG_PTR)SecurityDescriptor->Group +
(ULONG_PTR)SecurityDescriptor);
else
Group = (PSID)SecurityDescriptor->Group;
GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
}
Control |= (SecurityDescriptor->Control & SE_GROUP_DEFAULTED);
}
else
{
if (ObjectSd->Group != NULL)
{
Group = (PSID)((ULONG_PTR)ObjectSd->Group + (ULONG_PTR)ObjectSd);
GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
}
Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED);
}
/* Get DACL and DACL size */
if (SecurityInformation & DACL_SECURITY_INFORMATION)
{
if ((SecurityDescriptor->Control & SE_DACL_PRESENT) &&
(SecurityDescriptor->Dacl != NULL))
{
if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
Dacl = (PACL)((ULONG_PTR)SecurityDescriptor->Dacl +
(ULONG_PTR)SecurityDescriptor);
else
Dacl = (PACL)SecurityDescriptor->Dacl;
DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4);
}
Control |= (SecurityDescriptor->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT));
}
else
{
if ((ObjectSd->Control & SE_DACL_PRESENT) &&
(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));
}
/* Get SACL and SACL size */
if (SecurityInformation & SACL_SECURITY_INFORMATION)
{
if ((SecurityDescriptor->Control & SE_SACL_PRESENT) &&
(SecurityDescriptor->Sacl != NULL))
{
if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
Sacl = (PACL)((ULONG_PTR)SecurityDescriptor->Sacl +
(ULONG_PTR)SecurityDescriptor);
else
Sacl = (PACL)SecurityDescriptor->Sacl;
SaclLength = ROUND_UP((ULONG)Sacl->AclSize, 4);
}
Control |= (SecurityDescriptor->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT));
}
else
{
if ((ObjectSd->Control & SE_SACL_PRESENT) &&
(ObjectSd->Sacl != NULL))
{
Sacl = (PACL)((ULONG_PTR)ObjectSd->Sacl + (ULONG_PTR)ObjectSd);
SaclLength = ROUND_UP((ULONG)Sacl->AclSize, 4);
}
Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT));
}
NewSd = ExAllocatePool(NonPagedPool,
sizeof(SECURITY_DESCRIPTOR) + OwnerLength + GroupLength +
DaclLength + SaclLength);
if (NewSd == NULL)
{
ObDereferenceObject(Object);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCreateSecurityDescriptor(NewSd,
SECURITY_DESCRIPTOR_REVISION1);
/* We always build a self-relative descriptor */
NewSd->Control = Control | SE_SELF_RELATIVE;
Current = (ULONG_PTR)NewSd + sizeof(SECURITY_DESCRIPTOR);
if (OwnerLength != 0)
{
RtlCopyMemory((PVOID)Current,
Owner,
OwnerLength);
NewSd->Owner = (PSID)(Current - (ULONG_PTR)NewSd);
Current += OwnerLength;
}
if (GroupLength != 0)
{
RtlCopyMemory((PVOID)Current,
Group,
GroupLength);
NewSd->Group = (PSID)(Current - (ULONG_PTR)NewSd);
Current += GroupLength;
}
if (DaclLength != 0)
{
RtlCopyMemory((PVOID)Current,
Dacl,
DaclLength);
NewSd->Dacl = (PACL)(Current - (ULONG_PTR)NewSd);
Current += DaclLength;
}
if (SaclLength != 0)
{
RtlCopyMemory((PVOID)Current,
Sacl,
SaclLength);
NewSd->Sacl = (PACL)(Current - (ULONG_PTR)NewSd);
Current += SaclLength;
}
/* Add the new SD */
Status = ObpAddSecurityDescriptor(NewSd,
&Header->SecurityDescriptor);
if (NT_SUCCESS(Status))
{
/* Remove the old security descriptor */
ObpRemoveSecurityDescriptor(ObjectSd);
}
else
{
/* Restore the old security descriptor */
Header->SecurityDescriptor = ObjectSd;
}
ExFreePool(NewSd);
}
ObDereferenceObject(Object); ObDereferenceObject(Object);

View file

@ -188,6 +188,222 @@ VOID SepDeReferenceLogonSession(PLUID AuthenticationId)
UNIMPLEMENTED; UNIMPLEMENTED;
} }
NTSTATUS
STDCALL
SeDefaultObjectMethod(PVOID Object,
SECURITY_OPERATION_CODE OperationType,
SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor,
PULONG ReturnLength,
PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
POOL_TYPE PoolType,
PGENERIC_MAPPING GenericMapping)
{
PSECURITY_DESCRIPTOR ObjectSd;
PSECURITY_DESCRIPTOR NewSd;
POBJECT_HEADER Header = BODY_TO_HEADER(Object);
PSID Owner = 0;
PSID Group = 0;
PACL Dacl = 0;
PACL Sacl = 0;
ULONG OwnerLength = 0;
ULONG GroupLength = 0;
ULONG DaclLength = 0;
ULONG SaclLength = 0;
ULONG Control = 0;
ULONG_PTR Current;
NTSTATUS Status;
if (OperationType == SetSecurityDescriptor)
{
ObjectSd = Header->SecurityDescriptor;
/* Get owner and owner size */
if (SecurityInformation & OWNER_SECURITY_INFORMATION)
{
if (SecurityDescriptor->Owner != NULL)
{
if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
Owner = (PSID)((ULONG_PTR)SecurityDescriptor->Owner +
(ULONG_PTR)SecurityDescriptor);
else
Owner = (PSID)SecurityDescriptor->Owner;
OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
}
Control |= (SecurityDescriptor->Control & SE_OWNER_DEFAULTED);
}
else
{
if (ObjectSd->Owner != NULL)
{
Owner = (PSID)((ULONG_PTR)ObjectSd->Owner + (ULONG_PTR)ObjectSd);
OwnerLength = ROUND_UP(RtlLengthSid(Owner), 4);
}
Control |= (ObjectSd->Control & SE_OWNER_DEFAULTED);
}
/* Get group and group size */
if (SecurityInformation & GROUP_SECURITY_INFORMATION)
{
if (SecurityDescriptor->Group != NULL)
{
if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
Group = (PSID)((ULONG_PTR)SecurityDescriptor->Group +
(ULONG_PTR)SecurityDescriptor);
else
Group = (PSID)SecurityDescriptor->Group;
GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
}
Control |= (SecurityDescriptor->Control & SE_GROUP_DEFAULTED);
}
else
{
if (ObjectSd->Group != NULL)
{
Group = (PSID)((ULONG_PTR)ObjectSd->Group + (ULONG_PTR)ObjectSd);
GroupLength = ROUND_UP(RtlLengthSid(Group), 4);
}
Control |= (ObjectSd->Control & SE_GROUP_DEFAULTED);
}
/* Get DACL and DACL size */
if (SecurityInformation & DACL_SECURITY_INFORMATION)
{
if ((SecurityDescriptor->Control & SE_DACL_PRESENT) &&
(SecurityDescriptor->Dacl != NULL))
{
if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
Dacl = (PACL)((ULONG_PTR)SecurityDescriptor->Dacl +
(ULONG_PTR)SecurityDescriptor);
else
Dacl = (PACL)SecurityDescriptor->Dacl;
DaclLength = ROUND_UP((ULONG)Dacl->AclSize, 4);
}
Control |= (SecurityDescriptor->Control & (SE_DACL_DEFAULTED | SE_DACL_PRESENT));
}
else
{
if ((ObjectSd->Control & SE_DACL_PRESENT) &&
(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));
}
/* Get SACL and SACL size */
if (SecurityInformation & SACL_SECURITY_INFORMATION)
{
if ((SecurityDescriptor->Control & SE_SACL_PRESENT) &&
(SecurityDescriptor->Sacl != NULL))
{
if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
Sacl = (PACL)((ULONG_PTR)SecurityDescriptor->Sacl +
(ULONG_PTR)SecurityDescriptor);
else
Sacl = (PACL)SecurityDescriptor->Sacl;
SaclLength = ROUND_UP((ULONG)Sacl->AclSize, 4);
}
Control |= (SecurityDescriptor->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT));
}
else
{
if ((ObjectSd->Control & SE_SACL_PRESENT) &&
(ObjectSd->Sacl != NULL))
{
Sacl = (PACL)((ULONG_PTR)ObjectSd->Sacl + (ULONG_PTR)ObjectSd);
SaclLength = ROUND_UP((ULONG)Sacl->AclSize, 4);
}
Control |= (ObjectSd->Control & (SE_SACL_DEFAULTED | SE_SACL_PRESENT));
}
NewSd = ExAllocatePool(NonPagedPool,
sizeof(SECURITY_DESCRIPTOR) + OwnerLength + GroupLength +
DaclLength + SaclLength);
if (NewSd == NULL)
{
ObDereferenceObject(Object);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCreateSecurityDescriptor(NewSd,
SECURITY_DESCRIPTOR_REVISION1);
/* We always build a self-relative descriptor */
NewSd->Control = Control | SE_SELF_RELATIVE;
Current = (ULONG_PTR)NewSd + sizeof(SECURITY_DESCRIPTOR);
if (OwnerLength != 0)
{
RtlCopyMemory((PVOID)Current,
Owner,
OwnerLength);
NewSd->Owner = (PSID)(Current - (ULONG_PTR)NewSd);
Current += OwnerLength;
}
if (GroupLength != 0)
{
RtlCopyMemory((PVOID)Current,
Group,
GroupLength);
NewSd->Group = (PSID)(Current - (ULONG_PTR)NewSd);
Current += GroupLength;
}
if (DaclLength != 0)
{
RtlCopyMemory((PVOID)Current,
Dacl,
DaclLength);
NewSd->Dacl = (PACL)(Current - (ULONG_PTR)NewSd);
Current += DaclLength;
}
if (SaclLength != 0)
{
RtlCopyMemory((PVOID)Current,
Sacl,
SaclLength);
NewSd->Sacl = (PACL)(Current - (ULONG_PTR)NewSd);
Current += SaclLength;
}
/* Add the new SD */
Status = ObpAddSecurityDescriptor(NewSd,
&Header->SecurityDescriptor);
if (NT_SUCCESS(Status))
{
/* Remove the old security descriptor */
ObpRemoveSecurityDescriptor(ObjectSd);
}
else
{
/* Restore the old security descriptor */
Header->SecurityDescriptor = ObjectSd;
}
ExFreePool(NewSd);
}
else if (OperationType == QuerySecurityDescriptor)
{
Status = SeQuerySecurityDescriptorInfo(&SecurityInformation,
SecurityDescriptor,
ReturnLength,
&Header->SecurityDescriptor);
}
else if (OperationType == AssignSecurityDescriptor)
{
/* Assign the security descriptor to the object header */
Status = ObpAddSecurityDescriptor(SecurityDescriptor,
&Header->SecurityDescriptor);
}
return STATUS_SUCCESS;
}
/* /*
* @implemented * @implemented