Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, BharathKumar.

Asked: February 02, 2001 - 11:36 am UTC

Last updated: February 28, 2013 - 7:54 am UTC

Version: 8.1.6

Viewed 10K+ times! This question is

You Asked

I have an application which has its backend data on one schema in the database. Should I use the same username password combination for all clients or should I create individual ID's and make the users access the schema objects using public synonyms ?

If I use the synonym method, do I have a way of granting all access permissions on all objects to all the users using a single command ? (I know I can do this using a PL/SQL procedure using Dynamic SQL, but I want to know a single command). If I do it once during installation of the application, how do I ensure the grant of the similar rights to objects created later on the schema as part of the maintenance/upgrade of the application ?

Expecting a detailed reply.....

Thanks and Regards

Bharath

and Tom said...

see
</code> http://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:1344402741490 <code>
for a very very similar discussion and suggested solution.

You should either

o let everyone log in as themselves (i like this myself, total accountability)

o let people log in as various "roles" -- have many different schemas representing differing levels of functionality in your application (i've never seen an application where EVERYONE has the same rights and priveleges).

You do not need and I would not recommend public synonyms in any case.

Your application will have many roles associated with it -- lets for example use just two

- end_user
- admin_user

Your application setup will grant the appropriate privileges to each role. Perhaps table T1 is SELECTable by end_user and SELECTable and INSERTable by admin_user. You would:

o grant select on t to end_user_role;
o grant select, insert on t to admin_user_role;

You would do this for each object, granting the MINIMUM privelege the prople needed for the given role. Never over grant (else end_user will find some way to delete all of your data someday and it'll be your fault when they do).

Now, if you go the path of everyone logs in as themselves -- you simply grant the appropriate role to each user as you create their account. If the set of privs needs to change over time, change the set of privs the role has and you are done, all users are updated.

If you got the path of everyone logs in as some set of users, then you will grant each role needed to each of those users.


As for the synonyms -- don't use them. Make the first line of your application after connecting be (you could even use a database LOGIN trigger to effect this if you always want the default schema to be your application) :

alter session set current_schema = YOUR_APPLICATION_SCHEMA;

Now, if they issue:

select * from T;

instead of us interpreting that as:

select * from CURRENT_USERNAME.T;

we will execute:

select * from YOUR_APPLICATION_SCHEMA.T;

this command does not change your privilege set, it only alters the default schema we use to resolve non fully qualified references.

Again, I like a user/schema in that way I can tell exactly who did what and when via auditing (either my own auditing or using the system auditing capabilities).

Also, i would suggest using stored procedures to implement your logic and only granting EXECUTE on procedures and perhaps SELECT on tables (for reporting) -- never granting INSERT, UPDATE, or DELETE on any table at any time. In that fashion, you are gauranteed that only YOUR application can modify the tables -- end users will not be able to use some odbc tool to "accidently" destroy your data.

detailed enough?


Rating

  (43 ratings)

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

Comments

VERY USEFUL

ARUN KHANNA, June 26, 2002 - 7:16 am UTC

HI TOM
WHICH PRIVILIGES CAN NOT BE GRANTED TO ROLES.

THANKX IN ADVANCE

Tom Kyte
June 26, 2002 - 8:29 am UTC

unlimited tablespace

is the only one.

Yes... "detailed enough"

Robert, June 26, 2002 - 2:50 pm UTC

Tom,

I've never heard of 'set current_schema', this is very good.

I particularly appriciate your sharing your philosophy of design, etc.

Can you please give some information, why you don't like public synonyms?

Thanks,

Robert.

Tom Kyte
June 26, 2002 - 3:36 pm UTC

There are performance implications

Most importantly there are namespace clashes. I'm a big fan of "stick as many apps in my database as you can". If they all want a public synonym "S", we are in a heap of trouble.

Having problems with public synonym

Ken, November 26, 2002 - 12:14 pm UTC

hi Tom,
We've a data warehouse using Informatica as the ETL tool where we are trying to truncate a table in the STAGE schema from the EDR schema without prefixing the table with its schema name(STAGE), but it is not allowed in Oracle:

STAGE>Create table ken_test(id number)
/

STAGE>grant select, update, alter, delete on ken_test to EDR
/

STAGE> Create public synonym ken_test for STAGE.KEN_TEST
/

DBA> grant drop any table to EDR
/

EDR> truncate table ken_test
/
ORA-00942: table or view does not exist

EDR> truncate table STAGE.ken_test
/
Statement processed in 0.161sec

Because the truncate option is provided in Informatica and we can't alter its SQL, we couldn't prefix the schema name there.

We could do this in a store procedure, but just want to hear your opinion?

Thanks as always Ken.

Tom Kyte
November 26, 2002 - 12:52 pm UTC

Yah, you won't be able to do that. 

truncate will not work on a synonym.
truncate will not work on a view.

it is that way by design.  you must be explicit with ddl.

ops$tkyte@ORA920.US.ORACLE.COM> create synonym x for scott.emp;

Synonym created.

ops$tkyte@ORA920.US.ORACLE.COM> select * from x;

     EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------
      7369 SMITH      CLERK           7902 17-DEC-80        800                    20
      7499 ALLEN      SALESMAN        7698 20-FEB-81       1600        300         30
      7521 WARD       SALESMAN        7698 22-FEB-81       1250        500         30
      7566 JONES      MANAGER         7839 02-APR-81       2975                    20
      7654 MARTIN     SALESMAN        7698 28-SEP-81       1250       1400         30
      7698 BLAKE      MANAGER         7839 01-MAY-81       2850                    30
      7782 CLARK      MANAGER         7839 09-JUN-81       2450                    10
      7788 SCOTT      ANALYST         7566 19-APR-87       3000                    20
      7839 KING       PRESIDENT            17-NOV-81       5000                    10
      7844 TURNER     SALESMAN        7698 08-SEP-81       1500          0         30
      7876 ADAMS      CLERK           7788 23-MAY-87       1100                    20
      7900 JAMES      CLERK           7698 03-DEC-81        950                    30
      7902 FORD       ANALYST         7566 03-DEC-81       3000                    20
      7934 MILLER     CLERK           7782 23-JAN-82       1300                    10

14 rows selected.

ops$tkyte@ORA920.US.ORACLE.COM> drop table x;
drop table x
           *
ERROR at line 1:
ORA-00942: table or view does not exist


ops$tkyte@ORA920.US.ORACLE.COM> drop table scott.emp;

Table dropped.




it would be the cause of much heartburn otherwise. "whoops, I didn't know it was THAT table".

stored procedure will work. 

SUBBARAO, November 26, 2002 - 10:51 pm UTC

Hi Tom,
The discussion on this article is very interesting. In my current system, I have nearly 700-800 application users accessing my database. all these users fall into 4 categories and the access rights are given at the application leve. When the user logins, based on his login id they will have access to only some screens in the application.So they cant insert or update the data in other module tables.

This has been done already and system is running fine and will not change in this security.

If we were planned to handle this from backend, how we should exactly go about.

My Thinking in this regard is like this: Grant priviliges to the roles. So that i will create 4 roles. Now the issue is how to grant these roles to the users. As my users are 700+, do i need to create 700+ users in the database and then assign the roles to them. Iam not clear in this, can u explain.

SUBBARAO

Tom Kyte
November 27, 2002 - 7:07 am UTC

If you were to use database user accounts and roles, yes, you would create 700+ users and grant to them.

Then, you have the ability to know exactly who did what, when and where.



Very Very Useful

abhijit, November 26, 2002 - 11:39 pm UTC

Good and useful.
Could you tell me if there is a way to set the current_schema by default to some other schema whenever the user logs in?

Thanks,
Abhijit

Tom Kyte
November 27, 2002 - 7:09 am UTC

Using a ON LOGON schema trigger would work. See the appllication developers guide for details on that.

SUBBARAO, November 27, 2002 - 8:43 pm UTC

hi Tom,

U told "Then, you have the ability to know exactly who did what, when and where."

Will this be any performance drain, if it exceeds a certain number of users. What can be the maximum number of users.(this is just for enthusiasm). Can u tell me any example in any live systems with this kind of setup. And for tracking who did what and when, we need to enable auditing right? will this also be the performance issue. If we want some thing we need to scarifice some things, we can bare the little performance drain in this auditing. Please comment.


Tom Kyte
November 28, 2002 - 7:48 am UTC

Nothing is a performance issue if it is a requirement of your system.  I always love it when people say "auditing is a performance issue".  No, no it is not.  Auditing is either something you need to do (like putting an order in an order table is something you NEED to do in an order entry system -- it is NOT a performance issue that you have to insert) or something you don't need to do.  It is not a performance issue.

Auditing takes more resources then not auditing.  However, if auditing is something you have to do -- then you have to do it.


metalink has 6 figures worth of database users (i remember when we had to upgrade it from 7.3 which only supported 64k users to 8.0 with 2billion max users -- there was a while we could not add new metalink accounts).

My own internal database at Oracle that I run has 

ops$tkyte@ORA9I.WORLD> select count(*) from all_users;

  COUNT(*)
----------
     49800


runs just dandy. 

A few disagreements

Tony, November 29, 2002 - 1:26 am UTC

I have a few doubts here though your approach is interesting.


1. As per your suggestion, we have to create as many db users as we want to access a single main schema(user) where we have all our application tables. We have to use
alter session set current_schema = YOUR_APPLICATION_SCHEMA to change the default schema whenever the users log in. In this approach, the users will not be able to access their own tables/objects, if they have any, without <schema>.<username> syntax. How to overcome this problem?

2. For client server applications like D2K, this approach will be good as D2K checks the privilage before executing any query/DML and throws proper error message. What if we use VB or other web tools ASP, JSP, etc.? How to write easy logic to disable/ enable buttons or links in web pages based on their privilage?. Is it feasible first of all?

3. In my view, web applications have single schema and application users are created at the application level. Roles (who to access , what links(menu) to access) are also created at the application level and assigned to the users. So, access control is done at the application level. This seems more flexible and maintainable and logical. In your approach, is it possible to do so? will be happy if you give an example.

4. Is it easy to grant selectivily on each object to each user when the schema has thousands of tables and new tables are getting added frequently?

5. What if a databas has many main schemas to have tables/objects for many applications and these schema are accessed by thousands of users. How to differentiate the users from one app to other apps in case if I want to check all these from my front-end tool.

6. Is there any licence issues on number of users we create in oracle database?

Expecting your valuable comments.














Tom Kyte
November 29, 2002 - 10:08 am UTC

1) not sure what I'm comparing this to? Having a single schema -- if so, they wouldn't have any of their own tables. Having public synonyms for this other data? if so, confusion abounds. If they (the user) creates a table as the same name as the public synonym -- what then?

Me, personally, I've never had an issue with using SCHEMA names. Tools that generate queries have NO PROBLEMS using the schema name.

To me, this is much ado about nothing. Users don't log into sqlplus and start querying - -they use tools, they use stored queries (views). this is mostly hidden from them.

2) web tools like jsp's, servlets, etc are just as capable as client server things as far as security goes. The same things d2k would do -- you would do in asp. I see no differences there.

