Commit 493adfb7 authored by Jakob Unterwurzacher's avatar Jakob Unterwurzacher Committed by Han-Wen Nienhuys

loopback: preserve owner when running as root

If we are running as root have caller information from
the context, try to set the owner of newly created files
and directories.

Lays the foundation for fixing xfstests generic/087
(xfstests always run as root).

Change-Id: Ib8d768153f3ec82ce572021a433a6398560efd44
parent 037efc7d
...@@ -89,12 +89,26 @@ func (n *loopbackNode) Lookup(ctx context.Context, name string, out *fuse.EntryO ...@@ -89,12 +89,26 @@ func (n *loopbackNode) Lookup(ctx context.Context, name string, out *fuse.EntryO
return ch, 0 return ch, 0
} }
// preserveOwner sets uid and gid of `path` according to the caller information
// in `ctx`.
func (n *loopbackNode) preserveOwner(ctx context.Context, path string) error {
if os.Getuid() != 0 {
return nil
}
caller, ok := fuse.FromContext(ctx)
if !ok {
return nil
}
return syscall.Lchown(path, int(caller.Uid), int(caller.Gid))
}
func (n *loopbackNode) Mknod(ctx context.Context, name string, mode, rdev uint32, out *fuse.EntryOut) (*Inode, syscall.Errno) { func (n *loopbackNode) Mknod(ctx context.Context, name string, mode, rdev uint32, out *fuse.EntryOut) (*Inode, syscall.Errno) {
p := filepath.Join(n.path(), name) p := filepath.Join(n.path(), name)
err := syscall.Mknod(p, mode, int(rdev)) err := syscall.Mknod(p, mode, int(rdev))
if err != nil { if err != nil {
return nil, ToErrno(err) return nil, ToErrno(err)
} }
n.preserveOwner(ctx, p)
st := syscall.Stat_t{} st := syscall.Stat_t{}
if err := syscall.Lstat(p, &st); err != nil { if err := syscall.Lstat(p, &st); err != nil {
syscall.Rmdir(p) syscall.Rmdir(p)
...@@ -115,6 +129,7 @@ func (n *loopbackNode) Mkdir(ctx context.Context, name string, mode uint32, out ...@@ -115,6 +129,7 @@ func (n *loopbackNode) Mkdir(ctx context.Context, name string, mode uint32, out
if err != nil { if err != nil {
return nil, ToErrno(err) return nil, ToErrno(err)
} }
n.preserveOwner(ctx, p)
st := syscall.Stat_t{} st := syscall.Stat_t{}
if err := syscall.Lstat(p, &st); err != nil { if err := syscall.Lstat(p, &st); err != nil {
syscall.Rmdir(p) syscall.Rmdir(p)
...@@ -189,7 +204,7 @@ func (n *loopbackNode) Create(ctx context.Context, name string, flags uint32, mo ...@@ -189,7 +204,7 @@ func (n *loopbackNode) Create(ctx context.Context, name string, flags uint32, mo
if err != nil { if err != nil {
return nil, nil, 0, ToErrno(err) return nil, nil, 0, ToErrno(err)
} }
n.preserveOwner(ctx, p)
st := syscall.Stat_t{} st := syscall.Stat_t{}
if err := syscall.Fstat(fd, &st); err != nil { if err := syscall.Fstat(fd, &st); err != nil {
syscall.Close(fd) syscall.Close(fd)
...@@ -210,6 +225,7 @@ func (n *loopbackNode) Symlink(ctx context.Context, target, name string, out *fu ...@@ -210,6 +225,7 @@ func (n *loopbackNode) Symlink(ctx context.Context, target, name string, out *fu
if err != nil { if err != nil {
return nil, ToErrno(err) return nil, ToErrno(err)
} }
n.preserveOwner(ctx, p)
st := syscall.Stat_t{} st := syscall.Stat_t{}
if err := syscall.Lstat(p, &st); err != nil { if err := syscall.Lstat(p, &st); err != nil {
syscall.Unlink(p) syscall.Unlink(p)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment