Re: How do CHECK Constraint Function privileges work? - Mailing list pgsql-sql

From Ruwan Fernando
Subject Re: How do CHECK Constraint Function privileges work?
Date
Msg-id CANYEAx9YbbUhz9KMMKKSJQNkb9y391ZaG=RMyn4DGpXwpvbfCw@mail.gmail.com
Whole thread Raw
In response to Re: How do CHECK Constraint Function privileges work?  ("David G. Johnston" <david.g.johnston@gmail.com>)
List pgsql-sql
On Sun, Apr 5, 2020 at 8:07 PM David G. Johnston
<david.g.johnston@gmail.com> wrote:
>
> On Sun, Apr 5, 2020 at 1:22 AM Ruwan Fernando <rutechs@gmail.com> wrote:
>>
>> I have created a test harness in a fresh DB where a role has access to 2 custom schemas, and have created a
constraintcheck function in the app_private schema, while creating a table on the app_public schema.
 
>>
>> CREATE SCHEMA app_public;
>> CREATE SCHEMA app_private;
>>
>> GRANT USAGE ON SCHEMA app_public TO "grant_test_role";
>>
>> CREATE OR REPLACE FUNCTION app_private.constraint_max_length(name_ TEXT) RETURNS BOOLEAN
>>   AS $$
>> BEGIN
>>   -- do some checks here
>>   RETURN TRUE;
>> END;
>> $$ LANGUAGE plpgsql;
>>
>> CREATE TABLE app_public.test_tab (
>>    id INT NOT NULL PRIMARY KEY,
>>    name TEXT NOT NULL,
>>
>>    CONSTRAINT name_length_check CHECK (app_private.constraint_max_length(name));
>> );
>
>
> Assuming you are connected as a superuser role here; you are not setting an explicit owner.
I'm sorry, forgot to mention that part. I run the DDL statements as
the db_owner user role who owns the DB, who is also a superuser.
>
>>
>>
>> BEGIN;
>>   SET LOCAL ROLE TO "grant_test_role";
>>   INSERT INTO app_public.test_tab (id, name) VALUES (1, 'Very Long Name');
>> COMMIT;
>>
>> My expectation was the INSERT would give me an exception due to "grant_test_role" not having permissions on the
"app_private"schema, but it does not. Why does the CHECK constraint function executes fine in this instance?
 
>>
>> I feel I'm missing some knowledge on how PostgreSQL internals work when checking privileges for CHECK constraint
expressions,and I didn't find anything mentioned about this in documentation.
 
>
>
> While I cannot locate the relevant documentation right now, privileges for triggers and constraints attached to a
tableare made against the owner of the table, not the user performing the action.
 
>
> David J.
>
Thank you for your reply, and that was my thought initially as well.
I'm trying to abstract out pieces of a bigger problem one at a time
here. So originally I had a Trigger and Check constraint both on the
same table, and I was under the impression that privileges would only
be checked during "creation" of the trigger & constraint against the
owner of the objects, but not on runtime against the executor role.
This worked out fine for sometime. Then I wanted to tighten up the
security of my DB and introduced this DDL statement at the very
beginning of deployment after reading about it in a stack-overflow
answer.

ALTER DEFAULT PRIVILEGES REVOKE ALL ON FUNCTIONS FROM PUBLIC;

As I understood, this is supposed to revoke all grants on functions
created from that point onwards from the "PUBLIC" user role which all
other roles inherit. And now started my confusion. After introducing
this line early in my deployment script, the CHECK constraint
functions were now giving me runtime exceptions with the text
"permission denied for function constraint_max_length". But the
triggers continued to execute just fine, even though both the trigger
function and the check constraint function existed in the same
"app_private" schema, and I had not granted anything special for the
trigger function.

So then I understood that PostgreSQL is checking some sort of runtime
privilege before calling the check constraint function which it's not
doing for the trigger function. And I'm really fine with that, but I
don't know why this behavior (checking permissions for check
constraint function) only happens when I have the above REVOKE
privilege statement, and not otherwise. I don't see how the PUBLIC
role can affect the check constraint function, as it's inside an
"app_private" schema, which is not granted to the executing user, then
that should be the error message (permission denied for schema
app_private). Also if I look at the opposite of this (without the
REVOKE ALL ON FUNCTIONS statement) then the schema where the CHECK
Constraint function existed didn't matter for this privilege check.

So I kind of get the feeling when it comes to CHECK constraint
functions, the schema of the function is never considered for any
privilege checks but just the function itself is checked. Thus I
posted the question here in the mailing list, where I'm trying to
understand exactly how the privileges are checked when executing a
CHECK Constraint function in PostgreSQL as it seems different from the
logic for Trigger Functions.

/Ruwan.



pgsql-sql by date:

Previous
From: Tom Lane
Date:
Subject: Re: How do CHECK Constraint Function privileges work?
Next
From: Ruwan Fernando
Date:
Subject: Re: How do CHECK Constraint Function privileges work?