#include <sys/cdefs.h>
#if 0
__FBSDID("$FreeBSD: head/lib/libc/posix1e/acl_delete_entry.c 326193 2017-11-25 17:12:48Z pfg $");
#else
__RCSID("$NetBSD: acl_delete_entry.c,v 1.1 2020/05/16 18:31:47 christos Exp $");
#endif
#include "namespace.h"
#include <sys/types.h>
#include <sys/acl.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include "acl_support.h"
static int
_entry_matches(const acl_entry_t a, const acl_entry_t b)
{
switch (_entry_brand(a)) {
case ACL_BRAND_NFS4:
if (a->ae_tag != b->ae_tag || a->ae_entry_type != b->ae_entry_type)
return (0);
if (a->ae_tag == ACL_USER || a->ae_tag == ACL_GROUP) {
if (a->ae_id != b->ae_id)
return (0);
}
return (1);
default:
if ((a->ae_tag == b->ae_tag) && (a->ae_id == b->ae_id))
return (1);
}
return (0);
}
int
acl_delete_entry(acl_t acl, acl_entry_t entry_d)
{
struct acl_entry entry_int;
size_t i, j;
int found = 0;
if (acl == NULL || entry_d == NULL) {
errno = EINVAL;
return (-1);
}
if (_entry_brand(entry_d) != _acl_brand(acl)) {
errno = EINVAL;
return (-1);
}
if ((acl->ats_acl.acl_cnt < 1) ||
(acl->ats_acl.acl_cnt > ACL_MAX_ENTRIES)) {
errno = EINVAL;
return (-1);
}
entry_int = *entry_d;
for (i = 0; i < acl->ats_acl.acl_cnt;) {
if (_entry_matches(&(acl->ats_acl.acl_entry[i]), &entry_int)) {
for (j = i; j < acl->ats_acl.acl_cnt - 1; ++j)
acl->ats_acl.acl_entry[j] =
acl->ats_acl.acl_entry[j+1];
acl->ats_acl.acl_cnt--;
bzero(&acl->ats_acl.acl_entry[j],
sizeof(struct acl_entry));
acl->ats_cur_entry = 0;
found = 1;
} else
i++;
}
if (found)
return (0);
errno = EINVAL;
return (-1);
}
int
acl_delete_entry_np(acl_t acl, int offset)
{
struct acl *acl_int;
size_t i;
if (acl == NULL) {
errno = EINVAL;
return (-1);
}
acl_int = &acl->ats_acl;
if (offset < 0 || (size_t)offset >= acl_int->acl_cnt) {
errno = EINVAL;
return (-1);
}
if ((acl->ats_acl.acl_cnt < 1) ||
(acl->ats_acl.acl_cnt > ACL_MAX_ENTRIES)) {
errno = EINVAL;
return (-1);
}
for (i = offset; i < acl->ats_acl.acl_cnt - 1; ++i)
acl->ats_acl.acl_entry[i] =
acl->ats_acl.acl_entry[i+1];
acl->ats_acl.acl_cnt--;
bzero(&acl->ats_acl.acl_entry[i],
sizeof(struct acl_entry));
acl->ats_cur_entry = 0;
return (0);
}