3) More flexible to you, maybe.

Heinous, terrible, "hate it" to me.

So, do you think this web thing is the last application development paradigm??? It is the end right -- there will be nothing else.

Tell me -- how is is more flexible? Lets see, database has "create user" command - you can write code to do a "create user" in your applicaiton. Database has create role and grant, application has to code create role and grant. Database does auditing, application has to code auditing. (you see where I am going -- you are emulating the database functionality you already bought).

I guess, if by flexible you mean "It lets me write more code", you are right. If by flexible you mean "I get more functionality" -- i have yet to see it. You are developing YET ANOTHER authentication/authorization method. Do you do single sign on? Database can. Do you do advanced authentication methods like x509 PKI? Database can. Do you have so many spare cycles that writing identification and authorization and auditing and access control is something you can do? Great -- I don't.

Flexible? 3 years from now the next great programming paradigm comes along. Oh sorry you say -- cannot do it cause all of the security is tied up in the application and none of it is by the data. You can only access the data via my old fashioned application - -you cannot build new apps on top of the data using this new paradigm. All of a sudden, your cool web app is as appealing as a 3278 Green screen application from a mainframe. You know, the green screen apps

o did identification
o authorization
o access controls
o auditing

all tied up in the code.... Hmmm, guess what was really hard to migrate to client server and then web and then <next really cool programming method here>


Can I use an ad-hoc query tool against your data? What -- I cannot??? Bummer, seems to me that any time I put up a database application -- the end users say "cool, but what I really need to see is X". Well, if I have I&A, access control -- everything tied up in the application -- i cannot let them have at the data now can i? Guess it is really good for job security -- need more data, new reports? I'll be the only one that can do it for you.

Web applications are not special, they are not different, it is the same old thing on three tiers. You can make the same mistakes that were made with host based and client server systems all over again.

4) And it is easier in your application HOW??? If you have thousands of tables/functions -- it is easier in your "flexible" environment HOW??

5) Read about n-tier proxy authentication, read about fine grained access control. That does exactly that. Secure application roles plus security policies in place by application.

6) 2 billion.

Disagreements

Tony Andrews, November 29, 2002 - 10:35 am UTC

> 3) More flexible to you, maybe.
>
> Heinous, terrible, "hate it" to me.

You are so right! This is a message that really needs to be hammered home to the web / OO community. They get so wrapped up in how cool their tools are, they seem to think a database is just a bucket to put their data in while the app isn't running. The only DBMS features they want to use are INSERT, UPDATE, SELECT and DELETE - they don't even like database integrity much, let alone security. Gets in the way of doing it "their way", which of course being web/OO based is assumed to be far superior.

Web-based apps are just the latest way of providing a user interface to the data. Managing the data is still (should be) the job of the DBMS.


A reader, February 13, 2003 - 12:44 pm UTC

But what about the overhead of opening individual sessions every time a user access data? To establish a connection, it takes few seconds and that is considered toomuch on web applications. That is why connection pooling and application servers are invented. I don't understand how the two (ie. connection pooling and having individual database users) can go together. Can you please explain?

Tom Kyte
February 13, 2003 - 5:08 pm UTC

search the documentation for

proxy authentication


there is a "set user" capability in the database. Also, mod_plsql and many other things work very hard to reuse a physical circut for you.


Compilation over database link with this method

A Reader, March 13, 2003 - 9:19 am UTC

Tom,

This was very useful. However, I have a problem whereby I try to compile a package and get:

PLS-00201: identifier 'ABCDEF' must be declared

where ABCDEF is a SYNONYM pointing to a TABLE in a remote database (over a database link).

I used the above method of ALTER SESSION SET CURRENT_SCHEMA in a LOGON trigger (at Schema level) at the other end of the database link. The user I connect to only has CREATE SESSION, ALTER SESSION and SELECT on the schema owner tables. The trigger was created in this user's schema by SYS.

My question is - is SELECT enough for the compilation as:

USER A, DB A USER B, DB B SCHEMA OWNER, DB B
my pkg ---------> Trigger, alters schema ---> ultimate table
(DB LINK) (Select, Create Session)

If I switch the DB link to be direct to the Schema owner, it compiles but I don't want this as for security I don't want to have full access to the schema, only select.

Please advise.

Regards,

Paul

Tom Kyte
March 14, 2003 - 5:11 pm UTC

It would be normal to create synonyms on the remote site -- never tried set current_schema over a dblink.



Some more help

Sanjaya Balasuriya, September 19, 2003 - 1:13 am UTC

Tom,

Say I have a user X who owns a schema with set of tables and a set of packages.
I have a another user Y, who has only CREATE SESSION.

I want to let Y to modify X's tables and packages. For tables, I can give ALTER TABLE privilege on X's tables.
But what can I do about packages ? How can I let Y to modify X's packages ?


Tom Kyte
September 20, 2003 - 5:01 pm UTC

well, I would just let y log in as x, whats the difference here - not much you will be stopping Y from doing.

what do you mean by "modify" - do you mean "recompile" or "supply brand new code for it"

Revoking privileges

Asim Naveed, September 21, 2003 - 2:23 am UTC

Hi,

This is very usefull for me. I have a problem.

I installed Oracle 9i Rel. 2 database , created several
users with most of the default options. These users
have created many tables/indexes in there own user. And
they also use to ALTER them occasionaly.

Now I want that all users can only SELECT, UPDATE,
DELETE, INSERT there existing tables,
but they should NOT CREATE or ALTER anything. CREATE
and ALTER will only be done by SYS.

How can I do this?

Thanks in advance for your help.



Thank

How can I do this

Tom Kyte
September 21, 2003 - 9:46 am UTC

create is easy, just revoke the privileges from them. just give them CREATE SESSION and nothing more. they can modify their existing tables (you might have to adjust their quotas to allow these tables to grow) but they will not be able to create more.

ALTER is trickier, you can use a "before alter" "on schema" trigger (you need to do a before alter or drop probably)

sort of like this example:

</code> http://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:4111470834766 <code>



Lots of Oracle Database knowledge

Carlos Gongora, October 02, 2003 - 9:03 am UTC

I read your document, I am almost new in this topics.
They are helping me a lot to build an application right now.

THANK YOU

Grant access from achema A to B against C

A reader, March 18, 2004 - 9:02 am UTC

Tom

We would like to use a trigger on a table that when populated creates a grant for update access. Is this possible as someone here says a grant can only be issued by the table owner?

So, table A has a column which contains a tablename. Trigger on update/insert grants update to this schema/table to the account owning A. I was wondering if the trigger could belong to a DBA acc and so be secure this way?

Ta in advance!
Dave


Tom Kyte
March 18, 2004 - 9:40 am UTC

depends on the release and I don't see any info here for that :(

grant roles in 10g

Marvin, June 09, 2004 - 7:31 am UTC

Hi

I came across this situation, new to me. Dont understand what is going on

SQL> conn / as sysdba
Connected.

SQL> grant dba to sim;

Grant succeeded.

SQL> conn sim
Enter password: 
Connected.
SQL> select * from session_roles;

ROLE
------------------------------
CONNECT
RESOURCE

