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