From 0de00e872f301900ba10b9a4c70a73f40f8a5510 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Mon, 8 Oct 2018 15:08:07 -0700 Subject: [PATCH] dotnet: ModifySecurityDescriptorEx Deprecate ModifySecurityDecriptor and introduce ModifySecurityDescriptorEx. Works around the problem of clobbering an existing security descriptor when the native API FspSetSecurityDescriptor fails. --- src/dotnet/FileSystemBase.cs | 46 ++++++++++++++++++++++++++++++++++-- src/dotnet/Interop.cs | 20 ++++++++++++++++ tst/memfs-dotnet/Program.cs | 6 ++--- 3 files changed, 66 insertions(+), 6 deletions(-) diff --git a/src/dotnet/FileSystemBase.cs b/src/dotnet/FileSystemBase.cs index 5ed61a15..c29c7cbf 100644 --- a/src/dotnet/FileSystemBase.cs +++ b/src/dotnet/FileSystemBase.cs @@ -707,7 +707,7 @@ namespace Fsp /// Describes the modifications to apply to the file or directory security descriptor. /// /// STATUS_SUCCESS or error code. - /// + /// public virtual Int32 SetSecurity( Object FileNode, Object FileDesc, @@ -1105,7 +1105,7 @@ namespace Fsp return (int)Api.FspFileSystemOperationProcessId(); } /// - /// Modifies a security descriptor. + /// Modifies a security descriptor. [OBSOLETE] /// /// /// This is a helper for implementing the SetSecurity operation. @@ -1121,6 +1121,7 @@ namespace Fsp /// /// The modified security descriptor. /// + [Obsolete("use ModifySecurityDescriptorEx")] public static byte[] ModifySecurityDescriptor( Byte[] SecurityDescriptor, AccessControlSections Sections, @@ -1140,6 +1141,47 @@ namespace Fsp SecurityInformation, ModificationDescriptor); } + /// + /// Modifies a security descriptor. + /// + /// + /// This is a helper for implementing the SetSecurity operation. + /// + /// + /// The original security descriptor. + /// + /// + /// Describes what parts of the file or directory security descriptor should be modified. + /// + /// + /// Describes the modifications to apply to the file or directory security descriptor. + /// + /// + /// The modified security descriptor. This parameter is modified only on success. + /// + /// STATUS_SUCCESS or error code. + /// + public static Int32 ModifySecurityDescriptorEx( + Byte[] SecurityDescriptor, + AccessControlSections Sections, + Byte[] ModificationDescriptor, + ref Byte[] ModifiedDescriptor) + { + UInt32 SecurityInformation = 0; + if (0 != (Sections & AccessControlSections.Owner)) + SecurityInformation |= 1/*OWNER_SECURITY_INFORMATION*/; + if (0 != (Sections & AccessControlSections.Group)) + SecurityInformation |= 2/*GROUP_SECURITY_INFORMATION*/; + if (0 != (Sections & AccessControlSections.Access)) + SecurityInformation |= 4/*DACL_SECURITY_INFORMATION*/; + if (0 != (Sections & AccessControlSections.Audit)) + SecurityInformation |= 8/*SACL_SECURITY_INFORMATION*/; + return Api.ModifySecurityDescriptorEx( + SecurityDescriptor, + SecurityInformation, + ModificationDescriptor, + ref ModifiedDescriptor); + } public Int32 SeekableReadDirectory( Object FileNode, Object FileDesc, diff --git a/src/dotnet/Interop.cs b/src/dotnet/Interop.cs index 097ccb42..f813cba4 100644 --- a/src/dotnet/Interop.cs +++ b/src/dotnet/Interop.cs @@ -928,6 +928,26 @@ namespace Fsp.Interop return SecurityDescriptorBytes; } } + internal unsafe static Int32 ModifySecurityDescriptorEx( + Byte[] SecurityDescriptorBytes, + UInt32 SecurityInformation, + Byte[] ModificationDescriptorBytes, + ref Byte[] ModifiedDescriptorBytes) + { + fixed (Byte *S = SecurityDescriptorBytes) + fixed (Byte *M = ModificationDescriptorBytes) + { + IntPtr SecurityDescriptor; + Int32 Result = FspSetSecurityDescriptor( + (IntPtr)S, SecurityInformation, (IntPtr)M, out SecurityDescriptor); + if (0 > Result) + return Result; + SecurityDescriptorBytes = MakeSecurityDescriptor(SecurityDescriptor); + FspDeleteSecurityDescriptor(SecurityDescriptor, _FspSetSecurityDescriptorPtr); + ModifiedDescriptorBytes = SecurityDescriptorBytes; + return 0/*STATUS_SUCCESS*/; + } + } internal unsafe static Int32 CopyReparsePoint( Byte[] ReparseData, diff --git a/tst/memfs-dotnet/Program.cs b/tst/memfs-dotnet/Program.cs index 05bbe798..026ed986 100644 --- a/tst/memfs-dotnet/Program.cs +++ b/tst/memfs-dotnet/Program.cs @@ -783,10 +783,8 @@ namespace memfs if (null != FileNode.MainFileNode) FileNode = FileNode.MainFileNode; - FileNode.FileSecurity = ModifySecurityDescriptor( - FileNode.FileSecurity, Sections, SecurityDescriptor); - - return STATUS_SUCCESS; + return ModifySecurityDescriptorEx(FileNode.FileSecurity, Sections, SecurityDescriptor, + ref FileNode.FileSecurity); } public override Boolean ReadDirectoryEntry(