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

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.

Related

How to use Oracle trigger to clone user

I would like to know how to use "oracle triggers" to clone a user or copy all the roles and rights from one user to other.
The procedure should contain two parameter. One source user and other target user.
I wouldn't use a trigger for that. A trigger is a stored program unit that gets executed when one of the following operations occur:
DML statement on a table or view
DDL statement by a particular user
Database event
The list doesn't contain an event that triggers the cloning of a user. Besides, triggers don't have parameters like old or new users.
This overview explains nicely what triggers can do.

Oracle - deploying objects into a different schema

I'm surprised I haven't been able to find this question on the site already. Apologies if it turns out to be a duplicate!
In Oracle (10 upwards) is it possible for USER_A to deploy objects in USER_B's schema?
For example, assuming I am logged in as USER_B:
CREATE OR REPLACE PACKAGE user_a.my_example_pkg IS
PROCEDURE Make_Log;
PROCEDURE Init;
END user_a.my_example_pkg;
I get an ORA-1031: insufficient privileges response when I deploy.
I know that it is possible to log in as USER_A to deploy the package, and yes I can do that. But the point is that on my database, someone appears to have modified a package "across the schema" in this way. And I need to figure out how they did it!!
I'm fairly sure that the privilege exists, but I can't find what it is. Moreover, if there are many privileges which allow this to be done, it would be a bonus to get an exhaustive list of what those privileges are.
You'd want to look for the ANY privileges
CREATE PROCEDURE lets you create procedures in your schema. CREATE ANY PROCEDURE lets you create procedures in any schema.
CREATE TABLE lets you create tables in your schema. CREATE ANY TABLE lets you create tables in any schema.
CREATE VIEW lets you create views in your schema. CREATE ANY VIEW lets you create views in any schema.
For any of the CREATE privileges, there is a corresponding CREATE ANY privilege. Those ANY privileges are extremely powerful and really shouldn't be given to anyone other than a DBA since it would allow you to do things like create procedures owned by highly privileged users that can do anything a DBA could do.

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.

Add username into another table while creating a new Oracle user

I am creating a simple application where I am using a Servlet and JDBC to create users.
Is there any way I can use a trigger to insert the username into another table when the Oracle user is created with:
create user xyz ......
Once this query executes successfully, it inserts the user information in the DBA_USERS table.
I want the username to also be inserted into another table. Should I add it to that other table manually through JDBC, or can I create a trigger to do it automatically?
You could use a system trigger based on the create user DDL (but not a DML trigger on the dba_users view - you can't do that anyway, but don't even think about trying to do anything based on the data dictionary). But you wouldn't really have any way for that to know if the user being created is actually an application user - you'd be assuming any user added to the DB could only be related to your application.
Since you have to take other steps anyway - such as granting roles and/or privileges, maybe adding other application security data, etc., it probably makes more sense to do the table insert manually.
It may even make more sense to put all the user-creation code into a stored (and probably packaged) procedure, and just call that over JDBC; the downside of that is that the create user and any other DDL would need to be executed from within the procedure as dynamic SQL. Any of your own table inserts would be together though, and you'd only have that single JDBC call to make.
You can also have other procedures to modify and delete users.
Something to bear in mind, however you do it, is that DDL implicitly commits. Not necessarily a problem, just something to be aware of, so you can order the steps in a recoverable way.

Do Grant permissions Cascade?

This is hopefully a quick one, i'm new to oracle so need to check something before it bites me on the posterior
Ok i have a function that modifies a table
if i give the user permission to execute the function do they also need permission to update and insert in the table or is the fact they are approved to use the function enough?
the reason i ask is that the users need to edit these tables but only via approved functions which perform complex validation that can't be done easily via constraints
It depends on how you define your procedure, specifically the AUTHID property:
The AUTHID property of a stored PL/SQL unit affects the name resolution and privilege checking of SQL statements that the unit issues at run time.
By default the procedures are created with a AUTHID value of DEFINER (definer's right) ,the functions are executed as if the caller were temporarily given the rights of the definer.
With a value of CURRENT_USER, the AUTHID property will make the procedures check the privileges of the caller at run-time.
In your case, the scenario you describe would fit with the property value of DEFINER (the default): the users will only be able to call the procedures and functions without direct access to the underlying tables. A similar scenario is described in the documentation:
Scenario: Suppose that you must create an API whose procedures have unrestricted access to its tables, but you want to prevent ordinary users from selecting table data directly, and from changing it with INSERT, UPDATE, and DELETE statements.
Solution: In a special schema, create the tables and the procedures that comprise the API. By default, each procedure is a DR unit, so you need not specify AUTHID DEFINER when you create it. To other users, grant the EXECUTE privilege, but do not grant any privileges that allow data access.

Resources