有没有办法防止(撤消)特权,如:
create table, create package, create function
等,
以用户自己的模式来自用户,但允许他为另一个用户执行这些操作。
例子:
-- connected as DP1
-- will raise an exception
create table dp1.tst (id number);
-- no exception
create table dp2.tst (id number);
谢谢。
答案 0 :(得分:1)
通常这是不可能的。
您可以授予GRANT CREATE TABLE TO DP1
之类的特权,该特权允许用户DP1在其自己的模式中创建表。
或者您可以授予诸如GRANT CREATE ANY TABLE TO DP1
之类的特权,该特权允许用户DP1在任何模式(当然包括他自己的模式)中创建表。
一个解决方案可能是这样的过程:
create or replace procedure DP2.create_table(ddl in varchar2) as
begin
if regexp_like(ddl, '^CREATE TABLE DP2.', 'i') then
execute immediate ddl;
end if;
end;
/
grant execute on DP2.create_table to DP1;
但是,我认为这是一个丑陋的解决方法。 execute immediate ddl
造成潜在的安全漏洞,该过程容易出错。
另一种方法可以是Database Trigger:
GRANT CREATE ANY TABLE TO DP1;
CREATE OR REPLACE TRIGGER CREATE_TABLE_CHECK
BEFORE CREATE ON DATABASE
BEGIN
IF ora_login_user = 'DP1' THEN
IF NOT (ora_dict_obj_owner = 'DP2' AND ora_dict_obj_type = 'TABLE') THEN
RAISE_APPLICATION_ERROR(-20001, 'You are permitted only to create TABLES in schema "DP2"');
END IF;
END IF;
END;
但是您应该更好地查看您的设计要求。
答案 1 :(得分:0)
您可以从DP1撤消那些特权,但是随后允许它们在DP2下管理对象是混乱的,如@Wernfried解释的那样。您还可以将CREATE ANY
特权与DDL触发器一起使用,以使DDL的错误针对DP1模式运行,但这甚至更麻烦,由于它们是如此强大,因此应避免普遍使用ANY
特权。
您可以改为设置代理身份验证:
alter user DP2 grant connect through DP1;
然后代替DP1进行连接:
sqlplus dp1/dp1passwd@db
然后可以按以下方式连接:
sqlplus dp1[dp2]/dp1passwd@db
他们不需要知道DP2的帐户密码-他们仍然使用自己的 帐户密码进行身份验证。传递代理机制意味着,就所有意图和目的而言,它们现在都作为DP2处于会话中。任何DDL都将违反DP2的架构,并且审计跟踪可以显示这些操作是通过代理执行的,并且真实用户(即DP1)是谁。他们将具有DP2的角色和特权,因此即使他们自己的帐户没有创建特权,他们也将能够在该架构中管理对象。
他们甚至无法在自己的DP1模式中看到任何内容(除非他们已授予DP2特权);但是由于在这种情况下他们什么都不拥有,所以这是有争议的。
这当然不仅可以从SQL * Plus中获得,您还可以在OCI,JDBC等上使用它。