--- /dev/null
+#include <errno.h>
+#include <limits.h> /* PATH_MAX */
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* ACLs */
+#include <sys/types.h>
+#include <sys/acl.h>
+
+bool has_default_acl(const char* path) {
+ /* Return true if the given path has a default ACL, false
+ otherwise. */
+ acl_t defacl = acl_get_file(path, ACL_TYPE_DEFAULT);
+
+ if (defacl == (acl_t)NULL) {
+ return false;
+ }
+
+ /* Used to store the entry if it exists, even though we don't care
+ what it is. */
+ acl_entry_t dummy;
+
+ int result = acl_get_entry(defacl, ACL_FIRST_ENTRY, &dummy);
+
+ if (result == 1) {
+ /* There's a first entry in the default ACL. */
+ return true;
+ }
+ else if (result == 0) {
+ return false;
+ }
+ else {
+ perror("has_default_acl");
+ return false;
+ }
+}
+
+
+
+bool has_default_tag_acl(const char* path, acl_tag_t tag_type) {
+ /* Return true if the given path has a default ACL for the supplied
+ tag, false otherwise. */
+ acl_t defacl = acl_get_file(path, ACL_TYPE_DEFAULT);
+
+ if (defacl == (acl_t)NULL) {
+ return false;
+ }
+
+ acl_entry_t entry;
+ int result = acl_get_entry(defacl, ACL_FIRST_ENTRY, &entry);
+
+ while (result == 1) {
+ acl_tag_t tag = ACL_UNDEFINED_TAG;
+ int tag_result = acl_get_tag_type(entry, &tag);
+
+ if (tag_result == -1) {
+ perror("has_default_tag_acl");
+ return false;
+ }
+ else {
+ if (tag == tag_type) {
+ return true;
+ }
+ }
+
+ result = acl_get_entry(defacl, ACL_NEXT_ENTRY, &entry);
+ }
+
+ return false;
+}
+
+
+bool has_default_user_obj_acl(const char* path) {
+ return has_default_tag_acl(path, ACL_USER_OBJ);
+}
+
+bool has_default_group_obj_acl(const char* path) {
+ return has_default_tag_acl(path, ACL_GROUP_OBJ);
+}
+
+bool has_default_other_obj_acl(const char* path) {
+ return has_default_tag_acl(path, ACL_OTHER);
+}
+
+
+int get_default_tag_permset(const char* path,
+ acl_tag_t tag_type,
+ acl_permset_t* output_perms) {
+ /* Return true if the given path has a default ACL for the supplied
+ tag, false otherwise. */
+ acl_t defacl = acl_get_file(path, ACL_TYPE_DEFAULT);
+
+ if (defacl == (acl_t)NULL) {
+ /* Follow the acl_foo convention of -1 == error. */
+ return -1;
+ }
+
+ acl_entry_t entry;
+ int result = acl_get_entry(defacl, ACL_FIRST_ENTRY, &entry);
+
+ while (result == 1) {
+ acl_tag_t tag = ACL_UNDEFINED_TAG;
+ int tag_result = acl_get_tag_type(entry, &tag);
+
+ if (tag_result == -1) {
+ perror("get_default_tag_permset");
+ return -1;
+ }
+ else {
+ if (tag == tag_type) {
+ /* We found the right tag, now get the permset. */
+ return acl_get_permset(entry, output_perms);
+ }
+ }
+
+ result = acl_get_entry(defacl, ACL_NEXT_ENTRY, &entry);
+ }
+
+ return false;
+}
+
+int get_default_user_obj_permset(const char* path,
+ acl_permset_t* output_perms) {
+ return get_default_tag_permset(path, ACL_USER_OBJ, output_perms);
+}
+
+int get_default_group_obj_permset(const char* path,
+ acl_permset_t* output_perms) {
+ return get_default_tag_permset(path, ACL_GROUP_OBJ, output_perms);
+}
+
+int get_default_other_obj_permset(const char* path,
+ acl_permset_t* output_perms) {
+ return get_default_tag_permset(path, ACL_OTHER, output_perms);
+}
+
+
+int main(int argc, char* argv[]) {
+ const char* target = argv[1];
+ printf("Target: %s\n", target);
+
+ if (has_default_acl(target)) {
+ printf("Target has a default ACL.\n");
+ }
+ else {
+ printf("Target does not have a default ACL.\n");
+ }
+
+ if (has_default_user_obj_acl(target)) {
+ printf("Target has a default owner ACL.\n");
+ acl_permset_t owner_perms;
+ get_default_user_obj_permset(target, &owner_perms);
+ if (acl_get_perm(owner_perms, ACL_READ) == 1) {
+ printf("User: read\n");
+ }
+ if (acl_get_perm(owner_perms, ACL_WRITE) == 1) {
+ printf("User: write\n");
+ }
+ if (acl_get_perm(owner_perms, ACL_EXECUTE) == 1) {
+ printf("User: execute\n");
+ }
+ }
+ else {
+ printf("Target does not have a default owner ACL.\n");
+ }
+
+ if (has_default_group_obj_acl(target)) {
+ printf("Target has a default group ACL.\n");
+ }
+ else {
+ printf("Target does not have a default group ACL.\n");
+ }
+
+ if (has_default_other_obj_acl(target)) {
+ printf("Target has a default other ACL.\n");
+ }
+ else {
+ printf("Target does not have a default other ACL.\n");
+ }
+ /*
+ acl_permset_t group_perms;
+ get_default_group_obj_permset();
+
+ acl_permset_t other_perms;
+ get_default_other_obj_permset();
+ */
+ return EXIT_SUCCESS;
+}