174 Part II: Oracle Database Vault CUST_LAST_ CUST_YEAR_OF_BIRTH CUST_MARIT CUST_INCOME_LEVEL Beiers Duval Greeley Grover Hamilton Krider Majors Rowley Stone 9 rows selected. This example demonstrated column-level security using DBV factors and VPD. It is important to note that you can filter the records (row-level security) on the same table with the same approach. You can do this by omitting the sec_relevant_cols and sec_relevant_cols_opt parameters to the DBMS_RLS.ADD_POLICY procedure call. With this approach, MARY would not have been able to see any records (no rows selected) when querying the SH.CUSTOMERS tables outside the corporate network. DBV Factor Integration with OLS DBV includes a feature that allows you to associate DBV identities with OLS labels. When a specific DBV identity is asserted for a session, the OLS label associated with the identity will be merged with the maximum label that is assigned to the user. The merge operation is controlled by an OLS merge algorithm configured by the DBV security administrator. The merge results in an effective OLS session label that cannot be “upgraded” by the user because of the integrated access control of DBV and OLS. Even if the label assigned to the user exceeds the label of the DBV identity, the effective OLS label could be “downgraded” by the label of the DBV identity. The OLS session label controls the records that a user can SELECT, INSERT, UPDATE, or DELETE when OLS labels are applied to data tables. To illustrate this integration, suppose we have an OLS policy that defines labels with which we will categorize customer data records (SH.CUSTOMERS) based on their credit limit. We categorized the credit limits as shown in the table: Credit Limit Category Credit Limit Range LOW Less than $5000 MODERATE Between $5000 and $9999 HIGH Greater than or equal to $10,000 We can associate these OLS labels with the DBV identities we defined for the Connection_ Type factor used in the preceding section to establish an effective session label for OLS based on the identity that is set by DBV. We will prevent any session from accessing customer data records labeled as HIGH when the database session has come from outside the corporate network (Connection_Type = ‘OTHER’). The following table summarizes the rules we will establish: Chapter 5: Database Vault Fundamentals 175 Connection_Type Identity Effective Session Label for OLS LOCAL_DBA HIGH CORPORATE_SSL HIGH CORPORATE_PASSWORD HIGH OTHER LOW The steps to achieve this type of integration are as follows: 1. Define the OLS policy’s components and labels. 2. Create a column for the OLS label to be stored, and label the data records that will be protected. 3. Apply the OLS policy to the tables to be protected. 4. Assign an OLS label range to the users that require access to the data. 5. Enable the OLS policy within DBV and define the merge algorithm. 6. Define the DBV factors whose identities will be merged with the default OLS session label for a user. 7. Associate OLS labels from the policy to each DBV identity. We can implement an OLS policy for our example by simply defining three OLS level components and three OLS labels using the LBACSYS account. The LBACSYS account is the object-owner account for the OLS option. lbacsys@aos> first create the OLS policy with the lbacsys@aos> name of the column to store the label lbacsys@aos> in and the default access control options lbacsys@aos> BEGIN sa_sysdba.create_policy( policy_name => 'CUSTOMER_POLICY' , column_name => 'CUSTOMER_LABEL' , default_options =>'READ_CONTROL,WRITE_CONTROL,CHECK_CONTROL' ); END; / PL/SQL procedure successfully completed. lbacsys@aos> create the OLS levels for the lbacsys@aos> customer policy lbacsys@aos> BEGIN customers with a low credit limit sa_components.create_level( policy_name=> 'CUSTOMER_POLICY' , level_num => 10 , short_name => 'LOW' , long_name => 'LOW CREDIT LIMIT' ); 176 Part II: Oracle Database Vault customers with a moderate credit limit sa_components.create_level( policy_name=> 'CUSTOMER_POLICY' , level_num => 20 , short_name => 'MODERATE' , long_name => 'MODERATE CREDIT LIMIT' ); customers with a high credit limit sa_components.create_level( policy_name=> 'CUSTOMER_POLICY' , level_num => 30 , short_name => 'HIGH' , long_name => 'HIGH CREDIT LIMIT' ); END; / PL/SQL procedure successfully completed. lbacsys@aos> create the OLS labels for the lbacsys@aos> customer policy lbacsys@aos> BEGIN customers with a low credit limit sa_label_admin.create_label( policy_name => 'CUSTOMER_POLICY' , label_tag => 10 , label_value => 'LOW' ); customers with a moderate credit limit sa_label_admin.create_label( policy_name => 'CUSTOMER_POLICY' , label_tag => 20 , label_value => 'MODERATE' ); customers with a high credit limit sa_label_admin.create_label( policy_name => 'CUSTOMER_POLICY' , label_tag => 30 , label_value => 'HIGH' ); END; / PL/SQL procedure successfully completed. Note that OLS compartment and group components work with the DBV/OLS integration, but this example will simply use OLS level components. We can now create a column named CUSTOMER_LABEL in the SH_CUSTOMERS table. This column name was specified in the call to SA_SYSDBA.CREATE_POLICY earlier. This column will hold the OLS label number for each data record and is a requirement for OLS. The label numbers were defined in the calls to SA_LABEL_ ADMIN.CREATE_LABEL. We will first remove the VPD policy on SH.CUSTOMERS table that we had created in the preceding example, then add the new label column, and then populate the data records with the appropriate label number. Note that Oracle supports the condition in which multiple VPD and OLS policies exist and interoperate on a single table. We are simply removing Chapter 5: Database Vault Fundamentals 177 the example here to clarify that a single access control policy is active. The DBV realm administrator, MARY, of the Sales History realm can perform these steps. mary@aos> remove the VPD example from the previous example mary@aos> BEGIN dbms_rls.drop_policy( object_schema => 'SH' ,object_name => 'CUSTOMERS' ,policy_name => 'POLICY_CUSTOMERS' ); END; / PL/SQL procedure successfully completed. mary@aos> add the column to the customer table mary@aos> to hold the OLS security label mary@aos> ALTER TABLE sh.customers ADD customer_label NUMBER; Table altered. mary@aos> populate the customer_label column with the appropriate mary@aos> data label for LOW credit limit customers mary@aos> UPDATE sh.customers SET customer_label = 10 WHERE cust_credit_limit < 5000; 19309 rows updated. mary@aos> populate the customer_label column with the appropriate mary@aos> data label for MODERATE credit limit customers mary@aos> UPDATE sh.customers SET customer_label = 20 WHERE cust_credit_limit BETWEEN 5000 AND 9999; 25451 rows updated. mary@aos> populate the customer_label column with the appropriate mary@aos> data label for HIGH credit limit customers mary@aos> UPDATE sh.customers SET customer_label = 30 WHERE cust_credit_limit >= 10000; 10740 rows updated. mary@aos> save the data changes mary@aos>COMMIT; Commit complete. The next step is to use the LBACSYS account to apply our OLS policy to the SH.CUSTOMERS. This will provide the label-based access control protection on the table for any subsequent SELECT, INSERT, UPDATE, or DELETE transactions on the table. To perform this step, we must consider that OLS places Oracle database triggers on tables that are being protected. These triggers are used to ensure that labels for new data records are provided and will perform auditing for OLS operations on the protected tables. The SH.CUSTOMERS table is protected by the Sales History realm that will obviously prevent these CREATE TRIGGER statements from completing 178 Part II: Oracle Database Vault successfully. The best approach to handling this is to authorize the LBACSYS account in the Sales History realm as a participant rather than disabling the realm altogether. dbvowner@aos> authorize LBACSYS in the Sales History realm dbvowner@aos> BEGIN dbms_macadm.add_auth_to_realm ( realm_name =>'Sales History' , grantee => 'LBACSYS' , rule_set_name => NULL , auth_options => dbms_macutl.g_realm_auth_participant ); END; / PL/SQL procedure successfully completed. dbvowner@aos>connect lbacsys Enter password: Connected. lbacsys@aos> apply the OLS policy to the customer lbacsys@aos> table with the table-specific lbacsys@aos> access control options lbacsys@aos> BEGIN sa_policy_admin.apply_table_policy( policy_name => 'CUSTOMER_POLICY' , schema_name => 'SH' , table_name => 'CUSTOMERS' , table_options => 'READ_CONTROL,WRITE_CONTROL,CHECK_CONTROL' ); END; / PL/SQL procedure successfully completed. At this point in the configuration, the DBV Sales History realm administrator, MARY, cannot query data in the SH.CUSTOMERS table. mary@aos> SELECT cust_last_name , cust_year_of_birth , cust_marital_status , cust_income_level FROM sh.customers WHERE cust_state_province = 'TX' AND ROWNUM < 1 ORDER BY cust_last_name / no rows selected We have to assign MARY a label range in the OLS policy using the LBACSYS account. We want to provide MARY full access to all records in the SH.CUSTOMERS table so the range that will be assigned to her will be LOW–HIGH. assign the labels ranges of data records that MARY can read and write Chapter 5: Database Vault Fundamentals 179 BEGIN sa_user_admin.set_user_labels( policy_name => 'CUSTOMER_POLICY' , user_name => 'MARY' , min_write_label => 'LOW' , max_read_label => 'HIGH' , max_write_label => 'HIGH' , def_label => 'HIGH' , row_label => 'HIGH' ); END; / PL/SQL procedure successfully completed. As a result of this label range assignment, MARY can now access the records in the SH.CUSTOMERS table. mary@aos> query the SH.CUSTOMERS table mary@aos> SELECT cust_last_name , cust_year_of_birth , cust_marital_status , cust_income_level FROM sh.customers WHERE cust_state_province = 'TX' AND ROWNUM < 10 ORDER BY cust_last_name / CUST_LAST_ CUST_YEAR_OF_BIRTH CUST_MARIT CUST_INCOME_LEVEL Beiers 1982 single K: 250,000 - 299,999 Duval 1981 single H: 150,000 - 169,999 Greeley 1977 F: 110,000 - 129,999 Grover 1970 married D: 70,000 - 89,999 Hamilton 1961 single G: 130,000 - 149,999 Krider 1967 F: 110,000 - 129,999 Majors 1948 single G: 130,000 - 149,999 Rowley 1969 single H: 150,000 - 169,999 Stone 1978 single I: 170,000 - 189,999 9 rows selected. Having defined the OLS policy for the table, we want to protect and authorize the named users in this OLS policy, and we can remove the realm authorization for the LBACSYS account in the Sales History realm. We can also identify this OLS policy as being integrated with DBV using the PL/SQL procedure DBMS_MACADM.CREATE_MAC_POLICY. dbvowner@aos> remove the realm authorization for LBACSYS dbvowner@aos> as we've applied the policy on the table dbvowner@aos> BEGIN dbms_macadm.delete_auth_from_realm ( realm_name =>'Sales History' , grantee => 'LBACSYS' ); 180 Part II: Oracle Database Vault END; / PL/SQL procedure successfully completed. dbvowner@aos> enable the OLS policy within DBV and dbvowner@aos> define the merge algorithm BEGIN dbms_macadm.create_mac_policy( policy_name => 'CUSTOMER_POLICY' , algorithm => 'LII' ); END; / PL/SQL procedure successfully completed. The algorithm LII means “Least upper-bound of all levels, Intersection of compartments, Intersection of groups.” This algorithm is the most appropriate and most commonly used algorithm in commercial and government systems. This algorithm and others are available with OLS and are described in the “Label Security Administrator’s Guide” should you need to research them for your application’s needs. In our example, this algorithm basically means that the merging of the label LOW with a label of HIGH will result in LOW, or the least upper-bound of the levels. We now need to configure DBV with the name(s) of the DBV factor(s) whose identities will be merged with the default OLS session label for a user using this algorithm. Here we are simply using one factor, Connection_Type, and will use the PL/SQL procedure DBMS_MACADM. ADD_POLICY_FACTOR to accomplish this. dbvowner@aos> BEGIN dbms_macadm.add_policy_factor( policy_name => 'CUSTOMER_POLICY' , factor_name => 'Connection_Type' ); END; / PL/SQL procedure successfully completed. Note that the DBV integration with OLS does in fact support the merging of multiple factors with OLS. The final step in our configuration is to associate an OLS label from the policy to each DBV identity for the DBV factor Connection_Type. This can be accomplished using the PL/SQL procedure DBMS_MACADM.CREATE_POLICY_LABEL: dbvowner@aos> we will assign the LOCAL_DBA identity dbvowner@aos> an OLS label of HIGH dbvowner@aos> BEGIN dbms_macadm.CREATE_POLICY_LABEL( identity_factor_name => 'Connection_Type' , identity_factor_value => 'LOCAL_DBA' , policy_name => 'CUSTOMER_POLICY' , label => 'HIGH' ); END; / PL/SQL procedure successfully completed. Chapter 5: Database Vault Fundamentals 181 dbvowner@aos> we will assign the CORPORATE_SSL identity dbvowner@aos> an OLS label of HIGH dbvowner@aos> BEGIN dbms_macadm.CREATE_POLICY_LABEL( identity_factor_name => 'Connection_Type' , identity_factor_value => 'CORPORATE_SSL' , policy_name => 'CUSTOMER_POLICY' , label => 'HIGH' ); END; / PL/SQL procedure successfully completed. dbvowner@aos> we will assign the CORPORATE_PASSWORD identity dbvowner@aos> an OLS label of HIGH dbvowner@aos> BEGIN dbms_macadm.CREATE_POLICY_LABEL( identity_factor_name => 'Connection_Type' , identity_factor_value => 'CORPORATE_PASSWORD' , policy_name => 'CUSTOMER_POLICY' , label => 'HIGH' ); END; / PL/SQL procedure successfully completed. dbvowner@aos> we will assign the OTHER identity dbvowner@aos> an OLS label of LOW dbvowner@aos> BEGIN dbms_macadm.CREATE_POLICY_LABEL( identity_factor_name => 'Connection_Type' , identity_factor_value => 'OTHER' , policy_name => 'CUSTOMER_POLICY' , label => 'LOW' ); END; / PL/SQL procedure successfully completed. dbvowner@aos> COMMIT; Commit complete. We now want to examine how our policy behaves using the scenario in which MARY is querying the SH.CUSTOMERS table from within the corporate network. In this scenario, we expect MARY to be able to see all customers no matter what their credit limit. In addition, we expect the effective OLS session label to be the maximum label MARY is authorized to see—HIGH. mary@aos> show the Connection_Type factor and session context mary@aos>SELECT DVSYS.GET_FACTOR('Connection_Type') Connection_Type , DVSYS.GET_FACTOR('Authentication_Method') Authentication_Method , DVSYS.GET_FACTOR('Client_IP') Client_IP FROM DUAL; 182 Part II: Oracle Database Vault CONNECTION_TYPE AUTHENTICATION_METHO CLIENT_IP CORPORATE_PASSWORD PASSWORD 192.168.0.200 1 row selected. mary@aos> query MARY's OLS authorization and mary@aos> the effective OLS session label mary@aos> SELECT sa_session.label('CUSTOMER_POLICY') "EFFECTIVE_SESSION_LABEL" FROM DUAL; EFFECTIVE_SESSION_LABEL HIGH 1 row selected. mary@aos> query the SH.CUSTOMERS table mary@aos> SELECT cust_credit_limit , count(*) FROM sh.customers GROUP BY cust_credit_limit ORDER BY cust_credit_limit / CUST_CREDIT_LIMIT COUNT(*) 1500 11334 3000 7975 5000 7724 7000 8634 9000 9093 10000 5935 11000 2935 15000 1870 8 rows selected. Next we want to examine how our policy behaves when MARY is querying the SH.CUSTOMERS table from outside the corporate network. In this scenario, we expect MARY to be able to see only customers with a credit limit of LOW. In addition, we expect the effective OLS session label to be the maximum label MARY is authorized to see—LOW. mary@aos> show the Connection_Type factor and session context mary@aos>SELECT DVSYS.GET_FACTOR('Connection_Type') Connection_Type , DVSYS.GET_FACTOR('Authentication_Method') Authentication_Method , DVSYS.GET_FACTOR('Client_IP') Client_IP FROM DUAL; CONNECTION_TYPE AUTHENTICATION_METHO CLIENT_IP OTHER PASSWORD 10.10.10.10 Chapter 5: Database Vault Fundamentals 183 1 row selected. mary@aos> query MARY's OLS authorization and mary@aos> the effective OLS session label mary@aos> SELECT sa_session.label('CUSTOMER_POLICY') "EFFECTIVE_SESSION_LABEL" FROM DUAL; EFFECTIVE_SESSION_LABEL LOW 1 row selected. mary@aos> query the SH.CUSTOMERS table mary@aos> SELECT cust_credit_limit , count(*) FROM sh.customers GROUP BY cust_credit_limit ORDER BY cust_credit_limit / CUST_CREDIT_LIMIT COUNT(*) 1500 11334 3000 7975 2 rows selected. As you can see, even though MARY is in fact authorized to see data records labeled as HIGH and MODERATE, when she connects to the database from outside the corporate network, the integration of this OLS policy with DBV factors prevents this access. This integration allows us to mediate row-level access controls policies such as OLS with environmental factors such as the network path a client used to connect to the database, the method of authentication, or both. This integration capability truly is multifactored security. When we started our discussion on the DBV and OLS integration, we made the assertion that the effective OLS session label established by this integration could not be “upgraded” by the user. We can demonstrate this by attempting to set the session label to the maximum label the user is authorized to see using the OLS PL/SQL procedure SA_SESSION.SET_LABEL within the context of the session MARY established outside of the corporate network: mary@aos> show the Connection_Type factor and session context mary@aos>SELECT DVSYS.GET_FACTOR('Connection_Type') Connection_Type , DVSYS.GET_FACTOR('Authentication_Method') Authentication_Method , DVSYS.GET_FACTOR('Client_IP') Client_IP FROM DUAL; CONNECTION_TYPE AUTHENTICATION_METHO CLIENT_IP OTHER PASSWORD 10.10.10.10 1 row selected. . new label column, and then populate the data records with the appropriate label number. Note that Oracle supports the condition in which multiple VPD and OLS policies exist and interoperate. algorithm is the most appropriate and most commonly used algorithm in commercial and government systems. This algorithm and others are available with OLS and are described in the “Label Security. prevent these CREATE TRIGGER statements from completing 178 Part II: Oracle Database Vault successfully. The best approach to handling this is to authorize the LBACSYS account in the Sales History