Add file creation method that takes an ACL (dotnet/corefxdotnet/coreclr#42099)
authorCarlos Sanchez Lopez <1175054+carlossanlop@users.noreply.github.com>
Tue, 29 Oct 2019 22:48:49 +0000 (15:48 -0700)
committerJan Kotas <jkotas@microsoft.com>
Wed, 30 Oct 2019 03:55:59 +0000 (20:55 -0700)
Approved API Proposal: dotnet/coreclr#41614
Related change for directory creation method that takes an ACL: dotnet/coreclr#41834 -merged and ported to 3.1 Prev2

Description
We have extension methods in System.IO.FileSystem.AclExtensions that let the user get and set ACLs for existing files, but we do not have methods that create files with predefined ACLs.
.NET ACL (Access Control List) support is Windows specific. This change will reside inside the System.IO.FileSystem.AccessControl assembly.

Customer impact
Before this change, customers had to create a file or filestream, then set its ACLs. This presents a few problems:

Potential security hole as files can be accessed between creation and modification.
Porting difficulties as there isn't a 1-1 API replacement
Stability issues with background processes (file filters) can prevent modifying ACLs right after creation (typically surfaces as a security exception).
This change addresses those problems by adding a new extension method that allows creating a file and ensuring the provided ACLs are set during creation.
This change is expected to be backported to 3.1.

Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
Commit migrated from https://github.com/dotnet/coreclr/commit/be9323fa75dba520599815b1faa68e19a87a39a9

src/libraries/System.Private.CoreLib/src/System/IO/Win32Marshal.cs

index bedebee..35f7d2e 100644 (file)
@@ -3,6 +3,7 @@
 // See the LICENSE file in the project root for more information.
 
 #nullable enable
+using System.Diagnostics;
 using System.Runtime.InteropServices;
 
 namespace System.IO
@@ -25,6 +26,10 @@ namespace System.IO
         /// </summary>
         internal static Exception GetExceptionForWin32Error(int errorCode, string? path = "")
         {
+            // ERROR_SUCCESS gets thrown when another unexpected interop call was made before checking GetLastWin32Error().
+            // Errors have to get retrieved as soon as possible after P/Invoking to avoid this.
+            Debug.Assert(errorCode != Interop.Errors.ERROR_SUCCESS);
+
             switch (errorCode)
             {
                 case Interop.Errors.ERROR_FILE_NOT_FOUND: