- 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
);
typedef NTSTATUS
(STDCALL *OB_SECURITY_METHOD)(
PVOID ObjectBody,
SECURITY_OPERATION_CODE OperationCode,
SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor,
PULONG BufferLength
PVOID Object,
SECURITY_OPERATION_CODE OperationType,
SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR NewSecurityDescriptor,
PULONG ReturnLength,
PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
POOL_TYPE PoolType,
PGENERIC_MAPPING GenericMapping
);
/* FIXME: TEMPORARY HACK */

View file

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

View file

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

View file

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

View file

@ -181,6 +181,17 @@ SepReleaseAcl(IN PACL CapturedAcl,
IN KPROCESSOR_MODE AccessMode,
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) \
do { \
KeEnterCriticalRegion(); \

View file

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

View file

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

View file

@ -14,6 +14,7 @@
#define NDEBUG
#include <internal/debug.h>
extern ULONG NtGlobalFlag;
/* GLOBALS ****************************************************************/
@ -24,7 +25,7 @@ PDIRECTORY_OBJECT NameSpaceRoot = NULL;
PDIRECTORY_OBJECT ObpTypeDirectoryObject = NULL;
/* FIXME: Move this somewhere else once devicemap support is in */
PDEVICE_MAP ObSystemDeviceMap = NULL;
KEVENT ObpDefaultObject;
static GENERIC_MAPPING ObpDirectoryMapping = {
STANDARD_RIGHTS_READ|DIRECTORY_QUERY|DIRECTORY_TRAVERSE,
@ -430,6 +431,9 @@ ObInit(VOID)
/* Initialize the security descriptor cache */
ObpInitSdCache();
/* Initialize the Default Event */
KeInitializeEvent(&ObpDefaultObject, NotificationEvent, TRUE );
/* Create the Type Type */
DPRINT("Creating Type Type\n");
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
@ -538,6 +542,7 @@ ObpCreateTypeObject(POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
{
POBJECT_HEADER Header;
POBJECT_TYPE LocalObjectType;
ULONG HeaderSize;
NTSTATUS Status;
DPRINT("ObpCreateTypeObject(ObjectType: %wZ)\n", TypeName);
@ -580,14 +585,71 @@ ObpCreateTypeObject(POBJECT_TYPE_INITIALIZER ObjectTypeInitializer,
/* Set it up */
LocalObjectType->TypeInfo = *ObjectTypeInitializer;
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 */
if (ObpTypeDirectoryObject)
{
ObpAddEntryDirectory(ObpTypeDirectoryObject, Header, TypeName->Buffer);
ObReferenceObject(ObpTypeDirectoryObject);
}
*ObjectType = LocalObjectType;
return Status;
}

View file

@ -41,21 +41,15 @@ ObAssignSecurity(IN PACCESS_STATE AccessState,
if (!NT_SUCCESS(Status))
return Status;
if (Type->TypeInfo.SecurityProcedure != NULL)
{
/* Call the security method */
Status = Type->TypeInfo.SecurityProcedure(Object,
AssignSecurityDescriptor,
0,
NewDescriptor,
NULL);
}
else
{
/* Assign the security descriptor to the object header */
Status = ObpAddSecurityDescriptor(NewDescriptor,
&(BODY_TO_HEADER(Object)->SecurityDescriptor));
}
NULL,
NULL,
NonPagedPool,
NULL);
/* Release the new security descriptor */
SeDeassignSecurity(&NewDescriptor);
@ -97,7 +91,10 @@ ObGetObjectSecurity(IN PVOID Object,
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
NULL,
&Length);
&Length,
NULL,
NonPagedPool,
NULL);
if (Status != STATUS_BUFFER_TOO_SMALL)
return Status;
@ -113,7 +110,10 @@ ObGetObjectSecurity(IN PVOID Object,
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
*SecurityDescriptor,
&Length);
&Length,
NULL,
NonPagedPool,
NULL);
if (!NT_SUCCESS(Status))
{
ExFreePool(*SecurityDescriptor);
@ -187,23 +187,15 @@ NtQuerySecurityObject(IN HANDLE Handle,
return STATUS_UNSUCCESSFUL;
}
if (Header->Type->TypeInfo.SecurityProcedure != NULL)
{
*ResultLength = Length;
Status = Header->Type->TypeInfo.SecurityProcedure(Object,
QuerySecurityDescriptor,
SecurityInformation,
SecurityDescriptor,
ResultLength);
}
else
{
*ResultLength = Length;
Status = SeQuerySecurityDescriptorInfo(&SecurityInformation,
SecurityDescriptor,
ResultLength,
&Header->SecurityDescriptor);
}
ResultLength,
NULL,
NonPagedPool,
NULL);
ObDereferenceObject(Object);
@ -219,20 +211,8 @@ NtSetSecurityObject(IN HANDLE Handle,
IN SECURITY_INFORMATION SecurityInformation,
IN PSECURITY_DESCRIPTOR SecurityDescriptor)
{
PSECURITY_DESCRIPTOR ObjectSd;
PSECURITY_DESCRIPTOR NewSd;
POBJECT_HEADER Header;
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;
PAGED_CODE();
@ -259,187 +239,14 @@ NtSetSecurityObject(IN HANDLE Handle,
return STATUS_UNSUCCESSFUL;
}
if (Header->Type->TypeInfo.SecurityProcedure != NULL)
{
Status = Header->Type->TypeInfo.SecurityProcedure(Object,
SetSecurityDescriptor,
SecurityInformation,
SecurityDescriptor,
NULL);
}
else
{
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);
}
NULL,
NULL,
NonPagedPool,
NULL);
ObDereferenceObject(Object);

View file

@ -188,6 +188,222 @@ VOID SepDeReferenceLogonSession(PLUID AuthenticationId)
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