How to Recursively Apply Parent Directory’s Default ACLs to All Child Files and Directories in Linux


5 views

When working with Linux filesystems, you might encounter situations where default ACLs set on a parent directory don't automatically propagate to existing child items. This happens because default ACLs only affect:

  • Newly created files/directories
  • Items moved into the directory
  • Not pre-existing content

The most efficient way to apply parent directory's default ACLs recursively is:

find /path/to/parent -type d -exec setfacl -m d:u:phptutor:rwx {} \;
find /path/to/parent -type f -exec setfacl -m u:phptutor:rw {} \;

Breaking down what these commands do:

# For directories (-type d):
# -m : modify ACL
# d:u:phptutor:rwx : sets default ACL for user phptutor
# {} : placeholder for each found directory

# For files (-type f):
# Removes the 'x' permission as it's typically unnecessary for files

For more complex scenarios where you want to exactly copy all default ACLs:

getfacl /path/to/parent | grep '^default' | setfacl -d -M- /path/to/target

For directories with thousands of files, consider this optimized version:

find /path/to/parent -type d -print0 | xargs -0 -P 4 -I {} setfacl -m d:u:phptutor:rwx {}
find /path/to/parent -type f -print0 | xargs -0 -P 8 -I {} setfacl -m u:phptutor:rw {}

Key optimizations:

  • -print0 and -0 handle filenames with spaces
  • -P enables parallel processing (4 for dirs, 8 for files)

After applying ACLs, verify with:

getfacl /path/to/parent/some_child

Common issues to check:

  • Ensure parent directory actually has default ACLs (look for 'default:' lines in getfacl output)
  • Check for conflicting ACL masks that might override permissions
  • Verify the filesystem supports ACLs (ext4, xfs, etc.)

When working with Access Control Lists (ACLs) in Linux, you might encounter situations where newly set default ACLs on a parent directory don't automatically apply to existing files and subdirectories. This happens because default ACLs only affect newly created items.

$ getfacl parent_dir/
# file: parent_dir/
# owner: user
# group: group
user::rwx
group::r-x
other::r-x
default:user:phptutor:rwx

The most effective way to apply default ACLs to existing files is using setfacl with the --recursive flag and the --set-file option:

$ getfacl parent_dir/ | setfacl --recursive --set-file=- parent_dir/

This command:

  1. Gets the current ACLs of the parent directory
  2. Pipes them to setfacl
  3. Applies them recursively to all files and subdirectories

For more control over the process, you can combine find with setfacl:

$ find parent_dir/ -type d -exec setfacl -m d:u:phptutor:rwx {} \;
$ find parent_dir/ -type f -exec setfacl -m u:phptutor:rwx {} \;

Always verify the changes with getfacl:

$ getfacl parent_dir/subdir/file.txt
# file: parent_dir/subdir/file.txt
# owner: user
# group: group
user::rw-
user:phptutor:rwx
group::r--
mask::rwx
other::r--
  • Backup important data before running recursive ACL operations
  • Consider using --test flag first to see what changes would be made
  • Be aware of performance impact when processing large directory trees
  • Default ACLs (d:) only apply to directories, not files

For regular maintenance, you might want to create a script:

#!/bin/bash
if [ -z "$1" ]; then
    echo "Usage: $0 directory"
    exit 1
fi

TEMP_ACL=$(mktemp)
getfacl "$1" > "$TEMP_ACL"
find "$1" -exec setfacl --set-file="$TEMP_ACL" {} \;
rm "$TEMP_ACL"