grant select any table from one specific schema - oracle

I have just created a new read only user (TEMPDBREAD) for our developers # our oracle Database 11.2.0.4
Now they like read access to all tables from just one schema (TEMPDBUSER)
is there an alternative to grant select any table.
They should not be able to read the other schemes. But since the table structure often changes, it is difficult to justify everything manually.
That's why select any table is awarded very quickly and easier to place
Can i deny the access to the other schemes anyway?
Any Idea how i can solve this very simple?
BR Julian
Grant Table Access manually
Grant Select ANY Table

Nope. You either give them select any table and let them read any table in the database or you give them access to each table in TempDBUser individually. In the vast, vast majority of cases, you'd want to give them access to each table in TempDBUser (presumably via a role because there will be many developer accounts that need to run queries).
It isn't clear to me why giving object-level access is problematic for you. "Table structure changes" do not require new grants since they're just changes to existing objects. If you really mean that new tables are created frequently, you'd just want to incorporate the grants into your change control and deployment process.
If you have a packaged application that creates new tables periodically (a terrible practice), you could create a DDL trigger that issued the grant every time a new table was created in TempDBUser. You'd need a DDL trigger that submitted a job via the dbms_job package that did the actual grant which is a rather convoluted architecture but it works.

spool /tmp/grant_issue.sql
select 'grant select on TEMPDBUSER.' || table_name || ' TO TEMPDBREAD;' from dba_tables where owner='TEMPDBUSER' ;
spool off;
run the spool file.
sqlplus #/tmp/grant_issue.sql

Related

How to GRANT SELECT to ANY Table in a Schema to a Role (Oracle)

We wish to create an ANALYTICS role on our Oracle database. Anyone in this ANALYTICS role should be able to SELECT across any views in one (or more) schemas, but not ALL schemas.
We have a schema called ARIEL for example, and when we create new tables and views, we don't want to have to constantly apply GRANTS to the ANALYTICS role, and so we are hoping there is a way to apply a grant like this "GRANT SELECT ON ALL TABLES IN SCHEMA_X TO ANALYTICS"...note ANALYTICS is a role, not a schema.
Our DBA is saying this is not possible, and any future objects we create will need to have a grant applied, giving access to the ROLE.
"Our DBA is saying this is not possible, and any future objects we create will need to have a grant applied, giving access to the ROLE."
Your DBA is correct. You are searching for schema wide privileges(not implemented yet).
More: GRANT SELECT on all tables in a schema
Your DBA is correct that there would need to be a grant for every object that is created. It is possible to automate this which gives you basically the behavior that you want. I've done this in the past. But I'd seriously question the requirement before implementing it.
In general, new tables aren't created in production automatically, they're created as part of a build process. Part of that build process involves doing things like figuring out who should have access to the tables. Assuming that you're going through some sort of source control system, that means that you've got a history of the grants on objects and you can tie back changes in those grants to user stories. That's a useful thing to have.
If you have applications that are creating new tables in production dynamically (like an off the shelf app I was supporting) or doing something else where giving grants as part of a build process would be problematic, you can automate the process with a DDL trigger.
Create a DDL trigger that fires when a table is created
In that DDL trigger, use dbms_job to run a grant statement immediately after the CREATE TABLE statement commits
Something like this should work (untested)
CREATE OR REPLACE TRIGGER ddl_create
AFTER CREATE ON SCHEMA
DECLARE
l_job BINARY_INTEGER;
l_sql VARCHAR2(4000);
BEGIN
IF ora_dict_obj_type = 'TABLE'
THEN
l_sql := 'grant select on ' ||
ora_dict_obj_owner || '.' || ora_dict_obj_name ||
' to analytics';
DBMS_JOB.SUBMIT (
job => l_job,
what => l_sql );
END IF;
END;
Since the job runs asynchronously, it is possible that it will take a second or two to run after the table is created which may be an issue if the application immediately tries to run a query on the object. It is also possible that your DBA may disable jobs or limit the number of jobs that can run simultaneously which could further delay the grant. And if something goes wrong with the trigger or the job, this is a sufficiently obscure approach that it is going to take people a while to figure out where the problem is. DBAs aren't in the habit of looking for DDL triggers that may be granting privileges when someone decides, say, that they want a new role to automatically get insert access on the new table or when a grant didn't happen because jobs were disabled.

Allow another user to access my Oracle table

