https://git.reactos.org/?p=reactos.git;a=commitdiff;h=36c38c45eee2780c50bd5…
commit 36c38c45eee2780c50bd5c885188a73808636f64
Author: Pierre Schweitzer <pierre(a)reactos.org>
AuthorDate: Tue Dec 4 19:10:40 2018 +0100
Commit: Pierre Schweitzer <pierre(a)reactos.org>
CommitDate: Tue Dec 4 19:13:57 2018 +0100
[NTOSKRNL] Implement IopCreateDefaultDeviceSecurityDescriptor() and
IopCreateSecurityDescriptorPerType()
CORE-9176
---
ntoskrnl/include/internal/io.h | 12 +++
ntoskrnl/io/iomgr/device.c | 166 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 178 insertions(+)
diff --git a/ntoskrnl/include/internal/io.h b/ntoskrnl/include/internal/io.h
index 18a9b2de50..5835c66aa3 100644
--- a/ntoskrnl/include/internal/io.h
+++ b/ntoskrnl/include/internal/io.h
@@ -526,6 +526,18 @@ typedef struct _RESERVE_IRP_ALLOCATOR
CCHAR StackSize;
} RESERVE_IRP_ALLOCATOR, *PRESERVE_IRP_ALLOCATOR;
+//
+//
+//
+typedef enum _SECURITY_DESCRIPTOR_TYPE
+{
+ RestrictedPublic = 1,
+ UnrestrictedPublic,
+ RestrictedPublicOpen,
+ UnrestrictedPublicOpen,
+ SystemDefault,
+} SECURITY_DESCRIPTOR_TYPE, *PSECURITY_DESCRIPTOR_TYPE;
+
//
// Resource code
//
diff --git a/ntoskrnl/io/iomgr/device.c b/ntoskrnl/io/iomgr/device.c
index 416a16e6aa..5cb7f5cfda 100644
--- a/ntoskrnl/io/iomgr/device.c
+++ b/ntoskrnl/io/iomgr/device.c
@@ -25,6 +25,8 @@ extern LIST_ENTRY IopCdRomFileSystemQueueHead;
extern LIST_ENTRY IopTapeFileSystemQueueHead;
extern ERESOURCE IopDatabaseResource;
+#define DACL_SET 4
+
/* PRIVATE FUNCTIONS **********************************************************/
VOID
@@ -722,6 +724,170 @@ IopVerifyDeviceObjectOnStack(IN PDEVICE_OBJECT BaseDeviceObject,
return Result;
}
+NTSTATUS
+NTAPI
+IopCreateSecurityDescriptorPerType(IN PSECURITY_DESCRIPTOR SecurityDescriptor,
+ IN ULONG Type,
+ OUT PULONG OutputFlags)
+{
+ PACL Dacl;
+ NTSTATUS Status;
+
+ /* Select the DACL the caller wants */
+ switch (Type)
+ {
+ case RestrictedPublic:
+ Dacl = SePublicDefaultDacl;
+ break;
+
+ case UnrestrictedPublic:
+ Dacl = SePublicDefaultUnrestrictedDacl;
+ break;
+
+ case RestrictedPublicOpen:
+ Dacl = SePublicOpenDacl;
+ break;
+
+ case UnrestrictedPublicOpen:
+ Dacl = SePublicOpenUnrestrictedDacl;
+ break;
+
+ case SystemDefault:
+ Dacl = SeSystemDefaultDacl;
+ break;
+
+ default:
+ ASSERT(FALSE);
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Create the SD and set the DACL caller wanted */
+ Status = RtlCreateSecurityDescriptor(SecurityDescriptor,
SECURITY_DESCRIPTOR_REVISION);
+ ASSERT(NT_SUCCESS(Status));
+ Status = RtlSetDaclSecurityDescriptor(SecurityDescriptor, TRUE, Dacl, FALSE);
+
+ /* We've set DACL */
+ if (OutputFlags) *OutputFlags |= DACL_SET;
+
+ /* Done */
+ return Status;
+}
+
+PSECURITY_DESCRIPTOR
+NTAPI
+IopCreateDefaultDeviceSecurityDescriptor(IN DEVICE_TYPE DeviceType,
+ IN ULONG DeviceCharacteristics,
+ IN BOOLEAN HasDeviceName,
+ IN PSECURITY_DESCRIPTOR SecurityDescriptor,
+ OUT PACL * OutputDacl,
+ OUT PULONG OutputFlags)
+{
+ PACL Dacl;
+ ULONG AceId;
+ NTSTATUS Status;
+ PACCESS_ALLOWED_ACE Ace;
+ BOOLEAN AdminsSet, WorldSet;
+
+ PAGED_CODE();
+
+ /* Zero our output vars */
+ if (OutputFlags) *OutputFlags = 0;
+
+ *OutputDacl = NULL;
+
+ /* For FSD, easy use SePublicDefaultUnrestrictedDacl */
+ if (DeviceType == FILE_DEVICE_TAPE_FILE_SYSTEM ||
+ DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM ||
+ DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM ||
+ DeviceType == FILE_DEVICE_FILE_SYSTEM)
+ {
+ Status = IopCreateSecurityDescriptorPerType(SecurityDescriptor,
+ UnrestrictedPublic,
+ OutputFlags);
+ goto Quit;
+ }
+ /* For storage devices with a name and floppy attribute,
+ * use SePublicOpenUnrestrictedDacl
+ */
+ else if ((DeviceType != FILE_DEVICE_VIRTUAL_DISK &&
+ DeviceType != FILE_DEVICE_MASS_STORAGE &&
+ DeviceType != FILE_DEVICE_CD_ROM &&
+ DeviceType != FILE_DEVICE_DISK &&
+ DeviceType != FILE_DEVICE_DFS_FILE_SYSTEM &&
+ DeviceType != FILE_DEVICE_NETWORK &&
+ DeviceType != FILE_DEVICE_NETWORK_FILE_SYSTEM) ||
+ (HasDeviceName && BooleanFlagOn(DeviceCharacteristics,
FILE_FLOPPY_DISKETTE)))
+ {
+ Status = IopCreateSecurityDescriptorPerType(SecurityDescriptor,
+ UnrestrictedPublicOpen,
+ OutputFlags);
+ goto Quit;
+ }
+
+ /* The rest...
+ * We will rely on SePublicDefaultUnrestrictedDacl as well
+ */
+ Dacl = ExAllocatePoolWithTag(PagedPool, SePublicDefaultUnrestrictedDacl->AclSize,
'eSoI');
+ if (Dacl == NULL)
+ {
+ return NULL;
+ }
+
+ /* Copy our DACL */
+ RtlCopyMemory(Dacl, SePublicDefaultUnrestrictedDacl,
SePublicDefaultUnrestrictedDacl->AclSize);
+
+ /* Now, browse the DACL to make sure we have everything we want in them,
+ * including permissions
+ */
+ AceId = 0;
+ AdminsSet = FALSE;
+ WorldSet = FALSE;
+ while (NT_SUCCESS(RtlGetAce(Dacl, AceId, (PVOID *)&Ace)))
+ {
+ /* Admins must acess and in RWX, set it */
+ if (RtlEqualSid(SeAliasAdminsSid, &Ace->SidStart))
+ {
+ SetFlag(Ace->Mask, (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE));
+ AdminsSet = TRUE;
+ }
+
+ /* World can read a CD_ROM device */
+ if (DeviceType == FILE_DEVICE_CD_ROM && RtlEqualSid(SeWorldSid,
&Ace->SidStart))
+ {
+ SetFlag(Ace->Mask, GENERIC_READ);
+ WorldSet = TRUE;
+ }
+
+ ++AceId;
+ }
+
+ /* AdminSid was present and set (otherwise, we have big trouble) */
+ ASSERT(AdminsSet);
+
+ /* If CD_ROM device, we've set world permissions */
+ if (DeviceType == FILE_DEVICE_CD_ROM) ASSERT(WorldSet);
+
+ /* Now our DACL is correct, setup the security descriptor */
+ RtlCreateSecurityDescriptor(SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);
+ RtlSetDaclSecurityDescriptor(SecurityDescriptor, TRUE, Dacl, FALSE);
+
+ /* We've set DACL */
+ if (OutputFlags) *OutputFlags |= DACL_SET;
+
+ /* Return DACL to allow later freeing */
+ *OutputDacl = Dacl;
+ Status = STATUS_SUCCESS;
+
+Quit:
+ /* Only return SD if we succeed */
+ if (!NT_SUCCESS(Status))
+ {
+ return NULL;
+ }
+
+ return SecurityDescriptor;
+}
+
/* PUBLIC FUNCTIONS ***********************************************************/
/*