Posted on 08-28-2012 09:52 AM
Hi all,
Thought you might find this useful.
I got frustrated with having to use Server Admin to propagate ACLs and had a need to do this from the command line, so I wrote a script to walk a directory tree, looking for explicit ACEs and the propagate these down to any children with the inherited bit set.
Please let me know if you have any improvements.
Usual warnings apply, if you don't know what this does don't use it, if you don't have [tested] backups of your data or time to restore, don't use it.
Dan
#!/bin/bash
############################################ FUNCTIONS #############################################
function datetime() {
date "+%Y-%m-%d %H:%M:%S"
}
function process_dir() {
for dir in ${@}
do
DEFIFS=$IFS
IFS=$'
'
# Get every explicit ACE that this directory has applied
ACL=($( ls -led "$dir" | grep -v ^d | grep -v inherited | cut -d ' ' -f 3- ))
if [ ${#ACL[@]} -gt 0 ]; then
#echo "In function, processing: $dir"
# echo "${#ACL[@]} ACL found in $dir: "
for ACE in "${ACL[@]}"
do
NUMCHILD=$( ls -1 "$dir" | wc -l )
if [ $NUMCHILD -gt 0 ]; then
echo chmod -R +ai "${ACE:6}" $dir/*
chmod -R +ai "${ACE:6}" $dir/*
fi
done
fi
IFS=$DEFIFS
# List every child that is a directory
SUBDIRS=$( find "$dir" -type d -maxdepth 1 -mindepth 1 )
# Call this function recursively to process children
process_dir $SUBDIRS
done
}
####################################################################################################
############################################# USAGE ##############################################
USAGE=$(cat <<-'EOF'
Usage:
propagate-acls.sh dir1 /path/to/dir2 /path/to/dir3
EOF)
####################################################################################################
############################################## BODY ################################################
# Check if there are arguments, otherwise print USAGE
if [ $# -lt 1 ]; then
echo -e $USAGE
exit 0
fi
# Iterate over the arguments
for dir in "$@"
do
# Test to see if this is a directory
if [ -d "$dir" ]; then
echo "Processing... $dir"
# Pass the directory to the processing function
process_dir $dir
fi
done
exit 0
####################################################################################################