summaryrefslogtreecommitdiffstats
path: root/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'util.c')
-rw-r--r--util.c72
1 files changed, 71 insertions, 1 deletions
diff --git a/util.c b/util.c
index 0ec6dba..359a5cd 100644
--- a/util.c
+++ b/util.c
@@ -30,6 +30,10 @@
#include <sys/types.h>
#include <unistd.h>
+#if BFS_HAS_SYS_ACL
+# include <sys/acl.h>
+#endif
+
#if BFS_HAS_POSIX1E_CAPABILITIES
# include <sys/capability.h>
#endif
@@ -382,7 +386,7 @@ int bfs_minor(dev_t dev) {
#endif
}
-#if BFS_HAS_POSIX1E_CAPABILITIES
+#if BFS_HAS_SYS_ACL || BFS_HAS_POSIX1E_CAPABILITIES
static const char *open_path(const struct BFTW *ftwbuf, int *fd) {
#ifdef O_PATH
@@ -429,6 +433,72 @@ static void close_path(const struct BFTW *ftwbuf, const char *path, int fd) {
}
}
+#endif // BFS_HAS_SYS_ACL || BFS_HAS_POSIX1E_CAPABILITIES
+
+#if BFS_HAS_SYS_ACL
+
+/** Check if any ACLs of the given type are non-trivial. */
+static bool bfs_check_acl_type(const char *path, acl_type_t type) {
+ acl_t acl = acl_get_file(path, type);
+ if (!acl) {
+ return false;
+ }
+
+ bool ret = false;
+ acl_entry_t entry;
+ for (int status = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry);
+ status > 0;
+ status = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry)) {
+ acl_tag_t tag;
+ if (acl_get_tag_type(entry, &tag) != 0) {
+ continue;
+ }
+ if (tag != ACL_USER_OBJ && tag != ACL_GROUP_OBJ && tag != ACL_OTHER) {
+ ret = true;
+ break;
+ }
+ }
+
+ acl_free(acl);
+ return ret;
+}
+
+bool bfs_check_acl(const struct BFTW *ftwbuf) {
+ if (ftwbuf->typeflag == BFTW_LNK) {
+ return false;
+ }
+
+ int fd;
+ const char *path = open_path(ftwbuf, &fd);
+ if (!path) {
+ return false;
+ }
+
+ bool ret = false;
+ if (bfs_check_acl_type(path, ACL_TYPE_ACCESS)) {
+ ret = true;
+ } else if (bfs_check_acl_type(path, ACL_TYPE_DEFAULT)) {
+ ret = true;
+#ifdef ACL_TYPE_EXTENDED
+ } else if (bfs_check_acl_type(path, ACL_TYPE_EXTENDED)) {
+ ret = true;
+#endif
+ }
+
+ close_path(ftwbuf, path, fd);
+ return ret;
+}
+
+#else // !BFS_HAS_SYS_ACL
+
+bool bfs_check_acl(const struct BFTW *ftwbuf) {
+ return false;
+}
+
+#endif
+
+#if BFS_HAS_POSIX1E_CAPABILITIES
+
bool bfs_check_capabilities(const struct BFTW *ftwbuf) {
bool ret = false;