postgres.git / summary / log / commit / refs

commit    3352c23a611bdf2e1bcbd697f1265f0042b08136
Author:   Tom Lane <tgl@sss.pgh.pa.us>
Date:     Tue Aug 11 00:10:16 2015 +0000

    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.


src/bin/pg_dump/pg_dump.c | 85 ++++++++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 38 deletions(-) diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 08eb15d3c51..399e7ab3a68 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -3268,7 +3268,7 @@ getTypes(Archive *fout, int *numTypes) else if (fout->remoteVersion >= 80300) { appendPQExpBuffer(query, "SELECT tableoid, oid, typname, " - "typnamespace, '{=U}' AS typacl, " + "typnamespace, NULL AS typacl, " "(%s typowner) AS rolname, " "typinput::oid AS typinput, " "typoutput::oid AS typoutput, typelem, typrelid, " @@ -3283,7 +3283,7 @@ getTypes(Archive *fout, int *numTypes) else if (fout->remoteVersion >= 70300) { appendPQExpBuffer(query, "SELECT tableoid, oid, typname, " - "typnamespace, '{=U}' AS typacl, " + "typnamespace, NULL AS typacl, " "(%s typowner) AS rolname, " "typinput::oid AS typinput, " "typoutput::oid AS typoutput, typelem, typrelid, " @@ -3297,7 +3297,7 @@ getTypes(Archive *fout, int *numTypes) else if (fout->remoteVersion >= 70100) { appendPQExpBuffer(query, "SELECT tableoid, oid, typname, " - "0::oid AS typnamespace, '{=U}' AS typacl, " + "0::oid AS typnamespace, NULL AS typacl, " "(%s typowner) AS rolname, " "typinput::oid AS typinput, " "typoutput::oid AS typoutput, typelem, typrelid, " @@ -3313,7 +3313,7 @@ getTypes(Archive *fout, int *numTypes) appendPQExpBuffer(query, "SELECT " "(SELECT oid FROM pg_class WHERE relname = 'pg_type') AS tableoid, " "oid, typname, " - "0::oid AS typnamespace, '{=U}' AS typacl, " + "0::oid AS typnamespace, NULL AS typacl, " "(%s typowner) AS rolname, " "typinput::oid AS typinput, " "typoutput::oid AS typoutput, typelem, typrelid, " @@ -4004,7 +4004,7 @@ getAggregates(Archive *fout, int *numAggs) "CASE WHEN aggbasetype = 0 THEN 0 ELSE 1 END AS pronargs, " "aggbasetype AS proargtypes, " "(%s aggowner) AS rolname, " - "'{=X}' AS aggacl " + "NULL AS aggacl " "FROM pg_aggregate " "where oid > '%u'::oid", username_subquery, @@ -4019,7 +4019,7 @@ getAggregates(Archive *fout, int *numAggs) "CASE WHEN aggbasetype = 0 THEN 0 ELSE 1 END AS pronargs, " "aggbasetype AS proargtypes, " "(%s aggowner) AS rolname, " - "'{=X}' AS aggacl " + "NULL AS aggacl " "FROM pg_aggregate " "where oid > '%u'::oid", username_subquery, @@ -4163,7 +4163,7 @@ getFuncs(Archive *fout, int *numFuncs) appendPQExpBuffer(query, "SELECT tableoid, oid, proname, prolang, " "pronargs, proargtypes, prorettype, " - "'{=X}' AS proacl, " + "NULL AS proacl, " "0::oid AS pronamespace, " "(%s proowner) AS rolname " "FROM pg_proc " @@ -4179,7 +4179,7 @@ getFuncs(Archive *fout, int *numFuncs) " WHERE relname = 'pg_proc') AS tableoid, " "oid, proname, prolang, " "pronargs, proargtypes, prorettype, " - "'{=X}' AS proacl, " + "NULL AS proacl, " "0::oid AS pronamespace, " "(%s proowner) AS rolname " "FROM pg_proc " @@ -6014,7 +6014,7 @@ getProcLangs(Archive *fout, int *numProcLangs) /* pg_language has a laninline column */ appendPQExpBuffer(query, "SELECT tableoid, oid, " "lanname, lanpltrusted, lanplcallfoid, " - "laninline, lanvalidator, lanacl, " + "laninline, lanvalidator, lanacl, " "(%s lanowner) AS lanowner " "FROM pg_language " "WHERE lanispl " @@ -6026,7 +6026,7 @@ getProcLangs(Archive *fout, int *numProcLangs) /* pg_language has a lanowner column */ appendPQExpBuffer(query, "SELECT tableoid, oid, " "lanname, lanpltrusted, lanplcallfoid, " - "lanvalidator, lanacl, " + "0 AS laninline, lanvalidator, lanacl, " "(%s lanowner) AS lanowner " "FROM pg_language " "WHERE lanispl " @@ -6036,7 +6036,9 @@ getProcLangs(Archive *fout, int *numProcLangs) else if (fout->remoteVersion >= 80100) { /* Languages are owned by the bootstrap superuser, OID 10 */ - appendPQExpBuffer(query, "SELECT tableoid, oid, *, " + appendPQExpBuffer(query, "SELECT tableoid, oid, " + "lanname, lanpltrusted, lanplcallfoid, " + "0 AS laninline, lanvalidator, lanacl, " "(%s '10') AS lanowner " "FROM pg_language " "WHERE lanispl " @@ -6046,27 +6048,47 @@ getProcLangs(Archive *fout, int *numProcLangs) else if (fout->remoteVersion >= 70400) { /* Languages are owned by the bootstrap superuser, sysid 1 */ - appendPQExpBuffer(query, "SELECT tableoid, oid, *, " + appendPQExpBuffer(query, "SELECT tableoid, oid, " + "lanname, lanpltrusted, lanplcallfoid, " + "0 AS laninline, lanvalidator, lanacl, " "(%s '1') AS lanowner " "FROM pg_language " "WHERE lanispl " "ORDER BY oid", username_subquery); } - else if (fout->remoteVersion >= 70100) + else if (fout->remoteVersion >= 70300) { /* No clear notion of an owner at all before 7.4 ... */ - appendPQExpBufferStr(query, "SELECT tableoid, oid, * FROM pg_language " - "WHERE lanispl " - "ORDER BY oid"); + appendPQExpBuffer(query, "SELECT tableoid, oid, " + "lanname, lanpltrusted, lanplcallfoid, " + "0 AS laninline, lanvalidator, lanacl, " + "NULL AS lanowner " + "FROM pg_language " + "WHERE lanispl " + "ORDER BY oid"); + } + else if (fout->remoteVersion >= 70100) + { + appendPQExpBuffer(query, "SELECT tableoid, oid, " + "lanname, lanpltrusted, lanplcallfoid, " + "0 AS laninline, 0 AS lanvalidator, NULL AS lanacl, " + "NULL AS lanowner " + "FROM pg_language " + "WHERE lanispl " + "ORDER BY oid"); } else { - appendPQExpBufferStr(query, "SELECT " - "(SELECT oid FROM pg_class WHERE relname = 'pg_language') AS tableoid, " - "oid, * FROM pg_language " - "WHERE lanispl " - "ORDER BY oid"); + appendPQExpBuffer(query, "SELECT " + "(SELECT oid FROM pg_class WHERE relname = 'pg_language') AS tableoid, " + "oid, " + "lanname, lanpltrusted, lanplcallfoid, " + "0 AS laninline, 0 AS lanvalidator, NULL AS lanacl, " + "NULL AS lanowner " + "FROM pg_language " + "WHERE lanispl " + "ORDER BY oid"); } res = ExecuteSqlQuery(fout, query->data, PGRES_TUPLES_OK); @@ -6082,7 +6104,6 @@ getProcLangs(Archive *fout, int *numProcLangs) i_lanname = PQfnumber(res, "lanname"); i_lanpltrusted = PQfnumber(res, "lanpltrusted"); i_lanplcallfoid = PQfnumber(res, "lanplcallfoid"); - /* these may fail and return -1: */ i_laninline = PQfnumber(res, "laninline"); i_lanvalidator = PQfnumber(res, "lanvalidator"); i_lanacl = PQfnumber(res, "lanacl"); @@ -6098,22 +6119,10 @@ getProcLangs(Archive *fout, int *numProcLangs) planginfo[i].dobj.name = pg_strdup(PQgetvalue(res, i, i_lanname)); planginfo[i].lanpltrusted = *(PQgetvalue(res, i, i_lanpltrusted)) == 't'; planginfo[i].lanplcallfoid = atooid(PQgetvalue(res, i, i_lanplcallfoid)); - if (i_laninline >= 0) - planginfo[i].laninline = atooid(PQgetvalue(res, i, i_laninline)); - else - planginfo[i].laninline = InvalidOid; - if (i_lanvalidator >= 0) - planginfo[i].lanvalidator = atooid(PQgetvalue(res, i, i_lanvalidator)); - else - planginfo[i].lanvalidator = InvalidOid; - if (i_lanacl >= 0) - planginfo[i].lanacl = pg_strdup(PQgetvalue(res, i, i_lanacl)); - else - planginfo[i].lanacl = pg_strdup("{=U}"); - if (i_lanowner >= 0) - planginfo[i].lanowner = pg_strdup(PQgetvalue(res, i, i_lanowner)); - else - planginfo[i].lanowner = pg_strdup(""); + planginfo[i].laninline = atooid(PQgetvalue(res, i, i_laninline)); + planginfo[i].lanvalidator = atooid(PQgetvalue(res, i, i_lanvalidator)); + planginfo[i].lanacl = pg_strdup(PQgetvalue(res, i, i_lanacl)); + planginfo[i].lanowner = pg_strdup(PQgetvalue(res, i, i_lanowner)); if (fout->remoteVersion < 70300) { [parent: 7e0add386184]