diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c index 2235e5626f..caf48cefa9 100644 --- a/src/backend/catalog/objectaddress.c +++ b/src/backend/catalog/objectaddress.c @@ -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: diff --git a/src/test/regress/input/constraints.source b/src/test/regress/input/constraints.source index 0abf95577e..c325b2753d 100644 --- a/src/test/regress/input/constraints.source +++ b/src/test/regress/input/constraints.source @@ -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; diff --git a/src/test/regress/output/constraints.source b/src/test/regress/output/constraints.source index 465d6da0e0..e27caedcab 100644 --- a/src/test/regress/output/constraints.source +++ b/src/test/regress/output/constraints.source @@ -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;