Direct privilege grant vs ALL PRIVILEGES vs roles vs PUBLIC - sql

1/ To my knowledge, direct privilege grant and ROLE grant and PUBLIC grant are independent, meaning all 3 can carry themselves the same privilege. Revoking from one does not interfere with that privilege still staying with the user.
Meaning if we
GRANT SELECT ON T TO userA
GRANT SELECT ON T TO roleA; GRANT roleA to userA
GRANT SELECT on T TO PUBLIC
Revoking one or two of the 3 Grants leaves the userA with the SELECT privilege.
How about ALL PRIVILEGES, does it overlap with any of these 3 zones ? If we have the 3 grants above and the following
GRANT ALL PRIVILEGES on T to userA;
and then we
REVOKE ALL PRIVILEGES on T to userA;
which one of the 3 grants will be additionally removed ? Does it behave the same for system privilege and object privileges ?
2/ There is a GRANT ANY PRIVILEGE and GRANT ALL PRIVILEGE*S*. Are they the same ?

As per the docs "Oracle Database provides the ALL PRIVILEGES shortcut for granting all the system privileges listed in Table 18-1, except the SELECT ANY DICTIONARY privilege." Your examples are not system privileges so there is no overlap. https://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_9013.htm
As for GRANT ANY PRIVILEGE, this grants the user the ability to in turn grant a system privilege to other users. For example:
dba#db> GRANT GRANT ANY PRIVILEGE to some_user;
grant succeeded
reconnect as some_user. This user can now pass on system grants to some_other_user.
some_user#db> GRANT COMMENT ANY TABLE to some_other_user;
grant succeeded
This seems to be like a privilege you want to use when you want to give a user partial dba privileges and should be used with care.
In contrast ALL PRIVILEGES is more like a macro that grants all of the individual system privileges at once so
GRANT ALL PRIVILEGES to some_user;
would be like running grant statements for all system privileges (and there are many):
GRANT ADVISOR TO some_user;
GRANT ADMINISTER SQL TUNING SET TO some_user;
GRANT ADMINISTER ANY SQL TUNING SET TO some_user;
GRANT CREATE ANY SQL PROFILE TO some_user;
GRANT DROP ANY SQL PROFILE TO some_user;
GRANT ALTER ANY SQL PROFILE TO some_user;
etc...
EDIT:
Further in the link above, under the grant_object_privileges section there is also:
ALL [PRIVILEGES]
Specify ALL to grant all the privileges for the object that you have
been granted with the GRANT OPTION. The user who owns the schema
containing an object automatically has all privileges on the object
with the GRANT OPTION. The keyword PRIVILEGES is provided for semantic
clarity and is optional.
If you do something like
GRANT ALL PRIVILEGES on some_table TO some_user;
that user gets all of these table privileges (at least this is the list I get in 12c):
FLASHBACK
DEBUG
QUERY REWRITE
ON COMMIT REFRESH
READ
REFERENCES
UPDATE
SELECT
INSERT
INDEX
DELETE
ALTER
For sequences you get:
SELECT
ALTER
(And other object types will have their own list.)
So, it's just like ALL PRIVILEGES for system privileges in that it's a shortcut for granting all of the object privileges for the type of object specified; there isn't one "ALL PRIVILEGES" privilege that you get. For tables it's like typing in the grant statements for the 12 privileges listed above:
GRANT FLASHBACK on ...
GRANT DEBUG on ...
GRANT QUERY REWRITE on ...
Each one of these privileges can be individually revoked. So if you did:
REVOKE INSERT, UPDATE, DELETE on some_table FROM some_user;
you would still have the 9 other privileges from the above table privileges.
If you use "ALL PRIVILEGES" with REVOKE:
REVOKE ALL PRIVILEGES on some_table FROM some_user;
it will take away whatever table privileges some_user had remaining on some_table in the above list.
So, to make a long story longer, here's a SQL example to show the answer to your original question (the owner of table T is USERT):
SQL> create table t (a varchar2(1));
Table created.
SQL> grant select on t to userA;
Grant succeeded.
SQL> select grantor
2 , grantee
3 , table_schema
4 , table_name
5 , privilege
6 from all_tab_privs
7 where table_name = 'T'
8 order by grantee;
GRANTOR GRANTEE TABLE_SCHEMA TABLE_NAME PRIVILEGE
---------- ---------- ------------ ---------- --------------------
USERT USERA USERT T SELECT
SQL>
SQL> grant select on t to roleA;
Grant succeeded.
SQL> select grantor
2 , grantee
3 , table_schema
4 , table_name
5 , privilege
6 from all_tab_privs
7 where table_name = 'T'
8 order by grantee;
GRANTOR GRANTEE TABLE_SCHEMA TABLE_NAME PRIVILEGE
---------- ---------- ------------ ---------- --------------------
USERT ROLEA USERT T SELECT
USERT USERA USERT T SELECT
SQL> grant select on t to public;
Grant succeeded.
SQL> select grantor
2 , grantee
3 , table_schema
4 , table_name
5 , privilege
6 from all_tab_privs
7 where table_name = 'T'
8 order by grantee;
GRANTOR GRANTEE TABLE_SCHEMA TABLE_NAME PRIVILEGE
---------- ---------- ------------ ---------- --------------------
USERT PUBLIC USERT T SELECT
USERT ROLEA USERT T SELECT
USERT USERA USERT T SELECT
SQL> grant all privileges on t to userA;
Grant succeeded.
SQL> select grantor
2 , grantee
3 , table_schema
4 , table_name
5 , privilege
6 from all_tab_privs
7 where table_name = 'T'
8 order by grantee;
GRANTOR GRANTEE TABLE_SCHEMA TABLE_NAME PRIVILEGE
---------- ---------- ------------ ---------- --------------------
USERT PUBLIC USERT T SELECT
USERT ROLEA USERT T SELECT
USERT USERA USERT T INDEX
USERT USERA USERT T INSERT
USERT USERA USERT T ALTER
USERT USERA USERT T SELECT
USERT USERA USERT T FLASHBACK
USERT USERA USERT T DELETE
USERT USERA USERT T REFERENCES
USERT USERA USERT T READ
USERT USERA USERT T ON COMMIT REFRESH
USERT USERA USERT T QUERY REWRITE
USERT USERA USERT T DEBUG
USERT USERA USERT T UPDATE
14 rows selected.
SQL> REVOKE ALL PRIVILEGES on T from userA;
Revoke succeeded.
SQL> select grantor
2 , grantee
3 , table_schema
4 , table_name
5 , privilege
6 from all_tab_privs
7 where table_name = 'T'
8 order by grantee;
GRANTOR GRANTEE TABLE_SCHEMA TABLE_NAME PRIVILEGE
---------- ---------- ------------ ---------- --------------------
USERT PUBLIC USERT T SELECT
USERT ROLEA USERT T SELECT
So the REVOKE ALL PRIVILEGES command removed all of the direct grants on table T from userA, but that user would still have SELECT privileges through the grant select to roleA (assuming userA has been granted the role) or the grant select to public.

