Replace checkPermBits error-return with hasPermBits bool
- hasPermBits uses a 4-entry mask array indexed by mode&3 to select the required permission bits: OREAD→4, OWRITE→2, ORDWR→6, OEXEC→1 - Zero branches, zero error paths — returns bits&mask == mask - open() uses OR semantics: checks owner, group, world independently; any tier granting access is sufficient - checkPerm removed entirely; permission logic is pure boolean math
This commit is contained in:
parent
325ad224be
commit
0b4daf016a
|
|
@ -144,35 +144,11 @@ func fileOwnerGroup(root *fs.Tree, path string) (uid, gid string) {
|
|||
return "ollie", "agent"
|
||||
}
|
||||
|
||||
func checkPerm(uname string, mode uint8, uid string, perm uint32, inGroup bool) error {
|
||||
var bits uint32
|
||||
if uname == uid {
|
||||
bits = (perm >> 6) & 7
|
||||
} else if inGroup {
|
||||
bits = (perm >> 3) & 7
|
||||
} else {
|
||||
bits = perm & 7
|
||||
}
|
||||
omode := mode & 3
|
||||
switch omode {
|
||||
case plan9.OREAD:
|
||||
if bits&4 == 0 {
|
||||
return fmt.Errorf("permission denied")
|
||||
}
|
||||
case plan9.OWRITE:
|
||||
if bits&2 == 0 {
|
||||
return fmt.Errorf("permission denied")
|
||||
}
|
||||
case plan9.ORDWR:
|
||||
if bits&6 != 6 {
|
||||
return fmt.Errorf("permission denied")
|
||||
}
|
||||
case plan9.OEXEC:
|
||||
if bits&1 == 0 {
|
||||
return fmt.Errorf("permission denied")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
var permMask = [4]uint32{4, 2, 6, 1} // OREAD, OWRITE, ORDWR, OEXEC
|
||||
|
||||
func hasPermBits(mode uint8, bits uint32) bool {
|
||||
m := permMask[mode&3]
|
||||
return bits&m == m
|
||||
}
|
||||
|
||||
const readTimeout = 10 * time.Second
|
||||
|
|
@ -413,8 +389,20 @@ func (s *Server) open(cs *connState, fc *plan9.Fcall) *plan9.Fcall {
|
|||
return errFcall(fc, "bad fid")
|
||||
}
|
||||
uid, gid := fileOwnerGroup(s.rootTree, f.path)
|
||||
if err := checkPerm(cs.uname, fc.Mode, uid, uint32(makeStat(s.rootTree, f.path).Mode)&0777, s.InGroup(gid, cs.uname)); err != nil {
|
||||
return errFcall(fc, err.Error())
|
||||
perm := uint32(makeStat(s.rootTree, f.path).Mode) & 0777
|
||||
|
||||
allowed := false
|
||||
if cs.uname == uid {
|
||||
allowed = hasPermBits(fc.Mode, perm>>6)
|
||||
}
|
||||
if !allowed && s.InGroup(gid, cs.uname) {
|
||||
allowed = hasPermBits(fc.Mode, perm>>3)
|
||||
}
|
||||
if !allowed {
|
||||
allowed = hasPermBits(fc.Mode, perm)
|
||||
}
|
||||
if !allowed {
|
||||
return errFcall(fc, "permission denied")
|
||||
}
|
||||
f.mode = fc.Mode
|
||||
return &plan9.Fcall{Type: plan9.Ropen, Tag: fc.Tag, Qid: f.qid}
|
||||
|
|
|
|||
Loading…
Reference in New Issue