SIM is an user I imported from a 8i database. The strange thing is this only happens to this specific user. This user uses FGAC, can be that a cause?¿ 

Tom Kyte
June 09, 2004 - 9:25 am UTC

<b>someone issued:

alter user sim default roles connect, resource;

at some time.  So, sim has dba, but DBA is not one of the default roles, so sim would have to enable it.

you can alter user sim default role all; to reset this.</b>


ops$tkyte@ORA9IR2> conn / as sysdba;
Connected.
ops$tkyte@ORA9IR2> create user sim identified by sim;
 
User created.
 
ops$tkyte@ORA9IR2> grant connect, resource to sim;
 
Grant succeeded.
 
ops$tkyte@ORA9IR2> alter user sim default roles connect, resource;
 
User altered.
 
ops$tkyte@ORA9IR2> grant dba to sim;
 
Grant succeeded.
 
ops$tkyte@ORA9IR2> @connect sim/sim;
sim@ORA9IR2> select * from session_roles;
 
ROLE
------------------------------
CONNECT
RESOURCE
 
sim@ORA9IR2> set role ALL;
 
Role set.
 
sim@ORA9IR2> select * from session_roles;
 
ROLE
------------------------------
PLUSTRACE
CONNECT
RESOURCE
DBA
SELECT_CATALOG_ROLE
HS_ADMIN_ROLE
EXECUTE_CATALOG_ROLE
DELETE_CATALOG_ROLE
EXP_FULL_DATABASE
IMP_FULL_DATABASE
GATHER_SYSTEM_STATISTICS
WM_ADMIN_ROLE
JAVA_ADMIN
JAVA_DEPLOY
XDBADMIN
OLAP_DBA
 
16 rows selected.
 

grant select on table partition

brao, July 19, 2004 - 4:12 pm UTC

Is there any way to grant only the selected partition of the table to a role.



Tom Kyte
July 19, 2004 - 4:58 pm UTC

nope.

you would use fine grained access control to limit access to specific rows within a table

or create a view that only selects that partition.

grant select on table partition

brao, July 19, 2004 - 5:38 pm UTC

With reference to my earlier question on grant privs on partition to a role, I have a Table with data from different regions,each region user has different DB login.

table master_data(
column1 number(10),
column2 number(10),
region varchar(2)
);

Prior we had given privilage on all the records to all the five region users.

Now we are thinking of going for a validation.

we want to validate the table and give access to only relevant group.

But the main problem is all our screens and other views are based on this table.So we dont want to create views on partitions or we view with check option.

Do you suggest any thing to resolve this problem.

Thanks

Tom Kyte
July 19, 2004 - 7:05 pm UTC

fine grained access control was invented to do exactly this:

</code> http://asktom.oracle.com/~tkyte/article2/index.html <code>



FAC

brao, August 03, 2004 - 9:41 am UTC

I'm using Context method to refine the data.
I have two tables
emp ( empno number(3),sal number(10));
and
weekjob (weekno number(4) , empnonumber(10));

i want to restrict data in emp table based on week job table.
at any point of time employee can only see the current weeks job.


job_count <> 0 then
For i in CUR
DBMS_SESSION.SET_CONTEXT('TEST_CTX', 'job_OWNER', i.jobid);
Where_condition := ' job_id= '||jobid;
return (Where_condition);

Is this a valid statement. the context is reset to the last value of the cursor always.
how can I modify this statement.
Thanks



Tom Kyte
August 03, 2004 - 10:03 am UTC

not sure what I'm looking at -- whats "jobid". a cursor for loop with a return inside of it?



FAC

Brao, August 03, 2004 - 10:30 am UTC

select * from emp

empno week_no salary dblogin
1 1
2 1
1 2
4 1
2 2


desc weekjob

weekno dblogin jobid hours_worked


Yes. Sorry my question was not clear.


I have a cursor which returns set of records.


Create or replace Function test_context as
.
.
.
.
cursor c is select job_id from weekjob
where DBLOGIN = SYS_CONTEXT('USERENV','SESSION_USER') .
begin

select count(*) from weekjob

-- i want to restrict the data in the emp table
-- at anypoint of time one can view only his records (emp 101 can see only emp 101 )
-- and the data with jobid returned by the cursor

.
.
.
.
Elsif emp_id <> 'ADMIN' and job_count <> 0 then
--DBMS_SESSION.SET_CONTEXT('TEST_CTX', 'CASE_OWNER', div_id);
Where_condition := ' emp_id = '||emp_id||' OR ' ||' job_ID IN ('||
SELECT job_ID INTO FROM weekjob WHERE where DBLOGIN = SYS_CONTEXT('USERENV','SESSION_USER'));
return (Where_condition);

-- i want some function to replace this select clause
-- im trying with cursor as an option
-- i want to restrict data based on his dblogin and the jobid (returns group of records)

Thanks for a quick responce.







Tom Kyte
August 03, 2004 - 10:34 am UTC

you need to use the context in the predicate itself -- you want to BIND, not hard code values. suggest you take a look at:

</code> http://asktom.oracle.com/~tkyte/article2/index.html <code>

Reader

A reader, November 12, 2004 - 3:25 am UTC

Quote <have many different schemas representing differing levels of functionality in your application (i've never
seen an application where EVERYONE has the same rights and priveleges).</quote>

We are doing exacly this,but application requires cross schema query like join between two schema.What is the best way to do this ?? we have a user called say "A" who has all the objects inside.Then we have another User called B who has different set of objects.Likewise we have many.Most of them need to talk with each other.What's best way to acheive this.Any example will be helpful

Cheers




Tom Kyte
November 12, 2004 - 7:11 am UTC

appropriate use of grants?

Grants to Users

Ravi, June 04, 2005 - 1:15 am UTC

I'm using 8i Enterprise edition. Can you pl. tell me whether one user can grant SELECT ANY TABLE privilege to another user for all the tables in that user through a single statement or do i need to grant the privilege on each table.


Tom Kyte
June 04, 2005 - 8:23 am UTC

there is no "select any table in this schema" privilege. No.

Grants to Users

V.Ravi, June 08, 2005 - 4:56 am UTC