Related

Want to grant select to a specific user on all tables

I use the below to grant select permission to amy on table1:
grant select schema.table1 to amy;
However, the below does not work:
grant select on schema.* to amy;
the error is
ORA-00903: invalid table name
Please advise what is wrong in my command. What I want is grant select to amy on ALL tables.
thanks
The syntax for the GRANT command (as of Oracle 21c) makes it clear that the granted item can only be a specific object:
on_object_clause:
The best you can do is create a role and grant the role to Amy, but you will still have to grant privileges on each individual table to the role.
create role analyst;
grant analyst to amy;
grant read on hr.countries to analyst;
grant read on hr.departments to analyst;
grant read on hr.employees to analyst;
To create a role and grant it to amy:
create role select_all_tables;
grant select_all_tables to amy;
alter user amy default role select_all_tables;
Use the following query to generate a script, which you can copy/paste and run to complete all the grants:
select 'grant select on '|| owner || '.' || table_name ||' to select_all_tables;'
from dba_tables where owner='SCHEMA';
copy and paste the output, and execute it as as script.
grant select on schema.table1 to select_all_tables;
grant select on schema.table2 to select_all_tables;
...
If you would rather grant the privileges directly and not use a role, alter the script query:
select 'grant select on '|| owner || '.' || table_name ||' to amy;'
from dba_tables where owner='SCHEMA';
and then run the output as a script:
grant select on schema.table1 to amy;
grant select on schema.table2 to amy;
...
grant select on table to public;
But be careful when you do that -- make sure it's what you really want to do.

