VPD - RLS

Dear Experts,
We are implementing row level security at our organization to achieve Multi-Tenancy. Our DB Version is Oracle 11g release 2.
                              At the application we have multiple skew id's, which exists in the master table at the database. Using Oracle VPD we want to implement row level security for different dependant tables which has skew id column. From the front end if application user select the specific skew id we want the end user to select or view particular rows pertaininig to the skew id. These skew id's are not constant they are added or modified on adhoc basis.
Master Table - skew_master
skew_id,- Parent key
date,
mod,
label1
label2
location,
sector
All Dependent 20 tables  have column - skew_id as foreign key
We cannot create DB user's for mapping the VPD. I would appreciate, if you can give inputs with an example how to fulfill this requirement with an policy function , application context to understand what parameters need to be passed.
Awaiting for your reply. Thanks

As I told you on the other forum there is NOTHING you need to do:
A standard parent/child table relationship would appear to do what  you want: when a parent SKEW_ID is used it will ONLY link to child rows with that same SKEW_ID.
Just join the parent table to the child tabes you need for a query.
VPD has no application or use if you are just using a parent/child relationship like yours.

Similar Messages

  • Oracle VPD - RLS

    Dear Experts,
    We are implementing row level security at our organization to achieve Multi-Tenancy. Our DB Version is Oracle 11g release 2.
                                  At the application we have multiple skew id's, which exists in the master table at the database. Using Oracle VPD we want to implement row level security for different dependant tables which has skew id column. From the front end if application user select the specific skew id we want the end user to select or view particular rows pertaininig to the skew id. These skew id's are not constant they are added or modified on adhoc basis.
    We cannot create DB user's for mapping the VPD. I would appreciate, if you can give inputs with an example how to fulfill this requirement with an policy function , application context to understand what parameters need to be passed.
    Awaiting for your reply. Thanks

    Sorry - wrong forum. Although the forum title is multitenant this forum is for the 12c database version using the new multitenant architecture.
    Please mark the thread ANSWERED and repost it in the SQL and PL/SQL forum.
    PL/SQL
    When you repost you need to provide some sample data to show what you need to do.
    A standard parent/child table relationship would appear to do what  you want: when a parent SKEW_ID is used it will ONLY link to child rows with that same SKEW_ID.
    That is why you need to show an example of what you mean.

  • Help With FGAC (VPD, RLS...)

    Hi all.
    I'm trying to create a Discoverer Trigger to implement FGAC. The point is:
    Discoverer DEMANDS you to create a DB function without any argument, returning integer (that won't be used anywhere), and register it in Disco. Adm. Edition. This is the easy part.
    Then I created two db. functions. The first one configures Policies (INFO_SEC). The second one (this is the one I try to invoke in discoverer - EUL_TRIGGER$POST_LOGIN), simply creates the policy using DBMS_RLS package.
    SQL> create or replace function info_sec( p_schema in varchar2) return varchar2
      2  as
      3  v_user varchar2(30);
      4  begin
      5  select sys_context('USERENV', 'SESSION_USER')
      6   into v_user
      7  FROM DUAL;
      8    if (v_user = 'DWH_ADMIN' ) then
      9      return '';
    10    else
    11      return 'upper(nm_emp) = '||v_user;
    12    end if;
    13  end;
    14  /
    Function created.
    SQL> create or replace FUNCTION EUL_TRIGGER$POST_LOGIN RETURN INTEGER
      2  as
      3  begin
      4  dbms_rls.add_policy
      5  ( object_schema   => 'DWH_ADMIN',
      6  object_name     => 'EMP_T',
      7  policy_name     => 'POL_EMP',
      8  function_schema => NULL,
      9  policy_function => 'INFO_SEC',
    10  statement_types => 'select, insert, update, delete' ,
    11  update_check    => TRUE );
    12   RETURN(10000);
    13  end;
    14  /
    Function created.
    SQL> select EUL_TRIGGER$POST_LOGIN FROM DUAL;
    select EUL_TRIGGER$POST_LOGIN FROM DUAL
    ERROR at line 1:
    ORA-14552: cannot perform a DDL, commit or rollback inside a query or DML
    ORA-06512: at "SYS.DBMS_RLS", line 308
    ORA-06512: at "DWH_ADMIN.EUL_TRIGGER$POST_LOGIN", line 4I understand this is due to the insert that dbms_rls tries to perform in order to create the policy.
    My question is if anyone has an alternative for setting this using pl/sql. I need to set the RLS policy in discoverer only, so, i MUST use Discoverer Triggers.
    If you need more info about Discoverer Triggers, you cand find it in:
    http://www.huihoo.com/oracle/docs/B25016_04/doc/dl/bi/B13916_04/appendix_b.htm
    Anything you guys input here will be highly appreciate!
    Regards,
    Marcos

    You do not want any part of a system which intends to apply different FGAC policies to the same Oracle user based on the application they are using. Assuming you managed to set things up so that each application was setting up its own FGAC policy, FGAC policies apply to the instance. So the policy that would apply to the Discoverer session, for example, could change when some other application created a session and set its own policy. This is a disaster waiting to happen.
    Your policy function could look at information about the session to try to determine the application being used and tailor the policy accordingly. This is generally a bad idea since this information is being passed in by the client, meaninging that it is relatively easy to spoof a different application.
    Justin

  • Tuning VPD predicate

    Hi,
    I'm using VPD(RLS) to filter data based.
    I have a performance issue due to the VPD predicate my VPD function generate.
    I have two tables:
    - MARKER which is the table I want to secure and contains a primary key named marker_id and a filed use by VPD name VPD_IS_PUBLIC.
    - DATASECURITY which is the table containing security information and tells to VPD wich data can be seen for a given role.
    I put the script at the end of the message.
    If you look to the code, the VPD function can return two predicates:
    VPD_IS_PUBLIC=1
    or
    VPD_IS_PUBLIC=1 or marker_id in (select field_id from datasecurity where roleid=3)
    The problem with the second query is that more I have data in my MARKER table more the query is slow.
    This is because of "VPD_IS_PUBLIC=1 or" statement.
    Is there another way to write that predicate?
    Does someone can help me?
    Cheers,
    Sebastien
    CREATE TABLE DATASECURITY
    OBJECT_DB_ID NUMBER(10),
    ROLEID NUMBER(10),
    FIELD_ID NUMBER(10),
    CREATION_DATE TIMESTAMP(6) WITH TIME ZONE DEFAULT systimestamp CONSTRAINT NN_DATASECURITY_CREATIONDATE NOT NULL,
    CONSTRAINT PK_DATASECURITY
    PRIMARY KEY
    (OBJECT_DB_ID, ROLEID, FIELD_ID)
    CREATE INDEX INDEX_DATASECURITY ON DATASECURITY
    (FIELD_ID);
    CREATE OR REPLACE TRIGGER TRG_AFT_INSERT_DATASECURITY
    AFTER INSERT
    ON DATASECURITY
    REFERENCING NEW AS New OLD AS Old
    FOR EACH ROW
    DECLARE
    BEGIN
    UPDATE marker
    SET vpd_is_public = 0
    WHERE marker_id = :new.field_id;
    END TRG_BEF_INSERT_DATASECURITY;
    CREATE TABLE MARKER
    MARKER_ID NUMBER(10) NOT NULL,
    MARKER_TYPE_ID NUMBER(10),
    MARKER_ACC VARCHAR2(50 BYTE),
    VERSION VARCHAR2(10 BYTE),
    DISPLAY_SYNONYM_ID NUMBER(10),
    SPECIES_ID NUMBER(10) NOT NULL,
    GERMPLASM_ID NUMBER(10),
    LIBRARY_ID NUMBER(10),
    DESCRIPTION VARCHAR2(2000 BYTE),
    DATE_CREATED DATE,
    DATE_UPDATED DATE,
    VPD_IS_PUBLIC NUMBER(1) DEFAULT 1 CONSTRAINT NN_MARKER_VPD_IS_PUBLIC NOT NULL,
    CONSTRAINT PK_MARKER
    PRIMARY KEY
    (MARKER_ID)
    CREATE INDEX INDEX_MARKER ON MARKER
    (VPD_IS_PUBLIC);
    -- This function return the value stored in the session client info
    CREATE OR REPLACE FUNCTION CSFDS.get_cwid
    RETURN VARCHAR2
    IS
    retval VARCHAR2 (50);
    BEGIN
    DBMS_APPLICATION_INFO.READ_CLIENT_INFO (retval);
    RETURN retval;
    EXCEPTION
    WHEN OTHERS
    THEN
    RAISE;
    END get_cwid;
    -- This function sets the value to the session client info
    CREATE OR REPLACE FUNCTION CSFDS.set_cwid (cwid IN VARCHAR2)
    RETURN NUMBER
    IS
    BEGIN
    DBMS_APPLICATION_INFO.set_client_info (cwid);
    RETURN 1;
    EXCEPTION
    WHEN OTHERS
    THEN
    RETURN 0;
    END set_cwid;
    -- This function is the vpd function.
    -- It returns differents predicate according the value in the session client info
    CREATE OR REPLACE FUNCTION CSFDS.vpd (sch_name IN VARCHAR2, tab_name IN VARCHAR2)
    RETURN VARCHAR2
    IS
    retval VARCHAR2 (500) DEFAULT '' ;
    l_roleid NUMBER DEFAULT 3 ;
    BEGIN
    IF GET_CWID = 'csfds'
    THEN
    retval := 'VPD_IS_PUBLIC=1 or ';
    retval :=
    retval
    || 'marker_id in (select field_id from datasecurity where roleid='
    || l_roleid
    || ')';
    ELSE
    retval := 'VPD_IS_PUBLIC=1';
    END IF;
    RETURN retval;
    EXCEPTION
    WHEN OTHERS
    THEN
    RAISE;
    END vpd;
    -- To create the VPD policy
    BEGIN
    SYS.DBMS_RLS.ADD_POLICY (
    object_schema => 'CSFDS'
    ,object_name => 'MARKER'
    ,policy_name => 'TEST_VPD'
    ,function_schema => 'CSFDS'
    ,policy_function => 'VPD'
    ,statement_types => 'SELECT'
    ,policy_type => dbms_rls.dynamic
    ,long_predicate => FALSE
    ,sec_relevant_cols => 'MARKER_ID,MARKER_TYPE_ID,MARKER_ACC,VERSION,DISPLAY_SYNONYM_ID,SPECIES_ID,GERMPLASM_ID,LIBRARY_ID,DESCRIPTION,DATE_CREATED,DATE_UPDATED,VPD_IS_PUBLIC'
    ,sec_relevant_cols_opt => NULL
    ,update_check => TRUE
    ,static_policy => FALSE
    ,enable => TRUE );
    END;
    Edited by: sfrade on Mar 18, 2009 2:00 PM

    Hi
    Done using the following commands:
    execute DBMS_STATS.gather_table_stats ( ownname => 'CSFDS', tabname => 'DATASECURITY', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt => 'FOR ALL COLUMNS SIZE AUTO', cascade => TRUE );
    execute DBMS_STATS.gather_table_stats ( ownname => 'CSFDS', tabname => 'MARKER', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt => 'FOR ALL COLUMNS SIZE AUTO', cascade => TRUE );
    and the plan for the following query
    SELECT COUNT ( * )
    FROM MARKER
    WHERE marker_id in (SELECT FIELD_ID
    FROM DATASECURITY
    WHERE roleid = 1)
    OR vpd_is_public = 1;
    Plan
    SELECT STATEMENT ALL_ROWSCost: 314 Bytes: 10 Cardinality: 1                          
         7 SORT AGGREGATE Bytes: 10 Cardinality: 1                     
              6 FILTER                
                   4 VIEW VIEW CSFDS.index$_join$_001 Cost: 314 Bytes: 176,780 Cardinality: 17,678           
                        3 HASH JOIN      
                             1 INDEX FAST FULL SCAN INDEX (UNIQUE) CSFDS.PK_MARKER Cost: 83 Bytes: 176,780 Cardinality: 17,678
                             2 INDEX FAST FULL SCAN INDEX CSFDS.INDEX_MARKER Cost: 89 Bytes: 176,780 Cardinality: 17,678
                   5 INDEX SKIP SCAN INDEX (UNIQUE) CSFDS.PK_DATASECURITY Cost: 2 Bytes: 10 Cardinality: 1
    By the way, how do you know that the stat were out of date?
    Edited by: sfrade on Mar 20, 2009 8:54 AM

  • Dynamic where clause, user/row security

    I haev two tables:
    create table table1(
    First_name varchar2(12),
    Last_Name varchar2(17),
    Middle_name varchar2(1),
    Cabinet varchar2(2),
    Department varchar2(3),
    Division varchar2(2),
    branch varchar2(2),
    section varchar2(2),
    unit varchar2(2),
    serial varchar2(3),
    job_title varchar2(13),
    other fields......
    create table security(
    USERname VARCHAR2(14),
    FIRST_NAME VARCHAR2(20),
    PER_CABINET VARCHAR2(2),
    PER_DEPT VARCHAR2(3),
    PER_DIVISION VARCHAR2(2),
    PER_BRANCH VARCHAR2(2),
    PER_SECTION VARCHAR2(2),
    PER_UNIT VARCHAR2(2),
    PER_SERIAL VARCHAR2(2),
    other fields....
    ****security table sample data****
    username first_name cabinet dept division branch section unit serial
    username1 firstname1 10 785 05 01 02
    username2 firstname2 32 527 02 03
    username3 firstname3 32 527 02 01
    username4 firstname4 46 546 22 06 05
    username5 firstname5 46 546 27 15 01
    username6 firstname6 10 005 01 01 01 01
    username7 firstname7 10 005 01 01 01 01
    username8 firstname8 10
    username9 firstname9 10 005
    username10 firstname10 10 005 01
    What I would like to do is, based on the values assigned to user in security table, the records from table1 should be fetched.
    For example: (lets say there are 1000 records in table 1 for cabinet 10)
    username8 should be able to see all records pertaining to cabinet 10. (record count=1000)
    Username9 should be able to see all records pertaining to cabinet 10 and dept 005 (record count=800)
    username10 should be able to see all records pertaining to cabinet 10 and dept 005 and division 01 (record count=600)
    username1 should be able to see all records pertaining to cabinet 10 and dept 785 and division 05 and branch 01 and unit 02 (record count=10)
    ....and so on
    To summarize I have to narrow down the number of records a user can see.
    I tried to implement this using set_context each for cabinet, department etc... the problem is some users may not have all the values. so my where clause fails and returns 0 rows.
    example:
    select count(1) from table1 where cabinet=(select per_cabinet from security where username='username1') and department=(select per_dept from security where username='username1') and division=(select per_division from security where username='username1') and branch=(select per_branch from security where username='username1') and section=(select per_section from security where username='username1') and unit=(select per_unit from security where username='username1');
    I would get 0 rwos because username1 does not have any value for section.
    I point to keep in mind is that not all users have same values.
    Any thoughts or ideas on how to resolve my problem? Thanks.

    By set_context, I hope you mean you are using sys_context and VPD/RLS for this filtering. For the filter condition, how about modifying each part in the form:
    unit = nvl((select per_unit from security where username = :username), unit)or
    unit = (select nvl(per_unit, unit) from security where username = :username)

  • New HTMLDB User - Want to authenticate against a database user

    Greetings... I would like to authenticate a user sign-in/logon screen against database users setup in the database. It appears to me that DAD might do this, but I'm a bit fuzzy on how to make it work. I looked in some of the FAQ's here and can't seem to find something that tells me how to do this. I'd be thankful for any help you can give this old DBA who's stepping into HTMLDB Development.
    (Love the product so far by the way!)
    Robert

    Robert - It depends on what your aim is, but one way to do it is to create a new DAD without a username or password in the connect info. This will require users to respond to the basic authentication challenge allowing those who have database accounts to authenticate to your application.
    Regardless of which database account is used to authenticate, keep in mind that all SQL and PL/SQL in the application executes as the schema designated as the application's "owner" or parsing schema, so the identity of the authenticated user with respect to database roles and privileges plays no part unless you actively use the session's USER value in VPD/RLS, for example.
    Scott

  • AUTH_CHECK_MISMATCH and LANGUAGE_MISMATCH

    Hi all
    I have identified that same sql_id has 4 child_number in v$sql, in order to find out what is the reason of execution changes I looked into v$sql_shared_cursor with sql_id and I saw
    AUTH_CHECK_MISMATCH=Y and LANGUAGE_MISMATCH=Y for 4 child sql ;
    1-why value=y for all childs ? doesnt have to someone has value=N ?
    2-What is the exact mean of these mismatchs give me some example ? when these mismatchs happens ?
    3-V$Sql_Shared_Cursor is the best view to find child number changes or execution changes ?
    Best Regards
    10.2.2
    Edited by: EB on Feb 5, 2009 5:36 PM

    EB wrote:
    I have identified that same sql_id has 4 child_number in v$sql, in order to find out what is the reason of execution changes I looked into v$sql_shared_cursor with sql_id and I saw
    AUTH_CHECK_MISMATCH=Y and LANGUAGE_MISMATCH=Y for 4 child sql ;
    2-What is the exact mean of these mismatchs give me some example ? when these mismatchs happens ?The AUTH_CHECK_MISMATCH is usually indicating that a VPD/RLS policy is active and therefore the SQL is actually unique and not sharable, although not visible in V$SQL.
    See e.g. AskTom for an example: http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:62048567543425#673597500346350876
    The LANGUAGE_MISMATCH indicates that different NLS related settings, e.g. different NLS_SORT or NLS_COMP settings were used that influence the meaning/sort output/filter predicates and therefore are not sharable.
    You can try it yourself by simply executing a query like "SELECT * FROM <TABLE> ORDER BY <VARCHAR_COL>" twice, the first time using a binary sort order ("ALTER SESSION SET NLS_SORT = binary"), the second time using a different sort order like "ALTER SESSION SET NLS_SORT = german". Then you'll find two child cursors for this statement.
    A quick test with 10g XE though revealed that a different NLS_SORT setting already showed a 'Y' in both the AUTH_CHECK_MISMATCH and LANGUAGE_MISMATCH columns, although I'm not sure why the AUTH_CHECK_MISMATCH column shows 'Y' in this particular case.
    So may be you simply have sessions that use different NLS settings which could already be caused by different NLS client settings.
    Regards,
    Randolf
    Oracle related stuff blog:
    http://oracle-randolf.blogspot.com/
    SQLTools++ for Oracle (Open source Oracle GUI for Windows):
    http://www.sqltools-plusplus.org:7676/
    http://sourceforge.net/projects/sqlt-pp/

  • Effect of RLS policy (VPD) on execution plan of a query

    Hi
    I have been working on tuning of few queries. A RLS policy is defined on most of the tables which appends an extra where condition (something like AREA_CODE=1). I am not able to understand the effect of this extra where clause on the execution plan of the query. In the execution plan there is no mention of the clause added by VPD. In 10046 trace it does show the policy function being executed but nothing after that.
    Can someone shed some light on the issue that has VPD any effect on the execution plan of the query ? Also would it matter whether the column on which VPD is applied, was indexed or non-indexed ?
    Regards,
    Amardeep Sidhu

    Amardeep Sidhu wrote:
    I have been working on tuning of few queries. A RLS policy is defined on most of the tables which appends an extra where condition (something like AREA_CODE=1). I am not able to understand the effect of this extra where clause on the execution plan of the query. In the execution plan there is no mention of the clause added by VPD. In 10046 trace it does show the policy function being executed but nothing after that.
    VPD is supposed to be invisible - which is why you get minimal information about security predicates in the standard trace file. However, if you reference a table with a security preidcate in your query, the table is effectively replaced by an inline view of the form: "select * from original_table where {security_predicate}", and the result is then optimised. So the effects of the security predicate is just the same as you writing the predicate into the query.
    Apart from your use of v$sql_plan to show the change in plan and the new predicates, you can see the effects of the predicates by setting event 10730 with 10046. In current versions of Oracle this causes the substitute view being printed in the trace file.
    Bear in mind that security predicates can be very complex - including subqueries - so the effect isn't just that of including the selectivity of "another simple predicate".
    Can someone shed some light on the issue that has VPD any effect on the execution plan of the query ? Also would it matter whether the column on which VPD is applied, was indexed or non-indexed ?
    Think of the effect of changing the SQL by hand - and how you would need to optimise the resultant query. Sometimes you do need to modify your indexing to help the security predicates, sometimes it won't make enough difference to matter.
    Regards
    Jonathan Lewis
    http://jonathanlewis.wordpress.com
    http://www.jlcomp.demon.co.uk
    "Science is more than a body of knowledge; it is a way of thinking"
    Carl Sagan
    To post code, statspack/AWR report, execution plans or trace files, start and end the section with the tag {noformat}{noformat} (lowercase, curly brackets, no spaces) so that the text appears in fixed format.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

  • Peoplesoft Enterprise with OLS or VPD/FGAC/RLS

    I know that the EBusiness Suite 11i and 12i have been certified (with Patches) for VPD.
    I can't find information on Certification / Patches / Implementation of Peoplesoft Enterprise (particularly say Peoplesoft Financials Modules) with Oracle Label Security or with VPD/FGAC/RLS.
    Is there such information on metalink3 ? Has anyone implemented/enhanced Peoplesoft in this manner ?

    Well, generally the level security is application embedded and configured, very rarely database level implemented (because mainly only one database user is used). The report should be run through the application query which comes with row level security.
    But it is supported, even Database Vault.
    Nicolas.

  • Query rewrite problem related to FGAC/RLS/VPD

    My problem in related to Fine Grained Access Control / DBMS_RLS.
    Let's start with a simple example and elaborate further.
    Basic problem:
    Let's say we have two tables:
    create table LEVEL1( L1NR NUMBER not null, TAG NUMBER);
    alter table LEVEL1 add constraint LEVEL1_PK primary key (L1NR);
    create table LEVEL2( L1NR NUMBER, L2NR NUMBER not null);
    alter table LEVEL2 add constraint LEVEL2_PK primary key (L2NR);
    alter table LEVEL2 add constraint LEVEL2_FK foreign key (L1NR) references LEVEL1 (L1NR);
    I want to convince the database to rewrite a query that looks like this:
    A)
    SELECT L1.TAG, L2.L2NR
    FROM
    LEVEL2 L2
    INNER JOIN LEVEL1 L1
    ON L2.L1NR = L1.L1NR
    WHERE
    EXISTS( SELECT 1 FROM LEVEL1 L1B WHERE L1B.L1NR = L2.L1NR)
    As L2 will be joined to L1 for my human eye and mind
    it is obvious that the where clause is redundant,
    and the query is equivalent to:
    B)
    SELECT L1.TAG, L2.L2NR
    FROM
    LEVEL2 L2
    INNER JOIN LEVEL1 L1
    ON L2.L1NR = L1.L1NR
    Is there any way to convince the parser/optimizer to remove the redundant join?
    Why do I have a query like A) and why I cannot rewrite it myself I will explain below.
    For those to ask themselves why do I need such a thing let me elaborate.
    We develop an application and we want to enforce security on the data at the row level.
    The problem is more complicate than my following example, but the example is good enough.
    Let's say that we have an application that makes invoices.
    We want to give a user the privilege to make reports on the invoices issued for a category of customers.
    I see three main ways to enforce row level security on data:
    1) At the application level
    2) Using views
    3) Using Fine Grained Access Control / DBMS_RLS
    Choice 1) is more flexible, but it has a major drawback:
    You cannot make the database available for reporting with BI/ad-hoc reporting tools.
    And also you have to be careful with every query you write. Or create something that takes care of the security, which can be really tricky.
    And it also makes report creation for the application difficult since you need to embed the security system into the reporting module.
    If you use Crystal Reports or some other reporting tool to build your application report you've got a problem.
    Choices 2) and 3) are somewhat similar, but 3) is more flexible
    For those who don't know how FGAC/DBMS_RLS works and don't want to dig deeper here is a short explanation:
    DBMS_RLS allows the database developer to attach dynamic where clauses to queries.
    It does this by rewriting queries like:
    "select blabla from employees"
    to "select blabla from (select * from employees where <some expression that filters the data according to the user's policy>)"
    The filters are attached on a table by table basis, so queries like:
    SELECT dept.NAME, empl.NAME
    FROM
    DEPARTMENT dept
    INNER JOIN employees empl
    are rewritten to
    SELECT dept.NAME, empl.NAME
    FROM
    (SELECT * FROM DEPARTMENT WHERE <FILTER_DEPT>) dept
    INNER JOIN (SELECT * FROM employees WHERE <FILTER_EMP>) empl
    So far so good, nothing looks bad, but the devil is in the detail
    Back to our reporting problem.
    Let's say we have a scenario simpler than life, and I associate the user directly to a customer category by adding a CUST_CAT_ID column to the APP_USER table.
    I want restrict the user to see only the data associated to its category (category, customers, invoices, invoice item)
    So when he writes "select NAME, ADDRESS from customer" the query is rewritten to
    "select NAME, ADDRESS from (SELECT * FROM CUSTOMER WHERE (EXISTS SELECT 1 FROM category join app_user on ... where customer.CUST_CAT_ID = app_user.CUST_CAT_ID and app_user.login = get_current_user()))"
    where get_current_user is some framework function that gives me the current user.
    A little complicated, but nothing too scary.
    But when I write something like:
    SELECT <relevant columns> FROM category cat JOIN customer cust JOIN invoice inv JOIN invoice_item item WHERE <some filters>
    ...(query totally legitimate for a sales report), this gets expanded to a scary query that looks like this:
    SELECT <relevant columns>
    FROM
    (SELECT * FROM category WHERE (EXISTS SELECT 1 FROM app_user u WHERE u.CUST_CAT_ID = CAT_ID AND u.login = get_current_user())) cat
    JOIN (SELECT * FROM customer WHERE(EXITS SELECT 1 FROM category JOIN app_user WHERE ...)) cust
    JOIN (SELECT * FROM invoice WHERE(EXITS SELECT 1 FROM customer JOIN category JOIN app_user WHERE ...)) inv
    JOIN (SELECT * FROM invoice_item WHERE(EXITS SELECT 1 FROM invoice JOIN customer JOIN category JOIN app_user WHERE ...)) item
    WHERE
    <some filters>
    Oops! A query with 4 tables is expanded to a 14 tables query, when all I really need is:
    SELECT <relevant columns>
    FROM category cat JOIN customer cust JOIN invoice inv JOIN invoice_item item
    WHERE <some filters> AND (EXISTS SELECT 1 FROM app_user u WHERE u.CUST_CAT_ID = CAT_ID AND u.login = get_current_user())
    Let me tell you that we don't use here roles and privileges tables that we must use in a real life scenario.
    In a real life scenario we will easily transform the original query in a 20-30 table join (grrrrrrr).
    Well, I cannot change the way DBMS_RLS/FGAC works, and also if I choose to use views I cannot write a filtered view for every possible join that a user might create.
    All I want is to find out if there is any way to instruct the parser/optimizer, using primary and foreign keys, optimizer parameters hints and other methods, to rewrite the query and eliminate redundant joins.
    Of course I can create some materialized views or bitmap join indexes to help me in the process and speed up the query, but using this method in a database that has hundreds of tables can be a little problem in terms of management and performance.

    Hello again,
    It appeared that, the problem is present only when I try the query in pl/sql developer.
    For some reason, even though I set QUERY_REWRITE_INTEGRITY to STALE_TOLERATED, it behaved as this parameter was set to ENFORCED.
    So the case was that:
    for session - STALE_TOLERATED
    for system - ENFORCED
    In v$parameter2 against "QUERY_REWRITE_INTEGRITY" was shown "stale_tolerated", but the query was not rewritten.
    When I do the same (altering the session and perform the select query) in SQLPlus, everything works as expected - the query is rewritten.
    And I conclude the problem is in PL/SQL Developer (my version is 8.0.1.1498) or something related to this.
    Edited by: Verdi on 2010-2-12 14:00

  • Row level security without using VPD

    I am wondering if there is a way to have row level security in APEX without having to use the virtual private database (VPD). I cannot afford the Enterprise Edition license that is required for VPD.
    I need a way to customize the list of rows that appear for each user on a report page.
    For example, I only want managers to be able to see their employees and not employees of other managers.
    Thanks for your help !
    -Reid

    While it wont provide all the features that Oracle RLS does, you can leverage Oracle 'Contexts' to provide a form of Row Level Security.
    This article describes how
    http://www.dbazine.com/oracle/or-articles/jlewis15
    Within APEX you can set your application to call the 'context' setting function in the 'VPD' section of the 'Edit Security Attributes' page.
    Varad

  • RLS Solutions with BI Applications

    If I have customer that has a BI application that queries a table for say the average of the salary column. If they introduce a row-level security solution like VPD or OLS and a subset of the rows are redacted for that BI query (say policy is you only want the user to be able to see salary for members of their org), the results would be altered and inaccurate results would be returned. What are the best practices for implementing a RLS solution and not interfere with BI-type applications that utilize this data?
    Thanks,
    Matt
    [email protected]

    That probably depends on what sort of BI the users need on that aggregate information. One option would be to create an aggregate table (potentially via a materialized view) and to grant the users access to that aggregate table (i.e. a SALARY_DEPT_AGGREGATE table that gives the average, standard deviation, median, etc. salary by department a SALARY_CITY_AGGREGATE table that gives the same breakdown by city). You would have to be able to anticipate the sorts of BI queries that would be allowed by fixing the dimensions of interest, which limits the flexibility of the BI you can perform. And you'd have to be careful that the aggregate data didn't provide enough information to allow users to back in to row-level data (i.e. if there is only one employee in a particular city).
    Justin

  • VPD - Label Security

    Hello All!
    I need to change the text of Query with OLS. But, OLS enable change the WHERE clause and don't change the FROM clause. Am i right?
    If yes, exists any feature that do make changes the WHERE clause and FROM?
    Thanks.
    Att,
    Anderson Haertel Rodrigues
    Database Administrator - DBA
    Florianópolis/SC/Brasil

    That's VPD AKA RLS - row level security. So yes it's just about the WHERE clause. If you want to change the tables people see then you'll need to use views and synonyms t make it work. Depending on the precise details of your implementation you may be able to use some of your VPD infrastructure in the view definition.
    Cheers, APC

  • Best practice for VPD and remote tables

    Not specifically an HTMLDB question, but here goes...
    HTMLDB 1.6 on 9.2.0.4 connecting over database link (fixed username/password) to 9.2.0.4
    I've currently "wrapped" access to the remote tables in views, i.e. view "T" in the HTMLDB parsing schema LOCAL_USER is defined as "SELECT * FROM T@remote"
    I'd like to put VPD controls on my backend tables, but I don't get how v('APP_USER') (or even APP_USER put into an application context) would be seen by the remote database.
    Should I just put VPD policies on LOCAL_USER's views and call it a day?
    Thanks for input!
    -John

    If you implemented the VPD in the remote database, what would your VPD be restricting? All queries would apply the policy based on the DB link fixed username resulting in all users of the HTML DB application having same policy restrictions.
    The policy in the remote database does not has access to the value of v('APP_USER'). That value is only available in the database that has HTML DB. You would have to write APIs in the remote database in PL/SQL functions/procedures to pass in the V('APP_USER') value to the remote database. This is doable, but cumbersome.
    If you want to have your policy modify your WHERE clause on the fly based on your HTML DB user account, then I would implement the VPD in the database which has your HTML DB repository. I am not sure which of the two scenarios below occur when doing a SELECT * FROM T.
    1.) The query goes across the database link, gets all the data out of table T in the remote database, passes back to the HTML DB database, and applies the policy WHERE clause modification in the HTML DB database.
    2.) The query applies the policy WHERE clause modification to the view, goes across the database link with the WHERE clause modified, and gets only the data allowed based on the policy from the remote database.
    You should test this out to find out for performance purposes what query is actually performed on the remote database.
    As always if anyone sees anything inaccurate in what I have written, please correct me.
    Mike

  • Help on VPD

    I am trying to use VPD in our application. It works fine if I directly use SQL select statement. However I can not get the right reocrd set if the SQL statement in stored procedures, functions, or package. Your kind reply will be highly appreciated.

    Find the issue.
    If I logon into system use sys as sysdba and then grant exempt access policy to one user, then i get the problem. If I logon the current schema using one user with DBA roles, and then grant exempt access policy to one user, the whole system works fine now.
    Thanks a lot.

Maybe you are looking for

  • Getting Information from ID3 tags from streamed mp3 files in Flash CS4 AS3.0

    Hi everyone: I have spend my whole day trying to find a good way to access ID3 tags in AS3.0; but didn't find anything helpful. In my project I am making a sound object and assigning it a URL: Then I stream the sound into a sound channel: var s:Sound

  • Apple TV/itunes & Elgato Software - export problems

    I am using Elgato software to capture TV and then compact and convert to Apple TV. Used to work fine but it has now gone a bit haywire. The export (convert I guess) process takes some time and the file just disappears most times. (ie cannot find it u

  • Script logic record more than 300,000 record

    Hi Expert, When I run my logic I have error in my formula log: (More than 300,000 records. Details are not being logged) Ignoring Status Posting ok I check my script it pull out total 422076 records. Is it meaning I cannot More than 300,000 records??

  • MESSAGING app STOPPED WORKING

    Why has this app stopped working i have only had the phone for two days i can`t send any messages because it keeps saying closing down

  • Custom multiline table header

    I was trying to set JPanel with two inner components (JTextField and JLabel) as header renderer. When I put this component to JFrame text field is editable, but when it appears in my custom table header it is disabled or not focusable, that part I co