Mon, 28 Jan 2013 17:37:18 +0100
Correct socket error reporting improvement with IPv6 portable code,
after helpful recommendation by Saúl Ibarra Corretgé on OSips devlist.
michael@300 | 1 | #!@l_bash@ |
michael@300 | 2 | ## |
michael@300 | 3 | ## pg_passwd -- PostgreSQL Database Password Changing Utility |
michael@300 | 4 | ## Copyright (c) 2007 OpenPKG Foundation e.V. <http://openpkg.net/> |
michael@300 | 5 | ## Copyright (c) 2007 Ralf S. Engelschall <http://engelschall.com/> |
michael@300 | 6 | ## |
michael@300 | 7 | ## Permission to use, copy, modify, and distribute this software for |
michael@300 | 8 | ## any purpose with or without fee is hereby granted, provided that |
michael@300 | 9 | ## the above copyright notice and this permission notice appear in all |
michael@300 | 10 | ## copies. |
michael@300 | 11 | ## |
michael@300 | 12 | ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED |
michael@300 | 13 | ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
michael@300 | 14 | ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
michael@300 | 15 | ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR |
michael@300 | 16 | ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
michael@300 | 17 | ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
michael@300 | 18 | ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
michael@300 | 19 | ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
michael@300 | 20 | ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
michael@300 | 21 | ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
michael@300 | 22 | ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
michael@300 | 23 | ## SUCH DAMAGE. |
michael@300 | 24 | ## |
michael@300 | 25 | |
michael@300 | 26 | # determine system username |
michael@300 | 27 | system_username="`(id -un) 2>/dev/null`" |
michael@300 | 28 | if [ ".$system_username" = . ]; then |
michael@300 | 29 | str="`(id) 2>/dev/null`" |
michael@300 | 30 | if [ ".`echo $str | grep '^uid[ ]*=[ ]*[0-9]*('`" != . ]; then |
michael@300 | 31 | system_username=`echo $str | sed -e 's/^uid[ ]*=[ ]*[0-9]*(//' -e 's/).*$//'` |
michael@300 | 32 | fi |
michael@300 | 33 | if [ ".$system_username" = . ]; then |
michael@300 | 34 | system_username="$LOGNAME" |
michael@300 | 35 | if [ ".$system_username" = . ]; then |
michael@300 | 36 | system_username="$USER" |
michael@300 | 37 | if [ ".$system_username" = . ]; then |
michael@300 | 38 | system_username="`(whoami) 2>/dev/null | awk '{ printf("%s", $1); }'`" |
michael@300 | 39 | if [ ".$system_username" = . ]; then |
michael@300 | 40 | system_username="`(who am i) 2>/dev/null | awk '{ printf("%s", $1); }'`" |
michael@300 | 41 | fi |
michael@300 | 42 | fi |
michael@300 | 43 | fi |
michael@300 | 44 | fi |
michael@300 | 45 | fi |
michael@300 | 46 | |
michael@300 | 47 | # determine database superuser username, password and database |
michael@300 | 48 | superuser_username="" |
michael@300 | 49 | superuser_password="" |
michael@300 | 50 | superuser_database="" |
michael@300 | 51 | superuser_config_file="@l_prefix@/var/postgresql/db/pg_superuser.conf" |
michael@300 | 52 | if [ -r $superuser_config_file ]; then |
michael@300 | 53 | # read information |
michael@300 | 54 | eval `. $superuser_config_file; \ |
michael@300 | 55 | echo superuser_database=\"$superuser_database\"; \ |
michael@300 | 56 | echo superuser_username=\"$superuser_username\"; \ |
michael@300 | 57 | echo superuser_password=\"$superuser_password\"` |
michael@300 | 58 | else |
michael@300 | 59 | # guess information |
michael@300 | 60 | superuser_username="postgresql" |
michael@300 | 61 | superuser_database="template1" |
michael@300 | 62 | fi |
michael@300 | 63 | |
michael@300 | 64 | # determine requested username, database and hostname |
michael@300 | 65 | username="$1" |
michael@300 | 66 | database="$2" |
michael@300 | 67 | hostname="$3" |
michael@300 | 68 | if [ ".$username" = . ]; then |
michael@300 | 69 | if [ ".$system_username" = ".root" -o ".$system_username" = ".@l_rusr@" ]; then |
michael@300 | 70 | username="$superuser_username" |
michael@300 | 71 | else |
michael@300 | 72 | username="$system_username" |
michael@300 | 73 | fi |
michael@300 | 74 | fi |
michael@300 | 75 | if [ ".$database" = . ]; then |
michael@300 | 76 | if [ ".$username" = ".$superuser_username" ]; then |
michael@300 | 77 | database="$superuser_database" |
michael@300 | 78 | else |
michael@300 | 79 | database="$username" |
michael@300 | 80 | fi |
michael@300 | 81 | fi |
michael@300 | 82 | if [ ".$hostname" = . ]; then |
michael@300 | 83 | hostname="localhost" |
michael@300 | 84 | fi |
michael@300 | 85 | |
michael@300 | 86 | # make sure that the PostgreSQL super-user password |
michael@300 | 87 | # can be kept in sync with the external storage |
michael@300 | 88 | if [ ".$username" = ".$superuser_username" -a \ |
michael@300 | 89 | ".$database" = ".$superuser_database" ]; then |
michael@300 | 90 | if [ ".$system_username" != ".root" -a ".$system_username" != ".@l_rusr@" ]; then |
michael@300 | 91 | echo "$0:ERROR: super-user account password can be changed by \"root\" and \"@l_rusr@\" only" 2>&1 |
michael@300 | 92 | exit 1 |
michael@300 | 93 | fi |
michael@300 | 94 | if [ -h $superuser_config_file ]; then |
michael@300 | 95 | echo "$0:ERROR: superuser config \"$superuser_config_file\": invalid (symbolic link)" 2>&1 |
michael@300 | 96 | exit 1 |
michael@300 | 97 | fi |
michael@300 | 98 | if [ ! -f $superuser_config_file ]; then |
michael@300 | 99 | echo "$0:WARNING: superuser config \"$superuser_config_file\": not existing" 2>&1 |
michael@300 | 100 | exit 1 |
michael@300 | 101 | elif [ ! -w $superuser_password_file ]; then |
michael@300 | 102 | echo "$0:ERROR: superuser config \"$superuser_config_file\": permission denied (not writeable)" 2>&1 |
michael@300 | 103 | exit 1 |
michael@300 | 104 | fi |
michael@300 | 105 | fi |
michael@300 | 106 | |
michael@300 | 107 | # request old and new password |
michael@300 | 108 | password_old="" |
michael@300 | 109 | password_new="" |
michael@300 | 110 | password_new_verify="" |
michael@300 | 111 | if [ ".$username" = ".$superuser_username" -a \ |
michael@300 | 112 | ".$database" = ".$superuser_database" ]; then |
michael@300 | 113 | password_old="$superuser_password" |
michael@300 | 114 | fi |
michael@300 | 115 | while [ ".$password_old" = . ]; do |
michael@300 | 116 | read -s -p "$username:$database:$hostname OLD password: " password_old |
michael@300 | 117 | echo "" |
michael@300 | 118 | done |
michael@300 | 119 | while [ ".$password_new" = . ]; do |
michael@300 | 120 | read -s -p "$username:$database:$hostname NEW password: " password_new |
michael@300 | 121 | echo "" |
michael@300 | 122 | done |
michael@300 | 123 | while [ ".$password_new_verify" = . ]; do |
michael@300 | 124 | read -s -p "$username:$database:$hostname NEW password (retype to verify): " password_new_verify |
michael@300 | 125 | echo "" |
michael@300 | 126 | done |
michael@300 | 127 | if [ ".$password_new" != ".$password_new_verify" ]; then |
michael@300 | 128 | echo "$0:ERROR: mismatch on NEW password" 1>&2 |
michael@300 | 129 | exit 1 |
michael@300 | 130 | fi |
michael@300 | 131 | |
michael@300 | 132 | # change the password |
michael@300 | 133 | echo "ALTER ROLE $username WITH PASSWORD '$password_new'" | \ |
michael@300 | 134 | PGPASSWORD="$password_old" @l_prefix@/bin/psql \ |
michael@300 | 135 | -q -U $username -d $database -h $hostname -f- || exit $? |
michael@300 | 136 | |
michael@300 | 137 | # update superuser configuration |
michael@300 | 138 | if [ ".$username" = ".$superuser_username" -a \ |
michael@300 | 139 | ".$database" = ".$superuser_database" ]; then |
michael@300 | 140 | ( umask 077 |
michael@300 | 141 | sed -e "s;.*\(superuser_password=\"\).*\(\"\).*;\1$password_new\2;" \ |
michael@300 | 142 | <$superuser_config_file >$superuser_config_file.new || exit $? |
michael@300 | 143 | cp $superuser_config_file.new $superuser_config_file || exit $? |
michael@300 | 144 | rm -f $superuser_config_file.new || exit $? |
michael@300 | 145 | exit 0 |
michael@300 | 146 | ) || { |
michael@300 | 147 | echo "$0:ERROR: \"$superuser_config_file\": failed to update content" 1>&2 |
michael@300 | 148 | rm -f $superuser_config_file.new || true |
michael@300 | 149 | exit $? |
michael@300 | 150 | } |
michael@300 | 151 | ( superuser_database_old="$superuser_database" |
michael@300 | 152 | superuser_username_old="$superuser_username" |
michael@300 | 153 | superuser_password_old="$superuser_password" |
michael@300 | 154 | . $superuser_config_file |
michael@300 | 155 | [ ".$superuser_database" != ".$superuser_database_old" ] && exit 1 |
michael@300 | 156 | [ ".$superuser_username" != ".$superuser_username_old" ] && exit 1 |
michael@300 | 157 | [ ".$superuser_password" = ".$superuser_password_old" ] && exit 1 |
michael@300 | 158 | [ ".$superuser_password" != ".$password_new" ] && exit 1 |
michael@300 | 159 | exit 0 |
michael@300 | 160 | ) || { |
michael@300 | 161 | echo "$0:ERROR: \"$superuser_config_file\": unexpected updated content" 1>&2 |
michael@300 | 162 | exit $? |
michael@300 | 163 | } |
michael@300 | 164 | ( if [ ".$system_username" = ".root" ]; then |
michael@300 | 165 | chown @l_rusr@:@l_rgrp@ $superuser_config_file || exit $? |
michael@300 | 166 | fi |
michael@300 | 167 | chmod 600 $superuser_config_file || exit $? |
michael@300 | 168 | exit 0 |
michael@300 | 169 | ) || { |
michael@300 | 170 | echo "$0:ERROR: \"$superuser_config_file\": failed to fixate attributes" 1>&2 |
michael@300 | 171 | exit $? |
michael@300 | 172 | } |
michael@300 | 173 | fi |
michael@300 | 174 |