Dear Tom,

Suppose there are two oracle users X and Y. X contains table p,q and r. I want to grant access of tables p,q and r to Y and Y should have access to the tables in X user only and not to any others e.g. if there is another user Z then Y should not have access to Z.

Do i need to give the grant of these tables separately to Y as below:

GRANT SELECT, UPDATE, DELETE ON p to Y;
GRANT SELECT, UPDATE, DELETE ON q to Y;
GRANT SELECT, UPDATE, DELETE ON r to Y;

Or is there any way i can give this in a single statement.

This is just an example, in my current LIVE environment i am having some 400 tables.

Thanx in advance,
Ravi


Tom Kyte
June 08, 2005 - 8:39 am UTC

you could easily script this, if you have a list of tables to grant on in a table somewhere

begin
for x in ( select .... from t )
loop
execute immediate 'grant all on ' || x.tname || ' to y';
end loop;
end;
/

but the object grants are on an object, a grant per object to be granted.

Grants to Users

V.Ravi Shankar, June 09, 2005 - 1:06 am UTC

Dear Tom,

Let us assume there are two users X and Y. I want to give CREATE TABLE rights to Y so that user Y can create tables in X. But, i want to restrict user Y from creating tables in others users apart from X.

For e.g. i issue the following command

x@oracle>GRANT CREATE ANY TABLE to Y

Then, it allows Y to create tables in any user. If i issue the following then tables can be created only in Y user.

x@oracle>GRANT CREATE TABLE to Y

Thanx in advance,
Ravi


Tom Kyte
June 09, 2005 - 6:35 am UTC

there is either the ability to

a) create tables for yourself (grant create table to YOU)
b) create tables for ANYONE (grant create ANY table to YOU)

there is no "grant create tables for THEM to YOU"


You can use a stored procedure, as X you would:

create procedure create_table( p_str in varchar2 )
as
begin
execute immediate 'create table ' || p_str;
end;
/

grant execute on create_table to Y;


and y can

sql> execute x.create_table( 't ( x int, y int )' );

but be aware of sql injection, anytime you do dynamic sql like that.
</code> https://www.oracle.com/technetwork/issue-archive/2005/05-jan/o15asktom-084959.html <code>


How do I alter session in Informatica ?

Souju, June 13, 2006 - 12:13 pm UTC

We have a datawarehouse using Informatica 7.1 power center as ETL.I am trying to load a table with 16 million rows.I am altering the index to make it unusable before the load.How do I set the 'Alter session set skip-unusable_indexes = true' in Informatica right before loading the data into the table.

Please idea ?

Thanks in advance.

Tom Kyte
June 13, 2006 - 12:33 pm UTC

Be a question for the makers of "informatica"?

grants

sam, November 30, 2006 - 6:59 pm UTC

Tom:

If DBA is creating a developer account in 9i with following grants, do you think this is sufficient? or you need more.

create user devadmin identified by devadmin
default tablespace userdata
temporary tablespace temp;
grant connect, resource to devadmin ;
grant plustrce to devadmin ;
grant select any table, create public synonym to devadmin ;
grant create trigger to devadmin;
grant create procedure to devadmin;
grant create materialized view to devadmin;
grant select any dictionary to devadmin;
grant create any context to devadmin;


Tom Kyte
November 30, 2006 - 8:41 pm UTC

grant connect, resource - I would NOT use those.

grant select any table - OH MY - revoke that IMMEDIATELY, RIGHT NOW, RIGHT AWAY - not a change.

grant create public synonym - SAME THING, revoke it, right now, not a chance

grant create any context - SAME THING, revoke it, right now, immediately


To create a developer account:

alter user devadmin quota unlimited on userdata;
grant create session to devadmin;
grant plustrace to devadmin;

and then if they need to create tables, grant them create table.
if they need to create a materialized view, grant them that


avoid the ANY privileges and grant AS LITTLE AS YOU CAN - and no more. And question every grant.

Grants to developers

BC, December 07, 2006 - 10:58 am UTC

Tom,

We need to grant developers access to only view source code of stored procedures in the production database. How do we accomplish that?

We are trying to lock developers out of the production system. And prevent them from altering production source code.

Thanks

BC




Tom Kyte
December 07, 2006 - 1:15 pm UTC

create your own view then of DBA_SOURCE and grant them select on it

or, if they should see ALL source code, grant them select on DBA_SOURCE.

A reader, January 11, 2007 - 10:30 am UTC

Tom,

What is the data dictionary object to check existing roles in a database?

Thanks.

Granting to Roles

Russell, June 05, 2007 - 11:55 pm UTC

Tom,


We have our main application UserID (PIAPAK), which has tables etc (Oracle 9.2)

We have created a role and given Select access to some tables to that role.

We have created other users, and have given them access to the role. The users can select quite happily from the tables indicated.

The users try to create a view in their own schema based on table(s) in the main schema, and we get ORA-01031: insufficient privileges errors. Why is this happening?

CREATE USER PIAPAK IDENTIFIED BY PIAPAK;
GRANT CONNECT TO PIAPAK;
GRANT RESOURCE TO PIAPAK;

CREATE USER RFTEST IDENTIFIED BY RFTEST;
GRANT CREATE VIEW TO RFTEST;
GRANT CREATE SESSION TO RFTEST;

CREATE ROLE CR_REPORTS;

CONNECT PIAPAK/PIAPAK;

CREATE TABLE PIAPAK.PEOPLE_STRUCTURE
(
  EMP_NAME                 VARCHAR2(255 BYTE),
  AGS                      VARCHAR2(10 BYTE),
  EGM                      VARCHAR2(65 BYTE)
);

Insert into PIAPAK.PEOPLE_STRUCTURE (EMP_NAME, AGS, EGM)  Values    ('Mark Smith', '12345', 'Service Delivery South West');
Insert into PIAPAK.PEOPLE_STRUCTURE (EMP_NAME, AGS, EGM)  Values       ('Wilfred Jones', '12356', 'Service Delivery South West');
Insert into PIAPAK.PEOPLE_STRUCTURE (EMP_NAME, AGS, EGM)  Values       ('Grahame Brown', '12378', 'Service Delivery East');
Insert into PIAPAK.PEOPLE_STRUCTURE (EMP_NAME, AGS, EGM)  Values       ('Barry Black', '12390', 'Service Delivery East');

