mirror of
https://github.com/reactos/reactos.git
synced 2024-11-07 07:00:19 +00:00
c501d8112c
svn path=/branches/aicom-network-fixes/; revision=34994
152 lines
5.8 KiB
C
152 lines
5.8 KiB
C
/*
|
|
* PROJECT: ReactOS Kernel
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
* FILE: ntoskrnl/config/cmse.c
|
|
* PURPOSE: Configuration Manager - Security Subsystem Interface
|
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
|
*/
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
#include "ntoskrnl.h"
|
|
#define NDEBUG
|
|
#include "debug.h"
|
|
|
|
/* GLOBALS *******************************************************************/
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
PSECURITY_DESCRIPTOR
|
|
NTAPI
|
|
CmpHiveRootSecurityDescriptor(VOID)
|
|
{
|
|
NTSTATUS Status;
|
|
PSECURITY_DESCRIPTOR SecurityDescriptor;
|
|
PACL Acl, AclCopy;
|
|
PSID Sid[4];
|
|
SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
|
|
SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
|
|
ULONG AceLength, AclLength, SidLength;
|
|
PACE_HEADER AceHeader;
|
|
ULONG i;
|
|
PAGED_CODE();
|
|
|
|
/* Phase 1: Allocate SIDs */
|
|
SidLength = RtlLengthRequiredSid(1);
|
|
Sid[0] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
|
|
Sid[1] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
|
|
Sid[2] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
|
|
SidLength = RtlLengthRequiredSid(2);
|
|
Sid[3] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
|
|
|
|
/* Make sure all SIDs were allocated */
|
|
if (!(Sid[0]) || !(Sid[1]) || !(Sid[2]) || !(Sid[3]))
|
|
{
|
|
/* Bugcheck */
|
|
KEBUGCHECKEX(REGISTRY_ERROR, 11, 1, 0, 0);
|
|
}
|
|
|
|
/* Phase 2: Initialize all SIDs */
|
|
Status = RtlInitializeSid(Sid[0], &WorldAuthority, 1);
|
|
Status |= RtlInitializeSid(Sid[1], &NtAuthority, 1);
|
|
Status |= RtlInitializeSid(Sid[2], &NtAuthority, 1);
|
|
Status |= RtlInitializeSid(Sid[3], &NtAuthority, 2);
|
|
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 2, 0, 0);
|
|
|
|
/* Phase 2: Setup SID Sub Authorities */
|
|
*RtlSubAuthoritySid(Sid[0], 0) = SECURITY_WORLD_RID;
|
|
*RtlSubAuthoritySid(Sid[1], 0) = SECURITY_RESTRICTED_CODE_RID;
|
|
*RtlSubAuthoritySid(Sid[2], 0) = SECURITY_LOCAL_SYSTEM_RID;
|
|
*RtlSubAuthoritySid(Sid[3], 0) = SECURITY_BUILTIN_DOMAIN_RID;
|
|
*RtlSubAuthoritySid(Sid[3], 1) = DOMAIN_ALIAS_RID_ADMINS;
|
|
|
|
/* Make sure all SIDs are valid */
|
|
ASSERT(RtlValidSid(Sid[0]));
|
|
ASSERT(RtlValidSid(Sid[1]));
|
|
ASSERT(RtlValidSid(Sid[2]));
|
|
ASSERT(RtlValidSid(Sid[3]));
|
|
|
|
/* Phase 3: Calculate ACL Length */
|
|
AclLength = sizeof(ACL);
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
/* This is what MSDN says to do */
|
|
AceLength = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart);
|
|
AceLength += SeLengthSid(Sid[i]);
|
|
AclLength += AceLength;
|
|
}
|
|
|
|
/* Phase 3: Allocate the ACL */
|
|
Acl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_CM);
|
|
if (!Acl) KEBUGCHECKEX(REGISTRY_ERROR, 11, 3, 0, 0);
|
|
|
|
/* Phase 4: Create the ACL */
|
|
Status = RtlCreateAcl(Acl, AclLength, ACL_REVISION);
|
|
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 4, Status, 0);
|
|
|
|
/* Phase 5: Build the ACL */
|
|
Status = RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[0]);
|
|
Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[1]);
|
|
Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[2]);
|
|
Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[3]);
|
|
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 5, Status, 0);
|
|
|
|
/* Phase 5: Make the ACEs inheritable */
|
|
Status = RtlGetAce(Acl, 0,( PVOID*)&AceHeader);
|
|
ASSERT(NT_SUCCESS(Status));
|
|
AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
|
|
Status = RtlGetAce(Acl, 1, (PVOID*)&AceHeader);
|
|
ASSERT(NT_SUCCESS(Status));
|
|
AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
|
|
Status = RtlGetAce(Acl, 2, (PVOID*)&AceHeader);
|
|
ASSERT(NT_SUCCESS(Status));
|
|
AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
|
|
Status = RtlGetAce(Acl, 3, (PVOID*)&AceHeader);
|
|
ASSERT(NT_SUCCESS(Status));
|
|
AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
|
|
|
|
/* Phase 6: Allocate the security descriptor and make space for the ACL */
|
|
SecurityDescriptor = ExAllocatePoolWithTag(PagedPool,
|
|
sizeof(SECURITY_DESCRIPTOR) +
|
|
AclLength,
|
|
TAG_CM);
|
|
if (!SecurityDescriptor) KEBUGCHECKEX(REGISTRY_ERROR, 11, 6, 0, 0);
|
|
|
|
/* Phase 6: Make a copy of the ACL */
|
|
AclCopy = (PACL)((PISECURITY_DESCRIPTOR)SecurityDescriptor + 1);
|
|
RtlCopyMemory(AclCopy, Acl, AclLength);
|
|
|
|
/* Phase 7: Create the security descriptor */
|
|
Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
|
|
SECURITY_DESCRIPTOR_REVISION);
|
|
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 7, Status, 0);
|
|
|
|
/* Phase 8: Set the ACL as a DACL */
|
|
Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor,
|
|
TRUE,
|
|
AclCopy,
|
|
FALSE);
|
|
if (!NT_SUCCESS(Status)) KEBUGCHECKEX(REGISTRY_ERROR, 11, 8, Status, 0);
|
|
|
|
/* Free the SIDs and original ACL */
|
|
for (i = 0; i < 4; i++) ExFreePool(Sid[i]);
|
|
ExFreePool(Acl);
|
|
|
|
/* Return the security descriptor */
|
|
return SecurityDescriptor;
|
|
}
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
CmpSecurityMethod(IN PVOID ObjectBody,
|
|
IN SECURITY_OPERATION_CODE OperationCode,
|
|
IN PSECURITY_INFORMATION SecurityInformation,
|
|
IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
|
|
IN OUT PULONG BufferLength,
|
|
IN OUT PSECURITY_DESCRIPTOR *OldSecurityDescriptor,
|
|
IN POOL_TYPE PoolType,
|
|
IN PGENERIC_MAPPING GenericMapping)
|
|
{
|
|
/* HACK */
|
|
return STATUS_SUCCESS;
|
|
}
|