Skip to content

Commit 75d02d7

Browse files
committed
Fix privilege dumping from servers too old to have that type of privilege.
pg_dump produced fairly silly GRANT/REVOKE commands when dumping types from pre-9.2 servers, and when dumping functions or procedural languages from pre-7.3 servers. Those server versions lack the typacl, proacl, and/or lanacl columns respectively, and pg_dump substituted default values that were in fact incorrect. We ended up revoking all the owner's own privileges for the object while granting all privileges to PUBLIC. Of course the owner would then have those privileges again via PUBLIC, so long as she did not try to revoke PUBLIC's privileges; which may explain the lack of field reports. Nonetheless this is pretty silly behavior. The stakes were raised by my recent patch to make pg_dump dump shell types, because 9.2 and up pg_dump would proceed to emit bogus GRANT/REVOKE commands for a shell type if dumping from a pre-9.2 server; and the server will not accept GRANT/REVOKE commands for a shell type. (Perhaps it should, but that's a topic for another day.) So the resulting dump script wouldn't load without errors. The right thing to do is to act as though these objects have default privileges (null ACL entries), which causes pg_dump to print no GRANT/REVOKE commands at all for them. That fixes the silly results and also dodges the problem with shell types. In passing, modify getProcLangs() to be less creatively different about how to handle missing columns when dumping from older server versions. Every other data-acquisition function in pg_dump does that by substituting appropriate default values in the version-specific SQL commands, and I see no reason why this one should march to its own drummer. Its use of "SELECT *" was likewise not conformant with anyplace else, not to mention it's not considered good SQL style for production queries. Back-patch to all supported versions. Although 9.0 and 9.1 pg_dump don't have the issue with typacl, they are more likely than newer versions to be used to dump from ancient servers, so we ought to fix the proacl/lanacl issues all the way back.
1 parent 9cd3a0f commit 75d02d7

File tree

1 file changed

+41
-32
lines changed

1 file changed

+41
-32
lines changed

src/bin/pg_dump/pg_dump.c

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3231,7 +3231,7 @@ getTypes(Archive *fout, int *numTypes)
32313231
else if (fout->remoteVersion >= 80300)
32323232
{
32333233
appendPQExpBuffer(query, "SELECT tableoid, oid, typname, "
3234-
"typnamespace, '{=U}' AS typacl, "
3234+
"typnamespace, NULL AS typacl, "
32353235
"(%s typowner) AS rolname, "
32363236
"typinput::oid AS typinput, "
32373237
"typoutput::oid AS typoutput, typelem, typrelid, "
@@ -3246,7 +3246,7 @@ getTypes(Archive *fout, int *numTypes)
32463246
else if (fout->remoteVersion >= 70300)
32473247
{
32483248
appendPQExpBuffer(query, "SELECT tableoid, oid, typname, "
3249-
"typnamespace, '{=U}' AS typacl, "
3249+
"typnamespace, NULL AS typacl, "
32503250
"(%s typowner) AS rolname, "
32513251
"typinput::oid AS typinput, "
32523252
"typoutput::oid AS typoutput, typelem, typrelid, "
@@ -3260,7 +3260,7 @@ getTypes(Archive *fout, int *numTypes)
32603260
else if (fout->remoteVersion >= 70100)
32613261
{
32623262
appendPQExpBuffer(query, "SELECT tableoid, oid, typname, "
3263-
"0::oid AS typnamespace, '{=U}' AS typacl, "
3263+
"0::oid AS typnamespace, NULL AS typacl, "
32643264
"(%s typowner) AS rolname, "
32653265
"typinput::oid AS typinput, "
32663266
"typoutput::oid AS typoutput, typelem, typrelid, "
@@ -3276,7 +3276,7 @@ getTypes(Archive *fout, int *numTypes)
32763276
appendPQExpBuffer(query, "SELECT "
32773277
"(SELECT oid FROM pg_class WHERE relname = 'pg_type') AS tableoid, "
32783278
"oid, typname, "
3279-
"0::oid AS typnamespace, '{=U}' AS typacl, "
3279+
"0::oid AS typnamespace, NULL AS typacl, "
32803280
"(%s typowner) AS rolname, "
32813281
"typinput::oid AS typinput, "
32823282
"typoutput::oid AS typoutput, typelem, typrelid, "
@@ -3965,7 +3965,7 @@ getAggregates(Archive *fout, int *numAggs)
39653965
"CASE WHEN aggbasetype = 0 THEN 0 ELSE 1 END AS pronargs, "
39663966
"aggbasetype AS proargtypes, "
39673967
"(%s aggowner) AS rolname, "
3968-
"'{=X}' AS aggacl "
3968+
"NULL AS aggacl "
39693969
"FROM pg_aggregate "
39703970
"where oid > '%u'::oid",
39713971
username_subquery,
@@ -3980,7 +3980,7 @@ getAggregates(Archive *fout, int *numAggs)
39803980
"CASE WHEN aggbasetype = 0 THEN 0 ELSE 1 END AS pronargs, "
39813981
"aggbasetype AS proargtypes, "
39823982
"(%s aggowner) AS rolname, "
3983-
"'{=X}' AS aggacl "
3983+
"NULL AS aggacl "
39843984
"FROM pg_aggregate "
39853985
"where oid > '%u'::oid",
39863986
username_subquery,
@@ -4124,7 +4124,7 @@ getFuncs(Archive *fout, int *numFuncs)
41244124
appendPQExpBuffer(query,
41254125
"SELECT tableoid, oid, proname, prolang, "
41264126
"pronargs, proargtypes, prorettype, "
4127-
"'{=X}' AS proacl, "
4127+
"NULL AS proacl, "
41284128
"0::oid AS pronamespace, "
41294129
"(%s proowner) AS rolname "
41304130
"FROM pg_proc "
@@ -4140,7 +4140,7 @@ getFuncs(Archive *fout, int *numFuncs)
41404140
" WHERE relname = 'pg_proc') AS tableoid, "
41414141
"oid, proname, prolang, "
41424142
"pronargs, proargtypes, prorettype, "
4143-
"'{=X}' AS proacl, "
4143+
"NULL AS proacl, "
41444144
"0::oid AS pronamespace, "
41454145
"(%s proowner) AS rolname "
41464146
"FROM pg_proc "
@@ -5890,7 +5890,7 @@ getProcLangs(Archive *fout, int *numProcLangs)
58905890
/* pg_language has a laninline column */
58915891
appendPQExpBuffer(query, "SELECT tableoid, oid, "
58925892
"lanname, lanpltrusted, lanplcallfoid, "
5893-
"laninline, lanvalidator, lanacl, "
5893+
"laninline, lanvalidator, lanacl, "
58945894
"(%s lanowner) AS lanowner "
58955895
"FROM pg_language "
58965896
"WHERE lanispl "
@@ -5902,7 +5902,7 @@ getProcLangs(Archive *fout, int *numProcLangs)
59025902
/* pg_language has a lanowner column */
59035903
appendPQExpBuffer(query, "SELECT tableoid, oid, "
59045904
"lanname, lanpltrusted, lanplcallfoid, "
5905-
"lanvalidator, lanacl, "
5905+
"0 AS laninline, lanvalidator, lanacl, "
59065906
"(%s lanowner) AS lanowner "
59075907
"FROM pg_language "
59085908
"WHERE lanispl "
@@ -5912,7 +5912,9 @@ getProcLangs(Archive *fout, int *numProcLangs)
59125912
else if (fout->remoteVersion >= 80100)
59135913
{
59145914
/* Languages are owned by the bootstrap superuser, OID 10 */
5915-
appendPQExpBuffer(query, "SELECT tableoid, oid, *, "
5915+
appendPQExpBuffer(query, "SELECT tableoid, oid, "
5916+
"lanname, lanpltrusted, lanplcallfoid, "
5917+
"0 AS laninline, lanvalidator, lanacl, "
59165918
"(%s '10') AS lanowner "
59175919
"FROM pg_language "
59185920
"WHERE lanispl "
@@ -5922,25 +5924,45 @@ getProcLangs(Archive *fout, int *numProcLangs)
59225924
else if (fout->remoteVersion >= 70400)
59235925
{
59245926
/* Languages are owned by the bootstrap superuser, sysid 1 */
5925-
appendPQExpBuffer(query, "SELECT tableoid, oid, *, "
5927+
appendPQExpBuffer(query, "SELECT tableoid, oid, "
5928+
"lanname, lanpltrusted, lanplcallfoid, "
5929+
"0 AS laninline, lanvalidator, lanacl, "
59265930
"(%s '1') AS lanowner "
59275931
"FROM pg_language "
59285932
"WHERE lanispl "
59295933
"ORDER BY oid",
59305934
username_subquery);
59315935
}
5932-
else if (fout->remoteVersion >= 70100)
5936+
else if (fout->remoteVersion >= 70300)
59335937
{
59345938
/* No clear notion of an owner at all before 7.4 ... */
5935-
appendPQExpBuffer(query, "SELECT tableoid, oid, * FROM pg_language "
5939+
appendPQExpBuffer(query, "SELECT tableoid, oid, "
5940+
"lanname, lanpltrusted, lanplcallfoid, "
5941+
"0 AS laninline, lanvalidator, lanacl, "
5942+
"NULL AS lanowner "
5943+
"FROM pg_language "
5944+
"WHERE lanispl "
5945+
"ORDER BY oid");
5946+
}
5947+
else if (fout->remoteVersion >= 70100)
5948+
{
5949+
appendPQExpBuffer(query, "SELECT tableoid, oid, "
5950+
"lanname, lanpltrusted, lanplcallfoid, "
5951+
"0 AS laninline, 0 AS lanvalidator, NULL AS lanacl, "
5952+
"NULL AS lanowner "
5953+
"FROM pg_language "
59365954
"WHERE lanispl "
59375955
"ORDER BY oid");
59385956
}
59395957
else
59405958
{
59415959
appendPQExpBuffer(query, "SELECT "
59425960
"(SELECT oid FROM pg_class WHERE relname = 'pg_language') AS tableoid, "
5943-
"oid, * FROM pg_language "
5961+
"oid, "
5962+
"lanname, lanpltrusted, lanplcallfoid, "
5963+
"0 AS laninline, 0 AS lanvalidator, NULL AS lanacl, "
5964+
"NULL AS lanowner "
5965+
"FROM pg_language "
59445966
"WHERE lanispl "
59455967
"ORDER BY oid");
59465968
}
@@ -5958,7 +5980,6 @@ getProcLangs(Archive *fout, int *numProcLangs)
59585980
i_lanname = PQfnumber(res, "lanname");
59595981
i_lanpltrusted = PQfnumber(res, "lanpltrusted");
59605982
i_lanplcallfoid = PQfnumber(res, "lanplcallfoid");
5961-
/* these may fail and return -1: */
59625983
i_laninline = PQfnumber(res, "laninline");
59635984
i_lanvalidator = PQfnumber(res, "lanvalidator");
59645985
i_lanacl = PQfnumber(res, "lanacl");
@@ -5974,22 +5995,10 @@ getProcLangs(Archive *fout, int *numProcLangs)
59745995
planginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_lanname));
59755996
planginfo[i].lanpltrusted = *(PQgetvalue(res, i, i_lanpltrusted)) == 't';
59765997
planginfo[i].lanplcallfoid = atooid(PQgetvalue(res, i, i_lanplcallfoid));
5977-
if (i_laninline >= 0)
5978-
planginfo[i].laninline = atooid(PQgetvalue(res, i, i_laninline));
5979-
else
5980-
planginfo[i].laninline = InvalidOid;
5981-
if (i_lanvalidator >= 0)
5982-
planginfo[i].lanvalidator = atooid(PQgetvalue(res, i, i_lanvalidator));
5983-
else
5984-
planginfo[i].lanvalidator = InvalidOid;
5985-
if (i_lanacl >= 0)
5986-
planginfo[i].lanacl = pg_strdup(PQgetvalue(res, i, i_lanacl));
5987-
else
5988-
planginfo[i].lanacl = pg_strdup("{=U}");
5989-
if (i_lanowner >= 0)
5990-
planginfo[i].lanowner = pg_strdup(PQgetvalue(res, i, i_lanowner));
5991-
else
5992-
planginfo[i].lanowner = pg_strdup("");
5998+
planginfo[i].laninline = atooid(PQgetvalue(res, i, i_laninline));
5999+
planginfo[i].lanvalidator = atooid(PQgetvalue(res, i, i_lanvalidator));
6000+
planginfo[i].lanacl = pg_strdup(PQgetvalue(res, i, i_lanacl));
6001+
planginfo[i].lanowner = pg_strdup(PQgetvalue(res, i, i_lanowner));
59936002

59946003
if (fout->remoteVersion < 70300)
59956004
{

0 commit comments

Comments
 (0)