GRANT SELECT ON PIAPAK.PEOPLE_STRUCTURE TO CR_REPORTS;

GRANT CR_REPORTS TO RFTEST;

CONNECT RFTEST/RFTEST;

SELECT *
FROM PIAPAK.PEOPLE_STRUCTURE
WHERE EGM = 'Service Delivery East;

CREATE VIEW VW_PEOPLE AS
SELECT *
FROM PIAPAK.PEOPLE_STRUCTURE
WHERE EGM = 'Service Delivery East;



Thanks in Advance,
Russell

Alexander the ok, April 04, 2008 - 12:35 pm UTC

Hi Tom,

In your travels have you ever come across a problem with a java application not having roles take effect and having to grant directly to the user?

I've encountered this issue for the second time, the only similarity I know of is there both java apps.

If we grant via a role, they get "table or view doesn't exist". When we grant the privileges back to the user, it works.

I can create a dummy user, assign the role, log in via sqlplus, works fine.

I checked to see if the roles we enabled, they are.

I'm baffled.
Tom Kyte
April 04, 2008 - 1:09 pm UTC

if they use proxy users - sure, when you granted connect through to the proxy user - you listed the roles that would be in effect.


http://docs.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_4003.htm#sthref5729


also make sure the roles were "defaulted", on for that user by default (dba_role_privs).

Alexander the ok, April 04, 2008 - 1:24 pm UTC

Uh can I tell from the database end if proxy users are being used?

We did check the defaults, they're good.
Tom Kyte
April 04, 2008 - 10:09 pm UTC

you'd see two sessions for a single process - one is the proxy user and the other would be the "application user"

but, you could just ask the developers.

In order to believe you checked the defaults, I'd need to see "evidence" of that. I'd want a java program that when run would show a different set of rows in session_roles than a query in sqlplus would

java is just a language, like C (just not as good). This will be something the programmer themselves did - we don't recognize java as a client - we just recognize clients.

Alexander, April 08, 2008 - 11:01 am UTC

We figured out proxy users we not being used. After the developer told us is was too much work to add the query for session_roles, we fiddled with the knobs and found a work around that was bouncing the instance.

Since it's RAC, we can do one at a time with no disruption.

Can you even begin to suggest how that could possibly make a difference? Are you aware of middle tier software like websphere that would cache anything like that? Makes no sense to me at all. I know those grants take effect immediately.
Tom Kyte
April 09, 2008 - 2:32 pm UTC

I can only think that the roles were non-default, without an actual cut and paste example, I cannot diagnose it from where I sit.

revoking create procedure

Tito, April 22, 2008 - 6:53 am UTC

Hi Tom.

Regarding "grants to users". We have a little problem here. Compiling in our production systems is not allowed for developers, but they ussualy jump the rule. The last month we have had some troubles for decompilation and invalidation of packages that resulted in a downtime.

The user where the code is has the connect and resource grants. so what i did was to create a new role with all the system privileges that connect and resource has, create a new user for test purpose, then i assigned that role to user, and then revoke connect and resource .. a little confusing, but is kind of testing stuff. Once i did that, i create some package in the new schema, until then no problem at all. The next step was to revoke the "CREATE PROCEDURE" from the new role and recompile the package expecting to receive a "NO PRIVILEGES" error, but no, it let me do the recompiling.

I noticed that i only receive the "NO PRIVILEGES" error when i create a new package, but not when i "CREATE OR REPLACE" an existing package.

What im trying to do with all the test is to begin a priviliges cutting, starting with the "CREATE PROCEDURE". The less, the best.

Is there any way to avoid recompilation of existing packages, procedures, views, etc ..inside a schema?

Thanks for your big help, hope you can help me, and sorry about my english .. Regards. Tito


Tom Kyte
April 23, 2008 - 5:46 pm UTC

... Compiling in our
production systems is not allowed for developers, ...

and I read that and said "LOGGING IN OUR production system...." that should be the words you used. Why are they allowed IN at all??

do not allow developers to log into the production schema, that is madness.

Re: revoking create procedure

Tito, April 24, 2008 - 4:26 am UTC

Yes .. Yes .. I know !! .. But the fact is that exists some kind of culture in this company, and we're trying to eliminate it, but after more than 8 years working against production (im kind of new here) is difficult. Is a continous fight .. but our bosses dont have the "political will" that we need in order to cut the logons off. That means that we cant avoid the logons. Its exhausting.

Well. We're revoking grants from users as a pimary solution. Meanwhile, we follow the fight for production freedom. So, Is there any way to avoid "CREATE OR REPLACE ..." in existing objects?.

Thanks for your big help !!

Tito
Tom Kyte
April 28, 2008 - 11:09 am UTC

That means you cannot get there from here.



You could create a ddl trigger, but you know, if the developers can log in, they can probably defeat that as well (since they probably have access to the account that would hold the ddl/system event trigger as well)

ops$tkyte%ORA10GR2> create or replace trigger ddl_trigger
  2  before create or alter or drop on schema
  3  begin
  4          raise_application_error( -20001, 'no, you cannot' );
  5  end;
  6  /

Trigger created.

ops$tkyte%ORA10GR2> drop table t;
drop table t
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: no, you cannot
ORA-06512: at line 2


ops$tkyte%ORA10GR2> create or replace function f return number as begin return 0; end;
  2  /
create or replace function f return number as begin return 0; end;
*
ERROR at line 1:
ORA-00604: error occurred at recursive SQL level 1
ORA-20001: no, you cannot
ORA-06512: at line 2


ops$tkyte%ORA10GR2> desc f;
FUNCTION f RETURNS VARCHAR2
 Argument Name                  Type                    In/Out Default?
 ------------------------------ ----------------------- ------ --------
 P1                             VARCHAR2                IN
 P2                             VARCHAR2                IN
 P3                             VARCHAR2                IN



however...

ops$tkyte%ORA10GR2> drop trigger ddl_trigger;

