diff -r 33c0b135173e -r 382048971a24 postgresql/pg_passwd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/postgresql/pg_passwd Mon Nov 22 16:54:26 2010 +0100 @@ -0,0 +1,174 @@ +#!@l_bash@ +## +## pg_passwd -- PostgreSQL Database Password Changing Utility +## Copyright (c) 2007 OpenPKG Foundation e.V. +## Copyright (c) 2007 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 +