summaryrefslogtreecommitdiffstats
path: root/fsade.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2020-01-07 10:36:33 -0500
committerTavian Barnes <tavianator@tavianator.com>2020-01-07 10:36:33 -0500
commit3fa560ca6e0d68938f71ed1984f63f8c5cb7e7cc (patch)
treee27913a1146b563d2fe202a289e326ef9071b2de /fsade.c
parent8644e0e5ce28b662a0b4e4b19351a38be5fa6681 (diff)
downloadbfs-3fa560ca6e0d68938f71ed1984f63f8c5cb7e7cc.tar.xz
fsade: Support NFSv4 ACLs on FreeBSD
Diffstat (limited to 'fsade.c')
-rw-r--r--fsade.c61
1 files changed, 38 insertions, 23 deletions
diff --git a/fsade.c b/fsade.c
index c7f9fed..df85431 100644
--- a/fsade.c
+++ b/fsade.c
@@ -136,6 +136,17 @@ static int bfs_check_acl_type(const char *path, acl_type_t type) {
}
int ret = 0;
+
+#if __FreeBSD__
+ int trivial;
+ if (acl_is_trivial_np(acl, &trivial) < 0) {
+ ret = -1;
+ } else if (trivial) {
+ ret = 0;
+ } else {
+ ret = 1;
+ }
+#else
acl_entry_t entry;
for (int status = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry);
#if __APPLE__
@@ -160,46 +171,50 @@ static int bfs_check_acl_type(const char *path, acl_type_t type) {
break;
#endif
}
+#endif // !__FreeBSD__
+ int error = errno;
acl_free(acl);
+ errno = error;
return ret;
}
int bfs_check_acl(const struct BFTW *ftwbuf) {
+ static const acl_type_t acl_types[] = {
+#if __APPLE__
+ // macOS gives EINVAL for either of the two standard ACL types,
+ // supporting only ACL_TYPE_EXTENDED
+ ACL_TYPE_EXTENDED,
+#else
+ // The two standard POSIX.1e ACL types
+ ACL_TYPE_ACCESS,
+ ACL_TYPE_DEFAULT,
+#endif
+
+#ifdef ACL_TYPE_NFS4
+ ACL_TYPE_NFS4,
+#endif
+ };
+ static const size_t n_acl_types = sizeof(acl_types)/sizeof(acl_types[0]);
+
if (ftwbuf->typeflag == BFTW_LNK) {
return 0;
}
const char *path = fake_at(ftwbuf);
- int error = ENOTSUP;
int ret = -1;
-
-#if __APPLE__
- // macOS gives EINVAL for either of the two standard ACL types,
- // supporting only ACL_TYPE_EXTENDED
- if (ret <= 0) {
- ret = bfs_check_acl_type(path, ACL_TYPE_EXTENDED);
- if (ret < 0) {
- error = errno;
- }
- }
-#else
- if (ret <= 0) {
- ret = bfs_check_acl_type(path, ACL_TYPE_ACCESS);
- if (ret < 0) {
- error = errno;
+ for (size_t i = 0; i < n_acl_types && ret <= 0; ++i) {
+ if (acl_types[i] == ACL_TYPE_DEFAULT && ftwbuf->typeflag != BFTW_DIR) {
+ // ACL_TYPE_DEFAULT is supported only for directories,
+ // otherwise acl_get_file() gives EACCESS
+ continue;
}
- }
- if (ret <= 0 && ftwbuf->typeflag == BFTW_DIR) {
- ret = bfs_check_acl_type(path, ACL_TYPE_DEFAULT);
- if (ret < 0) {
- error = errno;
- }
+ ret = bfs_check_acl_type(path, acl_types[i]);
}
-#endif
+ int error = errno;
free_fake_at(ftwbuf, path);
errno = error;
return ret;