diff --git a/cdist/conf/type/__acl/explorer/acl_is b/cdist/conf/type/__acl/explorer/acl_is index e2ae0932..a693c023 100755 --- a/cdist/conf/type/__acl/explorer/acl_is +++ b/cdist/conf/type/__acl/explorer/acl_is @@ -18,9 +18,14 @@ # along with cdist. If not, see . # -if [ -e "/$__object_id" ] +[ ! -e "/$__object_id" ] && exit 0 + +if ! command -v getfacl > /dev/null then - getfacl "/$__object_id" 2>/dev/null \ - | grep -E '^((default:)?(user|group):[^:]|(default:)?mask::)' \ - || true + echo 'getfacl not available' >&2 + exit 1 fi + +getfacl "/$__object_id" 2>/dev/null \ + | grep -Eo '^(default:)?(user|group|(mask|other):):[^:][[:graph:]]+' \ + || true diff --git a/cdist/conf/type/__acl/explorer/file_is b/cdist/conf/type/__acl/explorer/file_is new file mode 100755 index 00000000..096cffd1 --- /dev/null +++ b/cdist/conf/type/__acl/explorer/file_is @@ -0,0 +1,31 @@ +#!/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 . +# + +if [ -e "/$__object_id" ] +then + if [ -d "/$__object_id" ] + then echo directory + elif [ -f "/$__object_id" ] + then echo regular + else echo other + fi +else + echo missing +fi diff --git a/cdist/conf/type/__acl/explorer/missing_users_groups b/cdist/conf/type/__acl/explorer/missing_users_groups new file mode 100755 index 00000000..b4af614c --- /dev/null +++ b/cdist/conf/type/__acl/explorer/missing_users_groups @@ -0,0 +1,47 @@ +#!/bin/sh -e +# +# 2019 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 . +# + +[ ! -e "/$__object_id" ] && exit 0 + +for parameter in user group +do + if [ ! -f "$__object/parameter/$parameter" ] + then + continue + fi + + while read -r acl + do + check="$( echo "$acl" | awk -F: '{print $1}' )" + + if [ "$parameter" = 'user' ] + then + getent_db=passwd + else + getent_db="$parameter" + fi + + if ! getent "$getent_db" "$check" > /dev/null + then + echo "missing $parameter '$check'" + fi + done \ + < "$__object/parameter/$parameter" +done diff --git a/cdist/conf/type/__acl/gencode-remote b/cdist/conf/type/__acl/gencode-remote index 8ab7b566..a0f25a15 100755 --- a/cdist/conf/type/__acl/gencode-remote +++ b/cdist/conf/type/__acl/gencode-remote @@ -18,43 +18,61 @@ # along with cdist. If not, see . # -os="$( cat "$__global/explorer/os" )" +file_is="$( cat "$__object/explorer/file_is" )" -acl_path="/$__object_id" +[ "$file_is" = 'missing' ] && exit 0 + +missing_users_groups="$( cat "$__object/explorer/missing_users_groups" )" + +if [ -n "$missing_users_groups" ] +then + echo "$missing_users_groups" >&2 + exit 1 +fi + +os="$( cat "$__global/explorer/os" )" acl_is="$( cat "$__object/explorer/acl_is" )" -acl_should="$( for parameter in user group +acl_path="/$__object_id" + +if [ -f "$__object/parameter/default" ] && [ "$file_is" = 'directory' ] +then + set_default=1 +else + set_default=0 +fi + +acl_should="$( for parameter in user group mask other do if [ ! -f "$__object/parameter/$parameter" ] - then continue + then + continue fi - while read -r l + + while read -r acl do - echo "$parameter:$l" + if echo "$acl" | awk -F: '{ print $NF }' | grep -Fq 'X' + then + [ "$file_is" = 'directory' ] && rep=x || rep=- - if [ -f "$__object/parameter/default" ] - then echo "default:$parameter:$l" + acl="$( echo "$acl" | sed "s/\(.*\)X/\1$rep/" )" fi - done < "$__object/parameter/$parameter" -done -if [ -f "$__object/parameter/mask" ] -then - l=$( cat "$__object/parameter/mask" ) - echo "mask::$l" + echo "$parameter" | grep -Eq '(mask|other)' && sep=:: || sep=: - if [ -f "$__object/parameter/default" ] - then echo "default:mask::$l" - fi -fi -)" + echo "$parameter$sep$acl" + + [ "$set_default" = '1' ] && echo "default:$parameter$sep$acl" + done \ + < "$__object/parameter/$parameter" +done )" setfacl_exec='setfacl' if [ -f "$__object/parameter/recursive" ] then - if echo "$os" | grep -Eq 'macosx|netbsd|freebsd|openbsd' + if echo "$os" | grep -Eq 'macosx|freebsd' then echo "$os setfacl do not support recursive operations" >&2 else @@ -73,13 +91,23 @@ then else echo "$acl_is" | while read -r acl do - if echo "$acl_should" | grep -Fq "$acl" + # 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 - no_bits="$( echo "$acl" | sed -r 's/:[rwx-]+$//' )" + if echo "$os" | grep -Eq 'macosx|freebsd' + then + remove="$acl" + else + remove="$( echo "$acl" | sed 's/:...$//' )" + fi - echo "$setfacl_exec -x \"$no_bits\" \"$acl_path\"" + echo "$setfacl_exec -x \"$remove\" \"$acl_path\"" + echo "removed '$remove'" >> "$__messages_out" done fi fi @@ -87,6 +115,14 @@ fi for acl in $acl_should do if ! echo "$acl_is" | grep -Eq "^$acl" - then echo "$setfacl_exec -m \"$acl\" \"$acl_path\"" + then + if echo "$os" | grep -Eq 'macosx|freebsd' \ + && echo "$acl" | grep -Eq '^default:' + then + echo "setting default ACL in $os is currently not supported. sorry :(" >&2 + else + echo "$setfacl_exec -m \"$acl\" \"$acl_path\"" + echo "added '$acl'" >> "$__messages_out" + fi fi done diff --git a/cdist/conf/type/__acl/man.rst b/cdist/conf/type/__acl/man.rst index c10ee1a0..092eb555 100644 --- a/cdist/conf/type/__acl/man.rst +++ b/cdist/conf/type/__acl/man.rst @@ -3,20 +3,20 @@ cdist-type__acl(7) NAME ---- -cdist-type__acl - Basic wrapper around `setfacl` +cdist-type__acl - Set ACL entries DESCRIPTION ----------- -ACL must be defined as 3-symbol combination, using `r`, `w`, `x` and `-`. +ACL must be defined as 3-symbol combination, using ``r``, ``w``, ``x`` and ``-``. -See setfacl(1) and acl(5) for more details. +Fully supported on Linux (tested on Debian and CentOS). +Partial support for FreeBSD, OSX and Solaris. -OPTIONAL PARAMETERS -------------------- -mask - Add mask ACL entry. +OpenBSD and NetBSD support is not possible. + +See ``setfacl`` and ``acl`` manpages for more details. OPTIONAL MULTIPLE PARAMETERS @@ -28,16 +28,26 @@ group Add group ACL entry. +OPTIONAL PARAMETERS +------------------- +mask + Add mask ACL entry. + +other + Add other ACL entry. + + BOOLEAN PARAMETERS ------------------ recursive - Operate recursively (Linux only). + Make ``setfacl`` recursive (Linux only), but not ``getfacl`` in explorer. default - Add default ACL entries. + Add default ACL entries (FreeBSD not supported). remove Remove undefined ACL entries (Solaris not supported). + ACL entries for ``mask`` and ``other`` can't be removed. EXAMPLES @@ -53,7 +63,8 @@ EXAMPLES --user bob:r-x \ --group project-group:rwx \ --group some-other-group:r-x \ - --mask r-x + --mask r-x \ + --other r-x AUTHORS diff --git a/cdist/conf/type/__acl/parameter/optional b/cdist/conf/type/__acl/parameter/optional index bb4fcf2b..4b32086b 100644 --- a/cdist/conf/type/__acl/parameter/optional +++ b/cdist/conf/type/__acl/parameter/optional @@ -1 +1,2 @@ mask +other