mirror of
https://github.com/restic/restic.git
synced 2025-12-08 06:09:56 +00:00
61 lines
2.2 KiB
Go
61 lines
2.2 KiB
Go
//go:build windows
|
|
|
|
package fs
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/restic/restic/internal/errors"
|
|
"github.com/restic/restic/internal/test"
|
|
"golang.org/x/sys/windows"
|
|
)
|
|
|
|
func TestBackupPrivilegeBypassACL(t *testing.T) {
|
|
testPath := testGetRestrictedFilePath(t)
|
|
|
|
// Read-only Open/OpenFile should automatically use FILE_FLAG_BACKUP_SEMANTICS since Go v1.20.
|
|
testfile, err := os.Open(testPath)
|
|
test.OK(t, errors.Wrapf(err, "failed to open file for reading: %s", testPath))
|
|
test.OK(t, testfile.Close())
|
|
}
|
|
|
|
func TestRestorePrivilegeBypassACL(t *testing.T) {
|
|
testPath := testGetRestrictedFilePath(t)
|
|
|
|
// Writable OpenFile needs explicit FILE_FLAG_BACKUP_SEMANTICS.
|
|
// Go with issue #73676 merged would allow: os.OpenFile(testPath, os.O_WRONLY|windows.O_FILE_FLAG_BACKUP_SEMANTICS, 0)
|
|
utf16Path := windows.StringToUTF16Ptr(testPath)
|
|
handle, err := windows.CreateFile(utf16Path, windows.GENERIC_WRITE, 0, nil, windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL|windows.FILE_FLAG_BACKUP_SEMANTICS, 0)
|
|
test.OK(t, errors.Wrapf(err, "failed to open file for writing: %s", testPath))
|
|
test.OK(t, windows.Close(handle))
|
|
}
|
|
|
|
func testGetRestrictedFilePath(t *testing.T) string {
|
|
// Non-admin is unlikely to have needed privileges.
|
|
isAdmin, err := isAdmin()
|
|
test.OK(t, errors.Wrap(err, "failed to check if user is admin"))
|
|
if !isAdmin {
|
|
t.Skip("not running with administrator access, skipping")
|
|
}
|
|
|
|
// Create temporary file.
|
|
tempDir := t.TempDir()
|
|
testPath := filepath.Join(tempDir, "testfile.txt")
|
|
|
|
testfile, err := os.Create(testPath)
|
|
test.OK(t, errors.Wrapf(err, "failed to create temporary file: %s", testPath))
|
|
test.OK(t, testfile.Close())
|
|
|
|
// Set restricted permissions.
|
|
// Deny file read/write/execute to "Everyone" (all accounts); allow delete to "Everyone".
|
|
sd, err := windows.SecurityDescriptorFromString("D:PAI(D;;FRFWFX;;;WD)(A;;SD;;;WD)")
|
|
test.OK(t, errors.Wrap(err, "failed to parse SDDL: %s"))
|
|
dacl, _, err := sd.DACL()
|
|
test.OK(t, errors.Wrap(err, "failed to extract SD DACL"))
|
|
err = windows.SetNamedSecurityInfo(testPath, windows.SE_FILE_OBJECT, windows.DACL_SECURITY_INFORMATION|windows.PROTECTED_DACL_SECURITY_INFORMATION, nil, nil, dacl, nil)
|
|
test.OK(t, errors.Wrapf(err, "failed to set SD: %s", testPath))
|
|
|
|
return testPath
|
|
}
|