rename to fortify and restructure
More sandbox features will be added and this will no longer track ego's features and behaviour. Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
This commit is contained in:
99
internal/acl/c.go
Normal file
99
internal/acl/c.go
Normal file
@@ -0,0 +1,99 @@
|
||||
package acl
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//#include <stdlib.h>
|
||||
//#include <sys/acl.h>
|
||||
//#include <acl/libacl.h>
|
||||
//#cgo linux LDFLAGS: -lacl
|
||||
import "C"
|
||||
|
||||
type acl struct {
|
||||
val C.acl_t
|
||||
freed bool
|
||||
}
|
||||
|
||||
func aclGetFile(path string, t C.acl_type_t) (*acl, error) {
|
||||
p := C.CString(path)
|
||||
a, err := C.acl_get_file(p, t)
|
||||
C.free(unsafe.Pointer(p))
|
||||
|
||||
if errors.Is(err, syscall.ENODATA) {
|
||||
err = nil
|
||||
}
|
||||
return &acl{val: a, freed: false}, err
|
||||
}
|
||||
|
||||
func (a *acl) setFile(path string, t C.acl_type_t) error {
|
||||
if C.acl_valid(a.val) != 0 {
|
||||
return fmt.Errorf("invalid acl")
|
||||
}
|
||||
|
||||
p := C.CString(path)
|
||||
_, err := C.acl_set_file(p, t, a.val)
|
||||
C.free(unsafe.Pointer(p))
|
||||
return err
|
||||
}
|
||||
|
||||
func (a *acl) removeEntry(tt C.acl_tag_t, tq int) error {
|
||||
var e C.acl_entry_t
|
||||
|
||||
// get first entry
|
||||
if r, err := C.acl_get_entry(a.val, C.ACL_FIRST_ENTRY, &e); err != nil {
|
||||
return err
|
||||
} else if r == 0 {
|
||||
// return on acl with no entries
|
||||
return nil
|
||||
}
|
||||
|
||||
for {
|
||||
if r, err := C.acl_get_entry(a.val, C.ACL_NEXT_ENTRY, &e); err != nil {
|
||||
return err
|
||||
} else if r == 0 {
|
||||
// return on drained acl
|
||||
return nil
|
||||
}
|
||||
|
||||
var (
|
||||
q int
|
||||
t C.acl_tag_t
|
||||
)
|
||||
|
||||
// get current entry tag type
|
||||
if _, err := C.acl_get_tag_type(e, &t); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// get current entry qualifier
|
||||
if rq, err := C.acl_get_qualifier(e); err != nil {
|
||||
// neither ACL_USER nor ACL_GROUP
|
||||
if errors.Is(err, syscall.EINVAL) {
|
||||
continue
|
||||
}
|
||||
|
||||
return err
|
||||
} else {
|
||||
q = *(*int)(rq)
|
||||
C.acl_free(rq)
|
||||
}
|
||||
|
||||
// delete on match
|
||||
if t == tt && q == tq {
|
||||
_, err := C.acl_delete_entry(a.val, e)
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (a *acl) free() {
|
||||
if a.freed {
|
||||
panic("acl already freed")
|
||||
}
|
||||
C.acl_free(unsafe.Pointer(a.val))
|
||||
a.freed = true
|
||||
}
|
||||
86
internal/acl/export.go
Normal file
86
internal/acl/export.go
Normal file
@@ -0,0 +1,86 @@
|
||||
package acl
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//#include <stdlib.h>
|
||||
//#include <sys/acl.h>
|
||||
//#include <acl/libacl.h>
|
||||
//#cgo linux LDFLAGS: -lacl
|
||||
import "C"
|
||||
|
||||
const (
|
||||
Read = C.ACL_READ
|
||||
Write = C.ACL_WRITE
|
||||
Execute = C.ACL_EXECUTE
|
||||
|
||||
TypeDefault = C.ACL_TYPE_DEFAULT
|
||||
TypeAccess = C.ACL_TYPE_ACCESS
|
||||
|
||||
UndefinedTag = C.ACL_UNDEFINED_TAG
|
||||
UserObj = C.ACL_USER_OBJ
|
||||
User = C.ACL_USER
|
||||
GroupObj = C.ACL_GROUP_OBJ
|
||||
Group = C.ACL_GROUP
|
||||
Mask = C.ACL_MASK
|
||||
Other = C.ACL_OTHER
|
||||
)
|
||||
|
||||
func UpdatePerm(path string, uid int, perms ...C.acl_perm_t) error {
|
||||
// read acl from file
|
||||
a, err := aclGetFile(path, TypeAccess)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// free acl on return if get is successful
|
||||
defer a.free()
|
||||
|
||||
// remove existing entry
|
||||
if err = a.removeEntry(User, uid); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// create new entry if perms are passed
|
||||
if len(perms) > 0 {
|
||||
// create new acl entry
|
||||
var e C.acl_entry_t
|
||||
if _, err = C.acl_create_entry(&a.val, &e); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// get perm set of new entry
|
||||
var p C.acl_permset_t
|
||||
if _, err = C.acl_get_permset(e, &p); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add target perms
|
||||
for _, perm := range perms {
|
||||
if _, err = C.acl_add_perm(p, perm); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// set perm set to new entry
|
||||
if _, err = C.acl_set_permset(e, p); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// set user tag to new entry
|
||||
if _, err = C.acl_set_tag_type(e, User); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// set qualifier (uid) to new entry
|
||||
if _, err = C.acl_set_qualifier(e, unsafe.Pointer(&uid)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// calculate mask after update
|
||||
if _, err = C.acl_calc_mask(&a.val); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// write acl to file
|
||||
return a.setFile(path, TypeAccess)
|
||||
}
|
||||
Reference in New Issue
Block a user