На днях возникла проблема отслеживания прав на объекты. Привилегии в базе Oracle делятся на системные, объектные, ролевые. Отдельно заслуживают внимания так называемый пользователь Public и синонимы.
Для примера создадим трёх пользователей с таблицами и пакетами. Выдадим объектные привилегии юзерам на таблицу, колонку в таблице, на спецификации пакетов. Какие-то права определим конкретно (только просмотр или только редактирование). В число примеров включим грантование юзеру Public и на синонимы без прав на сами объекты.
-- создаём юзеров с системными привилегиями
CREATE USER USER1
IDENTIFIED BY **** --Password hidden
/
GRANT CONNECT TO USER1
/
GRANT RESOURCE TO USER1
/
GRANT CREATE PROCEDURE TO USER1
/
GRANT CREATE SYNONYM TO USER1
/
GRANT CREATE TABLE TO USER1
/
GRANT UNLIMITED TABLESPACE TO USER1
/
CREATE USER USER2
IDENTIFIED BY **** --Password hidden
/
GRANT CONNECT TO USER2
/
GRANT RESOURCE TO USER2
/
GRANT CREATE PROCEDURE TO USER2
/
GRANT CREATE SYNONYM TO USER2
/
GRANT CREATE TABLE TO USER2
/
GRANT UNLIMITED TABLESPACE TO USER2
/
CREATE USER USER3
IDENTIFIED BY **** --Password hidden
/
GRANT CONNECT TO USER3
/
GRANT RESOURCE TO USER3
/
GRANT CREATE PROCEDURE TO USER3
/
GRANT CREATE PUBLIC SYNONYM TO USER3
/
GRANT CREATE SYNONYM TO USER3
/
GRANT CREATE TABLE TO USER3
/
GRANT UNLIMITED TABLESPACE TO USER3
/
--создаём роли и выдаём юзерам
CREATE ROLE ROLE_PRC_TBL
/
GRANT ROLE_PRC_TBL TO USER1
/
CREATE ROLE ROLE_ROLE_TBL
/
GRANT ROLE_ROLE_TBL TO USER3
/
CREATE ROLE ROLE_TBL
/
GRANT ROLE_TBL TO ROLE_ROLE_TBL
/
GRANT ROLE_TBL TO USER2
/
--создаём объекты в схемах, синонимы на некоторые и выдаём объектные привилегии
connect user1
/
CREATE TABLE USER1.US1_TB1
(
US1TB1COL1 VARCHAR2(10 BYTE) NULL,
US1TB1COL2 NUMBER(5,0) NULL,
US1TB1COL3 DATE NULL
)
/
GRANT DELETE, INSERT, SELECT, UPDATE ON USER1.US1_TB1 TO ROLE_TBL
/
CREATE OR REPLACE PACKAGE USER1.us1pkg1
AS
PROCEDURE us1pkg1prc1;
FUNCTION us1pkg1fun1 RETURN VARCHAR2;
END;
/
GRANT DEBUG, EXECUTE ON USER1.US1PKG1 TO USER3
/
CREATE OR REPLACE PACKAGE BODY USER1.us1pkg1
AS
PROCEDURE us1pkg1prc1 IS
BEGIN
dbms_output.put_line('us1pkg1prc1');
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
FUNCTION us1pkg1fun1 RETURN VARCHAR2 IS
BEGIN
return 'yes us1pkg1fun1';
END;
END;
/
CREATE OR REPLACE SYNONYM USER1.SYN_US1PKG1 FOR USER1.US1PKG1
/
CREATE TABLE USER2.US2_TB1
(
US2TB1COL1 VARCHAR2(10 BYTE) NULL,
US2TB1COL2 NUMBER(5,0) NULL,
US2TB1COL3 DATE NULL
)
/
GRANT SELECT ON USER2.US2_TB1 TO ROLE_PRC_TBL
/
CREATE TABLE USER2.US2_TB2
(
US2TB2COL1 VARCHAR2(10 BYTE) NULL,
US2TB2COL2 NUMBER(5,0) NULL,
US2TB2COL3 DATE NULL
)
/
CREATE OR REPLACE SYNONYM USER2.SYN_US2_TB2 FOR USER2.US2_TB2
/
CREATE OR REPLACE PACKAGE USER2.us2pkg1
AS
PROCEDURE us2pkg1prc1 (prm1 in number);
FUNCTION us2pkg1fun1 (prm2 in number) RETURN VARCHAR2;
END;
/
GRANT EXECUTE ON USER2.US2PKG1 TO ROLE_PRC_TBL
/
CREATE OR REPLACE PACKAGE BODY USER2.us2pkg1
AS
PROCEDURE us2pkg1prc1 (prm1 in number) IS
BEGIN
dbms_output.put_line('us2pkg1prc1 '||to_char(prm1));
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
FUNCTION us2pkg1fun1 (prm2 in number) RETURN VARCHAR2 IS
BEGIN
return 'us2pkg1fun1'||to_char(prm2);
END;
END;
/
CREATE OR REPLACE PACKAGE USER2.us2pkg2
AS
PROCEDURE us2pkg2prc1 (prm3 in number, prm4 in date);
FUNCTION us2pkg2fun1 (prm5 in number, prm6 in number) RETURN VARCHAR2;
END;
/
GRANT DEBUG ON USER2.US2PKG2 TO USER1
/
GRANT DEBUG ON USER2.US2PKG2 TO USER3
/
CREATE OR REPLACE PACKAGE BODY USER2.us2pkg2
AS
PROCEDURE us2pkg2prc1 (prm3 in number, prm4 in date) IS
BEGIN
dbms_output.put_line('us2pkg2prc1 '||to_char(prm3));
END;
FUNCTION us2pkg2fun1 (prm5 in number, prm6 in number) RETURN VARCHAR2 IS
BEGIN
return 'us2pkg2fun1'||to_char(prm5);
END;
END;
/
CREATE TABLE USER3.US3_TB1
(
US3TB1COL1 VARCHAR2(10 BYTE) NULL,
US3TB1COL2 NUMBER(5,0) NULL,
US3TB1COL3 DATE NULL
)
/
CREATE TABLE USER3.US3_TB2
(
US3TB2COL1 VARCHAR2(10 BYTE) NULL,
US3TB2COL2 NUMBER(5,0) NULL,
US3TB2COL3 DATE NULL
)
/
GRANT SELECT ON USER3.US3_TB2 TO USER1
/
CREATE TABLE USER3.US3_TB3
(
US3TB3COL1 VARCHAR2(10 BYTE) NULL,
US3TB3COL2 NUMBER(5,0) NULL,
US3TB3COL3 DATE NULL
)
/
CREATE OR REPLACE PACKAGE USER3.us3pkg1
AS
PROCEDURE us3pkg1prc1;
FUNCTION us3pkg1fun1 RETURN VARCHAR2;
END;
/
CREATE OR REPLACE PACKAGE BODY USER3.us3pkg1
AS
PROCEDURE us3pkg1prc1 IS
BEGIN
dbms_output.put_line('us3pkg1prc1');
END;
FUNCTION us3pkg1fun1 RETURN VARCHAR2 IS
BEGIN
return 'us3pkg1fun1';
END;
END;
/
CREATE OR REPLACE PACKAGE USER3.us3pkg2
AS
PROCEDURE us3pkg2prc1 (prm7 in number);
FUNCTION us3pkg2fun1 (prm8 in date) RETURN VARCHAR2;
END;
/
GRANT EXECUTE ON USER3.US3PKG2 TO USER1
/
CREATE OR REPLACE PACKAGE BODY USER3.us3pkg2
AS
PROCEDURE us3pkg2prc1 (prm7 in number) IS
BEGIN
dbms_output.put_line('us3pkg2prc1 '||to_char(prm7));
END;
FUNCTION us3pkg2fun1 (prm8 in date) RETURN VARCHAR2 IS
BEGIN
return 'yes us3pkg2fun1';
END;
END;
/
CREATE OR REPLACE PACKAGE USER3.us3pkg3
AS
PROCEDURE us3pkg3prc1;
FUNCTION us3pkg3fun1 RETURN VARCHAR2;
PROCEDURE us3pkg3prc2;
FUNCTION us3pkg3fun2 RETURN VARCHAR2;
END;
/
GRANT DEBUG, EXECUTE ON USER3.US3PKG3 TO USER1
/
GRANT DEBUG, EXECUTE ON USER3.US3PKG3 TO USER2
/
CREATE OR REPLACE PACKAGE BODY USER3.us3pkg3
AS
PROCEDURE us3pkg3prc1 IS
BEGIN
dbms_output.put_line('us3pkg3prc1');
END;
FUNCTION us3pkg3fun1 RETURN VARCHAR2 IS
BEGIN
return 'us3pkg3fun1';
END;
PROCEDURE us3pkg3prc2 IS
BEGIN
dbms_output.put_line('us3pkg3prc2');
END;
FUNCTION us3pkg3fun2 RETURN VARCHAR2 IS
BEGIN
dbms_output.put_line('yes us3pkg3fun2');
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('no us3pkg3fun2');
END;
END;
/
--создаём public синонимы и позже выдаём права
CREATE OR REPLACE PUBLIC SYNONYM SYN_P_US3_TB1 FOR USER3.US3_TB1
/
CREATE OR REPLACE PUBLIC SYNONYM SYN_P_US3PKG1 FOR USER3.US3PKG1
/
GRANT DELETE, INSERT, SELECT, UPDATE ON SYN_P_US3_TB1 TO PUBLIC
/
GRANT DEBUG, EXECUTE ON SYN_P_US3PKG1 TO PUBLIC
/
К сожалению, моя попытка отследить все зависимости с помощью ClearDB (для доки были взяты все объекты трёх рабочих схем, пользовательские роли и public синонимы, всем доступным диаграммам выставлены уровни DB и третий порядок вложенности, включены все свойства объектов) ограничилась лишь R&D диаграммой, построенной по вьюверам "SYS.ALL(DBA)_REFS" "SYS.ALL(DBA)_DEPENDENCIES".
ER диаграмма и CRUD2 матрица оказались пусты, Call Tree диаграммы - бесполезны. Пришлось рисовать вручную.
По диаграмме, построенной на данных системных вьюверов ("SYS.ALL(DBA)_TAB_PRIVS", "SYS.TABLE_PRIVILEGES", "SYS.COLUMN_PRIVILEGES", "SYS.DBA_PUBLISHED_COLUMNS", "SYS.DBA_ROLE_PRIVS", "SYS.PUBLICSYN", "SYS.ROLE_ROLE_PRIVS" и других) легче понять, какой юзер сможет воспользоваться данными и в каком объёме. По ней очевидными стали результаты нижеследующих скриптов.
-----------сессия первого юзера
connect user1
/
BEGIN USER3.US3PKG3.US3PKG3PRC2; END;
select USER3.US3PKG3.US3PKG3FUN1() from dual;
BEGIN USER3.US3PKG2.US3PKG2PRC1(:PRM7 /* IN - NUMBER */ ); END;
select USER3.US3PKG2.US3PKG2FUN1(sysdate) from dual;
--ORA-06550: line 2, column 3:
--PLS-00201: identifier 'SYN_P_US3PKG1' must be declared
----BUT OK after GRANT ALL PRIVILEGES ON SYN_P_US3PKG1 TO public
BEGIN syn_p_us3pkg1.US3PKG1PRC1; END;
--ORA-00904: : invalid identifier
----BUT OK after GRANT ALL PRIVILEGES ON SYN_P_US3PKG1 TO public
select syn_p_us3pkg1.US3PKG1FUN1 from dual;
--редактировать можно только одну колонку, но в CodeAssistant (SQL Editor или Stored Program Editor в SQLDetective) можно просмотреть структуру всей таблицы
insert into USER3.US3_TB3(US3TB3COL1) values (:US3TB3COL1 /* IN - NUMBER */ );
UPDATE USER3.US3_TB3 SET US3TB3COL1 = :US3TB3COL1 /* IN - NUMBER */ ;
SELECT * FROM USER3.US3_TB2 ;
--ORA-00942: table or view does not exist
----BUT OK after GRANT ALL PRIVILEGES ON SYN_P_US3_TB1 TO public
SELECT * FROM USER3.US3_TB1 ;
--ORA-00942: table or view does not exist
----BUT OK after GRANT ALL PRIVILEGES ON SYN_P_US3_TB1 TO public
SELECT * FROM SYN_P_US3_TB1;
--PLS-00904: insufficient privilege to access object USER2.US2PKG2
--available DDL viewing
BEGIN USER2.US2PKG2.US2PKG2PRC1(:PRM3 /* IN - NUMBER */ , :PRM4 /* IN - DATE */ ); END;
--ORA-01031: insufficient privileges
--available DDL viewing
SELECT USER2.US2PKG2.US2PKG2FUN1(:prm5 /* in number */, :prm6 /* in number */ ) FROM dual;
BEGIN USER2.US2PKG1.US2PKG1PRC1(:PRM1 /* IN - NUMBER */ ); END;
select USER2.US2PKG1.US2PKG1FUN1(:prm2 /* in number */) from dual;
SELECT * FROM USER2.US2_TB1 ;
-------------------сессия второго юзера
connect user2
/
BEGIN USER3.US3PKG3.US3PKG3PRC2; END;
select USER3.US3PKG3.US3PKG3FUN1() from dual;
--PLS-00201: identifier 'USER3.US3PKG2' must be declared
BEGIN USER3.US3PKG2.US3PKG2PRC1(:PRM7 /* IN - NUMBER */ ); END;
--ORA-00904: : invalid identifier
select USER3.US3PKG2.US3PKG2FUN1(sysdate) from dual;
--ORA-06550: line 2, column 3:
--PLS-00201: identifier 'SYN_P_US3PKG1' must be declared
----BUT OK after GRANT ALL PRIVILEGES ON SYN_p_US3pkg1 TO public
BEGIN syn_p_us3pkg1.US3PKG1PRC1; END;
--ORA-00904: : invalid identifier
----BUT OK after GRANT ALL PRIVILEGES ON SYN_p_US3pkg1 TO public
select syn_p_us3pkg1.US3PKG1FUN1 from dual;
--ORA-00942: table or view does not exist
insert into USER3.US3_TB3(US3TB3COL1) values (:US3TB3COL1 /* IN - NUMBER */ );
--ORA-00942: table or view does not exist
UPDATE USER3.US3_TB3 SET US3TB3COL1 = :US3TB3COL1 /* IN - NUMBER */ ;
--ORA-00942: table or view does not exist
SELECT * FROM USER3.US3_TB2 ;
--ORA-00942: table or view does not exist
----BUT OK after GRANT ALL PRIVILEGES ON SYN_P_US3_TB1 TO public
SELECT * FROM USER3.US3_TB1 ;
--ORA-00942: table or view does not exist
----BUT OK after GRANT ALL PRIVILEGES ON SYN_P_US3_TB1 TO public
SELECT * FROM SYN_P_US3_TB1;
--PLS-00201: identifier 'USER1.US1PKG1' must be declared
BEGIN USER1.US1PKG1.US1PKG1PRC1; END;
--ORA-00904: : invalid identifier
select USER1.US1PKG1.US1PKG1FUN1 from dual;
SELECT A.* FROM USER1.US1_TB1 A;
INSERT INTO USER1.US1_TB1(US1TB1COL1, US1TB1COL2, US1TB1COL3) VALUES (:US1TB1COL1, :US1TB1COL2, :US1TB1COL3);
UPDATE USER1.US1_TB1 SET US1TB1COL1 = :US1TB1COL1, US1TB1COL2 = :US1TB1COL2, US1TB1COL3 = :US1TB1COL3;
DELETE FROM USER1.US1_TB1;
--------------------------сессия третьего юзера
connect user 3
/
--PLS-00904: insufficient privilege to access object USER2.US2PKG2
--available DDL viewing
BEGIN USER2.US2PKG2.US2PKG2PRC1(:PRM3 /* IN - NUMBER */ , :PRM4 /* IN - DATE */ ); END;
--ORA-01031: insufficient privileges
--available DDL viewing
SELECT USER2.US2PKG2.US2PKG2FUN1(:prm5 /* in number */, :prm6 /* in number */ ) FROM dual;
--PLS-00201: identifier 'USER2.US2PKG1' must be declared
--no DDL viewing
BEGIN USER2.US2PKG1.US2PKG1PRC1(:PRM1 /* IN - NUMBER */ ); END;
--ORA-00904: : invalid identifier
--no DDL viewing
select USER2.US2PKG1.US2PKG1FUN1(:prm2 /* in number */) from dual;
--ORA-00942: table or view does not exist
SELECT * FROM USER2.US2_TB1 ;
BEGIN USER1.US1PKG1.US1PKG1PRC1; END;
select USER1.US1PKG1.US1PKG1FUN1 from dual;
INSERT INTO USER1.US1_TB1(US1TB1COL1, US1TB1COL2, US1TB1COL3) VALUES (:US1TB1COL1, :US1TB1COL2, :US1TB1COL3);
UPDATE USER1.US1_TB1 SET US1TB1COL1 = :US1TB1COL1, US1TB1COL2 = :US1TB1COL2, US1TB1COL3 = :US1TB1COL3;
DELETE FROM USER1.US1_TB1;
----зелёным шрифтом помечены удачные попытки выполнения, а красным - проблемные доступы к объектам
А у вас есть визуализатор привилегий?
Для примера создадим трёх пользователей с таблицами и пакетами. Выдадим объектные привилегии юзерам на таблицу, колонку в таблице, на спецификации пакетов. Какие-то права определим конкретно (только просмотр или только редактирование). В число примеров включим грантование юзеру Public и на синонимы без прав на сами объекты.
-- создаём юзеров с системными привилегиями
CREATE USER USER1
IDENTIFIED BY **** --Password hidden
/
GRANT CONNECT TO USER1
/
GRANT RESOURCE TO USER1
/
GRANT CREATE PROCEDURE TO USER1
/
GRANT CREATE SYNONYM TO USER1
/
GRANT CREATE TABLE TO USER1
/
GRANT UNLIMITED TABLESPACE TO USER1
/
CREATE USER USER2
IDENTIFIED BY **** --Password hidden
/
GRANT CONNECT TO USER2
/
GRANT RESOURCE TO USER2
/
GRANT CREATE PROCEDURE TO USER2
/
GRANT CREATE SYNONYM TO USER2
/
GRANT CREATE TABLE TO USER2
/
GRANT UNLIMITED TABLESPACE TO USER2
/
CREATE USER USER3
IDENTIFIED BY **** --Password hidden
/
GRANT CONNECT TO USER3
/
GRANT RESOURCE TO USER3
/
GRANT CREATE PROCEDURE TO USER3
/
GRANT CREATE PUBLIC SYNONYM TO USER3
/
GRANT CREATE SYNONYM TO USER3
/
GRANT CREATE TABLE TO USER3
/
GRANT UNLIMITED TABLESPACE TO USER3
/
--создаём роли и выдаём юзерам
CREATE ROLE ROLE_PRC_TBL
/
GRANT ROLE_PRC_TBL TO USER1
/
CREATE ROLE ROLE_ROLE_TBL
/
GRANT ROLE_ROLE_TBL TO USER3
/
CREATE ROLE ROLE_TBL
/
GRANT ROLE_TBL TO ROLE_ROLE_TBL
/
GRANT ROLE_TBL TO USER2
/
--создаём объекты в схемах, синонимы на некоторые и выдаём объектные привилегии
connect user1
/
CREATE TABLE USER1.US1_TB1
(
US1TB1COL1 VARCHAR2(10 BYTE) NULL,
US1TB1COL2 NUMBER(5,0) NULL,
US1TB1COL3 DATE NULL
)
/
GRANT DELETE, INSERT, SELECT, UPDATE ON USER1.US1_TB1 TO ROLE_TBL
/
CREATE OR REPLACE PACKAGE USER1.us1pkg1
AS
PROCEDURE us1pkg1prc1;
FUNCTION us1pkg1fun1 RETURN VARCHAR2;
END;
/
GRANT DEBUG, EXECUTE ON USER1.US1PKG1 TO USER3
/
CREATE OR REPLACE PACKAGE BODY USER1.us1pkg1
AS
PROCEDURE us1pkg1prc1 IS
BEGIN
dbms_output.put_line('us1pkg1prc1');
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
FUNCTION us1pkg1fun1 RETURN VARCHAR2 IS
BEGIN
return 'yes us1pkg1fun1';
END;
END;
/
CREATE OR REPLACE SYNONYM USER1.SYN_US1PKG1 FOR USER1.US1PKG1
/
CREATE TABLE USER2.US2_TB1
(
US2TB1COL1 VARCHAR2(10 BYTE) NULL,
US2TB1COL2 NUMBER(5,0) NULL,
US2TB1COL3 DATE NULL
)
/
GRANT SELECT ON USER2.US2_TB1 TO ROLE_PRC_TBL
/
CREATE TABLE USER2.US2_TB2
(
US2TB2COL1 VARCHAR2(10 BYTE) NULL,
US2TB2COL2 NUMBER(5,0) NULL,
US2TB2COL3 DATE NULL
)
/
CREATE OR REPLACE SYNONYM USER2.SYN_US2_TB2 FOR USER2.US2_TB2
/
CREATE OR REPLACE PACKAGE USER2.us2pkg1
AS
PROCEDURE us2pkg1prc1 (prm1 in number);
FUNCTION us2pkg1fun1 (prm2 in number) RETURN VARCHAR2;
END;
/
GRANT EXECUTE ON USER2.US2PKG1 TO ROLE_PRC_TBL
/
CREATE OR REPLACE PACKAGE BODY USER2.us2pkg1
AS
PROCEDURE us2pkg1prc1 (prm1 in number) IS
BEGIN
dbms_output.put_line('us2pkg1prc1 '||to_char(prm1));
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
FUNCTION us2pkg1fun1 (prm2 in number) RETURN VARCHAR2 IS
BEGIN
return 'us2pkg1fun1'||to_char(prm2);
END;
END;
/
CREATE OR REPLACE PACKAGE USER2.us2pkg2
AS
PROCEDURE us2pkg2prc1 (prm3 in number, prm4 in date);
FUNCTION us2pkg2fun1 (prm5 in number, prm6 in number) RETURN VARCHAR2;
END;
/
GRANT DEBUG ON USER2.US2PKG2 TO USER1
/
GRANT DEBUG ON USER2.US2PKG2 TO USER3
/
CREATE OR REPLACE PACKAGE BODY USER2.us2pkg2
AS
PROCEDURE us2pkg2prc1 (prm3 in number, prm4 in date) IS
BEGIN
dbms_output.put_line('us2pkg2prc1 '||to_char(prm3));
END;
FUNCTION us2pkg2fun1 (prm5 in number, prm6 in number) RETURN VARCHAR2 IS
BEGIN
return 'us2pkg2fun1'||to_char(prm5);
END;
END;
/
CREATE TABLE USER3.US3_TB1
(
US3TB1COL1 VARCHAR2(10 BYTE) NULL,
US3TB1COL2 NUMBER(5,0) NULL,
US3TB1COL3 DATE NULL
)
/
CREATE TABLE USER3.US3_TB2
(
US3TB2COL1 VARCHAR2(10 BYTE) NULL,
US3TB2COL2 NUMBER(5,0) NULL,
US3TB2COL3 DATE NULL
)
/
GRANT SELECT ON USER3.US3_TB2 TO USER1
/
CREATE TABLE USER3.US3_TB3
(
US3TB3COL1 VARCHAR2(10 BYTE) NULL,
US3TB3COL2 NUMBER(5,0) NULL,
US3TB3COL3 DATE NULL
)
/
CREATE OR REPLACE PACKAGE USER3.us3pkg1
AS
PROCEDURE us3pkg1prc1;
FUNCTION us3pkg1fun1 RETURN VARCHAR2;
END;
/
CREATE OR REPLACE PACKAGE BODY USER3.us3pkg1
AS
PROCEDURE us3pkg1prc1 IS
BEGIN
dbms_output.put_line('us3pkg1prc1');
END;
FUNCTION us3pkg1fun1 RETURN VARCHAR2 IS
BEGIN
return 'us3pkg1fun1';
END;
END;
/
CREATE OR REPLACE PACKAGE USER3.us3pkg2
AS
PROCEDURE us3pkg2prc1 (prm7 in number);
FUNCTION us3pkg2fun1 (prm8 in date) RETURN VARCHAR2;
END;
/
GRANT EXECUTE ON USER3.US3PKG2 TO USER1
/
CREATE OR REPLACE PACKAGE BODY USER3.us3pkg2
AS
PROCEDURE us3pkg2prc1 (prm7 in number) IS
BEGIN
dbms_output.put_line('us3pkg2prc1 '||to_char(prm7));
END;
FUNCTION us3pkg2fun1 (prm8 in date) RETURN VARCHAR2 IS
BEGIN
return 'yes us3pkg2fun1';
END;
END;
/
CREATE OR REPLACE PACKAGE USER3.us3pkg3
AS
PROCEDURE us3pkg3prc1;
FUNCTION us3pkg3fun1 RETURN VARCHAR2;
PROCEDURE us3pkg3prc2;
FUNCTION us3pkg3fun2 RETURN VARCHAR2;
END;
/
GRANT DEBUG, EXECUTE ON USER3.US3PKG3 TO USER1
/
GRANT DEBUG, EXECUTE ON USER3.US3PKG3 TO USER2
/
CREATE OR REPLACE PACKAGE BODY USER3.us3pkg3
AS
PROCEDURE us3pkg3prc1 IS
BEGIN
dbms_output.put_line('us3pkg3prc1');
END;
FUNCTION us3pkg3fun1 RETURN VARCHAR2 IS
BEGIN
return 'us3pkg3fun1';
END;
PROCEDURE us3pkg3prc2 IS
BEGIN
dbms_output.put_line('us3pkg3prc2');
END;
FUNCTION us3pkg3fun2 RETURN VARCHAR2 IS
BEGIN
dbms_output.put_line('yes us3pkg3fun2');
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('no us3pkg3fun2');
END;
END;
/
--создаём public синонимы и позже выдаём права
CREATE OR REPLACE PUBLIC SYNONYM SYN_P_US3_TB1 FOR USER3.US3_TB1
/
CREATE OR REPLACE PUBLIC SYNONYM SYN_P_US3PKG1 FOR USER3.US3PKG1
/
GRANT DELETE, INSERT, SELECT, UPDATE ON SYN_P_US3_TB1 TO PUBLIC
/
GRANT DEBUG, EXECUTE ON SYN_P_US3PKG1 TO PUBLIC
/
К сожалению, моя попытка отследить все зависимости с помощью ClearDB (для доки были взяты все объекты трёх рабочих схем, пользовательские роли и public синонимы, всем доступным диаграммам выставлены уровни DB и третий порядок вложенности, включены все свойства объектов) ограничилась лишь R&D диаграммой, построенной по вьюверам "SYS.ALL(DBA)_REFS" "SYS.ALL(DBA)_DEPENDENCIES".
ER диаграмма и CRUD2 матрица оказались пусты, Call Tree диаграммы - бесполезны. Пришлось рисовать вручную.
По диаграмме, построенной на данных системных вьюверов ("SYS.ALL(DBA)_TAB_PRIVS", "SYS.TABLE_PRIVILEGES", "SYS.COLUMN_PRIVILEGES", "SYS.DBA_PUBLISHED_COLUMNS", "SYS.DBA_ROLE_PRIVS", "SYS.PUBLICSYN", "SYS.ROLE_ROLE_PRIVS" и других) легче понять, какой юзер сможет воспользоваться данными и в каком объёме. По ней очевидными стали результаты нижеследующих скриптов.
-----------сессия первого юзера
connect user1
/
BEGIN USER3.US3PKG3.US3PKG3PRC2; END;
select USER3.US3PKG3.US3PKG3FUN1() from dual;
BEGIN USER3.US3PKG2.US3PKG2PRC1(:PRM7 /* IN - NUMBER */ ); END;
select USER3.US3PKG2.US3PKG2FUN1(sysdate) from dual;
--ORA-06550: line 2, column 3:
--PLS-00201: identifier 'SYN_P_US3PKG1' must be declared
----BUT OK after GRANT ALL PRIVILEGES ON SYN_P_US3PKG1 TO public
BEGIN syn_p_us3pkg1.US3PKG1PRC1; END;
--ORA-00904: : invalid identifier
----BUT OK after GRANT ALL PRIVILEGES ON SYN_P_US3PKG1 TO public
select syn_p_us3pkg1.US3PKG1FUN1 from dual;
--редактировать можно только одну колонку, но в CodeAssistant (SQL Editor или Stored Program Editor в SQLDetective) можно просмотреть структуру всей таблицы
insert into USER3.US3_TB3(US3TB3COL1) values (:US3TB3COL1 /* IN - NUMBER */ );
UPDATE USER3.US3_TB3 SET US3TB3COL1 = :US3TB3COL1 /* IN - NUMBER */ ;
SELECT * FROM USER3.US3_TB2 ;
--ORA-00942: table or view does not exist
----BUT OK after GRANT ALL PRIVILEGES ON SYN_P_US3_TB1 TO public
SELECT * FROM USER3.US3_TB1 ;
--ORA-00942: table or view does not exist
----BUT OK after GRANT ALL PRIVILEGES ON SYN_P_US3_TB1 TO public
SELECT * FROM SYN_P_US3_TB1;
--PLS-00904: insufficient privilege to access object USER2.US2PKG2
--available DDL viewing
BEGIN USER2.US2PKG2.US2PKG2PRC1(:PRM3 /* IN - NUMBER */ , :PRM4 /* IN - DATE */ ); END;
--ORA-01031: insufficient privileges
--available DDL viewing
SELECT USER2.US2PKG2.US2PKG2FUN1(:prm5 /* in number */, :prm6 /* in number */ ) FROM dual;
BEGIN USER2.US2PKG1.US2PKG1PRC1(:PRM1 /* IN - NUMBER */ ); END;
select USER2.US2PKG1.US2PKG1FUN1(:prm2 /* in number */) from dual;
SELECT * FROM USER2.US2_TB1 ;
-------------------сессия второго юзера
connect user2
/
BEGIN USER3.US3PKG3.US3PKG3PRC2; END;
select USER3.US3PKG3.US3PKG3FUN1() from dual;
--PLS-00201: identifier 'USER3.US3PKG2' must be declared
BEGIN USER3.US3PKG2.US3PKG2PRC1(:PRM7 /* IN - NUMBER */ ); END;
--ORA-00904: : invalid identifier
select USER3.US3PKG2.US3PKG2FUN1(sysdate) from dual;
--ORA-06550: line 2, column 3:
--PLS-00201: identifier 'SYN_P_US3PKG1' must be declared
----BUT OK after GRANT ALL PRIVILEGES ON SYN_p_US3pkg1 TO public
BEGIN syn_p_us3pkg1.US3PKG1PRC1; END;
--ORA-00904: : invalid identifier
----BUT OK after GRANT ALL PRIVILEGES ON SYN_p_US3pkg1 TO public
select syn_p_us3pkg1.US3PKG1FUN1 from dual;
--ORA-00942: table or view does not exist
insert into USER3.US3_TB3(US3TB3COL1) values (:US3TB3COL1 /* IN - NUMBER */ );
--ORA-00942: table or view does not exist
UPDATE USER3.US3_TB3 SET US3TB3COL1 = :US3TB3COL1 /* IN - NUMBER */ ;
--ORA-00942: table or view does not exist
SELECT * FROM USER3.US3_TB2 ;
--ORA-00942: table or view does not exist
----BUT OK after GRANT ALL PRIVILEGES ON SYN_P_US3_TB1 TO public
SELECT * FROM USER3.US3_TB1 ;
--ORA-00942: table or view does not exist
----BUT OK after GRANT ALL PRIVILEGES ON SYN_P_US3_TB1 TO public
SELECT * FROM SYN_P_US3_TB1;
--PLS-00201: identifier 'USER1.US1PKG1' must be declared
BEGIN USER1.US1PKG1.US1PKG1PRC1; END;
--ORA-00904: : invalid identifier
select USER1.US1PKG1.US1PKG1FUN1 from dual;
SELECT A.* FROM USER1.US1_TB1 A;
INSERT INTO USER1.US1_TB1(US1TB1COL1, US1TB1COL2, US1TB1COL3) VALUES (:US1TB1COL1, :US1TB1COL2, :US1TB1COL3);
UPDATE USER1.US1_TB1 SET US1TB1COL1 = :US1TB1COL1, US1TB1COL2 = :US1TB1COL2, US1TB1COL3 = :US1TB1COL3;
DELETE FROM USER1.US1_TB1;
--------------------------сессия третьего юзера
connect user 3
/
--PLS-00904: insufficient privilege to access object USER2.US2PKG2
--available DDL viewing
BEGIN USER2.US2PKG2.US2PKG2PRC1(:PRM3 /* IN - NUMBER */ , :PRM4 /* IN - DATE */ ); END;
--ORA-01031: insufficient privileges
--available DDL viewing
SELECT USER2.US2PKG2.US2PKG2FUN1(:prm5 /* in number */, :prm6 /* in number */ ) FROM dual;
--PLS-00201: identifier 'USER2.US2PKG1' must be declared
--no DDL viewing
BEGIN USER2.US2PKG1.US2PKG1PRC1(:PRM1 /* IN - NUMBER */ ); END;
--ORA-00904: : invalid identifier
--no DDL viewing
select USER2.US2PKG1.US2PKG1FUN1(:prm2 /* in number */) from dual;
--ORA-00942: table or view does not exist
SELECT * FROM USER2.US2_TB1 ;
BEGIN USER1.US1PKG1.US1PKG1PRC1; END;
select USER1.US1PKG1.US1PKG1FUN1 from dual;
INSERT INTO USER1.US1_TB1(US1TB1COL1, US1TB1COL2, US1TB1COL3) VALUES (:US1TB1COL1, :US1TB1COL2, :US1TB1COL3);
UPDATE USER1.US1_TB1 SET US1TB1COL1 = :US1TB1COL1, US1TB1COL2 = :US1TB1COL2, US1TB1COL3 = :US1TB1COL3;
DELETE FROM USER1.US1_TB1;
----зелёным шрифтом помечены удачные попытки выполнения, а красным - проблемные доступы к объектам
No comments:
Post a Comment