diff --git a/reactos/include/ndk/obtypes.h b/reactos/include/ndk/obtypes.h index 7b97d2df114..c79a85e3bde 100644 --- a/reactos/include/ndk/obtypes.h +++ b/reactos/include/ndk/obtypes.h @@ -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 */ diff --git a/reactos/ntoskrnl/cm/cm.h b/reactos/ntoskrnl/cm/cm.h index 4a610348fc1..338cbeb3c30 100644 --- a/reactos/ntoskrnl/cm/cm.h +++ b/reactos/ntoskrnl/cm/cm.h @@ -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, diff --git a/reactos/ntoskrnl/cm/regobj.c b/reactos/ntoskrnl/cm/regobj.c index 0ac4f8fcb86..5b0493ff47e 100644 --- a/reactos/ntoskrnl/cm/regobj.c +++ b/reactos/ntoskrnl/cm/regobj.c @@ -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"); diff --git a/reactos/ntoskrnl/include/internal/io.h b/reactos/ntoskrnl/include/internal/io.h index 74e1cba5b4c..ea37455784d 100644 --- a/reactos/ntoskrnl/include/internal/io.h +++ b/reactos/ntoskrnl/include/internal/io.h @@ -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 diff --git a/reactos/ntoskrnl/include/internal/se.h b/reactos/ntoskrnl/include/internal/se.h index 5514eca6bc3..34d38ae2428 100644 --- a/reactos/ntoskrnl/include/internal/se.h +++ b/reactos/ntoskrnl/include/internal/se.h @@ -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(); \ diff --git a/reactos/ntoskrnl/io/file.c b/reactos/ntoskrnl/io/file.c index 3453913481c..17bfea8fec2 100644 --- a/reactos/ntoskrnl/io/file.c +++ b/reactos/ntoskrnl/io/file.c @@ -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; diff --git a/reactos/ntoskrnl/ob/handle.c b/reactos/ntoskrnl/ob/handle.c index a9b46d32271..0fffe185eae 100644 --- a/reactos/ntoskrnl/ob/handle.c +++ b/reactos/ntoskrnl/ob/handle.c @@ -1109,6 +1109,9 @@ ObInsertObject(IN PVOID Object, AssignSecurityDescriptor, 0, NewSecurityDescriptor, + NULL, + NULL, + NonPagedPool, NULL); } else diff --git a/reactos/ntoskrnl/ob/namespc.c b/reactos/ntoskrnl/ob/namespc.c index 46f058d1a3a..df73bfe6272 100644 --- a/reactos/ntoskrnl/ob/namespc.c +++ b/reactos/ntoskrnl/ob/namespc.c @@ -14,6 +14,7 @@ #define NDEBUG #include +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; } diff --git a/reactos/ntoskrnl/ob/security.c b/reactos/ntoskrnl/ob/security.c index 1fd2a2e4cd1..619dc9961b5 100644 --- a/reactos/ntoskrnl/ob/security.c +++ b/reactos/ntoskrnl/ob/security.c @@ -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); diff --git a/reactos/ntoskrnl/se/semgr.c b/reactos/ntoskrnl/se/semgr.c index b72d6c50a44..b2af8a76a3c 100644 --- a/reactos/ntoskrnl/se/semgr.c +++ b/reactos/ntoskrnl/se/semgr.c @@ -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