2013-01-29 11:15 keltezéssel, Magnus Hagander írta:
On Thu, Jan 24, 2013 at 7:04 AM, Hari Babu <haribabu.ko...@huawei.com> wrote:
On Wed, Jan 23, 2013 11:48 PM, Magnus Hagander wrote:
On Wed, Jan 23, 2013 at 10:18 AM, Hari Babu <haribabu.ko...@huawei.com>
wrote:
Test scenario to reproduce:
         1. Start the server
         2. create the user as follows
                 ./psql postgres -c "create user user1 superuser login
password 'use''1'"

         3. Take the backup with -R option as follows.
                 ./pg_basebackup -D ../../data1 -R -U user1 -W

The following errors are occurring when the new standby on the backup
database starts.

FATAL:  could not connect to the primary server: missing "=" after "1'"
in
connection info string
What does the resulting recovery.conf file look like?
The recovery.conf which is generated is as follows

standby_mode = 'on'
primary_conninfo = 'user=''user1'' password=''use''1'' port=''5432'' '


I observed the problem is while reading primary_conninfo from the
recovery.conf file
the function "GUC_scanstr" removes the quotes of the string and also makes
the
continuos double quote('') as single quote(').

By using the same connection string while connecting to primary server the
function "conninfo_parse" the escape quotes are not able to parse properly
and it is leading
to problem.

please correct me if any thing wrong in my observation.
Well, it's clearly broken at least :O

Zoltan, do you have time to  look at it? I won't have time until at
least after FOSDEM, unfortunately.

I looked at it shortly. What I tried first is adding another pair of single
quotes manually like this:

primary_conninfo = 'user=''user1'' password=''use''''1'' host=''192.168.1.2'' port=''5432'' sslmode=''disable'' sslcompression=''1'' '

But it doesn't solve the problem either, I got:

FATAL: could not connect to the primary server: missing "=" after "'1'" in connection info string

This worked though:

primary_conninfo = 'user=user1 password=use\'1 host=192.168.1.2 port=5432 sslmode=disable sslcompression=1 '

When I added an elog() to print the conninfo string in libpqrcv_connect(),
I saw that the double quotes were properly eliminated by ParseConfigFp()
in the first case.

So, there is a bug in generating recovery.conf by not double-escaping
the values and another bug in parsing the connection string in libpq
when the parameter value starts with a single-quote character.

Attached are two patches to fix these two bugs, the libpq part can
be back-patched.

Best regards,
Zoltán Böszörményi

--
----------------------------------
Zoltán Böszörményi
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt, Austria
Web: http://www.postgresql-support.de
     http://www.postgresql.at/

diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index eea9c6b..6528f77 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -4216,9 +4216,12 @@ conninfo_parse(const char *conninfo, PQExpBuffer errorMessage,
 				}
 				if (*cp == '\'')
 				{
-					*cp2 = '\0';
 					cp++;
-					break;
+					if (*cp != '\'')
+					{
+						*cp2 = '\0';
+						break;
+					}
 				}
 				*cp2++ = *cp++;
 			}
diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
index fb5a1bd..1c2ef9a 100644
--- a/src/bin/pg_basebackup/pg_basebackup.c
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -1127,6 +1127,7 @@ escape_quotes(const char *src)
 static void
 GenerateRecoveryConf(PGconn *conn)
 {
+	PQExpBufferData		arg_buf;
 	PQconninfoOption *connOptions;
 	PQconninfoOption *option;
 
@@ -1137,6 +1138,13 @@ GenerateRecoveryConf(PGconn *conn)
 		disconnect_and_exit(1);
 	}
 
+	initPQExpBuffer(&arg_buf);
+	if (PQExpBufferDataBroken(arg_buf))
+	{
+		fprintf(stderr, _("%s: out of memory"), progname);
+		disconnect_and_exit(1);
+	}
+
 	connOptions = PQconninfo(conn);
 	if (connOptions == NULL)
 	{
@@ -1150,6 +1158,7 @@ GenerateRecoveryConf(PGconn *conn)
 	for (option = connOptions; option && option->keyword; option++)
 	{
 		char	   *escaped;
+		char	   *escaped2;
 
 		/*
 		 * Do not emit this setting if: - the setting is "replication",
@@ -1169,10 +1178,13 @@ GenerateRecoveryConf(PGconn *conn)
 		 * necessary and doubled single quotes around the value string.
 		 */
 		escaped = escape_quotes(option->val);
+		printfPQExpBuffer(&arg_buf, "%s='%s'", option->keyword, escaped);
 
-		appendPQExpBuffer(recoveryconfcontents, "%s=''%s'' ", option->keyword, escaped);
+		escaped2 = escape_quotes(arg_buf.data);
+		appendPQExpBuffer(recoveryconfcontents, "%s ", escaped2);
 
 		free(escaped);
+		free(escaped2);
 	}
 
 	appendPQExpBufferStr(recoveryconfcontents, "'\n");
@@ -1183,6 +1195,7 @@ GenerateRecoveryConf(PGconn *conn)
 	}
 
 	PQconninfoFree(connOptions);
+	termPQExpBuffer(&arg_buf);
 }
 
 
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to