Preventing a user from dropping its' own trigger - oracle

I have created a read only user A in Oracle DB. (who can access schema X but cannot alter anything) Then i am asked to give user A create table privilege on schema X.
However as far as i know, i can either give create any table privilege to user A or create table privilege. One of them is for creating table on his/her own schema, other one is for creating table on all schemas, which should not be preferred.
So i have given create any table privilege to user A and then created a trigger which prevents user A from creating a table on schemas other than X.
HOWEVER,
I needed to create the trigger as user A, and now user A can easily drop that trigger because A is the owner.
Is there any way i can prevent user A from dropping triggers even if he/she's the owner ?
As far as i experienced,user A does not need to have drop any trigger or administer database trigger privileges since trigger is already his/her own.
Is there any workaround for this ? Or should i search for an alternative way to give create table permission on other schemas.
Thank you in advance.

No, there is no way to prevent a user from dropping an object that it owns.
There's also no way to directly allow for user A to create objects in user X's schema, unless you start granting "ANY" privileges.
One possible workaround may be to create a stored procedure in user X's schema that will create objects in user X's schema (execute immediate) and grant EXECUTE privilege on said stored procedure to user A.
So, in this way, user A could do something like:
exec create_in_x_schema('create table blah(a number)');
And that procedure would just do an execute immediate on the string passed in.
A procedure that looks something like:
create or replace procedure create_in_x_schema(doit varchar2)
begin
execute immediate doit;
end;
/
ought to do it.
(Code is untested, but should give you some idea.)
Hope that helps.

Related

Grant create any trigger vs grant create trigger

In Oracle you can grant system privileges like
GRANT CREATE TRIGGER TO MY_USER;
But you can as well grant privileges this way
GRANT CREATE ANY TRIGGER TO MY_USER;
As system privileges are system-wide, where is the difference between the 2 statements above. Does the additional ANY-keyword grant anything else more than system? If I add a Grant ... ON SCHEMA ... it's no system privilege anymore, is it?
Assumption is that there are multiple schemas/objects in the database from different users one cannot access without these privileges.
EDIT:
SELECT *
FROM DBA_SYS_PRIVS
WHERE grantee = 'MY_USER';
returns
GRANTEE PRIVILEGE
------------ -------------
MY_USER CREATE ANY TRIGGER
MY_USER CREATE TRIGGER
(I omitted the columns ADMIN_OPTION and COMMON)
And the result is the same when querying this with MY_USER, MY_USER2 or any other user. I see no connection to a schema here. And it is also possible to only have the CREATE ANY TRIGGER-privilege.
In most cases, the trigger owner is also the owner of the table (or view) on which the trigger is based. In those cases, the table owner, with CREATE TRIGGER can create create triggers on their own table.
CREATE ANY TRIGGER allows the user to create a trigger owned by any user on any table. It is a big security hole because they can create a trigger owned by a privileged user on a table that they own or can insert into. Because they can insert into that table, they can force the trigger to execute and the trigger executes with the privileges of the trigger owner. The effect is that a user with CREATE ANY TRIGGER privilege can create and execute code as a privileged user (similar to having CREATE ANY PROCEDURE plus EXECUTE ANY PROCEDURE).
Limit to as few as people as possible and audit appropriately.
The first statements grants the right to create triggers in the schema of MY_USER. The owner will always by MY_USER.
The second statements grants the right to create triggers in ANY schema. The owner of the trigger can then be any user.
The last option is usually not wanted because it gives user MY_USERS the possibility to corrupt the data model.

How to determine who owns a schema (PL/SQL)

I am new to PL/SQL Developer, and I used the File->New->Table option to create a new table. After using the GUI to set up my table descriptions, when I click "apply" I get the error "no privileges on table space".
I tried googling a solution and I read that I need to give the owner of the schema privileges to modify this table. How do I determine who the owner of a schema is so that I can give them privileges?
Is there another solution to this issue that I do not know of?
You have created the table, so it belongs to you, there is no need to grant something on schema level.
A different story altogether is the tablespace in which the table is created. There, you need a quota. With a privileged user, you can give the quote like so:
alter user <your-username>
quota unlimited on <tablespace-name>;
You need someone with sysdba privileges on the database your schema belongs to (typically a DBA) to grant your schema the necessary privileges to create objects (tables, procedures etc), along with a quota on the tablespace in question.

I want to auto increment a column and make it as a primary key in oracle10g. But on trigger creation I get an error

I have created a Sequence for the table and on creation of a trigger I got the following error:
ORA-04089: cannot create triggers on objects owned by SYS.
Can someone explain me what is it and how can it be solved? Since I'm a beginner, is there a simple way to solve it?
MY TABLE NAME IS-testing.
create sequence example_seq
start with 1
increment by 1
nomaxvalue;
create trigger example_trigger
before insert on testing
for each row
begin
select example_seq.nextval into :new.id from dual;
end;
The error message is quite clear:
ORA-04089: cannot create triggers on objects owned by SYS.
So obviously you are logged in as SYS, and creating objects in that user;s schemas. You must not do this. SYS is the user who owns the data dictionary and all the objects which manage the database. Changing the SYS schema is, at best, bad practice and runs the risk of corrupting the database. Find out more.
What you need to do is create a new user, for your application objects. This is quite simple. Connect as SYSTEM (avoid using SYS for menial tasks):
create user your_name_here identified by << password >>
/
grant create session, create table, create sequence, create trigger
to your_name_here
/
Obviously you will need to grant more privileges. The full list is in the documentation.
Once you've created your new user you can connect to it and create all the objects you desire.

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.

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