Merge pull request #5019 from MichaelEischer/fix-windows-sd-race

backup: Fix spurious "A Required Privilege Is Not Held by the Client" error
This commit is contained in:
Michael Eischer 2024-08-29 16:59:06 +02:00 committed by GitHub
commit a0f2dfbc19
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 22 additions and 12 deletions

View file

@ -0,0 +1,12 @@
Bugfix: Fix spurious "A Required Privilege Is Not Held by the Client" error
On Windows, creating a backup could sometimes print the following error
```
error: nodeFromFileInfo [...]: get named security info failed with: a required privilege is not held by the client.
```
This has been fixed.
https://github.com/restic/restic/issues/5004
https://github.com/restic/restic/pull/5019

View file

@ -48,19 +48,18 @@ func GetSecurityDescriptor(filePath string) (securityDescriptor *[]byte, err err
var sd *windows.SECURITY_DESCRIPTOR
if lowerPrivileges.Load() {
// store original value to avoid unrelated changes in the error check
useLowerPrivileges := lowerPrivileges.Load()
if useLowerPrivileges {
sd, err = getNamedSecurityInfoLow(filePath)
} else {
sd, err = getNamedSecurityInfoHigh(filePath)
}
if err != nil {
if !lowerPrivileges.Load() && isHandlePrivilegeNotHeldError(err) {
if !useLowerPrivileges && isHandlePrivilegeNotHeldError(err) {
// If ERROR_PRIVILEGE_NOT_HELD is encountered, fallback to backups/restores using lower non-admin privileges.
lowerPrivileges.Store(true)
sd, err = getNamedSecurityInfoLow(filePath)
if err != nil {
return nil, fmt.Errorf("get low-level named security info failed with: %w", err)
}
return GetSecurityDescriptor(filePath)
} else if errors.Is(err, windows.ERROR_NOT_SUPPORTED) {
return nil, nil
} else {
@ -109,20 +108,19 @@ func SetSecurityDescriptor(filePath string, securityDescriptor *[]byte) error {
sacl = nil
}
if lowerPrivileges.Load() {
// store original value to avoid unrelated changes in the error check
useLowerPrivileges := lowerPrivileges.Load()
if useLowerPrivileges {
err = setNamedSecurityInfoLow(filePath, dacl)
} else {
err = setNamedSecurityInfoHigh(filePath, owner, group, dacl, sacl)
}
if err != nil {
if !lowerPrivileges.Load() && isHandlePrivilegeNotHeldError(err) {
if !useLowerPrivileges && isHandlePrivilegeNotHeldError(err) {
// If ERROR_PRIVILEGE_NOT_HELD is encountered, fallback to backups/restores using lower non-admin privileges.
lowerPrivileges.Store(true)
err = setNamedSecurityInfoLow(filePath, dacl)
if err != nil {
return fmt.Errorf("set low-level named security info failed with: %w", err)
}
return SetSecurityDescriptor(filePath, securityDescriptor)
} else {
return fmt.Errorf("set named security info failed with: %w", err)
}