Oracle 11g audit trail for specific tables - oracle

I would like to submit a question about creating an audit trail for specific tables on Oracle 11g database. We would like to track user's changes, on some specific tables, that records has been changed from the application (front end) side. Of course the first idea we came up with was to create manually audit tables and set triggers to track:
who is changing the data
what type of operation is it (I, U, D)
time of the operation
But I read that Oracle has in-build mechanism that can handle audit trails, but at this moment I don't know any details how is it working. So the main question is: "What is the best / most elegant, with easy and clear access to the data, way to perform audit tracking?"

First of all your auditing should be on by setting your audit_trail
parameter to a valid value like DB, DB_EXTENDED, XML,
XML_EXTENDED or OS with scope=spfile and restart database.
Next, you need to use audit commands for what you want to track, such
as :
audit drop user by access;
audit drop any procedure by access;
audit drop any table by access;
audit audit system by access;
audit grant any privilege by access;
audit insert, update, delete on myschema.mytable by access;
To track sessions by audit-trail it's advisible to use
Dbms_Session.Set_Identifier( :i_client );
to set client info, during connection phase of your program unit.
Dbms_Session.Set_Identifier sets the session's client id to the
given value. This value can be used to identify sessions in
v$session by means of v$session.client_identifier. It can also be
used to identify sessions by means of
sys_context('USERENV','CLIENT_IDENTIFIER').
This procedure is executable by PUBLIC.
In addition ;
Dbms_Application_Info.Set_Client_Info( :i_client );
Dbms_Application_Info.Set_Module( :i_modul,null );
-- :i_modul is the name of your module or program unit from which
-- you are connecting to db .
methods are also useful to monitor from gv$session view's client_info and module columns.

Related

Error during export dump file oracle using sql developer Version Version 18.1.0.095 Build 095.1630

I want to export dump file DDL my database (Oralce database version 11.2.0.4). I created user and granted permission (sysdba). I connected to database using user above, I choose View --> DBA --> Data Pump --> Data Pump Export Wizard --> choose connection above --> and it alert error "Cant use Data Pump as sys.".
Here's an interesting thing about SYS, it cannot use SERIALIZABLE transactions. This also applies to users connected as SYSDBA. Find out more.
The SERIALIZABLE isolation level means that all statements in a transaction are read consistent. The default for Oracle is READ COMMITTED, which applies at the statement level. The difference is this: if we run select * from T1 followed by select * from T2 under READ COMMITTED isolation level then we will any changes committed to T2 while we were querying T1. That is, the result sets for T1 and T2 are both consistent set of records, but we might have seen different results if we had run the queries the other way round. Whereas, under SERIALIZABLE the result sets are consistent with the start of the transaction. It doesn't matter what order we query the tables, the results are stable.
You can see why this is important for exporting. The entire set of exported tables must be consistent in order to guarantee the relational integrity of a subsequent import. We don't want to export a child table with records which depend on records added to the parent table after we exported it. (The old Export utility allowed us to set consistency=N - indeed that was the default! - but Data Pump protects us from ourselves).
So this is why we can't run exports as SYS, or SYSDBA users. Fortunately there is a simple solution: revoke SYSDBA from your user and grant it DATAPUMP_EXP_FULL_DATABASE and DATAPUMP_IMP_FULL_DATABASE roles instead. [Find out more][2].
I found answer to my question:
- when login we choose Role default
We need grant dba permission to user
Ex:
Grant dba to vinhhc_vsc;

create plsql trigger for any DML operations performed in any tables

