#!/bin/sh -e # # 2018 Ander Punnar (ander-at-kvlt-dot-ee) # # This file is part of cdist. # # cdist is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # cdist is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with cdist. If not, see . # file_is="$( cat "$__object/explorer/file_is" )" if [ "$file_is" = 'missing' ] \ && [ -z "$__cdist_dry_run" ] \ && [ ! -f "$__object/parameter/file" ] \ && [ ! -f "$__object/parameter/directory" ] then exit 0 fi os="$( cat "$__global/explorer/os" )" acl_path="/$__object_id" acl_is="$( cat "$__object/explorer/acl_is" )" if [ -f "$__object/parameter/source" ] then acl_source="$( cat "$__object/parameter/source" )" if [ "$acl_source" = '-' ] then acl_should="$( cat "$__object/stdin" )" else acl_should="$( grep -Ev '^#|^$' "$acl_source" )" fi elif [ -f "$__object/parameter/entry" ] then acl_should="$( cat "$__object/parameter/entry" )" else echo 'no parameters set' >&2 exit 1 fi # instead of setfacl's non-helpful message "Option -m: Invalid argument near character X" # let's check if target has necessary users and groups, since mistyped or missing # users/groups in target is most common reason. echo "$acl_should" \ | grep -Po '(user|group):[^:]+' \ | sort -u \ | while read -r l do if ! grep "$l" -Fxq "$__object/explorer/getent" then echo "no $l' in target" | sed "s/:/ '/" >&2 exit 1 fi done if [ -f "$__object/parameter/default" ] then acl_should="$( echo "$acl_should" \ | sed 's/^default://' \ | sort -u \ | sed 's/\(.*\)/default:\1\n\1/' )" fi if [ "$file_is" = 'regular' ] \ && echo "$acl_should" | grep -Eq '^default:' then # only directories can have default ACLs, # but instead of error, # let's just remove default entries acl_should="$( echo "$acl_should" | grep -Ev '^default:' )" fi if echo "$acl_should" | awk -F: '{ print $NF }' | grep -Fq 'X' then [ "$file_is" = 'directory' ] && rep=x || rep=- acl_should="$( echo "$acl_should" | sed "s/\\(.*\\)X/\\1$rep/" )" fi setfacl_exec='setfacl' if [ -f "$__object/parameter/recursive" ] then if echo "$os" | grep -Fq 'freebsd' then echo "$os setfacl do not support recursive operations" >&2 else setfacl_exec="$setfacl_exec -R" fi fi if [ -f "$__object/parameter/remove" ] then echo "$acl_is" | while read -r acl do # skip wanted ACL entries which already exist # and skip mask and other entries, because we # can't actually remove them, but only change. if echo "$acl_should" | grep -Eq "^$acl" \ || echo "$acl" | grep -Eq '^(default:)?(mask|other)' then continue fi if echo "$os" | grep -Fq 'freebsd' then remove="$acl" else remove="$( echo "$acl" | sed 's/:...$//' )" fi echo "$setfacl_exec -x \"$remove\" \"$acl_path\"" echo "removed '$remove'" >> "$__messages_out" done fi for acl in $acl_should do if ! echo "$acl_is" | grep -Eq "^$acl" then if echo "$os" | grep -Fq 'freebsd' \ && echo "$acl" | grep -Eq '^default:' then echo "setting default ACL in $os is currently not supported" >&2 else echo "$setfacl_exec -m \"$acl\" \"$acl_path\"" echo "added '$acl'" >> "$__messages_out" fi fi done