+ * @return
+ * - @c ACL_SUCCESS - The ACLs were wiped successfully, or none
+ * existed in the first place.
+ * - @c ACL_ERROR - Unexpected library error.
+ */
+int wipe_acls(int fd) {
+ /* Initialize an empty ACL, and then overwrite the one on "fd" with it. */
+ acl_t empty_acl = acl_init(0);
+
+ if (empty_acl == (acl_t)NULL) {
+ perror("wipe_acls (acl_init)");
+ return ACL_ERROR;
+ }
+
+ if (acl_set_fd(fd, empty_acl) == ACL_ERROR) {
+ perror("wipe_acls (acl_set_fd)");
+ acl_free(empty_acl);
+ return ACL_ERROR;
+ }
+
+ acl_free(empty_acl);
+ return ACL_SUCCESS;
+}
+
+
+/**
+ * @brief Copy ACLs between file descriptors as xattrs, verbatim.
+ *
+ * There is a small deficiency in libacl, namely that there is no way
+ * to get or set default ACLs through file descriptors. The @c
+ * acl_get_file and @c acl_set_file functions can do it, but they use
+ * paths, and are vulnerable to symlink attacks.
+ *
+ * Fortunately, when inheriting an ACL, we don't really need to look
+ * at what it contains. That means that we can copy the on-disk xattrs
+ * from the source directory to the destination file/directory without
+ * passing through libacl, and this can be done with file descriptors
+ * through @c fgetxattr and @c fsetxattr. That's what this function
+ * does.
+ *
+ * @param src_fd
+ * The file descriptor from which the ACL will be copied.
+ *
+ * @param src_type
+ * The type of ACL (either @c ACL_TYPE_ACCESS or @c ACL_TYPE_DEFAULT)
+ * to copy from @c src_fd.