/* FUNCTIONS *****************************************************************/
+//INIT_FUNCTION
PSECURITY_DESCRIPTOR
NTAPI
-INIT_FUNCTION
CmpHiveRootSecurityDescriptor(VOID)
{
NTSTATUS Status;
/* 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);
+ Sid[0] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CMSD);
+ Sid[1] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CMSD);
+ Sid[2] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CMSD);
SidLength = RtlLengthRequiredSid(2);
- Sid[3] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CM);
+ Sid[3] = ExAllocatePoolWithTag(PagedPool, SidLength, TAG_CMSD);
/* Make sure all SIDs were allocated */
if (!(Sid[0]) || !(Sid[1]) || !(Sid[2]) || !(Sid[3]))
}
/* Phase 3: Allocate the ACL */
- Acl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_CM);
+ Acl = ExAllocatePoolWithTag(PagedPool, AclLength, TAG_CMSD);
if (!Acl) KeBugCheckEx(REGISTRY_ERROR, 11, 3, 0, 0);
/* Phase 4: Create the ACL */
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]);
+ Status = RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[2]);
+ Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_ALL_ACCESS, Sid[3]);
+ Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[0]);
+ Status |= RtlAddAccessAllowedAce(Acl, ACL_REVISION, KEY_READ, Sid[1]);
if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 5, Status, 0);
/* Phase 5: Make the ACEs inheritable */
- Status = RtlGetAce(Acl, 0,( PVOID*)&AceHeader);
+ Status = RtlGetAce(Acl, 0, (PVOID*)&AceHeader);
ASSERT(NT_SUCCESS(Status));
AceHeader->AceFlags |= CONTAINER_INHERIT_ACE;
Status = RtlGetAce(Acl, 1, (PVOID*)&AceHeader);
SecurityDescriptor = ExAllocatePoolWithTag(PagedPool,
sizeof(SECURITY_DESCRIPTOR) +
AclLength,
- TAG_CM);
+ TAG_CMSD);
if (!SecurityDescriptor) KeBugCheckEx(REGISTRY_ERROR, 11, 6, 0, 0);
/* Phase 6: Make a copy of the ACL */
if (!NT_SUCCESS(Status)) KeBugCheckEx(REGISTRY_ERROR, 11, 8, Status, 0);
/* Free the SIDs and original ACL */
- for (i = 0; i < 4; i++) ExFreePoolWithTag(Sid[i], TAG_CM);
- ExFreePoolWithTag(Acl, TAG_CM);
+ for (i = 0; i < 4; i++) ExFreePoolWithTag(Sid[i], TAG_CMSD);
+ ExFreePoolWithTag(Acl, TAG_CMSD);
/* Return the security descriptor */
return SecurityDescriptor;
}
+NTSTATUS
+CmpQuerySecurityDescriptor(IN PCM_KEY_CONTROL_BLOCK Kcb,
+ IN SECURITY_INFORMATION SecurityInformation,
+ OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
+ IN OUT PULONG BufferLength)
+{
+ PISECURITY_DESCRIPTOR_RELATIVE RelSd;
+ ULONG SidSize;
+ ULONG AclSize;
+ ULONG SdSize;
+ NTSTATUS Status;
+ SECURITY_DESCRIPTOR_CONTROL Control = 0;
+ ULONG Owner = 0;
+ ULONG Group = 0;
+ ULONG Dacl = 0;
+
+ DBG_UNREFERENCED_PARAMETER(Kcb);
+
+ DPRINT("CmpQuerySecurityDescriptor()\n");
+
+ if (SecurityInformation == 0)
+ {
+ return STATUS_ACCESS_DENIED;
+ }
+
+ SidSize = RtlLengthSid(SeWorldSid);
+ RelSd = SecurityDescriptor;
+ SdSize = sizeof(*RelSd);
+
+ if (SecurityInformation & OWNER_SECURITY_INFORMATION)
+ {
+ Owner = SdSize;
+ SdSize += SidSize;
+ }
+
+ if (SecurityInformation & GROUP_SECURITY_INFORMATION)
+ {
+ Group = SdSize;
+ SdSize += SidSize;
+ }
+
+ if (SecurityInformation & DACL_SECURITY_INFORMATION)
+ {
+ Control |= SE_DACL_PRESENT;
+ Dacl = SdSize;
+ AclSize = sizeof(ACL) + sizeof(ACE) + SidSize;
+ SdSize += AclSize;
+ }
+
+ if (SecurityInformation & SACL_SECURITY_INFORMATION)
+ {
+ Control |= SE_SACL_PRESENT;
+ }
+
+ if (*BufferLength < SdSize)
+ {
+ *BufferLength = SdSize;
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+
+ *BufferLength = SdSize;
+
+ Status = RtlCreateSecurityDescriptorRelative(RelSd,
+ SECURITY_DESCRIPTOR_REVISION);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ RelSd->Control |= Control;
+ RelSd->Owner = Owner;
+ RelSd->Group = Group;
+ RelSd->Dacl = Dacl;
+
+ if (Owner)
+ RtlCopyMemory((PUCHAR)RelSd + Owner,
+ SeWorldSid,
+ SidSize);
+
+ if (Group)
+ RtlCopyMemory((PUCHAR)RelSd + Group,
+ SeWorldSid,
+ SidSize);
+
+ if (Dacl)
+ {
+ Status = RtlCreateAcl((PACL)((PUCHAR)RelSd + Dacl),
+ AclSize,
+ ACL_REVISION);
+ if (NT_SUCCESS(Status))
+ {
+ Status = RtlAddAccessAllowedAce((PACL)((PUCHAR)RelSd + Dacl),
+ ACL_REVISION,
+ GENERIC_ALL,
+ SeWorldSid);
+ }
+ }
+
+ ASSERT(Status == STATUS_SUCCESS);
+ return Status;
+}
+
+NTSTATUS
+CmpSetSecurityDescriptor(IN PCM_KEY_CONTROL_BLOCK Kcb,
+ IN PSECURITY_INFORMATION SecurityInformation,
+ IN PSECURITY_DESCRIPTOR SecurityDescriptor,
+ IN POOL_TYPE PoolType,
+ IN PGENERIC_MAPPING GenericMapping)
+{
+ DPRINT("CmpSetSecurityDescriptor()\n");
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+CmpAssignSecurityDescriptor(IN PCM_KEY_CONTROL_BLOCK Kcb,
+ IN PSECURITY_DESCRIPTOR SecurityDescriptor)
+{
+ DPRINT("CmpAssignSecurityDescriptor(%p %p)\n",
+ Kcb, SecurityDescriptor);
+ return STATUS_SUCCESS;
+}
+
NTSTATUS
NTAPI
CmpSecurityMethod(IN PVOID ObjectBody,
IN POOL_TYPE PoolType,
IN PGENERIC_MAPPING GenericMapping)
{
- /* HACK */
- return STATUS_SUCCESS;
+ PCM_KEY_CONTROL_BLOCK Kcb;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ DBG_UNREFERENCED_PARAMETER(OldSecurityDescriptor);
+ DBG_UNREFERENCED_PARAMETER(GenericMapping);
+
+ Kcb = ((PCM_KEY_BODY)ObjectBody)->KeyControlBlock;
+
+ /* Acquire the hive lock */
+ CmpLockRegistry();
+
+ /* Acquire the KCB lock */
+ if (OperationCode == QuerySecurityDescriptor)
+ {
+ CmpAcquireKcbLockShared(Kcb);
+ }
+ else
+ {
+ CmpAcquireKcbLockExclusive(Kcb);
+ }
+
+ /* Don't touch deleted keys */
+ if (Kcb->Delete)
+ {
+ /* Release the KCB lock */
+ CmpReleaseKcbLock(Kcb);
+
+ /* Release the hive lock */
+ CmpUnlockRegistry();
+ return STATUS_KEY_DELETED;
+ }
+
+ switch (OperationCode)
+ {
+ case SetSecurityDescriptor:
+ DPRINT("Set security descriptor\n");
+ ASSERT((PoolType == PagedPool) || (PoolType == NonPagedPool));
+ Status = CmpSetSecurityDescriptor(Kcb,
+ SecurityInformation,
+ SecurityDescriptor,
+ PoolType,
+ GenericMapping);
+ break;
+
+ case QuerySecurityDescriptor:
+ DPRINT("Query security descriptor\n");
+ Status = CmpQuerySecurityDescriptor(Kcb,
+ *SecurityInformation,
+ SecurityDescriptor,
+ BufferLength);
+ break;
+
+ case DeleteSecurityDescriptor:
+ DPRINT("Delete security descriptor\n");
+ /* HACK */
+ break;
+
+ case AssignSecurityDescriptor:
+ DPRINT("Assign security descriptor\n");
+ Status = CmpAssignSecurityDescriptor(Kcb,
+ SecurityDescriptor);
+ break;
+
+ default:
+ KeBugCheckEx(SECURITY_SYSTEM, 0, STATUS_INVALID_PARAMETER, 0, 0);
+ }
+
+ /* Release the KCB lock */
+ CmpReleaseKcbLock(Kcb);
+
+ /* Release the hive lock */
+ CmpUnlockRegistry();
+
+ return Status;
}