From c52635fce35aa7d2e4414a44bac9fe06dfb56885 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Mon, 17 Dec 2018 22:05:49 -0500 Subject: Implement -acl test --- util.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) (limited to 'util.c') diff --git a/util.c b/util.c index 0ec6dba..359a5cd 100644 --- a/util.c +++ b/util.c @@ -30,6 +30,10 @@ #include #include +#if BFS_HAS_SYS_ACL +# include +#endif + #if BFS_HAS_POSIX1E_CAPABILITIES # include #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; -- cgit v1.2.3