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