I would simply like to allow a colleague to view and edit the Database I've created.
I've tried:
GRANT ALL on FISHTABLE to CDEMARES;
and it returned Grant succeeded but nothing changed for him and he still wasn't able to view my table.
I also tried
GRANT SELECT smahala.fishtable to cdemares#sole.nefsc.noaa.gov;
but that failed with SQL Error: ORA_00990: missing or invalid privilege.
Is my issue that I don't have the administrative authority to allow someone else to view my Oracle table? Any advice is appreciated, thanks.
Your colleague needs to prefix your table with your schema name, otherwise Oracle doesn't know where to look for it, e.g.:
select * from smahala.fishtable
If they don't do that, and simply try to use:
select * from fishtable
then Oracle will look for the table in their own schema, and then look for a view, or a private synonym, or a public synonym. Your colleague could create a synonym if they'll be accessing this table a lot (and they don't have their own table with the same name). It's also possible to change their session's current schema, but that will make it harder to see their own objects.
You can read more about object naming and how to refer to objects in the documentation.
SQL Developer allows you to browse objects in other schemas. If your colleague was connected when you granted the permissions, they can refresh the object list, or disconnect and reconnect. Either way they should then be abke to see your table under your schema.
(Your second grant statement is missing an on, and you can't grant permissions across a database link, if that's what you're trying to do.)

Grant Select on All VIEWS [current and future] in Schema X

I have a situation in our Oracle environment where I would like to be able to grant select permissions to a certain user/group on all views in a particular schema.
I realize that I could write a dynamic statement to iterate over all the views in the schema and grant permissions to them individually as shown here but I would like to be able to have this apply to all views that exist in the schema now or in the future.
I was also contemplating the possibility of writing a DDL trigger that could monitor for the creation of new views but setting permissions in a trigger isn't something I've seen done before and doesn't seem like accepted practice.
Basically, is there a VIEW analog to the GRANT EXECUTE ANY PROCEDURE?
The EXECUTE ANY PROCEDURE grant allows a user to execute any procedure in any schema in the database, not just those in a particular schema. You can grant a user the SELECT ANY TABLE privilege-- that will allow the user to query any table or view in any schema in the database not just those in a particular schema. That's the analogous privilege, it just seems unlikely that either is really what you're after.
Since views should not be created dynamically, this sort of requirement would normally be handled by simply including the appropriate GRANT statements in the scripts that create the new views which get promoted up through the environments. Dynamically granting privileges is generally frowned upon because it generally implies that you have issues with your change control process that need to be addressed.
I have, for third party applications that insist on creating new objects periodically, created a DDL trigger that grants privileges on new objects. In order to do that, you would need to submit a job that actually does the GRANT. A GRANT is a DDL statement so it issues an implicit commit and implicit commits aren't allowed in triggers, you have to have a separate job that runs moments after the object is created. This means that you end up with a number of moving pieces that generally makes your environment more complex.

Oracle synonym randomly not viewable

here's a tricky case on which 5 peoples including a DBA have been struggling on for days... I offer lifetime consideration to the one which will identify the root cause of the issue.
here it is:
Oracle Client: 10g
Oracle Server: 11g
We have 2 schemas and 1 user:
SCHEMA1
SCHEMA2
USER
We have 1 table 'TOTO' which is defined in SCHEMA1 (SCHEMA1.TOTO)
We have a private synonym of table 'TOTO', called 'TOTO' defined in SCHEMA2, created like this:
CREATE SYNONYM SCHEMA2.TOTO FOR SCHEMA1.TABLE1;
We have granted SELECT,UPDATE,DELETE,INSERT priviledges on "SCHEMA2.TOTO " (so on the synonym) to SCHEMA2 (so that any session ran from SCHEMA2 has access to the synonym table)
GRANT SELECT, UPDATE, DELETE, INSERT ON SCHEMA2.TOTO TO SCHEMA2;
Our application connects to the DB with USER, then directly switches to SCHEMA2:
ALTER SESSION SET CURRENT_SCHEMA=SCHEMA2;
Then after that, it tries to perform a select query on the synonym table WITHOUT prefixing the synonym name by SCHEMA1 (this is a constrain of the framework we use):
SELECT COL FROM TOTO;
Most of the times this query works successfully, which is what we expect since we have altered our session to SCHEMA2, by default that where the objects are looked.
But sometimes it fails, with an ORA-00942: table or view does not exist error.
I insist on the fact that between the time when it works and when it fails, nothing has changed, we've just restarted the application (which is of course re-connecting to the DB the same way at each startup).
We've been investigated with a DBA monitoring all the events on USER,SCHEMA1,SCHEMA2 hoping to find an external process modifying the GRANTS on one of thoses, between a success and a failure, but nothing changes. Yet, at some point, randomnly we get the ORA-00942 error, then we restart the application several times and it's back again...
Would someone have an idea or any suggestion/hint that could lead us to identify what we're missing here?
Many thanks for your help!
The grant should go to USER, not to SCHEMA2:
GRANT SELECT, UPDATE, DELETE, INSERT ON schema1.toto TO userxy;
This should solve the problem. If it doesn't, can you please post the result of
SELECT * FROM all_objects WHERE object_name='TOTO';

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