diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c index 15e5923e191..1fb81d1bebc 100644 --- a/src/bin/pg_dump/dumputils.c +++ b/src/bin/pg_dump/dumputils.c @@ -168,48 +168,28 @@ buildACLCommands(const char *name, const char *subname, const char *nspname, for (i = 0; i < nraclitems; i++) { if (!parseAclItem(raclitems[i], type, name, subname, remoteVersion, - grantee, grantor, privs, privswgo)) + grantee, grantor, privs, NULL)) { ok = false; break; } - if (privs->len > 0 || privswgo->len > 0) + if (privs->len > 0) { - if (privs->len > 0) - { - appendPQExpBuffer(firstsql, "%sREVOKE %s ON %s ", - prefix, privs->data, type); - if (nspname && *nspname) - appendPQExpBuffer(firstsql, "%s.", fmtId(nspname)); - appendPQExpBuffer(firstsql, "%s FROM ", name); - if (grantee->len == 0) - appendPQExpBufferStr(firstsql, "PUBLIC;\n"); - else if (strncmp(grantee->data, "group ", - strlen("group ")) == 0) - appendPQExpBuffer(firstsql, "GROUP %s;\n", - fmtId(grantee->data + strlen("group "))); - else - appendPQExpBuffer(firstsql, "%s;\n", - fmtId(grantee->data)); - } - if (privswgo->len > 0) - { - appendPQExpBuffer(firstsql, - "%sREVOKE GRANT OPTION FOR %s ON %s ", - prefix, privswgo->data, type); - if (nspname && *nspname) - appendPQExpBuffer(firstsql, "%s.", fmtId(nspname)); - appendPQExpBuffer(firstsql, "%s FROM ", name); - if (grantee->len == 0) - appendPQExpBufferStr(firstsql, "PUBLIC"); - else if (strncmp(grantee->data, "group ", - strlen("group ")) == 0) - appendPQExpBuffer(firstsql, "GROUP %s", - fmtId(grantee->data + strlen("group "))); - else - appendPQExpBufferStr(firstsql, fmtId(grantee->data)); - } + appendPQExpBuffer(firstsql, "%sREVOKE %s ON %s ", + prefix, privs->data, type); + if (nspname && *nspname) + appendPQExpBuffer(firstsql, "%s.", fmtId(nspname)); + appendPQExpBuffer(firstsql, "%s FROM ", name); + if (grantee->len == 0) + appendPQExpBufferStr(firstsql, "PUBLIC;\n"); + else if (strncmp(grantee->data, "group ", + strlen("group ")) == 0) + appendPQExpBuffer(firstsql, "GROUP %s;\n", + fmtId(grantee->data + strlen("group "))); + else + appendPQExpBuffer(firstsql, "%s;\n", + fmtId(grantee->data)); } } } @@ -459,10 +439,13 @@ buildDefaultACLCommands(const char *type, const char *nspname, * (the /grantor part will not be present if pre-7.4 database). * * The returned grantee string will be the dequoted username or groupname - * (preceded with "group " in the latter case). The returned grantor is - * the dequoted grantor name or empty. Privilege characters are decoded - * and split between privileges with grant option (privswgo) and without - * (privs). + * (preceded with "group " in the latter case). Note that a grant to PUBLIC + * is represented by an empty grantee string. The returned grantor is the + * dequoted grantor name. Privilege characters are translated to GRANT/REVOKE + * comma-separated privileges lists. If "privswgo" is non-NULL, the result is + * separate lists for privileges with grant option ("privswgo") and without + * ("privs"). Otherwise, "privs" bears every relevant privilege, ignoring the + * grant option distinction. * * Note: for cross-version compatibility, it's important to use ALL when * appropriate. @@ -512,7 +495,7 @@ parseAclItem(const char *item, const char *type, do { \ if ((pos = strchr(eqpos + 1, code))) \ { \ - if (*(pos + 1) == '*') \ + if (*(pos + 1) == '*' && privswgo != NULL) \ { \ AddAcl(privswgo, keywd, subname); \ all_without_go = false; \ diff --git a/src/test/modules/test_pg_dump/t/001_base.pl b/src/test/modules/test_pg_dump/t/001_base.pl index e8384f78dc0..e562a4edcdb 100644 --- a/src/test/modules/test_pg_dump/t/001_base.pl +++ b/src/test/modules/test_pg_dump/t/001_base.pl @@ -383,6 +383,57 @@ my %tests = ( }, }, + 'REVOKE ALL ON FUNCTION wgo_then_no_access' => { + create_order => 3, + create_sql => q{ + DO $$BEGIN EXECUTE format( + 'REVOKE ALL ON FUNCTION wgo_then_no_access() + FROM pg_signal_backend, public, %I', + (SELECT usename + FROM pg_user JOIN pg_proc ON proowner = usesysid + WHERE proname = 'wgo_then_no_access')); END$$;}, + regexp => qr/^ + \QREVOKE ALL ON FUNCTION public.wgo_then_no_access() FROM PUBLIC;\E + \n\QREVOKE ALL ON FUNCTION public.wgo_then_no_access() FROM \E.*; + \n\QREVOKE ALL ON FUNCTION public.wgo_then_no_access() FROM pg_signal_backend;\E + /xm, + like => { + binary_upgrade => 1, + clean => 1, + clean_if_exists => 1, + createdb => 1, + defaults => 1, + no_owner => 1, + schema_only => 1, + section_pre_data => 1, }, + unlike => { + no_privs => 1, + pg_dumpall_globals => 1, + section_post_data => 1, }, }, + + 'REVOKE GRANT OPTION FOR UPDATE ON SEQUENCE wgo_then_regular' => { + create_order => 3, + create_sql => 'REVOKE GRANT OPTION FOR UPDATE ON SEQUENCE + wgo_then_regular FROM pg_signal_backend;', + regexp => qr/^ + \QREVOKE ALL ON SEQUENCE public.wgo_then_regular FROM pg_signal_backend;\E + \n\QGRANT SELECT,UPDATE ON SEQUENCE public.wgo_then_regular TO pg_signal_backend;\E + \n\QGRANT USAGE ON SEQUENCE public.wgo_then_regular TO pg_signal_backend WITH GRANT OPTION;\E + /xm, + like => { + binary_upgrade => 1, + clean => 1, + clean_if_exists => 1, + createdb => 1, + defaults => 1, + no_owner => 1, + schema_only => 1, + section_pre_data => 1, }, + unlike => { + no_privs => 1, + pg_dumpall_globals => 1, + section_post_data => 1, }, }, + 'CREATE ACCESS METHOD regress_test_am' => { regexp => qr/^ \QCREATE ACCESS METHOD regress_test_am TYPE INDEX HANDLER bthandler;\E diff --git a/src/test/modules/test_pg_dump/test_pg_dump--1.0.sql b/src/test/modules/test_pg_dump/test_pg_dump--1.0.sql index c7a35c3afa0..110f7eef66c 100644 --- a/src/test/modules/test_pg_dump/test_pg_dump--1.0.sql +++ b/src/test/modules/test_pg_dump/test_pg_dump--1.0.sql @@ -28,6 +28,15 @@ GRANT SELECT(col1) ON regress_pg_dump_table TO public; GRANT SELECT(col2) ON regress_pg_dump_table TO regress_dump_test_role; REVOKE SELECT(col2) ON regress_pg_dump_table FROM regress_dump_test_role; +CREATE FUNCTION wgo_then_no_access() RETURNS int LANGUAGE SQL AS 'SELECT 1'; +GRANT ALL ON FUNCTION wgo_then_no_access() + TO pg_signal_backend WITH GRANT OPTION; + +CREATE SEQUENCE wgo_then_regular; +GRANT ALL ON SEQUENCE wgo_then_regular TO pg_signal_backend WITH GRANT OPTION; +REVOKE GRANT OPTION FOR SELECT ON SEQUENCE wgo_then_regular + FROM pg_signal_backend; + CREATE ACCESS METHOD regress_test_am TYPE INDEX HANDLER bthandler; -- Create a set of objects that are part of the schema created by