summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2024-01-03 15:55:27 -0500
committerTavian Barnes <tavianator@tavianator.com>2024-01-03 16:43:15 -0500
commitd874481987c381fd572a6f3c43840c50111a9554 (patch)
tree991fe47290d47125d5f14fe73ec8d9f8010aae47 /src
parent976514edfb6063170049f561f5edbf330bbe4132 (diff)
downloadbfs-d874481987c381fd572a6f3c43840c50111a9554.tar.xz
fsade: Fix ACL checks on DragonFly BSD
Diffstat (limited to 'src')
-rw-r--r--src/fsade.c54
1 files changed, 45 insertions, 9 deletions
diff --git a/src/fsade.c b/src/fsade.c
index a48eeb0..d6ef4b8 100644
--- a/src/fsade.c
+++ b/src/fsade.c
@@ -117,24 +117,60 @@ static bool is_absence_error(int error) {
#if BFS_CAN_CHECK_ACL
+/** Unified interface for incompatible acl_get_entry() implementations. */
+static int bfs_acl_entry(acl_t acl, int which, acl_entry_t *entry) {
+#if __DragonFly__ && !defined(ACL_FIRST_ENTRY) && !defined(ACL_NEXT_ENTRY)
+# define ACL_FIRST_ENTRY 0
+# define ACL_NEXT_ENTRY 1
+
+ switch (which) {
+ case ACL_FIRST_ENTRY:
+ *entry = &acl->acl_entry[0];
+ break;
+ case ACL_NEXT_ENTRY:
+ ++*entry;
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+
+ acl_entry_t last = &acl->acl_entry[acl->acl_cnt];
+ return *entry == last;
+#else
+ int ret = acl_get_entry(acl, which, entry);
+# if __APPLE__
+ // POSIX.1e specifies a return value of 1 for success, but macOS returns 0 instead
+ return !ret;
+# else
+ return ret;
+# endif
+#endif
+}
+
+/** Unified interface for acl_get_tag_type(). */
+static int bfs_acl_tag_type(acl_entry_t entry, acl_tag_t *tag) {
+#if __DragonFly__
+ *tag = entry->ae_tag;
+ return 0;
+#else
+ return acl_get_tag_type(entry, tag);
+#endif
+}
+
/** Check if a POSIX.1e ACL is non-trivial. */
static int bfs_check_posix1e_acl(acl_t acl, bool ignore_required) {
int ret = 0;
acl_entry_t entry;
- for (int status = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry);
-#if __APPLE__
- // POSIX.1e specifies a return value of 1 for success, but macOS
- // returns 0 instead
- status == 0;
-#else
+ for (int status = bfs_acl_entry(acl, ACL_FIRST_ENTRY, &entry);
status > 0;
-#endif
- status = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry)) {
+ status = bfs_acl_entry(acl, ACL_NEXT_ENTRY, &entry))
+ {
#if defined(ACL_USER_OBJ) && defined(ACL_GROUP_OBJ) && defined(ACL_OTHER)
if (ignore_required) {
acl_tag_t tag;
- if (acl_get_tag_type(entry, &tag) != 0) {
+ if (bfs_acl_tag_type(entry, &tag) != 0) {
ret = -1;
continue;
}