PetrZ
Dabbler
- Joined
- Feb 23, 2018
- Messages
- 20
I didn't found simple way to set ACLs using provided tools, so I wrote basic script.
Feel free to use it, but there is no guarantee. :)
It is using bash and I run it with redirected stderr:
./acl_set.sh 2>error.log
Feel free to use it, but there is no guarantee. :)
It is using bash and I run it with redirected stderr:
./acl_set.sh 2>error.log
Code:
#!/usr/bin/env bash export ROOT_DIR="/mnt/DATA" ACL_RW_FILE='rw-p-daARWc---:-------:allow'; ACL_RW_DIR='rwxp-daARWc---:fd-----:allow'; ACL_RO_FILE='r-----a-R-c---:-------:allow'; ACL_RO_DIR='r-x---a-R-c---:fd-----:allow'; # ACLs set by winacl as default will be deleted read -r -d '' ACL_DEL_FILE <<'ACL' group@:rwxpDdaARWcCos:------I:allow everyone@:r-x---a-R-c---:------I:allow ACL read -r -d '' ACL_DEL_DIR <<'ACL' group@:rwxpDdaARWcCos:fd----I:allow everyone@:r-x---a-R-c---:fd----I:allow ACL CUR_DIR=`pwd` # In case of harld links, setfacl fails as already # removed ACLs can not be removed again. Therefore # it is needed to check if we can skip this error. function acl_check { TYPE="${1}" OBJ="${2}" # check if delete was done already if [[ ! -z "$(getfacl "${OBJ}" | grep -E $(cut -d':' -f1 "/tmp/acl_delete_${TYPE}.def" | sed -e 's/^\(.*\)$/(\1)|/' | tr -d "\n" | sed -e 's/\(.*\)|/\1/'))" ]]; then return 1; fi # check if add was done already if [[ -z "$(getfacl "${OBJ}" | grep -Eoz $(sed -e 's/$/\\s*/g' /tmp/acl_add.def | tr -d "\n" | sed -e 's/\(.*\)\\s\*/\1/'))" ]]; then return 1; fi return 0 } # Set ACL for single file / dir function acl_set { TYPE="${1}" DIR="${2}" FILE="${3}" set +e { ERR=$(setfacl -h -M "/tmp/acl_add.def" -X "/tmp/acl_delete_${TYPE}.def" "${DIR}/${FILE}" 2>&1 1>&$out); } {out}>&1; STATUS=$?; set -e # Check if error is "skippable", log to stderr if [ $STATUS -ne 0 ]; then printf "Set ACL for %s failed, check ACL" "${FILE}" >&2 if acl_check "${TYPE}" "${DIR}/${FILE}"; then echo ... passed >&2 else echo ... failed >&2 echo Command: setfacl -h -M "/tmp/acl_add.def" -X "/tmp/acl_delete_${TYPE}.def" "${FILE}" >&2 echo Result: "${ERR}" >&2 ERR_COUNT=$(( ERR_COUNT + 1)) return 1 fi fi } # Set ACLs recursively. When single is not empty, apply without recursive. # type d|f, acl rule, dir, single function acl_walk { TYPE="${1}" ACL="${2}" DIR="${3}" SINGLE="${4}" # Write ACLs to be added printf "${ACL}" >/tmp/acl_add.def cd "${DIR}" if [[ "${TYPE}" == "d" ]]; then acl_set "${TYPE}" "${DIR}" "" fi if [[ ! -z "${SINGLE}" ]]; then return 0; fi TOTAL=$(find . -type "${TYPE}" ! -name . ! -name .windows | wc -l) COUNT=0 find . -type "${TYPE}" ! -name . ! -name .windows -print0 | while IFS= read -r -d '' FILE; do COUNT=$(( COUNT + 1)) printf '\r%9d / %d, Errors %d' "${COUNT}" "${TOTAL}" "${ERR_COUNT}" acl_set "${TYPE}" "${DIR}" "${FILE}" done echo } # Print count of detected errors on exit function errors { printf '\nDetected %d errors\n' "${ERR_COUNT}" } set -e ERR_COUNT=0 trap errors EXIT echo "${ACL_DEL_FILE}" >/tmp/acl_delete_f.def echo "${ACL_DEL_DIR}" >/tmp/acl_delete_d.def # I use it this way echo "Set owner and default for whole share" winacl -O root -G wheel -a reset -r -p "${ROOT_DIR}/your_share" echo "Set RO for Employer for your_share top level" acl_walk d "group:Employer:${ACL_RO_DIR}" "${ROOT_DIR}/your_share" single echo "Set RW for Employer for following subfolders" for sub in Public General Misc; do echo " /${sub} - directories" acl_walk d "group:Employer:${ACL_RW_DIR}" "${ROOT_DIR}/your_share/${sub}" echo " /${sub} - files" acl_walk f "group:Employer:${ACL_RW_FILE}" "${ROOT_DIR}/your_share/${sub}" done echo "Set RW for Finances for Accounts" echo " - directories" acl_walk d "group:Finances:${ACL_RW_DIR}" "${ROOT_DIR}/your_share/Accounts" echo " - files" acl_walk f "group:Finances:${ACL_RW_FILE}" "${ROOT_DIR}/your_share/Accounts" # Other share will have RO and RW for different groups echo "Set owner and default for whole other_share" winacl -O root -G wheel -a reset -r -p "${ROOT_DIR}/other_share" echo "Set RO for Media and Mediamanagement for other_share top level" acl_walk d "group:Media:${ACL_RO_DIR}\ngroup:Mediamanagement:${ACL_RO_DIR}" "${ROOT_DIR}/other_share" single echo "Set RO for Media, RW for Mediamanagement for following subfolders" for sub in Documents Video Photos; do echo " /${sub} - directories" acl_walk d "group:Media:${ACL_RO_DIR}\ngroup:Mediamanagement:${ACL_RW_DIR}" "${ROOT_DIR}/other_share/${sub}" echo " /${sub} - files" acl_walk f "group:Media:${ACL_RO_FILE}\ngroup:Mediamanagement:${ACL_RW_FILE}" "${ROOT_DIR}/other_share/${sub}" done echo "Set RW for Media and Mediamanagement for UPLOAD" echo " - directories" acl_walk d "group:Media:${ACL_RW_DIR}\ngroup:Mediamanagement:${ACL_RW_DIR}" "${ROOT_DIR}/other_share/UPLOAD" echo " - files" acl_walk f "group:Media:${ACL_RW_FILE}\ngroup:Mediamanagement:${ACL_RW_FILE}" "${ROOT_DIR}/other_share/UPLOAD" cd "${CUR_DIR}"
Last edited: