Skip to content
Advertisement

VPD Policy Function

I’m new to oracle security and I have a question about Virtual Private Database: Let’s assume i have the following table which is called “Payroll” created by a user called “PCM”

Now what i want to achieve is the following: Anyone with the dept = accounting" can select all other rows with dept != accounting but anyone with dept != accounting can only view his/her record. My problem is: since we can’t apply a select statement on the table we are restricting the access to inside the policy function (which is payroll) and since applying a policy function on the (payroll) table will be applied to any view based on it, what’s the logic to solve this problem?? what is the solution, I’ve wrote the following “I’m connected as another user not the owner of the payroll table so I’m connected as a user called ANNE”:

Considering that the users who will try to access the table have the names of the emp_id column,now:

Now the problem(i know it’s wrong) but can’t find the solution:

And then:

and the error message i’m getting when a user E1 tries to select from payroll:

what i’m doing wrong?? I have edited the question and the result based on the answers below.

Advertisement

Answer

I’m going to make some guesses but if none of them solve your problem you will need to look for the diagnostic information the database provides. ORA-28112 will produce a trace file in the user_dump_dest directory on the database server. This should give you all the information you need to diagnose and fix any errors in your policy code. If you don’t have access to that directory you will need to ask your friendly DBA/Sysadmin team to help.

So, the guesses.

You’re setting vv_dept to a string of 'dept = SYS_CONTEXT(''payroll_ctx'', ''dept'')'. In the IF block you concatenate that to a WHERE clause filter. So your final string is actually:

(It will never execute DEPT != branch because you’re assigning that string to vv_dept not executing it, so vv_dept can never equal 'Accounting'.)

This is clearly wrong and so it’s no surprise that Oracle hurls ORA-28112. Fortunately the solution is equally clear: just tidy the assignment of vv_dept:

The other thing to look at is the formatting on the policy itself. You are testing for equality of a string, so you need to wrap it it in quotes to make valid SQL:

And the same for the other branch, obviously.

One other thing to consider. If you logon as a user who is not in payroll table (not sure whether that’s possible) you execute this:

Consequently, that session has no context set which means the policy function will fail if the user subsequently tries to query payroll. A better approach would be to set the context with a null for dept, then in the policy add a test for vv_dept is null which applies 1=2 or something similar.

ORA-06502: PL/SQL: numeric or value error: character string buffer too small

Well you’d certainly get that if you were running your posted sec_fun code, because you defined vv_dept as varchar2(20) and the assigned string is longer than twenty characters. But you say you are running my suggested revisions, so it can’t be that. What is the size of payroll.dept?

Last word.

VPD policies are just a special case of dynamic SQL, and the core teaching remains: dynamic SQL is hard because it turns compilation errors into runtime errors. Likewise the main debugging tool is still writing an execution handle which logs the whole assembled string to a table (or file).


Incidentally, I think there’s a flaw in the business logic. As it stands now nobody can look at the records for the Accounting department (except for power users with the EXEMPT ACCESS POLICY privilege).

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement