commit beb19f986cd16abe04068c7e623920357ce9b0e2
parent 63ac8a1fbeaf116d9d3bcf114186b4d430b0bf82
Author: Matsuda Kenji <info@mtkn.jp>
Date: Wed, 20 Dec 2023 07:45:18 +0900
unite GidFS to FS
Diffstat:
3 files changed, 15 insertions(+), 23 deletions(-)
diff --git a/fs.go b/fs.go
@@ -8,6 +8,10 @@ import (
type FS interface {
// OpenFile opens file named name with omode.
OpenFile(name string, omode OpenMode) (File, error)
+ // IsGroupLeader reports whether uid is the leader of group.
+ IsGroupLeader(group, uid string) bool
+ // IsGroupMember reports whether uid is a member of group.
+ IsGroupMember(group, uid string) bool
}
type CreaterFS interface {
@@ -23,12 +27,6 @@ type RemoverFS interface {
Remove(name string) error
}
-type GidFS interface {
- FS
- IsGroupLeader(group, uid string) bool
- IsGroupMember(group, uid string) bool
-}
-
func FSModeToQidType(fm fs.FileMode) QidType {
var qt QidType
if fm&fs.ModeDir != 0 {
diff --git a/server.go b/server.go
@@ -436,7 +436,7 @@ func sOpen(ctx context.Context, s *Server, r *Req) {
Respond(ctx, r, ErrPerm)
return
}
- if !hasPerm(st, r.Fid.Uid, p) {
+ if !hasPerm(s.fs, st, r.Fid.Uid, p) {
Respond(ctx, r, ErrPerm)
return
}
@@ -447,7 +447,7 @@ func sOpen(ctx context.Context, s *Server, r *Req) {
Respond(ctx, r, fmt.Errorf("stat parent: %v", err))
return
}
- if !hasPerm(st, r.Fid.Uid, AWRITE) {
+ if !hasPerm(s.fs, st, r.Fid.Uid, AWRITE) {
Respond(ctx, r, ErrPerm)
return
}
@@ -490,7 +490,7 @@ func sCreate(ctx context.Context, s *Server, r *Req) {
Respond(ctx, r, fmt.Errorf("create in non-dir"))
return
}
- if !hasPerm(dirstat, r.Fid.Uid, AWRITE) {
+ if !hasPerm(s.fs, dirstat, r.Fid.Uid, AWRITE) {
Respond(ctx, r, ErrPerm)
return
}
@@ -734,7 +734,7 @@ func sRemove(ctx context.Context, s *Server, r *Req) {
Respond(ctx, r, fmt.Errorf("stat parent: %v", err))
return
}
- if !hasPerm(pstat, r.Fid.Uid, AWRITE) {
+ if !hasPerm(s.fs, pstat, r.Fid.Uid, AWRITE) {
Respond(ctx, r, ErrPerm)
return
}
@@ -829,7 +829,7 @@ func sWStat(ctx context.Context, s *Server, r *Req) {
Respond(ctx, r, fmt.Errorf("stat parent: %v", err))
return
}
- if !hasPerm(pstat, r.Fid.Uid, AWRITE) {
+ if !hasPerm(s.fs, pstat, r.Fid.Uid, AWRITE) {
Respond(ctx, r, ErrPerm)
return
}
@@ -854,7 +854,7 @@ func sWStat(ctx context.Context, s *Server, r *Req) {
newStat.Name = wstat.Name
}
if wstat.Length != ^int64(0) && wstat.Length != newStat.Length {
- if fi.IsDir() || !hasPerm(fi, r.Fid.Uid, AWRITE) {
+ if fi.IsDir() || !hasPerm(s.fs, fi, r.Fid.Uid, AWRITE) {
Respond(ctx, r, ErrPerm)
return
}
@@ -883,17 +883,12 @@ func sWStat(ctx context.Context, s *Server, r *Req) {
// TODO: check group membership
// for now, group member == group leader == gid
if wstat.Gid != "" && wstat.Gid != newStat.Gid {
- fsys, ok := s.fs.(GidFS)
- if !ok {
- Respond(ctx, r, ErrOperation)
- return
- }
// by the owner if also a member of the new group;
// or by the group leader of the file's current group if
// also the leader of the new group.
- if r.Fid.Uid == newStat.Uid && fsys.IsGroupMember(wstat.Gid, r.Fid.Uid) ||
- fsys.IsGroupLeader(newStat.Gid, r.Fid.Uid) &&
- fsys.IsGroupLeader(wstat.Gid, r.Fid.Uid) {
+ if r.Fid.Uid == newStat.Uid && s.fs.IsGroupMember(wstat.Gid, r.Fid.Uid) ||
+ s.fs.IsGroupLeader(newStat.Gid, r.Fid.Uid) &&
+ s.fs.IsGroupLeader(wstat.Gid, r.Fid.Uid) {
newStat.Gid = wstat.Gid
} else {
Respond(ctx, r, ErrPerm)
diff --git a/uid.go b/uid.go
@@ -6,8 +6,7 @@ import (
// hasPerm reports whether the user uid have the permission p on the File f.
// p is logical OR of AREAD, AWRITE, AEXEC.
-// TODO: user is assumed to be the leader of the group
-func hasPerm(fi fs.FileInfo, uid string, p fs.FileMode) bool {
+func hasPerm(fsys FS, fi fs.FileInfo, uid string, p fs.FileMode) bool {
fp := fi.Mode().Perm()
stat := fi.Sys().(*Stat)
m := fp & 7 // other
@@ -20,7 +19,7 @@ func hasPerm(fi fs.FileInfo, uid string, p fs.FileMode) bool {
return true
}
}
- if stat.Gid == uid {
+ if fsys.IsGroupMember(stat.Gid, uid) {
m |= (fp >> 3) & 7
if (p & m) == p {
return true