|
|
|
@ -1,6 +1,7 @@
|
|
|
|
|
#!/bin/sh |
|
|
|
|
#!/bin/sh -e |
|
|
|
|
# |
|
|
|
|
# 2011 Steven Armstrong (steven-cdist at armstrong.cc) |
|
|
|
|
# 2020 Dennis Camera (dennis.camera at ssrq-sds-fds.ch) |
|
|
|
|
# |
|
|
|
|
# This file is part of cdist. |
|
|
|
|
# |
|
|
|
@ -11,32 +12,140 @@
|
|
|
|
|
# |
|
|
|
|
# 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 |
|
|
|
|
# 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 <http://www.gnu.org/licenses/>. |
|
|
|
|
# |
|
|
|
|
|
|
|
|
|
case "$("${__explorer}/os")" |
|
|
|
|
case $("${__explorer:?}/os") |
|
|
|
|
in |
|
|
|
|
netbsd) |
|
|
|
|
postgres_user='pgsql' |
|
|
|
|
;; |
|
|
|
|
openbsd) |
|
|
|
|
postgres_user='_postgresql' |
|
|
|
|
;; |
|
|
|
|
*) |
|
|
|
|
postgres_user='postgres' |
|
|
|
|
;; |
|
|
|
|
(netbsd) |
|
|
|
|
postgres_user='pgsql' |
|
|
|
|
;; |
|
|
|
|
(openbsd) |
|
|
|
|
postgres_user='_postgresql' |
|
|
|
|
;; |
|
|
|
|
(*) |
|
|
|
|
postgres_user='postgres' |
|
|
|
|
;; |
|
|
|
|
esac |
|
|
|
|
|
|
|
|
|
rolename=${__object_id:?} |
|
|
|
|
|
|
|
|
|
name="$__object_id" |
|
|
|
|
|
|
|
|
|
if test -n "$(su - "$postgres_user" -c "psql postgres -twAc \"SELECT 1 FROM pg_roles WHERE rolname='$name'\"")" |
|
|
|
|
psql_query() { |
|
|
|
|
su -l "${postgres_user}" -c "$( |
|
|
|
|
printf "psql -q -F '\034' -R '\036' -wAc '%s'" \ |
|
|
|
|
"$(printf %s "$*" | sed "s/'/'\\\\''/g")" |
|
|
|
|
)" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
password_check_login() ( |
|
|
|
|
PGPASSWORD=$(cat "${__object:?}/parameter/password"; printf .) |
|
|
|
|
PGPASSWORD=${PGPASSWORD%?.} |
|
|
|
|
export PGPASSWORD |
|
|
|
|
psql -q -w -h localhost -U "${rolename}" template1 -c '\q' >/dev/null 2>&1 |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
role_properties=$( |
|
|
|
|
psql_query "SELECT * FROM pg_roles WHERE rolname = '${rolename}'" \ |
|
|
|
|
| awk ' |
|
|
|
|
BEGIN { RS = "\036"; FS = "\034" } |
|
|
|
|
/^\([0-9]+ rows?\)/ { exit } |
|
|
|
|
NR == 1 { for (i = 1; i <= NF; i++) cols[i] = $i; next } |
|
|
|
|
NR == 2 { for (i = 1; i <= NF; i++) printf "%s=%s\n", cols[i], $i } |
|
|
|
|
' |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
if test -n "${role_properties}" |
|
|
|
|
then |
|
|
|
|
echo 'present' |
|
|
|
|
# Check if the user's properties match the parameters |
|
|
|
|
for prop in login createdb createrole superuser |
|
|
|
|
do |
|
|
|
|
bool_should=$(test -f "${__object:?}/parameter/${prop}" && echo 't' || echo 'f') |
|
|
|
|
bool_is=$( |
|
|
|
|
printf '%s\n' "${role_properties}" | |
|
|
|
|
awk -F '=' -v key="${prop}" ' |
|
|
|
|
BEGIN { |
|
|
|
|
if (key == "login") |
|
|
|
|
key = "canlogin" |
|
|
|
|
else if (key == "superuser") |
|
|
|
|
key = "super" |
|
|
|
|
key = "rol" key |
|
|
|
|
} |
|
|
|
|
$1 == key { |
|
|
|
|
sub(/^[^=]*=/, "") |
|
|
|
|
print |
|
|
|
|
} |
|
|
|
|
' |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
test "${bool_is}" = "${bool_should}" || { |
|
|
|
|
state='different properties' |
|
|
|
|
} |
|
|
|
|
done |
|
|
|
|
|
|
|
|
|
# Check password |
|
|
|
|
passwd_stored=$( |
|
|
|
|
psql_query "SELECT rolpassword FROM pg_authid WHERE rolname = '${rolename}'" \ |
|
|
|
|
| awk 'BEGIN { RS = "\036" } NR == 2' |
|
|
|
|
printf . |
|
|
|
|
) |
|
|
|
|
passwd_stored=${passwd_stored%?.} |
|
|
|
|
|
|
|
|
|
if test -f "${__object:?}/parameter/password" |
|
|
|
|
then |
|
|
|
|
passwd_should=$(cat "${__object:?}/parameter/password"; printf .) |
|
|
|
|
fi |
|
|
|
|
passwd_should=${passwd_should%?.} |
|
|
|
|
|
|
|
|
|
if test -z "${passwd_stored}" |
|
|
|
|
then |
|
|
|
|
test -z "${passwd_should}" || state="${state:-different} password" |
|
|
|
|
elif expr "${passwd_stored}" : 'SCRAM-SHA-256\$.*$' >/dev/null |
|
|
|
|
then |
|
|
|
|
# SCRAM-SHA-256 "encrypted" password |
|
|
|
|
# NOTE: There is currently no easy way to check SCRAM passwords without |
|
|
|
|
# logging in |
|
|
|
|
password_check_login || state="${state:-different} password" |
|
|
|
|
elif expr "${passwd_stored}" : 'md5[0-9a-f]\{32\}$' >/dev/null |
|
|
|
|
then |
|
|
|
|
# MD5 "encrypted" password |
|
|
|
|
if command -v md5sum >/dev/null 2>&1 |
|
|
|
|
then |
|
|
|
|
should_md5=$( |
|
|
|
|
printf '%s%s' "${passwd_should}" "${rolename}" \ |
|
|
|
|
| md5sum - | sed -e 's/[^0-9a-f]*$//') |
|
|
|
|
elif command -v gmd5sum >/dev/null 2>&1 |
|
|
|
|
then |
|
|
|
|
should_md5=$( |
|
|
|
|
printf '%s%s' "${passwd_should}" "${rolename}" \ |
|
|
|
|
| gmd5sum - | sed -e 's/[^0-9a-f]*$//') |
|
|
|
|
elif command -v openssl >/dev/null 2>&1 |
|
|
|
|
then |
|
|
|
|
should_md5=$( |
|
|
|
|
printf '%s%s' "${passwd_should}" "${rolename}" \ |
|
|
|
|
| openssl dgst -md5 | sed 's/^.* //') |
|
|
|
|
fi |
|
|
|
|
|
|
|
|
|
if test -n "${should_md5}" |
|
|
|
|
then |
|
|
|
|
test "${passwd_stored}" = "md5${should_md5}" \ |
|
|
|
|
|| state="${state:-different} password" |
|
|
|
|
else |
|
|
|
|
password_check_login || state="${state:-different} password" |
|
|
|
|
fi |
|
|
|
|
else |
|
|
|
|
# unencrypted password (unsupported since PostgreSQL 10) |
|
|
|
|
test "${passwd_stored}" = "${passwd_should}" \ |
|
|
|
|
|| state="${state:-different} password" |
|
|
|
|
fi |
|
|
|
|
|
|
|
|
|
test -n "${state}" || state='present' |
|
|
|
|
else |
|
|
|
|
echo 'absent' |
|
|
|
|
state='absent' |
|
|
|
|
fi |
|
|
|
|
|
|
|
|
|
echo "${state}" |
|
|
|
|