Re: SET LOCAL ROLE inside SECURITY INVOKER (LANGUAGE plpgsql) function

From: Adrian Klaver <adrian(dot)klaver(at)aklaver(dot)com>
To: Dominique Devienne <ddevienne(at)gmail(dot)com>, pgsql-general(at)lists(dot)postgresql(dot)org
Subject: Re: SET LOCAL ROLE inside SECURITY INVOKER (LANGUAGE plpgsql) function
Date: 2025-07-30 15:23:37
Message-ID: fa68fc72-e109-452e-8642-2b99c613f870@aklaver.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-general

On 7/30/25 04:37, Dominique Devienne wrote:
> Hi. PostgreSQL v17 here.
>
> I'm stumped by something, and would like pointers to sort something out.
> Inside my function, I do:
> ------------
> EXECUTE format('SET LOCAL ROLE %I', schema_owner);
> raise notice 'CURRENT_USER = %, can DELETE = %', CURRENT_USER,
> has_table_privilege('SchemaMapping', 'DELETE');
>
> DELETE FROM SchemaMapping
> WHERE "schema" = schema_name;
> -----------
>
> PQ: NOTICE: CURRENT_USER = Joe, can DELETE = t
>
> ERROR: permission denied for table schemamapping CONTEXT: SQL
> statement "DELETE FROM SchemaMapping WHERE "schema" = schema_name"
> PL/pgSQL function foo(text,text) line 28 at SQL statement
>
> The raise notice output is correct, and as expected. The DELETE error isn't.
> How can has_table_privilege() return true, yet the DELETE fail? I don't get it.
>
> My setup ensures that the role I SET LOCAL ROLE to, has (indirectly)
> been granted DMLs on that table.
>
> I also double-checked outside the routine, directly in code, for that privilege:
>
> c.ctx().setRole(schema_owner);
> auto rset = pq::exec(c, "select
> has_table_privilege('SchemaMapping', 'DELETE')");
> bool has_delete_mapping = rset.scalar<bool>();
> BOOST_CHECK(has_delete_mapping);
>
> Are there special consideration I'm unaware of, regarding SET ROLE
> inside routines?
>
> (beside the fact you can't SET ROLE in a SECURITY DEFINER routime! As
> I discovered recently...).
>
> I'd really appreciate some help here, as I don't understand what's going on.

What is the ROLE that defined the function?

What does "My setup ensures that the role I SET LOCAL ROLE to, has
(indirectly) been granted DMLs on that table." in terms of actual GRANTs?

>
> Thanks, --DD
>
>

--
Adrian Klaver
adrian(dot)klaver(at)aklaver(dot)com

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Dominique Devienne 2025-07-30 15:47:14 Re: SET LOCAL ROLE inside SECURITY INVOKER (LANGUAGE plpgsql) function
Previous Message Siraj G 2025-07-30 13:57:11 Re: Failing to allocate memory when I think it shouldn't