diff options
author | Joe Conway <mail@joeconway.com> | 2021-03-31 13:55:25 -0400 |
---|---|---|
committer | Joe Conway <mail@joeconway.com> | 2021-03-31 13:55:25 -0400 |
commit | b12bd4869b5e64b742a69ca07915e2f77f85a9ae (patch) | |
tree | 44c2f80d86ccabaf46d7489b515a258eaece4f1c /src/include/utils/acl.h | |
parent | 86dc90056dfdbd9d1b891718d2e5614e3e432f35 (diff) | |
download | postgresql-b12bd4869b5e64b742a69ca07915e2f77f85a9ae.tar.gz postgresql-b12bd4869b5e64b742a69ca07915e2f77f85a9ae.zip |
Fix has_column_privilege function corner case
According to the comments, when an invalid or dropped column oid is passed
to has_column_privilege(), the intention has always been to return NULL.
However, when the caller had table level privilege the invalid/missing
column was never discovered, because table permissions were checked first.
Fix that by introducing extended versions of pg_attribute_acl(check|mask)
and pg_class_acl(check|mask) which take a new argument, is_missing. When
is_missing is NULL, the old behavior is preserved. But when is_missing is
passed by the caller, no ERROR is thrown for dropped or missing
columns/relations, and is_missing is flipped to true. This in turn allows
has_column_privilege to check for column privileges first, providing the
desired semantics.
Not backpatched since it is a user visible behavioral change with no previous
complaints, and the fix is a bit on the invasive side.
Author: Joe Conway
Reviewed-By: Tom Lane
Reported by: Ian Barwick
Discussion: https://postgr.es/m/flat/9b5f4311-157b-4164-7fe7-077b4fe8ed84%40joeconway.com
Diffstat (limited to 'src/include/utils/acl.h')
-rw-r--r-- | src/include/utils/acl.h | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/src/include/utils/acl.h b/src/include/utils/acl.h index 541a438387b..af771c901d1 100644 --- a/src/include/utils/acl.h +++ b/src/include/utils/acl.h @@ -233,8 +233,14 @@ extern void RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid); extern AclMode pg_attribute_aclmask(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mask, AclMaskHow how); +extern AclMode pg_attribute_aclmask_ext(Oid table_oid, AttrNumber attnum, + Oid roleid, AclMode mask, + AclMaskHow how, bool *is_missing); extern AclMode pg_class_aclmask(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how); +extern AclMode pg_class_aclmask_ext(Oid table_oid, Oid roleid, + AclMode mask, AclMaskHow how, + bool *is_missing); extern AclMode pg_database_aclmask(Oid db_oid, Oid roleid, AclMode mask, AclMaskHow how); extern AclMode pg_proc_aclmask(Oid proc_oid, Oid roleid, @@ -256,9 +262,14 @@ extern AclMode pg_type_aclmask(Oid type_oid, Oid roleid, extern AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode); +extern AclResult pg_attribute_aclcheck_ext(Oid table_oid, AttrNumber attnum, + Oid roleid, AclMode mode, + bool *is_missing); extern AclResult pg_attribute_aclcheck_all(Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how); extern AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode); +extern AclResult pg_class_aclcheck_ext(Oid table_oid, Oid roleid, + AclMode mode, bool *is_missing); extern AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode); extern AclResult pg_proc_aclcheck(Oid proc_oid, Oid roleid, AclMode mode); extern AclResult pg_language_aclcheck(Oid lang_oid, Oid roleid, AclMode mode); |