Checking snapshots out of refresh groups in Oracle - oracle

I have an Oracle Database with a schema A, which has select privilege on DBA_* views.
I also have an schema B that doesn't have these privilege, but it has a lot of materialized views.
In schema A, there are three refresh groups, each one having some materialized views from schema B.
I'd like to check whether there are snapshots out of the refresh groups, but I'd like to do this check connected as B.
I'm using the following query to perform this check in schema A:
SELECT OWNER, NAME FROM DBA_SNAPSHOTS WHERE OWNER = 'B'
MINUS
SELECT OWNER, NAME FROM DBA_REFRESH_CHILDREN WHERE RNAME IN ('REFRESH_G1','REFRESH_G2','REFRESH_G3');
The problems:
B doesn't have privileges on DBA_* views (and It can't have)
If I change DBA_* views for ALL_* views, B can't see the refresh groups (and I can not grant alter any materialized view to B)
So:
Is there another way to perform this check in B?
Or is there another way to make B see the refresh groups?
Or is there a way to "freeze" the result of the query using ALL_* views, such as B will see the result of the query as A?
Thanks!

On A
CREATE OR REPLACE VIEW V_REFRESH_SNAPSHOT AS
SELECT OWNER, NAME FROM DBA_SNAPSHOTS WHERE OWNER = 'B'
MINUS
SELECT OWNER, NAME FROM DBA_REFRESH_CHILDREN WHERE RNAME IN ('REFRESH_G1','REFRESH_G2','REFRESH_G3');
GRANT SELECT ON A.V_REFRESH_SNAPSHOT TO B;
From B
SELECT * FROM A.V_REFRESH_SNAPSHOT;

Related

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.

Privileges on views/synonyms vs on underlying tables

Referring to here and here
Would a user need both SELECT /INSERT/DELETE/UPDATE, etc. privileges on the view AND on the underlying table to be able to perform these actions ? Or privileges on EITHER table/view is enough ?
In other words, consider a user A owning the table T and the view V (constructed from T). Can a user B with SELECT right on V execute a SELECT if he does not SELECT right on T, and vice-versa ? If he could, wouldn't that mean the View privilege "overrides" the table privilege, as A does not give him right over T ?
Update
In a related question, how about synonym ? From what I understand in a book, users need both SELECT privileges on the synonym and the underlying table. This will be different from views.
On the other hand, Oracle seems to indicate that synonyms behave similar to views.
A user can be granted the SELECT privilege on a synonym or a view
without being explicitly granted the SELECT privilege on the
originating table
Update 2
Following everyone's answer that we only need the privileges on view to select the table (at least what the view sees from the table) and no privilege on table is needed, let's consider this scenario :
Table T belongs to A
A GRANT SELECT ON T to B (without GRANT OPTION)
B CREATE VIEW V AS SELECT * FROM A.T
B GRANT SELECT ON V TO C
C performing SELECT * FROM B.V
According to what you have said, C will be able to select from V, therefore equivalent to selecting from T. Is it that cheating ? B is effectively letting C seeing A.T although C does not have the right on T and B does not have GRANT OPTION. Is there a security hole somewhere ?
One of the fundamental uses of views is to protect privacy. A base table may have confidential information that some users don't need to see (for example, in an employee table, you may have salary). Some users need access to query (select), or to update, only certain fields from the base table, without having access to the full information. For example: select phone number, or update address (but no access to see salary or bonus). Then one would create a view and give those users "select" and "update" privileges on the view only, and not on the base table. (The select still goes against the base table, but the COLUMNS will be limited to those included in the view... updates can/will be made to the base table, but again, only for values in the columns included in the view.) The view can limit not only the columns, but also the rows - for example, with a WHERE clause in the view, you may exclude the CEO from the view completely.
So, one of the main uses of views is based exactly on that: some users may have privileges on the view, but not on the base table.
Yes. Usually the view runs as the view owner, and the user runs with permission on the view. So user b only needs access to the view.
However when looking at this sort of question, you may want to look into row level security as well. This works by granting access to a portion of the table to a given user or group (i.e. effectively enforcing where clauses at the end of queries). Depending on your use case, it may be simpler or more complex to manage.

Synonyms & materialized view