I have around 500 tables in DB. If there is any DML operations performed on that table then trigger should be fired to capture those dml activities and should load it into an audit table. I dont want to write 500 individual triggers. Any simple method to achieve this?
To switch all high level auditing of DML statements for all tables:
AUDIT INSERT TABLE, UPDATE TABLE, DELETE TABLE;
What objects we can manage depends on what privileges we have. Find out more.
AUDIT will write basic information to the audit trail. The destination depends on the value of the AUDIT_TRAIL parameter. If the parameter is set to db the output is written to a database table: we can see our trail in USER_AUDIT_TRAIL or (if we have the privilege) everything in DBA_AUDIT_TRAIL.
The audit trail is high level, which means it records that user FOX updated the EMP table but doesn't tell us which records or what the actual changes were. We can implement granular auditing by creating Fine-Grained Audit policies. This requires a lot more work on our part so we may decide not to enable it for all our tables. Find out more.
Triggers are used on tables only, not the entire database. Ignoring the complexity of maintaining disparate data types, data use, context of various tables and their use, what you are looking for would be extremely complex, something no RDBMS has addressed at the database level.
There is some information on triggers at this link:
https://docs.oracle.com/cd/A57673_01/DOC/server/doc/SCN73/ch15.htm
You could place a trigger on each table that calls the same procedure ... but then all that complexity comes into play.

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.

Where will the record get inserted first?

I have a schema called "CUSTOMERS". In this schema there is a table called RECEIVABLES.
There is another schema called "ACCOUNTS". In this schema, there is a table called RECEIVABLES_AC.
RECEIVABLES_AC has a public synoym called RECEIVABLES.
The table structure of both the tables is exactly the same.
If your front-end uses the customer schema credentials to establish a connection, how can you ensure that the record will get inserted in RECEIVABLES_AC without changing the front-end code.
I think this is a trick question. Short of renaming the table RECEIVABLES in the CUSTOMERS schema, I don't see how this can be done.
The only way that I can think of (without changing the login or insert statement) is to use a database trigger that runs on login and changes the current schema to ACCOUNTS:
create or replace trigger logon_set_schema
AFTER LOGON ON DATABASE
BEGIN
if sys_context('USERENV','SESSION_USER') = 'CUSTOMERS' then
execute immediate 'alter session set current_schema=accounts';
end if
END;
/
However, this would likely break other aspects of the code, so changing the application to specify the schema name would be vastly preferable.
What isn't specified is if the behavior is supposed to be instead-of or in-addition-to.
Use replication on ACCOUNTS.RECEIVABLES to propagate DML to CUSTOMER.RECEIVABLES_AC. Triggers, streams, what have you.
Use the ALTER SESSION SET CURRENT_SCHEMA statement to change the default namespace of the user's session.
The right way to respond is to fix the design, and to not have multiple receivables tables with public schemas floating about.
Two good ways to solve this problem are:
Option 1
Rename CUSTOMERS.RECEIVABLES.
Drop the public synonym.
Create a private synonym in the CUSTOMERS schema, called RECEIVABLES that points to ACCOUNTS.RECEIVABLES_AC.
Option 2
Change the front-end to refer to RECEIVABLES_AC instead of RECEIVABLES.
Create a private synonym in the CUSTOMERS schema, called RECEIVABLES_AC that points to ACCOUNTS.RECEIVABLES_AC.
I would prefer Option 2. Private synonyms are a great way of controlling which tables are used by a particular schema, without having to hard-code the schema name in the app.

Difference between a user and a schema in Oracle?

