314 Part II: Oracle Database Vault ORGANIZATION EXTERNAL (TYPE ORACLE_LOADER DEFAULT DIRECTORY dbv_dir_log ACCESS PARAMETERS ( RECORDS DELIMITED BY NEWLINE BADFILE 'dbv_auth.bad' DISCARDFILE 'dbv_auth.dis' LOGFILE 'dbv_auth.log' FIELDS TERMINATED BY "," OPTIONALLY ENCLOSED BY '"' ( username CHAR(30) , event CHAR(30) , owner CHAR(30) , object CHAR(130) , status INTEGER EXTERNAL(6) ) ) LOCATION (DBV_DIR:'external_authorize.conf') ) REJECT LIMIT UNLIMITED / Table created. The decision concept around the OET is that we can model the Subject-Verb-Object portion of a security profile directly in the OET using the USERNAME/EVENT/OWNER and OBJECT columns and use the STATUS column as an indicator of TRUE(1) or FALSE(0) to allow the command. The conditional aspect of our profile is satisfied by the file owner (root, in this example) controlling when the commands are authorized on any given object. The table is empty at this point, but if we populate the underlying comma-separated-values (CSV) file as the root OS account we will see the data in the table. [root@node1 ~] #echo "MARY,DELETE,SH,%,1" > /etc/dbv/external_authorize.conf In this example we model the concept that the USERNAME MARY is allowed (STATUS=1) to execute a DELETE (EVENT) on any (OBJECT) whose OWNER is SH. If we attempt to update this file with the Oracle OS account, the OS file’s permissions prevent the attempt: [oracle@node1 ~]$ echo "ANTHONY,DELETE,SH,%,1" > /etc/dbv/external_authorize.conf -bash: /etc/dbv/external_authorize.conf: Permission denied This is a simple example that makes use of the root and Oracle OS accounts. Note that technologies such as fine-grained OS access control lists, based on IEEE’s POSIX 1003 standards, would offer a solution that uses a non-root account as the file owner, but for brevity we simply used the root account. With this file populated, we can now query the external table as the DBVEXT object-owner account and create a PL/SQL package that can be used in DBV rule sets: dvf@aos> query the populated OET dvf@aos>SELECT * FROM dbvext.external_authorize; Chapter 7: Applied Database Vault for Existing Applications 315 USERNAME EVENT OWNER OBJECT STATUS MARY DELETE SH % 1 1 row selected dvf@aos> create a helper package for DBV Rule Sets that dvf@aos> can query the OET dvf@aos> CREATE OR REPLACE PACKAGE external_rule AS FUNCTION authorized( user_name IN VARCHAR2 , event_name IN VARCHAR2 , owner_name IN VARCHAR2 DEFAULT '%' , object_name IN VARCHAR2 DEFAULT '%' ) RETURN NUMBER; END; / Package created. dvf@aos>CREATE OR REPLACE PACKAGE BODY external_rule AS FUNCTION authorized( user_name IN VARCHAR2 , event_name IN VARCHAR2 , owner_name IN VARCHAR2 , object_name IN VARCHAR2 ) RETURN NUMBER IS BEGIN FOR c_rules IN ( SELECT username FROM external_authorize WHERE UPPER(event) = UPPER(event_name) AND UPPER(owner) = UPPER(owner_name) AND UPPER(object) = UPPER(object_name) AND status = 1 ) LOOP IF UPPER(c_rules.username) = UPPER(user_name) THEN RETURN 1; END IF; note that we could event use the package procedure DBVEXT.DBMS_MAC_EXTENSION.USER_HAS_ROLE here to base the authorization on role names store in CSV file END LOOP; RETURN 0; EXCEPTION WHEN OTHERS THEN RAISE_APPLICATION_ERROR(-20001, 'external_rule (error):' || SUBSTR(SQLERRM, 1 , 2000) ); RETURN 0; END; 316 Part II: Oracle Database Vault END; / Package body created. dvf@aos> grant EXECUTE privilege on the package to DVSYS as always dvf@aos>GRANT EXECUTE ON dbvext.external_rule TO dvsys; Grant succeeded. Finally, we create the DBV rule set and an example DBV command rule that uses our OET-based package function. dvf@aos>CONNECT diego_dbvmgr Enter password: Connected. diego_dbvmgr@aos> create the DBV Rule for DELETE on an SH objects diego_dbvmgr@aos>BEGIN dbms_macadm.create_rule( rule_name => 'Externally Controlled DELETE for Sales History' ,rule_expr => 'DBVEXT.EXTERNAL_RULE.AUTHORIZED(DVSYS.DV_LOGIN_USER,' || '''DELETE'',''SH'',''%'') = 1' ); END; / PL/SQL procedure successfully completed. diego_dbvmgr@aos> create the DBV Rule Set and diego_dbvmgr@aos> associate our DBV Rule to it diego_dbvmgr@aos>BEGIN dbms_macadm.create_rule_set( rule_set_name =>'Sales History DELETE Controls', description =>'Authorizes deletes against the Sales History tables.', enabled =>dbms_macutl.g_yes, eval_options =>dbms_macutl.g_ruleset_eval_all, audit_options =>dbms_macutl.g_ruleset_audit_fail, fail_options =>dbms_macutl.g_ruleset_fail_show, fail_message =>NULL, fail_code =>NULL, handler_options =>dbms_macutl.g_ruleset_handler_off, handler =>NULL); END; / PL/SQL procedure successfully completed. diego_dbvmgr@aos>BEGIN dbms_macadm.add_rule_to_rule_set ( rule_set_name => 'Sales History DELETE Controls' , rule_name => 'Externally Controlled DELETE for Sales History' ); END; / PL/SQL procedure successfully completed. diego_dbvmgr@aos> create the DBV Command Rule that ties into our OET authorizations Chapter 7: Applied Database Vault for Existing Applications 317 diego_dbvmgr@aos>BEGIN dbms_macadm.create_command_rule ( command => 'DELETE' ,rule_set_name => 'Sales History DELETE Controls' ,object_owner => 'SH' ,object_name => '%' ,enabled => 'Y' ); END; / PL/SQL procedure successfully completed. We can test the control using the realm administrator account MARY to verify that the DELETE command is allowed. We can also verify that the DELETE command is not allowed for an EUS- based realm administrator such as JOE, who was authorized to do this based on the earlier realm authorization example. diego_dbvmgr@aos>CONNECT mary Enter password: Connected. mary@aos>DELETE SH.COSTS WHERE ROWNUM < 2; 1 row deleted. If we change the status mary@aos>CONNECT joe Enter password: Connected. global_oid_tree1@aos>DELETE SH.COSTS WHERE ROWNUM < 2; DELETE SH.COSTS WHERE ROWNUM < 2 * ERROR at line 1: ORA-01031: insufficient privileges We can also disable the ability for MARY to perform the sensitive transaction using the root OS account as follows: [root@node1 ~]# echo "MARY,DELETE,SH,%,0" > /etc/dbv/external_authorize.conf When MARY attempts the same DELETE statement at this point, her attempt is not authorized based on the updated contents of the file: global_oid_tree1@aos>CONNECT mary Enter password: Connected. mary@aos>DELETE SH.COSTS WHERE ROWNUM < 2; DELETE SH.COSTS WHERE ROWNUM < 2 * ERROR at line 1: ORA-01031: insufficient privileges This example demonstrates how you can create an externally controlled decision point using DBV command rules for sensitive transactions using basic OS and Oracle features. This type of external control is also useful when coupled with the DBV CONNECT command rule to restrict 318 Part II: Oracle Database Vault the ability for privileged accounts to log into the database. Privileged accounts such as LBACSYS or object-owner accounts such as SH that house sensitive data can be restricted from login in the foreground. Make sure you account for any database jobs the account may have by adding a check to the PL/SQL package function DBVEXT.EXTERNAL_RULE.AUTHORIZED for the value returned from the function SYS_CONTEXT('USERENV', 'BG_JOB_ID') being NOT NULL to authorize these job sessions. Identifying DBV Factors Based on Business or System Conditions The DBV rules we develop based on business rules or system conditions can leverage DBV factors as we had demonstrated in Chapter 6. Some types of factors you will develop can be based on the results of the queries we ran previously on the audit and database configuration. You can attempt to have some questions answered by application experts to help uncover these factors. Factors Based on Compliance Compliance-related factors are often simple constants that drive system behavior (either in code or in DBV rules) as demonstrated with the audit retention period example in Chapter 6. In addition to time-based constants that have units such as Number of Days, you may seek input from application experts on event-driven controls that can be controlled with a DBV factor. For example, the concept of a “quiet period” may be useful in application controls and depicts a compliance-sensitive stage or event in the context of the business itself, versus the particular application. Factors Based on Conflict of Interest or Separation of Duty As you examine the initial Subject-Verb-Object-Condition results created from the preceding sensitive transactions query, you should be asking application experts if a single role or group of accounts is allowed to perform each type of transaction. In our example for creating product costs through the SH.SALES_TRANSACTIONS package, we defined a rule “Is Sales Department Manager” that is a perfect example of a separation of duty control. Once you’ve identified the roles or accounts for each transaction, you can create factors to support these rules that enforce separation of duty on the transactions. In the examples of Chapter 6, we created factors such as User_Department_Name and Is_Department_Manager to serve this purpose. Factors Based on Organizational Policy To understand which organizational policy affects the security in a database application, you need to interview application experts. The types of questions that you need to ask will be related to data ownership, reporting requirements, and timing of key business events. In the example presented in Chapter 6, we looked at the product category to determine the manager who could control sales costs or read detailed product data. Similar data ownership rules may exist within your organization. The controls that enforce these ownership rules can take many forms, such as VPD policy, OLS policy, WHERE conditions in views, PL/SQL application code, and in application code that is external to the database, such as code found in Java or ASP programs. Chapter 7: Applied Database Vault for Existing Applications 319 Factors Based on Time Factors that are based on time are useful in situations where you want to control the timeframe (WHEN) in which a sensitive transaction can take place. We can examine both the database audit trail’s timestamp and schedule for database batch processing (jobs) to derive time-based factors. The following query demonstrates how the audit trail can be examined for time-based factors that could be developed for a sensitive transaction. sys@aos>SELECT db_user subject, action_name verb, object_schema || '.'|| object_name object, TO_CHAR ( extended_timestamp, 'DAY HH24:MI') "DAY_TIME", COUNT(*) FROM aos_common_audit_trail WHERE action_name = 'DELETE' AND object_schema = 'SH' AND object_type NOT LIKE '%PARTITION%' GROUP BY db_user , action_name , object_schema || '.'|| object_name, TO_CHAR ( extended_timestamp, 'DAY HH24:MI') ORDER BY db_user , action_name , object_schema || '.'|| object_name ; SUBJECT VERB OBJECT DAY_TIME COUNT(*) ALAN_ANALYST DELETE SH.COSTS TUESDAY 10:50 1 DEB_DATA_MGR DELETE SH.COSTS TUESDAY 14:39 1 MARY DELETE SH.COSTS SATURDAY 15:36 1 MARY DELETE SH.SALES SATURDAY 15:33 1 OPS$APPSERVER_1 DELETE SH.SALES WEDNESDAY 14:07 1 5 rows selected. The DELETE transactions that occurred on TUESDAY and WEDNESDAY may be out of the normal or expected time frame for this type of transaction. This may point to a need to create a factor and rule for the specific time window in which a DELETE is authorized. This type of control is similar to the one we demonstrated with the SYSTEM.AUD$ table in Chapter 6. We can also identify additional areas for time-based factors by looking at the intervals in which database jobs are executing. The PL/SQL programs that are executing are typically associated with the business events that an application supports, such as the close of a month’s financial process. The following query will help you identify the time frame the job intervals in which these types of PL/SQL programs are run: sys@aos>SET SERVEROUTPUT ON sys@aos>BEGIN FOR c_jobs IN ( SELECT cowner owner , 'Job #:' || TO_CHAR(job) job_name , interval# repeat_interval , what program 320 Part II: Oracle Database Vault FROM job$ UNION SELECT j.owner , job_name , decode(j.repeat_interval, NULL, decode(s.repeat_interval, NULL, w.window_group_name, s.repeat_interval) ,j.repeat_interval) "repeat_interval" , decode(j.program_name,NULL ,j.job_action,p.owner || '.' || p.program_action) "program" FROM dba_scheduler_jobs j , dba_scheduler_programs p , dba_scheduler_schedules s , dba_scheduler_window_groups w WHERE j.program_owner = p.owner (+) AND j.program_name = p.program_name (+) AND j.schedule_owner = s.owner (+) AND j.schedule_name = s.schedule_name (+) AND j.schedule_owner = s.owner (+) AND j.schedule_name = w.window_group_name (+) ORDER BY 1 ) LOOP DBMS_OUTPUT.PUT_LINE(' '); DBMS_OUTPUT.PUT_LINE('Job: ' || c_jobs.owner || '.' || c_jobs.job_name ); DBMS_OUTPUT.PUT_LINE('Interval: ' || c_jobs.repeat_interval ); DBMS_OUTPUT.PUT_LINE('Program: ' || c_jobs.program ); END LOOP; END; / Job: EXFSYS.RLM$EVTCLEANUP Interval: FREQ = HOURLY; INTERVAL = 1 Program: begin dbms_rlmgr_dr.cleanup_events; end; Job: EXFSYS.RLM$SCHDNEGACTION Program: FREQ=MINUTELY;INTERVAL=60 What: begin dbms_rlmgr_dr.execschdactions('RLM$SCHDNEGACTION'); end; Job: FLOWS_030000.Job #:4001 Interval: sysdate + 8/24 Program: wwv_flow_cache.purge_sessions(p_purge_sess_older_then_hrs => 24); Job: FLOWS_030000.Job #:4002 Interval: sysdate + 10/1440 Program: wwv_flow_mail.push_queue(wwv_flow_platform.get_preference('SMTP_HOST_ ADDRESS'),wwv_flow_platform.get_preference('SMTP_HOST_PORT')); Chapter 7: Applied Database Vault for Existing Applications 321 Job: ORACLE_OCM.MGMT_CONFIG_JOB Interval: MAINTENANCE_WINDOW_GROUP Program: ORACLE_OCM.MGMT_CONFIG.collect_config <output truncated for brevity> Factors Based on Identity Management You can verify whether a database is using Oracle EUS for authentication by issuing the following query: sys@aos>SHOW PARAMETER ldap NAME TYPE VALUE ldap_directory_access string PASSWORD ldap_directory_sysauth string no In this example output, the database is configured to use EUS. If the LDAP_DIRECTORY_ACCESS parameter were set to SSL, the database would also be configured to use EUS. If the LDAP_ DIRECTORY_ACCESS parameter were set to NONE, the database is not configured to use EUS. The more difficult question to answer is how a database application is using identity management attributes available in the SYS_LDAP_USER_DEFAULT context namespace that EUS maintains. The difficulty is because SYS_CONTEXT usage is not tracked in the DBA_ DEPENDENCIES view and there is no tracking of the namespace usage in an Oracle dictionary view. You can make an educated guess that the application makes use of the techniques outline in Oracle Metalink note 242156.1 “An Example of Using Application Context’s Initialized Globally” by querying the DBA_CONTEXT view, as shown next: sys@aos>SELECT namespace FROM dba_context WHERE TYPE = 'INITIALIZED GLOBALLY'; NAMESPACE DBV_POLICY_EXAMPLE 1 row selected. If any namespaces are returned and EUS is configured, there is a good chance that identity management information from EUS is being used within the databases. Finally, you can attempt to examine PL/SQL source code for usage of the default or custom namespaces to determine where identity management information for EUS is being used. The following query shows how to examine this PL/SQL source code but will work only on source code that has not been wrapped: sys@aos>SELECT DISTINCT owner, name, type FROM all_source WHERE INSTR (UPPER(text),'SYS_LDAP_USER_DEFAULT') > 0 322 Part II: Oracle Database Vault OR INSTR (UPPER(text),'<custom namespace from above>') > 0 ; OWNER NAME TYPE SYS TESTEUS PROCEDURE 1 row selected. Factors Based on Access Path to the Database We can determine the network access path used for a given type of transaction by including the USERHOST column in a query against the captured audit trail. The following query shows the access path taken for DELETE transactions on the tables owned by the SH object-owner account. The results of this type of query can help you determine to which database client IP address you’d want to restrict certain sensitive transactions. Convert the hostnames to the appropriate IP address values and use a DBV factor such as Client_IP in your DBV rules. sys@aos>SELECT db_user subject, action_name verb, object_schema || '.'|| object_name object, userhost, COUNT(*) FROM aos_common_audit_trail WHERE object_schema = 'SH' AND action_name = 'DELETE' AND object_type NOT LIKE '%PARTITION%' GROUP BY db_user , action_name , object_schema || '.'|| object_name, userhost ORDER BY db_user , action_name , object_schema || '.'|| object_name, userhost ; SUBJECT VERB OBJECT USERHOST COUNT(*) ALAN_ANALYST DELETE SH.COSTS node1.mycompany.com 1 DEB_DATA_MGR DELETE SH.COSTS node1.mycompany.com 1 MARY DELETE SH.COSTS node1.mycompany.com 1 MARY DELETE SH.SALES node1.mycompany.com 1 OPS$APPSERVER_1 DELETE SH.SALES appserver1.mycompany.com 1 5 rows selected. Many database environments use the invited nodes feature of Oracle networking to control which IP addresses can connect to the database. If this feature is enabled for your database listener, you will see the following entries in the file $ORACLE_HOME/network/admin/sqlnet.ora: TCP.VALIDNODE_CHECKING=YES TCP.INVITED_NODES=(192.168.0.251, 192.168.0.252, 192.168.0.200) This list can supplement the queries performed on the captured audit trail as it is a definitive list of the IP addresses for database clients that can actually connect to the database remotely. With this list in hand, you can discuss the requirements for each IP address from the perspective of the database applications that are used and which transactions should be allowed. Chapter 7: Applied Database Vault for Existing Applications 323 Factors Based on Operational Context The sensitive transactions query results also include several records for EXECUTE transactions on the SH.SALES_TRANSACTION PL/SQL package. We expected this result based on the examples we’ve created in the past two chapters. As you examine the query results for your own applications, you should ask the application experts whether the PL/SQL programs are the only interfaces (paths) for other more fundament commands such as INSERT, UPDATE, and DELETE. If you find that certain PL/SQL programs fit this classification, you can create command rules for the INSERT, UPDATE, and DELETE commands that enforce the use of the PL/SQL program similar to the examples we created that depend on the DBMS_UTILITY package being part of the PL/SQL call stack. Factors Based on Transactional Sequence Another form of operational context that you can mine from your audit trail is related to the sequence of statements that are issued to the database as part of a transaction. If we consider the notional use case presented in Chapter 6 named Add Monthly Product Cost, portions of the audit trail records may look similar to the following: sys@aos>SELECT transactionid ,action_name ,object_schema ,object_name FROM aos_common_audit_trail WHERE object_schema = 'SH' AND action_name IN ( 'SELECT' ,'INSERT' ,'UPDATE' ,'DELETE' ) AND object_type = 'TABLE' AND extended_timestamp > sysdate - 1 ORDER BY extended_timestamp, transactionid; TRANSACTIONID ACTION_NAME OBJECT_SCHEMA OBJECT_NAME SELECT SH PRODUCTS SELECT SH CHANNELS SELECT SH PROMOTIONS 040015004E960000 INSERT SH COSTS 040015004E960000 UPDATE SH MONTHLY_COST_SUMMARY SELECT SH PRODUCTS SELECT SH CHANNELS SELECT SH PROMOTIONS 0A0014001F950000 INSERT SH COSTS 0A0014001F950000 UPDATE SH MONTHLY_COST_SUMMARY SELECT SH PRODUCTS SELECT SH CHANNELS SELECT SH PROMOTIONS 03000800FE940000 INSERT SH COSTS 03000800FE940000 UPDATE SH MONTHLY_COST_SUMMARY 15 rows selected. . DBV Command Rule that ties into our OET authorizations Chapter 7: Applied Database Vault for Existing Applications 317 diego_dbvmgr@aos>BEGIN dbms_macadm.create_command_rule ( command =>. j.program_owner = p.owner (+) AND j.program_name = p.program_name (+) AND j.schedule_owner = s.owner (+) AND j.schedule_name = s.schedule_name (+) AND j.schedule_owner = s.owner (+) AND j.schedule_name. fundament commands such as INSERT, UPDATE, and DELETE. If you find that certain PL/SQL programs fit this classification, you can create command rules for the INSERT, UPDATE, and DELETE commands that