SET sql_mode=ORACLE; CREATE DATABASE db1; CREATE USER u1@localhost IDENTIFIED BY ''; GRANT SELECT ON db1.* TO u1@localhost; connect conn1,localhost,u1,,db1; SELECT CURRENT_USER; CURRENT_USER u1@localhost SET sql_mode=ORACLE; # # User u1 cannot drop PROCEDURE, PACKAGE, PACKAGE BODY by default # DROP PROCEDURE p1; ERROR 42000: alter routine command denied to user 'u1'@'localhost' for routine 'db1.p1' DROP PACKAGE pkg1; ERROR 42000: alter routine command denied to user 'u1'@'localhost' for routine 'db1.pkg1' DROP PACKAGE BODY pkg1; ERROR 42000: alter routine command denied to user 'u1'@'localhost' for routine 'db1.pkg1' # # User u1 cannot create PROCEDURE, PACKAGE, PACKAGE BODY by default # CREATE PROCEDURE p1 AS BEGIN NULL; END; $$ ERROR 42000: Access denied for user 'u1'@'localhost' to database 'db1' CREATE PACKAGE pkg1 AS PROCEDURE p1; END; $$ ERROR 42000: Access denied for user 'u1'@'localhost' to database 'db1' CREATE PACKAGE BODY pkg1 AS PROCEDURE p1 AS BEGIN NULL; END; END; $$ ERROR 42000: PACKAGE db1.pkg1 does not exist # # Now create a PACKAGE by root # connection default; USE db1; CREATE PROCEDURE p1root AS BEGIN SELECT 1; END; $$ CREATE PACKAGE pkg1 AS PROCEDURE p1; FUNCTION f1 RETURN TEXT; END; $$ SHOW CREATE PACKAGE pkg1; Package sql_mode Create Package character_set_client collation_connection Database Collation pkg1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="root"@"localhost" PACKAGE "pkg1" AS PROCEDURE p1; FUNCTION f1 RETURN TEXT; END latin1 latin1_swedish_ci latin1_swedish_ci # # u1 cannot SHOW yet: # - the standalone procedure earlier created by root # - the package specifications earlier create by root # connection conn1; SHOW CREATE PROCEDURE p1root; ERROR 42000: PROCEDURE p1root does not exist SHOW CREATE PACKAGE pkg1; ERROR 42000: PACKAGE pkg1 does not exist # # User u1 still cannot create a PACKAGE BODY # connection conn1; CREATE PACKAGE BODY pkg1 AS PROCEDURE p1 AS BEGIN NULL; END; FUNCTION f1 RETURN TEXT AS BEGIN RETURN 'This is f1'; END; END; $$ ERROR 42000: Access denied for user 'u1'@'localhost' to database 'db1' # # Now grant EXECUTE: # - on the standalone procedure earlier created by root # - on the package specification earlier created by root # connection default; GRANT EXECUTE ON PROCEDURE db1.p1root TO u1@localhost; GRANT EXECUTE ON PACKAGE db1.pkg1 TO u1@localhost; # # Now u1 can do SHOW for: # - the standalone procedure earlier created by root # - the package specification earlier created by root # disconnect conn1; connect conn1,localhost,u1,,db1; SET sql_mode=ORACLE; SHOW CREATE PROCEDURE db1.p1root; Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation p1root PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT NULL latin1 latin1_swedish_ci latin1_swedish_ci SHOW CREATE PACKAGE db1.pkg1; Package sql_mode Create Package character_set_client collation_connection Database Collation pkg1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT NULL latin1 latin1_swedish_ci latin1_swedish_ci # # Now revoke EXECUTE and grant CREATE ROUTINE instead # connection default; REVOKE EXECUTE ON PROCEDURE db1.p1root FROM u1@localhost; REVOKE EXECUTE ON PACKAGE db1.pkg1 FROM u1@localhost; GRANT CREATE ROUTINE ON db1.* TO u1@localhost; # # Reconnect u1 to make new grants have effect # disconnect conn1; connect conn1,localhost,u1,,db1; SET sql_mode=ORACLE; # # Now u1 can SHOW: # - standalone routines earlier created by root # - package specifications earlier created by root # SHOW CREATE PROCEDURE p1root; Procedure sql_mode Create Procedure character_set_client collation_connection Database Collation p1root PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT NULL latin1 latin1_swedish_ci latin1_swedish_ci SHOW CREATE PACKAGE pkg1; Package sql_mode Create Package character_set_client collation_connection Database Collation pkg1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT NULL latin1 latin1_swedish_ci latin1_swedish_ci # # Now u1 can CREATE, DROP and EXECUTE its own standalone procedures # CREATE PROCEDURE p1 AS BEGIN NULL; END; $$ SHOW GRANTS; Grants for u1@localhost GRANT USAGE ON *.* TO "u1"@"localhost" GRANT SELECT, CREATE ROUTINE ON "db1".* TO "u1"@"localhost" GRANT EXECUTE, ALTER ROUTINE ON PROCEDURE "db1"."p1" TO "u1"@"localhost" CALL p1; DROP PROCEDURE p1; SHOW GRANTS; Grants for u1@localhost GRANT USAGE ON *.* TO "u1"@"localhost" GRANT SELECT, CREATE ROUTINE ON "db1".* TO "u1"@"localhost" # # Now u1 can also CREATE, DROP its own package specifications # CREATE PACKAGE pkg2 AS PROCEDURE p1; FUNCTION f1 RETURN TEXT; END; $$ SHOW CREATE PACKAGE pkg2; Package sql_mode Create Package character_set_client collation_connection Database Collation pkg2 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="u1"@"localhost" PACKAGE "pkg2" AS PROCEDURE p1; FUNCTION f1 RETURN TEXT; END latin1 latin1_swedish_ci latin1_swedish_ci SHOW GRANTS; Grants for u1@localhost GRANT USAGE ON *.* TO "u1"@"localhost" GRANT SELECT, CREATE ROUTINE ON "db1".* TO "u1"@"localhost" GRANT EXECUTE, ALTER ROUTINE ON PACKAGE "db1"."pkg2" TO "u1"@"localhost" DROP PACKAGE pkg2; SHOW GRANTS; Grants for u1@localhost GRANT USAGE ON *.* TO "u1"@"localhost" GRANT SELECT, CREATE ROUTINE ON "db1".* TO "u1"@"localhost" # # Now u1 can also CREATE, DROP package bodies and EXECUTE package body routines # CREATE PACKAGE BODY pkg1 AS PROCEDURE p1 AS BEGIN SELECT 'This is pkg1.p1' AS `comment`; END; FUNCTION f1 RETURN TEXT AS BEGIN RETURN 'This is pkg1.f1'; END; END; $$ SHOW CREATE PACKAGE pkg1; Package sql_mode Create Package character_set_client collation_connection Database Collation pkg1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT NULL latin1 latin1_swedish_ci latin1_swedish_ci SHOW CREATE PACKAGE BODY pkg1; Package body sql_mode Create Package Body character_set_client collation_connection Database Collation pkg1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT CREATE DEFINER="u1"@"localhost" PACKAGE BODY "pkg1" AS PROCEDURE p1 AS BEGIN SELECT 'This is pkg1.p1' AS `comment`; END; FUNCTION f1 RETURN TEXT AS BEGIN RETURN 'This is pkg1.f1'; END; END latin1 latin1_swedish_ci latin1_swedish_ci SHOW GRANTS; Grants for u1@localhost GRANT USAGE ON *.* TO "u1"@"localhost" GRANT SELECT, CREATE ROUTINE ON "db1".* TO "u1"@"localhost" GRANT EXECUTE, ALTER ROUTINE ON PACKAGE BODY "db1"."pkg1" TO "u1"@"localhost" CALL pkg1.p1; comment This is pkg1.p1 SELECT pkg1.f1(); pkg1.f1() This is pkg1.f1 DROP PACKAGE BODY pkg1; SHOW GRANTS; Grants for u1@localhost GRANT USAGE ON *.* TO "u1"@"localhost" GRANT SELECT, CREATE ROUTINE ON "db1".* TO "u1"@"localhost" # # Now create a PACKAGE BODY by root. # u1 does not have EXECUTE access by default. # connection default; CREATE PACKAGE BODY pkg1 AS PROCEDURE p1 AS BEGIN SELECT 'This is pkg1.p1' AS `comment`; END; FUNCTION f1 RETURN TEXT AS BEGIN RETURN 'This is pkg1.f1'; END; END; $$ connection conn1; SHOW CREATE PACKAGE pkg1; Package sql_mode Create Package character_set_client collation_connection Database Collation pkg1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT NULL latin1 latin1_swedish_ci latin1_swedish_ci SHOW CREATE PACKAGE BODY pkg1; Package body sql_mode Create Package Body character_set_client collation_connection Database Collation pkg1 PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ORACLE,NO_KEY_OPTIONS,NO_TABLE_OPTIONS,NO_FIELD_OPTIONS,NO_AUTO_CREATE_USER,SIMULTANEOUS_ASSIGNMENT NULL latin1 latin1_swedish_ci latin1_swedish_ci CALL pkg1.p1; ERROR 42000: execute command denied to user 'u1'@'localhost' for routine 'db1.pkg1' SELECT pkg1.f1(); ERROR 42000: execute command denied to user 'u1'@'localhost' for routine 'db1.pkg1' # # Now grant EXECUTE to u1 on the PACKAGE BODY created by root # connection default; GRANT EXECUTE ON PACKAGE BODY db1.pkg1 TO u1@localhost; disconnect conn1; connect conn1,localhost,u1,,db1; SELECT CURRENT_USER; CURRENT_USER u1@localhost SET sql_mode=ORACLE; SHOW GRANTS; Grants for u1@localhost GRANT USAGE ON *.* TO "u1"@"localhost" GRANT SELECT, CREATE ROUTINE ON "db1".* TO "u1"@"localhost" GRANT EXECUTE ON PACKAGE BODY "db1"."pkg1" TO "u1"@"localhost" CALL pkg1.p1; comment This is pkg1.p1 SELECT pkg1.f1(); pkg1.f1() This is pkg1.f1 connection default; DROP PACKAGE BODY pkg1; # # u1 still cannot DROP the package specification earlier created by root. # connection conn1; DROP PACKAGE pkg1; ERROR 42000: alter routine command denied to user 'u1'@'localhost' for routine 'db1.pkg1' # # Grant ALTER ROUTINE to u1 # connection default; GRANT ALTER ROUTINE ON db1.* TO u1@localhost; # # Now u1 can DROP: # - the standalone procedure earlier created by root # - the package specification earlier created by root # disconnect conn1; connect conn1,localhost,u1,,db1; SET sql_mode=ORACLE; DROP PACKAGE pkg1; DROP PROCEDURE p1root; disconnect conn1; connection default; DROP USER u1@localhost; DROP DATABASE db1; USE test; # # Creator=root, definer=xxx # CREATE USER xxx@localhost; CREATE DEFINER=xxx@localhost PACKAGE p1 AS PROCEDURE p1; END; $$ CREATE DEFINER=xxx@localhost PACKAGE BODY p1 AS PROCEDURE p1 AS BEGIN SELECT SESSION_USER(), CURRENT_USER(), 'p1.p1' AS msg; END; BEGIN SELECT SESSION_USER(), CURRENT_USER(), 'package body p1' AS msg; END; $$ CALL p1.p1; ERROR 42000: execute command denied to user 'xxx'@'localhost' for routine 'test.p1' GRANT EXECUTE ON PACKAGE BODY test.p1 TO xxx@localhost; CALL p1.p1; SESSION_USER() CURRENT_USER() msg root@localhost xxx@localhost package body p1 SESSION_USER() CURRENT_USER() msg root@localhost xxx@localhost p1.p1 DROP PACKAGE p1; DROP USER xxx@localhost; # # Creator=root, definer=xxx, SQL SECURITY INVOKER # CREATE USER xxx@localhost; CREATE DEFINER=xxx@localhost PACKAGE p1 AS PROCEDURE p1; END; $$ CREATE DEFINER=xxx@localhost PACKAGE BODY p1 SQL SECURITY INVOKER AS PROCEDURE p1 AS BEGIN SELECT SESSION_USER(), CURRENT_USER(), 'p1.p1' AS msg; END; BEGIN SELECT SESSION_USER(), CURRENT_USER(), 'package body p1' AS msg; END; $$ CALL p1.p1; SESSION_USER() CURRENT_USER() msg root@localhost root@localhost package body p1 SESSION_USER() CURRENT_USER() msg root@localhost root@localhost p1.p1 DROP PACKAGE p1; DROP USER xxx@localhost;