Skip to Main Content
  • Questions
  • Oracle - grant package access not wotking for inner tables

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Matheus.

Asked: February 02, 2017 - 6:01 pm UTC

Last updated: November 08, 2024 - 5:39 pm UTC

Version: Oracle 11g

Viewed 10K+ times! This question is

You Asked

Hi!

I have two Users on a same Oracle Instance, APP and TRDP. The user APP is a third-party user and the TRDP is one of my own. So the APP user have a package (API) which receives three parameters and updates an internal table. During the processing of this package, it does a series of validations e.g.: check status of the document which I'm trying to update, raise internal workflow events and those validations requires access to some other tables. I have granted EXECUTE on this API from APP user to TRDP user and also created a Synonym on TRDP user for this Package. And my problem now is: in order to run this Package I have to grant select on all subsquent objects it uses. So, for example, I have to grant select on workflow tables, on sequences, on other tables which I don't intend to use.

I looked everywhere for this situation, but for all I know and could find, the Oracle Database grants that I don't need to "know" about the objects this Package uses as long as I have grant to execute it.

I couldn't find any Database parameter that requires me to grant access on each subsequent object, still I have to manually grant access on each object that this API uses.

If someone had gone through this, can I have some advice, please?

Thanks in advance!

and Connor said...

By default, you dont need access to the tables, eg

SQL> create user APP identified by APP;

User created.

SQL> alter user app quota 100m on users;

User altered.

SQL>
SQL> create table app.t1 ( x int );

Table created.

SQL> create table app.t2 ( x int );

Table created.

SQL> create table app.t3 ( x int );

Table created.

SQL>
SQL> create or replace
  2  procedure app.p is
  3  begin
  4    insert into t1 values (1);
  5    insert into t2 values (1);
  6    insert into t3 values (1);
  7  end;
  8  /

Procedure created.

SQL>
SQL> grant execute on app.p to scott;

Grant succeeded.


I now connect as SCOTT and I can run the proc without issue, *even though* I still do not have access to the underlying objects.

SQL> conn scott/tiger
Connected.

SQL> exec app.p

PL/SQL procedure successfully completed.

SQL>
SQL> delete from app.t1;
delete from app.t1
                *
ERROR at line 1:
ORA-00942: table or view does not exist



The procedure (by default) runs with the privileges of the owner of the procedure. The procedure *may* have been defined as authid current user, which means it runs with privilege of the person *executing* the procedure. In this case, you would need access on the underlying tables directly. A DBA can list all of tables owned by APP and grant access to your user.

Rating

  (3 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Thanks

Matheus, February 03, 2017 - 10:58 am UTC

Thank you for your answer. Indeed the API package I was calling have the authid current_user in its declaration. Many thanks for your fast and clear reply.
Connor McDonald
February 03, 2017 - 7:31 pm UTC

glad we could help

Invoking SQL Macro Package

Zahir Mohideen, November 06, 2024 - 3:37 pm UTC

I am trying to use Macro in a package and grant execute privs to another user ( in my case , rptuser).

DBUSER has a table , regular package , SQL macro package.
Both are with DEFINER rights .
Also , learn that , we can't have a SQL macro package with invoker rights.

When I execute the "regular" package from another user, I get the results as expected.
When I execute the "SQL Macro" package from another , I get "invalid permissions" ( ORA-00942).

Here is my test case below.
Am I misunderstanding about the usage of "SQL Macro" package ?

DB Version 
----------
SQL> select banner from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production


DBUSER
-------

Here , I am creating tables and packages under "DBUSER".

create table emp ( eid int , ename varchar2(50) ) 

insert into emp values ( 100 , 'Zahir Mohideen') ;
insert into emp values ( 101 , 'Abdul Hameed') ;

commit;

create or replace package pkg_emp
as
    procedure listemp( p_eid  int , rfc_emp OUT SYS_REFCURSOR );
end pkg_emp;
/

CREATE OR REPLACE PACKAGE BODY pkg_emp AS
    PROCEDURE listemp (
        p_eid   INT,
        rfc_emp OUT SYS_REFCURSOR
    ) AS
    BEGIN
        OPEN rfc_emp FOR SELECT
                                              ename
                                          FROM
                                              dbuser.emp
                         WHERE
                             eid = p_eid;

    END listemp;
END pkg_emp;
/

create or replace package pkg_emp_mac
as
    FUNCTION listemp ( p_eid  int  )   RETURN VARCHAR2 SQL_MACRO ;
end pkg_emp_mac;
/

CREATE OR REPLACE PACKAGE BODY pkg_emp_mac AS
      FUNCTION listemp ( p_eid  int  )   RETURN VARCHAR2 SQL_MACRO 
       IS
      BEGIN
          
          RETURN q'{
          Select  ename from emp where eid = p_eid           
      }';
     END;
END pkg_emp_mac
;
/

grant execute on pkg_emp_mac to rptuser;
grant execute on pkg_emp to rptuser;


Here , I am executing package calls as "RPTUSER"

SQL> show user
USER is "RPTUSER"
SQL> var x refcursor;


SQL> exec dbuser.pkg_emp.listemp( 100 , :x);

PL/SQL procedure successfully completed.

SQL> print :x;

ENAME
--------------------------------------------------
Zahir Mohideen

SQL> select * from dbuser.pkg_emp_mac.listemp(100);
select * from dbuser.pkg_emp_mac.listemp(100)
                                            *
ERROR at line 1:
ORA-00942: table or view does not exist

Chris Saxon
November 07, 2024 - 1:27 pm UTC

The text returned by a SQL macro becomes part of the parent SQL statement.

So:
select * from dbuser.pkg_emp_mac.listemp(100);


is equivalent to
Select  ename from dbuser.emp where eid = 100


To call the macro, RPTUSER needs the same privileges as it would to run the underlying query - so READ/SELECT on dbuser.emp in this example

On SQL macro equivalency

Mikhail Velikikh, November 08, 2024 - 11:12 am UTC

> is equivalent to
> Select ename from dbuser.emp where eid = 100

It is not.
One can use event trace[ptf_comp] to trace SQL macro expansions.
Here it is a simple SQL text returned by the function being parsed as RPTUSER.
Thus, RPTUSER tries to resolve the name EMP under his schema.
Therefore, it is really equivalent to:

Select ename from emp where eid = p_eid

which is parsed under the RPTUSER schema.

Chris Saxon
November 08, 2024 - 5:39 pm UTC

Ah yes, you're right - it does resolve objects to the current user's schema.

p_eid will resolve to whatever value is passed for this, so

select * from dbuser.pkg_emp_mac.listemp(100);


becomes:

Select ename from emp where eid = 100

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library