How to export users in Oracle with its roles and system privileges using expdp? - oracle

I am trying to export a schema/user in Oracle with its roles and system privileges. I don't want to export any data or any table. I have tried to export users using the following command.
expdp system/system#gisdblocal include=user DIRECTORY = TestBack
logfile=test12.log DUMPFILE=test12.dmp SCHEMAS=test_replication
When I import this in other database or in the same database with a different name i.e
impdp system/system#gisdblocal DIRECTORY = TestBack DUMPFILE = test12.dmp
SCHEMAS = test_replication REMAP_SCHEMA =
test_replication:test_replication_copy
the user or schema is created but it has not been granted any role or system privileges.
I am doing this because I have created a backup of a schema using the user that did not have the required rights DATAPUMP_IMP_FULL_DATABASE or DATAPUMP_EXP_FULL_DATABASE. When I restore that backup in another database, it says the user does not exist. Therefore, I am thinking to create a user with the same privileges first and then restore the backup.

Using SQL...
SELECT dbms_metadata.get_ddl('USER', :name)
FROM dual
UNION ALL
SELECT dbms_metadata.get_granted_ddl('ROLE_GRANT', grantee)
FROM dba_role_privs
WHERE grantee = :name
AND ROWNUM = 1
UNION ALL
SELECT dbms_metadata.get_granted_ddl('DEFAULT_ROLE', grantee)
FROM dba_role_privs
WHERE grantee = :name
AND ROWNUM = 1
UNION ALL
SELECT dbms_metadata.get_granted_ddl('SYSTEM_GRANT', grantee)
FROM dba_sys_privs sp,
system_privilege_map spm
WHERE sp.grantee = :name
AND sp.privilege = spm.name
AND spm.property <> 1
AND ROWNUM = 1
UNION ALL
SELECT dbms_metadata.get_granted_ddl('OBJECT_GRANT', grantee)
FROM dba_tab_privs
WHERE grantee = :name
AND ROWNUM = 1
UNION ALL
SELECT dbms_metadata.get_granted_ddl('TABLESPACE_QUOTA', username)
FROM dba_ts_quotas
WHERE username = :name
AND ROWNUM = 1
:name being...a bind variable for the USER you want to re-create.

Related

Oracle: How to drop role, which has no owner with admin option

I have a role in oracle database. The role was created by some user (unknown), but currently no user has admin option on the role.
I know that the role exists:
SELECT * FROM DBA_ROLES WHERE ROLE = 'roleName';
The query returns the role.
No user has admin option
SELECT rp.grantee, rp.granted_role, rp.admin_option
FROM dba_role_privs rp
JOIN dba_users u
ON rp.grantee = u.username
WHERE admin_option = 'YES'
AND rp.granted_role = 'roleName'
ORDER BY grantee, granted_role;
The query returns nothing
I need drop the role.
I don't know, how this situation appeared, because for all other roles, some user with admin option exists. Could someone help me?
Thanks

How to extract ddl for oracle db links?

