From 4900cd6d41fa5e6d046151abbc35fdd1be3e8a0e Mon Sep 17 00:00:00 2001 From: Ophestra Date: Mon, 17 Feb 2025 20:37:10 +0900 Subject: [PATCH] acl: implement removeEntry in C Signed-off-by: Ophestra --- acl/acl-update.c | 47 +++++++++++++++++++++++++++++ acl/acl-update.h | 5 ++++ acl/acl.go | 77 +++++------------------------------------------- 3 files changed, 59 insertions(+), 70 deletions(-) create mode 100644 acl/acl-update.c create mode 100644 acl/acl-update.h diff --git a/acl/acl-update.c b/acl/acl-update.c new file mode 100644 index 0000000..c0d8285 --- /dev/null +++ b/acl/acl-update.c @@ -0,0 +1,47 @@ +#include "acl-update.h" +#include +#include +#include +#include + +acl_t f_acl_get_file(const char *path_p, acl_type_t type) { + acl_t acl = acl_get_file(path_p, type); + free((void *)path_p); + return acl; +} + +int f_acl_set_file(const char *path_p, acl_type_t type, acl_t acl) { + if (acl_valid(acl) != 0) { + return -1; + } + + int ret = acl_set_file(path_p, type, acl); + free((void *)path_p); + return ret; +} + +void f_acl_delete_by_uid(acl_t acl, uid_t uid) { + acl_entry_t entry; // acl_get_entry does not store entry_p + acl_tag_t tag_type; // acl_get_tag_type does not store tag_type_p + void *qualifier_p; + bool res; + + for (int r = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry); r == 1; r = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry)) { + if (acl_get_tag_type(entry, &tag_type) != 0) + return; + if (tag_type != ACL_USER) + continue; + + qualifier_p = acl_get_qualifier(entry); + if (qualifier_p == NULL) + return; + res = *(uid_t *)qualifier_p == uid; + acl_free(qualifier_p); + + if (!res) + continue; + + acl_delete_entry(acl, entry); + break; + } +} diff --git a/acl/acl-update.h b/acl/acl-update.h new file mode 100644 index 0000000..1dfc1ae --- /dev/null +++ b/acl/acl-update.h @@ -0,0 +1,5 @@ +#include + +acl_t f_acl_get_file(const char *path_p, acl_type_t type); +int f_acl_set_file(const char *path_p, acl_type_t type, acl_t acl); +void f_acl_delete_by_uid(acl_t acl, uid_t uid); diff --git a/acl/acl.go b/acl/acl.go index fe35561..39ff33a 100644 --- a/acl/acl.go +++ b/acl/acl.go @@ -11,30 +11,12 @@ import ( /* #cgo linux pkg-config: --static libacl -#include -#include -#include - -static acl_t _go_acl_get_file(const char *path_p, acl_type_t type) { - acl_t acl = acl_get_file(path_p, type); - free((void *)path_p); - return acl; -} - -static int _go_acl_set_file(const char *path_p, acl_type_t type, acl_t acl) { - if (acl_valid(acl) != 0) { - return -1; - } - - int ret = acl_set_file(path_p, type, acl); - free((void *)path_p); - return ret; -} +#include "acl-update.h" */ import "C" func getFile(name string, t C.acl_type_t) (*ACL, error) { - a, err := C._go_acl_get_file(C.CString(name), t) + a, err := C.f_acl_get_file(C.CString(name), t) if errors.Is(err, syscall.ENODATA) { err = nil } @@ -43,7 +25,7 @@ func getFile(name string, t C.acl_type_t) (*ACL, error) { } func (acl *ACL) setFile(name string, t C.acl_type_t) error { - _, err := C._go_acl_set_file(C.CString(name), t, acl.acl) + _, err := C.f_acl_set_file(C.CString(name), t, acl.acl) return err } @@ -85,54 +67,9 @@ type ( Perm C.acl_perm_t ) -func (acl *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(acl.acl, 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(acl.acl, 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(acl.acl, e) - return err - } - } +func (acl *ACL) removeEntry(uid int) error { + _, err := C.f_acl_delete_by_uid(acl.acl, C.uid_t(uid)) + return err } // Update replaces ACL_USER entry with qualifier uid. @@ -146,7 +83,7 @@ func Update(name string, uid int, perms ...Perm) error { defer a.free() // remove existing entry - if err = a.removeEntry(User, uid); err != nil { + if err = a.removeEntry(uid); err != nil { return err }