Trigger dropped.


so, you'd have to create that trigger in another schema, using "on database" instead of "on schema" and put the appropriate schema checks in there.

lock it down

and make sure the developers do not have any of the "ANY" privileges...

A reader, April 01, 2009 - 10:59 am UTC

Tom,

This is a silly question, but can you explain why if I

SQL> create user x identified by x;

User created.

SQL> alter user x quota unlimited on users;

User altered.

SQL> grant create table to x;

Grant succeeded.

SQL> grant connect to x;

Grant succeeded.

SQL> connect x/x
Connected.
SQL> create table t as select * from dual;

Table created.
SQL> connect /
Connected.
SQL> revoke create table from x;

Revoke succeeded.

SQL> connect x/x
Connected.
SQL> drop table t;  

Table dropped.   <=== Why is this allowed?

Tom Kyte
April 01, 2009 - 4:25 pm UTC

you own it? anything you own, of course you can drop.

you revoked the ability going forward to CREATE new tables - why do you think that would or should prevent you from dropping that which you already own?

Alexander, April 01, 2009 - 5:00 pm UTC

Because the id no longer has those privileges. How come it doesn't need the drop table privilege?

I guess this is just how it works, but it's a little strange to me. It would be like (conceptually) if you granted update, then later revoked but still had the ability to update rows you touched in the past.

I feel like revoking that privilege I am explicitly saying "I don't want you to be able to do this.."

I raise the question because we have vendors that require running as the owner but those ids are flagged by auditors and much is made about how to secure them because of their "elevated" privileges.
Tom Kyte
April 02, 2009 - 9:11 am UTC

he *OWNS* it. You don't need "drop your own table" privs - there isn't even such a concept. Given there is no "revoke drop that_table", there is no concept of not being able to drop stuff you own.

And I don't see the correlation between this and the update. In the update scenario - you don't OWN the rows you update. You do however OWN the table in this case, you *own it*. You cannot *create* anymore, but you can still drop, delete, truncate, insert, update, cause it to grow, etc.

Actually, if someone else creates the table for you - you can still drop it, you are the OWNER of the table.

ops$tkyte%ORA10GR2> drop user a cascade;

User dropped.

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> create user a identified by a quota unlimited on users;

User created.

ops$tkyte%ORA10GR2> grant create session to a;

Grant succeeded.

ops$tkyte%ORA10GR2> create table a.t ( x int );

Table created.

ops$tkyte%ORA10GR2> connect a/a
Connected.
a%ORA10GR2> drop table t;

Table dropped.

a%ORA10GR2> create table t ( x int );
create table t ( x int )
*
ERROR at line 1:
ORA-01031: insufficient privileges


You'll have to change your feeling - because, well, it doesn't even make sense (in my opinion).


You can prevent an owner from dropping a table in 11g - by placing it in the flashback data archive.



ops$tkyte%ORA11GR1> create user a identified by a quota unlimited on users;

User created.

ops$tkyte%ORA11GR1> grant create session to a;

Grant succeeded.

ops$tkyte%ORA11GR1> create table a.t ( x int );

Table created.

ops$tkyte%ORA11GR1>
ops$tkyte%ORA11GR1> create flashback archive demo tablespace users retention 1 month;

Flashback archive created.

ops$tkyte%ORA11GR1> alter table a.t flashback archive demo;

Table altered.

ops$tkyte%ORA11GR1>
ops$tkyte%ORA11GR1> connect a/a
Connected.
a%ORA11GR1> drop table t;
drop table t
           *
ERROR at line 1:
ORA-55610: Invalid DDL statement on history-tracked table


a%ORA11GR1> alter table t no flashback archive;
alter table t no flashback archive
*
ERROR at line 1:
ORA-55620: No privilege to use Flashback Archive


a%ORA11GR1>
a%ORA11GR1> connect /
Connected.
ops$tkyte%ORA11GR1> alter table a.t no flashback archive;

Table altered.

ops$tkyte%ORA11GR1> drop table a.t;

Table dropped.

Implicit grants

Nenad, November 12, 2009 - 3:45 am UTC

Hi,
We are trying to stop the use of generic accounts (eg system) and those of
application owners. We prefer that DBAs connect as themselves to create
objects in object owning schemas. It makes for a simple separation and an
easier to follow audit trail and is a company standard.

We have come unstuck on creation of roles. When a DBA creates a role they are
implicitly granted it. This is in violation of our separation of duty standards.
I realize the dba doesn't need the roles, as he is a dba, but we end up with
unauthorised grants.

eg

sys@DEVP4 > create user new_dba identified by new_dba;

User created.

sys@DEVP4 > grant dba,create session to new_dba;

Grant succeeded.

sys@DEVP4 > conn new_dba/new_dba;

Connected.

new_dba@DEVP4 > create role new_role;

Role created.

new_dba@DEVP4 >select *
2 from dba_role_privs
3 where granted_role='NEW_ROLE';

GRANTEE GRANTED_ROLE ADM DEF
---------------- --------------- --- ---
NEW_DBA NEW_ROLE YES YES

We keep our system and application owner schemas locked. We don't want to have
to unlock them to create roles.

What can we do here?

Thanks
Nenad
Tom Kyte
November 15, 2009 - 1:43 pm UTC

if you can remember the other place you posted this, i responded over there.

grant role inside trigger

Just reader, July 19, 2010 - 7:30 pm UTC

Tom,

Database version: 11.1
Is it possible to grant role inside "after startup on database" trigger? I am trying create trigger which grants certain role to user after database starts up. Is there work around that? I even created stored proc which has grant statement and called from inside of trigger and nothing.

Any feedback much appreciated



Tom Kyte
July 23, 2010 - 6:43 am UTC

this seems strange, tell us more. Why would you need to grant on a role every time the database starts up?

Can I tell you how to do this - yes.

I want to know what you are doing first because it sounds very very very fishy to me.

To grant role inside trigger

Just reader, July 23, 2010 - 12:03 pm UTC

We have two databases - primary and cloned through BCV. The cloned is used for testing and reporting.

Certain user which exists in primary database need to be granted DBA privs. so that upon cloned database start-up he can perform DBA tasks.

