diff --git a/src/sys/create.c b/src/sys/create.c index 43c334c8..fedcf217 100644 --- a/src/sys/create.c +++ b/src/sys/create.c @@ -298,6 +298,8 @@ static NTSTATUS FspFsvolCreateNoLock( ULONG CreateOptions = IrpSp->Parameters.Create.Options; USHORT FileAttributes = IrpSp->Parameters.Create.FileAttributes; PSECURITY_DESCRIPTOR SecurityDescriptor = AccessState->SecurityDescriptor; + BOOLEAN SecurityDescriptorRelative = 0 != SecurityDescriptor && + BooleanFlagOn(((SECURITY_DESCRIPTOR *)SecurityDescriptor)->Control, SE_SELF_RELATIVE); ULONG SecurityDescriptorSize = 0; UINT64 AllocationSize = Irp->Overlay.AllocationSize.QuadPart; UINT64 AllocationUnit; @@ -406,7 +408,10 @@ static NTSTATUS FspFsvolCreateNoLock( if (!RtlValidSecurityDescriptor(SecurityDescriptor)) return STATUS_INVALID_PARAMETER; #endif - SecurityDescriptorSize = RtlLengthSecurityDescriptor(SecurityDescriptor); + if (SecurityDescriptorRelative) + SecurityDescriptorSize = RtlLengthSecurityDescriptor(SecurityDescriptor); + else + RtlAbsoluteToSelfRelativeSD(SecurityDescriptor, 0, &SecurityDescriptorSize); } /* align allocation size */ @@ -702,8 +707,18 @@ static NTSTATUS FspFsvolCreateNoLock( /* copy the security descriptor (if any) into the request */ if (0 != SecurityDescriptorSize) - RtlCopyMemory(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset, - SecurityDescriptor, SecurityDescriptorSize); + { + if (SecurityDescriptorRelative) + RtlCopyMemory( + Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset, + SecurityDescriptor, + SecurityDescriptorSize); + else + RtlAbsoluteToSelfRelativeSD( + SecurityDescriptor, + (PSECURITY_DESCRIPTOR)(Request->Buffer + Request->Req.Create.SecurityDescriptor.Offset), + &SecurityDescriptorSize); + } /* copy the extra buffer (if any) into the request */ if (0 != ExtraBuffer) diff --git a/src/sys/security.c b/src/sys/security.c index e39fbe2b..ae6dd641 100644 --- a/src/sys/security.c +++ b/src/sys/security.c @@ -207,6 +207,8 @@ static NTSTATUS FspFsvolSetSecurity( FSP_FILE_DESC *FileDesc = FileObject->FsContext2; SECURITY_INFORMATION SecurityInformation = IrpSp->Parameters.SetSecurity.SecurityInformation; PSECURITY_DESCRIPTOR SecurityDescriptor = IrpSp->Parameters.SetSecurity.SecurityDescriptor; + BOOLEAN SecurityDescriptorRelative = + BooleanFlagOn(((SECURITY_DESCRIPTOR *)SecurityDescriptor)->Control, SE_SELF_RELATIVE); ULONG SecurityDescriptorSize = 0; ASSERT(FileNode == FileDesc->FileNode); @@ -216,7 +218,10 @@ static NTSTATUS FspFsvolSetSecurity( if (0 == SecurityDescriptor || !RtlValidSecurityDescriptor(SecurityDescriptor)) return STATUS_INVALID_PARAMETER; #endif - SecurityDescriptorSize = RtlLengthSecurityDescriptor(SecurityDescriptor); + if (SecurityDescriptorRelative) + SecurityDescriptorSize = RtlLengthSecurityDescriptor(SecurityDescriptor); + else + RtlAbsoluteToSelfRelativeSD(SecurityDescriptor, 0, &SecurityDescriptorSize); FspFileNodeAcquireExclusive(FileNode, Full); @@ -236,7 +241,16 @@ static NTSTATUS FspFsvolSetSecurity( Request->Req.SetSecurity.SecurityInformation = SecurityInformation; Request->Req.SetSecurity.SecurityDescriptor.Offset = 0; Request->Req.SetSecurity.SecurityDescriptor.Size = (UINT16)SecurityDescriptorSize; - RtlCopyMemory(Request->Buffer, SecurityDescriptor, SecurityDescriptorSize); + if (SecurityDescriptorRelative) + RtlCopyMemory( + Request->Buffer, + SecurityDescriptor, + SecurityDescriptorSize); + else + RtlAbsoluteToSelfRelativeSD( + SecurityDescriptor, + (PSECURITY_DESCRIPTOR)Request->Buffer, + &SecurityDescriptorSize); FspFileNodeSetOwner(FileNode, Full, Request); FspIopRequestContext(Request, RequestFileNode) = FileNode;