In Oracle, Can you create a new table with the same groups if you use CTAS Query?

I use the query CTAS to create a new table, however, when CTAS has finished, other users canĀ“t select the new table, but they had access to the old, Is it a way to pass all the users and groups to the new table? because the old table will be deleted.
"A way" is to grant (at least) select privileges to all those users.
If you used a role and granted select privilege to that role, and then granted role to those users, things would be quite simpler - just grant select privilege on the new table to the same role, and everyone will "see" it.
Otherwise, you can write query to create those grant statements for you.
For example, in Scott's schema there's the EMP table. I've previously granted privileges on it to other users in my database, and now I'm going to create a "new" CTAS table and grant privileges to the same set of users.
SQL> create table my_new_table as select * from emp;
Table created.
SQL> select 'grant select on my_new_table to ' || grantee ||';' run_me
2 from all_tab_privs_made
3 where owner = 'SCOTT'
4 and table_name = 'EMP';
RUN_ME
---------------------------------------------------------------
grant select on my_new_table to SYS;
grant select on my_new_table to SUPERUSER;
grant select on my_new_table to MY_ROLE;
grant select on my_new_table to MIKE;
Now simply copy/paste the above bunch of grant statements:
SQL> grant select on my_new_table to SYS;
Grant succeeded.
SQL> grant select on my_new_table to SUPERUSER;
Grant succeeded.
SQL> grant select on my_new_table to MY_ROLE;
Grant succeeded.
SQL> grant select on my_new_table to MIKE;
Grant succeeded.
SQL>
If there's zillion of users, PL/SQL option would be simpler as it would do everything for you (i.e. no copy/pasting):
SQL> begin
2 for cur_r in (select grantee
3 from all_tab_privs_made
4 where owner = 'SCOTT'
5 and table_name = 'EMP'
6 )
7 loop
8 execute immediate 'grant select on my_new_table to ' || cur_r.grantee;
9 end loop;
10 end;
11 /
PL/SQL procedure successfully completed.
SQL>
If you create a table using CTAS from an existing one, the new one is a new segment, therefore it lacks of privileges. You need to recover the permissions granted to the old table and granting to the new one. For that you can use several alternatives ( dbms_metadata, dynamic sql ).
For the purposes , I'd do it like this
SQL> CREATE TABLE T2 AS SELECT * FROM T1 ;
SQL> begin
dbms_metadata.set_transform_param (dbms_metadata.session_transform,
'SQLTERMINATOR', true);
dbms_metadata.set_transform_param (dbms_metadata.session_transform, 'PRETTY',
true);
end;
/
select replace(dbms_metadata.get_dependent_ddl('OBJECT_GRANT', 'T1', 'OWNER_OF_T1' ),'T1','T2') AS ddl
from dual;
The first part is for creating in a nice format the list of necessary grants. The second part retrieves all the privileges granted to T1 and generates the list of grants statements for running to the T2 table. Then you only need to run the list of grants
As I said, there are several alternatives to do this.
Regards

Why in list of table privileges I can not see my table privileges?

I created the table and granted the select statement to the role. Then I grant the role to user. User can perform select statement on my table, but he can not see information about this privilege via SELECT * FROM USER_TAB_PRIVS;
Step-by-step below by HR user:
CREATE TABLE A1 (ID NUMBER);
Table A1 created.
CREATE TABLE A2 (ID NUMBER);
Table A2 created.
CREATE ROLE ROLE1;
Role ROLE1 created.
GRANT SELECT ON A1 TO ROLE1;
Grant succeeded.
GRANT SELECT ON A2 TO ROLE1;
Grant succeeded.
GRANT ROLE1 TO MAX;
Grant succeeded.
Then steps by user MAX:
SET ROLE ROLE1;
Role ROLE1 succeeded.
SELECT * FROM HR.A1;--successfull
SELECT * FROM USER_TAB_PRIVS;--successful, but no rows
Whre is the problem? Whi can clarify?
User MAX has no table privileges, only privileges on role ROLE1.
Use the USER_ROLE_PRIVS to show these privileges.
user_tab_privs is limited to the privileges of the connected/current user.
Table user_tab_privs is a table from Oracle dictionary. So i suggest a Oracle database.
After the grant select you will get an entry from user_tab_privs if you are connected as the user HR. If you use a dba user you have to query dba_tab_privs.

