我想向用户授予CREATE ANY DIRECTORY
权限,但有以下限制:此用户创建的所有目录必须位于/foo/bar
内,并且任何在此之外创建目录的尝试都应该失败,出现权限错误。我如何在Oracle 11G或12C上执行此操作?
答案 0 :(得分:2)
这取决于,如果要限制Oracle可以从utl_file命令访问哪些OS目录,则可以设置utl_file_dir
参数。不幸的是,此参数是系统范围的,因此您无法使用此参数为特定用户授予/撤消。另请注意,如果您对此参数进行了更改,那么这些更改将在Oracle数据库重新启动之前生效:
alter system set utl_file_dir = '/foo/bar' scope=spfile;
shutdown immediate;
startup open;
有关utl_file_dir
的详细信息,请参阅12.1 Oracle Docs。
也就是说,如果你真的想限制谁可以创建Oracle目录到特定的操作系统目录,那么一个过程适合于该任务,因为这样可以让你获得更精细的控制(并限制谁具有非常强大的{{ 1}}对过程所有者的特权):
create any directory
答案 1 :(得分:1)
您可以在触发器中包含此限制。系统事件和属性列表Working with system events
CREATE OR REPLACE TRIGGER trg_before_ddl
BEFORE DDL ON DATABASE
declare
v_sql ORA_NAME_LIST_T;
v_ddl varchar2(4000);
v_cnt BINARY_INTEGER;
is_valid number;
begin
if ora_sysevent in ('CREATE') and ora_dict_obj_type = 'DIRECTORY' then
v_cnt := ora_sql_txt (v_sql);
FOR i IN 1..v_cnt LOOP
v_ddl := v_ddl || RTRIM (v_sql (i), CHR (0));
END LOOP;
v_ddl := regexp_substr(v_ddl,'AS ''(.*)''', 1, 1, 'i', 1 ); -- get path from ddl_statement
-- check valid directory here, path is in v_ddl ;
is_valid := REGEXP_instr(v_ddl,'^/valid_dir/.*$');
if (is_valid = 0) then
raise_application_error(-20000,'Directory is not valid' || v_ddl);
end if;
end if;
END;
/
CREATE DIRECTORY valid_dir AS '/valid_dir/xyz';
CREATE DIRECTORY invalid_dir AS '/invalid_dir/xyz';