Oracle How to grant CREATE ANY DIRECTORY with the restriction that all directories must be created inside a given directory?

核能气质少年 提交于 2019-12-12 21:36:12

问题


I want to grant the CREATE ANY DIRECTORY permission to a user, with the following restriction: all directories created by this user must be inside of /foo/bar, and any attempt to create a directory outside of this should fail with a permission error. How may I do this on Oracle 11G or 12C?


回答1:


That depends, if you want to restrict which OS directories Oracle can access from utl_file commands, you can set the utl_file_dir parameter. Unfortunately, this parameter is system wide, so you won't be able to grant/revoke for a specific user using this parameter. Also keep in mind that if you make changes to this parameter, those changes won't go into effect until the Oracle database is restarted:

alter system set utl_file_dir = '/foo/bar' scope=spfile;
shutdown immediate;
startup open;

Consult the 12.1 Oracle Docs for more information regarding utl_file_dir.

That said, if you really want to restrict who can create Oracle Directories to specific OS directories, a procedure would be appropriate for that task since that would allow you to have finer grained control (and limit who has the very powerful create any directory privilege to the owner of the procedure):

sqlplus kjohnston

create or replace procedure mydircreate (p_dir varchar2)
as
  ex_custom EXCEPTION;
  PRAGMA EXCEPTION_INIT( ex_custom, -20001 );
begin
  if lower(p_dir) not like '/foo/bar/%' then
    raise_application_error( -20001, 'Not authorized' );
  end if;

  execute immediate 'create or replace directory mydir as ''' || p_dir || '''';
end mydircreate;

create user testuser identified by <password>;
grant create session to testuser;
grant execute on kjohnston.mydircreate to testuser;

exit;

sqlplus testuser

SQL> exec kjohnston.mydircreate('mydir', '/randomdir');
ORA-20001: Not authorized

SQL> exec kjohnston.mydircreate('mydir', '/foo/bar/baz');
PL/SQL procedure successfully completed.



回答2:


You can include this restriction in trigger. List of system events and attributes 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';


来源:https://stackoverflow.com/questions/44142383/oracle-how-to-grant-create-any-directory-with-the-restriction-that-all-directori

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!