Unable to grant any privileges to user in oracle 11gR2 except create session

I am using oracle database 11g Release 2
I am able to create user and give it create session privileges, but I am unable to give it select privilege.
create user user1 identified by pass;
User created.
grant create session to user1;
Grant succeeded.
grant select on emp to user1;
Grant succeeded.
After this I connect as user1
Now when I run this statement it say
select * from emp;
oracle reply=
ERROR at line 1:
ORA-00942: table or view does not exist
Than I checked privileges to user1 using
select * from session_privs;
PRIVILEGE
---------------------------------
CREATE SESSION
Which means only create session privilege is available to user1. How can I give select privileges to user1?
Giving a use the SELECT privilege (or any other privilege for that matter) does not create a synonym. As user1, who is not the table's owner, you should still reference the table by its fully qualified name, with the owner.
Assuming the owner is called owner1, user1's query should be:
SELECT * FROM owner1.emp
As for the data dictionary query, this is also to be expected. These privileges are recorded in the [DBA|ALL|USER]_TAB_PRIVS views:
SELECT * FROM all_tab_privs WHERE grantee = 'USER1'

View loses its grants when modifying

Is it normal for an oracle view to loose all its grants when modifying the source SQL?
I am using SQL Developer if that has anything to do with it.
First of all, you don't have "grants" - "grant" is an operation. You have "roles" and "privileges".
Second, views have neither roles nor privileges themselves - schemas do have. Basically, a self-descriptive command is: grant select on view_1 to schema_1.
Third, schemas do not lose their privileges if you create or replace your view. Here's a quick sample:
11:03:07 #> conn system/sys#oars_sandbox
Connected.
11:03:15 SYSTEM#oars_sandbox> create user test1 identified by test1;
User created.
11:03:39 SYSTEM#oars_sandbox> create user test2 identified by test2;
User created.
11:03:48 SYSTEM#oars_sandbox> create view test1.view1 as select * from dual;
View created.
11:04:03 SYSTEM#oars_sandbox> grant select on test1.view1 to test2;
Grant succeeded.
11:04:15 SYSTEM#oars_sandbox> select grantee, owner, table_name, privilege, grantor from dba_tab_privs where grantee = 'TEST2';
GRANTEE OWNER TABLE_NAME PRIVILEGE GRANTOR
------------------------------ ------------------------------ ------------------------------ ---------------------------------------- ------------------------------
TEST2 TEST1 VIEW1 SELECT TEST1
11:05:13 SYSTEM#oars_sandbox> create or replace view test1.view1 as select * from dual;
View created.
11:05:24 SYSTEM#oars_sandbox> select grantee, owner, table_name, privilege, grantor from dba_tab_privs where grantee = 'TEST2';
GRANTEE OWNER TABLE_NAME PRIVILEGE GRANTOR
------------------------------ ------------------------------ ------------------------------ ---------------------------------------- ------------------------------
TEST2 TEST1 VIEW1 SELECT TEST1
However, it is quite possible that SQL developer invokes drop view first instead of create or replace. In this case, your privileges are automatically removed.
11:05:26 SYSTEM#oars_sandbox> drop view test1.view1;
View dropped.
11:10:21 SYSTEM#oars_sandbox> select grantee, owner, table_name, privilege, grantor from dba_tab_privs where grantee = 'TEST2';
no rows selected
11:10:24 SYSTEM#oars_sandbox> create or replace view test1.view1 as select * from dual;
View created.
11:10:26 SYSTEM#oars_sandbox> select grantee, owner, table_name, privilege, grantor from dba_tab_privs where grantee = 'TEST2';
no rows selected