forked from TrueCloudLab/restic
Merge pull request #4954 from MichaelEischer/improve-windows-path-handling
Improve windows path handling
This commit is contained in:
commit
3faeddcd5f
5 changed files with 46 additions and 6 deletions
7
changelog/unreleased/issue-4953
Normal file
7
changelog/unreleased/issue-4953
Normal file
|
@ -0,0 +1,7 @@
|
|||
Bugfix: Correctly handle long paths on older Windows versions
|
||||
|
||||
When using older Windows versions, like Windows Server 2012, restic 0.17.0
|
||||
failed to back up files with long paths. This has been fixed.
|
||||
|
||||
https://github.com/restic/restic/issues/4953
|
||||
https://github.com/restic/restic/pull/4954
|
|
@ -134,7 +134,7 @@ func IsAccessDenied(err error) bool {
|
|||
// ResetPermissions resets the permissions of the file at the specified path
|
||||
func ResetPermissions(path string) error {
|
||||
// Set the default file permissions
|
||||
if err := os.Chmod(path, 0600); err != nil {
|
||||
if err := os.Chmod(fixpath(path), 0600); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -85,7 +85,7 @@ func ClearSystem(path string) error {
|
|||
|
||||
// ClearAttribute removes the specified attribute from the file.
|
||||
func ClearAttribute(path string, attribute uint32) error {
|
||||
ptr, err := windows.UTF16PtrFromString(path)
|
||||
ptr, err := windows.UTF16PtrFromString(fixpath(path))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -129,22 +129,22 @@ func SetSecurityDescriptor(filePath string, securityDescriptor *[]byte) error {
|
|||
|
||||
// getNamedSecurityInfoHigh gets the higher level SecurityDescriptor which requires admin permissions.
|
||||
func getNamedSecurityInfoHigh(filePath string) (*windows.SECURITY_DESCRIPTOR, error) {
|
||||
return windows.GetNamedSecurityInfo(filePath, windows.SE_FILE_OBJECT, highSecurityFlags)
|
||||
return windows.GetNamedSecurityInfo(fixpath(filePath), windows.SE_FILE_OBJECT, highSecurityFlags)
|
||||
}
|
||||
|
||||
// getNamedSecurityInfoLow gets the lower level SecurityDescriptor which requires no admin permissions.
|
||||
func getNamedSecurityInfoLow(filePath string) (*windows.SECURITY_DESCRIPTOR, error) {
|
||||
return windows.GetNamedSecurityInfo(filePath, windows.SE_FILE_OBJECT, lowBackupSecurityFlags)
|
||||
return windows.GetNamedSecurityInfo(fixpath(filePath), windows.SE_FILE_OBJECT, lowBackupSecurityFlags)
|
||||
}
|
||||
|
||||
// setNamedSecurityInfoHigh sets the higher level SecurityDescriptor which requires admin permissions.
|
||||
func setNamedSecurityInfoHigh(filePath string, owner *windows.SID, group *windows.SID, dacl *windows.ACL, sacl *windows.ACL) error {
|
||||
return windows.SetNamedSecurityInfo(filePath, windows.SE_FILE_OBJECT, highSecurityFlags, owner, group, dacl, sacl)
|
||||
return windows.SetNamedSecurityInfo(fixpath(filePath), windows.SE_FILE_OBJECT, highSecurityFlags, owner, group, dacl, sacl)
|
||||
}
|
||||
|
||||
// setNamedSecurityInfoLow sets the lower level SecurityDescriptor which requires no admin permissions.
|
||||
func setNamedSecurityInfoLow(filePath string, dacl *windows.ACL) error {
|
||||
return windows.SetNamedSecurityInfo(filePath, windows.SE_FILE_OBJECT, lowRestoreSecurityFlags, nil, nil, dacl, nil)
|
||||
return windows.SetNamedSecurityInfo(fixpath(filePath), windows.SE_FILE_OBJECT, lowRestoreSecurityFlags, nil, nil, dacl, nil)
|
||||
}
|
||||
|
||||
// enableBackupPrivilege enables privilege for backing up security descriptors
|
||||
|
|
|
@ -1506,3 +1506,36 @@ func TestRestoreToFile(t *testing.T) {
|
|||
err := res.RestoreTo(ctx, tempdir)
|
||||
rtest.Assert(t, strings.Contains(err.Error(), "cannot create target directory"), "unexpected error %v", err)
|
||||
}
|
||||
|
||||
func TestRestorerLongPath(t *testing.T) {
|
||||
tmp := t.TempDir()
|
||||
|
||||
longPath := tmp
|
||||
for i := 0; i < 20; i++ {
|
||||
longPath = filepath.Join(longPath, "aaaaaaaaaaaaaaaaaaaa")
|
||||
}
|
||||
|
||||
rtest.OK(t, os.MkdirAll(longPath, 0o700))
|
||||
f, err := fs.OpenFile(filepath.Join(longPath, "file"), fs.O_CREATE|fs.O_RDWR, 0o600)
|
||||
rtest.OK(t, err)
|
||||
_, err = f.WriteString("Hello, World!")
|
||||
rtest.OK(t, err)
|
||||
rtest.OK(t, f.Close())
|
||||
|
||||
repo := repository.TestRepository(t)
|
||||
|
||||
local := &fs.Local{}
|
||||
sc := archiver.NewScanner(local)
|
||||
rtest.OK(t, sc.Scan(context.TODO(), []string{tmp}))
|
||||
arch := archiver.New(repo, local, archiver.Options{})
|
||||
sn, _, _, err := arch.Snapshot(context.Background(), []string{tmp}, archiver.SnapshotOptions{})
|
||||
rtest.OK(t, err)
|
||||
|
||||
res := NewRestorer(repo, sn, Options{})
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
rtest.OK(t, res.RestoreTo(ctx, tmp))
|
||||
_, err = res.VerifyFiles(ctx, tmp)
|
||||
rtest.OK(t, err)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue