diff --git a/reactos/ntoskrnl/ob/security.c b/reactos/ntoskrnl/ob/security.c index dca9187196c..02ef4e89436 100644 --- a/reactos/ntoskrnl/ob/security.c +++ b/reactos/ntoskrnl/ob/security.c @@ -156,10 +156,21 @@ NtQuerySecurityObject(IN HANDLE Handle, { POBJECT_HEADER Header; PVOID Object; + PSECURITY_DESCRIPTOR ObjectSd; + PSID Owner; + PSID Group; + PACL Dacl; + PACL Sacl; + ULONG OwnerLength = 0; + ULONG GroupLength = 0; + ULONG DaclLength = 0; + ULONG SaclLength = 0; + ULONG Control = 0; + ULONG_PTR Current; NTSTATUS Status; Status = ObReferenceObjectByHandle(Handle, - 0, + (SecurityInformation & SACL_SECURITY_INFORMATION) ? ACCESS_SYSTEM_SECURITY : 0, NULL, KeGetPreviousMode(), &Object, @@ -171,7 +182,10 @@ NtQuerySecurityObject(IN HANDLE Handle, Header = BODY_TO_HEADER(Object); if (Header->ObjectType == NULL) - return STATUS_UNSUCCESSFUL; + { + ObDereferenceObject(Object); + return STATUS_UNSUCCESSFUL; + } if (Header->ObjectType->Security != NULL) { @@ -184,15 +198,94 @@ NtQuerySecurityObject(IN HANDLE Handle, } else { - if (Header->SecurityDescriptor != NULL) + ObjectSd = Header->SecurityDescriptor; + + if (ObjectSd != NULL) { - /* FIXME: Use SecurityInformation */ - *ResultLength = RtlLengthSecurityDescriptor(Header->SecurityDescriptor); + 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)); + } + + *ResultLength = OwnerLength + GroupLength + + DaclLength + SaclLength + sizeof(SECURITY_DESCRIPTOR); if (Length >= *ResultLength) { - RtlCopyMemory(SecurityDescriptor, - Header->SecurityDescriptor, - *ResultLength); + RtlCreateSecurityDescriptor(SecurityDescriptor, + SECURITY_DESCRIPTOR_REVISION1); + SecurityDescriptor->Control = Control; + + Current = (ULONG_PTR)SecurityDescriptor + sizeof(SECURITY_DESCRIPTOR); + + if (OwnerLength != 0) + { + RtlCopyMemory((PVOID)Current, + Owner, + OwnerLength); + SecurityDescriptor->Owner = (PSID)(Current - (ULONG_PTR)SecurityDescriptor); + Current += OwnerLength; + } + + if (GroupLength != 0) + { + RtlCopyMemory((PVOID)Current, + Group, + GroupLength); + SecurityDescriptor->Group = (PSID)(Current - (ULONG_PTR)SecurityDescriptor); + Current += GroupLength; + } + + if (DaclLength != 0) + { + RtlCopyMemory((PVOID)Current, + Dacl, + DaclLength); + SecurityDescriptor->Dacl = (PACL)(Current - (ULONG_PTR)SecurityDescriptor); + Current += DaclLength; + } + + if (SaclLength != 0) + { + RtlCopyMemory((PVOID)Current, + Sacl, + SaclLength); + SecurityDescriptor->Sacl = (PACL)(Current - (ULONG_PTR)SecurityDescriptor); + Current += SaclLength; + } Status = STATUS_SUCCESS; } @@ -227,19 +320,24 @@ NtSetSecurityObject(IN HANDLE Handle, NTSTATUS Status; Status = ObReferenceObjectByHandle(Handle, - 0, + (SecurityInformation & SACL_SECURITY_INFORMATION) ? ACCESS_SYSTEM_SECURITY : 0, NULL, KeGetPreviousMode(), &Object, NULL); if (!NT_SUCCESS(Status)) { - return(Status); + return Status; } Header = BODY_TO_HEADER(Object); - if (Header->ObjectType != NULL && - Header->ObjectType->Security != NULL) + if (Header->ObjectType != NULL) + { + ObDereferenceObject(Object); + return STATUS_UNSUCCESSFUL; + } + + if (Header->ObjectType->Security != NULL) { Status = Header->ObjectType->Security(Object, SetSecurityDescriptor, @@ -254,7 +352,7 @@ NtSetSecurityObject(IN HANDLE Handle, ObDereferenceObject(Object); - return(Status); + return Status; } /* EOF */