insufficient INHERIT PRIVILEGES privilege error in oracle - oracle

i was trying to get some information from a stored video inoracle dba ,
while executiong this script :
DECLARE
vid_data BFILE := BFILENAME('EXT_DIR','video.mp4');
mimeType VARCHAR2(80);
format VARCHAR2(32) := NULL;
width NUMBER;
height NUMBER;
frameResolution NUMBER;
frameRate NUMBER;
videoDuration NUMBER;
numberOfFrames NUMBER;
compressionType VARCHAR2(160);
numberOfColors NUMBER;
bitRate NUMBER;
BEGIN
-- get properties from bfile
ORDSYS.ORD_VIDEO.getProperties(vid_data, mimeType, format,
width, height, frameResolution, frameRate,
videoDuration, numberOfFrames, compressionType,
numberOfColors, bitRate);
-- print properties
DBMS_OUTPUT.PUT_LINE('mimeType: ' || mimeType );
DBMS_OUTPUT.PUT_LINE('format: ' || format );
DBMS_OUTPUT.PUT_LINE('width: ' || width );
DBMS_OUTPUT.PUT_LINE('height: ' || height );
DBMS_OUTPUT.PUT_LINE('frameResolution: ' || frameResolution );
DBMS_OUTPUT.PUT_LINE('frameRate: ' || frameRate );
DBMS_OUTPUT.PUT_LINE('videoDuration: ' || videoDuration );
DBMS_OUTPUT.PUT_LINE('numberOfFrames: ' || numberOfFrames );
DBMS_OUTPUT.PUT_LINE('compressionType: ' || compressionType );
DBMS_OUTPUT.PUT_LINE('numberOfColors: ' || numberOfColors );
DBMS_OUTPUT.PUT_LINE('bitRate: ' || bitRate );
EXCEPTION
WHEN OTHERS THEN
RAISE;
END;
/
here is the full error :
Error report -
ORA-06598: insufficient INHERIT PRIVILEGES privilege
ORA-06512: at line 37
ORA-06512: at "ORDSYS.ORD_VIDEO", line 50
ORA-06512: at line 17
06598. 00000 - "insufficient INHERIT PRIVILEGES privilege"
*Cause: An attempt was made to run an AUTHID CURRENT_USER function or
procedure, or to reference a BEQUEATH CURRENT_USER view, and the
owner of that function, procedure, or view lacks INHERIT PRIVILEGES
privilege on the calling user.
*Action: Either do not call the function or procedure or reference the view,
or grant the owner of the function, procedure, or view
INHERIT PRIVILEGES privilege on the calling user.

The error ORA-06598: insufficient INHERIT PRIVILEGES privilege is warning you about a possible privilege escalation issue. You have a more powerful user calling a package owned by a less powerful user. That situation isn't normally a problem, but in this case the package being called includes AUTHID CURRENT_USER, which means the package runs with the more powerful user's privileges.
To indicate to Oracle that you trust the less powerful user not to abuse the elevated privileges, you have to allow it to inherit the privileges with a command like this (assuming you are running the PL/SQL block as SYS):
GRANT INHERIT PRIVILEGES ON USER SYS TO ORDSYS;

Related

Oracle: Permissions to dir

