fusefrontend: preserve owner for symlinks

https://github.com/rfjakob/gocryptfs/issues/64
This commit is contained in:
Jakob Unterwurzacher 2016-11-28 23:15:24 +01:00
parent e3c5e3f1c8
commit 55df8acac3
1 changed files with 15 additions and 9 deletions

View File

@ -351,7 +351,6 @@ func (fs *FS) Symlink(target string, linkName string, context *fuse.Context) (co
// Symlinks are encrypted like file contents (GCM) and base64-encoded // Symlinks are encrypted like file contents (GCM) and base64-encoded
cBinTarget := fs.contentEnc.EncryptBlock([]byte(target), 0, nil) cBinTarget := fs.contentEnc.EncryptBlock([]byte(target), 0, nil)
cTarget := base64.URLEncoding.EncodeToString(cBinTarget) cTarget := base64.URLEncoding.EncodeToString(cBinTarget)
// Handle long file name // Handle long file name
cName := filepath.Base(cPath) cName := filepath.Base(cPath)
if nametransform.IsLongContent(cName) { if nametransform.IsLongContent(cName) {
@ -361,25 +360,32 @@ func (fs *FS) Symlink(target string, linkName string, context *fuse.Context) (co
return fuse.ToStatus(err) return fuse.ToStatus(err)
} }
defer dirfd.Close() defer dirfd.Close()
// Create ".name" file
// Create ".name"
err = fs.nameTransform.WriteLongName(dirfd, cName, linkName) err = fs.nameTransform.WriteLongName(dirfd, cName, linkName)
if err != nil { if err != nil {
return fuse.ToStatus(err) return fuse.ToStatus(err)
} }
// Create "gocryptfs.longfile." symlink
// Create symlink
// TODO use syscall.Symlinkat once it is available in Go // TODO use syscall.Symlinkat once it is available in Go
err = syscall.Symlink(cTarget, cPath) err = syscall.Symlink(cTarget, cPath)
if err != nil { if err != nil {
nametransform.DeleteLongName(dirfd, cName) nametransform.DeleteLongName(dirfd, cName)
} }
} else {
// Create symlink
err = os.Symlink(cTarget, cPath)
}
if err != nil {
return fuse.ToStatus(err) return fuse.ToStatus(err)
} }
// Set owner
err = os.Symlink(cTarget, cPath) if fs.args.PreserveOwner {
return fuse.ToStatus(err) err = os.Lchown(cPath, int(context.Owner.Uid), int(context.Owner.Gid))
if err != nil {
tlog.Warn.Printf("Mknod: Lchown failed: %v", err)
}
}
return fuse.OK
} }
// Rename implements pathfs.Filesystem. // Rename implements pathfs.Filesystem.