diff options
author | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2015-12-21 19:16:15 -0300 |
---|---|---|
committer | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2015-12-21 19:16:15 -0300 |
commit | ab14c1383836301f00461b2a5593aebd340dd801 (patch) | |
tree | 63f380d6909869d66801639fcd102fc7a71c94da | |
parent | 6270ec1e5cb0efdcb2c8a22f126958e356496e51 (diff) | |
download | postgresql-ab14c1383836301f00461b2a5593aebd340dd801.tar.gz postgresql-ab14c1383836301f00461b2a5593aebd340dd801.zip |
adjust ACL owners for REASSIGN and ALTER OWNER TO
When REASSIGN and ALTER OWNER TO are used, both the object owner and ACL
list should be changed from the old owner to the new owner. This patch
fixes types, foreign data wrappers, and foreign servers to change their
ACL list properly; they already changed owners properly.
Report by Alexey Bashtanov
This is a backpatch of commit 59367fdf97c (for bug #9923) by Bruce
Momjian to branches 9.1 - 9.4; it wasn't backpatched originally out of
concerns that it would create a backwards compatibility problem, but per
discussion related to bug #13666 that turns out to have been misguided.
(Therefore, the entry in the 9.5 release notes should be removed.)
Note that 9.1 didn't have privileges on types (which were introduced by
commit 729205571e81), so this commit only changes foreign-data related
objects in that branch.
Discussion: http://www.postgresql.org/message-id/20151216224004.GL2618@alvherre.pgsql
http://www.postgresql.org/message-id/10227.1450373793@sss.pgh.pa.us
-rw-r--r-- | src/backend/commands/foreigncmds.c | 56 | ||||
-rw-r--r-- | src/test/regress/expected/foreign_data.out | 75 |
2 files changed, 92 insertions, 39 deletions
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c index 67572fa2f12..0bf6ea000d7 100644 --- a/src/backend/commands/foreigncmds.c +++ b/src/backend/commands/foreigncmds.c @@ -211,6 +211,12 @@ static void AlterForeignDataWrapperOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) { Form_pg_foreign_data_wrapper form; + Datum repl_val[Natts_pg_foreign_data_wrapper]; + bool repl_null[Natts_pg_foreign_data_wrapper]; + bool repl_repl[Natts_pg_foreign_data_wrapper]; + Acl *newAcl; + Datum aclDatum; + bool isNull; form = (Form_pg_foreign_data_wrapper) GETSTRUCT(tup); @@ -232,7 +238,27 @@ AlterForeignDataWrapperOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerI if (form->fdwowner != newOwnerId) { - form->fdwowner = newOwnerId; + memset(repl_null, false, sizeof(repl_null)); + memset(repl_repl, false, sizeof(repl_repl)); + + repl_repl[Anum_pg_foreign_data_wrapper_fdwowner - 1] = true; + repl_val[Anum_pg_foreign_data_wrapper_fdwowner - 1] = ObjectIdGetDatum(newOwnerId); + + aclDatum = heap_getattr(tup, + Anum_pg_foreign_data_wrapper_fdwacl, + RelationGetDescr(rel), + &isNull); + /* Null ACLs do not require changes */ + if (!isNull) + { + newAcl = aclnewowner(DatumGetAclP(aclDatum), + form->fdwowner, newOwnerId); + repl_repl[Anum_pg_foreign_data_wrapper_fdwacl - 1] = true; + repl_val[Anum_pg_foreign_data_wrapper_fdwacl - 1] = PointerGetDatum(newAcl); + } + + tup = heap_modify_tuple(tup, RelationGetDescr(rel), repl_val, repl_null, + repl_repl); simple_heap_update(rel, &tup->t_self, tup); CatalogUpdateIndexes(rel, tup); @@ -305,6 +331,12 @@ static void AlterForeignServerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) { Form_pg_foreign_server form; + Datum repl_val[Natts_pg_foreign_server]; + bool repl_null[Natts_pg_foreign_server]; + bool repl_repl[Natts_pg_foreign_server]; + Acl *newAcl; + Datum aclDatum; + bool isNull; form = (Form_pg_foreign_server) GETSTRUCT(tup); @@ -336,7 +368,27 @@ AlterForeignServerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) } } - form->srvowner = newOwnerId; + memset(repl_null, false, sizeof(repl_null)); + memset(repl_repl, false, sizeof(repl_repl)); + + repl_repl[Anum_pg_foreign_server_srvowner - 1] = true; + repl_val[Anum_pg_foreign_server_srvowner - 1] = ObjectIdGetDatum(newOwnerId); + + aclDatum = heap_getattr(tup, + Anum_pg_foreign_server_srvacl, + RelationGetDescr(rel), + &isNull); + /* Null ACLs do not require changes */ + if (!isNull) + { + newAcl = aclnewowner(DatumGetAclP(aclDatum), + form->srvowner, newOwnerId); + repl_repl[Anum_pg_foreign_server_srvacl - 1] = true; + repl_val[Anum_pg_foreign_server_srvacl - 1] = PointerGetDatum(newAcl); + } + + tup = heap_modify_tuple(tup, RelationGetDescr(rel), repl_val, repl_null, + repl_repl); simple_heap_update(rel, &tup->t_self, tup); CatalogUpdateIndexes(rel, tup); diff --git a/src/test/regress/expected/foreign_data.out b/src/test/regress/expected/foreign_data.out index 5b112a2265d..850edf6522a 100644 --- a/src/test/regress/expected/foreign_data.out +++ b/src/test/regress/expected/foreign_data.out @@ -416,21 +416,20 @@ ERROR: role "regress_test_indirect" cannot be dropped because some objects depe DETAIL: owner of server s1 privileges for foreign-data wrapper foo \des+ - List of foreign servers - Name | Owner | Foreign-data wrapper | Access privileges | Type | Version | Options -------+-----------------------+----------------------+-----------------------------------------+--------+---------+--------------------------------- - s1 | regress_test_indirect | foo | foreign_data_user=U/foreign_data_user +| | 1.1 | {servername=s1} - | | | regress_test_role=U/foreign_data_user | | | - s2 | foreign_data_user | foo | | | 1.1 | {host=a,dbname=b} - s3 | foreign_data_user | foo | | oracle | | {tnsname=orcl,port=1521} - s4 | foreign_data_user | foo | | oracle | | {host=a,dbname=b} - s5 | foreign_data_user | foo | | | 15.0 | - s6 | foreign_data_user | foo | foreign_data_user=U/foreign_data_user +| | 16.0 | {host=a,dbname=b} - | | | regress_test_role2=U*/foreign_data_user | | | - s7 | foreign_data_user | foo | | oracle | 17.0 | {host=a,dbname=b} - s8 | foreign_data_user | postgresql | | | | {dbname=db1,connect_timeout=30} - t1 | regress_test_role | foo | | | | - t2 | regress_test_role | foo | | | | + List of foreign servers + Name | Owner | Foreign-data wrapper | Access privileges | Type | Version | Options +------+-----------------------+----------------------+-----------------------------------------------+--------+---------+--------------------------------- + s1 | regress_test_indirect | foo | regress_test_indirect=U/regress_test_indirect | | 1.1 | {servername=s1} + s2 | foreign_data_user | foo | | | 1.1 | {host=a,dbname=b} + s3 | foreign_data_user | foo | | oracle | | {tnsname=orcl,port=1521} + s4 | foreign_data_user | foo | | oracle | | {host=a,dbname=b} + s5 | foreign_data_user | foo | | | 15.0 | + s6 | foreign_data_user | foo | foreign_data_user=U/foreign_data_user +| | 16.0 | {host=a,dbname=b} + | | | regress_test_role2=U*/foreign_data_user | | | + s7 | foreign_data_user | foo | | oracle | 17.0 | {host=a,dbname=b} + s8 | foreign_data_user | postgresql | | | | {dbname=db1,connect_timeout=30} + t1 | regress_test_role | foo | | | | + t2 | regress_test_role | foo | | | | (10 rows) -- DROP SERVER @@ -803,21 +802,21 @@ SELECT * FROM information_schema.user_mapping_options ORDER BY lower(authorizati (7 rows) SELECT * FROM information_schema.usage_privileges WHERE object_type LIKE 'FOREIGN%' ORDER BY 1, 2, 3, 4, 5; - grantor | grantee | object_catalog | object_schema | object_name | object_type | privilege_type | is_grantable --------------------+-----------------------+----------------+---------------+-------------+----------------------+----------------+-------------- - foreign_data_user | foreign_data_user | regression | | foo | FOREIGN DATA WRAPPER | USAGE | YES - foreign_data_user | foreign_data_user | regression | | s6 | FOREIGN SERVER | USAGE | YES - foreign_data_user | regress_test_indirect | regression | | foo | FOREIGN DATA WRAPPER | USAGE | NO - foreign_data_user | regress_test_role2 | regression | | s6 | FOREIGN SERVER | USAGE | YES + grantor | grantee | object_catalog | object_schema | object_name | object_type | privilege_type | is_grantable +-----------------------+-----------------------+----------------+---------------+-------------+----------------------+----------------+-------------- + foreign_data_user | foreign_data_user | regression | | foo | FOREIGN DATA WRAPPER | USAGE | YES + foreign_data_user | regress_test_indirect | regression | | foo | FOREIGN DATA WRAPPER | USAGE | NO + regress_test_indirect | regress_test_indirect | regression | | s6 | FOREIGN SERVER | USAGE | YES + regress_test_indirect | regress_test_role2 | regression | | s6 | FOREIGN SERVER | USAGE | YES (4 rows) SELECT * FROM information_schema.role_usage_grants WHERE object_type LIKE 'FOREIGN%' ORDER BY 1, 2, 3, 4, 5; - grantor | grantee | object_catalog | object_schema | object_name | object_type | privilege_type | is_grantable --------------------+-----------------------+----------------+---------------+-------------+----------------------+----------------+-------------- - foreign_data_user | foreign_data_user | regression | | foo | FOREIGN DATA WRAPPER | USAGE | YES - foreign_data_user | foreign_data_user | regression | | s6 | FOREIGN SERVER | USAGE | YES - foreign_data_user | regress_test_indirect | regression | | foo | FOREIGN DATA WRAPPER | USAGE | NO - foreign_data_user | regress_test_role2 | regression | | s6 | FOREIGN SERVER | USAGE | YES + grantor | grantee | object_catalog | object_schema | object_name | object_type | privilege_type | is_grantable +-----------------------+-----------------------+----------------+---------------+-------------+----------------------+----------------+-------------- + foreign_data_user | foreign_data_user | regression | | foo | FOREIGN DATA WRAPPER | USAGE | YES + foreign_data_user | regress_test_indirect | regression | | foo | FOREIGN DATA WRAPPER | USAGE | NO + regress_test_indirect | regress_test_indirect | regression | | s6 | FOREIGN SERVER | USAGE | YES + regress_test_indirect | regress_test_role2 | regression | | s6 | FOREIGN SERVER | USAGE | YES (4 rows) SELECT * FROM information_schema.foreign_tables ORDER BY 1, 2, 3; @@ -845,18 +844,20 @@ SELECT * FROM information_schema.user_mapping_options ORDER BY 1, 2, 3, 4; (5 rows) SELECT * FROM information_schema.usage_privileges WHERE object_type LIKE 'FOREIGN%' ORDER BY 1, 2, 3, 4, 5; - grantor | grantee | object_catalog | object_schema | object_name | object_type | privilege_type | is_grantable --------------------+-----------------------+----------------+---------------+-------------+----------------------+----------------+-------------- - foreign_data_user | regress_test_indirect | regression | | foo | FOREIGN DATA WRAPPER | USAGE | NO - foreign_data_user | regress_test_role2 | regression | | s6 | FOREIGN SERVER | USAGE | YES -(2 rows) + grantor | grantee | object_catalog | object_schema | object_name | object_type | privilege_type | is_grantable +-----------------------+-----------------------+----------------+---------------+-------------+----------------------+----------------+-------------- + foreign_data_user | regress_test_indirect | regression | | foo | FOREIGN DATA WRAPPER | USAGE | NO + regress_test_indirect | regress_test_indirect | regression | | s6 | FOREIGN SERVER | USAGE | YES + regress_test_indirect | regress_test_role2 | regression | | s6 | FOREIGN SERVER | USAGE | YES +(3 rows) SELECT * FROM information_schema.role_usage_grants WHERE object_type LIKE 'FOREIGN%' ORDER BY 1, 2, 3, 4, 5; - grantor | grantee | object_catalog | object_schema | object_name | object_type | privilege_type | is_grantable --------------------+-----------------------+----------------+---------------+-------------+----------------------+----------------+-------------- - foreign_data_user | regress_test_indirect | regression | | foo | FOREIGN DATA WRAPPER | USAGE | NO - foreign_data_user | regress_test_role2 | regression | | s6 | FOREIGN SERVER | USAGE | YES -(2 rows) + grantor | grantee | object_catalog | object_schema | object_name | object_type | privilege_type | is_grantable +-----------------------+-----------------------+----------------+---------------+-------------+----------------------+----------------+-------------- + foreign_data_user | regress_test_indirect | regression | | foo | FOREIGN DATA WRAPPER | USAGE | NO + regress_test_indirect | regress_test_indirect | regression | | s6 | FOREIGN SERVER | USAGE | YES + regress_test_indirect | regress_test_role2 | regression | | s6 | FOREIGN SERVER | USAGE | YES +(3 rows) DROP USER MAPPING FOR current_user SERVER t1; SET ROLE regress_test_role2; |