Grant delete on newly created table in Oracle - 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.

Related

ORA-00942: Table or View not exist connecting with another user

in Oracle SQL developer I got error ORA-00942: Table or View not exist connecting with another user when I do the following:
CREATE USER marta IDENTIFIED BY 'marta';
GRANT SELECT, INSERT ON myTable TO marta;
so then, executing:
CONNECT marta/marta;
INSERT INTO myTable VALUES ('1', 'foo', bar');
got the ORA-00942...
Obviusly, If I use system user I can insert row with no issues.
I searched other answers but I couldnt solve this... what is wrong
Obviusly, If I use system user I can insert row with no issues.
Uh-oh. There's nothing obvious about that. The SYSTEM user should not own a table called MY_TABLE (or whatever application table that is actually named). The SYSTEM user is part of the Oracle database, its schema is governed by Oracle and using it for our own application objects is really bad practice.
But it seems you have created a table in that schema and user MARTA can't see it. That's standard. By default users can only see their own objects. They can only see objects in other schemas if the object's owner (or a power user) grants privileges on that object to the other user.
So, as SYSTEM
grant select on my_table to marta;
Then, as MARTA
select * from system.my_table;
To avoid prefixing the owning schema MARTA can create a synonym:
create or replace synonym my_table for system.my_table;
select * from my_table;
But really, you need to stop using SYSTEM for your own tables.

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.

Oracle Create Table without Insert permission

Is it possible in oracle dbms for a user to have the permission to create a table but not have the permission to insert in it although the same user just created it?
Thank you in advance!
Short answer:
No, it's not.
Longer answer:
You can do pretty much anything you want. If you want to restrict insert access the usual method would be to create the table in a different schema. Assuming you have a table emp in the schema hr, which you wanted to access from the schema 'users`:
You would grant users permission to SELECT from the table emp when connected as hr:
grant select on emp to users
or, if you also want users to be able to UPDATE emp:
grant select, update on emp to users
Lastly, when connected as users, you prefix the table name with the schema it is located in:
select * from hr.emps
You can now select from the table but not insert into it.

Create a user who can only query data from a tablespace (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.

Schema, User and functional Id in Oracle

I confused lot in oracle about schema, user and functional id. Let consider my two different cases
Case I :
Let us consider SCOTT#ORCL.If we think SCOTT is user. while creating user alone it ll create a schema. Correct me If i am wrong. In this case while we were creating SCOTT user alone SCOTT schema was created. Suppose If we create another schema say X . Is this possible to SCOTT user owns X schema ?
Case II :
Let us consider SCOTT#ORCL.If we think SCOTT is schema alone i-e which is created by schema command alone. If it is so then what is the use of schema w/o any user who is going to own it.
I heard oracle function ID is one which will connect several user/schema(i don't know whether I can put schema/user here ) in a data base. is there is difference b/w oracle functional ID with user/schema ?
Many people find this topic confusing, because we tend to bandy around USER and SCHEMA interchangeably, when they are in fact separate if related entities.
A schema is the collection of database objects owned by a user. When we create a user we create their schema at the same time. Initially their schema is empty.
It is easy to demonstrate that USER and SCHEMA are distinct, because we change the current schema in the session. This just means we can reference objects in another user's schema without prefixing them with the owner's name.
SQL> desc t1
Name Null? Type
----------------------------------------- -------- -------------
ID NUMBER
SQL> alter session set current_schema=APC
2 /
Session altered.
SQL> desc t1
ERROR:
ORA-04043: object t1 does not exist
SQL> sho user
USER is "X"
SQL>
In this case, either APC doesn't have a table called T1 or he hasn't granted it to X. The only way X can see her own table is to prefix it with her own name, or switch the current schema back to herself.
To answer your first question, the schema always has the same name as the user. So it is not possible for SCOTT to own schema X; schema X is owned by user X.
To answer your second question, it is impossible to create a schema without a user.
True, there is a CREATE SCHEMA command, but this requires the prior creation of the user. It is actually not creating a schema but creating several database objects. In effect it is more of a ADD OBJECTS TO SCHEMA command.
SQL> conn sys as sysdba
Enter password:
Connected.
SQL> create user x identified by x
2 default tablespace users quota 10m on users
3 /
User created.
SQL> grant create session, create table to x
2 /
Grant succeeded.
SQL> conn x/x
Connected.
SQL> create schema authorization x
2 create table t1 (id number)
3 create table t2 (id number)
4 /
Schema created.
SQL> select table_name from user_tables
2 /
TABLE_NAME
------------------------------
T1
T2
SQL>
The CREATE SCHEMA command is pretty limited: we can create tables, views and indexes, and grant privileges on objects. The advantage of it is simply that we can create several objects in a single transaction, so that all the creates are rolled back if one fails. This is not possible when we run each create statement separately.
Not sure what you're thinking off when you mention "function ID". It's not a standard piece of Oracle functionality.
This does not define the difference between an owner and schema.
But I have always struggled with the idea that I create N number of users....when I want each of these users to "consume" (aka, use) a single schema.
This guy shows how to do this (have N number of users...get "redirected" to a single schema.
I will paste his code as well, on the off-chance the URL link dies in the future.
http://www.oracle-base.com/articles/misc/schema-owners-and-application-users.php
He has a second "synonym" approach. But I am only pasting the CURRENT_SCHEMA version.
AGAIN, I take NO credit for this. I just hate when someone says "your answer is at this link" and BOOM, the link is dead. :<
......................................................
(from http://www.oracle-base.com/articles/misc/schema-owners-and-application-users.php)
CURRENT_SCHEMA Approach
This method uses the CURRENT_SCHEMA session attribute to automatically point application users to the correct schema.
First, we create the schema owner and an application user.
CONN sys/password AS SYSDBA
-- Remove existing users and roles with the same names.
DROP USER schema_owner CASCADE;
DROP USER app_user CASCADE;
DROP ROLE schema_rw_role;
DROP ROLE schema_ro_role;
-- Schema owner.
CREATE USER schema_owner IDENTIFIED BY password
DEFAULT TABLESPACE users
TEMPORARY TABLESPACE temp
QUOTA UNLIMITED ON users;
GRANT CONNECT, CREATE TABLE TO schema_owner;
-- Application user.
CREATE USER app_user IDENTIFIED BY password
DEFAULT TABLESPACE users
TEMPORARY TABLESPACE temp;
GRANT CONNECT TO app_user;
Notice that the application user can connect, but does not have any tablespace quotas or privileges to create objects.
Next, we create some roles to allow read-write and read-only access.
CREATE ROLE schema_rw_role;
CREATE ROLE schema_ro_role;
We want to give our application user read-write access to the schema objects, so we grant the relevant role.
GRANT schema_rw_role TO app_user;
We need to make sure the application user has its default schema pointing to the schema owner, so we create an AFTER LOGON trigger to do this for us.
CREATE OR REPLACE TRIGGER app_user.after_logon_trg
AFTER LOGON ON app_user.SCHEMA
BEGIN
DBMS_APPLICATION_INFO.set_module(USER, 'Initialized');
EXECUTE IMMEDIATE 'ALTER SESSION SET current_schema=SCHEMA_OWNER';
END;
/
Now we are ready to create an object in the schema owner.
CONN schema_owner/password
CREATE TABLE test_tab (
id NUMBER,
description VARCHAR2(50),
CONSTRAINT test_tab_pk PRIMARY KEY (id)
);
GRANT SELECT ON test_tab TO schema_ro_role;
GRANT SELECT, INSERT, UPDATE, DELETE ON test_tab TO schema_rw_role;
Notice how the privileges are granted to the relevant roles. Without this, the objects would not be visible to the application user. We now have a functioning schema owner and application user.
SQL> CONN app_user/password
Connected.
SQL> DESC test_tab
Name Null? Type
----------------------------------------------------- -------- ------------------------------------
ID NOT NULL NUMBER
DESCRIPTION VARCHAR2(50)
SQL>
This method is ideal where the application user is simply an alternative entry point to the main schema, requiring no objects of its own.

Resources