Skip to content

Commit

Permalink
Apply ACLs for CREATOR_OWNER to the newly created windows files
Browse files Browse the repository at this point in the history
We encountered an issue in testing where the new owner of the file had no permissions of any of the downloaded files.
It appears that this was due to the s5cmd process running as a SYSTEM service and executing --preserve-ownership to set the owner to "Ahuge".
  • Loading branch information
Ahuge committed Mar 6, 2024
1 parent 5bff5b7 commit 5f12f1f
Showing 1 changed file with 75 additions and 0 deletions.
75 changes: 75 additions & 0 deletions storage/fs_windows.go
Expand Up @@ -9,6 +9,13 @@ import (
"strings"
"syscall"
"time"
"unsafe"
)

// Load the SetEntriesInAclW Win API function
var (
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
procSetEntriesInAclW = modadvapi32.NewProc("SetEntriesInAclW")
)

func GetFileTime(filename string) (time.Time, time.Time, time.Time, error) {
Expand Down Expand Up @@ -118,6 +125,11 @@ func SetFileUserGroup(filename, userId, groupId string) error {
return err
}

err = addCreatorOwnerAclToFile(filename)
if err != nil {
return err
}

return nil
}

Expand Down Expand Up @@ -147,3 +159,66 @@ func StringSidAsName(strSID string) (name string, err error) {
}
return name, nil
}

// addCreatorOwnerAclToFile is required because on Windows systems, a new file doesn
func addCreatorOwnerAclToFile(filename string) error {
// Get the DACL security descriptor from the filename
sd, err := windows.GetNamedSecurityInfo(filename, windows.SE_FILE_OBJECT, windows.DACL_SECURITY_INFORMATION)
if err != nil {
return err
}

// Get the DACL from the security descriptor
dacl, _, err := sd.DACL()
if err != nil {
return err
}

// Create a SID for the CREATOR_OWNER
sid, err := windows.StringToSid("S-1-3-0")
if err != nil {
return err
}

// Create an access control entry (ACE) for the CREATOR_OWNER SID
ace := windows.EXPLICIT_ACCESS{
AccessPermissions: windows.GENERIC_ALL,
AccessMode: windows.GRANT_ACCESS,
Trustee: windows.TRUSTEE{
TrusteeForm: windows.TRUSTEE_IS_SID,
TrusteeType: windows.TRUSTEE_IS_USER,
TrusteeValue: windows.TrusteeValueFromSID(sid),
},
}

newAcl := new(windows.ACL)
newAclH := windows.Handle(unsafe.Pointer(&newAcl))
entries := []windows.EXPLICIT_ACCESS{ace}
if err := SetEntriesInAcl(
entries,
windows.Handle(unsafe.Pointer(dacl)),
&newAclH,
); err != nil {
return err
}

// Set the updated security descriptor of the file
err = windows.SetNamedSecurityInfo(filename, windows.SE_FILE_OBJECT, windows.DACL_SECURITY_INFORMATION|windows.UNPROTECTED_DACL_SECURITY_INFORMATION, nil, nil, &newAcl, nil)
if err != nil {
return err
}
return nil
}

func SetEntriesInAcl(entries []windows.EXPLICIT_ACCESS, oldAcl windows.Handle, newAcl *windows.Handle) error {
ret, _, _ := procSetEntriesInAclW.Call(
uintptr(len(entries)),
uintptr(unsafe.Pointer(&entries[0])),
uintptr(oldAcl),
uintptr(unsafe.Pointer(newAcl)),
)
if ret != 0 {
return windows.Errno(ret)
}
return nil
}

0 comments on commit 5f12f1f

Please sign in to comment.