Create a user who can only query data from a tablespace (oracle) - oracle

I have 3 users in my oracle Database
user_admin
user
user_query
The user_admin have dba rol.
user have connect and resource rol
and user_query the same as user.
I want to configure the last one to deny him of all kind of insert,update,delete but form the full tablespace not from a table, view or procedure...
The point is to have a secure-only-querying data user.
But i can't do it for a tablespace, at least as far i know.
Any idea?

You can loop through all table that use the tablespace in question and grant select. I would try to stay away from powerful privs like "SELECT ANY TABLE", as that would apply to the entire database.
For example, if your tablespace is named XXX then:
BEGIN
FOR tbl IN (SELECT owner, table_name
FROM dba_tables dt
WHERE dt.tablespace_name = 'XXX') LOOP
EXECUTE IMMEDIATE 'GRANT SELECT ON ' || tbl.owner || '.' || tbl.table_name || ' TO USER_QUERY';
END LOOP;
END;

there is the following which grants select to any table or view (except those owned by SYS):
grant select any table to user_query;
It doesn't restrict to a single tablespace though - any table in the entire database would be available for select.

Firstly, the use of the CONNECT and RESOURCE roles is discouraged, and documented as such.
That aside, no, there is no privilege for granting by tablespace, or even by user. For one thing, a partitioned table or index can use multiple tablespaces, none of which might be the default for that object.
Grants are at the object level. You could create a procedure to grant privileges to a user (or better to a role) based on the tablespace of a table though.

Related

Truncate table privilege without stored procedures

SYSTEM creates several tables, and would like to grant userA the ability to truncate tables. On oracle's docs, the minimum privilege is :
GRANT DROP ANY TABLE TO userA
https://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_10007.htm#SQLRF01707
DROP ANY TABLE as stated is too powerful of a privilege to be granted to a user, and from looking around there is no way to limit the tables the user can truncate with it.
The proper way as previous topics has touched on is to use stored procedures:
CREATE OR REPLACE procedure truncateTables
AS
BEGIN
execute immediate 'TRUNCATE TABLE table1';
end;
/
GRANT EXECUTE on system.truncateTables TO userA;
However, if I want to avoid using any stored procedures at all, is there an alternative way to allow a user that is not the table owner to truncate tables, but not with a privilege that is potentially destructive like "DROP ANY TABLE" ?
You cant do it without procedure.
you can do it dynamically like this:
CREATE OR REPLACE procedure pr_truncate_table(p_table_name varchar2) is
begin
execute immediate 'truncate table ' || p_table_name || '';
end;
/
A work-around that I have used is to grant delete to the other user, then use a delete instead of truncate to remove the rows. This is NOT a proper truncate as it does not clear the used storage, but it allows the same tasks to be achieved.
With the table owner account
GRANT delete on Table_Name to "User_Account";
With the other account
Delete from Table_Name where 1=1;

What Oracle privilege is to be granted to a role so it allows users to see tables in Oracle SQL Developer schema

Using Oracle 12c, I have a role which I have granted basic CRUD operations to using Oracle SQL Developer. The problem is, users of the group can not see the list of tables in Oracle SQL Developer. All they see is the branch that shows a tables node but there is no plus sign to expand and see the tables for the one schema they need to work with. What other privilege needs to be granted to the group so they can see all the table nodes for their schema when using Oracle SQL Developer? Thanks in advance.
If I understood you correctly, you
created a role
granted certain privileges to that role
created bunch of users
granted role (from step 1) to those users
but they still don't see anything.
If that's so, they won't see anything regardless of what you grant - it is because they don't have those objects in theirs schemas.
What you (or they) should/could do is to precede table name with owner name while selecting data from those tables. Suppose that there's a table named EMPLOYEE and your users want to select data from it - they should run select * from robertcode.employee (presuming that user robertcode owns that table)
Although it works, users won't be happy because they don't know table names. Therefore, create a script which they will run in their schemas - that script will create synonyms to your tables.
In order to do that, write query which will create query:
SQL> select 'create synonym ' || table_name || ' for ' || table_name ||';'
2 from user_tables;
'CREATESYNONYM'||TABLE_NAME||'FOR'||TABLE_NAME||';'
--------------------------------------------------------------------------------
create synonym EMP for EMP;
create synonym BONUS for BONUS;
create synonym SALGRADE for SALGRADE;
create synonym DEPT for DEPT;
Copy/paste all those create synonym ... statements into an e-mail message and let them create synonyms for themselves.
They still won't see anything under the Tables node (because those users don't have tables (until they create them in their own schema), but will see something in Synonyms.

Grant insert/update access to schema

I have a request to grant user TOM Insert/Update access to all the tables on a schema JERRY.
I use the following query achieve it.
FOR x IN (SELECT * FROM user_tables)
LOOP
EXECUTE IMMEDIATE 'GRANT SELECT ON ' || x.table_name || ' TO <<someone>>';
END LOOP;
After granting the rights on the existing tables, i have to create few more tables on JERRY schema. Will TOM have insert/update access to those newly created tables?
If NO do i need to execute the above statement every time i create a new table?
or is there a way to grant access to the whole schema?

Grant delete on newly created table in Oracle