I have two tables. a) student b) restricted_student.
two users a) admin b) user
one synonyms stu for both the users. in admin it refer to student but for user it refer to restricted_student.
I want to create a materialized view MV .
The code of materialized view look like
CREATE MATERIALIZED VIEW SELECT TABLE_NAME,COLUMN_NAME FROM USER_TAB_COLUMNS;
such that if i am connected to admin then it should refer to student and for user it should refer to restricted_student by passing the only synonyms name stu.
something like
SELECT TABLE_NAME,COLUMN_NAME FROM USER_TAB_COLUMNS E='st';
the result i wanted when i connected to user it should give the restricted_student table columns. whereas whenever i connected to admin it should give the student table columns.
I created all the above objects.but materialized view is not giving the expected result as i want.
You can use a normal view where you can union these 2 tables and filter by the user logged in.
Also check Oracle RLS (row level security), https://docs.oracle.com/cd/B28359_01/network.111/b28529/intro.htm
Irrespective of the application and user, you can control how the where clause should be. That way you have a much higher control over the records that is queries.
For example,
Admin user
select * from stu;
Normal user
select * from stu;
Would have completely different results, based on the predicate you set for RLS.

How to solve tora issue of "object can not be described"

in tora program when i press f4 to open any table this massage appear "Object TABLE_NAME (DB_USER) cannot be described",
please, how to solve.
The permissions are the issue:
A user account only allows a successful login
Permissions to view a table is granted by the table owner
Use a SELECT statement of the ALL_OBJECTS data dictionary view to see which tables you have access to:
SELECT * FROM ALL_OBJECTS
Use the DBA_TABLES data dictionary view to see all tables:
SELECT * FROM DBA_TABLES
References
Managing Security for Oracle Database Users
The Data Dictionary
Catalog Views/Data Dictionary Views
Tables Data Dictionary Views
Data Dictionary Translation Support
ALL_OBJECTS
Syntax for Schema Objects and Parts in SQL Statements
torasql - knowhow:debugger
Granting Object Privileges on Behalf of the Object Owner
ALTER USER
DBMS_DESCRIBE, 1 of 2
DBMS_DESCRIBE, 2 of 2

Granting permission to users on different schema

I have tables in Schema A. I created views in Schema B using the tables in schema A.
I want to grant permissions to a user to select the data from view in Schema B.
For this to work i know we have to enable the grant option on tables in Schema A to user B.
But I want to do it in a single script (This script has to be in schema B). Is there a way to do this using the user name/password of schema A.
It's not unusual to want to have a single script to deploy a change. The thing is, such a script needs to be run by a power user, because it needs to have system privileges at the ANY level. This usually means a DBA account, preferably an application account but otherwise SYSTEM or SYS.
So the script you want would look like this:
grant select on user_a.t23 to user_b
/
grant select on user_a.t42 to user_b
/
create view user_b.v_69 as
select t23.col1, t42.col2
from user_a.t42
join user_a.t23
on (t42.id = t23.id)
/
grant select on user_b.v_69 to user_c
/
A common scenario is that we have a suite of individual scripts which have been written to be run by different users but which we now need to bundle up into a single deployment. The original scripts don't contain the schema names, and there are many good reasons why we wouldn't want to hardcode them in the scripts.
One way to build that master script is to use change the CURRENT_SCHEMA syntax:
alter session set current_schema=USER_A
/
#run_grants_to_userb.sql
alter session set current_schema=USER_B
/
#create_view69.sql
#run_grants_to_userc.sql
We still need a DBA user to run the master script. One advantage of switching the current schema is that it allows us to deploy objects like database links, which through a quirk of syntax cannot have the schema name in their declaration. One gotcha is that the user doesn't change, so a script which employs the USER pseudo-column may produce unwanted results.
Simply Run the query
GRANT INSERT, SELECT, UPDATE, DELETE ON TABLE1 TO SCHEMA2;
Only by connecting as user A at some point. You can still do it in one script if you really want to:
connect userA/passwordA
grant select on my_table to userB;
connect userB/passwordB
create view my_view as select * from userA.my_table;
Of course now you have a script lying around which exposes two sets of user credentials to anyone who can read it. So something to think hard about before doing in production, for example.
If you want other users to be able to select from the view, you don't need to grant explicit permissions on userA.my_table to them; as long as the view owner can see the underlying table, other users just need to be able to see the view. Which is often kinda the point (or one of them) as you can restrict the view to only expose selected data from the underlying table to the rest of the world. I assume you have a reason for not creating the view in schema A.
I'm not sure if you're really asking about granting select to user B with admin option so that user B can then grant select on user A's table to other people. If that's possible, it doesn't sound like a good idea, and isn't necessary for the view to work.
Let user A grant select on his tables to B and include the 'grant option'.
As user A:
GRANT select ON table TO user_b WITH GRANT OPTION;
Let user B grant select on his views to user A and include the 'grant option'.
As user B:
GRANT select ON view TO user_a WITH GRANT OPTION;
As user A:
GRANT select on user_b.view TO user_c;
This allows user A to pass this grant on to other users.

Resources