From 73b7c1e933f5275f2741a5b32f501bc8353a359a Mon Sep 17 00:00:00 2001 From: kwnam Date: Wed, 18 Dec 2024 18:52:52 +0900 Subject: [PATCH] Support all-squash mount option --- cmd/mount_unix.go | 83 ++++++++++++++++++++++++++++----------------- pkg/fuse/context.go | 5 +++ pkg/vfs/vfs.go | 7 ++-- 3 files changed, 60 insertions(+), 35 deletions(-) diff --git a/cmd/mount_unix.go b/cmd/mount_unix.go index d404e2811778..7fec5e691a86 100644 --- a/cmd/mount_unix.go +++ b/cmd/mount_unix.go @@ -315,6 +315,10 @@ func fuseFlags() []cli.Flag { Name: "root-squash", Usage: "mapping local root user (uid = 0) to another one specified as :", }, + &cli.StringFlag{ + Name: "all-squash", + Usage: "mapping all users to another one specified as :", + }, &cli.BoolFlag{ Name: "prefix-internal", Usage: "add '.jfs' prefix to all internal files", @@ -828,6 +832,45 @@ func launchMount(mp string, conf *vfs.Config) error { } } +func getNobodyUIDGID() (uint32, uint32) { + var uid, gid uint32 = 65534, 65534 + if u, err := user.Lookup("nobody"); err == nil { + nobody, err := strconv.ParseUint(u.Uid, 10, 32) + if err != nil { + logger.Fatalf("invalid uid: %s", u.Uid) + } + uid = uint32(nobody) + } + if g, err := user.LookupGroup("nogroup"); err == nil { + nogroup, err := strconv.ParseUint(g.Gid, 10, 32) + if err != nil { + logger.Fatalf("invalid gid: %s", g.Gid) + } + gid = uint32(nogroup) + } + return uid, gid +} + +func parseUIDGID(input string, defaultUid uint32, defaultGid uint32) (uint32, uint32) { + ss := strings.SplitN(strings.TrimSpace(input), ":", 2) + uid, gid := defaultUid, defaultGid + if ss[0] != "" { + u, err := strconv.ParseUint(ss[0], 10, 32) + if err != nil { + logger.Fatalf("invalid uid: %s", ss[0]) + } + uid = uint32(u) + } + if len(ss) == 2 && ss[1] != "" { + g, err := strconv.ParseUint(ss[1], 10, 32) + if err != nil { + logger.Fatalf("invalid gid: %s", ss[1]) + } + gid = uint32(g) + } + return uid, gid +} + func mountMain(v *vfs.VFS, c *cli.Context) { if os.Getuid() == 0 { disableUpdatedb() @@ -838,39 +881,15 @@ func mountMain(v *vfs.VFS, c *cli.Context) { conf.DirEntryTimeout = utils.Duration(c.String("dir-entry-cache")) conf.NonDefaultPermission = c.Bool("non-default-permission") rootSquash := c.String("root-squash") + allSquash := c.String("all-squash") + nobodyUid, nobodyGid := getNobodyUIDGID() if rootSquash != "" { - var uid, gid uint32 = 65534, 65534 - if u, err := user.Lookup("nobody"); err == nil { - nobody, err := strconv.ParseUint(u.Uid, 10, 32) - if err != nil { - logger.Fatalf("invalid uid: %s", u.Uid) - } - uid = uint32(nobody) - } - if g, err := user.LookupGroup("nogroup"); err == nil { - nogroup, err := strconv.ParseUint(g.Gid, 10, 32) - if err != nil { - logger.Fatalf("invalid gid: %s", g.Gid) - } - gid = uint32(nogroup) - } - - ss := strings.SplitN(strings.TrimSpace(rootSquash), ":", 2) - if ss[0] != "" { - u, err := strconv.ParseUint(ss[0], 10, 32) - if err != nil { - logger.Fatalf("invalid uid: %s", ss[0]) - } - uid = uint32(u) - } - if len(ss) == 2 && ss[1] != "" { - g, err := strconv.ParseUint(ss[1], 10, 32) - if err != nil { - logger.Fatalf("invalid gid: %s", ss[1]) - } - gid = uint32(g) - } - conf.RootSquash = &vfs.RootSquash{Uid: uid, Gid: gid} + uid, gid := parseUIDGID(rootSquash, nobodyUid, nobodyGid) + conf.RootSquash = &vfs.AnonymousAccount{Uid: uid, Gid: gid} + } + if allSquash != "" { + uid, gid := parseUIDGID(allSquash, nobodyUid, nobodyGid) + conf.AllSquash = &vfs.AnonymousAccount{Uid: uid, Gid: gid} } logger.Infof("Mounting volume %s at %s ...", conf.Format.Name, conf.Meta.MountPoint) err := fuse.Serve(v, c.String("o"), c.Bool("enable-xattr"), c.Bool("enable-ioctl")) diff --git a/pkg/fuse/context.go b/pkg/fuse/context.go index c4b985c1921e..54ff55162537 100644 --- a/pkg/fuse/context.go +++ b/pkg/fuse/context.go @@ -68,6 +68,11 @@ func (fs *fileSystem) newContext(cancel <-chan struct{}, header *fuse.InHeader) ctx.header.Uid = fs.conf.RootSquash.Uid ctx.header.Gid = fs.conf.RootSquash.Gid } + if fs.conf.AllSquash != nil { + ctx.checkPermission = true + ctx.header.Uid = fs.conf.AllSquash.Uid + ctx.header.Gid = fs.conf.AllSquash.Gid + } return ctx } diff --git a/pkg/vfs/vfs.go b/pkg/vfs/vfs.go index f808f0fed530..f9b855875b20 100644 --- a/pkg/vfs/vfs.go +++ b/pkg/vfs/vfs.go @@ -128,8 +128,9 @@ type Config struct { AccessLog string `json:",omitempty"` PrefixInternal bool HideInternal bool - RootSquash *RootSquash `json:",omitempty"` - NonDefaultPermission bool `json:",omitempty"` + RootSquash *AnonymousAccount `json:",omitempty"` + AllSquash *AnonymousAccount `json:",omitempty"` + NonDefaultPermission bool `json:",omitempty"` Pid int PPid int @@ -138,7 +139,7 @@ type Config struct { FuseOpts *FuseOptions `json:",omitempty"` } -type RootSquash struct { +type AnonymousAccount struct { Uid uint32 Gid uint32 }