So when database starts on new host server and "after startup on database" trigger fires it checks host name and grants privs. appropriately.

Trigger logic:

SELECT host_name into v_host_name FROM v$instance;

if v_host_name = 'srvbcvdb'
then
execute immediate 'grant DBA to JOE';
ELSE
null;

end if;

Tom Kyte
July 23, 2010 - 12:48 pm UTC

ops$tkyte%ORA10GR2> connect / as sysdba;
Connected.
sys%ORA10GR2> grant dba to ops$tkyte with admin option;

Grant succeeded.

sys%ORA10GR2>
sys%ORA10GR2> connect /
Connected.
ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> create or replace trigger after_startup
  2  after startup on database
  3  declare
  4          l_job number;
  5  begin
  6          if ( 1=1 )
  7          then
  8                  dbms_job.submit( l_job,
  9                  'begin execute immediate ''grant dba to a''; end;' );
 10          end if;
 11  end;
 12  /

Trigger created.

ops$tkyte%ORA10GR2> select * from dba_role_privs where grantee = 'A';

no rows selected

ops$tkyte%ORA10GR2>
ops$tkyte%ORA10GR2> connect / as sysdba;
Connected.
sys%ORA10GR2> shutdown
Database closed.
Database dismounted.
ORACLE instance shut down.
sys%ORA10GR2> startup
ORACLE instance started.

Total System Global Area  536870912 bytes
Fixed Size                  1268484 bytes
Variable Size             155190524 bytes
Database Buffers          373293056 bytes
Redo Buffers                7118848 bytes
Database mounted.
Database opened.
sys%ORA10GR2> exec dbms_lock.sleep(10);

PL/SQL procedure successfully completed.

sys%ORA10GR2> select * from dba_role_privs where grantee = 'A';

GRANTEE                        GRANTED_ROLE                   ADM DEF
------------------------------ ------------------------------ --- ---
A                              DBA                            NO  YES

sys%ORA10GR2>
sys%ORA10GR2> connect /
Connected.
ops$tkyte%ORA10GR2> drop trigger after_startup;

Trigger dropped.


use the job queues to run the grant as a job outside of the trigger. I slept for 10 seconds only for the demo - you would not do this in real life.

Yes, job queues/scheduler would have to be enabled for this.

To grant role inside trigger

Just reader, July 23, 2010 - 1:27 pm UTC

Terrific. Thank you very much.

complete schame access

Nadeesh, January 24, 2011 - 7:17 am UTC

Hi Tom,

We have 10 application schemas hold almost every type of database objects. Now business want to grant schema 'test' the complete access DML/DDL to objects in all 10 application schemas.

e.g insert/update/delete drop for every table of 10 schemas.

And similar/relevant type of grant for all objects in 10 schemas to 'test'schema.

I can see that in one of the schema the object types are as below:

SQL> select object_type, count(*) from dba_objects where owner='BATAP5' group by object_type;

OBJECT_TYPE           COUNT(*)
------------------- ----------
DATABASE LINK               29
FUNCTION                    23
INDEX                      321
INDEX PARTITION           6266
JAVA CLASS                   1
JAVA SOURCE                  1
JOB                          1
LOB                         18
MATERIALIZED VIEW            1
PACKAGE                    114
PACKAGE BODY               111

OBJECT_TYPE           COUNT(*)
------------------- ----------
PROCEDURE                  336
PROGRAM                      2
SCHEDULE                     1
SEQUENCE                    47
SYNONYM                    172
TABLE                      673
TABLE PARTITION           1997
TRIGGER                     86
TYPE                        15
TYPE BODY                    1
VIEW                        69

22 rows selected.

Other schemas may hold different objects types. So how can I give complete grants to test user so that test has same grants as these 10 application schemas have for their own objects.

I am not able to find any way to do this?

Tom Kyte
February 01, 2011 - 10:14 am UTC

Well, I would start by saying to the "business" - you mind your business and we'll mind ours. Ours is database and yours is "business" (whatever that means).

They need to be introduced to the concept of LEAST PRIVILEGES - there is no reason under the sun that

a) the testing account needs Carte Blanche access to all of the schemas, no way

b) that the set of objects that it would need access to would not already be fully documented as part of the "system"

Why bother with security at all?


You want to document that which you will be granting - and you would only grant on some of the objects in that list - indexes, no. functions - maybe (maybe not, there isn't any reason they need access to everything)

You will grant on those things that NEED to be granted on.

A test user should not have insert/update/delete on MOST tables - maybe a few, but certainly not MOST and definitely not ALL.

vinay, July 28, 2012 - 7:27 am UTC

Hello admin;
when I enter (select * from emp;)query ..
i getting ORA-00942:table or view does not exist...
please replay me through mail....

Tom Kyte
July 30, 2012 - 11:47 am UTC

create an emp table and then it'll work....

????

insufficient privileges

Issa, February 27, 2013 - 4:39 pm UTC

Hi Tom
Please I need your help as whenever I do my View Query as in:

CREATE OR REPLACE VIEW DEPT_NAME AS
SELECT SSN,FIRST_NAME ,LAST_NAME, SALARY, DEPT_NAME
FROM EMPLOYEE, DEPARTMENT
WHERE EMPLOYEE.DEPT_NO = DEPARTMENT.DEPT_NUM;

It's always come back to me as :

SQL Error: ORA-01031: insufficient privileges
01031. 00000 - "insufficient privileges"
*Cause: An attempt was made to change the current username or password
without the appropriate privilege. This error also occurs if
attempting to install a database without the necessary operating
system privileges.
When Trusted Oracle is configure in DBMS MAC, this error may occur
if the user was granted the necessary privilege at a higher label
than the current login.
*Action: Ask the database administrator to perform the operation or grant
the required privileges.
For Trusted Oracle users getting this error although granted the
the appropriate privilege at a higher label, ask the database
administrator to regrant the privilege at the appropriate label.


WHAT SHALL I DO?



Tom Kyte
February 28, 2013 - 7:54 am UTC

you do not have the create view privilege.


get create view granted to you.

schema

A reader, December 15, 2014 - 10:07 pm UTC


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