VPD Question

Hi all,
I have a technical question about VPD.
The documentation says, VPD is working the following way:
When a user issues a statement, the statement is automaticly rewritten. This is done by appending a predicate delivered by a pl/sql function to the original query just before the parsing of the query is done.
But it was not working as I expected. I can give you an example:
I have to schemas. One schema (lets say scott) contains my application data. The other schema (say vpd_admin) stores the policies.
In the vpd_admin schema I created a procedure to return the predicate:
CREATE OR REPLACE FUNCTION nur_bereich (
                               p_schema IN VARCHAR2 DEFAULT NULL,
                               p_object IN VARCHAR2 DEFAULT NULL)
                       RETURN VARCHAR2
AS
BEGIN
  IF sys_context('my_ctx','user') is null then
    RETURN NULL;
  ELSE
      IF p_object = 'EMP' THEN
        RETURN 'ename = sys_context(''my_ctx'',''user'') ' ;
      ELSIF p_object = 'DEPT' THEN
        RETURN 'deptno IN (SELECT deptno FROM emp)';
      END IF;
    END IF;
  END IF;
END;
/I applied the the policy to both tables (emp and dept)
BEGIN
DBMS_RLS.add_policy
         (object_schema => 'SCOTT',
          object_name => 'EMP',
          policy_name => 'ONLY_ME',
          function_schema => 'vpd_admin',
          policy_function => 'nur_bereich',
          statement_types => 'SELECT,INSERT,UPDATE',
          update_check => TRUE,
          policy_type => dbms_rls.CONTEXT_SENSITIVE
END;
BEGIN
DBMS_RLS.add_policy
         (object_schema => 'SCOTT',
          object_name => 'DEPT',
          policy_name => 'ONLY_ME',
          function_schema => 'vpd_admin',
          policy_function => 'nur_bereich',
          statement_types => 'SELECT,INSERT,UPDATE',
          update_check => TRUE,
          policy_type => dbms_rls.CONTEXT_SENSITIVE
END;
/But if I issue a select statement against the dept table, I get an Invalid predicate exception. After looking at the generated trace file, I found that the original error is a table not found exception. After granting select on emp to vpd_admin and creating a synonym it works like a charm.
It appears to me, that the parsing is done in the vpd_admin schema. But the next strange thing was, that when i created the policy function in the scott schema and applied this policy to the dept table (using the vpd_admin schema), it works great.
So now I a disturbed about the question how the query rewrite is done, where is it done and who does the parsing.
Any explanation would be welcome.
Regards
Stephan

Hi Rob,
thank you for your answer. But what I don't understand is why the secure schema must be able to access the table to which the policy is linked. I thought the policy function returns the predicate and then the query is rewritten with the privileges of the user issuing the query. But it appears that the query is rewritten with the privileges of the user that owns the predicate function. So if the predicate function is defined in the scott schema, the query is rewritten and parsed in the scott schema. And if the predicate function is defined in the secure schema, the query is rewritten and parsed in the secure schema.
So my initial guess, that the query is rewritten in the secure schema and is afterwards parsed as SCOTT is wrong. Or does the process of rewriting the query need access to SCOTT objects referenced by the the predicate? I think thats very likely.
If I got it right, the process of how VPD works is:
1; User queries table emp
2; VPD intercepts the query and evaluated the policy function defined in a secure schema
3; The query is rewritten in the secure schema. This process may need access to the tables and or objects of the query schema
4; After the query is rewritten in the secure schema, it is parsed and executed in the query schema. The user gets his data.
Is this correct?
Thanks
Stephan

Similar Messages

  • VPD Question - Not executing Policy?

    Hi, I followed the script and my results are below:
    But I do a select * from T and get all 5 rows:
    Can anyone see anything missing?
    select
    namespace, attribute, value
    from
    session_context
    where namespace = 'MYCTX';
    create or replace function rls_examp ( p_schema in varchar2,
    p_object in varchar2
    return varchar2
    as
    l_x number;
    begin
    select sys_context( 'myctx', 'X' ) into l_x from dual;
    if ( nvl(l_x,-1)) != -1
    --sys_context( 'myctx', 'x' ) is not null )
    then
    return ' data = ''data 01'' ';
    -- return 'X = to_number( sys_context(''myctx'',''x''))';
    else
    return 'X = 3 ';
    end if;
    end;
    drop table t;
    create table t ( X number,data varchar2(10) );
    insert into t values ( 1,'data 01' );
    insert into t values ( 2,'data 02' );
    insert into t values ( 3,'data 03' );
    insert into t values ( 4,'data 04' );
    insert into t values ( 1234,'data 1234' );
    begin
    begin
    dbms_rls.drop_policy( user, 'T', 'T_POLICY' );
    exception
    when others then null;
    end;
    begin
    dbms_rls.add_policy
    ( object_schema => user,
    object_name => 'T', --table name
    policy_name => 'T_POLICY',
    function_schema => user,
    policy_function => 'rls_examp',
    statement_types => 'SELECT,INSERT,UPDATE,DELETE',
    update_check => FALSE, -- set back to FALSE
    enable => TRUE,
    static_policy => FALSE);
    end;
    end;
    create or replace procedure set_ctx( p_val in varchar2 )
    as
    begin
    -- dbms_session.clear_all_context( 'myctx' );
    dbms_session.set_context( 'myctx', 'X', p_val );
    end;
    create or replace context myctx using set_ctx;
    begin
    set_ctx( null );
    end;
    select rls_examp(' ',' ') from dual;
    select * from t;
    select
    namespace, attribute, value
    from
    session_context
    where namespace = 'MYCTX';
    begin
    set_ctx( 99 ) ;
    end;
    select rls_examp(' ',' ') from dual;
    select * from t;
    select
    namespace, attribute, value
    from
    session_context
    where namespace = 'MYCTX';
    select rls_examp(' ',' ') from dual;

    Here is what I tried just to get an error...
    Could I have created the function somewhere else and be accessing it instead where I would get errors but still would get no altered results?
    Bill
    select
    namespace, attribute, value
    from
    session_context
    where namespace = 'MYCTX';
    drop table t;
    create table T ( X number,data varchar2(10) );
    insert into T values ( 1,'data 01' );
    insert into T values ( 2,'data 02' );
    insert into T values ( 3,'data 03' );
    insert into t values ( 4,'data 04' );
    insert into T values ( 1234,'data 1234' );
    create or replace function RLS_EXAMP(p_schema in varchar2,
    p_object in varchar2 )
    return varchar2
    as
    l_x number;
    begin
    return 'owner = 3 ';
    end;
    begin
    dbms_rls.drop_policy( 'BOLINF', 'T', 'T_POLICY' );
    exception
    when others then null;
    end;
    begin
    dbms_rls.add_policy
    ( object_schema => 'BOLINF',
    object_name => 'T', --table name
    policy_name => 'T_POLICY',
    function_schema => 'BOLINF',
    policy_function => 'RLS_EXAMP',
    statement_types => 'SELECT,UPDATE,DELETE');
    end;
    CREATE OR REPLACE PROCEDURE show_context_info
    IS
    context_info DBMS_SESSION.AppCtxTabTyp;
    info_count PLS_INTEGER;
    indx PLS_INTEGER;
    BEGIN
    DBMS_SESSION.LIST_CONTEXT (
    context_info,
    info_count);
    indx := context_info.FIRST;
    LOOP
    EXIT WHEN indx IS NULL;
    DBMS_OUTPUT.PUT_LINE (
    context_info(indx).namespace || '.' ||
    context_info(indx).attribute || ' = ' ||
    context_info(indx).value);
    indx := context_info.NEXT (indx);
    END LOOP;
    END;
    create or replace procedure set_ctx( p_val in varchar2 )
    as
    begin
    -- dbms_session.clear_all_context( 'myctx' );
    dbms_session.set_context( 'myctx', 'X', p_val );
    end;
    create or replace context myctx using set_ctx;
    begin
    set_ctx( '3' );
    end;
    /

  • (VPD) Virtual Private Database Question?

    Hi All,
    I have a question regarding VPD, I want to implement Column level security, senario is: (Oracle 9i, 10g)
    TABLE
    =======
    CUSTOMER
    (cust_id, name , address, phone, email ) etc
    There is one user "PIN"in which all objects are created and stored, and others users has granted rights through synonyms created on their schemas,
    my question is: All users can access/fetch all rows of customer table but they should not see address and phone fields?, these 2 fields should be NULL for them, is it possible to implement this security policy through VPD?
    prompt reply would be appreciated.
    regards
    qamar
    Edited by: qamarsyed on Nov 5, 2008 12:43 PM

    From the same example, I created the function to exclude all department numbers from DEPT table and I got what you were looking for. But based on your requirement, this function can prove to be costly.
    SQL> ed
    Wrote file afiedt.buf
      1  CREATE OR REPLACE FUNCTION pf_job (oowner IN VARCHAR2, ojname IN VARCHAR2)
      2  RETURN VARCHAR2 AS
      3    con VARCHAR2 (200);
      4  BEGIN
      5    con := 'deptno not in (select deptno from dept)';
      6    RETURN (con);
      7* END pf_job;
    SQL> /
    Function created.And here is the output from other user.
    SQL> /
        DEPTNO      EMPNO ENAME             SAL       COMM
            20       7369 SMITH
            30       7499 ALLEN
            30       7521 WARD
            20       7566 JONES
            30       7654 MARTIN
            30       7698 BLAKE
            10       7782 CLARK
            20       7788 SCOTT
            10       7839 KING
            30       7844 TURNER
            20       7876 ADAMS
            30       7900 JAMES
            20       7902 FORD
            10       7934 MILLER
    14 rows selected.
    SQL>

  • 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

  • Few Questions on OBIEE Architecture

    This is just a continuation of this thread:
    Confused on BI Publisher and BI Presentation Services
    So just want to know how the whole process takes place, from RPD, XDO, NSQconfig..
    So from Step 1 =)
    From what I understand as of now is I need to go to Administration Tool, create first a repository? Then go to BI Presentation Services to create reports ( using Answers )? When does the user creation comes into place? What is the purpose of BI Publisher? I've already setup a few things on BI Publisher like User, Roles, etc. but still not on the part of creating a report. Sorry If I ask too many questions, I'm just trying to understand what's the relationship of each tool. I've checked the docs and mostly they're just diving into modifying configs without really explaining why. ( at least that's how I saw it ) =)
    Thank you very much again!

    Wow - where do we start !
    Remember they are two seperate products, OBIEE and its related configs / components (RPD, BI Server, BI Presentation services - Answers, Dashboards, ibots etc)
    BI Publisher, formerley XML Publisher, sucessor to Oracle Reports.
    They fall under the Oracle BI Stack.
    Loads of info on our website, link in the previous post you mentioned.
    'Roles' in OBIEE can determine - Authorisation ie what you can do in the sytem or "Priviledges". What objects (reports / dashboards) you can use and can also be used for data security filters (Like a OBIEE 'virtual private database' version of the real Oracle DB option 'VPD')
    Roles in BI Publsher typically can mean the same, who can create folders, who can create reports, who can run them , who can create data sources etc. Sometimes you have to use a system specific role name, sometimes you can create your own names and reference them as you please (BIP roles are typically one of a pre-defined set, OBIEE roles can be called whatever you want)
    Sounds hard at first and without prior experience but seriously, there are some very very good blogs out there, as mentioned in previous response, we also have a lot of info on our website (Peakindicators.com)
    Feel free to email me.

  • Implement row-level security using Oracleu2019s Virtual Private Databases (VPD)

    Environment: Business Objects XI R2; Oracle 10g
    Functional Requirement:
    Implement row-level security using Oracleu2019s Virtual Private Databases (VPD) technology. The restriction is that the Business Objects Universe connection should use a generic/u201Capplicationu201D database user account. This will allow the organization to avoid the situation where the Business Objects password and the Oracle password need to be kept in synch.
    What do we need from the Business Objects support team?
    1.     Review the 2 attempted solutions that we have tried to implement
    2.     Propose solutions/answers to open questions for each of the attempted solutions
    3.     Propose any alternate solution that will help us implement the Function Requirement stated above
    Attempted Solution 1: Connection String uses Oracle Proxy User
    The connection string that is specified in the Universe is the following:
    app_user[end_user]/app_user_pwdarrobaDatabase.WORLD
    app_user = generic application user
    end_user = the oracle account of the end user which is set using arrobaVariable('BOUSER') app_user_pwd = password of the generic application user
    We have tried and implemented this in our test environment. However, we have some questions and concerns around how the connections are reused in a connection pool environment.
    Open Question for Solution 1:
    i. What happens when multiple proxy users try to connect on at the same time?  Business Objects shares the generic app_user connect string.  However, every user that logs on will have their own unique proxy user credentials.  Will there be any contention involved?  If so, what kind of errors can we expect?
    ii. If a user logs on using his credentials (proxy user), and business objects opens up a connection to the database using that user's credentials (as the proxy user but logging in through the generic app user). Then the user exits out --> based on our test today, it seems like the database connection remains open.  In that case, if another user logs on similarly with their credentials, will business objects simply assign the first users connection to that second user?  If so, then our security will not work.  Is there a way that Business Objects can somehow ensure that everytime we close a report, the connection is also terminated both at the BO and DB levels?
    iii. Our 3rd question is general high level -> How connection pooling works in general and how it is implemented in BO, i.e. how are new connections assigned, how are they recycled, how are they closed, etc.
    Attempted Solution 2: Using the ConnectInit parameter
    Reading through a couple of the Business Objects documents, it states that u201CUsing the ConnectInit parameter it is possible to send commands to the database when opening the session which can be used to set database specific parameters used for optimization.u201D
    Therefore, we tried to set the parameter in the Universe using several different options:
    ConnectInit = BEGIN SYSTEM.prc_logon('arrobaVARIABLE('BOUSER')'); COMMIT; END; ConnectInit = BEGIN DBMS_SESSION.SET_IDENTIFIER('arrobaVariable('BOUSER')'); COMMIT; END;
    Neither of the above iterations or any variation of that seemed to work. It seems that the variable is not being set or being u201Cexecutedu201D on the database.
    One of the Business Objects documents had stated that Patch ID 38, 977, 350 must be installed in our BO environments. We have verified that this patch has been applied on our system.
    Open Questions for Solution 2:
    How do we get the parameter ConnectInit to work? i.e. what is the proper syntax to enter and what other things do we need to check to get this to work.
    Note: Arroba word is being used instead of the symbol in order to avoid following error message:
    We are sorry but your message can not be posted since you have included an email address. Please remove the email address and re-post.

    the connectinit setting should look something like this:
    declare a date; begin vpd_setup('@VARIABLE('BOUSER')'); Commit; end;
    The vpd_setup procedure (in Oracle) should look like this:
    CREATE OR REPLACE procedure vpd_setup (p_user varchar)IS
    BEGIN
      DBMS_SESSION.set_vpd( 'SESSION_VALUES', 'USERID', p_user );
    END vpd_setup;
    Then you can retrieve the value of the context variable in your vpd functions
    and set the vpd.

  • Converting a delete statement using VPD policies and context

    Hello,
    I'm trying to convert a delete statement in a update statement using VPD policies and context.
    +/* Supose the user 'user1' already exists. This is an application user */+
    conn user1/pwd
    create table user1.test_a (
    id                number(4),
    description       varchar2(100),
    deleted           number(1)
    +);+
    alter table user1.test_a add constraint test_a_pk primary key (id);
    insert into user1.test_a (1, 'abc', 0);
    insert into user1.test_a (2, 'def', 0);
    commit;
    I'd like to convert each physical deletion into a logical deletion: statements like "delete from user1.test_a where id = 1" must be converted into "update user1.test_a set deleted = 1 where id = 1".
    I've found the following way: I will create a policy to avoid physical deletion. Additionally, the policy function should update the deletion flag too.
    conn user1/pwd
    +/* Create context package */+
    create or replace package user1.pkg_security_context is
    procedure p_set_ctx(
    i_test_a_id      in   user1.test_a.id   %type
    +);+
    end;
    +/+
    create or replace package body user1.pkg_security_context is
    procedure p_set_ctx (
    i_test_a_id      in   user1.test_a.id   %type
    +) is+
    begin
    dbms_session.set_context( 'user1_ctx', 'test_a_id', i_test_a_id );
    end;
    end;
    +/+
    show errors
    +/* Create trigger to set the context before deletion */+
    create or replace trigger user1.test_a_bef_trg
    before delete on user1.test_a
    for each row
    declare
    pragma autonomous_transaction;
    begin
    -- only commits the preceding update, not the delete that fired the trigger.
    commit;
    user1.pkg_security_context.p_set_ctx( :old.id );
    end;
    +/+
    show errors
    create context user1_ctx using user1.pkg_security_context;
    +/* Policy function */+
    create or replace function user1.f_policy_chk_dels (
    object_schema in   varchar2,
    object_name   in   varchar2
    +) return varchar2+
    is
    out_string                 varchar2(400)   default '1=2 ';
    +/*+
    * out_string is the return value.
    *  - 'WHERE 1=2' means 'nothing to access'
    begin
    if ( loc_logged_usr_authorized > 0 ) then
    +/*+
    * Set the flag deleted to 1
    update user1.test_a set deleted = 1 where id = sys_context( 'user1_ctx', 'test_a_id' );
    out_string := out_string || 'or 1=1 ';
    end if;
    return out_string;
    end;
    +/+
    show errors
    +/*+
    * Create policy
    begin
    dbms_rls.add_policy(
    object_schema   => 'user1'                   ,
    object_name     => 'test_a'                  ,
    policy_name     => 'policy_chk_dels'         ,
    function_schema => 'user1'                   , -- function schema
    policy_function => 'f_policy_chk_dels'       , -- policy function
    statement_types => 'DELETE'
    +);+
    end;
    +/+
    When I try to delete a record of the table test_a:
    conn user1/pwd
    SQL> delete from ilogdia.oplsimulaciones sim       where sim.id = 9999;
    +0 rows deleted+
    No rows has been deleted, but the update stmt does not work. That means, the "deleted" flag has not been updated.
    Any ideas?
    Thank you in advance.
    Marco A. Serrano
    Edited by: albrotar on Oct 15, 2012 8:42 AM
    Edited by: albrotar on Oct 15, 2012 8:42 AM
    Edited by: albrotar on Oct 15, 2012 8:43 AM

    The policy function is applied once per statement execution. The policy function executes first and the UPDATE statement, presumably, updates no rows because the context is not yet populated. The row-level populates the context (I'm assuming that your session can even see context values populated by an autonomous transaction-- I would guess it could but I'd have to test that) after the UPDATE statement is already complete. The COMMIT in the row-level trigger is also pointless-- it only applies to changes made by the current autonomous transaction, of which there are none-- it cannot apply to changes made in other autonomous transactions. Declaring the row-level trigger to use autonomous transactions doesn't seem to accomplish anything other than to open the question of whether the values set in the context by the autonomous transaction are visible in the caller's transaction.
    Even if this, somehow, did work, using autonomous transactions would be a very bad idea since Oracle is free to roll-back a partially executed statement (and the work done by its triggers) and re-execute it. Oracle does that with some regularity to maintain write consistency.
    Justin

  • Using VPD in combination with a user table?

    I'm very new with VPD's. In fact, I don't know a thing about it yet (I know the philosophy behind it and the principle, but not the practical implementation). My question: Are VPD's always based on database-users? Our applications have a user-table now, where the access rights to applications are stored. Once a user is present in that table and has the necessary rights, he can login to the application. So we don't have an actual database-user for each "real-life" user, just an entry in a table.
    Is it possible to use the system of VPD's (and maybe Oracle Label Security) with users stored in a table, instead of actual database users?

    TomVD wrote:
    My question: Are VPD's always based on database-users? No, they are not. You could for example put VPD policies on tables that restrict access after a certain time of the day (not caring which user attempts to access the data, using only SYSDATE and a given cut off access time).
    TomVD wrote:
    Is it possible to use the system of VPD's (and maybe Oracle Label Security) with users stored in a table, instead of actual database users?Yes you can.
    VPD allows you to construct a predicate as you would like based on your requirements (you are basically appending a WHERE clause in to every query based on the logic you dictate on the objects and accesses you determine necessary).
    Typically if you're running through a connection pool (as it sounds like you are) you would use an application context to set a specific value (the logging in user) and then validate that against your Users table in whatever fashion tickles your fancy
    [Some Tutorials|http://www.google.ca/#hl=en&source=hp&q=oracle+vpd+tutorial&btnG=Google+Search&meta=&aq=0&oq=oracle+vpd+&fp=8e6c6930b7d53e73] may also be helpful
    and of course .. [The Documentation|http://download.oracle.com/docs/cd/E11882_01/network.112/e10574/vpd.htm]

  • Multimaster Replication and VPD in Oracle 10g R2

    Hello,
    I would like to know if MlitiMaster Replication supports the VPD(Virtual Private Database) Row level or column level access control? if so could some one point me to the right documentation? i searched Metalink and googled but unable to find any info regarding the support of VPD to replication.
    Thank you....

    Justin,
    we have streams and replication in our environment. our databases on window 2003 server and oracle 10gR2. my question is we are planning to implement the VPD on few tables which are already in replication group. We use 'REPADMIN' for replication. will it propagate the data for VPD columns that are in replication environment? how will this impact performance wise? I am trying to find also some Pros and Cons too.
    Thank you.

  • VPD column-masking: unexpected results using masked column in WHERE?

    Hi everyone..
    We are considering implementing VPD column-masking (to hide sensitive columns from unauthorized users), but I am concerned that queries will return incorrect results if an unauthorized user submits a query using a masked column in a WHERE clause - particularly in a JOIN operation.
    Our initial experiment confirms my concern:
    - We have a VPD policy on TABLE_X.COLUMN_Y:
    DBMS_RLS.ADD_POLICY(
    object_schema => 'xxxx',
    object_name => 'TABLE_X',
    policy_name => 'policy_x',
    function_schema => 'xxxx',
    policy_function => 'function_x',
    sec_relevant_cols =>'COLUMN_Y',
    sec_relevant_cols_opt => dbms_rls.ALL_ROWS)
    - The VPD function determines whether the user is authorized (1=1) or not (1=0)
    - COLUMN_Y contains various values, including NULL
    - when an "authorized" user submits the query "SELECT COUNT(*) FROM TABLE_X WHERE COLUMN_Y IS NULL", COUNT=correct number of rows containing NULL
    - when an "unauthorized" user submits the same query, COUNT=the total number of rows in the table -- presumably because the WHERE clause was modified to WHERE NULL=NULL
    In my opinion, the unauthorized user's query should return an error, because any other result is either wrong (i.e. COUNT=all rows, or returns a null result set) or something the user is not permitted to know (i.e. COUNT=correct number of rows)
    Am I missing some feature/setting of VPD that could let me force an error? I hope there is something out there, since I don't see any discussion or warnings about this pitfall.
    We are currently using Oracle 10.2.0.4 but upgrading to 11.1 soon.
    Thanks!
    Betty
    p.s. I originally incorrectly posted this question on the Technologies / Security forum.

    Thanks - yes, we have a function that checks whether the user id is authorized or not.
    The column-masking works, that is, authorized users can see the data; unauthorized users cannot. The issue is what happens when unauthorized users use the masked column in a WHERE predicate.

  • Does a table/view still return records if the underlying VPD policy fails ?

    Hi All,
    I have one following question -
    Does a table or view still return records if the underlying VPD policy fails?
    I am adding one more thing here. Let us say security is being implemented using the application context and VPD.
    What would happen when application context is not set ? Would the application apply any default privilege as VPD?
    Thanks,
    Ashi

    AshiKD wrote:
    Hi All,
    I have one following question -
    Does a table or view still return records if the underlying VPD policy fails?No, you get a standard error message if the VPD function is wrong and if you won't pass the conditions of the VPD, you get nothing. That's what in general happens and should happen as well.
    >
    I am adding one more thing here. Let us say security is being implemented using the application context and VPD.
    What would happen when application context is not set ? Would the application apply any default privilege as VPD?This would be a wrong approach then. If you are truly setting a VPD, you have to make sure that the context is set and the condition variable are passed through it. This is normally done through a logon trigger so again, generically , its not possible that it would not be set. I didn't get at all what ever you said in the last line? What is "default priv for VPD" ?
    HTH
    Aman....

  • VPD: Problems calling a function on another schema

    Here's the setup:
    I've create a schema called "AllYourBase".  It contains all of my tables, views, functions, procs, etc.
    These tables are protected by a DBMS_RLS policy.  The policy uses a function to define its predicate which looks like this:
    create or replace function tous_filter(schemaName varchar2, tableName varchar2)
    return varchar2 is
    begin
    return  'account = sys_context(''USERENV'', ''CLIENT_IDENTIFIER'')';
    end;
    All of the tables have an account column for this to work.  So far, this is a pretty basic VPD setup.
    I have other db users that login and view data in the "AllYourBase" schema.
    So when "ArbyLong" logs in, I set sys_context('USERENV', 'CLIENT_IDENTIFIER') to "ArbyLong", and when he runs a query, he gets back his rows.
    Now, "AllYourBase" has several functions.  Here's a very contrived, simplified example of one (but it illustrates the issue I'm running into just fine):
    create or replace function getUserID
    return integer is retval integer;
    begin
    select user_id into retval from users;
    return (retval);
    end;
    When "ArbyLong" runs the equivalent query (select user_id from users), he gets back the one row where the account column is equal to "ArbyLong", as expected.
    But this getUserID function lives in the "AllYourBase" schema.  And here's the catch: I've made "AllYourBase" exempt from the policies by running "grant exempt access policy to AllYourBase".
    When "ArbyLong" runs the function getUserID, it runs in the "AllYourBase" schema and pulls ALL of the rows from the users table.
    This particular function simply errors out (since it's only expecting one row), but other functions are returning data that the logged in user shouldn't see.
    So even though there are policies in place, by calling a function on another schema who is exempt from the policies, a user is able to see all returned data and not just the rows they are normally limited to.
    Ultimately my question is this: Is there a way to enforce VPD policies when a user calls a function that lives in another schema?
    Doing my own research, the answers I've come up with are:
    * Don't use "grant exempt policy"!
    * Put the function directly into the users' schemas.  So "ArbyLong" would have his own getUserID function that would look at the "AllYourBase" users table.
    I'd rather not do either of these, so does anyone have any other ideas?  If it turns out these are the only solutions, then I'll go with one of them.
    Thanks!

    Need more info. Are you using a ViewStack or other navigator container, and trying to access a view that has not been displayed yet, due to deferred instantiation?
    If this post answers your question or helps, please mark it as such.
    Greg Lafrance - Flex 2 and 3 ACE certified
    www.ChikaraDev.com
    Flex Training and Support Services

  • VPD+DBLINK

    Hi, I am trying VPD functionality, Can any one guide me?
    I have 2 schema in one database
    shema are 1.bdev 2.hdev
    I have customer table in hdev schema like
    Table CUSTOMERS -
    COD_ENTITY VARCHAR2(20)
    CUST_ID NUMBER
    CUST_NAME VARCHAR2(20)
    create table customers
    (cod_entity varchar2(20),
    cust_id number,
    cust_name varchar2(20));
    Customer table Data
    COD_ENTITY CUST_ID CUST_NAME
    MARK 123 Tom
    SALES 456 Wim Patel
    MARK 124 George
    SALES 789 Smith
    There is a view in bdev schema which is based on CUSTOMERS table of hdev schema.
    view
    CREATE OR REPLACE VIEW CUSTOMERS
    (COD_ENTITY, CUST_ID, CUST_NAME) AS
    SELECT COD_ENTITY, CUST_ID, CUST_NAME FROM CUSTOMERS@dllink
    here dllink is a database link which points to hdev. That means CUSTOMERS view in bdev retrieves data from hdev and shows when I query select * from customers at dhev
    Now here problem comes, I want to apply VPD policy on CUSTOMER table at hdev
    Policy function at hdev
    create or replace function vpd_func_customers
    p_schema in varchar2,
    p_table in varchar2
    return varchar2
    as
    l_retstr varchar2(2000);
    l_ctr number;
    begin
    if (SYS_CONTEXT ('USERENV', 'CLIENT_INFO') = 'ALL') then
    l_retstr := null;
    else
    l_retstr := '(cod_entity = SYS_CONTEXT (''USERENV'', ''CLIENT_INFO'')) OR (cod_entity = ''ALL'')';
    end if;
    return l_retstr;
    end;
    Applied Policy at hdev on Customer table
    begin
    dbms_rls.add_policy (
    object_schema => 'hdev',
    object_name => 'CUSTOMERS',
    policy_name => 'vpd_customers_policy',
    function_schema => 'hdev',
    policy_function => 'vpd_func_customers',
    statement_types => 'SELECT,INSERT,UPDATE,DELETE',
    update_check => TRUE
    end;
    Now tested policy function at hdev
    call DBMS_APPLICATION_INFO.SET_CLIENT_INFO ('MARK')
    select * from customers
    it gave me two rows
    1 MARK 123 Tom
    2 MARK 124 George
    upto this is ok
    but when I logon to bdev and fires query
    call DBMS_APPLICATION_INFO.SET_CLIENT_INFO ('MARK')
    select * from customers
    it gives me zero rows.
    PLEASE HELP ME OUT HOW TO USE VPD with DBLINK. I NEED IT URGENT FOR MY PROJECT.
    Thanks in Advance
    Santosh

    Santhosh,
    you are posting to the wrong forum. Its a database related question and should be posted on a database forum.
    Frank

  • Problem with VPD policy function

    Hi All,
    I'm trying to secure database tables with VPD and getting "ORA-28112: failed to execute policy function" error when I query the table.
    --My schema is "sales"
    grant crete any context to sales;
    -- created context using this statement
    create OR REPLACE context sales_APP_CTX using PKG_SECURITY ACCESSED GLOBALLY;
    -- Package spec
    CREATE OR REPLACE PACKAGE PKG_SECURITY is
    function vpd_sec_pol_func return varchar2 ;
    procedure set_sales_app_context(p_user varchar2,p_security_level varchar2);
    end;
    -- package body
    CREATE OR REPLACE PACKAGE BODY PKG_SECURITY is
    function vpd_sec_pol_func return varchar2 is
    -- v_user varchar2(100) := UPPER(portal.wwctx_api.get_user);
    begin
    if user not in ('SALES','ORACLE') then
    return ' state in (select state from app_user_states where user_id = sys_context(''SALES_APP_CTX'', ''APP_USER''))';
    else
    return null;
    end if;
    end;
    procedure set_sales_app_context(p_user varchar2,p_security_level varchar2) is
    begin
    dbms_session.set_context('SALES_APP_CTX','APP_USER',p_user);
    -- dbms_session.set_context('SALES_APP_CTX','SECURITY_LEVEL',p_security_level);
    end;
    end;
    -- Added the policy to the table
    begin
    dbms_rls.add_policy
    ( object_schema => 'SALES',
    object_name => 'SALES_SUMMARY',
    policy_name => 'SALES_SUMMARY_POLICY',
    function_schema => 'SALES',
    policy_function => 'PKG_SECURITY.VPD_SEC_POL_FUNC',
    statement_types => 'SELECT,INSERT,UPDATE,DELETE' ,
    update_check => TRUE );
    end;
    -- I was able to set context using sqlplus by executing the procedure
    exec PKG_SECURITY.set_sales_app_context('TEST_USER','R');
    What am I doing wrong?
    Thanks

    Hi,
    ml_huang wrote:
    Is it necessary to create 'Context' and 'Procedure' before the function and policy?It is not necessary to create a context.
    A context can be very useful for doing row-level security, but it is not required.
    Even if you are using SYS_CONTEXT, you can create the function first, if you want to.
    Sorry, I don't understand what 'Procedure' you mean.
    I have created a function (with no parameters) and a policy and kept getting the Ora-28112 error.Policy functions must accept 2 VARCHAR2 parameters. See the messages above.
    Any suggestions for me? Thanks!Start your own thread for your own question.
    I think more people will want to read (and therefore respond to) a new message with 0 replies than a 3-month old message with 4 replies.

  • EJB3 and/or Toplink and setting context for VPD

    We are looking at moving to the latest version of jdeveloper and taking advantage of the ejb3 and/or toplink features for the model part of applications. I have a question on how to set the vpd context using this new model. Currently we use:
    Jdeveloper 10.1.2.1
    Oracle application server 10g R2 Enterprise Edition ver 10.1.2.0.2
    OracleOCI driver
    Oracle 9i database
    Our database access is in regular java beans where we get a connection from the pool , set the context for the current user (by running a stored procedure on the connection) perform the required data access and then release the connection. It looks like when you use Toplink or EJBs with CMP the database access is out of the developer's control. How will I be able to set the context for each connection ( it's different for each user) once I move to the new model?

    Thank you. That looks like exactly what I need, at least for toplink. I have been told though, that since we are deploying to the OC4J container and it will manage persistence and since EJB 3 simplifies the creation of entity beans that we should use EJB 3 entity beans and a session facade for the model and not add toplink as it would be an extra layer we don't really need , would you agree?

Maybe you are looking for