From 0af9e46e76018068beb8f8be13aa6f5e1fe1c2d2 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Mon, 8 May 2017 21:25:03 -0700 Subject: [PATCH] src: dotnet: FileSystemBase.ModifySecurityDescriptor --- src/dotnet/FileSystemBase.cs | 19 +++++++++++++ src/dotnet/Interop.cs | 52 +++++++++++++++++++++++++++++------- 2 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/dotnet/FileSystemBase.cs b/src/dotnet/FileSystemBase.cs index 24ae8432..031bd2b1 100644 --- a/src/dotnet/FileSystemBase.cs +++ b/src/dotnet/FileSystemBase.cs @@ -366,6 +366,25 @@ namespace Fsp { return Api.FspWin32FromNtStatus(Status); } + public static byte[] ModifySecurityDescriptor( + Byte[] SecurityDescriptor, + AccessControlSections Sections, + Byte[] ModificationDescriptor) + { + 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.ModifySecurityDescriptor( + SecurityDescriptor, + SecurityInformation, + ModificationDescriptor); + } public Int32 SeekableReadDirectory( Object FileNode, Object FileDesc, diff --git a/src/dotnet/Interop.cs b/src/dotnet/Interop.cs index 33f62e80..0e3f3761 100644 --- a/src/dotnet/Interop.cs +++ b/src/dotnet/Interop.cs @@ -546,6 +546,16 @@ namespace Fsp.Interop [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void FspFileSystemDeleteDirectoryBuffer( ref IntPtr PDirBuffer); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate Int32 FspSetSecurityDescriptor( + IntPtr InputDescriptor, + UInt32 SecurityInformation, + IntPtr ModificationDescriptor, + out IntPtr PSecurityDescriptor); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + internal delegate void FspDeleteSecurityDescriptor( + IntPtr SecurityDescriptor, + IntPtr CreateFunc); /* Service */ [UnmanagedFunctionPointer(CallingConvention.Cdecl)] @@ -650,6 +660,9 @@ namespace Fsp.Interop internal static Proto.FspFileSystemReleaseDirectoryBuffer FspFileSystemReleaseDirectoryBuffer; internal static Proto.FspFileSystemReadDirectoryBuffer FspFileSystemReadDirectoryBuffer; internal static Proto.FspFileSystemDeleteDirectoryBuffer FspFileSystemDeleteDirectoryBuffer; + internal static Proto.FspSetSecurityDescriptor FspSetSecurityDescriptor; + internal static IntPtr _FspSetSecurityDescriptorPtr; + internal static Proto.FspDeleteSecurityDescriptor FspDeleteSecurityDescriptor; internal static Proto.FspServiceCreate FspServiceCreate; internal static Proto.FspServiceDelete FspServiceDelete; internal static Proto.FspServiceAllowConsoleMode FspServiceAllowConsoleMode; @@ -816,6 +829,24 @@ namespace Fsp.Interop else return null; } + internal unsafe static byte[] ModifySecurityDescriptor( + Byte[] SecurityDescriptorBytes, + UInt32 SecurityInformation, + Byte[] ModificationDescriptorBytes) + { + fixed (Byte *S = SecurityDescriptorBytes) + fixed (Byte *M = ModificationDescriptorBytes) + { + IntPtr SecurityDescriptor; + Int32 Result = FspSetSecurityDescriptor( + (IntPtr)S, SecurityInformation, (IntPtr)M, out SecurityDescriptor); + if (0 > Result) + return null; + SecurityDescriptorBytes = MakeSecurityDescriptor(SecurityDescriptor); + FspDeleteSecurityDescriptor(SecurityDescriptor, _FspSetSecurityDescriptorPtr); + return SecurityDescriptorBytes; + } + } internal unsafe static Int32 CopyReparsePoint( Byte[] ReparseData, @@ -903,17 +934,17 @@ namespace Fsp.Interop } return Module; } + private static IntPtr GetEntryPointPtr(IntPtr Module, String Name) + { + IntPtr Proc = GetProcAddress(Module, Name); + if (IntPtr.Zero == Proc) + throw new EntryPointNotFoundException("cannot get entry point " + Name); + return Proc; + } private static T GetEntryPoint(IntPtr Module) { - try - { - return (T)(object)Marshal.GetDelegateForFunctionPointer( - GetProcAddress(Module, typeof(T).Name), typeof(T)); - } - catch (ArgumentNullException) - { - throw new EntryPointNotFoundException("cannot get entry point " + typeof(T).Name); - } + return (T)(object)Marshal.GetDelegateForFunctionPointer( + GetEntryPointPtr(Module, typeof(T).Name), typeof(T)); } private static void LoadProto(IntPtr Module) { @@ -938,6 +969,9 @@ namespace Fsp.Interop FspFileSystemReleaseDirectoryBuffer = GetEntryPoint(Module); FspFileSystemReadDirectoryBuffer = GetEntryPoint(Module); FspFileSystemDeleteDirectoryBuffer = GetEntryPoint(Module); + FspSetSecurityDescriptor = GetEntryPoint(Module); + _FspSetSecurityDescriptorPtr = GetEntryPointPtr(Module, "FspSetSecurityDescriptor"); + FspDeleteSecurityDescriptor = GetEntryPoint(Module); FspServiceCreate = GetEntryPoint(Module); FspServiceDelete = GetEntryPoint(Module); FspServiceAllowConsoleMode = GetEntryPoint(Module);