Skip to Main Content
  • Questions
  • Regarding create index and drop table privileges

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Om.

Asked: September 12, 2002 - 6:40 am UTC

Last updated: November 02, 2004 - 10:44 am UTC

Version: 8.1.7

Viewed 50K+ times! This question is

You Asked

Hi Tom,

I have few privileges questions to ask .

There is no direct create index and drop table privilege.

Q1) How do you give a particular use "create index" privilege.

Q2) How to give drop table privilege to a user or it is not
just possible for a user to drop a table which he doesn't own ?

Best regards,
Om

and Tom said...

q1) if you own a table, you can index it (hence CREATE TABLE conveys the ability to create an index on that table)

you can grant CREATE ANY INDEX (bad idea) in order to create an index on ANY table in the system

you can grant CREATE INDEX ON TABLENAME to ANOTHER_USER to allow another schema to index some tables in your schema.

q2) I use stored procedures for such customized, fine grained granting of privileges. It is very easy to do. For example,


create procedure drop_table( p_tname in varchar2 )
as
begin
.... whatever complex logic you want to determine if they CAN drop it ....
execute immediate 'drop table ' || p_tname;
end;
/

and if the owner of that procedure either OWNS the table in question to be dropped OR the owner of the procedure has the super powerful "drop any table" priv, they can now drop the table on behalf of someone after performing whatever security checks you want.

The other user just needs EXECUTE on that procedure.

Rating

  (7 ratings)

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

Comments

Security?

Dennis, September 12, 2002 - 1:05 pm UTC

Tom,

Wouldn't you want to be very protective of such a procedure and make it only drop "the table" and not potentially drop any table? Of course, I don't know what logic you're sticking in, I just fear the openness of the procedure as you could plug any name in there. I do something similar for truncating tables currently, and I did allow a parameter in your fashion, but checked that the p_table_name was one of the three values I approved of. Is that what your logic would be, or would you also have some user checks (I'm relying on the EXECUTE privilege...should I not (nobody except other DBAs have EXECUTE ANY))?

Thanks Tom.

Dennis

Tom Kyte
September 12, 2002 - 4:13 pm UTC

.... whatever complex logic you want to determine if they CAN drop it ....


should cover my behind on this one ;)

that is what .... whatever .... meant -- do your check, whatever it may be, to make darn sure they CAN drop it.

Just wondering

Dennis, September 12, 2002 - 5:27 pm UTC

Yeah, you were covered. I worded my question incorrectly. We have two different sets of procedures in place. One, where you call the procedure and it truncates a specific table (there are something like five of these). Another, where you call a procedure with a value to truncate one of three tables. I didn't want to make the developers call 100 billion procedures to truncate (well ok, three) ;) so I chose to pass in a parameter, but put in the logic to make sure it was one of the three tables.

Now, is that wrong? Is the other way better (one proc per table)? Or should I have logic to check that the user is a certain user and not worry about checking the tables (hoping the user knows what he/she/it is doing), or do the table check as an extra precaution (yes, I see big red abandon ship, missile(s) incoming warning lights all over the not including it option, but I gotta ask)?

Does checking for user 'X' do what I think it does and just protect me from those who have the execute any privilege that I don't know about and don't particularly want truncating (or dropping or whatever) my tables?
Leaving me at the point where only certain people can run my procedure, but I'm still not safe from anyone like you who can rewrite my stuff at will (hey...maybe you can also make it really fast while you're at it...).

I almost posted a reply right away, but hoped that your crystal ball was back from the shop ;) Guess I should've known better, but I was also trying to be lazy :) As well as horde time so I could think of a better way to ask it.

Thanks Tom.
Dennis

Tom Kyte
September 12, 2002 - 8:11 pm UTC

You should do what you feel needs to be done in order to have this happen securely, reliably and correctly.

I might have used a table with "username" "tablename" and insert rows in there (sort of like DBA_SYS_PRIVS for example) to make it table driven and in a single procedure (to cut down on code)....

You need to write the procedure in a way that is only lets those you want -- truncate. Anyone with EXECUTE on it, or EXECUTE ANY PROCEDURE can run it -- a table driven approach will make it so only those you actually give permission to at the table level have it.

Doubt......

Ashok, September 13, 2002 - 1:52 am UTC

Hi

"you can grant CREATE INDEX ON TABLENAME to ANOTHER_USER to allow another schema to index some tables in your schema."

Will this index be considered by the optimizer if the owner of the table fires any query on this table that affects the indexed column (created by another user)?

Tom Kyte
September 14, 2002 - 1:35 pm UTC

