aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/acl/export.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/acl/export.go')
-rw-r--r--internal/acl/export.go86
1 files changed, 86 insertions, 0 deletions
diff --git a/internal/acl/export.go b/internal/acl/export.go
new file mode 100644
index 00000000..aeb8ed96
--- /dev/null
+++ b/internal/acl/export.go
@@ -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)
+}