A script has to be run as user A.
This script creates a table B.temptable .
Then the script has to delete from B.temptable.
This gives an error ORA-01031:Insufficient privileges.
How can I give user A permission to delete rows from this newly created table and any other tables in the schema of user B?
My preferred solution consists of a (grant?) statement that can be run by user C to make user A able to delete records from any table for user B.
Details:
User A has the create any table permission as well as the drop table permission.
The user B is a 'temp' schema that is used by other users as well to store data that is used to perform processing of other data in other schemas.
User A is granted permission on the schema by user C, who is an administrator user with permissions on all schemas.
The table is created with the following statement (columns and tablenames obfuscated):
create table tmp_schemaB.mytemptable as
select cola, colb, colc from
(
select s.*,
ROW_NUMBER() OVER (PARTITION BY cola order by colb) rn
from schemaA.myorgtable s
)
where rn=1;
Then I will process the rows in the table in batches and delete them after processing.
As #AlexPoole says the correct solution to this problem would be to stop dropping and recreating a permanent table, and use a Global Temporary Table instead. However, it seems this is not an option "because of conventions that are made in our team".
An alternative solution would be to create the non-temporary table with just the rows you actually need, by adding a WHERE clause to the CREATE TABLE B.temptable AS SELECT * FROM ... statement.
If what you want is a table with no rows use a WHERE clause which returns an empty set:
CREATE TABLE B.temptable AS SELECT * FROM whatever
where 1 = 2
/
This avoids the problem of granting DELETE on B.temptable. Of course it doesn't solve the problem of privileges to INSERT records or indeed querying the table.
B owns the table, so either B or a user with DBA privileges has to grant permissions on it to A.
Perhaps B could own a definer-rights procedure that performed grants, and grant execute permission on that procedure to A.
create or replace procedure grant_delete
( p_table user_tables.table_name%type
, p_grantee user_users.username%type )
as
begin
-- Filtering here (e.g. temp tables only, name matches some pattern etc, else fail)
-- Log the request
execute immediate 'grant delete on '||p_table||' to '||p_grantee;
end grant_delete;
/
grant execute on grant_select to A;
Alternatively, B could own a procedure that dynamically deletes from a table, and grant execute on that to A similarly to the above, so that A could request B to perform the deletion.
None of this is particularly secure, but the requirement seems to demand something insecure.
The statement
Grant delete any table to A
can be run as user C to give A the rights to delete from any table in any schema.
There is no grant statement that restricts the delete permission to just one user/schema.

Revoke ANY Privileges Oracle

Hi I have this question.
Is posibble GRANT ANY privileges excluding some tables of the same schema.
For Example:
EXECUTE IMMEDIATE
'CREATE USER USREJECUTA_SUI_ABAS
IDENTIFIED BY VALUES ''test''
DEFAULT TABLESPACE USERS
TEMPORARY TABLESPACE TEMP
PROFILE DEFAULT
ACCOUNT UNLOCK';
-- 2 Roles for USREJECUTA_SUI
EXECUTE IMMEDIATE 'GRANT CONNECT TO USREJECUTA_SUI_ABAS';
EXECUTE IMMEDIATE 'GRANT RESOURCE TO USREJECUTA_SUI_ABAS';
EXECUTE IMMEDIATE 'ALTER USER USREJECUTA_SUI_ABAS DEFAULT ROLE ALL';
-- 1 System Privileges for USREJECUTA_SUI
EXECUTE IMMEDIATE 'GRANT SELECT ANY TABLE TO USREJECUTA_SUI_ABAS';
EXECUTE IMMEDIATE 'GRANT UPDATE ANY TABLE TO USREJECUTA_SUI_ABAS';
EXECUTE IMMEDIATE 'GRANT INSERT ANY TABLE TO USREJECUTA_SUI_ABAS';
EXECUTE IMMEDIATE 'GRANT UNLIMITED TABLESPACE TO USREJECUTA_SUI_ABAS';
Now revoke the permissions from some tables
REVOKE INSERT,UPDATE ON VELITTDA.TAPROVEEDORESXPAIS FROM USREJECUTA_SUI';
but the system launch this error:
ORA-01927: cannot REVOKE privileges you did not grant.
Do you kow some wat to do this? I will apreciate a lot your help.
No, you can't. If you give someone SELECT ANY TABLE, you've given them the ability to query any table in the database. You can't revoke object-level privileges when you haven't granted object-level privileges.
The proper approach is almost always to create a role that has object-level privileges on the actual set of objects that the user needs access to. Grant the role to the user (and any other users that need a similar set of privileges). The various ANY roles are really only appropriate for folks like DBAs.
Granting the SELECT ANY TABLE (or any other ANY TABLE) privilege is generally the wrong thing to do and is almost as bad as granting DBA to arbitrary schema users.
If you are trying to avoid issuing a lot of grant statements, then use the simple trick of generating your DDL from the data dictionary.
set head off
set pagesize 0
spool grant_foo.sql
select 'GRANT SELECT ON '||table_name||' TO FOO_ROLE;'
from all_tables where owner = 'FOO'
order by table_name
;
spool off
Then edit grant_foo.sql as needed before executing.

Resources