mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
- 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:
parent
c8e0c7ed3e
commit
b1b87307bb
10 changed files with 339 additions and 224 deletions
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(); \
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -1109,6 +1109,9 @@ ObInsertObject(IN PVOID Object,
|
|||
AssignSecurityDescriptor,
|
||||
0,
|
||||
NewSecurityDescriptor,
|
||||
NULL,
|
||||
NULL,
|
||||
NonPagedPool,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -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,6 +585,63 @@ 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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue