Oracle 11g manual user authentication - oracle

I need help to create a manual user authentication in Oracle DB 11g.
A separate table is there which contains authorized user names. If the user is not in the table, he will get disconnected with a message stating something like 'you are not authorized' or something.
This the function I created to get return code based on username presence in ref table:
create or replace function user_check return integer is
user_name varchar2(10);
cursor usr is select * from user_ref;
begin
select USERNAME into user_name
from v$session where audsid = sys_context('userenv','sessionid');
for u in usr loop
if u.user_name = user_name then
return 1;
goto out_of_loop;
end if;
end loop;
return 0;
<<out_of_loop>>
null;
end;
/
I am trying to create a trigger as:
create or replace trigger user_verify_trg after logon on database
declare
sid varchar2(10);
serial varchar2(10);
q varchar2(100);
begin
if(gs.user_check = 1) then
select SID, serial# into sid,serial
from v$session where audsid = sys_context('userenv','sessionid');
q := 'alter system kill session '||sid||','||serial;
execute immediate q;
end if;
end;
/
But it's not working. Please help.

Related

"No data found" error during execute the procedure in oracle trigger

i have a trigger in different and want execute procedure for different schema to extract the data.
executing procedure with parameter in trigger is not working.
create or replace TRIGGER TRIGER_LEAD_INSERT
AFTER INSERT ON AT_NEO_CM.LEAD_INFORMATION
FOR EACH ROW
DECLARE
--PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
IF :new.LEAD_REFERENCE_NUMBER IS NOT NULL THEN
AT_NEO_CAS_LMS.PKG_LEAD_DATA.USP_INSERT_NEWAPP(:NEW.LEAD_REFERENCE_NUMBER,:NEW.ID );
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
INSERT INTO LEADDATA VALUES( :NEW.ID, :NEW.LEAD_REFERENCE_NUMBER,2322, 'NO DATA FOUND');
END TRIGER_LEAD_INSERT;
Using a another table in procedure with same primary key which passed in procedure as parameter.
To call a procedure from another schema, you just need to set the right grants:
CREATE USER u1 IDENTIFIED BY u1 QUOTA 1M ON USERS;
CREATE USER u2 IDENTIFIED BY u2 QUOTA 1M ON USERS;
GRANT CONNECT, RESOURCE TO u1;
GRANT CONNECT, RESOURCE TO u2;
User u1 has a procedure p1 and grants it to user u2:
CREATE PROCEDURE p1(p NUMBER) AS BEGIN NULL; END p1;
GRANT EXECUTE ON p1 TO u2;
User u2 can now execute this procedure:
CONNECT u2/u2;
EXEC u1.p1(1);
or use it in a trigger:
CREATE TABLE t2 (id NUMBER);
CREATE OR REPLACE TRIGGER tr2 AFTER INSERT ON t2
FOR EACH ROW
BEGIN
IF :new.id IS NOT NULL THEN
u1.p1(:new.id);
END IF;
END tr2;
/

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 :)

Second statement in begin block is not executed

I have written this stored procedure in Oracle:
CREATE OR REPLACE FUNCTION GET_SOLVER_ID(username_in IN VARCHAR2)
RETURN NUMBER
IS
solver_id number(19);
system_user_id number(19);
BEGIN
SELECT id
INTO solver_id
FROM usr_solver
WHERE username = username_in;
select ID into system_user_id from USR_USER where USER_TYPE = 'X';
solver_id := nvl(solver_id, system_user_id);
RETURN(solver_id);
END;
When I call the function with username that doesn't exist in table usr_solver I get null for the result. I expect to get system_user_id instead.
It seems like the other select statement and nvl function in begin block didn't execute.
Could you help, I can't see the reason why...
Thanks,
mismas
This should do what you want
CREATE OR REPLACE FUNCTION GET_SOLVER_ID(
username_in IN VARCHAR2)
RETURN NUMBER
IS
some_id NUMBER(19);
BEGIN
BEGIN
SELECT id
INTO some_id
FROM usr_solver
WHERE username = username_in;
EXCEPTION
WHEN NO_DATA_FOUND THEN
SELECT ID
INTO some_id
FROM USR_USER
WHERE USER_TYPE = 'X';
END;
RETURN(some_id);
END;

Oracle select inside an IF statement in a stored procedure

Coming from a sql server background, I am trying to get the grasp of oracle syntax. I am trying to return some records back from a stored procedure but getting an error:
CREATE OR REPLACE PROCEDURE SP_GetCustomers(username IN VARCHAR2)
AS
BEGIN
if username = 'all' then
select *
from customers c;
else
select *
from customers c
where c.created_by = username;
end if;
END;
What am I missing?
you are missing an INTO clause, but at this stage its better to use a FUNCTION to return values and a PROCEDURE to perform action.
ORACLE doesn't create implicit cursors as a return parameter, you will have to explicitly declare a ref cursor and open it to return a pointer to a cursor, something like:
CREATE OR REPLACE Function SP_GetCustomers(username IN VARCHAR2) return sys_refcursor
AS
ret_cursor sys_refcursor;
BEGIN
if username = 'all' then
open ret_cursor for
'select *
from customers c';
else
open ret_cursor for
'select *
from customers c
where c.created_by = :username' using username ;
end if;
return ret_cursor;
END;

GRANT DDL in Oracle to specific user

How to grant DDL privileges in oracle ?
On database I've users SCHEMA_1, SCHEMA_2 and SCHEMA_3
and now i want to from schema_1 be able to do DDL only on SCHEMA_2
Is the grant is possible from SCHEMA_2 level or system only ?
Oracle doesn't work that way. You'd have to grant CREATE ANY [OBJECT_TYPE] to that user and have a system event trigger which restricts them from working in the schemas you don't want them to.
Warning: Undocumented / underdocumented features of DBMS_STANDARD are used.
CREATE OR REPLACE TRIGGER schema_1_on_schema_2
before DDL on DATABASE
as
has_dba_priv number;
n number;
stmt ora_name_list_t;
BEGIN
-- exit if user is object owner
if ora_dict_obj_owner = ora_login_user then
return
end if;
-- exit if user has dba directly
select count(*)
into has_dba_priv
from dba_role_privs
where granted_role = 'DBA'
and grantee = ora_login_user;
if has_dba_priv <> 0 then
return;
end if;
-- exit if action is an automatic recompile
stmt := null;
n := ora_sql_txt(sql_text);
FOR i IN 1..n LOOP
stmt := stmt || sql_text(i);
END LOOP;
if stmt like 'ALTER % COMPILE REUSE SETTINGS%' then
return;
end if;
-- you should probably organize this into a database table of permitted
-- schema_x can affect schema_y, but this is a "basic" example
if (ora_dict_obj_owner = 'SCHEMA_2')
and (ora_login_user = 'SCHEMA_1') then
null;
else
raise_application_error (-20000, 'User ' || ora_login_user ||
' is not permitted to execute DDL against ' || ora_dict_obj_owner);
end if;
end;
A better way might be to embed the schema_2 DDL into procedures and grant execute on those procedures to schema_1. A fuller explanation of your requirements may lead to fuller / better answers.

Resources