summaryrefslogtreecommitdiff
path: root/internal/fusefrontend_reverse/rpath.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/fusefrontend_reverse/rpath.go')
-rw-r--r--internal/fusefrontend_reverse/rpath.go21
1 files changed, 21 insertions, 0 deletions
diff --git a/internal/fusefrontend_reverse/rpath.go b/internal/fusefrontend_reverse/rpath.go
index fa7680f..2dc76e1 100644
--- a/internal/fusefrontend_reverse/rpath.go
+++ b/internal/fusefrontend_reverse/rpath.go
@@ -8,6 +8,7 @@ import (
"github.com/rfjakob/gocryptfs/internal/nametransform"
"github.com/rfjakob/gocryptfs/internal/pathiv"
+ "github.com/rfjakob/gocryptfs/internal/syscallcompat"
"github.com/rfjakob/gocryptfs/internal/tlog"
)
@@ -89,3 +90,23 @@ func (rfs *ReverseFS) decryptPath(relPath string) (string, error) {
rPathCache.store(cDir, dirIV, nametransform.Dir(pRelPath))
return pRelPath, nil
}
+
+// openBackingDir decrypt the relative ciphertext path "cRelPath", opens
+// the directory that contains the target file/dir and returns the fd to
+// the directory and the decrypted name of the target file.
+// The fd/name pair is intended for use with fchownat and friends.
+func (rfs *ReverseFS) openBackingDir(cRelPath string) (dirfd int, pName string, err error) {
+ // Decrypt relative path
+ pRelPath, err := rfs.decryptPath(cRelPath)
+ if err != nil {
+ return -1, "", err
+ }
+ // Open directory, safe against symlink races
+ pDir := filepath.Dir(pRelPath)
+ dirfd, err = syscallcompat.OpenNofollow(rfs.args.Cipherdir, pDir, syscall.O_RDONLY|syscall.O_DIRECTORY, 0)
+ if err != nil {
+ return -1, "", err
+ }
+ pName = filepath.Base(pRelPath)
+ return dirfd, pName, nil
+}