Reputation: 2431
I have a use case where I need to check for FUTURE grants on an input database and schema. If FUTURE grants are found and not match with Input Role then I want to revoke them and then assign the permissions to a Input role.
I have written a procedure with ACCOUNTADMIN
as the Owner. My concern is that I want to execute this procedure as the owner, not as the caller. If I use EXECUTE AS CALLER
, I would need to higher grant permissions to custom Roles for all checks, which I want to avoid. However, SHOW
commands are not supported in procedures with EXECUTE AS OWNER
.
I have also tried using a parent procedure as the owner and a nested procedure as the caller, but this approach did not work.
How can I design the procedure to work with EXECUTE AS OWNER
or there is any way to get FUTURE GRANT other than SHOW Query?
Below is Sample Procedure:
-- Parametes
-- Database Name
-- Schema Name
-- Object Type such as TABLE, EXTERNAL TABLE, VIEWS etc.
-- Input Role Name
CREATE OR REPLACE PROCEDURE PARENT_SECURE_PROCEDURE("DATABASE_NAME" VARCHAR(16777216), "SCHEMA_NAME" VARCHAR(16777216),
"OBJECT_TYPE" VARCHAR(16777216), "ROLE_NAME" VARCHAR(16777216) )
RETURNS VARCHAR
LANGUAGE SQL
EXECUTE AS OWNER
$$
DECLARE
cc VARCHAR;
BEGIN
CALL GET_OR_REVOKE_FUTURE_GRANTS(:database_name, :schema_name, :object_type, :role_name);
cc := (SELECT * FROM TABLE(RESULT_SCAN(LAST_QUERY_ID())));
EXECUTE IMMEDIATE cc;
RETURN cc;
END;
$$
CREATE OR REPLACE PROCEDURE GET_OR_REVOKE_FUTURE_GRANTS("DATABASE_NAME" VARCHAR(16777216), "SCHEMA_NAME" VARCHAR(16777216), obj_type VARCHAR, role_name VARCHAR)
RETURNS VARCHAR
LANGUAGE SQL
EXECUTE AS CALLER
AS
$$
DECLARE
future_obj OBJECT;
sq VARCHAR;
cc VARCHAR;
BEGIN
cc := '--';
sq := 'SHOW FUTURE GRANTS IN SCHEMA ' || :database_name || '.' || :schema_name;
EXECUTE IMMEDIATE (sq);
future_obj := (SELECT OBJECT_AGG(REPLACE("grant_on" ||'S','_',' '),TO_VARIANT(UPPER("grantee_name")))
FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()))
WHERE "privilege" = 'OWNERSHIP' AND "grant_to" = 'ROLE' GROUP BY "grant_to");
IF (future_obj[obj_type] IS NULL) THEN
cc := '-- NO EXISTING FUTURE GRANT FOR OBJECT ' || obj_type || ' , TO THE SCHEMA ' || schema_name;
ELSEIF (future_obj[TRIM(UPPER(obj_type))] != role_name) THEN
cc := 'REVOKE OWNERSHIP ON FUTURE ' || UPPER(obj_type) || ' IN SCHEMA ' || database_name ||'.'|| schema_name || ' FROM ROLE ' || future_obj[TRIM(UPPER(obj_type))];
ELSE
cc := ' -- SKIPPING, the FUTURE GRANT FOR OBJECT ' || obj_type || ' ,ALERDY ASSIGNED TO THE SCHEMA ROLE ' || role_name;
END IF;
RETURN cc;
END;
$$
Upvotes: 0
Views: 217
Reputation: 772
FUTURE GRANTS can be retrieved via the SHOW command only and there is a limitation currently for SHOW command usage in the 'Owner's Rights' Stored Procedure.
You can use Caller's rights Stored Procedure for using SHOW commands in the Stored Procedure.
Upvotes: 0