- /* The file descriptor corresponding to "path" */
- int fd = 0;
-
- /* The file descriptor for the directory containing "path" */
- int parent_fd = 0;
-
- /* dirname() and basename() mangle their arguments, so we need
- to make copies of "path" before using them. */
- char* dirname_path_copy = NULL;
- char* basename_path_copy = NULL;
-
- /* Get the parent directory of "path" with dirname(), which happens
- * to murder its argument and necessitates a path_copy. */
- dirname_path_copy = strdup(path);
- if (dirname_path_copy == NULL) {
- perror("apply_default_acl (strdup)");
- return ACL_ERROR;
- }
- char* parent = dirname(dirname_path_copy);
- parent_fd = safe_open(parent, O_DIRECTORY | O_NOFOLLOW);
- if (parent_fd == OPEN_ERROR) {
- if (errno == ELOOP || errno == ENOTDIR) {
- /* We hit a symlink, either in the last path component (ELOOP)
- or higher up (ENOTDIR). */
- result = ACL_FAILURE;
- goto cleanup;
- }
- else {
- perror("apply_default_acl (open parent fd)");
- result = ACL_ERROR;
- goto cleanup;
- }
- }
-
- /* 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;
- }
-
- /* We already obtained the parent fd safely, so if we use the
- basename of path here instead of the full thing, then we can get
- away with using openat() and spare ourselves the slowness of
- another safe_open(). */
- basename_path_copy = strdup(path);
- if (basename_path_copy == NULL) {
- perror("apply_default_acl (strdup)");
- return ACL_ERROR;
- }
- fd = openat(parent_fd, basename(basename_path_copy), O_NOFOLLOW);
- if (fd == OPEN_ERROR) {
- if (errno == ELOOP || errno == ENOTDIR) {
- /* We hit a symlink, either in the last path component (ELOOP)
- or higher up (ENOTDIR). */
- result = ACL_FAILURE;
- goto cleanup;
- }
- else {
- perror("apply_default_acl (open fd)");
- result = ACL_ERROR;
- goto cleanup;
- }
- }
-