mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 00:03:57 -04:00 
			
		
		
		
	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. BACKWARD INCOMPATIBILITY? Report by Alexey Bashtanov
This commit is contained in:
		
							parent
							
								
									b181a91981
								
							
						
					
					
						commit
						59367fdf97
					
				| @ -225,6 +225,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); | ||||
| 
 | ||||
| @ -246,7 +252,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); | ||||
| @ -327,6 +353,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); | ||||
| 
 | ||||
| @ -358,7 +390,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); | ||||
|  | ||||
| @ -3376,12 +3376,34 @@ AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype) | ||||
| 			ATExecChangeOwner(typTup->typrelid, newOwnerId, true, AccessExclusiveLock); | ||||
| 		else | ||||
| 		{ | ||||
| 			/*
 | ||||
| 			 * We can just apply the modification directly. | ||||
| 			 * | ||||
| 			 * okay to scribble on typTup because it's a copy | ||||
| 			 */ | ||||
| 			typTup->typowner = newOwnerId; | ||||
| 			Datum		repl_val[Natts_pg_type]; | ||||
| 			bool		repl_null[Natts_pg_type]; | ||||
| 			bool		repl_repl[Natts_pg_type]; | ||||
| 			Acl		   *newAcl; | ||||
| 			Datum		aclDatum; | ||||
| 			bool		isNull; | ||||
| 
 | ||||
| 			memset(repl_null, false, sizeof(repl_null)); | ||||
| 			memset(repl_repl, false, sizeof(repl_repl)); | ||||
| 
 | ||||
| 			repl_repl[Anum_pg_type_typowner - 1] = true; | ||||
| 			repl_val[Anum_pg_type_typowner - 1] = ObjectIdGetDatum(newOwnerId); | ||||
| 
 | ||||
| 			aclDatum = heap_getattr(tup, | ||||
| 									Anum_pg_type_typacl, | ||||
| 									RelationGetDescr(rel), | ||||
| 									&isNull); | ||||
| 			/* Null ACLs do not require changes */ | ||||
| 			if (!isNull) | ||||
| 			{ | ||||
| 				newAcl = aclnewowner(DatumGetAclP(aclDatum), | ||||
| 									 typTup->typowner, newOwnerId); | ||||
| 				repl_repl[Anum_pg_type_typacl - 1] = true; | ||||
| 				repl_val[Anum_pg_type_typacl - 1] = PointerGetDatum(newAcl); | ||||
| 			} | ||||
| 
 | ||||
| 			tup = heap_modify_tuple(tup, RelationGetDescr(rel), repl_val, repl_null, | ||||
| 									repl_repl); | ||||
| 
 | ||||
| 			simple_heap_update(rel, &tup->t_self, tup); | ||||
| 
 | ||||
| @ -3424,6 +3446,12 @@ AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId, | ||||
| 	Relation	rel; | ||||
| 	HeapTuple	tup; | ||||
| 	Form_pg_type typTup; | ||||
| 	Datum		repl_val[Natts_pg_type]; | ||||
| 	bool		repl_null[Natts_pg_type]; | ||||
| 	bool		repl_repl[Natts_pg_type]; | ||||
| 	Acl		   *newAcl; | ||||
| 	Datum		aclDatum; | ||||
| 	bool		isNull; | ||||
| 
 | ||||
| 	rel = heap_open(TypeRelationId, RowExclusiveLock); | ||||
| 
 | ||||
| @ -3432,10 +3460,27 @@ AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId, | ||||
| 		elog(ERROR, "cache lookup failed for type %u", typeOid); | ||||
| 	typTup = (Form_pg_type) GETSTRUCT(tup); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Modify the owner --- okay to scribble on typTup because it's a copy | ||||
| 	 */ | ||||
| 	typTup->typowner = newOwnerId; | ||||
| 	memset(repl_null, false, sizeof(repl_null)); | ||||
| 	memset(repl_repl, false, sizeof(repl_repl)); | ||||
| 
 | ||||
| 	repl_repl[Anum_pg_type_typowner - 1] = true; | ||||
| 	repl_val[Anum_pg_type_typowner - 1] = ObjectIdGetDatum(newOwnerId); | ||||
| 
 | ||||
| 	aclDatum = heap_getattr(tup, | ||||
| 							Anum_pg_type_typacl, | ||||
| 							RelationGetDescr(rel), | ||||
| 							&isNull); | ||||
| 	/* Null ACLs do not require changes */ | ||||
| 	if (!isNull) | ||||
| 	{ | ||||
| 		newAcl = aclnewowner(DatumGetAclP(aclDatum), | ||||
| 							 typTup->typowner, newOwnerId); | ||||
| 		repl_repl[Anum_pg_type_typacl - 1] = true; | ||||
| 		repl_val[Anum_pg_type_typacl - 1] = PointerGetDatum(newAcl); | ||||
| 	} | ||||
| 
 | ||||
| 	tup = heap_modify_tuple(tup, RelationGetDescr(rel), repl_val, repl_null, | ||||
| 							repl_repl); | ||||
| 
 | ||||
| 	simple_heap_update(rel, &tup->t_self, tup); | ||||
| 
 | ||||
|  | ||||
| @ -424,9 +424,8 @@ privileges for foreign-data wrapper foo | ||||
| \des+ | ||||
|                                                                            List of foreign servers | ||||
|  Name |         Owner         | Foreign-data wrapper |               Access privileges               |  Type  | Version |             FDW Options              | Description  | ||||
| ------+-----------------------+----------------------+-----------------------------------------+--------+---------+--------------------------------------+------------- | ||||
|  s1   | regress_test_indirect | foo                  | foreign_data_user=U/foreign_data_user  +|        | 1.1     | (servername 's1')                    |  | ||||
|       |                       |                      | regress_test_role=U/foreign_data_user   |        |         |                                      |  | ||||
| ------+-----------------------+----------------------+-----------------------------------------------+--------+---------+--------------------------------------+------------- | ||||
|  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 |         | ("tns name" 'orcl', port '1521')     |  | ||||
|  s4   | foreign_data_user     | foo                  |                                               | oracle |         | (host 'a', dbname 'b')               |  | ||||
| @ -443,9 +442,8 @@ ALTER SERVER s8 RENAME to s8new; | ||||
| \des+ | ||||
|                                                                            List of foreign servers | ||||
|  Name  |         Owner         | Foreign-data wrapper |               Access privileges               |  Type  | Version |             FDW Options              | Description  | ||||
| -------+-----------------------+----------------------+-----------------------------------------+--------+---------+--------------------------------------+------------- | ||||
|  s1    | regress_test_indirect | foo                  | foreign_data_user=U/foreign_data_user  +|        | 1.1     | (servername 's1')                    |  | ||||
|        |                       |                      | regress_test_role=U/foreign_data_user   |        |         |                                      |  | ||||
| -------+-----------------------+----------------------+-----------------------------------------------+--------+---------+--------------------------------------+------------- | ||||
|  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 |         | ("tns name" 'orcl', port '1521')     |  | ||||
|  s4    | foreign_data_user     | foo                  |                                               | oracle |         | (host 'a', dbname 'b')               |  | ||||
| @ -938,20 +936,20 @@ SELECT * FROM information_schema.user_mapping_options ORDER BY lower(authorizati | ||||
| 
 | ||||
| SELECT * FROM information_schema.usage_privileges WHERE object_type LIKE 'FOREIGN%' AND object_name IN ('s6', 'foo') 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 | ||||
|  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%' AND object_name IN ('s6', 'foo') 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 | ||||
|  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; | ||||
| @ -981,17 +979,19 @@ SELECT * FROM information_schema.user_mapping_options ORDER BY 1, 2, 3, 4; | ||||
| 
 | ||||
| SELECT * FROM information_schema.usage_privileges WHERE object_type LIKE 'FOREIGN%' AND object_name IN ('s6', 'foo') 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) | ||||
|  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%' AND object_name IN ('s6', 'foo') 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) | ||||
|  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; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user