Yes, an index is an index is an index. The optimizer sees them all.

yay I get to help!

Dennis, September 13, 2002 - 7:47 am UTC

Yes the index would. You can thank Tom for my example skills, I'm trying "to be like Mike".

06:48:48 WINKID1@HIS2:scsp05> create table test_me as select * from dba_objects;

Table created.

Elapsed: 00:00:00.51
06:49:00 WINKID1@HIS2:scsp05> insert into test_me select * from test_me;

8597 rows created.

Elapsed: 00:00:00.40
06:49:15 WINKID1@HIS2:scsp05> /

17194 rows created.

Elapsed: 00:00:00.10
06:49:16 WINKID1@HIS2:scsp05> /

34388 rows created.

Elapsed: 00:00:01.02
06:49:18 WINKID1@HIS2:scsp05> /

68776 rows created.

Elapsed: 00:00:02.04
06:49:21 WINKID1@HIS2:scsp05> /

137552 rows created.

Elapsed: 00:00:06.70
06:49:29 WINKID1@HIS2:scsp05> commit;

Commit complete.

Elapsed: 00:00:00.20
06:49:30 WINKID1@HIS2:scsp05> create index tab_owner_idx01 on test_me(owner);

Index created.

Elapsed: 00:00:08.92
06:50:03 WINKID1@HIS2:scsp05> @connect
userid:dbaoper
password:*********
sid:his2
Connected.
06:50:12 DBAOPER@HIS2:scsp05> create index other_owner_idx01
06:50:31 2 on winkid1.test_me(object_name, object_type);

Index created.

Elapsed: 00:00:08.03
06:50:53 DBAOPER@HIS2:scsp05> @connect
userid:winkid1
password:********
sid:his2
Connected.
06:51:00 WINKID1@HIS2:scsp05> set autotrace traceonly explain
06:51:07 WINKID1@HIS2:scsp05> select object_name, object_type
06:51:18 2 from test_me
06:51:24 3 where object_name like 'S%' and
06:51:38 4 object_type = 'TABLE'
06:51:48 5 /
Elapsed: 00:00:00.00

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 INDEX (RANGE SCAN) OF 'OTHER_OWNER_IDX01' (NON-UNIQUE)



06:51:49 WINKID1@HIS2:scsp05> spool off
06:51:57 WINKID1@HIS2:scsp05>

Tom Kyte
September 14, 2002 - 1:55 pm UTC

All right - it is working!!! The ability to try out things is spreading ;)

thanks.

CREATE INDEX ON TABLENAME TO USER is not working

Howie, January 02, 2003 - 10:07 am UTC

Hi

I am using oracle 8.1.7 and I was trying to grant privilege to other user so that he can create index on my tables ( not all but some of them). I tried to user CREATE INDEX ON HR_TAB to USER_01 but it failed with following error
ERROR at line 1:
ORA-00990: missing or invalid privilege

Can you please explain how to use this?

Tom Kyte
January 02, 2003 - 10:12 am UTC

ops$tkyte@ORA817DEV> grant index on t to scott;

Grant succeeded.

 

Dropped Table Information

A reader, March 07, 2003 - 2:23 am UTC

Hi Tom,

I dropped a table. The table contains no data. I have no backups.

1)Which data dictionary table contains information about the dropped tables. ie information like the table structure, indexes associated with it, primary key , foriegn key etc ?
Or does such information exists in the datadictionary at all?

2) Is there any other way you can find those informations
about a recently dropped table (other than from the backups)?

Thanks and regards
Praveen KV

Tom Kyte
March 07, 2003 - 8:05 am UTC

you are what they officially term as "hosed".

it is all gone. if you are on 9i, there is a chance we can use flashback query to see the DEFINITION of the table (but not the data).

Restricting drop table

Yogesh, November 02, 2004 - 10:06 am UTC

I was reading the document for init.ora parameter DML_LOCKS.

<quote>
If the value is set to 0, enqueues are disabled and performance is slightly increased. However, you cannot use DROP TABLE, CREATE INDEX, or explicit lock statements such as LOCK TABLE IN EXCLUSIVE MODE.
</quote>

Can we use this as a protection, so that no user will be able to drop table? OR we'll face problems if we do so?


Tom Kyte
November 02, 2004 - 10:44 am UTC

well, are you going to do things like create index?

sure, you can use this to prevent a table from getting dropped, but it'll prevent other things as well -- will that be a problem for you? only you can answer that!

More to Explore

Security

All of the vital components for a secure database are covered in the Security guide.