diff options
Diffstat (limited to 'internal/system/acl.go')
| -rw-r--r-- | internal/system/acl.go | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/internal/system/acl.go b/internal/system/acl.go new file mode 100644 index 00000000..9c89752b --- /dev/null +++ b/internal/system/acl.go @@ -0,0 +1,78 @@ +package system + +import ( + "fmt" + "slices" + + "git.ophivana.moe/cat/fortify/acl" + "git.ophivana.moe/cat/fortify/internal/fmsg" + "git.ophivana.moe/cat/fortify/internal/state" + "git.ophivana.moe/cat/fortify/internal/verbose" +) + +// UpdatePerm appends an ephemeral acl update Op. +func (sys *I) UpdatePerm(path string, perms ...acl.Perm) { + sys.UpdatePermType(Process, path, perms...) +} + +// UpdatePermType appends an acl update Op. +func (sys *I) UpdatePermType(et state.Enablement, path string, perms ...acl.Perm) { + sys.lock.Lock() + defer sys.lock.Unlock() + + sys.ops = append(sys.ops, &ACL{et, path, perms}) +} + +type ACL struct { + et state.Enablement + path string + perms []acl.Perm +} + +func (a *ACL) Type() state.Enablement { + return a.et +} + +func (a *ACL) apply(sys *I) error { + verbose.Println("applying ACL", a, "uid:", sys.uid, "type:", TypeString(a.et), "path:", a.path) + return fmsg.WrapErrorSuffix(acl.UpdatePerm(a.path, sys.uid, a.perms...), + fmt.Sprintf("cannot apply ACL entry to %q:", a.path)) +} + +func (a *ACL) revert(sys *I, ec *Criteria) error { + if ec.hasType(a) { + verbose.Println("stripping ACL", a, "uid:", sys.uid, "type:", TypeString(a.et), "path:", a.path) + return fmsg.WrapErrorSuffix(acl.UpdatePerm(a.path, sys.uid), + fmt.Sprintf("cannot strip ACL entry from %q:", a.path)) + } else { + verbose.Println("skipping ACL", a, "uid:", sys.uid, "tag:", TypeString(a.et), "path:", a.path) + return nil + } +} + +func (a *ACL) Is(o Op) bool { + a0, ok := o.(*ACL) + return ok && a0 != nil && + a.et == a0.et && + a.path == a0.path && + slices.Equal(a.perms, a0.perms) +} + +func (a *ACL) Path() string { + return a.path +} + +func (a *ACL) String() string { + var s = []byte("---") + for _, p := range a.perms { + switch p { + case acl.Read: + s[0] = 'r' + case acl.Write: + s[1] = 'w' + case acl.Execute: + s[2] = 'x' + } + } + return string(s) +} |
