Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 599dba4

Browse files
committed
Fix several problems in pg_dump's handling of SQL/MED objects, notably failure
to dump a PUBLIC user mapping correctly, as per bug #5560 from Shigeru Hanada. Use the pg_user_mappings view rather than trying to access pg_user_mapping directly, so that the code doesn't fail when run by a non-superuser. And clean up some minor carelessness such as unsafe usage of fmtId(). Back-patch to 8.4 where this code was added.
1 parent d494e68 commit 599dba4

File tree

1 file changed

+27
-17
lines changed

1 file changed

+27
-17
lines changed

src/bin/pg_dump/pg_dump.c

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
* http://archives.postgresql.org/pgsql-bugs/2010-02/msg00187.php
2626
*
2727
* IDENTIFICATION
28-
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.581 2010/07/06 19:18:59 momjian Exp $
28+
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.582 2010/07/14 21:21:08 tgl Exp $
2929
*
3030
*-------------------------------------------------------------------------
3131
*/
@@ -173,7 +173,7 @@ static void dumpTSTemplate(Archive *fout, TSTemplateInfo *tmplinfo);
173173
static void dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo);
174174
static void dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo);
175175
static void dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo);
176-
static void dumpUserMappings(Archive *fout, const char *target,
176+
static void dumpUserMappings(Archive *fout,
177177
const char *servername, const char *namespace,
178178
const char *owner, CatalogId catalogId, DumpId dumpId);
179179
static void dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo);
@@ -10138,6 +10138,7 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
1013810138
query = createPQExpBuffer();
1013910139

1014010140
/* look up the foreign-data wrapper */
10141+
selectSourceSchema("pg_catalog");
1014110142
appendPQExpBuffer(query, "SELECT fdwname "
1014210143
"FROM pg_foreign_data_wrapper w "
1014310144
"WHERE w.oid = '%u'",
@@ -10198,9 +10199,7 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
1019810199
free(namecopy);
1019910200

1020010201
/* Dump user mappings */
10201-
resetPQExpBuffer(q);
10202-
appendPQExpBuffer(q, "SERVER %s", fmtId(srvinfo->dobj.name));
10203-
dumpUserMappings(fout, q->data,
10202+
dumpUserMappings(fout,
1020410203
srvinfo->dobj.name, NULL,
1020510204
srvinfo->rolname,
1020610205
srvinfo->dobj.catId, srvinfo->dobj.dumpId);
@@ -10217,7 +10216,7 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
1021710216
* for the server.
1021810217
*/
1021910218
static void
10220-
dumpUserMappings(Archive *fout, const char *target,
10219+
dumpUserMappings(Archive *fout,
1022110220
const char *servername, const char *namespace,
1022210221
const char *owner,
1022310222
CatalogId catalogId, DumpId dumpId)
@@ -10228,7 +10227,7 @@ dumpUserMappings(Archive *fout, const char *target,
1022810227
PQExpBuffer tag;
1022910228
PGresult *res;
1023010229
int ntups;
10231-
int i_umuser;
10230+
int i_usename;
1023210231
int i_umoptions;
1023310232
int i;
1023410233

@@ -10237,31 +10236,40 @@ dumpUserMappings(Archive *fout, const char *target,
1023710236
delq = createPQExpBuffer();
1023810237
query = createPQExpBuffer();
1023910238

10239+
/*
10240+
* We read from the publicly accessible view pg_user_mappings, so as not
10241+
* to fail if run by a non-superuser. Note that the view will show
10242+
* umoptions as null if the user hasn't got privileges for the associated
10243+
* server; this means that pg_dump will dump such a mapping, but with no
10244+
* OPTIONS clause. A possible alternative is to skip such mappings
10245+
* altogether, but it's not clear that that's an improvement.
10246+
*/
10247+
selectSourceSchema("pg_catalog");
10248+
1024010249
appendPQExpBuffer(query,
10241-
"SELECT (%s umuser) AS umuser, "
10250+
"SELECT usename, "
1024210251
"array_to_string(ARRAY(SELECT option_name || ' ' || quote_literal(option_value) FROM pg_options_to_table(umoptions)), ', ') AS umoptions\n"
10243-
"FROM pg_user_mapping "
10244-
"WHERE umserver=%u",
10245-
username_subquery,
10252+
"FROM pg_user_mappings "
10253+
"WHERE srvid = %u",
1024610254
catalogId.oid);
1024710255

1024810256
res = PQexec(g_conn, query->data);
1024910257
check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
1025010258

1025110259
ntups = PQntuples(res);
10252-
i_umuser = PQfnumber(res, "umuser");
10260+
i_usename = PQfnumber(res, "usename");
1025310261
i_umoptions = PQfnumber(res, "umoptions");
1025410262

1025510263
for (i = 0; i < ntups; i++)
1025610264
{
10257-
char *umuser;
10265+
char *usename;
1025810266
char *umoptions;
1025910267

10260-
umuser = PQgetvalue(res, i, i_umuser);
10268+
usename = PQgetvalue(res, i, i_usename);
1026110269
umoptions = PQgetvalue(res, i, i_umoptions);
1026210270

1026310271
resetPQExpBuffer(q);
10264-
appendPQExpBuffer(q, "CREATE USER MAPPING FOR %s", fmtId(umuser));
10272+
appendPQExpBuffer(q, "CREATE USER MAPPING FOR %s", fmtId(usename));
1026510273
appendPQExpBuffer(q, " SERVER %s", fmtId(servername));
1026610274

1026710275
if (umoptions && strlen(umoptions) > 0)
@@ -10270,10 +10278,12 @@ dumpUserMappings(Archive *fout, const char *target,
1027010278
appendPQExpBuffer(q, ";\n");
1027110279

1027210280
resetPQExpBuffer(delq);
10273-
appendPQExpBuffer(delq, "DROP USER MAPPING FOR %s SERVER %s;\n", fmtId(umuser), fmtId(servername));
10281+
appendPQExpBuffer(delq, "DROP USER MAPPING FOR %s", fmtId(usename));
10282+
appendPQExpBuffer(delq, " SERVER %s;\n", fmtId(servername));
1027410283

1027510284
resetPQExpBuffer(tag);
10276-
appendPQExpBuffer(tag, "USER MAPPING %s %s", fmtId(umuser), target);
10285+
appendPQExpBuffer(tag, "USER MAPPING %s SERVER %s",
10286+
usename, servername);
1027710287

1027810288
ArchiveEntry(fout, nilCatalogId, createDumpId(),
1027910289
tag->data,

0 commit comments

Comments
 (0)