+NTSTATUS
+NTAPI
+CreateBaseAcls(OUT PACL* Dacl,
+ OUT PACL* RestrictedDacl)
+{
+ PSID SystemSid, WorldSid, RestrictedSid;
+ SID_IDENTIFIER_AUTHORITY NtAuthority = {SECURITY_NT_AUTHORITY};
+ SID_IDENTIFIER_AUTHORITY WorldAuthority = {SECURITY_WORLD_SID_AUTHORITY};
+ NTSTATUS Status;
+ // UCHAR KeyValueBuffer[0x40];
+ // PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo;
+ // UNICODE_STRING KeyName;
+ // ULONG ProtectionMode = 0;
+ ULONG AclLength; // , ResultLength;
+ // HANDLE hKey;
+ // OBJECT_ATTRIBUTES ObjectAttributes;
+
+ /* Open the Session Manager Key */
+ /*
+ RtlInitUnicodeString(&KeyName, SM_REG_KEY);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = NtOpenKey(&hKey, KEY_READ, &ObjectAttributes);
+ if (NT_SUCCESS(Status))
+ {
+ /\* Read the key value *\/
+ RtlInitUnicodeString(&KeyName, L"ProtectionMode");
+ Status = NtQueryValueKey(hKey,
+ &KeyName,
+ KeyValuePartialInformation,
+ KeyValueBuffer,
+ sizeof(KeyValueBuffer),
+ &ResultLength);
+
+ /\* Make sure it's what we expect it to be *\/
+ KeyValuePartialInfo = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer;
+ if ((NT_SUCCESS(Status)) && (KeyValuePartialInfo->Type == REG_DWORD) &&
+ (*(PULONG)KeyValuePartialInfo->Data))
+ {
+ /\* Save the Protection Mode *\/
+ // ProtectionMode = *(PULONG)KeyValuePartialInfo->Data;
+ }
+
+ /\* Close the handle *\/
+ NtClose(hKey);
+ }
+ */
+
+ /* Allocate the System SID */
+ Status = RtlAllocateAndInitializeSid(&NtAuthority,
+ 1, SECURITY_LOCAL_SYSTEM_RID,
+ 0, 0, 0, 0, 0, 0, 0,
+ &SystemSid);
+ ASSERT(NT_SUCCESS(Status));
+
+ /* Allocate the World SID */
+ Status = RtlAllocateAndInitializeSid(&WorldAuthority,
+ 1, SECURITY_WORLD_RID,
+ 0, 0, 0, 0, 0, 0, 0,
+ &WorldSid);
+ ASSERT(NT_SUCCESS(Status));
+
+ /* Allocate the restricted SID */
+ Status = RtlAllocateAndInitializeSid(&NtAuthority,
+ 1, SECURITY_RESTRICTED_CODE_RID,
+ 0, 0, 0, 0, 0, 0, 0,
+ &RestrictedSid);
+ ASSERT(NT_SUCCESS(Status));
+
+ /* Allocate one ACL with 3 ACEs each for one SID */
+ AclLength = sizeof(ACL) + 3 * sizeof(ACCESS_ALLOWED_ACE) +
+ RtlLengthSid(SystemSid) +
+ RtlLengthSid(RestrictedSid) +
+ RtlLengthSid(WorldSid);
+ *Dacl = RtlAllocateHeap(BaseSrvHeap, 0, AclLength);
+ ASSERT(*Dacl != NULL);
+
+ /* Set the correct header fields */
+ Status = RtlCreateAcl(*Dacl, AclLength, ACL_REVISION2);
+ ASSERT(NT_SUCCESS(Status));
+
+ /* Give the appropriate rights to each SID */
+ /* FIXME: Should check SessionId/ProtectionMode */
+ Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY | READ_CONTROL, WorldSid);
+ ASSERT(NT_SUCCESS(Status));
+ Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_ALL_ACCESS, SystemSid);
+ ASSERT(NT_SUCCESS(Status));
+ Status = RtlAddAccessAllowedAce(*Dacl, ACL_REVISION2, DIRECTORY_TRAVERSE, RestrictedSid);
+ ASSERT(NT_SUCCESS(Status));
+
+ /* Now allocate the restricted DACL */
+ *RestrictedDacl = RtlAllocateHeap(BaseSrvHeap, 0, AclLength);
+ ASSERT(*RestrictedDacl != NULL);
+
+ /* Initialize it */
+ Status = RtlCreateAcl(*RestrictedDacl, AclLength, ACL_REVISION2);
+ ASSERT(NT_SUCCESS(Status));
+
+ /* And add the same ACEs as before */
+ /* FIXME: Not really fully correct */
+ Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_QUERY | DIRECTORY_TRAVERSE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY | READ_CONTROL, WorldSid);
+ ASSERT(NT_SUCCESS(Status));
+ Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_ALL_ACCESS, SystemSid);
+ ASSERT(NT_SUCCESS(Status));
+ Status = RtlAddAccessAllowedAce(*RestrictedDacl, ACL_REVISION2, DIRECTORY_TRAVERSE, RestrictedSid);
+ ASSERT(NT_SUCCESS(Status));
+
+ /* The SIDs are captured, can free them now */
+ RtlFreeHeap(BaseSrvHeap, 0, SystemSid);
+ RtlFreeHeap(BaseSrvHeap, 0, WorldSid);
+ RtlFreeHeap(BaseSrvHeap, 0, RestrictedSid);
+ return Status;
+}
+