diff --git a/cmd/syncthing/decrypt/decrypt.go b/cmd/syncthing/decrypt/decrypt.go index 1bb56c683..5d4746ed9 100644 --- a/cmd/syncthing/decrypt/decrypt.go +++ b/cmd/syncthing/decrypt/decrypt.go @@ -129,6 +129,9 @@ func (c *CLI) getFolderID() (string, error) { // process handles the file named path in srcFs, decrypting it into dstFs // unless dstFs is nil. func (c *CLI) process(srcFs fs.Filesystem, dstFs fs.Filesystem, path string) error { + // Which filemode bits to preserve + const retainBits = fs.ModePerm | fs.ModeSetgid | fs.ModeSetuid | fs.ModeSticky + if c.Verbose { log.Printf("Processing %q", path) } @@ -168,6 +171,9 @@ func (c *CLI) process(srcFs fs.Filesystem, dstFs fs.Filesystem, path string) err return fmt.Errorf("%s: %w", plainFi.Name, err) } defer plainFd.Close() // also closed explicitly in the return + if err := dstFs.Chmod(plainFi.Name, fs.FileMode(plainFi.Permissions&uint32(retainBits))); err != nil { + return fmt.Errorf("%s: %w", plainFi.Name, err) + } } if err := c.decryptFile(encFi, &plainFi, encFd, plainFd); err != nil { @@ -184,7 +190,12 @@ func (c *CLI) process(srcFs fs.Filesystem, dstFs fs.Filesystem, path string) err } if plainFd != nil { - return plainFd.Close() + if err := plainFd.Close(); err != nil { + return fmt.Errorf("%s: %w", plainFi.Name, err) + } + if err := dstFs.Chtimes(plainFi.Name, plainFi.ModTime(), plainFi.ModTime()); err != nil { + return fmt.Errorf("%s: %w", plainFi.Name, err) + } } return nil }