Can not find Permissions assigned to created roles in Oracle - oracle

I logged in as SYSTEM in SQL dev and did this:
ALTER SESSION SET "_ORACLE_SCRIPT" = TRUE;
CREATE TABLE Attendance
(
ID INT ,
NAME NVARCHAR2(300),
CONSTRAINT IdPk PRIMARY KEY (ID)
);
CREATE ROLE DataEntry;
GRANT SELECT, INSERT, UPDATE ON Attendance TO DataEntry;
How to find the permissions assigned to the DataEntry role? I've researched for a while, but the answers found didn't work. For example:
select * from ROLE_ROLE_PRIVS;
select * from ROLE_TAB_PRIVS;
select * from ROLE_SYS_PRIVS;
These statements return many many roles such as: dba,sys,.... But i still can't find my 'DataEntry' role. Can someone explain this to me? Thanks alot.

If you created any objects connected as SYSTEM, you'd rather not do that. SYS and SYSTEM are special, don't mess up with them.
As of your question:
SQL> show user
USER is "SCOTT"
SQL> create role dataentry;
Role created.
SQL> grant select, insert, update on emp to dataentry;
Grant succeeded.
SQL> select * From role_tab_privs;
ROLE OWNER TABLE_NAME COLUMN_NAM PRIVILEGE GRA
---------- ---------- ---------- ---------- ---------- ---
DATAENTRY SCOTT EMP INSERT NO
DATAENTRY SCOTT EMP SELECT NO
DATAENTRY SCOTT EMP UPDATE NO
SQL>
If you wanted to do such a query connected as a privileged user, then it is dba_tab_privs:
SQL> show user
USER is "SYS"
SQL> select * From dba_tab_privs where owner = 'SCOTT';
GRANTEE OWNER TABLE_NAME GRANTOR PRIVILEGE GRA HIE
------------ ---------- ---------- ---------- ---------- --- ---
MIKE SCOTT DEPT SCOTT DELETE YES NO
DATAENTRY SCOTT EMP SCOTT INSERT NO NO
DATAENTRY SCOTT EMP SCOTT SELECT NO NO
DATAENTRY SCOTT EMP SCOTT UPDATE NO NO
SQL>

Since you tagged SQLDev...open the View menu, select DBA.
Add your connection. Expand, go to Security, Select Roles, open your Role.
Observe the Object Privs panel.
SQL Developer gets the object privs for a roles using this SQL
SELECT privilege AS "Object Privilege"
, owner AS "Schema"
, table_name AS "Object"
FROM dba_tab_privs
WHERE grantee = :name -- DATAENTRY
ORDER BY 2
, 3
, 1

Related

Unable to select from SYS.TABLES - Table or View does not exist

