in internal/util/security/windows_permission.go [18:110]
func CheckFileRights(filePath string) error {
if _, err := os.Stat(filePath); err != nil {
return fmt.Errorf("Cannot get file's stat %s: %v", filePath, err)
}
var fileDacl *Acl
err := GetNamedSecurityInfo(filePath,
SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION,
nil,
nil,
&fileDacl,
nil,
nil)
if err != nil {
return fmt.Errorf("Cannot get file security info %s: %s", filePath, err)
}
var aclSizeInfo AclSizeInformation
err = GetAclInformation(fileDacl, &aclSizeInfo, AclSizeInformationEnum)
if err != nil {
return fmt.Errorf("Cannot query file's ACLs %s: %s", filePath, err)
}
// create the sids that are acceptable to us (local system account and administrators group)
// For more information on account type: https://stackoverflow.com/a/510225
var localSystem *windows.SID
err = windows.AllocateAndInitializeSid(&windows.SECURITY_NT_AUTHORITY,
1, // local system has 1 valid subauth
windows.SECURITY_LOCAL_SYSTEM_RID,
0, 0, 0, 0, 0, 0, 0,
&localSystem)
if err != nil {
return fmt.Errorf("Cannot initialize Local System SID: %v", err)
}
defer windows.FreeSid(localSystem)
var administrators *windows.SID
err = windows.AllocateAndInitializeSid(&windows.SECURITY_NT_AUTHORITY,
2, // administrators group has 2 valid subauths
windows.SECURITY_BUILTIN_DOMAIN_RID,
windows.DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&administrators)
if err != nil {
return fmt.Errorf("Cannot initialize Administrator SID: %s", err)
}
defer windows.FreeSid(administrators)
hasFileAllAccessLocalSystem := false
hasFileAllAccessAdministrators := false
for i := uint32(0); i < aclSizeInfo.AceCount; i++ {
var pAce *AccessAllowedAce
if err := GetAce(fileDacl, i, &pAce); err != nil {
return fmt.Errorf("Could not query a ACE on %s with: %s", filePath, err)
}
compareSid := (*windows.SID)(unsafe.Pointer(&pAce.SidStart))
compareIsLocalSystem := windows.EqualSid(compareSid, localSystem)
compareIsAdministrators := windows.EqualSid(compareSid, administrators)
if pAce.AceType == ACCESS_DENIED_ACE_TYPE {
// if the file has denied access to local system or administrators, then it cannot be protected by those accounts
if compareIsLocalSystem || compareIsAdministrators {
return fmt.Errorf("File %s has deny access for Administrators and Local System", filePath)
}
}
if pAce.AccessMask == FILE_ALL_ACCESS {
if compareIsLocalSystem {
hasFileAllAccessLocalSystem = true
}
if compareIsAdministrators {
hasFileAllAccessAdministrators = true
}
}
}
if !hasFileAllAccessLocalSystem || !hasFileAllAccessAdministrators {
return fmt.Errorf("No highest file access for Administrators and Local System with %s", filePath)
}
return nil
}