forked from TrueCloudLab/restic
fs: fallback to low privilege security descriptors on access denied
This commit is contained in:
parent
d46525a51b
commit
7bfe3d99ae
2 changed files with 36 additions and 0 deletions
14
changelog/unreleased/issue-5003
Normal file
14
changelog/unreleased/issue-5003
Normal file
|
@ -0,0 +1,14 @@
|
|||
Bugfix: fix metadata errors during backup of removable disks on Windows
|
||||
|
||||
Since restic 0.17.0, backups of removable disks on Windows could report
|
||||
errors with retrieving metadata like shown below.
|
||||
|
||||
```
|
||||
error: incomplete metadata for d:\filename: get named security info failed with: Access is denied.
|
||||
```
|
||||
|
||||
This has now been fixed.
|
||||
|
||||
https://github.com/restic/restic/issues/5003
|
||||
https://github.com/restic/restic/pull/5123
|
||||
https://forum.restic.net/t/backing-up-a-folder-from-a-veracrypt-volume-brings-up-errors-since-restic-v17-0/8444
|
|
@ -54,6 +54,15 @@ func GetSecurityDescriptor(filePath string) (securityDescriptor *[]byte, err err
|
|||
sd, err = getNamedSecurityInfoLow(filePath)
|
||||
} else {
|
||||
sd, err = getNamedSecurityInfoHigh(filePath)
|
||||
// Fallback to the low privilege version when receiving an access denied error.
|
||||
// For some reason the ERROR_PRIVILEGE_NOT_HELD error is not returned for removable media
|
||||
// but instead an access denied error is returned. Workaround that by just retrying with
|
||||
// the low privilege version, but don't switch privileges as we cannot distinguish this
|
||||
// case from actual access denied errors.
|
||||
// see https://github.com/restic/restic/issues/5003#issuecomment-2452314191 for details
|
||||
if err != nil && isAccessDeniedError(err) {
|
||||
sd, err = getNamedSecurityInfoLow(filePath)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
if !useLowerPrivileges && isHandlePrivilegeNotHeldError(err) {
|
||||
|
@ -114,6 +123,10 @@ func SetSecurityDescriptor(filePath string, securityDescriptor *[]byte) error {
|
|||
err = setNamedSecurityInfoLow(filePath, dacl)
|
||||
} else {
|
||||
err = setNamedSecurityInfoHigh(filePath, owner, group, dacl, sacl)
|
||||
// See corresponding fallback in getSecurityDescriptor for an explanation
|
||||
if err != nil && isAccessDeniedError(err) {
|
||||
err = setNamedSecurityInfoLow(filePath, dacl)
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
@ -174,6 +187,15 @@ func isHandlePrivilegeNotHeldError(err error) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// isAccessDeniedError checks if the error is ERROR_ACCESS_DENIED
|
||||
func isAccessDeniedError(err error) bool {
|
||||
if errno, ok := err.(syscall.Errno); ok {
|
||||
// Compare the error code to the expected value
|
||||
return errno == windows.ERROR_ACCESS_DENIED
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// SecurityDescriptorBytesToStruct converts the security descriptor bytes representation
|
||||
// into a pointer to windows SECURITY_DESCRIPTOR.
|
||||
func SecurityDescriptorBytesToStruct(sd []byte) (*windows.SECURITY_DESCRIPTOR, error) {
|
||||
|
|
Loading…
Reference in a new issue