What is the difference between a user and a schema in Oracle?
From Ask Tom
You should consider a schema to be the user account and collection of all objects therein
as a schema for all intents and purposes.
SCOTT is a schema that includes the EMP, DEPT and BONUS tables with various grants, and
other stuff.
SYS is a schema that includes tons of tables, views, grants, etc etc etc.
SYSTEM is a schema.....
Technically -- A schema is the set of metadata (data dictionary) used by the database,
typically generated using DDL. A schema defines attributes of the database, such as
tables, columns, and properties. A database schema is a description of the data in a
database.
I believe the problem is that Oracle uses the term schema slightly differently from what it generally means.
Oracle's schema (as explained in Nebakanezer's answer): basically the set of all tables and other objects owned by a user account, so roughly equivalent to a user account
Schema in general: The set of all tables, sprocs etc. that make up the database for a given system / application (as in "Developers should discuss with the DBAs about the schema for our new application.")
Schema in sense 2. is similar, but not the same as schema in sense 1. E.g. for an application that uses several DB accounts, a schema in sense 2 might consist of several Oracle schemas :-).
Plus schema can also mean a bunch of other, fairly unrelated things in other contexts (e.g. in mathematics).
Oracle should just have used a term like "userarea" or "accountobjects", instead of overloadin "schema"...
From WikiAnswers:
A schema is collection of database objects, including logical structures such as tables, views, sequences, stored procedures, synonyms, indexes, clusters, and database links.
A user owns a schema.
A user and a schema have the same name.
The CREATE USER command creates a user. It also automatically creates a schema for that user.
The CREATE SCHEMA command does not create a "schema" as it implies, it just allows you to create multiple tables and views and perform multiple grants in your own schema in a single transaction.
For all intents and purposes you can consider a user to be a schema and a schema to be a user.
Furthermore, a user can access objects in schemas other than their own, if they have permission to do so.
Think of a user as you normally do (username/password with access to log in and access some objects in the system) and a schema as the database version of a user's home directory. User "foo" generally creates things under schema "foo" for example, if user "foo" creates or refers to table "bar" then Oracle will assume that the user means "foo.bar".
This answer does not define the difference between an owner and schema but I think it adds to the discussion.
In my little world of thinking:
I have struggled with the idea that I create N number of users where I want each of these users to "consume" (aka, use) a single schema.
Tim at oracle-base.com shows how to do this (have N number of users and each of these users will be "redirected" to a single schema.
He has a second "synonym" approach (not listed here). I am only quoting the CURRENT_SCHEMA version (one of his approaches) here:
CURRENT_SCHEMA Approach
This method uses the CURRENT_SCHEMA session attribute to automatically
point application users to the correct schema.
First, we create the schema owner and an application user.
CONN sys/password AS SYSDBA
-- Remove existing users and roles with the same names.
DROP USER schema_owner CASCADE;
DROP USER app_user CASCADE;
DROP ROLE schema_rw_role;
DROP ROLE schema_ro_role;
-- Schema owner.
CREATE USER schema_owner IDENTIFIED BY password
DEFAULT TABLESPACE users
TEMPORARY TABLESPACE temp
QUOTA UNLIMITED ON users;
GRANT CONNECT, CREATE TABLE TO schema_owner;
-- Application user.
CREATE USER app_user IDENTIFIED BY password
DEFAULT TABLESPACE users
TEMPORARY TABLESPACE temp;
GRANT CONNECT TO app_user;
Notice that the application user can connect, but does not have any
tablespace quotas or privileges to create objects.
Next, we create some roles to allow read-write and read-only access.
CREATE ROLE schema_rw_role;
CREATE ROLE schema_ro_role;
We want to give our application user read-write access to the schema
objects, so we grant the relevant role.
GRANT schema_rw_role TO app_user;
We need to make sure the application user has its default schema
pointing to the schema owner, so we create an AFTER LOGON trigger to
do this for us.
CREATE OR REPLACE TRIGGER app_user.after_logon_trg
AFTER LOGON ON app_user.SCHEMA
BEGIN
DBMS_APPLICATION_INFO.set_module(USER, 'Initialized');
EXECUTE IMMEDIATE 'ALTER SESSION SET current_schema=SCHEMA_OWNER';
END;
/
Now we are ready to create an object in the schema owner.
CONN schema_owner/password
CREATE TABLE test_tab (
id NUMBER,
description VARCHAR2(50),
CONSTRAINT test_tab_pk PRIMARY KEY (id)
);
GRANT SELECT ON test_tab TO schema_ro_role;
GRANT SELECT, INSERT, UPDATE, DELETE ON test_tab TO schema_rw_role;
Notice how the privileges are granted to the relevant roles. Without
this, the objects would not be visible to the application user. We now
have a functioning schema owner and application user.
SQL> CONN app_user/password
Connected.
SQL> DESC test_tab
Name Null? Type
----------------------------------------------------- -------- ------------------------------------
ID NOT NULL NUMBER
DESCRIPTION VARCHAR2(50)
SQL>
This method is ideal where the application user is simply an
alternative entry point to the main schema, requiring no objects of
its own.
It's very simple.
If USER has OBJECTS
then call it SCHEMA
else
call it USER
end if;
A user may be given access to schema objects owned by different Users.
Schema is an encapsulation of DB.objects about an idea/domain of intrest, and owned by ONE user. It then will be shared by other users/applications with suppressed roles. So users need not own a schema, but a schema needs to have an owner.
--USER and SCHEMA
The both words user and schema are interchangeble,thats why most people get confusion on this words below i explained the difference between them
--User User is a account to connect database(Server). we can create user by using CREATE USER user_name IDENTIFIED BY password .
--Schema
Actually Oracle Database contain logical and physical strucutre to process the data.The Schema Also Logical Structure to process the data in Database(Memory Component). Its Created automatically by oracle when user created.It Contains All Objects created by the user associated to that schema.For Example if i created a user with name santhosh then oracle createts a schema called santhosh,oracle stores all objects created by user santhosh in santhosh schema.
We can create schema by CREATE SCHEMA statement ,but Oracle Automatically create a user for that schema.
We can Drop the schema by using DROP SCHEMA schama_name RESTRICT statement but it can not delete scehema contains objects,so to drop schema it must be empty.here the restrict word forcely specify that schema with out objects.
If we try to drop a user contain objects in his schema we must specify CASCADE word because oracle does not allow you to delete user contain objects.
DROP USER user_name CASCADE
so oracle deletes the objects in schema and then it drops the user automatically,Objects refered to this schema objects from other schema like views and private synonyms goes to invalid state.
I hope now you got the difference between them,if you have any doubts on this topic,please feel free to ask.
Thank you.
A user account is like relatives who holds a key to your home, but does not own anything i.e. a user account does not own any database object...no data dictionary...
Whereas a schema is an encapsulation of database objects. It's like the owner of the house who owns everything in your house and a user account will be able to access the goods at the home only when the owner i.e. schema gives needed grants to it.
A schema and database users are same but if schema has owned database objects and they can do anything their object but user just access the objects, They can't DO any DDL operations until schema user give you the proper privileges.
Based on my little knowledge of Oracle... a USER and a SCHEMA are somewhat similar. But there is also a major difference. A USER can be called a SCHEMA if the "USER" owns any object, otherwise ... it will only remain a "USER". Once the USER owns at least one object then by virtue of all of your definitions above.... the USER can now be called a SCHEMA.
User: Access to resource of the database. Like a key to enter a house.
Schema: Collection of information about database objects. Like Index in your book which contains the short information about the chapter.
Look here for details
For most of the people who are more familiar with MariaDB or MySQL this seems little confusing because in MariaDB or MySQL they have different schemas (which includes different tables, view , PLSQL blocks and DB objects etc) and USERS are the accounts which can access those schema. Therefore no specific user can belong to any particular schema. The permission has be to given to that Schema then the user can access it. The Users and Schema is separated in databases like MySQL and MariaDB.
In Oracle schema and users are almost treated as same. To work with that schema you need to have the permission which is where you will feel that the schema name is nothing but user name. Permissions can be given across schemas to access different database objects from different schema. In oracle we can say that a user owns a schema because when you create a user you create DB objects for it and vice a versa.
Schema is a container of objects.
It is owned by a user.
Well, I read somewhere that if your database user has the DDL privileges then it's a schema, else it's a user.

Resources