Oracle如何授予CREATE ANY DIRECTORY限制,必须在给定目录中创建所有目录?

时间:2017-05-23 18:25:32

标签: oracle oracle11g oracle12c

我想向用户授予CREATE ANY DIRECTORY权限,但有以下限制:此用户创建的所有目录必须位于/foo/bar内,并且任何在此之外创建目录的尝试都应该失败,出现权限错误。我如何在Oracle 11G或12C上执行此操作?

2 个答案:

答案 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';