+
+/**
+ * @brief Determine whether the given path has an ACL whose mask
+ * denies execute.
+ *
+ * @param path
+ * The path to check.
+ *
+ * @return
+ * - @c ACL_SUCCESS - @c path has a mask which denies execute.
+ * - @c ACL_FAILURE - The ACL for @c path does not deny execute,
+ * or @c path has no extended ACL at all.
+ * - @c ACL_ERROR - Unexpected library error.
+ */
+int acl_execute_masked(const char* path) {
+
+ acl_t acl = acl_get_file(path, ACL_TYPE_ACCESS);
+
+ if (acl == (acl_t)NULL) {
+ perror("acl_execute_masked (acl_get_file)");
+ return ACL_ERROR;
+ }
+
+ /* Our return value. */
+ int result = ACL_FAILURE;
+
+ acl_entry_t entry;
+ int ge_result = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry);
+
+ while (ge_result == ACL_SUCCESS) {
+ acl_tag_t tag = ACL_UNDEFINED_TAG;
+ int tag_result = acl_get_tag_type(entry, &tag);
+
+ if (tag_result == ACL_ERROR) {
+ perror("acl_execute_masked (acl_get_tag_type)");
+ result = ACL_ERROR;
+ goto cleanup;
+ }
+
+ if (tag == ACL_MASK) {
+ /* This is the mask entry, get its permissions, and see if
+ execute is specified. */
+ acl_permset_t permset;
+
+ int ps_result = acl_get_permset(entry, &permset);
+ if (ps_result == ACL_ERROR) {
+ perror("acl_execute_masked (acl_get_permset)");
+ result = ACL_ERROR;
+ goto cleanup;
+ }
+
+ int gp_result = acl_get_perm(permset, ACL_EXECUTE);
+ if (gp_result == ACL_ERROR) {
+ perror("acl_execute_masked (acl_get_perm)");
+ result = ACL_ERROR;
+ goto cleanup;
+ }
+
+ if (gp_result == ACL_FAILURE) {
+ /* No execute bit set in the mask; execute not allowed. */
+ return ACL_SUCCESS;
+ }
+ }
+
+ ge_result = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry);
+ }
+
+ cleanup:
+ acl_free(acl);
+ return result;
+}
+
+
+
+/**
+ * @brief Determine whether @c path is executable (by anyone) or a
+ * directory.
+ *
+ * This is used as part of the heuristic to determine whether or not
+ * we should mask the execute bit when inheriting an ACL. If @c path
+ * is a directory, the answer is a clear-cut yes. This behavior is
+ * modeled after the capital 'X' perms of setfacl.
+ *
+ * If @c path is a file, we check the @a effective permissions,
+ * contrary to what setfacl does.
+ *
+ * @param path
+ * The path to check.
+ *
+ * @return
+ * - @c ACL_SUCCESS - @c path is a directory, or someone has effective
+ execute permissions.
+ * - @c ACL_FAILURE - @c path is a regular file and nobody can execute
+ it.
+ * - @c ACL_ERROR - Unexpected library error.
+ */
+int any_can_execute_or_dir(const char* path) {
+
+ if (is_directory(path)) {
+ /* That was easy... */
+ return ACL_SUCCESS;
+ }
+