I read that
USER_TABLES is tables which you own
ALL_TABLES is tables which own, and tables owner by other users, which you have been granted explicit access to
DBA_TABLES is all tables in the database
All three are views of the underlying SYS tables
Based on the above and mention of SYS.TABLES in the Oracle Docs, I tried to
select * from SYS.TABLES;
but it resulted in an error that the table or view does not exist. I tried as both SYS and another username.
Question 1:
Is SYS.TABLES a valid table in Oracle 11g ?
Question 2:
If yes, is SYS.TABLES the underlying table for the view DBA_TABLES ?
Question 3:
If yes, what privileges do I need to select from the SYS.TABLES ?
Question 4:
How do I find the underlying column and the tables for a view such as DBA_TABLES ?
I have edited the question. Sorry about the confusion I caused earlier.
This is 11g (XE, though; never mind that).
As you wonder about SYS-owned objects, connect as such.
SQL> select * from v$version where rownum = 1;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production
SQL> connect sys as sysdba
Enter password:
Connected.
1.
Does TABLES exist? Nope.
SQL> desc tables;
ERROR:
ORA-04043: object tables does not exist
But, TAB does:
SQL> desc tab;
Name Null? Type
----------------------------------------- -------- ----------------------------
TNAME NOT NULL VARCHAR2(30)
TABTYPE VARCHAR2(7)
CLUSTERID NUMBER
2.
In order to find what DBA_TABLES really is:
SQL> select owner, object_type from dba_objects where object_name = 'DBA_TABLES';
OWNER OBJECT_TYPE
------------------------------ -------------------
SYS VIEW
PUBLIC SYNONYM
4.
OK, it is a view. Which query is it made of?
SQL> set long 20000
SQL> select text from dba_views where view_name = 'DBA_TABLES';
TEXT
--------------------------------------------------------------------------------
select u.name, o.name,
decode(bitand(t.property,2151678048), 0, ts.name,
decode(t.ts#, 0, null, ts.name)),
decode(bitand(t.property, 1024), 0, null, co.name),
decode((bitand(t.property, 512)+bitand(t.flags, 536870912)),
0, null, co.name),
decode(bitand(t.trigflag, 1073741824), 1073741824, 'UNUSABLE', 'VALID'),
<snip>
from sys.user$ u, sys.ts$ ts, sys.seg$ s, sys.obj$ co, sys.tab$ t, sys.obj$ o,
sys.obj$ cx, sys.user$ cu, x$ksppcv ksppcv, x$ksppi ksppi,
sys.deferred_stg$ ds
where o.owner# = u.user#
and o.obj# = t.obj#
and bitand(t.property, 1) = 0
and bitand(o.flags, 128) = 0
and t.bobj# = co.obj# (+)
and t.ts# = ts.ts#
<snip>
(It is a quite long query so I displayed only some parts of it; now that you know how to do it, do it yourself for more info).
TAB is, on the other hand, quite simpler:
SQL> select text from dba_views where view_name = 'TAB';
TEXT
---------------------------------------------------------------
select o.name,
decode(o.type#, 2, 'TABLE', 3, 'CLUSTER',
4, 'VIEW', 5, 'SYNONYM'), t.tab#
from sys.tab$ t, sys."_CURRENT_EDITION_OBJ" o
where o.owner# = userenv('SCHEMAID')
and o.type# >=2
and o.type# <=5
and o.linkname is null
and o.obj# = t.obj# (+)
You'd use the same principle for "tables" specified in the FROM clause, e.g.
SQL> select owner, object_type from dba_objects where object_name = 'TAB$';
OWNER OBJECT_TYPE
------------------------------ -------------------
SYS TABLE
So - yes, that's the end. TAB$ is the final table, there's nothing behind.
3.
If connected as SYS, you don't need any additional privileges. SYS owns the database, it is the boss, it can do anything.
For other users, owner grants privileges, e.g. (still connected as SYS):
SQL> grant select on tab$ to scott;
Grant succeeded.
SQL> grant select on x$ksppcv to scott;
grant select on x$ksppcv to scott
*
ERROR at line 1:
ORA-02030: can only select from fixed tables/views
SQL>
That should be it, I presume.
Just a note: SYS is, as I said, powerful. Be careful what you do. I hope you have a database to spare like I do; nothing much will happen if I screw something here, there's no important data stored in it. Don't play games on production databases.

Sequence can have synonym?

I created first sequence=>
SQL> create sequence sq_001;
Then synonym for sequence=>
SQL> create synonym syn_001 for sq_001;
Then I query the user_synonyms =>
SQL> select*from user_synonyms where synonym_name = 'SYN_001';
SYNONYM_NAME TABLE_OWNER TABLE_NAME DB_LINK ORIGIN_CON_ID
--------------- --------------- --------------- --------------- -------------
SYN_001 RAMIN SQ_001 3
This is confused me, written table_name but this is sequence(SQ_001) and worked =>
TABLE_NAME
---------------
SQ_001
Yes, a sequence can have a synonym as you have demonstrated. The view USER_SYNONYMS is confusing in having a column called TABLE_NAME that can contain other things - it should really be OBJECT_NAME. Presumably when USER_SYNONYMS was first created only tables could have synonyms.

HZ_CUST_SITE_USES no rows returned

When query the following table it returns zero records.
SQL> select count(*) from HZ_CUST_SITE_USES;
COUNT(*)
----------
0
SQL>
can you please help me some one
Per My Oracle Support (Doc ID 787677.1), You Have a Security Policy Enabled on the APPS Owned Synonym
This is a standard set-up associated with APPS#ERP owned synonyms in an Oracle R12 environment.
First, confirm that the APPS#ERP owned synonym when queried without setting an org specific security policy context will result in an empty set:
APPS#ERP>SELECT COUNT(1) FROM HZ_CUST_SITE_USES;
COUNT(1)
0
Next confirm that a security policy has been applied to this APPS#ERP owned synonym:
APPS#erp>SELECT object_name,
2 policy_group,
3 policy_name,
4 PACKAGE,
5 FUNCTION,
6 sel,
7 enable
8 FROM dba_policies
9 WHERE object_name = 'HZ_CUST_SITE_USES';
OBJECT_NAME POLICY_GROUP POLICY_NAME PACKAGE FUNCTION SEL ENABLE
HZ_CUST_SITE_USES SYS_DEFAULT ORG_SEC MO_GLOBAL ORG_SECURITY YES YES
Just confirm that the object type is a synonym:
APPS#erp>SELECT owner,
2 object_name,
3 object_type
4 FROM DBA_OBJECTS
5 WHERE 1 =1
6 AND OBJECT_NAME = 'HZ_CUST_SITE_USES';
OWNER OBJECT_NAME OBJECT_TYPE
APPS HZ_CUST_SITE_USES SYNONYM
Query the APPS#ERP view associated with the AR owned table, HZ_CUST_SITE_USES_ALL:
APPS#erp>--APPS owned view r12.2
APPS#erp>SELECT ORG_ID, COUNT(1) FROM HZ_CUST_SITE_USES_ALL GROUP BY ORG_ID;
ORG_ID COUNT(1)
123 458
456 2658
789 1210
Once the context is set for a session (org_id is 456), one can query results for that org_id:
APPS#erp>--set policy
APPS#erp>EXEC mo_global.set_policy_context('S', 456);
PL/SQL procedure successfully completed.
APPS#erp>SELECT COUNT(1) FROM HZ_CUST_SITE_USES;
COUNT(1)
2658

What privileges to grant in order to select from all PDBs

Why both select doesnt return the same result?
Or if you want more general question - What privileges to grant in order to select from all PDBs.
conn / as sysdba
create user c##nir identified by c##nir container=all;
grant connect,dba,resource to c##nir container=all;
grant select on cdb_synonyms to c##nir container=all;
select CON_ID from cdb_synonyms group by CON_ID;
CON_ID
----------
1
4
11
10
14
5
8
13
3
7
15
6
12
9
conn c##nir/c##nir
select CON_ID from cdb_synonyms group by CON_ID;
CON_ID
----------
1
select CON_ID from containers(dba_synonyms) group by CON_ID
*
ERROR at line 1:
ORA-00942: table or view does not exist
The answer:
ALTER USER c##nir set **container_data=all** container = current;
CONTAINER_DATA controls the data which will be viewed from.

Oracle VPD column masking, how can I change the default (null) value to XXX

Using Oracle VPD, after adding a policy and creating a function, I was able to hide a column from unauthorized users.
But instead of (null) how can i show something like 'xxxxxx'
Also in the function I am validation for the user login, like
if sys_context( 'userenv', 'session_user' ) = 'USER1'
what is the best approach to remove this hard coding in the function?
Thanks in advance.
in order to return text in the place of not null, you'd have to create a view over top of the table to change null into the static literal you wanted, as the only option in VPD would be to hide the rows or set the secret columns to NULL.
for your second part of your question, if you are using that check to determine who has access to the sensitive columns, you can use a role instead and have the VPD function check this like:
return 'exists (select null from session_roles where role = ''XXXXXX'')';
i.e. whomever has the role XXXXXX (just create an appropriate role and grant it to your privileged users) set in their session can see the data. That way you don't need to hard code a bunch of user ids.
e.g:
if we create a role and grant it to a test user:
SQL> create role ACCESS_TABLEA_SEC_COL;
Role created.
SQL> grant ACCESS_TABLEA_SEC_COL to test;
Grant succeeded.
for my set up ive created a simple test table + a policy that stops people reading the your_sec_col column.
SQL> create or replace package pkg_security_control
2 as
3 function apply_access(p_owner in varchar2, p_obj_name in varchar2) return varchar2;
4 end;
5 /
Package created.
SQL> create or replace package body pkg_security_control
2 as
3 function apply_access(p_owner in varchar2, p_obj_name in varchar2)
4 return varchar2
5 is
6 begin
7 return 'exists (select null from session_roles where role = ''ACCESS_TABLEA_SEC_COL'')';
8 end;
9 end;
10 /
Package body created.
SQL> create table TABLEA
2 (
3 id number primary key,
4 your_sec_col varchar2(30)
5 );
Table created.
SQL> insert into tablea values (1, 'secret text1');
1 row created.
SQL> insert into tablea values (2, 'secret text2');
1 row created.
now if we select from that table and we don't have the ACCESS_TABLEA_SEC_COL role, we'd get:
SQL> select *
2 from tablea;
ID YOUR_SEC_COL
---------- ------------------------------
1
2
but you want a string like xxxxx. VPD itself cannot do this, but a view could decode NULL to that string.
SQL> create view v_tablea
2 as
3 select id, case when your_sec_col is null then 'xxxxxx' else your_sec_col end your_sec_col
4 from TABLEA;
View created.
now selecting from the view will , depending on whether the role is set:
SQL> set role none;
Role set.
SQL> select *
2 from tablea;
ID YOUR_SEC_COL
---------- ------------------------------
1
2
SQL> select *
2 from v_tablea;
ID YOUR_SEC_COL
---------- ------------------------------
1 xxxxxx
2 xxxxxx
SQL> set role all;
Role set.
SQL> select *
2 from v_tablea;
ID YOUR_SEC_COL
---------- ------------------------------
1 secret text1
2 secret text2
SQL> select *
2 from tablea;
ID YOUR_SEC_COL
---------- ------------------------------
1 secret text1
2 secret text2
so VPD still protects your table against anyone selecting from it, but you'd have clients select from the view to get the literal string instead. If your protected strings can contain NULL, and you want to differentiate those from no access, you can put the role check in the view instead.
create view v_tablea
as
select id,
case (select 'A' from session_roles where role = 'ACCESS_TABLEA_SEC_COL')
when 'A' then your_sec_col else 'xxxxxxxx' end your_sec_col
from TABLEA;

Resources