X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=src%2Flibadacl.c;h=30a39f2704883a60429abd279a05c99caeb9b0c9;hb=b13aa67306336a89d9947735622c547c13acffb6;hp=d92432228358badf66a302e34e31ff459579b1de;hpb=c5fdaba07b5f965edca0a57d9c3cd8f8bbabc155;p=apply-default-acl.git diff --git a/src/libadacl.c b/src/libadacl.c index d924322..30a39f2 100644 --- a/src/libadacl.c +++ b/src/libadacl.c @@ -69,7 +69,7 @@ int safe_open_ex(int at_fd, char* pathname, int flags) { /* No more slashes, this is the base case. */ return openat(at_fd, pathname, flags); } - else if (firstslash[1] == '\0') { + if (firstslash[1] == '\0') { /* The first slash is the last character; ensure that we open a directory. */ firstslash[0] = '\0'; @@ -127,7 +127,7 @@ int safe_open_ex(int at_fd, char* pathname, int flags) { * and @c OPEN_ERROR if not. */ int safe_open(const char* pathname, int flags) { - if (pathname == NULL || strlen(pathname) == 0 || pathname[0] == '\0') { + if (pathname == NULL) { errno = EINVAL; perror("safe_open (args)"); return OPEN_ERROR; @@ -681,6 +681,30 @@ int acl_copy_xattr(int src_fd, } +/** + * @brief Determine if a file descriptor has a default ACL. + * + * @param fd + * The file descriptor whose default ACL is in question. + * + * @return + * - @c ACL_SUCCESS - If @c fd has a default ACL. + * - @c ACL_FAILURE - If @c fd does not have a default ACL. + * - @c ACL_ERROR - Unexpected library error. + */ +int has_default_acl_fd(int fd) { + if (fgetxattr(fd, XATTR_NAME_POSIX_ACL_DEFAULT, NULL, 0) == XATTR_ERROR) { + if (errno == ENODATA) { + return ACL_FAILURE; + } + perror("has_default_acl_fd (fgetxattr)"); + return ACL_ERROR; + } + + return ACL_SUCCESS; +} + + /** * @brief Apply parent default ACL to a path. * @@ -754,6 +778,13 @@ int apply_default_acl_ex(const char* path, } } + /* Check to make sure the parent descriptor actually has a default + ACL. If it doesn't, then we can "succeed" immediately. */ + if (has_default_acl_fd(parent_fd) == ACL_FAILURE) { + result = ACL_SUCCESS; + goto cleanup; + } + fd = safe_open(path, O_NOFOLLOW); if (fd == OPEN_ERROR) { if (errno == ELOOP || errno == ENOTDIR) { @@ -858,7 +889,13 @@ int apply_default_acl_ex(const char* path, */ /* Now we potentially need to mask the execute permissions in the - ACL on fd. First obtain the current one... */ + ACL on fd; or maybe now. */ + if (allow_exec) { + goto cleanup; + } + + /* OK, we need to mask some execute permissions. First obtain the + current ACL... */ new_acl = acl_get_fd(fd); if (new_acl == (acl_t)NULL) { perror("apply_default_acl_ex (acl_get_fd)"); @@ -902,21 +939,19 @@ int apply_default_acl_ex(const char* path, tag == ACL_GROUP_OBJ || tag == ACL_OTHER) { - if (!allow_exec) { - /* The mask doesn't affect acl_user_obj, acl_group_obj (in - minimal ACLs) or acl_other entries, so if execute should be - masked, we have to do it manually. */ - if (acl_delete_perm(permset, ACL_EXECUTE) == ACL_ERROR) { - perror("apply_default_acl_ex (acl_delete_perm)"); - result = ACL_ERROR; - goto cleanup; - } - - if (acl_set_permset(entry, permset) == ACL_ERROR) { - perror("apply_default_acl_ex (acl_set_permset)"); - result = ACL_ERROR; - goto cleanup; - } + /* The mask doesn't affect acl_user_obj, acl_group_obj (in + minimal ACLs) or acl_other entries, so if execute should be + masked, we have to do it manually. */ + if (acl_delete_perm(permset, ACL_EXECUTE) == ACL_ERROR) { + perror("apply_default_acl_ex (acl_delete_perm)"); + result = ACL_ERROR; + goto cleanup; + } + + if (acl_set_permset(entry, permset) == ACL_ERROR) { + perror("apply_default_acl_ex (acl_set_permset)"); + result = ACL_ERROR; + goto cleanup; } }