I run the write_test procedure, which works good.
begin
koll_data_pkg.write_test(p_customer_id=>247, p_addr=>'address', p_dir=>'\\SERVER01\Backup\Log\');
end;
But, when I change value of p_dir to another directory p_dir=>\SERVER12\Backup\Log\ it gives following error:
ORA-29283: invalid file operation
ORA-06512: by "SYS.UTL_FILE",
ORA-29283: invalid file operation
ORA-06512: by "DATA_PKG",
ORA-06512: by line
I have tried give permission using following commands, but still same error:
CREATE OR REPLACE DIRECTORY DEVO_INVREC_DIR AS '\\SERVER12\Backup\Log\';
GRANT READ, WRITE ON DIRECTORY DEVO_INVREC_DIR TO USER1;
GRANT READ, WRITE ON DIRECTORY DEVO_INVREC_DIR TO USER1;
GRANT EXECUTE ON UTL_FILE TO USER1;
Procedure:
procedure write_test(p_customer_id in koll_customer_party.customer_id%type,
p_addr in varchar,
p_dir in varchar,
p_filename in varchar2 default null)
is
lt_id id_tt;
lt_bolagsnamn bolagsnamn_tt;
l_file utl_file.file_type;
l_line varchar2(2048);
l_name varchar2(300):= 'DEVO_INVREC_DIR';
l_filename varchar2(100):= 'testfile.txt';
l_sql varchar2(512);
begin
select devo_id, bolagsnamn
bulk collect into lt_id, lt_bolagsnamn
from documents where customer_id=p_customer_id
if lt_id.count > 0 then
l_sql := 'create or replace directory ' || l_name || ' as ''' || p_dir || '''';
execute immediate l_sql;
if p_filename is not null then
l_filename := p_filename;
end if;
l_file := utl_file.fopen(l_name,l_filename,'w');
if utl_file.is_open(l_file) is not null then
for i in lt_id.first .. lt_devo_id.last loop
l_line:= lt_id(i) || ';' || replace(lt_bolagsnamn(i),';','');
utl_file.put_line(l_file, l_line);
end loop;
end if;
utl_file.fclose(l_file);
end if;
end;
Check out this forum response: https://community.oracle.com/thread/4145239?start=0&tstart=0
In summary, Oracle can't access the network shares in its default installed configuration because the Windows SYSTEM user can't access network shares by definition. You either have to reconfigure Oracle to run as a user other than SYSTEM, with permissions on the share, or allow SYSTEM to access network shares (a HUGE security risk). I was going to include a link describing how to change the user to be another service account, but they all seem to be broken or removed. It may depend on your exact version of Oracle and Windows, too, so you're best bet in the absence of other documentation would be to contact Oracle Support. There is no simple PL/SQL programming answer to your problem.

ORA-01031: insufficient privileges when executing rebuild index from Stored Procedure [duplicate]

Here is the definition of the stored procedure:
CREATE OR REPLACE PROCEDURE usp_dropTable(schema VARCHAR, tblToDrop VARCHAR) IS
BEGIN
DECLARE v_cnt NUMBER;
BEGIN
SELECT COUNT(*)
INTO v_cnt
FROM all_tables
WHERE owner = schema
AND table_name = tblToDrop;
IF v_cnt > 0 THEN
EXECUTE IMMEDIATE('DROP TABLE someschema.some_table PURGE');
END IF;
END;
END;
Here is the call:
CALL usp_dropTable('SOMESCHEMA', 'SOME_TABLE');
For some reason, I keep getting insufficient privileges error for the EXECUTE IMMEDIATE command. I looked online and found out that the insufficient privileges error usually means the oracle user account does not have privileges for the command used in the query that is passes, which in this case is DROP. However, I have drop privileges. I am really confused and I can't seem to find a solution that works for me.
Thanks to you in advance.
SOLUTION:
As Steve mentioned below, Oracle security model is weird in that it needs to know explicitly somewhere in the procedure what kind of privileges to use. The way to let Oracle know that is to use AUTHID keyword in the CREATE OR REPLACE statement. If you want the same level of privileges as the creator of the procedure, you use AUTHID DEFINER. If you want Oracle to use the privileges of the user currently running the stored procedure, you want to use AUTHID CURRENT_USER. The procedure declaration looks as follows:
CREATE OR REPLACE PROCEDURE usp_dropTable(schema VARCHAR, tblToDrop VARCHAR)
AUTHID CURRENT_USER IS
BEGIN
DECLARE v_cnt NUMBER;
BEGIN
SELECT COUNT(*)
INTO v_cnt
FROM all_tables
WHERE owner = schema
AND table_name = tblToDrop;
IF v_cnt > 0 THEN
EXECUTE IMMEDIATE('DROP TABLE someschema.some_table PURGE');
END IF;
END;
END;
Thank you everyone for responding. This was definitely very annoying problem to get to the solution.
Oracle's security model is such that when executing dynamic SQL using Execute Immediate (inside the context of a PL/SQL block or procedure), the user does not have privileges to objects or commands that are granted via role membership. Your user likely has "DBA" role or something similar. You must explicitly grant "drop table" permissions to this user. The same would apply if you were trying to select from tables in another schema (such as sys or system) - you would need to grant explicit SELECT privileges on that table to this user.
You should use this example with AUTHID CURRENT_USER :
CREATE OR REPLACE PROCEDURE Create_sequence_for_tab (VAR_TAB_NAME IN VARCHAR2)
AUTHID CURRENT_USER
IS
SEQ_NAME VARCHAR2 (100);
FINAL_QUERY VARCHAR2 (100);
COUNT_NUMBER NUMBER := 0;
cur_id NUMBER;
BEGIN
SEQ_NAME := 'SEQ_' || VAR_TAB_NAME;
SELECT COUNT (*)
INTO COUNT_NUMBER
FROM USER_SEQUENCES
WHERE SEQUENCE_NAME = SEQ_NAME;
DBMS_OUTPUT.PUT_LINE (SEQ_NAME || '>' || COUNT_NUMBER);
IF COUNT_NUMBER = 0
THEN
--DBMS_OUTPUT.PUT_LINE('DROP SEQUENCE ' || SEQ_NAME);
-- EXECUTE IMMEDIATE 'DROP SEQUENCE ' || SEQ_NAME;
-- ELSE
SELECT 'CREATE SEQUENCE COMPTABILITE.' || SEQ_NAME || ' START WITH ' || ROUND (DBMS_RANDOM.VALUE (100000000000, 999999999999), 0) || ' INCREMENT BY 1'
INTO FINAL_QUERY
FROM DUAL;
DBMS_OUTPUT.PUT_LINE (FINAL_QUERY);
cur_id := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.parse (cur_id, FINAL_QUERY, DBMS_SQL.v7);
DBMS_SQL.CLOSE_CURSOR (cur_id);
-- EXECUTE IMMEDIATE FINAL_QUERY;
END IF;
COMMIT;
END;
/
you could use "AUTHID CURRENT_USER" in body of your procedure definition for your requirements.
Alternatively you can grant the user DROP_ANY_TABLE privilege if need be and the procedure will run as is without the need for any alteration. Dangerous maybe but depends what you're doing :)

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

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?
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.
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';

Procedure being created but doesn't work

DECLARE
BEGIN
FOR s IN ( SELECT first_name
FROM EA_marketing_table
WHERE town = 'LONDON'
)
LOOP
EXECUTE IMMEDIATE 'CREATE USER ' ||(s.first_name)|| ' IDENTIFIED BY LOL';
dbms_output.put_line (s.first_name || ' IDENTIFIED BY LOL');
END LOOP;
END;
/
I am trying to create a user and the code above lets me create a user but when I try to create a procedure it wont work.
This is the new code
CREATE OR REPLACE PROCEDURE proc_it_development AS
first_name VARCHAR2 (25);
BEGIN
FOR r IN ( SELECT first_name
FROM EA_marketing_table
WHERE town = 'lONDON ')
LOOP
EXECUTE IMMEDIATE 'CREATE USER '||(r.first_name)|| ' IDENTIFIED BY POOP ';
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN dbms_output.put_line ('r SELECT...INTO did not return any row.');
END;
/
any help please?
:)
Roles are not enabled in procedures/packages so you need to get the privilege granted to your user directly. Most likely you are connecting through a user that has been given the CREATE USER privilege via a role (eg: the DBA role?)
To see what you can do in a procedure, you can disable the active roles for your current session:
set role none
then try your first code block. If it works, it will also work in a procedure.
To create a new schema with a procedure you will need the privilege granted directly to your schema:
GRANT CREATE USER TO <your_schema>;
You should enclose the password in double-quotes, in Oracle 11 passwords are case-sensitive by default. Then you only create a user without any privilege, i.e.CREATE SESSION Privilege is missing.

Execute Immediate Alter User Bind Variable

The following procedure:
create or replace
PROCEDURE ChangePassword
(
p_Name VARCHAR2,
p_Password VARCHAR2
)
AS
EXECUTE IMMEDIATE 'ALTER USER :a IDENTIFIED BY :b' USING p_Name, p_Password;
END;
compiles successfuly, but when executed:
exec ChangePassword('TestUser', 'newPassword');
results in error:
01935. 00000 - "missing user or role name"
*Cause: A user or role name was expected.
*Action: Specify a user or role name.
Why?
You can't use bind variables in place of identifiers, such as the user name in this statement. The value of the identifier needs to be known when the statement is parsed, whereas a bind value is incorporated after parsing, before execution.
I think that the following would work
create or replace PROCEDURE ChangePassword(p_Name IN VARCHAR2,
p_Old_password IN VARCHAR2,
p_New_password IN VARCHAR2)
AS
EXECUTE IMMEDIATE 'ALTER USER ' || p_name ||
' IDENTIFIED BY ' || p_New_password ||
' REPLACE ' || p_Old_password;
END;
Share and enjoy.

Resources