I know this sounds weird but it's an old project that I'm trying to make work.
I have two schemas SchemaA and SchemaB each one with it's own user.
I'm writing a plsql script in a package in SchemaB, but in this script I need to delete records from a table in SchemaA. But there is a trigger that won't let the delete happen.
So to make it work I have to do this command:
EXECUTE IMMEDIATE 'ALTER TRIGGER SchemaA.TDA_K$TriggerA DISABLE';
But when I do that I get ORA-01031 which is logical since SchemaB cannot disable a trigger From SchemaA
My question is, how can I GRANT the permission on the trigger (or table utilizing that trigger), to SchemaB to be able to disable it.
As per Oracle documentation
" Prerequisites
The trigger must be in your own schema or you must have ALTER ANY TRIGGER system privilege.
In addition, to alter a trigger on DATABASE, you must have the ADMINISTER database events system privilege.
"
Related
create or replace TRIGGER pdb_startup
AFTER STARTUP ON DATABASE
BEGIN
EXECUTE IMMEDIATE 'alter pluggable database all open';
END;
i try to made this trigger but i have insufficient privileges
To create a system trigger you must have the "ADMINISTER DATABASE TRIGGER" privilege.
While I don't work with PDB/CDB arrangements, what you are trying to do looks a bit strange. Normally we control database status through scripts external to the database, not in triggers. Are you sure this is the appropriate way to open your PDBs? I would also want to know whether this could deadlock on the library cache. At any rate, any DDL would require that a trigger be declared with the AUTONOMOUS_TRANSACTION pragma.
I would like to somehow protect databases on my SQL Server from being deleted without entering a password, even by someone with administrative access. There are times where a database has been deleted accidentally (for example, when two databases have similar names) and I'd like to prevent this from being an easy mistake to make.
I'm also open to any suggestions or alternative ideas on how to handle this. Thank you!
Create a Server Level Trigger that Rolls back any attempt to delete a database.
The Trigger will need to be disabled then re-enabled to perform any legitimate deletions.
USE [master]
GO
CREATE TRIGGER [Trig_Prevent_Drop_Database] ON ALL SERVER
FOR DROP_DATABASE
AS
RAISERROR('Dropping of databases has been disabled on this server.', 16,1);
ROLLBACK;
GO
DISABLE TRIGGER [Trig_Prevent_Drop_Database] ON ALL SERVER
GO
Or as a process:
Create a single-column, one row table in Master that will hold a database name.
Insert the name of the database in the Table.
Add an If statement to the trigger to check if the Database being dropped is identical to the Database in the table created in step 1. Otherwise Roll-back.
In this case you wouldn't need to disable the Trigger. But you're creating 2 points in the process where you define the database name.
Capturing the Database Name in a Server Level Trigger should be possible with:
SELECT CAST(eventdata().query('/EVENT_INSTANCE/DatabaseName[1]/text()') as NVarchar(128))
I have to implement a financial application. One of the acceptance criteria is:
"The data may never change."
Therefore I need to prevent update and delete operations on the database, because it will be deployed on machines owned and administrated by the customer.
Is this even possible? Maybe with triggers? If not, are there any other databases that can prevent update and delete?
The easiest way is via roles, such as a query role. Grant select on the list of tables to that role, and grant that role to the user of your application. You can of course create others such as an admin role with update and delete privileges, to be granted later on when needed.
Example:
CREATE ROLE FIN_APP_INS_SEL_ROLE;
GRANT INSERT, SELECT on <table1> to FIN_APP_INS_SEL_ROLE;
GRANT INSERT, SELECT on <table2> to FIN_APP_INS_SEL_ROLE;
GRANT CONNECT, FIN_APP_INS_SEL_ROLE to <app_user>;
You can also make tablespaces read only,
ALTER TABLESPACE <name> READ ONLY;
or the entire database read only.
ALTER DATABASE OPEN READ ONLY;
It turns out to be impossible.
There is no way to grant an INSERT privilege without allowing to UPDATE. As I understand it, the INSERT privilege is interpreted as may alter data of that table.
What is the best way to prevent changes to a database or verify the integrity of this, so that it can not be altered from an application created for this database.
assuming you have a username and password to access the database permits reading - writing.
requirements:
The user has write permissions
Do not depend on a particular system like (MySQL, Oracle, SQL Server)
solution I'm looking for is not based on the user's permissions on the database
Most modern databases allow you to grant reading and writing permissions but while disallowing DDL commands like ALTER TABLE.
Do not give users that should not alter the DB structure permission to execute DDL.
If by "Alter" you mean change any data rows, rather than the database structure, you can grant the user only SELECT rights.
The user or account that your application uses must be granted permissions from the database server. Typically permissions include things like:
Select
Insert
Update
Delete
Alter
Drop
Only give the user account the permissions needed; in other words, don't grant Alter permission, and the application (or anyone using the same login) won't be able to alter tables.
Two strategies: 1) if you are running SQL Server, Oracle, DB2, etc, you can configure permissions so users are reader/writer by default (which means no alter permissions). 2) you can periodically check to see if someone has changed the data structure or even set up a DB trigger to detect changes and record who/when, etc (depends on your DB platform)
I have a sproc (call it client.UpdateClient) that is executed by a SQL User (call it MyWCFServicesUser.
MyWCFServicesUser has datareader and datawriter permissions on the database. It also has execute permissions on the sproc (but no other permissions).
The sproc will insert a row into client.Client with SET IDENITY_INSERT client.Client ON.
When I run this sproc (from SSMS) with integrated security (I am sa), everything works fine.
When I run it as MyWCFServicesUser (from SSMS) it fails with this error:
Msg 1088, Level 16, State 11, Procedure UpdateClient, Line 33
Cannot find the object "client.Client" because it does not exist or you do not have permissions.
I usually have all my sprocs and tables in the default (dbo) schema, but this time I am trying to not use dbo.
Is that why I don't have permissions? Do I need to elevate the sproc somehow? Or the user? Or somehow change the schema?
I am stumped...
Turns out that SET IDENTITY_INSERT requires alter permissions by the user.
The proper way to resolve privilege requirements in store procs is to use code signing. This way you grant the required privilege (ie. ALTER TABLE) to the procedure, not to the user, and you need only grant EXECUTE on the procedure (or schema) to the user. The advantage is that your low privilege user can only invoke the procedure and do whatever action requires the elevated privilege (ie. setting identity_insert on) as controlled by the procedure. Had you been grant the required privilege directly to the user he/she could use it for any operation permitted by said privilege (eg. add columns, drop constraints etc etc). The link has several examples.
That being said, I must call out that your question is about SET IDENTITY_INSERT, which is a special setting normally used for one-time data load. The fact that you are setting this from what seems like a routine CRUD UpdateClient procedure is a bit of a code smell.
what will matter is who is the owner of the objects you mentioned.
Any chance they were created by different users? Maybe sa is the owner of the table and MyWCFServicesUser owns the proc?
See this link about Ownership Chains http://msdn.microsoft.com/en-us/library/ms188676.aspx it may help you on your investigation