acl: implement removeEntry in C
Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
parent
7e69893264
commit
4900cd6d41
47
acl/acl-update.c
Normal file
47
acl/acl-update.c
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#include "acl-update.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <sys/acl.h>
|
||||||
|
#include <acl/libacl.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
5
acl/acl-update.h
Normal file
5
acl/acl-update.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#include <sys/acl.h>
|
||||||
|
|
||||||
|
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);
|
77
acl/acl.go
77
acl/acl.go
@ -11,30 +11,12 @@ import (
|
|||||||
/*
|
/*
|
||||||
#cgo linux pkg-config: --static libacl
|
#cgo linux pkg-config: --static libacl
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include "acl-update.h"
|
||||||
#include <sys/acl.h>
|
|
||||||
#include <acl/libacl.h>
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
func getFile(name string, t C.acl_type_t) (*ACL, error) {
|
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) {
|
if errors.Is(err, syscall.ENODATA) {
|
||||||
err = nil
|
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 {
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,54 +67,9 @@ type (
|
|||||||
Perm C.acl_perm_t
|
Perm C.acl_perm_t
|
||||||
)
|
)
|
||||||
|
|
||||||
func (acl *ACL) removeEntry(tt C.acl_tag_t, tq int) error {
|
func (acl *ACL) removeEntry(uid int) error {
|
||||||
var e C.acl_entry_t
|
_, err := C.f_acl_delete_by_uid(acl.acl, C.uid_t(uid))
|
||||||
|
return err
|
||||||
// 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update replaces ACL_USER entry with qualifier uid.
|
// Update replaces ACL_USER entry with qualifier uid.
|
||||||
@ -146,7 +83,7 @@ func Update(name string, uid int, perms ...Perm) error {
|
|||||||
defer a.free()
|
defer a.free()
|
||||||
|
|
||||||
// remove existing entry
|
// remove existing entry
|
||||||
if err = a.removeEntry(User, uid); err != nil {
|
if err = a.removeEntry(uid); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user