#!@l_bash@ ## ## pg_passwd -- PostgreSQL Database Password Changing Utility ## Copyright (c) 2007-2018 Ralf S. Engelschall ## ## Permission to use, copy, modify, and distribute this software for ## any purpose with or without fee is hereby granted, provided that ## the above copyright notice and this permission notice appear in all ## copies. ## ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ## SUCH DAMAGE. ## # determine system username system_username="`(id -un) 2>/dev/null`" if [ ".$system_username" = . ]; then str="`(id) 2>/dev/null`" if [ ".`echo $str | grep '^uid[ ]*=[ ]*[0-9]*('`" != . ]; then system_username=`echo $str | sed -e 's/^uid[ ]*=[ ]*[0-9]*(//' -e 's/).*$//'` fi if [ ".$system_username" = . ]; then system_username="$LOGNAME" if [ ".$system_username" = . ]; then system_username="$USER" if [ ".$system_username" = . ]; then system_username="`(whoami) 2>/dev/null | awk '{ printf("%s", $1); }'`" if [ ".$system_username" = . ]; then system_username="`(who am i) 2>/dev/null | awk '{ printf("%s", $1); }'`" fi fi fi fi fi # determine database superuser username, password and database superuser_username="" superuser_password="" superuser_database="" superuser_config_file="@l_prefix@/var/postgresql/db/pg_superuser.conf" if [ -r $superuser_config_file ]; then # read information eval `. $superuser_config_file; \ echo superuser_database=\"$superuser_database\"; \ echo superuser_username=\"$superuser_username\"; \ echo superuser_password=\"$superuser_password\"` else # guess information superuser_username="postgresql" superuser_database="template1" fi # determine requested username, database and hostname username="$1" database="$2" hostname="$3" if [ ".$username" = . ]; then if [ ".$system_username" = ".root" -o ".$system_username" = ".@l_rusr@" ]; then username="$superuser_username" else username="$system_username" fi fi if [ ".$database" = . ]; then if [ ".$username" = ".$superuser_username" ]; then database="$superuser_database" else database="$username" fi fi if [ ".$hostname" = . ]; then hostname="localhost" fi # make sure that the PostgreSQL super-user password # can be kept in sync with the external storage if [ ".$username" = ".$superuser_username" -a \ ".$database" = ".$superuser_database" ]; then if [ ".$system_username" != ".root" -a ".$system_username" != ".@l_rusr@" ]; then echo "$0:ERROR: super-user account password can be changed by \"root\" and \"@l_rusr@\" only" 2>&1 exit 1 fi if [ -h $superuser_config_file ]; then echo "$0:ERROR: superuser config \"$superuser_config_file\": invalid (symbolic link)" 2>&1 exit 1 fi if [ ! -f $superuser_config_file ]; then echo "$0:WARNING: superuser config \"$superuser_config_file\": not existing" 2>&1 exit 1 elif [ ! -w $superuser_password_file ]; then echo "$0:ERROR: superuser config \"$superuser_config_file\": permission denied (not writeable)" 2>&1 exit 1 fi fi # request old and new password password_old="" password_new="" password_new_verify="" if [ ".$username" = ".$superuser_username" -a \ ".$database" = ".$superuser_database" ]; then password_old="$superuser_password" fi while [ ".$password_old" = . ]; do read -s -p "$username:$database:$hostname OLD password: " password_old echo "" done while [ ".$password_new" = . ]; do read -s -p "$username:$database:$hostname NEW password: " password_new echo "" done while [ ".$password_new_verify" = . ]; do read -s -p "$username:$database:$hostname NEW password (retype to verify): " password_new_verify echo "" done if [ ".$password_new" != ".$password_new_verify" ]; then echo "$0:ERROR: mismatch on NEW password" 1>&2 exit 1 fi # change the password echo "ALTER ROLE $username WITH PASSWORD '$password_new'" | \ PGPASSWORD="$password_old" @l_prefix@/bin/psql \ -q -U $username -d $database -h $hostname -f- || exit $? # update superuser configuration if [ ".$username" = ".$superuser_username" -a \ ".$database" = ".$superuser_database" ]; then ( umask 077 sed -e "s;.*\(superuser_password=\"\).*\(\"\).*;\1$password_new\2;" \ <$superuser_config_file >$superuser_config_file.new || exit $? cp $superuser_config_file.new $superuser_config_file || exit $? rm -f $superuser_config_file.new || exit $? exit 0 ) || { echo "$0:ERROR: \"$superuser_config_file\": failed to update content" 1>&2 rm -f $superuser_config_file.new || true exit $? } ( superuser_database_old="$superuser_database" superuser_username_old="$superuser_username" superuser_password_old="$superuser_password" . $superuser_config_file [ ".$superuser_database" != ".$superuser_database_old" ] && exit 1 [ ".$superuser_username" != ".$superuser_username_old" ] && exit 1 [ ".$superuser_password" = ".$superuser_password_old" ] && exit 1 [ ".$superuser_password" != ".$password_new" ] && exit 1 exit 0 ) || { echo "$0:ERROR: \"$superuser_config_file\": unexpected updated content" 1>&2 exit $? } ( if [ ".$system_username" = ".root" ]; then chown @l_rusr@:@l_rgrp@ $superuser_config_file || exit $? fi chmod 600 $superuser_config_file || exit $? exit 0 ) || { echo "$0:ERROR: \"$superuser_config_file\": failed to fixate attributes" 1>&2 exit $? } fi