Skip to content

Commit

Permalink
Merge pull request #4708 from zmanda/windows-securitydesc
Browse files Browse the repository at this point in the history
Back up and restore SecurityDescriptors on Windows
  • Loading branch information
MichaelEischer committed May 12, 2024
2 parents b5fdb1d + a4fd1b9 commit 92221c2
Show file tree
Hide file tree
Showing 12 changed files with 743 additions and 24 deletions.
2 changes: 1 addition & 1 deletion changelog/unreleased/pull-4611
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Enhancement: Back up windows created time and file attributes like hidden flag

Restic did not back up windows-specific meta-data like created time and file attributes like hidden flag.
Restic now backs up file created time and file attributes like hidden, readonly and encrypted flag when backing up files and folders on windows.
Restic now backs up file created time and file attributes like hidden, readonly and encrypted flag when backing up files and folders on Windows.

https://github.com/restic/restic/pull/4611

11 changes: 11 additions & 0 deletions changelog/unreleased/pull-4708
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Enhancement: Back up and restore SecurityDescriptors on Windows

Restic now backs up and restores SecurityDescriptors when backing up files and folders
on Windows which includes owner, group, discretionary access control list (DACL),
system access control list (SACL). This requires the user to be a member of backup
operators or the application must be run as admin.
If that is not the case, only the current user's owner, group and DACL will be backed up
and during restore only the DACL of the backed file will be restored while the current
user's owner and group will be set during the restore.

https://github.com/restic/restic/pull/4708
7 changes: 6 additions & 1 deletion doc/040_backup.rst
Original file line number Diff line number Diff line change
Expand Up @@ -514,12 +514,17 @@ written, and the next backup needs to write new metadata again. If you really
want to save the access time for files and directories, you can pass the
``--with-atime`` option to the ``backup`` command.

Backing up full security descriptors on Windows is only possible when the user
has ``SeBackupPrivilege``privilege or is running as admin. This is a restriction
of Windows not restic.
If either of these conditions are not met, only the owner, group and DACL will
be backed up.
Note that ``restic`` does not back up some metadata associated with files. Of
particular note are:

* File creation date on Unix platforms
* Inode flags on Unix platforms
* File ownership and ACLs on Windows

Reading data from a command
***************************
Expand Down
5 changes: 5 additions & 0 deletions doc/050_restore.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ Restoring symbolic links on windows is only possible when the user has
``SeCreateSymbolicLinkPrivilege`` privilege or is running as admin. This is a
restriction of windows not restic.

Restoring full security descriptors on Windows is only possible when the user has
``SeRestorePrivilege``, ``SeSecurityPrivilege`` and ``SeTakeOwnershipPrivilege``
privilege or is running as admin. This is a restriction of Windows not restic.
If either of these conditions are not met, only the DACL will be restored.

By default, restic does not restore files as sparse. Use ``restore --sparse`` to
enable the creation of sparse files if supported by the filesystem. Then restic
will restore long runs of zero bytes as holes in the corresponding files.
Expand Down
4 changes: 1 addition & 3 deletions internal/debug/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import (
"path/filepath"
"runtime"
"strings"

"github.com/restic/restic/internal/fs"
)

var opts struct {
Expand Down Expand Up @@ -46,7 +44,7 @@ func initDebugLogger() {

fmt.Fprintf(os.Stderr, "debug log file %v\n", debugfile)

f, err := fs.OpenFile(debugfile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
f, err := os.OpenFile(debugfile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
if err != nil {
fmt.Fprintf(os.Stderr, "unable to open debug log file: %v\n", err)
os.Exit(2)
Expand Down
24 changes: 15 additions & 9 deletions internal/errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,28 @@ func Is(x, y error) bool { return stderrors.Is(x, y) }
// unwrap errors returned by [Join].
func Unwrap(err error) error { return stderrors.Unwrap(err) }

// CombineErrors combines multiple errors into a single error.
func CombineErrors(errors ...error) error {
// CombineErrors combines multiple errors into a single error after filtering out any nil values.
// If no errors are passed, it returns nil.
// If one error is passed, it simply returns that same error.
func CombineErrors(errors ...error) (err error) {
var combinedErrorMsg string

for _, err := range errors {
if err != nil {
var multipleErrors bool
for _, errVal := range errors {
if errVal != nil {
if combinedErrorMsg != "" {
combinedErrorMsg += "; " // Separate error messages with a delimiter
multipleErrors = true
} else {
// Set the first error
err = errVal
}
combinedErrorMsg += err.Error()
combinedErrorMsg += errVal.Error()
}
}

if combinedErrorMsg == "" {
return nil // No errors, return nil
return nil // If no errors, return nil
} else if !multipleErrors {
return err // If only one error, return that first error
}

return fmt.Errorf("multiple errors occurred: [%s]", combinedErrorMsg)
}

0 comments on commit 92221c2

Please sign in to comment.