From 2e66c0b6f05acaf00283689786d2c3ac7d1014a0 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 14 Oct 2022 15:57:07 +0200 Subject: [PATCH] pkg/system: create SecurityAttribute only once (Windows) The same attribute was generated for each path that was created, but always the same, so instead of generating it in each iteration, generate it once, and pass it to our mkdirall() implementation. Signed-off-by: Sebastiaan van Stijn --- pkg/system/filesys_windows.go | 48 ++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/pkg/system/filesys_windows.go b/pkg/system/filesys_windows.go index c13e682ea9..24026fee71 100644 --- a/pkg/system/filesys_windows.go +++ b/pkg/system/filesys_windows.go @@ -21,19 +21,23 @@ var volumePath = regexp.MustCompile(`^\\\\\?\\Volume{[a-z0-9-]+}\\?$`) // so that it is both volume path aware, and can create a directory with // an appropriate SDDL defined ACL. func MkdirAllWithACL(path string, _ os.FileMode, sddl string) error { - return mkdirall(path, true, sddl) + sa, err := makeSecurityAttributes(sddl) + if err != nil { + return &os.PathError{Op: "mkdirall", Path: path, Err: err} + } + return mkdirall(path, sa) } // MkdirAll is a custom version of os.MkdirAll that is volume path aware for // Windows. It can be used as a drop-in replacement for os.MkdirAll. func MkdirAll(path string, _ os.FileMode) error { - return mkdirall(path, false, "") + return mkdirall(path, nil) } // mkdirall is a custom version of os.MkdirAll modified for use on Windows // so that it is both volume path aware, and can create a directory with // a DACL. -func mkdirall(path string, applyACL bool, sddl string) error { +func mkdirall(path string, perm *windows.SecurityAttributes) error { if volumePath.MatchString(path) { return nil } @@ -67,19 +71,14 @@ func mkdirall(path string, applyACL bool, sddl string) error { if j > 1 { // Create parent - err = mkdirall(path[0:j-1], false, sddl) + err = mkdirall(path[0:j-1], perm) if err != nil { return err } } // Parent now exists; invoke os.Mkdir or mkdirWithACL and use its result. - if applyACL { - err = mkdirWithACL(path, sddl) - } else { - err = os.Mkdir(path, 0) - } - + err = mkdirWithACL(path, perm) if err != nil { // Handle arguments like "foo/." by // double-checking that directory doesn't exist. @@ -99,24 +98,31 @@ func mkdirall(path string, applyACL bool, sddl string) error { // in golang to cater for creating a directory am ACL permitting full // access, with inheritance, to any subfolder/file for Built-in Administrators // and Local System. -func mkdirWithACL(name string, sddl string) error { - sa := windows.SecurityAttributes{Length: 0} - sd, err := windows.SecurityDescriptorFromString(sddl) - if err != nil { - return &os.PathError{Op: "mkdir", Path: name, Err: err} +func mkdirWithACL(name string, sa *windows.SecurityAttributes) error { + if sa == nil { + return os.Mkdir(name, 0) } - sa.Length = uint32(unsafe.Sizeof(sa)) - sa.InheritHandle = 1 - sa.SecurityDescriptor = sd namep, err := windows.UTF16PtrFromString(name) if err != nil { return &os.PathError{Op: "mkdir", Path: name, Err: err} } - e := windows.CreateDirectory(namep, &sa) - if e != nil { - return &os.PathError{Op: "mkdir", Path: name, Err: e} + err = windows.CreateDirectory(namep, sa) + if err != nil { + return &os.PathError{Op: "mkdir", Path: name, Err: err} } return nil } + +func makeSecurityAttributes(sddl string) (*windows.SecurityAttributes, error) { + var sa windows.SecurityAttributes + sa.Length = uint32(unsafe.Sizeof(sa)) + sa.InheritHandle = 1 + var err error + sa.SecurityDescriptor, err = windows.SecurityDescriptorFromString(sddl) + if err != nil { + return nil, err + } + return &sa, nil +}