Fix handling of COMMENT for domain constraints
For a non-superuser, changing a comment on a domain constraint was
leading to a cache lookup failure as the code tried to perform the
ownership lookup on the constraint OID itself, thinking that it was a
type, but this check needs to happen on the type the domain constraint
relies on. As the type a domain constraint relies on can be guessed
directly based on the constraint OID, first fetch its type OID and
perform the ownership on it.
This is broken since 7eca575
, which has split the handling of comments
for table constraints and domain constraints, so back-patch down to
9.5.
Reported-by: Clemens Ladisch
Author: Daniel Gustafsson, Michael Paquier
Reviewed-by: Álvaro Herrera
Discussion: https://postgr.es/m/15833-808e11904835d26f@postgresql.org
Backpatch-through: 9.5
This commit is contained in:
parent
e788e849ad
commit
ceac4505d3
|
@ -2295,10 +2295,32 @@ check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address,
|
|||
case OBJECT_TYPE:
|
||||
case OBJECT_DOMAIN:
|
||||
case OBJECT_ATTRIBUTE:
|
||||
case OBJECT_DOMCONSTRAINT:
|
||||
if (!pg_type_ownercheck(address.objectId, roleid))
|
||||
aclcheck_error_type(ACLCHECK_NOT_OWNER, address.objectId);
|
||||
break;
|
||||
case OBJECT_DOMCONSTRAINT:
|
||||
{
|
||||
HeapTuple tuple;
|
||||
Oid contypid;
|
||||
|
||||
tuple = SearchSysCache1(CONSTROID,
|
||||
ObjectIdGetDatum(address.objectId));
|
||||
if (!HeapTupleIsValid(tuple))
|
||||
elog(ERROR, "constraint with OID %u does not exist",
|
||||
address.objectId);
|
||||
|
||||
contypid = ((Form_pg_constraint) GETSTRUCT(tuple))->contypid;
|
||||
|
||||
ReleaseSysCache(tuple);
|
||||
|
||||
/*
|
||||
* Fallback to type ownership check in this case as this is
|
||||
* what domain constraints rely on.
|
||||
*/
|
||||
if (!pg_type_ownercheck(contypid, roleid))
|
||||
aclcheck_error_type(ACLCHECK_NOT_OWNER, contypid);
|
||||
}
|
||||
break;
|
||||
case OBJECT_AGGREGATE:
|
||||
case OBJECT_FUNCTION:
|
||||
case OBJECT_PROCEDURE:
|
||||
|
|
|
@ -518,6 +518,10 @@ ALTER TABLE deferred_excl ADD EXCLUDE (f1 WITH =);
|
|||
DROP TABLE deferred_excl;
|
||||
|
||||
-- Comments
|
||||
-- Setup a low-level role to enforce non-superuser checks.
|
||||
CREATE ROLE regress_constraint_comments;
|
||||
SET SESSION AUTHORIZATION regress_constraint_comments;
|
||||
|
||||
CREATE TABLE constraint_comments_tbl (a int CONSTRAINT the_constraint CHECK (a > 0));
|
||||
CREATE DOMAIN constraint_comments_dom AS int CONSTRAINT the_constraint CHECK (value > 0);
|
||||
|
||||
|
@ -535,5 +539,16 @@ COMMENT ON CONSTRAINT the_constraint ON DOMAIN no_comments_dom IS 'another bad c
|
|||
COMMENT ON CONSTRAINT the_constraint ON constraint_comments_tbl IS NULL;
|
||||
COMMENT ON CONSTRAINT the_constraint ON DOMAIN constraint_comments_dom IS NULL;
|
||||
|
||||
-- unauthorized user
|
||||
RESET SESSION AUTHORIZATION;
|
||||
CREATE ROLE regress_constraint_comments_noaccess;
|
||||
SET SESSION AUTHORIZATION regress_constraint_comments_noaccess;
|
||||
COMMENT ON CONSTRAINT the_constraint ON constraint_comments_tbl IS 'no, the comment';
|
||||
COMMENT ON CONSTRAINT the_constraint ON DOMAIN constraint_comments_dom IS 'no, another comment';
|
||||
RESET SESSION AUTHORIZATION;
|
||||
|
||||
DROP TABLE constraint_comments_tbl;
|
||||
DROP DOMAIN constraint_comments_dom;
|
||||
|
||||
DROP ROLE regress_constraint_comments;
|
||||
DROP ROLE regress_constraint_comments_noaccess;
|
||||
|
|
|
@ -704,6 +704,9 @@ ERROR: could not create exclusion constraint "deferred_excl_f1_excl"
|
|||
DETAIL: Key (f1)=(3) conflicts with key (f1)=(3).
|
||||
DROP TABLE deferred_excl;
|
||||
-- Comments
|
||||
-- Setup a low-level role to enforce non-superuser checks.
|
||||
CREATE ROLE regress_constraint_comments;
|
||||
SET SESSION AUTHORIZATION regress_constraint_comments;
|
||||
CREATE TABLE constraint_comments_tbl (a int CONSTRAINT the_constraint CHECK (a > 0));
|
||||
CREATE DOMAIN constraint_comments_dom AS int CONSTRAINT the_constraint CHECK (value > 0);
|
||||
COMMENT ON CONSTRAINT the_constraint ON constraint_comments_tbl IS 'yes, the comment';
|
||||
|
@ -720,5 +723,16 @@ COMMENT ON CONSTRAINT the_constraint ON DOMAIN no_comments_dom IS 'another bad c
|
|||
ERROR: type "no_comments_dom" does not exist
|
||||
COMMENT ON CONSTRAINT the_constraint ON constraint_comments_tbl IS NULL;
|
||||
COMMENT ON CONSTRAINT the_constraint ON DOMAIN constraint_comments_dom IS NULL;
|
||||
-- unauthorized user
|
||||
RESET SESSION AUTHORIZATION;
|
||||
CREATE ROLE regress_constraint_comments_noaccess;
|
||||
SET SESSION AUTHORIZATION regress_constraint_comments_noaccess;
|
||||
COMMENT ON CONSTRAINT the_constraint ON constraint_comments_tbl IS 'no, the comment';
|
||||
ERROR: must be owner of relation constraint_comments_tbl
|
||||
COMMENT ON CONSTRAINT the_constraint ON DOMAIN constraint_comments_dom IS 'no, another comment';
|
||||
ERROR: must be owner of type constraint_comments_dom
|
||||
RESET SESSION AUTHORIZATION;
|
||||
DROP TABLE constraint_comments_tbl;
|
||||
DROP DOMAIN constraint_comments_dom;
|
||||
DROP ROLE regress_constraint_comments;
|
||||
DROP ROLE regress_constraint_comments_noaccess;
|
||||
|
|
Loading…
Reference in New Issue