Is there anyway to extract ddl for all database links?
I would like to get in sql and recreate them via sql.
I can use below and it works for PUBLIC user but for non public user it doesn't give me db link owner.
Set long 1000
SELECT DBMS_METADATA.GET_DDL('DB_LINK',db.db_link,db.owner) from dba_db_links db;
Sample link owner and name
Owner db_link
public link1
public link2
user1 link3
If I ran above select it will give me below, #3 doesn't have username in it.
Output from above SELECT
1. create public database link "link1" using "db_alias"
2. create public database link "link2" using "db_alias"
3. create database link "link3" using "db_alias"
I recreate links using SYS and don't want to create #3 as SYS user.
Seems that even as SYS user you can't easity create dblink for another user (except of public dblink).
Even if you run create database link your_user.link3 using "db_alias" it's owner will be SYS.
Possible hacks are connect as another user (you may add conn into SQL*Plus script if you have credentials)
Or create procedure for user that need to have dblink that run create database link command with parameters and call it from sys.
this should help with links that do a "connect to"
SELECT MYCOMMAND
FROM
(
select trim(l.owner)||'__'||trim(l.db_link)||'__'||trim(l.username) ||'__'||trim(l.host) , '10'
, ' connect '||trim(l.owner)||'/CCCCCCCC#'||TRIM(INSTANCE_NAME)
AS MYCOMMAND
from dba_db_links l , V$INSTANCE i , dba_users u
where l.username = u.username
and l.username is not null
and l.username <> ' '
UNION ALL
select trim(l.owner)||'__'||trim(l.db_link)||'__'||trim(l.username)||'__'||trim(l.host) , '20'
, ' DROP DATABASE LINK '||trim(l.db_link)||' ; ' AS MYCOMMAND
from dba_db_links l , V$INSTANCE i , dba_users u
where l.username = u.username
and l.username is not null
and l.username <> ' '
UNION ALL
select trim(l.owner)||'__'||trim(l.db_link)||'__'||trim(l.username)||'__'||trim(l.host) , '30'
, ' CREATE DATABASE LINK '||trim(l.db_link)
||' CONNECT TO "'||trim(l.username)||'"'
||' IDENTIFIED BY "NNNNNNNN" '
||' USING '||trim(l.host) ||' ; 'AS MYCOMMAND
from dba_db_links l , V$INSTANCE i , dba_users u
where l.username = u.username
and l.username is not null
and l.username <> ' '
ORDER BY 1,2,3
)
To get ddl from db links, run the output of the command below:
set pages 999;
set long 90000;
SELECT 'SELECT dbms_metadata.get_ddl(''DB_LINK'',''' || db_link || ''',''' || owner || ''') FROM dual;'
FROM dba_db_links
WHERE db_link
IN ('DB_LINK1',
'DB_LINK2',
'DB_LINK3');
For create a db link for other user, with user SYS execute the DDL below:
CREATE DATABASE LINK "OWNER.DBLINK_NAME"
CONNECT TO "USER" IDENTIFIED BY "Password_user"
USING 'ALIAS';

Checking for specific permissions of Oracle users

Problem: I am working on a query that will produce a list of all Oracle users. I wish to determine in the query if they have the specific grant permissions for CONNECT and APPUSER and show them in a single table.
What I have tried: I am using one table, DBA_ROLE_PRIVS. This table shows all the information I need, but am failing to query it correctly. I can show all users who have permission to Connect with:
SELECT GRANTEE as "User Name", granted_role as "Connect"
FROM DBA_ROLE_PRIVS
WHERE GRANTED_ROLE='CONNECT';
I can also show users who have permission to APPUSER, simply by replacing CONNECT with APPUSER.
My problem is showing both permissions in one query. I have tried using different JOINs. However, using that seems to require two tables or more. I have researched a "self-join", but do not understand how to use two WHERE clauses. I have tried things like:
SELECT grantee as "User Name", t1.granted_role as "Connect", t2.granted_role as "APPUSER"
FROM t1.DBA_ROLE_PRIVS join t2.DBA_ROLE_PRIVS on t1.GRANTEE = t2.GRANTEE
WHERE t1.GRANTED_ROLE='CONNECT' and t2.GRANTED_ROLE='APP_USER';
I want my final query to show something like:
User Name Connect App User
---------- ---------- ----------
Bob CONNECT APPUSER
Sue APPUSER
Nick CONNECT APPUSER
Rob CONNECT
SELECT GRANTEE as "User Name", granted_role from DBA_ROLE_PRIVS where GRANTED_ROLE in ('CONNECT','APPUSER');
if you need one row for each user and two column for each access, you can use this
select c.GRANTEE as "User Name", a.granted_role as "Connect", c.granted_role as "APPUSER"
FROM
(SELECT GRANTEE, granted_role from DBA_ROLE_PRIVS where GRANTED_ROLE = 'CONNECT') a,
FULL OUTER JOIN
(SELECT GRANTEE, granted_role from DBA_ROLE_PRIVS where GRANTED_ROLE = 'APPUSER') c
on a.GRANTEE = c.GRANTEE;

Oracle select schema depending on select-statement

I have have two schemas with the same table. e.g schema1.adress and schema2.adress.
Both tables are identical.
Layout of table customer:
customerno: integer
name: varchar2(50)
Now I want to get the customers of schema 1 using something like
"select * from customer where schemaname = 1" or
"select * from customer where schemaname = 2"
Is there a mechanism in Oracle that can switch the schema depending on a criteria in a select-statement?
Before you ask: for a new project I have to query legacy schemas. I cannot change the schema, but I can set any permission on the schema / user.
Any ideas?
Thanks for any response,
Sven
You could create a private synonym for the user for the schema.table you want them to access,
create synonym user1.customer for schemaname1.customer;
create synonym user2.customer for schemaname2.customer;
Then your queries would always just be select * from customer;
So you are logged in as the same user both when you want to select from schema1.customer and select from schema2.customer?
A possible way can be something like:
select *
from (
select 'schema1' schema$name, c.* from schema1.customer c
union all
select 'schema2' schema$name, c.* from schema2.customer c
)
where schema$name = 'schema1'
If you can create views, it can be an idea to create a view like:
create or replace view customer_view as
select 'schema1' schema$name, c.* from schema1.customer c
union all
select 'schema2' schema$name, c.* from schema2.customer c
That makes it possible to do:
select *
from customer_view
where schema$name = 'schema1'
Whether you use view or not, Oracle optimizer can in most cases like this push the predicate "where schema$name = 'schema1'" into the UNION ALL and then it recognizes that it does not need to access schema2.customer at all.

How to find the privileges and roles granted to a user in Oracle? [duplicate]

This question already has answers here:
How to show all privileges from a user in oracle?
(7 answers)
Closed 2 years ago.
I am using Linux, Oracle10g.
I have created one user called test. and granted create session and select any dictionary permission to the same user.
i also granted sysdba and sysoper roles to the same users.
Now i want to display all the privileges and roles granted to the user.
I found following query but it shows only create session and select dictionary privileges.
select privilege
from dba_sys_privs
where grantee='SAMPLE'
order by 1;
please help to resolve the issue.
Thanks
In addition to VAV's answer, The first one was most useful in my environment
select * from USER_ROLE_PRIVS where USERNAME='SAMPLE';
select * from USER_TAB_PRIVS where Grantee = 'SAMPLE';
select * from USER_SYS_PRIVS where USERNAME = 'SAMPLE';
Look at http://docs.oracle.com/cd/B10501_01/server.920/a96521/privs.htm#15665
Check USER_SYS_PRIVS, USER_TAB_PRIVS, USER_ROLE_PRIVS tables with these select statements
SELECT * FROM USER_SYS_PRIVS;
SELECT * FROM USER_TAB_PRIVS;
SELECT * FROM USER_ROLE_PRIVS;
None of the other answers worked for me so I wrote my own solution:
As of Oracle 11g.
Replace USER with the desired username
Granted Roles:
SELECT *
FROM DBA_ROLE_PRIVS
WHERE GRANTEE = 'USER';
Privileges Granted Directly To User:
SELECT *
FROM DBA_TAB_PRIVS
WHERE GRANTEE = 'USER';
Privileges Granted to Role Granted to User:
SELECT *
FROM DBA_TAB_PRIVS
WHERE GRANTEE IN (SELECT granted_role
FROM DBA_ROLE_PRIVS
WHERE GRANTEE = 'USER');
Granted System Privileges:
SELECT *
FROM DBA_SYS_PRIVS
WHERE GRANTEE = 'USER';
If you want to lookup for the user you are currently connected as, you can replace DBA in the table name with USER and remove the WHERE clause.
Combining the earlier suggestions to determine your personal permissions (ie 'USER' permissions), then use this:
-- your permissions
select * from USER_ROLE_PRIVS where USERNAME= USER;
select * from USER_TAB_PRIVS where Grantee = USER;
select * from USER_SYS_PRIVS where USERNAME = USER;
-- granted role permissions
select * from ROLE_ROLE_PRIVS where ROLE IN (select granted_role from USER_ROLE_PRIVS where USERNAME= USER);
select * from ROLE_TAB_PRIVS where ROLE IN (select granted_role from USER_ROLE_PRIVS where USERNAME= USER);
select * from ROLE_SYS_PRIVS where ROLE IN (select granted_role from USER_ROLE_PRIVS where USERNAME= USER);
IF privileges are given to a user through some roles, then below SQL can be used
select * from ROLE_ROLE_PRIVS where ROLE = 'ROLE_NAME';
select * from ROLE_TAB_PRIVS where ROLE = 'ROLE_NAME';
select * from ROLE_SYS_PRIVS where ROLE = 'ROLE_NAME';
SELECT *
FROM DBA_ROLE_PRIVS
WHERE UPPER(GRANTEE) LIKE '%XYZ%';
select *
from ROLE_TAB_PRIVS
where role in (
select granted_role
from dba_role_privs
where granted_role in ('ROLE1','ROLE2')
)
always make SQL re-usuable: -:)
-- ===================================================
-- &role_name will be "enter value for 'role_name'".
-- Date: 2015 NOV 11.
-- sample code: define role_name=&role_name
-- sample code: where role like '%&&role_name%'
-- ===================================================
define role_name=&role_name
select * from ROLE_ROLE_PRIVS where ROLE = '&&role_name';
select * from ROLE_SYS_PRIVS where ROLE = '&&role_name';
select role, privilege,count(*)
from ROLE_TAB_PRIVS
where ROLE = '&&role_name'
group by role, privilege
order by role, privilege asc
;
The only visible result I was able to understand was first to connect with the user I wanted to get the rights, then with the following query:
SELECT GRANTEE, PRIVILEGE, TABLE_NAME FROM USER_TAB_PRIVS;

Resources