cockroach icon indicating copy to clipboard operation
cockroach copied to clipboard

sql: support SECURITY DEFINER for routines

Open annrpom opened this issue 1 year ago • 1 comments

sql: correct error code

This patch assigns the pgcode (42501) to an ownership privilege check error. This aligns with postgres behavior.

postgres=> alter function testfn1(int) security definer;
ERROR:  42501: must be owner of function testfn1
LOCATION:  aclcheck_error, aclchk.c:3790

Release note: None


opt/cat: add sentinel const for StableID

This patch adds the InvalidStableID constant of 0 to describe an uninitialized stable ID.

Release note: None


sql: support SECURITY DEFINER for routines

Epic: CRDB-37477 Fixes: https://github.com/cockroachdb/cockroach/issues/121514

Release note (sql change): Added support for SECURITY DEFINER in user defined functions (UDFs) and stored procedures (SPs). When a UDF/SP (routine) is created with SECURITY DEFINER, at execution, the privileges of the owner will be checked.

Routines can now specify [EXTERNAL] SECURITY INVOKER (this is the default -- privileges of the invoker are checked at execution) or [EXTERNAL] SECURITY DEFINER. Note that the EXTERNAL keyword is optional and solely exists for sql conformity.

In addition, altering a UDF's security "mode" is accomplished by: ALTER FUNCTION ... [EXTERNAL] SECURITY {INVOKER/DEFINER}.

annrpom avatar Aug 27 '24 15:08 annrpom

This change is Reviewable

cockroach-teamcity avatar Aug 27 '24 15:08 cockroach-teamcity

@mgartner this is RFAL!

annrpom avatar Oct 04 '24 14:10 annrpom

pkg/sql/opt/optbuilder/routine.go line 231 at r13 (raw file):

Previously, mgartner (Marcus Gartner) wrote…

We need to reset the user back to what it was previously after building the body of the function. I think we should move this block of code down to where other fields are reset in a defer: https://github.com/cockroachdb/cockroach/blob/9f61a38b670e57873509568f67bb665e50cd1935/pkg/sql/opt/optbuilder/routine.go#L341-L356

Can you also add this test case which shows the problem (the last SELECT should not be an error):

CREATE USER a;

CREATE USER b;

CREATE TABLE t (i INT);

GRANT SELECT ON t TO a;

SET ROLE b;

CREATE FUNCTION f() RETURNS INT LANGUAGE SQL SECURITY DEFINER AS $$
  SELECT 1
$$;

SET ROLE a;

SELECT i FROM t;
--   i
-- -----
-- (0 rows)

SELECT f()
UNION
SELECT i FROM t;
-- ERROR: user b does not have SELECT privilege on relation t
-- SQLSTATE: 42501

(Feel free to adjust the test case to use the invoker, owner pattern already used in your tests, if you'd like.)

mgartner avatar Oct 07 '24 22:10 mgartner

TFTR! ('-')7

bors r=mgartner, rafiss

annrpom avatar Oct 08 '24 20:10 annrpom