Rem Rem $Header: emcore/source/oracle/sysman/emdrep/sql/core/latest/sdk/sdk_user_pkgbody.sql /st_emcore_10.2.0.4.2db11.2/4 2009/04/21 08:04:36 nmathuri Exp $ Rem Rem sdk_user_pkgbody.sql Rem Rem Copyright (c) 2002, 2009, Oracle and/or its affiliates. Rem All rights reserved. Rem Rem NAME Rem sdk_user_pkgbody.sql - Rem Rem DESCRIPTION Rem The package that implements the User Model for Project Mozart Rem Rem NOTES Rem Rem MODIFIED (MM/DD/YY) Rem nmathuri 01/12/09 - Fix the bug#7695506 Rem nmathuri 05/27/07 - Backport of nmathuri_bug-6073322 from manin Rem nmathuri 04/23/07 - Backport nmathuri_bug-5972549 from main Rem rpatti 09/06/06 - XbranchMerge rpatti_bug-5503142 from main Rem nmathuri 08/07/06 - Backport nmathuri_bug-4725364 from main Rem nmathuri 07/14/06 - Bug fix for bug No: 4578684 Rem nmathuri 07/26/06 - Backport nmathuri_bug-4578684 from main Rem nmathuri 06/29/06 - Fix for bug 5307664 Rem nmathuri 07/26/06 - Backport nmathuri_bug-5307664 from main Rem dcawley 11/25/05 - Backport dcawley_bug-4674928 from main Rem dcawley 10/14/05 - Catch duplicate value when building visible Rem lists Rem dcawley 11/24/05 - Bug 4644415 Rem dcawley 11/04/05 - Remove distinct when building visible lists Rem dcawley 11/02/05 - XbranchMerge dcawley_bug-4644415_beta from Rem st_emgc_10.2gcbeta Rem dcawley 10/11/05 - Avoid duplicate subqueries Rem dcawley 10/02/05 - Set user to repository owner when getting target Rem types Rem dcawley 10/02/05 - Remove no guid check Rem dcawley 10/02/05 - Split query for building visible list Rem dcawley 09/27/05 - Include parent in propagate Rem dcawley 09/26/05 - INclude parent role Rem dcawley 09/24/05 - Rollback changes to flat roles Rem dcawley 09/24/05 - Remove or Rem dcawley 09/24/05 - Include cluster members Rem dcawley 09/21/05 - Rewrite query for getting target types Rem dcawley 09/01/05 - Fix flat role grants Rem dcawley 08/30/05 - Remove job grants Rem dcawley 08/15/05 - Use old collection type for strings Rem dcawley 08/08/05 - Remove collections to improve performance Rem dcawley 08/04/05 - fix bug 4533600 Rem dcawley 07/28/05 - Remove template check Rem dcawley 07/27/05 - Include template cas Rem bram 07/08/05 - Increase Role Desc to show 60 char Rem pratagar 06/27/05 - Type Display Name Rem dcawley 06/22/05 - Include privs for getting target types Rem dcawley 06/17/05 - Remove hints Rem dcawley 06/02/05 - Set predicate when predicate type is invalid Rem dcawley 06/01/05 - Add join condition for redundancy group Rem dcawley 05/30/05 - Do not propagate privileges for generic Rem redundancy groups Rem aholser 05/18/05 - provide for rac Rem dcawley 04/14/05 - Change booleans to number Rem dcawley 04/07/05 - Change error message Rem dcawley 04/07/05 - Catch misleading exception Rem dcawley 04/06/05 - Use quotes Rem dcawley 04/06/05 - Fix security problems Rem bram 04/06/05 - Fix for 4270327 -Administrator-Users Display Rem dcawley 03/30/05 - Fix granting of ca privs Rem bram 03/27/05 - Fix for UserModel Search Rem dcawley 03/09/05 - Move check Rem dcawley 03/09/05 - Change predicates Rem dcawley 03/08/05 - Check for invalid users Rem dcawley 03/03/05 - Store user in application context Rem dcawley 03/02/05 - Only check privs when propagating Rem shianand 03/01/05 - Rem dcawley 02/24/05 - Initialize repository owner on package load Rem dcawley 02/23/05 - Change get repository owner Rem dcawley 02/21/05 - Replace enter super user mode Rem dcawley 02/17/05 - Only super users can revoke from PUBLIC role Rem vkgarg 02/17/05 - Bug #4149757 - getting Duplicate target types Rem shianand 02/12/05 - Rem shianand 01/18/05 - Audit Functionality Added Rem shianand 01/17/05 - Rem ramalhot 02/02/05 - changed signature for handle_target_deleted Rem nkhatri 02/04/05 - Changed the approach of updating access data. Rem nkhatri 02/01/05 - Make changes in access procedures. Rem dcawley 01/27/05 - Include maintain target in callbacks Rem jaysmith 01/21/05 - make sure CA owner can see CA before looking up Rem dcawley 01/13/05 - Add priv granted callback Rem other users Rem nkhatri 01/10/05 - Add access page procedures. Rem dcawley 01/06/05 - Add target deletion callback Rem vkgarg 12/28/04 - get timezone region in get_targets_by_priv Rem method Rem dcawley 12/23/04 - Only super users can grant to the public role Rem dcawley 12/16/04 - Add opertions for invalidating contexts Rem dcawley 12/07/04 - Fix clusters and corrective action privs Rem jabramso 12/06/04 - revoke all report priv Rem jaysmith 11/24/04 - add ca update call Rem yaofeng 11/19/04 - default notification schedule Rem dcawley 11/08/04 - Do not allow SYS or SYSTEM be deleted Rem asawant 10/08/04 - Cutting over MGMT_USER_TYPE_METRIC_PREFS to Rem MGMT_USER_SUBTAB_COL_PREFS Rem dcawley 10/07/04 - Remove manage any user Rem jabramso 10/07/04 - check for VIEW_ANY_REPORT Rem jabramso 09/28/04 - Use report errors Rem asawant 09/27/04 - Cutting over API to fetch user subtab prefs. Rem jabramso 09/24/04 - Add some more report priv routines Rem kmanicka 09/18/04 - adding support for target owner Rem kmanicka 08/30/04 - add reassign user api, and related callbacks Rem dcawley 09/20/04 - Fix report predicate Rem dcawley 09/20/04 - Fix query for getting corrective actions Rem dcawley 09/15/04 - target group modified is no longer used Rem dcawley 09/14/04 - Use beacon associations Rem dcawley 09/08/04 - Add flat role grants Rem dcawley 09/03/04 - Fix get all target privs Rem dcawley 08/31/04 - Add callbacks for new objects Rem dcawley 08/30/04 - Leave group modification procedure Rem dcawley 08/23/04 - use associations Rem dcawley 08/19/04 - Lock context table when updating Rem dcawley 07/29/04 - Corrective Actions Rem dcawley 07/23/04 - New system privs Rem dcawley 07/07/04 - Increase user name size Rem gan 07/02/04 - create predicate, diamur's change Rem dsahrawa 06/22/04 - use MGMT_JOBS.get_job_schedule_record Rem aholser 06/10/04 - invalid users Rem aholser 05/27/04 - make SID and host match case-insensitive Rem kranjan 04/26/04 - Fix for Bug 3574400 Rem dcawley 03/24/04 - Add callback for nested jobs Rem jsadras 03/17/04 - Added locking functionality for drop/modify user Rem and blackout checking Rem aholser 03/04/04 - use gv$ instead of v$ Rem aholser 02/27/04 - add 'is_super' to get_users Rem aholser 12/19/03 - Rem aholser 08/04/03 - add guid to privs cursor Rem dcawley 08/08/03 - Allow user to revoke priv from themself Rem dcawley 01/26/04 - Do not pass user when granting full job Rem dcawley 01/22/04 - Improve granting of full_job Rem dcawley 01/21/04 - Check users exists before allowing grants Rem dcawley 01/20/04 - Fix job messages Rem dcawley 01/19/04 - Fix checks for invalid targets/jobs Rem dcawley 01/07/04 - Fix create user Rem dcawley 01/07/04 - Fix problem with modify_role Rem dcawley 01/07/04 - Fix problem with beacon privs Rem rpinnama 12/29/03 - Fix 3340948: Grant related targets for Rem jpyang 12/11/03 - delete from mgmt_licenses when delete user Rem aholser 11/24/03 - disregard composite guids of deleted targets Rem dcawley 11/18/03 - Use flat groups table Rem dcawley 11/18/03 - Rename predicate functions Rem dcawley 11/12/03 - Fix deadlock Rem dcawley 11/12/03 - Do not propogte target group privs Rem dcawley 10/29/03 - Change addition and propogation for websites Rem aholser 09/27/03 - fix regression Rem aholser 09/18/03 - call revoke_priv from modify_job_grants Rem dcawley 09/17/03 - Add procedure for granting full job to owner of Rem a job Rem aholser 09/12/03 - add 'deleting' to get_users cursor Rem dcawley 09/03/03 - Change insert when creating job list Rem dcawley 09/01/03 - Add job vpd Rem dcawley 08/27/03 - Add flag to allow revokes when deleting Rem aholser 08/25/03 - Rem dcawley 08/08/03 - Allow user to revoke priv from themself Rem skini 07/29/03 - Fix priv issue Rem kdas 07/31/03 - support for DB Console mode Rem dcawley 07/24/03 - Add array version of HAS_PRIV Rem dcawley 07/21/03 - Changes for removal of triggers Rem aholser 07/22/03 - more job stuff Rem aholser 07/07/03 - add job procs Rem dcawley 06/23/03 - Notification changes Rem dcawley 05/19/03 - Check for FULL_JOB explicitly Rem dcawley 05/15/03 - Use host_name Rem dcawley 04/25/03 - Make global context values visible to any session Rem aholser 04/18/03 - Rem aholser 04/02/03 - fix drop_user Rem yaofeng 04/09/03 - fix query for email addresses Rem dcawley 03/12/03 - Fix grant_new_privs Rem dcawley 03/10/03 - Use MGMT_PARAMETERS Rem dcawley 03/06/03 - Remove references to dbms_rls Rem dcawley 03/04/03 - Give VIEW_TARGET on associated targets of group members Rem dcawley 02/20/03 - User define privs give view on target Rem dcawley 02/17/03 - Fix GET_ALL_TARGET_PRIVS Rem dcawley 02/17/03 - Fix IS_SUPER_USER check in GET_USERS Rem yaofeng 02/16/03 - remove creating schedule Rem dcawley 02/10/03 - Fix call to emd_notification Rem dcawley 01/31/03 - Add IS_SUPER_USER Rem aholser 01/30/03 - fix 'numeric value error' when no emrep targets found Rem aholser 01/28/03 - make get_repository_targets more flexible Rem aholser 01/17/03 - fix get_repository_targets Rem dcawley 01/14/03 - Rename is_sso_user flag Rem dcawley 01/13/03 - Create notification schedule in create_user Rem xshi 01/10/03 - add user type - enterprise user Rem dcawley 01/07/03 - Change check for job Rem skini 01/03/03 - Do not allow SYS and SYSTEM to login Rem skini 01/03/03 - Add an additional OUT parameter to GET_MGMT_PRIVS Rem dcawley 12/20/02 - Get composite members of a certain type Rem dcawley 12/19/02 - Fix GET_TARGETS and GET_TARGET_TYPES Rem dcawley 12/13/02 - Remove grants for a target when it is deleted Rem dcawley 11/12/02 - Add Job privileges Rem skini 01/03/03 - Do not allow SYS and SYSTEM to login Rem skini 01/03/03 - Add an additional OUT parameter to GET_MGMT_PRIVS Rem aholser 11/11/02 - fix errors modifying users (tvmlu060 and tvmlu074) Rem dcawley 11/06/02 - Call user created callbacks earlier Rem dcawley 10/31/02 - Fix role callbacks Rem dcawley 10/31/02 - Fix bug 2643236 Rem jsoule 10/30/02 - add metric user prefs alias function Rem dcawley 10/23/02 - Add protected version of GET_MAX_PRIV Rem dcawley 10/17/02 - Add get_max_priv Rem dcawley 10/07/02 - Add role callbacks Rem dcawley 09/27/02 - Move drop user statement Rem rpatti 09/16/02 - remove hack Rem dcawley 09/13/02 - So not modify password for SSO users Rem dcawley 09/11/02 - Add old APIs to create/modify users Rem dcawley 09/09/02 - Remove old version of CREATE_USER Rem dcawley 09/02/02 - Allow multiple emails be specified Rem rpatti 09/11/02 - support custom folders Rem dcawley 08/26/02 - Change query for getting repository database Rem aholser 08/26/02 - Bug 2449299 Rem dcawley 08/19/02 - More changes for EM_MONITOR Rem rpatti 08/14/02 - add api to get target types based on privileges Rem dcawley 08/09/02 - Update security predicate based on EM_MONITOR Rem dcawley 08/07/02 - Add GET_ALL_TARGET_PRIVS Rem dcawley 08/06/02 - Add EM_MONITOR Rem tjaiswal 08/05/02 - Add get targets api Rem dcawley 07/17/02 - Fix exception in MDIFY_USER Rem tjaiswal 07/16/02 - Add get targets by priv for type api Rem dcawley 07/09/02 - Add callbacks Rem jpyang 07/10/02 - use broken_id > 0 for broken targets Rem dcawley 07/08/02 - Fix for bug 2449344 Rem aholser 07/08/02 - fix email update Rem dcawley 07/03/02 - Add priv on beacon when priv granted on website Rem jpyang 07/02/02 - revert to user KB Rem jpyang 06/20/02 - add agent status Rem jpyang 06/21/02 - fix last_upload_timestamp Rem jpyang 06/24/02 - use MB for mem usage Rem jpyang 06/18/02 - metric name changed Rem jpyang 06/17/02 - fix GET_NODE_WITH_PRIV Rem jpyang 06/11/02 - more selects in GET_NODE_WITH_PRIV Rem dcawley 06/12/02 - Priv on target gives priv on host that the target is on. Rem aholser 06/08/02 - Fix ora0651 assigning users Rem dcawley 06/04/02 - Split query in GET_TARGETS_BY_PRIV. Rem dcawley 05/31/02 - API to get target list with a certain privilege. Rem dcawley 05/20/02 - Changes for email device. Rem aholser 05/20/02 - merge performance Rem rpinnama 05/15/02 - rpinnama_reorg_rep_scripts Rem rpinnama 05/15/02 - Restructured. Rem aholser 04/29/02 - Allow usernames with '.'. Rem rpinnama 04/19/02 - Drop from created users on error. Rem skini 04/18/02 - Fix bug 2330911 Rem mbhoopat 04/18/02 - Fix bug 2330078.. Rem dcawley 04/16/02 - Remove COMMITs from SETEMUSERCONTEXT. Rem rpinnama 04/16/02 - Add the user to MGMT_CREATED_USERS in CREATE_USER. Rem dcawley 04/12/02 - Make sure context is recreated after GRANT_PRIV. Rem aholser 04/12/02 - fix description edit. Rem skini 04/11/02 - Change documentation for node_list API Rem skini 04/10/02 - Change API to return only targets with permission Rem dcawley 04/08/02 - Make setemusercontext run in an autonomous transaction. Rem dcawley 04/05/02 - Remove check for DBMS JOB when logging off. Rem dcawley 04/04/02 - Fix recursive statements. Rem skini 04/01/02 - Continue implementation of API Rem jpyang 03/14/02 - Fix enter_super_user_mode Rem skini 03/28/02 - Add target list APIs Rem skini 03/08/02 - Fix merge problem Rem dcawley 03/05/02 - Do not clean up context for DBMS JOB. Rem dcawley 03/01/02 - Use dba_procedures. Rem dcawley 02/27/02 - Add operation to clean up all contexts. Rem rpatti 02/25/02 - call createfolders in mgmt_user Rem dcawley 02/22/02 - Add check for NULL. Rem dcawley 02/21/02 - Select predicate from global context. Rem dcawley 02/21/02 - Fix logoff trigger. Rem dcawley 02/20/02 - Store current user in private context. Rem dcawley 02/19/02 - Remove priv_name from setemusercontext. Rem skini 03/01/02 - Implement make_em_user Rem dcawley 02/11/02 - Add modify_role. Rem aholser 02/12/02 - fix get_role_users. Rem skini 02/07/02 - Include composite targets in group check Rem skini 02/07/02 - Implement add_member_target Rem skini 02/05/02 - Add methods to enter and leave super-user mode Rem ancheng 02/01/02 - check folders in modify_user Rem dcawley 02/01/02 - Standardize on NULL meaning no change in MODIFY_USER. Rem dcawley 02/01/02 - Add checks for 0 count. Rem dcawley 02/01/02 - Remove direct call to SET_TARGET_LIST. Rem dcawley 01/31/02 - Add callbacks to notify of privilege modification. Rem dcawley 01/29/02 - Change get_role_users to return available and selected. Rem dcawley 01/28/02 - Fix get_role_users. Rem dcawley 01/23/02 - Change VIEW_ALL_TARGETS_GROUP to VIEW_ANY_TARGET. Rem dcawley 01/21/02 - Only drop privs and roles if new ones have been passed into modify_user. Rem aholser 01/19/02 - dont return rep owner on get_role_users. Rem dcawley 01/18/02 - Remove typo. Rem dcawley 01/16/02 - Add new implementation of HAS_PRIV. Rem dcawley 01/16/02 - Remove MGMT_ROLE_PRIVS. Rem dcawley 01/16/02 - Remove debug statement. Rem dcawley 01/12/02 - Changes for making groups always propagating. Rem ancheng 01/22/02 - add/delete folders Rem skini 01/08/02 - Move setEMUserContext Rem dcawley 01/04/02 - Use cursors instead of arrays for return values Rem dcawley 01/03/02 - Fixes for the UI. Rem dcawley 12/19/01 - Add groups. Rem dcawley 01/03/02 - Fixes for the UI. Rem dcawley 12/19/01 - Add groups. Rem dcawley 12/17/01 - Allow use of target name and target type. Rem dcawley 12/12/01 - Add check for VIEW_ALL_TARGETS in set_target_list. Rem dcawley 12/07/01 - Allow the super user drop any privilege. Rem dcawley 12/04/01 - Add APIs for UI. Rem dcawley 11/28/01 - Do not allow SUPER_USER to be deleted. Rem dcawley 11/27/01 - Merged dcawley_add_user_model Rem dcawley 11/27/01 - Created Rem CREATE OR REPLACE PACKAGE BODY MGMT_USER IS IS_SUPER_USER boolean := FALSE; CURRENT_SUPER_USER VARCHAR2(256) := NULL; EM_USER_CONTEXT varchar2(30) := 'em_user_context'; EM_USER_CONTEXT_USER varchar2(30) := 'username'; EM_USER_CONTEXT_TARGET varchar2(6) := 'target'; EM_USER_CONTEXT_JOB varchar2(3) := 'job'; EM_USER_CONTEXT_TEMPLATE varchar2(8) := 'template'; EM_USER_CONTEXT_REPORT_DEF varchar2(10) := 'report_def'; EM_USER_CONTEXT_ST_REPORT varchar2(13) := 'stored_report'; EM_USER_CONTEXT_CA varchar2(2) := 'ca'; -- The owner of the repository schema G_REPOSITORY_OWNER VARCHAR2(30) := NULL; -- Backwards compatability flag for group privilege propagation G_PROPAGATE_PRIVS NUMBER := -1; -- Flag to avoid check when granting privs/roles G_CREATING_USER BOOLEAN := FALSE; -- Flag to avoid infinite recursion when generating VPD predicate G_RECURSIVE_TARGET_VPD BOOLEAN := FALSE; G_RECURSIVE_JOB_VPD BOOLEAN := FALSE; G_RECURSIVE_CA_VPD BOOLEAN := FALSE; -- Flag to indicate whether the target policy is enabled G_TARGET_POLICY_IS_ENABLED VARCHAR2(256) := NULL; G_TARGET_PRIV_PREDICATE constant VARCHAR2(256) := '(target_guid IN (SELECT target_guid FROM MGMT_USER_TARGETS WHERE grantee = SYS_CONTEXT(''em_user_context'', ''username'')))'; G_TARGET_EM_MON_PREDICATE constant VARCHAR2(256) := '(target_type = ''oracle_emd'' OR target_guid IN (SELECT target_guid FROM MGMT_USER_TARGETS WHERE grantee = SYS_CONTEXT(''em_user_context'', ''username'')))'; G_JOB_PRIV_PREDICATE constant VARCHAR2(256) := '(IS_CORRECTIVE_ACTION = 1 OR job_id IN (SELECT job_id FROM MGMT_USER_JOBS WHERE grantee = SYS_CONTEXT(''em_user_context'', ''username'')))'; G_TEMPLATE_PRIV_PREDICATE constant VARCHAR2(256) := '(IS_PUBLIC = 1 OR template_guid IN (SELECT template_guid FROM MGMT_USER_TEMPLATES WHERE grantee = SYS_CONTEXT(''em_user_context'', ''username'')))'; G_REPORT_DEF_PRIV_PREDICATE constant VARCHAR2(256) := '(SYSTEM_REPORT = 1 OR report_guid IN (SELECT report_guid FROM MGMT_USER_REPORT_DEFS WHERE grantee = SYS_CONTEXT(''em_user_context'', ''username'')))'; G_ST_REPORT_PRIV_PREDICATE constant VARCHAR2(256) := '(report_guid IN (SELECT report_guid FROM MGMT_USER_REPORT_DEFS WHERE grantee = SYS_CONTEXT(''em_user_context'', ''username'')))'; G_CA_PRIV_PREDICATE constant VARCHAR2(256) := '(CA_SCOPE = 3 OR job_id IN (SELECT job_id FROM MGMT_USER_CAS WHERE grantee = SYS_CONTEXT(''em_user_context'', ''username'')))'; TYPE PRIV_GRANTEES IS TABLE OF VARCHAR2(256); -- These are here until they are added to jobs package CA_SCOPE_TARGET constant NUMBER(1) := MGMT_CA.CA_SCOPE_TARGET; CA_SCOPE_TEMPLATE constant NUMBER(1) := MGMT_CA.CA_SCOPE_TEMPLATE; CA_SCOPE_TARGET_TYPE constant NUMBER(1) := MGMT_CA.CA_SCOPE_TARGET_TYPE; CA_SCOPE_USER constant NUMBER(1) := MGMT_CA.CA_SCOPE_USER; CA_SCOPE_TEMPLATE_COPY constant NUMBER(1) := MGMT_CA.CA_SCOPE_TEMPLATE_COPY; -- --PURPOSE -- --Get a Exclusive lock on the user , currently a private procedure --called by modify user and drop user procedures only. --Opcode = MODIFY If called by MODIFY_USER procedure -- DROP if called by DROP_USER -- user_type: the user_type is passed out to avoid another select -- call in modify_user and drop_user procedures PROCEDURE get_exclusive_lock(user_name_in IN VARCHAR2, opcode_in IN VARCHAR2, user_type_out OUT NUMBER) IS l_exception_id NUMBER ; l_deleting NUMBER(1) ; user_locked_exception EXCEPTION ; l_lock_handle VARCHAR2(256) ; l_status number ; PRAGMA EXCEPTION_INIT(user_locked_exception,-54) ; BEGIN IF opcode_in = 'DROP' THEN l_exception_id := MGMT_GLOBAL.DROP_FAILED_ERR ; -- Wait for up to 5 minutes for user activity to stop and lock l_lock_handle := mgmt_lock_util.get_exclusive_lock(mgmt_lock_util.DROP_USER_LOCK, user_name_in, 300, l_exception_id, user_name_in||' has active sessions') ; ELSE l_exception_id := MGMT_GLOBAL.MODIFY_FAILED_ERR ; END IF ; -- cannot drop a non-existent user -- or a user being modified/deleted in another session BEGIN SELECT system_user,deleting INTO user_type_out, l_deleting FROM MGMT_CREATED_USERS WHERE user_name = user_name_in AND ROWNUM < 2 FOR UPDATE NOWAIT ; IF l_deleting = 1 THEN IF opcode_in ='DROP' THEN l_status := mgmt_lock_util.release_lock(l_lock_handle) ; END IF ; raise_application_error(l_exception_id, user_name_in||' is currently being dropped' ) ; END IF ; EXCEPTION WHEN NO_DATA_FOUND THEN IF opcode_in ='DROP' THEN l_status := mgmt_lock_util.release_lock(l_lock_handle) ; END IF ; raise_application_error(MGMT_GLOBAL.USER_DOES_NOT_EXIST_ERR, MGMT_GLOBAL.USER_DOES_NOT_EXIST_ERR_M || user_name_in); WHEN user_locked_exception THEN IF opcode_in ='DROP' THEN l_status := mgmt_lock_util.release_lock(l_lock_handle) ; END IF ; raise_application_error(l_exception_id, user_name_in||' is currently being modified') ; END; END get_exclusive_lock; -- -- PURPOSE -- -- Get a share/read lock in the user so that the user cannot be deleted -- When the user is doing some activity to prevent inconsistency -- if the user is marked for deletion then error out -- calling application's responsibility to pass exception_id -- between -20999 and -20000 -- FUNCTION get_read_lock(exception_id_in IN NUMBER ) RETURN VARCHAR2 IS l_deleting number ; l_exception_id number ; l_lock_handle VARCHAR2(256) ; l_status number ; l_user_name VARCHAR2(64) := mgmt_user.get_current_em_user(); BEGIN IF exception_id_in not between -20999 and -20000 THEN raise_application_error(MGMT_GLOBAL.INVALID_PARAMS_ERR, 'Invalid parameter:exception_id_in') ; END IF ; l_lock_handle := mgmt_lock_util.get_share_lock(mgmt_lock_util.DROP_USER_LOCK, l_user_name, 60, exception_id_in, l_user_name||' is currently being dropped') ; SELECT deleting INTO l_deleting FROM mgmt_created_users WHERE user_name=l_user_name ; IF l_deleting=1 THEN l_status := mgmt_lock_util.release_lock(l_lock_handle) ; raise_application_error(exception_id_in, l_user_name||' is currently being dropped') ; END IF ; RETURN(l_lock_handle) ; EXCEPTION WHEN NO_DATA_FOUND THEN l_status := mgmt_lock_util.release_lock(l_lock_handle) ; raise_application_error(MGMT_GLOBAL.USER_DOES_NOT_EXIST_ERR, MGMT_GLOBAL.USER_DOES_NOT_EXIST_ERR_M || l_user_name); END get_read_lock; -- -- PURPOSE -- -- Release the read lock -- FUNCTION release_read_lock(lock_handle_in IN VARCHAR2) RETURN number is BEGIN return(mgmt_lock_util.release_lock(lock_handle_in)) ; END ; -- -- PURPOSE -- Function to see if privilege propagation should be preserved for -- backwards compatability FUNCTION PROPAGATE_PRIVS(p_priv_name IN VARCHAR2) RETURN BOOLEAN IS BEGIN IF G_PROPAGATE_PRIVS = 1 AND p_priv_name <> CREATE_TARGET_IN_GROUP THEN RETURN TRUE; END IF; RETURN FALSE; END PROPAGATE_PRIVS; -- -- PURPOSE -- -- To check if a user has a privilege -- -- PARAMETERS -- -- USER_NAME_IN - the name of the user -- PRIV_NAME_IN - the name of the privilege -- GUID_IN - target guid in the case of a target privilege -- target group guid in the case of target group privilege -- job guid in the case of job privilege -- NULL in the case of system privilege -- -- NOTES -- -- RETURNS : USER_HAS_PRIV if the user has the privilege -- USER_DOES_NOT_HAVE_PRIV if the user does not have the privilege -- -- The caller must also have access to the target -- FUNCTION HAS_PRIV(user_name_in IN VARCHAR2, priv_name_in IN VARCHAR2, guid_in IN RAW DEFAULT NO_GUID) RETURN NUMBER IS uname VARCHAR2(256); pname VARCHAR2(30); cname VARCHAR2(30); oname VARCHAR2(256); ttype VARCHAR2(64); ptype NUMBER; dba_role VARCHAR2(30); groups MGMT_USER_GUID_ARRAY := MGMT_USER_GUID_ARRAY(); l_clusters MGMT_USER_GUID_ARRAY := MGMT_USER_GUID_ARRAY(); cnt NUMBER := 0; cuser VARCHAR2(256); l_iprivs SMP_EMD_STRING_ARRAY; l_ca_scope NUMBER := 0; l_ca_owner VARCHAR2(256); l_ca_target_guid RAW(16); l_ca_template_guid RAW(16); BEGIN uname := UPPER(user_name_in); pname := UPPER(priv_name_in); --------------------------- -- Check for VIEW privilege --------------------------- IF pname IN (VIEW_TARGET, VIEW_JOB, VIEW_TEMPLATE, VIEW_REPORT, VIEW_CA) THEN BEGIN cuser := GET_CURRENT_EM_USER; IF cuser <> uname THEN SETEMUSERCONTEXT(uname, OP_SET_IDENTIFIER); END IF; IF pname = VIEW_TARGET THEN SELECT count(target_guid) INTO cnt FROM MGMT_TARGETS WHERE target_guid = guid_in; ELSIF pname = VIEW_JOB THEN SELECT count(job_id) INTO cnt FROM MGMT_JOB WHERE job_id = guid_in; ELSIF pname = VIEW_TEMPLATE THEN SELECT count(template_guid) INTO cnt FROM MGMT_TEMPLATES WHERE template_guid = guid_in; ELSIF pname = VIEW_REPORT THEN SELECT count(report_guid) INTO cnt FROM MGMT_IP_REPORT_DEF WHERE report_guid = guid_in; ELSIF pname = VIEW_CA THEN SELECT count(job_id) INTO cnt FROM MGMT_CORRECTIVE_ACTION WHERE job_id = guid_in; END IF; IF cuser <> uname THEN SETEMUSERCONTEXT(cuser, OP_SET_IDENTIFIER); END IF; IF cnt = 0 THEN RETURN USER_DOES_NOT_HAVE_PRIV; ELSE RETURN USER_HAS_PRIV; END IF; EXCEPTION WHEN OTHERS THEN IF cuser <> uname THEN SETEMUSERCONTEXT(cuser, OP_SET_IDENTIFIER); END IF; RETURN USER_DOES_NOT_HAVE_PRIV; END; END IF; --------------------------------- -- Check for SUPER_USER privilege --------------------------------- -- Super Users are not automatically granted FULL_JOB on every job so -- we must explicitly check for FULL_JOB grants IF pname <> FULL_JOB THEN IF IS_SUPER_USER AND uname = CURRENT_SUPER_USER THEN RETURN USER_HAS_PRIV; END IF; -- check for reposiotry owner, as repository owner will have -- All privileges IF uname = GET_REPOSITORY_OWNER THEN IF uname = GET_CURRENT_EM_USER THEN IS_SUPER_USER := TRUE; CURRENT_SUPER_USER := uname; END IF; RETURN USER_HAS_PRIV; END IF; -- The SUPER_USER privilege can only be granted directly so no -- need to look up the roles the user may have. SUPER_USER has -- all privileges, so if granted, no need to check any further BEGIN SELECT priv_name INTO cname FROM MGMT_PRIV_GRANTS WHERE (grantee = uname AND priv_name = SUPER_USER) AND ROWNUM < 2; IF uname = GET_CURRENT_EM_USER THEN IS_SUPER_USER := TRUE; CURRENT_SUPER_USER := uname; END IF; RETURN USER_HAS_PRIV; EXCEPTION WHEN NO_DATA_FOUND THEN -- Move onto the next check NULL; END; -- If the user has DBA privileges then return true BEGIN -- This is the original way of checking for DBA, but Werner came -- up with a faster way --SELECT granted_role INTO dba_role FROM DBA_ROLE_PRIVS --WHERE granted_role = 'DBA' AND grantee = uname; -- More performant way. Note that neither approach checks for nested -- DBA grants -- select 1 into dba_role -- from sys.sysauth$ sa, sys.user$ u1, sys.user$ u2, sys.defrole$ ud -- where sa.grantee#=ud.user#(+) -- and sa.privilege#=ud.role#(+) -- and u1.user#=sa.grantee# -- and u2.user#=sa.privilege# -- and u1.name = uname -- and u2.name = 'DBA'; -- Access to sys.user$ table is no more available, -- so going back to orginal query SELECT granted_role INTO dba_role FROM DBA_ROLE_PRIVS WHERE granted_role = 'DBA' AND grantee = uname; IF uname = GET_CURRENT_EM_USER THEN IS_SUPER_USER := TRUE; CURRENT_SUPER_USER := uname; END IF; RETURN USER_HAS_PRIV; EXCEPTION WHEN NO_DATA_FOUND THEN -- If this check was for the current user then reset the super user flag IF uname = GET_CURRENT_EM_USER THEN IS_SUPER_USER := FALSE; CURRENT_SUPER_USER := NULL; END IF; -- If this was a check to see if the user is a SUPER_USER -- then return otherwise continue IF pname = SUPER_USER THEN RETURN USER_DOES_NOT_HAVE_PRIV; END IF; END; END IF; --------------------------------- -- Check for all other privileges --------------------------------- -- Get the privilege type SELECT priv_type INTO ptype FROM MGMT_PRIVS WHERE priv_name = pname; BEGIN -- Check for target or target_group privileges IF ptype IN (TARGET_PRIVILEGE, TARGET_GROUP_PRIVILEGE) THEN -- User with FULL_ANY_TARGET privilege will have full target -- privileges on all the targets IF HAS_PRIV ( uname, FULL_ANY_TARGET) = USER_HAS_PRIV THEN RETURN USER_HAS_PRIV; END IF; -- Get the target type SELECT target_type INTO ttype FROM MGMT_TARGETS WHERE target_guid = guid_in; -- Privilege propagation occurs if the backwards compatability flag is -- set and this is not a target group privilege or a website target IF (PROPAGATE_PRIVS(pname) AND ttype <> MGMT_GLOBAL.G_WEBSITE_TARGET_TYPE) THEN -- Get the list of groups that this target belongs to SELECT source_target_guid BULK COLLECT INTO groups FROM mgmt_flat_target_assoc WHERE assoc_target_guid = guid_in AND is_membership = 1; END IF; -- Include the target itself groups.extend; groups(groups.COUNT) := guid_in; -- Check if this target is a member of any clusters. Note that there -- is no propagation for generic redundancy groups BEGIN SELECT a.source_target_guid BULK COLLECT INTO l_clusters FROM mgmt_flat_target_assoc a, mgmt_targets t, mgmt_type_properties p WHERE a.assoc_target_guid = guid_in AND a.is_membership = 1 AND t.target_guid = a.source_target_guid AND t.target_type <> MGMT_GLOBAL.G_REDUNDANCY_GROUP_TARGET_TYPE AND p.target_type = t.target_type AND p.property_name = MGMT_GLOBAL.G_IS_CLUSTER_PROP AND p.property_value = '1'; IF l_clusters IS NOT NULL AND l_clusters.COUNT > 0 THEN FOR c IN l_clusters.FIRST..l_clusters.LAST LOOP groups.extend; groups(groups.COUNT) := l_clusters(c); END LOOP; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN NULL; END; -- Get the privs that include this privilege SELECT priv_name BULK COLLECT INTO l_iprivs FROM mgmt_priv_includes where ipriv_name = pname; l_iprivs.extend; l_iprivs(l_iprivs.COUNT) := pname; SELECT priv_name INTO cname FROM MGMT_PRIV_GRANTS WHERE (grantee = uname OR grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) OR grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) AND priv_name IN (SELECT /*+cardinality(pr 5) */ * FROM TABLE(CAST(l_iprivs AS SMP_EMD_STRING_ARRAY))) AND guid IN (SELECT * FROM TABLE(CAST(groups AS MGMT_USER_GUID_ARRAY))) AND ROWNUM < 2; ELSIF ptype = JOB_PRIVILEGE THEN SELECT job_owner INTO oname FROM mgmt_job WHERE job_id = guid_in; -- if this is not the owner, check for specific grant IF oname <> uname THEN SELECT priv_name INTO cname FROM MGMT_PRIV_GRANTS WHERE (grantee = uname OR grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) OR grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) AND ( priv_name = pname ) AND ( guid = guid_in) AND ROWNUM < 2; END IF; ELSIF ptype = TEMPLATE_PRIVILEGE THEN SELECT priv_name INTO cname FROM MGMT_PRIV_GRANTS WHERE (grantee = uname OR grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) OR grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) AND ( priv_name = pname ) AND ( guid = guid_in) AND ROWNUM < 2; ELSIF ptype = CA_PRIVILEGE THEN SELECT ca_scope, ca_target_guid, ca_template_guid INTO l_ca_scope, l_ca_target_guid, l_ca_template_guid FROM MGMT_CORRECTIVE_ACTION WHERE job_id = guid_in; IF l_ca_scope = CA_SCOPE_TARGET THEN -- Check for OPERATOR which will also check for FULL RETURN HAS_PRIV(uname, OPERATOR_TARGET, l_ca_target_guid); ELSIF l_ca_scope = CA_SCOPE_TEMPLATE THEN -- Check for FULL RETURN HAS_PRIV(uname, FULL_TEMPLATE, l_ca_template_guid); ELSIF l_ca_scope = CA_SCOPE_TARGET_TYPE THEN -- Only super users can have full privileges on a library ca RETURN USER_DOES_NOT_HAVE_PRIV; ELSIF l_ca_scope = CA_SCOPE_USER THEN SELECT job_owner INTO l_ca_owner FROM MGMT_JOB WHERE job_id = guid_in; IF l_ca_owner = uname THEN RETURN USER_HAS_PRIV; ELSE RETURN USER_DOES_NOT_HAVE_PRIV; END IF; END IF; ELSIF ptype = SYSTEM_PRIVILEGE THEN IF pname = EM_MONITOR THEN SELECT priv_name INTO cname FROM MGMT_PRIV_GRANTS WHERE (grantee = uname OR grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) OR grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) AND priv_name IN (VIEW_ANY_TARGET, EM_MONITOR) AND ROWNUM < 2; ELSE SELECT priv_name INTO cname FROM MGMT_PRIV_GRANTS WHERE (grantee = uname OR grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) OR grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) AND priv_name = pname AND ROWNUM < 2; END IF; END IF; cnt := 1; EXCEPTION WHEN NO_DATA_FOUND THEN cnt := 0; END; IF cnt > 0 THEN RETURN USER_HAS_PRIV; END IF; RETURN USER_DOES_NOT_HAVE_PRIV; END HAS_PRIV; -- -- PURPOSE -- Convenience function to resolve target name type into the target GUID -- FUNCTION HAS_PRIV(user_name_in IN VARCHAR2, priv_name_in IN VARCHAR2, target_name_in IN VARCHAR2, target_type_in IN VARCHAR2) RETURN NUMBER IS tguid RAW(16); pname VARCHAR2(30); l_priv_type NUMBER := -1; BEGIN pname := UPPER(priv_name_in); BEGIN SELECT priv_type INTO l_priv_type FROM MGMT_PRIVS WHERE priv_name = pname; EXCEPTION WHEN NO_DATA_FOUND THEN l_priv_type := -1; END; IF l_priv_type NOT IN (TARGET_PRIVILEGE, TARGET_GROUP_PRIVILEGE) THEN raise_application_error(MGMT_GLOBAL.INVALID_PRIVILEGE_ERR, MGMT_GLOBAL.INVALID_PRIVILEGE_ERR_M || priv_name_in|| ' for has_priv by target_name, target_type'); END IF; BEGIN SELECT target_guid INTO tguid FROM MGMT_TARGETS WHERE target_name = target_name_in AND target_type = target_type_in; EXCEPTION WHEN OTHERS THEN raise_application_error(MGMT_GLOBAL.TARGET_DOES_NOT_EXIST_ERR, MGMT_GLOBAL.TARGET_DOES_NOT_EXIST_ERR_M || target_name_in || ' (' || target_type_in || ')'); END; RETURN HAS_PRIV(user_name_in, priv_name_in, tguid); END HAS_PRIV; -- -- PURPOSE -- -- Takes an array of guids and returns an array of the guids -- that the user has the privilege on. -- -- NOTES -- -- RETURNS an array of the guids for which the user has the privilege. Note -- that the privilege must be something other than VIEW_TARGET -- FUNCTION HAS_PRIV(user_name_in IN VARCHAR2, priv_name_in IN VARCHAR2, target_guids_in IN MGMT_USER_GUID_ARRAY) RETURN GUID_CURSOR IS uname VARCHAR2(256); pname VARCHAR2(30); l_groups MGMT_USER_GUID_ARRAY; roles SMP_EMD_STRING_ARRAY; l_clusters MGMT_USER_GUID_ARRAY; guids_out GUID_CURSOR; l_priv_type NUMBER := -1; l_iprivs SMP_EMD_STRING_ARRAY; BEGIN uname := UPPER(user_name_in); pname := UPPER(priv_name_in); BEGIN SELECT priv_type INTO l_priv_type FROM MGMT_PRIVS WHERE priv_name = pname; EXCEPTION WHEN NO_DATA_FOUND THEN l_priv_type := -1; END; IF ( l_priv_type NOT IN (TARGET_PRIVILEGE, TARGET_GROUP_PRIVILEGE) AND pname <> FULL_ANY_TARGET ) OR pname = VIEW_TARGET THEN raise_application_error(MGMT_GLOBAL.INVALID_PRIVILEGE_ERR, MGMT_GLOBAL.INVALID_PRIVILEGE_ERR_M || priv_name_in); END IF; -- The super user has the privilege on all targets IF HAS_PRIV(uname, SUPER_USER) = USER_HAS_PRIV OR HAS_PRIV(uname, FULL_ANY_TARGET) = USER_HAS_PRIV THEN OPEN guids_out FOR SELECT column_value FROM TABLE(CAST(target_guids_in AS MGMT_USER_GUID_ARRAY)); return guids_out; END IF; -- Get the privs that include this privilege SELECT priv_name BULK COLLECT INTO l_iprivs FROM mgmt_priv_includes where ipriv_name = pname; l_iprivs.extend; l_iprivs(l_iprivs.COUNT) := pname; SELECT role_name BULK COLLECT INTO roles FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname) UNION SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname; -- Get the groups to which the targets belong that have the privilege IF PROPAGATE_PRIVS(pname) THEN SELECT DISTINCT guid BULK COLLECT INTO l_groups FROM MGMT_PRIV_GRANTS WHERE (grantee = uname OR grantee IN (SELECT * FROM TABLE(CAST(roles AS SMP_EMD_STRING_ARRAY)))) AND priv_name IN (SELECT /*+cardinality(pr 5) */ * FROM TABLE(CAST(l_iprivs AS SMP_EMD_STRING_ARRAY))) AND guid IN (SELECT source_target_guid FROM MGMT_FLAT_TARGET_ASSOC a, MGMT_TARGETS t WHERE a.is_membership = 1 AND a.assoc_target_guid IN (SELECT * FROM TABLE(CAST(target_guids_in AS MGMT_USER_GUID_ARRAY))) AND t.target_guid = a.source_target_guid AND t.target_type <> MGMT_GLOBAL.G_WEBSITE_TARGET_TYPE); END IF; -- Get the clusters to which the targets belong that have the privilege SELECT DISTINCT guid BULK COLLECT INTO l_clusters FROM MGMT_PRIV_GRANTS WHERE (grantee = uname OR grantee IN (SELECT * FROM TABLE(CAST(roles AS SMP_EMD_STRING_ARRAY)))) AND priv_name IN (SELECT /*+cardinality(pr 5) */ * FROM TABLE(CAST(l_iprivs AS SMP_EMD_STRING_ARRAY))) AND guid IN (SELECT a.source_target_guid FROM mgmt_flat_target_assoc a, mgmt_targets t, mgmt_type_properties p WHERE a.is_membership = 1 AND a.assoc_target_guid IN (SELECT * FROM TABLE(CAST(target_guids_in AS MGMT_USER_GUID_ARRAY))) AND t.target_guid = a.source_target_guid AND t.target_type <> MGMT_GLOBAL.G_REDUNDANCY_GROUP_TARGET_TYPE AND p.target_type = t.target_type AND p.property_name = MGMT_GLOBAL.G_IS_CLUSTER_PROP AND p.property_value = '1'); -- Get the list of guids the user has the privilege on directly or via -- a role and also as part of a group OPEN guids_out FOR SELECT DISTINCT guid FROM MGMT_PRIV_GRANTS WHERE (grantee = uname OR grantee IN (SELECT * FROM TABLE(CAST(roles AS SMP_EMD_STRING_ARRAY)))) AND priv_name IN (SELECT /*+cardinality(pr 5) */ * FROM TABLE(CAST(l_iprivs AS SMP_EMD_STRING_ARRAY))) AND (guid IN (SELECT * FROM TABLE(CAST(target_guids_in AS MGMT_USER_GUID_ARRAY)))) UNION SELECT column_value FROM TABLE(CAST(target_guids_in AS MGMT_USER_GUID_ARRAY)) WHERE column_value IN (SELECT assoc_target_guid FROM MGMT_FLAT_TARGET_ASSOC WHERE (source_target_guid IN (SELECT * FROM TABLE(CAST(l_groups AS MGMT_USER_GUID_ARRAY))) OR source_target_guid IN (SELECT * FROM TABLE(CAST(l_clusters AS MGMT_USER_GUID_ARRAY))))); RETURN guids_out; END HAS_PRIV; -- -- PURPOSE -- -- Takes an array of guids and returns true if the user has the privilege -- all the targets. -- -- NOTES -- -- RETURNS an array of the guids for which the user has the privilege. Note -- that the privilege must be something other than VIEW_TARGET -- FUNCTION HAS_PRIV_ON_ALL(user_name_in IN VARCHAR2, priv_name_in IN VARCHAR2, target_guids_in IN MGMT_USER_GUID_ARRAY) RETURN NUMBER IS uname VARCHAR2(256); pname VARCHAR2(30); l_groups MGMT_USER_GUID_ARRAY; roles SMP_EMD_STRING_ARRAY; l_clusters MGMT_USER_GUID_ARRAY; l_priv_type NUMBER := -1; l_iprivs SMP_EMD_STRING_ARRAY; l_cnt NUMBER := 0; l_cnt1 NUMBER := 0; BEGIN uname := UPPER(user_name_in); pname := UPPER(priv_name_in); BEGIN SELECT priv_type INTO l_priv_type FROM MGMT_PRIVS WHERE priv_name = pname; EXCEPTION WHEN NO_DATA_FOUND THEN l_priv_type := -1; END; IF ( l_priv_type NOT IN (TARGET_PRIVILEGE, TARGET_GROUP_PRIVILEGE) AND pname <> FULL_ANY_TARGET ) OR pname = VIEW_TARGET THEN raise_application_error(MGMT_GLOBAL.INVALID_PRIVILEGE_ERR, MGMT_GLOBAL.INVALID_PRIVILEGE_ERR_M || priv_name_in); END IF; -- The super user has the privilege on all targets IF HAS_PRIV(uname, SUPER_USER) = USER_HAS_PRIV OR HAS_PRIV(uname, FULL_ANY_TARGET) = USER_HAS_PRIV THEN return USER_HAS_PRIV; END IF; -- Get the privs that include this privilege SELECT priv_name BULK COLLECT INTO l_iprivs FROM mgmt_priv_includes where ipriv_name = pname; l_iprivs.extend; l_iprivs(l_iprivs.COUNT) := pname; SELECT role_name BULK COLLECT INTO roles FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname) UNION SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname; -- Get the groups to which the targets belong that have the privilege IF PROPAGATE_PRIVS(pname) THEN SELECT DISTINCT guid BULK COLLECT INTO l_groups FROM MGMT_PRIV_GRANTS WHERE (grantee = uname OR grantee IN (SELECT * FROM TABLE(CAST(roles AS SMP_EMD_STRING_ARRAY)))) AND priv_name IN (SELECT /*+cardinality(pr 5) */ * FROM TABLE(CAST(l_iprivs AS SMP_EMD_STRING_ARRAY))) AND guid IN (SELECT source_target_guid FROM MGMT_FLAT_TARGET_ASSOC a, MGMT_TARGETS t WHERE a.is_membership = 1 AND a.assoc_target_guid IN (SELECT * FROM TABLE(CAST(target_guids_in AS MGMT_USER_GUID_ARRAY))) AND t.target_guid = a.source_target_guid AND t.target_type <> MGMT_GLOBAL.G_WEBSITE_TARGET_TYPE); END IF; -- Get the clusters to which the targets belong that have the privilege SELECT DISTINCT guid BULK COLLECT INTO l_clusters FROM MGMT_PRIV_GRANTS WHERE (grantee = uname OR grantee IN (SELECT * FROM TABLE(CAST(roles AS SMP_EMD_STRING_ARRAY)))) AND priv_name IN (SELECT /*+cardinality(pr 5) */ * FROM TABLE(CAST(l_iprivs AS SMP_EMD_STRING_ARRAY))) AND guid IN (SELECT a.source_target_guid FROM mgmt_flat_target_assoc a, mgmt_targets t, mgmt_type_properties p WHERE a.is_membership = 1 AND a.assoc_target_guid IN (SELECT * FROM TABLE(CAST(target_guids_in AS MGMT_USER_GUID_ARRAY))) AND t.target_guid = a.source_target_guid AND t.target_type <> MGMT_GLOBAL.G_REDUNDANCY_GROUP_TARGET_TYPE AND p.target_type = t.target_type AND p.property_name = MGMT_GLOBAL.G_IS_CLUSTER_PROP AND p.property_value = '1'); -- Get the list of guids the user has the privilege on directly or via -- a role and also as part of a group SELECT COUNT(DISTINCT guid) INTO l_cnt FROM MGMT_PRIV_GRANTS WHERE (grantee = uname OR grantee IN (SELECT * FROM TABLE(CAST(roles AS SMP_EMD_STRING_ARRAY)))) AND priv_name IN (SELECT /*+cardinality(pr 5) */ * FROM TABLE(CAST(l_iprivs AS SMP_EMD_STRING_ARRAY))) AND (guid IN (SELECT * FROM TABLE(CAST(target_guids_in AS MGMT_USER_GUID_ARRAY)))); SELECT COUNT(DISTINCT column_value) INTO l_cnt1 FROM TABLE(CAST(target_guids_in AS MGMT_USER_GUID_ARRAY)) WHERE column_value IN (SELECT assoc_target_guid FROM MGMT_FLAT_TARGET_ASSOC WHERE (source_target_guid IN (SELECT * FROM TABLE(CAST(l_groups AS MGMT_USER_GUID_ARRAY))) OR source_target_guid IN (SELECT * FROM TABLE(CAST(l_clusters AS MGMT_USER_GUID_ARRAY))))); IF (l_cnt + l_cnt1) = target_guids_in.COUNT THEN RETURN USER_HAS_PRIV; ELSE RETURN USER_DOES_NOT_HAVE_PRIV; END IF; END HAS_PRIV_ON_ALL; -- -- -- PURPOSE -- Given a target guid, find all the users that have VIEW_TARGET on it FUNCTION GET_VIEW_TARGET_USERS(p_target_guid IN RAW) RETURN STRING_CURSOR IS l_roles SMP_EMD_STRING_ARRAY := SMP_EMD_STRING_ARRAY(); l_nroles SMP_EMD_STRING_ARRAY := SMP_EMD_STRING_ARRAY(); l_users STRING_CURSOR; BEGIN -- Find the roles with VIEW_ANY_TARGET or VIEW_TARGET on the target SELECT grantee BULK COLLECT INTO l_roles FROM MGMT_PRIV_GRANTS WHERE grantee_is_role = 1 AND (priv_name = VIEW_ANY_TARGET OR guid = p_target_guid); -- Find all roles that have one of the roles above SELECT role_grantee BULK COLLECT INTO l_nroles FROM MGMT_FLAT_ROLE_GRANTS WHERE role_name IN (SELECT * FROM TABLE(CAST(l_roles AS SMP_EMD_STRING_ARRAY))); -- Find all users that have one of the roles OPEN l_users FOR SELECT DISTINCT grantee FROM MGMT_ROLE_GRANTS WHERE grantee_is_role = 0 AND role_name IN (SELECT * FROM TABLE(CAST(l_roles AS SMP_EMD_STRING_ARRAY))) OR role_name IN (SELECT * FROM TABLE(CAST(l_nroles AS SMP_EMD_STRING_ARRAY))) UNION -- and all users that have VIEW_ANY_TARGET or VIEW_TARGET on the target SELECT grantee FROM MGMT_PRIV_GRANTS WHERE grantee_is_role = 0 AND (priv_name = VIEW_ANY_TARGET OR guid = p_target_guid); RETURN l_users; END GET_VIEW_TARGET_USERS; -- -- -- PURPOSE -- Given a template guid, find all the users that have VIEW_TEMPLATE on it FUNCTION GET_VIEW_TEMPLATE_USERS(p_template_guid IN RAW) RETURN STRING_CURSOR IS l_roles SMP_EMD_STRING_ARRAY := SMP_EMD_STRING_ARRAY(); l_nroles SMP_EMD_STRING_ARRAY := SMP_EMD_STRING_ARRAY(); l_users STRING_CURSOR; BEGIN -- Find the roles with VIEW_TEMPLATE on the template SELECT grantee BULK COLLECT INTO l_roles FROM MGMT_PRIV_GRANTS WHERE grantee_is_role = 1 AND guid = p_template_guid; -- Find all roles that have one of the roles above SELECT role_grantee BULK COLLECT INTO l_nroles FROM MGMT_FLAT_ROLE_GRANTS WHERE role_name IN (SELECT * FROM TABLE(CAST(l_roles AS SMP_EMD_STRING_ARRAY))); -- Find all users that have one of the roles OPEN l_users FOR SELECT grantee FROM MGMT_ROLE_GRANTS WHERE grantee_is_role = 0 AND role_name IN (SELECT * FROM TABLE(CAST(l_roles AS SMP_EMD_STRING_ARRAY))) OR role_name IN (SELECT * FROM TABLE(CAST(l_nroles AS SMP_EMD_STRING_ARRAY))) UNION -- and all users that have VIEW_TEMPLATE on the template SELECT grantee FROM MGMT_PRIV_GRANTS WHERE grantee_is_role = 0 AND guid = p_template_guid; RETURN l_users; END GET_VIEW_TEMPLATE_USERS; -- -- -- PURPOSE -- Private function to grant privileges based on values in MGMT_USER_PRIVILEGE -- object PROCEDURE GRANT_PRIV(grantee_in IN VARCHAR2, privilege_in IN MGMT_USER_PRIVILEGE) IS BEGIN IF privilege_in.guid <> NO_GUID THEN GRANT_PRIV(grantee_in, privilege_in.priv_name, privilege_in.guid, 0); ELSIF privilege_in.target_name IS NOT NULL THEN GRANT_PRIV(grantee_in, privilege_in.priv_name, privilege_in.target_name, privilege_in.target_type, 0); ELSE GRANT_PRIV(grantee_in, privilege_in.priv_name, NO_GUID, 0); END IF; END GRANT_PRIV; -- -- PURPOSE -- Function to parase the MGMT_USER_PRIVILEGES object and Grant the privileges with GRANT_PRIV -- object PROCEDURE GRANT_PRIVS(grantee_in IN VARCHAR2, privileges_in IN MGMT_USER_PRIVILEGES) IS BEGIN IF privileges_in IS NOT NULL AND privileges_in.COUNT > 0 THEN FOR i IN privileges_in.FIRST..privileges_in.LAST LOOP GRANT_PRIV(grantee_in, privileges_in(i)); END LOOP; END IF; END GRANT_PRIVS; -- -- PURPOSE -- Private function to revoke privileges based on values in MGMT_USER_PRIVILEGE -- object PROCEDURE REVOKE_PRIV(grantee_in IN VARCHAR2, privilege_in IN MGMT_USER_PRIVILEGE) IS BEGIN IF privilege_in.guid <> NO_GUID THEN REVOKE_PRIV(grantee_in, privilege_in.priv_name, privilege_in.guid, 0); ELSIF privilege_in.target_name IS NOT NULL THEN REVOKE_PRIV(grantee_in, privilege_in.priv_name, privilege_in.target_name, privilege_in.target_type, 0); ELSE REVOKE_PRIV(grantee_in, privilege_in.priv_name, NO_GUID, 0); END IF; END REVOKE_PRIV; -- -- PURPOSE -- Function to parase the MGMT_USER_PRIVILEGES object and revoke the privileges with REVOKE_PRIV -- object PROCEDURE REVOKE_PRIVS(grantee_in IN VARCHAR2, privileges_in IN MGMT_USER_PRIVILEGES) IS privilege_in MGMT_USER_PRIVILEGE; BEGIN IF privileges_in IS NOT NULL AND privileges_in.COUNT > 0 THEN FOR i IN privileges_in.FIRST..privileges_in.LAST LOOP -- REVOKE_PRIV(grantee_in, privileges_in(i)); privilege_in := privileges_in(i); IF privilege_in.guid <> NO_GUID THEN REVOKE_PRIV(grantee_in, privilege_in.priv_name, privilege_in.guid, 1); ELSIF privilege_in.target_name IS NOT NULL THEN REVOKE_PRIV(grantee_in, privilege_in.priv_name, privilege_in.target_name, privilege_in.target_type, 1); ELSE REVOKE_PRIV(grantee_in, privilege_in.priv_name, NO_GUID, 1); END IF; END LOOP; END IF; END REVOKE_PRIVS; -- -- PURPOSE -- Private function to grant only the new privileges in a list PROCEDURE GRANT_NEW_PRIVS(grantee_in IN VARCHAR2, privileges_in IN MGMT_USER_PRIVILEGES) IS current_privs SMP_EMD_STRING_ARRAY; current_guids MGMT_USER_GUID_ARRAY; guids MGMT_USER_GUID_ARRAY := MGMT_USER_GUID_ARRAY(); found BOOLEAN := FALSE; already_granted SMP_EMD_INTEGER_ARRAY := SMP_EMD_INTEGER_ARRAY(); BEGIN -- Get the current list of privileges but do not include privs -- that cannot be granted via the administative UI SELECT pg.priv_name, pg.guid BULK COLLECT INTO current_privs, current_guids FROM MGMT_PRIV_GRANTS pg, MGMT_PRIVS p WHERE pg.grantee = grantee_in AND pg.direct_grant = 1 AND p.priv_name = pg.priv_name AND p.priv_type IN (SYSTEM_PRIVILEGE, TARGET_PRIVILEGE, TARGET_GROUP_PRIVILEGE, JOB_PRIVILEGE); -- If the new list of privileges is empty then revoke all the current -- privileges IF privileges_in IS NULL OR privileges_in.COUNT = 0 THEN IF current_privs IS NOT NULL AND current_privs.COUNT > 0 THEN FOR i IN current_privs.FIRST..current_privs.LAST LOOP BEGIN REVOKE_PRIV(grantee_in, current_privs(i), current_guids(i),0); EXCEPTION WHEN OTHERS THEN NULL; END; END LOOP; END IF; RETURN; END IF; -- Set up array to cache the guids guids.extend(privileges_in.COUNT); FOR j IN privileges_in.FIRST..privileges_in.LAST LOOP -- Make sure the target GUID is available in the new privilege IF privileges_in(j).target_name IS NOT NULL AND (privileges_in(j).guid IS NULL OR privileges_in(j).guid = NO_GUID) THEN -- if this is a job privilege, use the job table rather than target table IF privileges_in(j).priv_type = JOB_PRIVILEGE THEN raise_application_error(MGMT_GLOBAL.INVALID_PRIVILEGE_ERR, MGMT_GLOBAL.INVALID_PRIVILEGE_ERR_M || privileges_in(j).priv_name||' requires a valid job id'); END IF; BEGIN SELECT target_guid INTO guids(j) FROM MGMT_TARGETS WHERE target_name = privileges_in(j).target_name AND target_type = privileges_in(j).target_type; EXCEPTION WHEN NO_DATA_FOUND THEN raise_application_error(MGMT_GLOBAL.INVALID_TARGET_ERR, MGMT_GLOBAL.INVALID_TARGET_ERR_M || privileges_in(j).target_name || ' (' || privileges_in(j).target_type || ')'); END; ELSIF privileges_in(j).guid IS NOT NULL THEN guids(j) := privileges_in(j).guid; ELSE guids(j) := NO_GUID; END IF; END LOOP; IF current_privs IS NOT NULL AND current_privs.COUNT > 0 THEN FOR i IN current_privs.FIRST..current_privs.LAST LOOP found := FALSE; FOR j IN privileges_in.FIRST..privileges_in.LAST LOOP -- Look for a match IF privileges_in(j).priv_name = current_privs(i) AND guids(j) = current_guids(i) THEN found := TRUE; already_granted.extend; already_granted(already_granted.COUNT) := j; EXIT; END IF; END LOOP; -- If the privilege was not found then revoke it IF found = FALSE THEN -- The privilege may already have been revoked (e.g., revoking -- EM_MONITOR also revokes VIEW_TARGET on several targets), so ignore -- error BEGIN REVOKE_PRIV(grantee_in, current_privs(i), current_guids(i),0); EXCEPTION WHEN OTHERS THEN NULL; END; END IF; END LOOP; END IF; -- Grant the new privs FOR i IN 1..privileges_in.COUNT LOOP found := FALSE; IF already_granted.COUNT > 0 THEN FOR j IN already_granted.FIRST..already_granted.LAST LOOP IF i = already_granted(j) THEN found := TRUE; EXIT; END IF; END LOOP; END IF; IF found = FALSE THEN GRANT_PRIV(grantee_in, privileges_in(i)); END IF; END LOOP; END GRANT_NEW_PRIVS; -- -- PURPOSE -- Private function to grant only the new roles in a list PROCEDURE GRANT_NEW_ROLES(grantee_in IN VARCHAR2, roles_in IN SMP_EMD_STRING_ARRAY) IS current_roles SMP_EMD_STRING_ARRAY; found BOOLEAN := FALSE; already_granted SMP_EMD_INTEGER_ARRAY := SMP_EMD_INTEGER_ARRAY(); BEGIN SELECT role_name BULK COLLECT INTO current_roles FROM MGMT_ROLE_GRANTS WHERE grantee = grantee_in; -- If the new list of roles is empty then revoke all the current roles IF roles_in IS NULL OR roles_in.COUNT = 0 THEN IF current_roles IS NOT NULL AND current_roles.COUNT > 0 THEN FOR i IN current_roles.FIRST..current_roles.LAST LOOP REVOKE_ROLE(grantee_in, current_roles(i), 0); END LOOP; END IF; RETURN; END IF; IF current_roles IS NOT NULL AND current_roles.COUNT > 0 THEN FOR i IN current_roles.FIRST..current_roles.LAST LOOP found := FALSE; FOR j IN roles_in.FIRST..roles_in.LAST LOOP -- Look for a match IF roles_in(j) = current_roles(i) THEN found := TRUE; already_granted.extend; already_granted(already_granted.COUNT) := j; EXIT; END IF; END LOOP; -- If the role was not found then revoke it IF found = FALSE THEN REVOKE_ROLE(grantee_in, current_roles(i), 0); END IF; END LOOP; END IF; -- Grant the new roles FOR i IN 1..roles_in.COUNT LOOP found := FALSE; IF already_granted.COUNT > 0 THEN FOR j IN already_granted.FIRST..already_granted.LAST LOOP IF i = already_granted(j) THEN found := TRUE; EXIT; END IF; END LOOP; END IF; IF found = FALSE THEN GRANT_ROLE(grantee_in, roles_in(i), 0); END IF; END LOOP; END GRANT_NEW_ROLES; -- -- A private util function to get the list of targets on which a user has a -- certain privilege -- FUNCTION GET_TARGETS_BY_PRIV(user_name_in IN VARCHAR2, target_type_in IN VARCHAR2, priv_name_in IN VARCHAR2) RETURN TARGETS_CURSOR IS targets_cursor_out TARGETS_CURSOR; uname VARCHAR2(256); pname VARCHAR2(30); include_agents BOOLEAN := FALSE; l_iprivs SMP_EMD_STRING_ARRAY; l_priv_type NUMBER := -1; l_cuser VARCHAR2(256); BEGIN uname := UPPER(user_name_in); pname := UPPER(priv_name_in); BEGIN SELECT priv_type INTO l_priv_type FROM MGMT_PRIVS WHERE priv_name = pname; EXCEPTION WHEN NO_DATA_FOUND THEN l_priv_type := -1; END; IF l_priv_type NOT IN (TARGET_PRIVILEGE, TARGET_GROUP_PRIVILEGE) THEN raise_application_error(MGMT_GLOBAL.INVALID_PRIVILEGE_ERR, MGMT_GLOBAL.INVALID_PRIVILEGE_ERR_M || priv_name_in||' for get_targets_by_priv'); END IF; -- If this is a SUPER_USER then return all targets IF pname = VIEW_TARGET OR HAS_PRIV(uname, SUPER_USER) = USER_HAS_PRIV THEN BEGIN IF pname = VIEW_TARGET THEN l_cuser := GET_CURRENT_EM_USER; SETEMUSERCONTEXT(uname, OP_SET_IDENTIFIER); END IF; IF( (target_type_in IS NULL) OR (length(trim(target_type_in))=0) ) THEN -- return all targets of all types OPEN targets_cursor_out FOR SELECT target_guid, target_name, target_type, load_timestamp, timezone_delta, display_name, type_display_name, service_type, host_name, emd_url, last_load_time, is_group, broken_reason, broken_str, last_rt_load_time, timezone_region FROM MGMT_TARGETS; ELSE -- return all targets of type - target_type_in OPEN targets_cursor_out FOR SELECT target_guid, target_name, target_type, load_timestamp, timezone_delta, display_name, type_display_name, service_type, host_name, emd_url, last_load_time, is_group, broken_reason, broken_str, last_rt_load_time, timezone_region FROM MGMT_TARGETS WHERE target_type=target_type_in; END IF; IF pname = VIEW_TARGET THEN SETEMUSERCONTEXT(l_cuser, OP_SET_IDENTIFIER); END IF; -- data has been obtained, return the cursor RETURN targets_cursor_out; EXCEPTION WHEN OTHERS THEN SETEMUSERCONTEXT(l_cuser, OP_SET_IDENTIFIER); raise; END; END IF; -- This is not a super user, so return targets based on the user's privileges -- Get the privs that include this privilege SELECT priv_name BULK COLLECT INTO l_iprivs FROM mgmt_priv_includes where ipriv_name = pname; l_iprivs.extend; l_iprivs(l_iprivs.COUNT) := pname; -- Get the targets the user has the privilege on IF( (target_type_in IS NULL) OR (length(trim(target_type_in))=0) ) THEN IF PROPAGATE_PRIVS(pname) THEN OPEN targets_cursor_out FOR SELECT DISTINCT tgt.target_guid, tgt.target_name, tgt.target_type, tgt.load_timestamp, tgt.timezone_delta, tgt.display_name, tgt.type_display_name, tgt.service_type, tgt.host_name, tgt.emd_url, tgt.last_load_time, tgt.is_group, tgt.broken_reason, tgt.broken_str, tgt.last_rt_load_time, tgt.timezone_region FROM MGMT_TARGETS tgt WHERE target_guid IN -- For each of the targets that is a group get the members of the group -- since the privilege propagates to the group members, but exclude -- website targets ((SELECT DISTINCT assoc_target_guid FROM MGMT_FLAT_TARGET_ASSOC a, MGMT_TARGETS t WHERE a.is_membership = 1 AND a.source_target_guid IN (SELECT guid FROM MGMT_PRIV_GRANTS WHERE (grantee = uname OR grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) OR grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) AND priv_name IN (SELECT /*+cardinality(pr 5) */ column_value FROM TABLE(CAST(l_iprivs AS SMP_EMD_STRING_ARRAY)))) AND t.target_guid = a.source_target_guid AND t.target_type <> MGMT_GLOBAL.G_WEBSITE_TARGET_TYPE) UNION ALL -- For each of the targets that is a cluster, get its members -- since privileges always propagate for clusters (SELECT a.assoc_target_guid FROM mgmt_flat_target_assoc a, mgmt_targets t, mgmt_type_properties p WHERE a.is_membership = 1 AND a.source_target_guid IN (SELECT guid FROM MGMT_PRIV_GRANTS WHERE (grantee = uname OR grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) OR grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) AND priv_name IN (SELECT /*+cardinality(pr 5) */ column_value FROM TABLE(CAST(l_iprivs AS SMP_EMD_STRING_ARRAY)))) AND t.target_guid = a.source_target_guid AND t.target_type <> MGMT_GLOBAL.G_REDUNDANCY_GROUP_TARGET_TYPE AND p.target_type = t.target_type AND p.property_name = MGMT_GLOBAL.G_IS_CLUSTER_PROP AND p.property_value = '1') UNION ALL -- Get the targets based on priv grants (SELECT guid FROM MGMT_PRIV_GRANTS WHERE (grantee = uname OR grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) OR grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) AND priv_name IN (SELECT /*+cardinality(pr 5) */ column_value FROM TABLE(CAST(l_iprivs AS SMP_EMD_STRING_ARRAY)))) ); ELSE -- The approach is the same as above but do not include groups -- since there is no propagation OPEN targets_cursor_out FOR SELECT DISTINCT tgt.target_guid, tgt.target_name, tgt.target_type, tgt.load_timestamp, tgt.timezone_delta, tgt.display_name, tgt.type_display_name, tgt.service_type, tgt.host_name, tgt.emd_url, tgt.last_load_time, tgt.is_group, tgt.broken_reason, tgt.broken_str, tgt.last_rt_load_time, tgt.timezone_region FROM MGMT_TARGETS tgt WHERE target_guid IN ((SELECT a.assoc_target_guid FROM mgmt_flat_target_assoc a, mgmt_targets t, mgmt_type_properties p WHERE a.is_membership = 1 AND a.source_target_guid IN (SELECT guid FROM MGMT_PRIV_GRANTS WHERE (grantee = uname OR grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) OR grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) AND priv_name IN (SELECT /*+cardinality(pr 5) */ column_value FROM TABLE(CAST(l_iprivs AS SMP_EMD_STRING_ARRAY)))) AND t.target_guid = a.source_target_guid AND t.target_type <> MGMT_GLOBAL.G_REDUNDANCY_GROUP_TARGET_TYPE AND p.target_type = t.target_type AND p.property_name = MGMT_GLOBAL.G_IS_CLUSTER_PROP AND p.property_value = '1') UNION ALL (SELECT guid FROM MGMT_PRIV_GRANTS WHERE (grantee = uname OR grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) OR grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) AND priv_name IN (SELECT /*+cardinality(pr 5) */ column_value FROM TABLE(CAST(l_iprivs AS SMP_EMD_STRING_ARRAY)))) ); END IF; ELSE -- -- Target type has been specifed -- IF PROPAGATE_PRIVS(pname) THEN OPEN targets_cursor_out FOR SELECT DISTINCT tgt.target_guid, tgt.target_name, tgt.target_type, tgt.load_timestamp, tgt.timezone_delta, tgt.display_name, tgt.type_display_name, tgt.service_type, tgt.host_name, tgt.emd_url, tgt.last_load_time, tgt.is_group, tgt.broken_reason, tgt.broken_str, tgt.last_rt_load_time, tgt.timezone_region FROM MGMT_TARGETS tgt WHERE target_guid IN -- For each of the targets that is a group get the members of the group -- that are of the right target type, since the privilege propagates to -- the group members ((SELECT target_guid FROM MGMT_TARGETS WHERE target_type = target_type_in AND target_guid IN (SELECT DISTINCT a.assoc_target_guid FROM MGMT_FLAT_TARGET_ASSOC a, MGMT_TARGETS t WHERE a.is_membership = 1 AND a.source_target_guid IN (SELECT priv.guid FROM MGMT_PRIV_GRANTS priv, MGMT_TARGETS tgt WHERE (priv.grantee = uname OR priv.grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) OR priv.grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) AND priv_name IN (SELECT /*+cardinality(pr 5) */ column_value FROM TABLE(CAST(l_iprivs AS SMP_EMD_STRING_ARRAY))) AND priv.guid = tgt.target_guid AND tgt.target_type = target_type_in) AND t.target_guid = a.source_target_guid AND t.target_type <> MGMT_GLOBAL.G_WEBSITE_TARGET_TYPE)) UNION ALL -- For each of the targets that is a cluster, get its members -- since privileges always propagate for clusters (SELECT target_guid FROM MGMT_TARGETS WHERE target_type = target_type_in AND target_guid IN (SELECT a.assoc_target_guid FROM mgmt_flat_target_assoc a, mgmt_targets t, mgmt_type_properties p WHERE a.is_membership = 1 AND a.source_target_guid IN (SELECT priv.guid FROM MGMT_PRIV_GRANTS priv, MGMT_TARGETS tgt WHERE (priv.grantee = uname OR priv.grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) OR priv.grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) AND priv_name IN (SELECT /*+cardinality(pr 5) */ column_value FROM TABLE(CAST(l_iprivs AS SMP_EMD_STRING_ARRAY))) AND priv.guid = tgt.target_guid AND tgt.target_type = target_type_in) AND t.target_guid = a.source_target_guid AND t.target_type <> MGMT_GLOBAL.G_REDUNDANCY_GROUP_TARGET_TYPE AND p.target_type = t.target_type AND p.property_name = MGMT_GLOBAL.G_IS_CLUSTER_PROP AND p.property_value = '1')) UNION ALL -- Get the targets based on priv grants (SELECT priv.guid FROM MGMT_PRIV_GRANTS priv, MGMT_TARGETS tgt WHERE (priv.grantee = uname OR priv.grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) OR priv.grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) AND priv_name IN (SELECT /*+cardinality(pr 5) */ column_value FROM TABLE(CAST(l_iprivs AS SMP_EMD_STRING_ARRAY))) AND priv.guid = tgt.target_guid AND tgt.target_type = target_type_in) ); ELSE -- The approach is the same as above but do not include groups -- since there is no propagation OPEN targets_cursor_out FOR SELECT DISTINCT tgt.target_guid, tgt.target_name, tgt.target_type, tgt.load_timestamp, tgt.timezone_delta, tgt.display_name, tgt.type_display_name, tgt.service_type, tgt.host_name, tgt.emd_url, tgt.last_load_time, tgt.is_group, tgt.broken_reason, tgt.broken_str, tgt.last_rt_load_time, tgt.timezone_region FROM MGMT_TARGETS tgt WHERE target_guid IN ((SELECT target_guid FROM MGMT_TARGETS WHERE target_type = target_type_in AND target_guid IN (SELECT a.assoc_target_guid FROM mgmt_flat_target_assoc a, mgmt_targets t, mgmt_type_properties p WHERE a.is_membership = 1 AND a.source_target_guid IN (SELECT priv.guid FROM MGMT_PRIV_GRANTS priv, MGMT_TARGETS tgt WHERE (priv.grantee = uname OR priv.grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) OR priv.grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) AND priv_name IN (SELECT /*+cardinality(pr 5) */ column_value FROM TABLE(CAST(l_iprivs AS SMP_EMD_STRING_ARRAY))) AND priv.guid = tgt.target_guid AND tgt.target_type = target_type_in) AND t.target_guid = a.source_target_guid AND t.target_type <> MGMT_GLOBAL.G_REDUNDANCY_GROUP_TARGET_TYPE AND p.target_type = t.target_type AND p.property_name = MGMT_GLOBAL.G_IS_CLUSTER_PROP AND p.property_value = '1')) UNION ALL -- Get the targets based on priv grants (SELECT priv.guid FROM MGMT_PRIV_GRANTS priv, MGMT_TARGETS tgt WHERE (priv.grantee = uname OR priv.grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) OR priv.grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) AND priv_name IN (SELECT /*+cardinality(pr 5) */ column_value FROM TABLE(CAST(l_iprivs AS SMP_EMD_STRING_ARRAY))) AND priv.guid = tgt.target_guid AND tgt.target_type = target_type_in) ); END IF; END IF; -- data has been obtained, return the cursor RETURN targets_cursor_out; END GET_TARGETS_BY_PRIV; -- -- PURPOSE: -- -- To get the list of targets on which a user has a certain privilege -- -- NOTE: -- This api should only be called by a privileged user(super user) -- FUNCTION GET_TARGETS(user_name_in IN VARCHAR2, target_type_in IN VARCHAR2, priv_name_in IN VARCHAR2) RETURN TARGETS_CURSOR IS l_user_exists_val NUMBER(1) := MGMT_GLOBAL.G_FALSE; l_user_name VARCHAR2(64) := ''; targets_cursor_out TARGETS_CURSOR; BEGIN IF priv_name_in = FULL_JOB OR priv_name_in = VIEW_JOB THEN raise_application_error(MGMT_GLOBAL.INVALID_PRIVILEGE_ERR, MGMT_GLOBAL.INVALID_PRIVILEGE_ERR_M || priv_name_in||' for get_targets'); END IF; -- if this is not a super user, throw an exception IF NOT IS_SUPER_USER AND HAS_PRIV(GET_CURRENT_EM_USER, SUPER_USER) = USER_DOES_NOT_HAVE_PRIV THEN -- this is not a super user RAISE MGMT_GLOBAL.insufficient_privileges; END IF; -- check for the existence of the user(if supplied) IF( (length(trim(user_name_in)) <> 0 ) ) THEN -- check for the existence of this user check_user_exists(user_name_in); l_user_exists_val := MGMT_GLOBAL.G_TRUE; END IF; IF( l_user_exists_val=MGMT_GLOBAL.G_TRUE ) THEN -- user name was passed in so get the targets data for user_name_in l_user_name := user_name_in; ELSE -- user name was not passed in so get the targets data for the current user l_user_name := mgmt_user.get_current_em_user(); END IF; -- get the targets data targets_cursor_out := get_targets_by_priv(l_user_name, target_type_in, priv_name_in); -- return the targets data return targets_cursor_out; END GET_TARGETS; -- -- PURPOSE: -- -- To get the list of targets on which the current user has a certain privilege -- -- NOTE: -- This api can be called by any user -- FUNCTION GET_TARGETS(target_type_in IN VARCHAR2, priv_name_in IN VARCHAR2) RETURN TARGETS_CURSOR IS -- get the current user name from sys context l_user_name VARCHAR2(64) := mgmt_user.get_current_em_user(); targets_cursor_out TARGETS_CURSOR; BEGIN -- get the targets data targets_cursor_out := get_targets_by_priv(l_user_name, target_type_in, priv_name_in); -- return the targets data return targets_cursor_out; END GET_TARGETS; -- -- PURPOSE: -- -- To get the list of target types on which the current -- user has a certain privilege -- -- NOTE: -- This api can be called by any user -- -- IN PARAMETERS: -- -- PRIV_NAME_IN - the name of the privilege -- -- RETURNS: -- TYPES_CURSOR: CURSOR_TYPE -- A cursor which returns rows containing the target type -- related information: target_type, type_display_name -- -- ERROR codes: -- None. -- FUNCTION GET_TARGET_TYPES(priv_name_in IN VARCHAR2) RETURN CURSOR_TYPE IS types_cursor_out CURSOR_TYPE; uname VARCHAR2(256); pname VARCHAR2(30); include_agent BOOLEAN := FALSE; l_priv_type NUMBER := -1; l_iprivs SMP_EMD_STRING_ARRAY; BEGIN uname := GET_CURRENT_EM_USER; pname := UPPER(priv_name_in); BEGIN SELECT priv_type INTO l_priv_type FROM MGMT_PRIVS WHERE priv_name = pname; EXCEPTION WHEN NO_DATA_FOUND THEN l_priv_type := -1; END; IF l_priv_type NOT IN (TARGET_PRIVILEGE, TARGET_GROUP_PRIVILEGE) THEN raise_application_error(MGMT_GLOBAL.INVALID_PRIVILEGE_ERR, MGMT_GLOBAL.INVALID_PRIVILEGE_ERR_M || priv_name_in||' for get_target_types'); END IF; -- If this is a SUPER_USER then return all targets IF pname = VIEW_TARGET OR HAS_PRIV(uname, SUPER_USER) = USER_HAS_PRIV THEN -- return all types OPEN types_cursor_out FOR SELECT DISTINCT tgts.target_type, NVL(tgt_types.type_display_nlsid, tgts.target_type) "TYPE_DISPLAY_NLSID" FROM mgmt_targets tgts, mgmt_target_types tgt_types WHERE tgt_types.target_type (+) = tgts.target_type; ELSE -- this is not a super user, so return -- types based on the user's privileges -- Become the super user to avoid predicate, the targets table -- is filtered by privilege grant so the user will only see -- targets on which they have a privilege SETEMUSERCONTEXT(GET_REPOSITORY_OWNER, OP_SET_IDENTIFIER); -- Get the privs that include this privilege SELECT priv_name BULK COLLECT INTO l_iprivs FROM mgmt_priv_includes where ipriv_name = pname; l_iprivs.extend; l_iprivs(l_iprivs.COUNT) := pname; -- For each of the targets that is a group get the members of the group -- since the privilege propagates to the group members IF PROPAGATE_PRIVS(pname) THEN OPEN types_cursor_out FOR WITH priv_grants AS ( SELECT priv.guid tgt_guid FROM MGMT_PRIV_GRANTS priv WHERE priv.grantee = uname AND priv.priv_name IN (SELECT /*+cardinality(pr 5) */ * FROM TABLE(CAST(l_iprivs AS SMP_EMD_STRING_ARRAY))) UNION SELECT priv.guid FROM MGMT_PRIV_GRANTS priv WHERE priv.grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) AND priv.priv_name IN (SELECT /*+cardinality(pr 5) */ * FROM TABLE(CAST(l_iprivs AS SMP_EMD_STRING_ARRAY))) UNION SELECT priv.guid FROM MGMT_PRIV_GRANTS priv WHERE priv.grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname) AND priv.priv_name IN (SELECT /*+cardinality(pr 5) */ * FROM TABLE(CAST(l_iprivs AS SMP_EMD_STRING_ARRAY))) ) SELECT DISTINCT target_type, target_type type_display_name FROM MGMT_TARGETS WHERE target_guid IN ( SELECT a.assoc_target_guid FROM mgmt_flat_target_assoc a WHERE a.source_target_guid IN (SELECT tgt_guid FROM priv_grants) AND a.is_membership = 1 UNION SELECT tgt_guid FROM priv_grants ); ELSE OPEN types_cursor_out FOR WITH priv_grants AS ( SELECT priv.guid tgt_guid FROM MGMT_PRIV_GRANTS priv WHERE priv.grantee = uname AND priv.priv_name IN (SELECT /*+cardinality(pr 5) */ * FROM TABLE(CAST(l_iprivs AS SMP_EMD_STRING_ARRAY))) UNION SELECT priv.guid FROM MGMT_PRIV_GRANTS priv WHERE priv.grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) AND priv.priv_name IN (SELECT /*+cardinality(pr 5) */ * FROM TABLE(CAST(l_iprivs AS SMP_EMD_STRING_ARRAY))) UNION SELECT priv.guid FROM MGMT_PRIV_GRANTS priv WHERE priv.grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname) AND priv.priv_name IN (SELECT /*+cardinality(pr 5) */ * FROM TABLE(CAST(l_iprivs AS SMP_EMD_STRING_ARRAY))) ) SELECT DISTINCT target_type, target_type type_display_name FROM MGMT_TARGETS WHERE target_guid IN ( SELECT a.assoc_target_guid FROM mgmt_flat_target_assoc a, mgmt_targets t, mgmt_type_properties p WHERE a.source_target_guid IN (SELECT tgt_guid from priv_grants) AND a.is_membership = 1 AND t.target_guid = a.source_target_guid AND t.target_type <> MGMT_GLOBAL.G_REDUNDANCY_GROUP_TARGET_TYPE AND p.target_type = t.target_type AND p.property_name = MGMT_GLOBAL.G_IS_CLUSTER_PROP AND p.property_value = '1' UNION SELECT tgt_guid from priv_grants ); END IF; END IF; SETEMUSERCONTEXT(uname, OP_SET_IDENTIFIER); -- return the cursor RETURN types_cursor_out; EXCEPTION WHEN OTHERS THEN SETEMUSERCONTEXT(uname, OP_SET_IDENTIFIER); raise; END GET_TARGET_TYPES; -- -- PURPOSE -- -- To check if a user has a role -- -- PARAMETERS -- -- USER_NAME_IN - the name of the user -- ROLE_NAME_IN - the name of the role -- WITH_ADMIN_IN - the with_admin flag -- -- NOTES -- -- Return codes for HAS_ROLE -- -- RETURNS : NO_SUCH_ROLE - if the role does not exist -- USER_DOES_NOT_HAVE_ROLE - if the user does not have the role -- USER_HAS_ROLE - if the user has the role -- -- FUNCTION HAS_ROLE(user_name_in IN VARCHAR2, role_name_in IN VARCHAR2, with_admin_in IN NUMBER DEFAULT 0) RETURN NUMBER IS ok VARCHAR2(30); uname VARCHAR2(256); rname VARCHAR2(30); cname VARCHAR2(30); BEGIN uname := UPPER(user_name_in); rname := UPPER(role_name_in); -- Check that the role exists BEGIN SELECT role_name INTO ok FROM MGMT_ROLES WHERE role_name = rname; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN NO_SUCH_ROLE; END; IF HAS_PRIV(uname, SUPER_USER) > 0 THEN RETURN USER_HAS_ROLE; END IF; -- Check if this user has been granted the role directly BEGIN SELECT role_name INTO ok FROM MGMT_ROLE_GRANTS WHERE grantee = uname AND (with_admin = with_admin_in OR with_admin = 1) AND role_name = rname; RETURN USER_HAS_ROLE; EXCEPTION WHEN NO_DATA_FOUND THEN -- Just catch the exception and continue onto next check NULL; END; -- Now check if the user has been granted the role via another role BEGIN SELECT role_name INTO cname FROM MGMT_ROLE_GRANTS WHERE grantee = uname AND (with_admin = with_admin_in OR with_admin = 1) AND role_name IN (SELECT grantee FROM MGMT_ROLE_GRANTS WHERE grantee_is_role = 1 START WITH role_name = rname CONNECT BY PRIOR grantee = role_name) AND ROWNUM < 2; RETURN USER_HAS_ROLE; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN USER_DOES_NOT_HAVE_ROLE; END; RETURN USER_DOES_NOT_HAVE_ROLE; END HAS_ROLE; -- -- PURPOSE -- -- To check whether a privilege is valid and whether the guid -- specified is correct. A target GUID must be specified for a target -- privilege and a job guid must be specified for a job privilege. Also -- make sure the caller can grant the privilege -- -- PARAMETERS -- -- PRIV_NAME_IN - the name of the privilege -- GUID_IN - the job or target GUID -- -- NOTES -- -- The privilege must have been trimmed of spaces and uppercased before -- calling this routine. The caller must also have access to the target -- PROCEDURE VALIDATE_PRIVILEGE(grantee_in IN VARCHAR2, isrole_in IN NUMBER, priv_name_in IN VARCHAR2, guid_in IN RAW, isgroup_out OUT NUMBER, ptype_out OUT NUMBER, owner_out OUT VARCHAR2) IS ptype NUMBER; res NUMBER; guid RAW(16); tname VARCHAR2(64); ttype VARCHAR2(1024); members MGMT_USER_GUID_ARRAY; cname VARCHAR2(30); l_is_cluster NUMBER := 0; --Audit l_job_name VARCHAR2(4000); l_job_type VARCHAR2(4000); l_target_name VARCHAR2(4000); l_target_priv VARCHAR2(4000); BEGIN isgroup_out := 0; BEGIN -- Get the privilege type SELECT priv_type INTO ptype FROM MGMT_PRIVS WHERE priv_name = priv_name_in; ptype_out := ptype; EXCEPTION WHEN NO_DATA_FOUND THEN raise_application_error(MGMT_GLOBAL.INVALID_PRIVILEGE_ERR, MGMT_GLOBAL.INVALID_PRIVILEGE_ERR_M || priv_name_in); END; IF ptype = SYSTEM_PRIVILEGE THEN -- Make sure no target guid has been specified. IF guid_in <> NO_GUID THEN raise_application_error(MGMT_GLOBAL.INVALID_TARGET_ERR, MGMT_GLOBAL.INVALID_TARGET_ERR_M || guid_in); ELSE -- Only super users can grant SYSTEM privileges IF IS_SUPER_USER = FALSE AND (HAS_PRIV(GET_CURRENT_EM_USER, SUPER_USER) = USER_DOES_NOT_HAVE_PRIV) THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || SUPER_USER); END IF; -- The SUPER_USER privilege cannot be granted to a role IF isrole_in = 1 AND priv_name_in = SUPER_USER THEN raise_application_error(MGMT_GLOBAL.INVALID_PRIVILEGE_TYPE_ERR, MGMT_GLOBAL.INVALID_PRIVILEGE_TYPE_ERR_M || SUPER_USER); END IF; END IF; --Audit grant_priv SYSTEM_PRIVILEGE mgmt_audit_log.audit_log(mgmt_audit_log.GRANT_SYSTEM_PRIV, priv_name_in, 'SYSTEM_PRIVILEGE', null, grantee_in); RETURN; ELSIF ptype = JOB_PRIVILEGE THEN -- Make sure that a GUID has been specified and that it is a valid job BEGIN SELECT job_id, job_owner, job_type, job_name INTO guid, owner_out, l_job_type, l_job_name FROM MGMT_JOB WHERE job_id = guid_in AND nested = 0; EXCEPTION WHEN NO_DATA_FOUND THEN raise_application_error(MGMT_GLOBAL.INVALID_JOB_ERR, guid_in); END; -- FULL_JOB cannot be granted to a role IF isrole_in = 1 AND priv_name_in = FULL_JOB THEN raise_application_error(MGMT_GLOBAL.GRANT_FAILED_ERR, MGMT_GLOBAL.GRANT_FAILED_ERR_M || 'FULL_JOB cannot be granted to role '|| grantee_in); END IF; -- Only owners and superusers can grant job privs IF GET_CURRENT_EM_USER <> owner_out THEN -- This is not the owner - is the caller a superuser? IF NOT IS_SUPER_USER AND HAS_PRIV(GET_CURRENT_EM_USER, SUPER_USER) <> USER_HAS_PRIV THEN -- No, throw an error raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || GET_CURRENT_EM_USER); ELSE -- Superusers can't grant full_job if they're not the owner IF priv_name_in = FULL_JOB THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || GET_CURRENT_EM_USER); END IF; END IF; END IF; --Audit grant_priv JOB_PRIVILEGE mgmt_audit_log.audit_log(mgmt_audit_log.GRANT_JOB_PRIV, priv_name_in, 'JOB_PRIVILEGE', null, grantee_in, l_job_name, l_job_type, owner_out); ELSIF ptype = REPORT_PRIVILEGE THEN -- Make sure that a GUID has been specified and that it is a valid report BEGIN SELECT report_guid, owner INTO guid, owner_out FROM MGMT_IP_REPORT_DEF WHERE report_guid = guid_in; RETURN; EXCEPTION WHEN NO_DATA_FOUND THEN raise_application_error(MGMT_GLOBAL.REPORT_DOES_NOT_EXIST_ERR, guid_in); END; -- Only the owner or a super user can grant priv IF GET_CURRENT_EM_USER <> owner_out THEN IF NOT IS_SUPER_USER AND HAS_PRIV(GET_CURRENT_EM_USER, SUPER_USER) <> USER_HAS_PRIV THEN -- No, throw an error raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || GET_CURRENT_EM_USER); END IF; END IF; ELSIF ptype = TEMPLATE_PRIVILEGE THEN -- Make sure that a GUID has been specified and that it is a valid template BEGIN SELECT template_guid, owner INTO guid, owner_out FROM MGMT_TEMPLATES WHERE template_guid = guid_in; RETURN; EXCEPTION WHEN NO_DATA_FOUND THEN raise_application_error(MGMT_GLOBAL.TEMPLATE_DOES_NOT_EXIST_ERR, guid_in); END; -- Only the owner or a super user can grant priv IF GET_CURRENT_EM_USER <> owner_out THEN IF NOT IS_SUPER_USER AND HAS_PRIV(GET_CURRENT_EM_USER, SUPER_USER) <> USER_HAS_PRIV THEN -- No, throw an error raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || GET_CURRENT_EM_USER); END IF; END IF; ELSIF ptype = TARGET_PRIVILEGE OR ptype = TARGET_GROUP_PRIVILEGE THEN BEGIN -- Make sure the target guid is for a valid target SELECT target_type,owner, target_name INTO ttype,owner_out, l_target_name FROM MGMT_TARGETS WHERE target_guid=guid_in; EXCEPTION WHEN NO_DATA_FOUND THEN raise_application_error(MGMT_GLOBAL.INVALID_TARGET_ERR, MGMT_GLOBAL.INVALID_TARGET_ERR_M || guid_in); END; -- Only the owner or a super user can grant priv IF GET_CURRENT_EM_USER <> owner_out THEN IF NOT IS_SUPER_USER AND HAS_PRIV(GET_CURRENT_EM_USER, SUPER_USER) <> USER_HAS_PRIV THEN -- No, throw an error raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || GET_CURRENT_EM_USER); ELSE -- Caller is a super user so no need to check anything else --Audit grant_priv TARGET_PRIVILEGE OR TARGET_GROUP_PRIVILEGE IF(ptype = TARGET_PRIVILEGE) THEN l_target_priv := 'TARGET_PRIVILEGE'; ELSIF(ptype = TARGET_GROUP_PRIVILEGE) THEN l_target_priv := 'TARGET_GROUP_PRIVILEGE'; END IF; mgmt_audit_log.audit_log(mgmt_audit_log.GRANT_TARGET_PRIV, priv_name_in, l_target_priv, null, grantee_in, l_target_name, ttype, owner_out); RETURN; END IF; END IF; -- Check if composite or group SELECT COUNT(property_value) INTO isgroup_out FROM MGMT_TYPE_PROPERTIES WHERE target_type = ttype AND property_value = '1' AND (property_name = MGMT_GLOBAL.G_IS_GROUP_PROP OR property_name = MGMT_GLOBAL.G_IS_COMPOSITE_PROP); -- If this is a group privilege then the target should be a group IF ptype = TARGET_GROUP_PRIVILEGE AND isgroup_out = 0 THEN raise_application_error(MGMT_GLOBAL.INVALID_GROUP_ERR, MGMT_GLOBAL.INVALID_GROUP_ERR_M); END IF; --Audit grant_priv TARGET_PRIVILEGE OR TARGET_GROUP_PRIVILEGE IF(ptype = TARGET_PRIVILEGE) THEN l_target_priv := 'TARGET_PRIVILEGE'; ELSIF (ptype = TARGET_GROUP_PRIVILEGE) THEN l_target_priv := 'TARGET_GROUP_PRIVILEGE'; END IF; mgmt_audit_log.audit_log(mgmt_audit_log.GRANT_TARGET_PRIV, priv_name_in, l_target_priv, null, grantee_in, l_target_name, ttype, owner_out); -- Check if this target has the cluster property set BEGIN IF ttype = MGMT_GLOBAL.G_REDUNDANCY_GROUP_TARGET_TYPE THEN l_is_cluster := 0; ELSE SELECT property_value INTO l_is_cluster FROM MGMT_TYPE_PROPERTIES WHERE target_type = ttype AND property_name = MGMT_GLOBAL.G_IS_CLUSTER_PROP; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN l_is_cluster := 0; END; IF isgroup_out = 0 THEN -- The target is not a group so make sure the user already has the -- privilege IF (HAS_PRIV(GET_CURRENT_EM_USER, priv_name_in, guid_in) = USER_DOES_NOT_HAVE_PRIV) THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || priv_name_in); END IF; ELSIF ttype <> MGMT_GLOBAL.G_WEBSITE_TARGET_TYPE AND l_is_cluster = 0 THEN -- Check if the user has CREATE_TARGET_IN_GROUP privilege on the -- group IF (HAS_PRIV(GET_CURRENT_EM_USER, CREATE_TARGET_IN_GROUP, guid_in) = USER_DOES_NOT_HAVE_PRIV AND HAS_PRIV(GET_CURRENT_EM_USER, OPERATOR_TARGET, guid_in) = USER_DOES_NOT_HAVE_PRIV) THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || '(' || CREATE_TARGET_IN_GROUP|| ', ' || OPERATOR_TARGET || ')'); END IF; -- If the target is a group then make sure the user has the -- privilege for each member of group IF PROPAGATE_PRIVS(priv_name_in) THEN SELECT assoc_target_guid BULK COLLECT INTO members FROM MGMT_FLAT_TARGET_ASSOC WHERE is_membership = 1 AND source_target_guid = guid_in AND source_target_guid NOT IN (SELECT target_guid FROM mgmt_targets_delete) AND assoc_target_guid NOT IN (SELECT target_guid FROM mgmt_targets_delete); IF members IS NOT NULL AND members.COUNT > 0 THEN FOR i IN members.FIRST..members.LAST LOOP res := HAS_PRIV(GET_CURRENT_EM_USER, priv_name_in, members(i)); IF res = USER_DOES_NOT_HAVE_PRIV THEN SELECT target_name, target_type INTO tname, ttype FROM MGMT_TARGETS WHERE target_guid = members(i); raise_application_error( MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || priv_name_in || ' - ' || tname || ' (' || ttype ||')'); END IF; END LOOP; END IF; END IF; -- propagate END IF; -- elsif END IF; END VALIDATE_PRIVILEGE; -- -- PURPOSE -- -- To check whether a target can be added to a group. The target can be -- added only if the user has the same privileges on the target as the user -- has on the group. For example if the user has MAINTAIN_TARGET on a group -- then a target can only be added to the group if the user also has -- MAINTAIN_TARGET on the group. -- -- PARAMETERS -- -- GROUP_GUID_IN - the target GUID of the group -- MEMBER_GUID_IN - the target GUID of the member to be added -- -- NOTES -- -- Returns 1 if member can be added to a group -- FUNCTION VALID_GROUP_MEMBER(group_guid_in IN RAW, member_guid_in IN RAW) RETURN NUMBER IS uname VARCHAR2(256); group_priv VARCHAR2(32); has_clone_from NUMBER := 0; BEGIN -- If group privileges are not being propagated then return. The priv -- name does not matter so long as it is not a target group priv IF NOT PROPAGATE_PRIVS(VIEW_TARGET) THEN RETURN 1; END IF; uname := GET_CURRENT_EM_USER; -- Get the highest privilege that the user has on the group target -- This must be revisited to take advantage of the priv_includes -- table. Note that we do not consider CLONE_FROM here since it -- does not figure in the hierarchy. IF has_priv(uname, FULL_TARGET, group_guid_in) > 0 THEN group_priv := FULL_TARGET; ELSIF has_priv(uname, MAINTAIN_TARGET, group_guid_in) > 0 THEN group_priv := MAINTAIN_TARGET; ELSIF has_priv(uname, OPERATOR_TARGET, group_guid_in) > 0 THEN group_priv := OPERATOR_TARGET; ELSIF has_priv(uname, VIEW_TARGET, group_guid_in) > 0 THEN group_priv := VIEW_TARGET; ELSE -- Shouldn't happen? RETURN 0; END IF; has_clone_from := has_priv(uname, CLONE_FROM_TARGET, group_guid_in); IF has_clone_from=1 THEN -- If the user has a CLONE_FROM privilege on the group, then -- the user must have the privilege on the target as well IF has_priv(uname, CLONE_FROM_TARGET, member_guid_in) = 0 THEN RETURN 0; END IF; END IF; -- Return true if the user has at least the group privilege on the -- member target RETURN has_priv(uname, group_priv, member_guid_in); END VALID_GROUP_MEMBER; -- -- PURPOSE -- -- To add a callback that is invoked whenever one of the following happens: -- * a user is created -- * a user is dropped -- * a user is reassigned to a new user -- * a user has a privilege granted -- * a user has a privilege revoked -- * to get a list of objects owned by the user -- * to check for conflicts while droping a user -- * to check for conflicts while reassigning a user -- -- PARAMETERS -- -- TYPE_IN - the type of the callback -- MGMT_USER.USER_CREATED_CALLBACK -- MGMT_USER.USER_DROPPED_CALLBACK -- MGMT_USER.USER_REASSIGN_CALLBACK -- MGMT_USER.PRIV_GRANTED_CALLBACK -- MGMT_USER.PRIV_REVOKED_CALLBACK -- MGMT_USER.GET_USER_OBJECTS_CALLBACK -- MGMT_USER.CHECK_DROP_USER_CALLBACK -- MGMT_USER.CHECK_REASSIGN_USER_CALLBACK -- -- PROC_IN - the name of the callback which must be defined as : -- -- PROCEDURE USER_CREATED_CALLBACK(user_name_in IN VARCHAR2, -- type_in IN NUMBER); -- -- PROCEDURE USER_DROPED_CALLBACK(user_name_in IN VARCHAR2, -- type_in IN NUMBER); -- -- PROCEDURE USER_REASSIGN_CALLBACK(user_name_in IN VARCHAR2, -- new_user_name_in IN VARCHAR2, -- type_in IN NUMBER); -- -- PROCEDURE PRIV_CALLBACK(user_names_in IN SMP_EMD_STRING_ARRAY, -- priv_names_in IN SMP_EMD_STRING_ARRAY, -- guids_in IN MGMT_USER_GUID_ARRAY, -- type_in IN NUMBER); -- -- PROCEDURE GET_USER_OBJECTS_CALLBACK( -- user_name_in IN VARCHAR2, -- user_objects_out OUT MGMT_USER_OBJECTS, -- type_in IN NUMBER); -- -- PROCEDURE CHECK_DROP_USER_CALLBACK( -- user_name_in IN VARCHAR2, -- user_objects_out OUT MGMT_USER_OBJECTS, -- type_in IN NUMBER); -- -- PROCEDURE CHECK_REASSIGN_USER_CALLBACK( -- user_name_in IN VARCHAR2, -- new_user_name_in IN VARCHAR2, -- user_objects_out OUT MGMT_USER_OBJECTS, -- type_in IN NUMBER); -- PROCEDURE ADD_CALLBACK(proc_in IN VARCHAR2, type_in IN NUMBER) IS l_ok BOOLEAN := FALSE; l_error_message VARCHAR2(1024); l_user MGMT_SHORT_STRING_ARRAY := mgmt_short_string_array('VARCHAR2', 'NUMBER'); l_reassign MGMT_SHORT_STRING_ARRAY := mgmt_short_string_array('VARCHAR2', 'VARCHAR2', 'NUMBER'); l_priv MGMT_SHORT_STRING_ARRAY := MGMT_SHORT_STRING_ARRAY('SMP_EMD_STRING_ARRAY', 'SMP_EMD_STRING_ARRAY', 'MGMT_USER_GUID_ARRAY', 'NUMBER'); l_check_drop MGMT_SHORT_STRING_ARRAY := MGMT_SHORT_STRING_ARRAY('VARCHAR2', 'MGMT_USER_OBJECTS', 'NUMBER'); l_check_reassign MGMT_SHORT_STRING_ARRAY := MGMT_SHORT_STRING_ARRAY('VARCHAR2', 'VARCHAR2', 'MGMT_USER_OBJECTS', 'NUMBER'); l_get_objects MGMT_SHORT_STRING_ARRAY := MGMT_SHORT_STRING_ARRAY('VARCHAR2', 'MGMT_USER_OBJECTS', 'NUMBER'); BEGIN -- Check the callback exists and conforms to the correct procedure -- signature IF type_in = USER_CREATED_CALLBACK OR type_in = USER_DROPPED_CALLBACK THEN l_ok := em_check.is_valid_signature(proc_in, l_user, l_error_message); ELSIF type_in = USER_REASSIGN_CALLBACK THEN l_ok := em_check.is_valid_signature(proc_in, l_reassign, l_error_message); ELSIF type_in = PRIV_GRANTED_CALLBACK OR type_in = PRIV_REVOKED_CALLBACK THEN l_ok := em_check.is_valid_signature(proc_in, l_priv, l_error_message); ELSIF type_in = CHECK_USER_DROPPED_CALLBACK THEN l_ok := em_check.is_valid_signature(proc_in, l_check_drop, l_error_message); ELSIF type_in = CHECK_USER_REASSIGN_CALLBACK THEN l_ok := em_check.is_valid_signature(proc_in, l_check_reassign, l_error_message); ELSIF type_in = GET_USER_OBJECTS_CALLBACK THEN l_ok := em_check.is_valid_signature(proc_in, l_get_objects, l_error_message); ELSE raise_application_error(MGMT_GLOBAL.INVALID_PARAMS_ERR, 'No such callback type'); END IF; IF NOT l_ok THEN raise_application_error(MGMT_GLOBAL.INVALID_PARAMS_ERR, l_error_message); END IF; INSERT INTO MGMT_USER_CALLBACKS (callback, type) VALUES (proc_in, type_in); END ADD_CALLBACK; -- -- PURPOSE -- -- To remove a callback -- -- PARAMETERS -- PROC_IN - the name of the callback -- TYPE_IN - the type of the callback -- PROCEDURE REMOVE_CALLBACK(proc_in IN VARCHAR2, type_in IN NUMBER) IS BEGIN DELETE FROM MGMT_USER_CALLBACKS WHERE callback = proc_in AND type = type_in; END REMOVE_CALLBACK; FUNCTION VALID_GROUP_MEMBER(group_guid_in IN RAW, member_target_name_in IN VARCHAR2, member_target_type_in IN VARCHAR2) RETURN NUMBER IS member_target_guid RAW(16); BEGIN BEGIN SELECT target_guid INTO member_target_guid FROM MGMT_TARGETS WHERE target_name = member_target_name_in AND target_type = member_target_type_in; EXCEPTION WHEN OTHERS THEN raise_application_error(MGMT_GLOBAL.TARGET_DOES_NOT_EXIST_ERR, MGMT_GLOBAL.TARGET_DOES_NOT_EXIST_ERR_M || member_target_name_in || ' (' || member_target_type_in || ')'); END; RETURN valid_group_member(group_guid_in, member_target_guid); END; -- Given a privilge, return an array of all targets that the -- current user has that privilege on FUNCTION GET_TARGET_LIST(p_privilege IN VARCHAR2, p_check_superuser_privs BOOLEAN DEFAULT true) RETURN MGMT_USER_GUID_ARRAY IS tguids MGMT_USER_GUID_ARRAY; group_members MGMT_USER_GUID_ARRAY; all_guids MGMT_USER_GUID_ARRAY; l_cluster MGMT_USER_GUID_ARRAY; uname VARCHAR2(256); pname VARCHAR2(30); l_priv_type NUMBER := -1; BEGIN uname := GET_CURRENT_EM_USER; pname := UPPER(p_privilege); BEGIN SELECT priv_type INTO l_priv_type FROM MGMT_PRIVS WHERE priv_name = pname; EXCEPTION WHEN NO_DATA_FOUND THEN l_priv_type := -1; END; IF l_priv_type NOT IN (TARGET_PRIVILEGE, TARGET_GROUP_PRIVILEGE) THEN raise_application_error(MGMT_GLOBAL.INVALID_PRIVILEGE_ERR, MGMT_GLOBAL.INVALID_PRIVILEGE_ERR_M || p_privilege|| ' for get_target_list'); END IF; IF pname = VIEW_TARGET THEN SELECT target_guid BULK COLLECT INTO all_guids FROM MGMT_TARGETS; RETURN all_guids; END IF; IF p_check_superuser_privs THEN -- If the user is a SUPER_USER then all targets are visible IF HAS_PRIV(uname, SUPER_USER) = USER_HAS_PRIV THEN SELECT target_guid BULK COLLECT INTO all_guids FROM MGMT_TARGETS; RETURN all_guids; END IF; END IF; -- Get the targets that the user has been granted the privilege directly or -- via a role SELECT guid BULK COLLECT INTO tguids FROM MGMT_PRIV_GRANTS WHERE grantee = uname AND priv_name=p_privilege UNION SELECT guid FROM MGMT_PRIV_GRANTS WHERE grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname)) AND priv_name=p_privilege UNION SELECT guid FROM MGMT_PRIV_GRANTS WHERE grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname) AND priv_name=p_privilege; -- For each of the targets that is a group get the members of the group -- since the privilege propagates to the group members IF PROPAGATE_PRIVS(pname) THEN SELECT DISTINCT assoc_target_guid BULK COLLECT INTO group_members FROM MGMT_FLAT_TARGET_ASSOC WHERE is_membership = 1 AND source_target_guid IN (SELECT * FROM TABLE(CAST(tguids AS MGMT_USER_GUID_ARRAY))); END IF; -- For each of the target that is a cluster, get its members -- since privileges always propagate for clusters. SELECT a.assoc_target_guid BULK COLLECT INTO l_cluster FROM mgmt_flat_target_assoc a, mgmt_targets t, mgmt_type_properties p WHERE a.is_membership = 1 AND a.source_target_guid IN (SELECT * FROM TABLE(CAST(tguids AS MGMT_USER_GUID_ARRAY))) AND t.target_guid = a.source_target_guid AND t.target_type <> MGMT_GLOBAL.G_REDUNDANCY_GROUP_TARGET_TYPE AND p.target_type = t.target_type AND p.property_name = MGMT_GLOBAL.G_IS_CLUSTER_PROP AND p.property_value = '1'; SELECT * BULK COLLECT INTO all_guids FROM TABLE(CAST(tguids AS MGMT_USER_GUID_ARRAY)) UNION SELECT * FROM TABLE(CAST(group_members AS MGMT_USER_GUID_ARRAY)) UNION SELECT * FROM TABLE(CAST(l_cluster AS MGMT_USER_GUID_ARRAY)); RETURN all_guids; END GET_TARGET_LIST; -- -- PURPOSE -- -- To notify the user model that a target has been deleted. This allows -- the user model to recompute the targets visible to users whose visible -- target list have been cached and to remove any grants for that target -- -- PARAMETERS -- -- TARGET_NAME_IN - the target name of the deleted target -- TARGET_TYPE_IN - the type of the deleted target -- PROCEDURE HANDLE_TARGET_DELETED(target_name_in IN VARCHAR2, target_type_in IN VARCHAR2, target_guid_in IN RAW) IS tguid RAW(16); CURSOR users IS SELECT DISTINCT grantee FROM MGMT_USER_TARGETS WHERE target_guid = tguid; BEGIN /* BEGIN SELECT target_guid INTO tguid FROM MGMT_TARGETS WHERE target_name = target_name_in AND target_type = target_type_in; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN; END; */ tguid := target_guid_in ; -- Delete the grants. There is no need to call REVOKE_PRIV anymore -- since there are no indirect grants DELETE FROM MGMT_PRIV_GRANTS WHERE guid = tguid; -- Get the list of users who have VIEW_TARGET privilege on this target FOR u IN users LOOP -- And set their predicate so it is recreated next time they -- access MGMT_TARGETS which will make sure the list no longer -- contains any targets that were visible as associations of the one -- being deleted UPDATE MGMT_USER_CONTEXT SET value = CREATE_PREDICATE WHERE client_identifier = u.grantee AND attribute = EM_TARGET_PREDICATE; END LOOP; DELETE FROM MGMT_USER_TARGETS WHERE target_guid = tguid; END HANDLE_TARGET_DELETED; -- -- PURPOSE -- -- To notify the user model that a target association has changed. This allows -- the user model to recompute the targets visible to users whose visible -- target list have been cached -- -- PARAMETERS -- -- SOURCE_TARGET_GUID_IN - the target GUID of the modified target -- ASSOC_TARGET_GUIDS_IN - the target GUIDs of the associated targets -- CHANGE_IN - what has changed -- 0 = removed 1 = added -- PROCEDURE TARGET_ASSOC_CHANGED(source_target_guid_in IN RAW, assoc_target_guids_in IN MGMT_USER_GUID_ARRAY, change_in IN NUMBER) IS l_assocs MGMT_USER_GUID_ARRAY; l_additions MGMT_USER_GUID_ARRAY; BEGIN IF change_in = 1 THEN -- Addition -- Get the associations for the new additions SELECT DISTINCT assoc_target_guid BULK COLLECT INTO l_assocs FROM MGMT_FLAT_TARGET_ASSOC WHERE source_target_guid IN (SELECT * FROM TABLE(CAST(assoc_target_guids_in AS MGMT_USER_GUID_ARRAY))); SELECT * BULK COLLECT INTO l_additions FROM TABLE(CAST(assoc_target_guids_in AS MGMT_USER_GUID_ARRAY)) UNION SELECT * FROM TABLE(CAST(l_assocs AS MGMT_USER_GUID_ARRAY)); FOR u IN (SELECT grantee FROM MGMT_USER_TARGETS WHERE target_guid = source_target_guid_in) LOOP FORALL i IN l_additions.FIRST..l_additions.LAST SAVE EXCEPTIONS DELETE FROM MGMT_USER_TARGETS WHERE grantee = u.grantee AND target_guid = l_additions(i); FORALL i IN l_additions.FIRST..l_additions.LAST SAVE EXCEPTIONS INSERT INTO MGMT_USER_TARGETS VALUES (u.grantee, l_additions(i)); END LOOP; ELSIF change_in = 0 THEN -- Removal UPDATE MGMT_USER_CONTEXT SET value = CREATE_PREDICATE WHERE attribute = EM_TARGET_PREDICATE AND client_identifier IN (SELECT grantee FROM MGMT_USER_TARGETS WHERE target_guid IN (SELECT * FROM TABLE(CAST(assoc_target_guids_in AS MGMT_USER_GUID_ARRAY)))); END IF; END TARGET_ASSOC_CHANGED; -- -- PURPOSE -- -- To notify the user model that a job has been deleted. This allows -- the User Model to remove any grants for that job -- -- PARAMETERS -- -- JOB_GUID_IN - the GUID of the deleted job -- PROCEDURE JOB_DELETED(job_guid_in IN RAW) IS BEGIN -- Remove all grants DELETE FROM MGMT_PRIV_GRANTS WHERE guid = job_guid_in; -- Remove all cache entries DELETE FROM MGMT_USER_JOBS WHERE job_id = job_guid_in; END JOB_DELETED; -- PURPOSE -- -- To notify the user model that a nested job has been added. This allows -- the User Model to allow it be visible to all users having access to the -- parent job by adding rows to the job cache -- -- PARAMETERS -- -- PARENT_JOBID_IN - the GUID of the parent job -- NESTED_JOBID_IN - the GUID of the nested job -- PROCEDURE NESTED_JOB_ADDED(parent_jobid_in IN RAW, nested_jobid_in IN RAW) IS pr SMP_EMD_STRING_ARRAY := SMP_EMD_STRING_ARRAY(); all_roles SMP_EMD_STRING_ARRAY := SMP_EMD_STRING_ARRAY(); users SMP_EMD_STRING_ARRAY := SMP_EMD_STRING_ARRAY(); BEGIN -- Find all roles that have a privilege on the parent job SELECT DISTINCT grantee BULK COLLECT INTO pr FROM MGMT_PRIV_GRANTS WHERE guid = parent_jobid_in AND grantee_is_role = 1; -- Find all the roles that include roles that have the privilege SELECT DISTINCT role_grantee BULK COLLECT INTO all_roles FROM MGMT_FLAT_ROLE_GRANTS WHERE role_name IN (SELECT * FROM TABLE(CAST(pr AS SMP_EMD_STRING_ARRAY))); -- Find all users that have one of these roles SELECT grantee BULK COLLECT INTO users FROM MGMT_ROLE_GRANTS WHERE grantee_is_role = 0 AND role_name IN (SELECT * FROM TABLE(CAST(pr AS SMP_EMD_STRING_ARRAY)) UNION SELECT * FROM TABLE(CAST(all_roles AS SMP_EMD_STRING_ARRAY))) UNION SELECT grantee FROM MGMT_PRIV_GRANTS WHERE guid = parent_jobid_in AND grantee_is_role = 0; IF users IS NOT NULL AND users.COUNT > 0 THEN FORALL i IN users.FIRST..users.LAST SAVE EXCEPTIONS INSERT INTO MGMT_USER_JOBS VALUES (users(i), nested_jobid_in); END IF; END NESTED_JOB_ADDED; -- -- PURPOSE -- -- To notify the user model that a nested job has been deleted. This allows -- the User Model to remove it from the job cache -- -- PARAMETERS -- -- NESTED_JOBID_IN - the GUID of the nested job -- PROCEDURE NESTED_JOB_DELETED( nested_jobid_in IN RAW) IS BEGIN DELETE FROM MGMT_USER_JOBS WHERE job_id = nested_jobid_in; END NESTED_JOB_DELETED; -- -- PURPOSE -- -- To notify the user model that a report has been deleted. This allows -- the User Model to remove any grants for that job -- -- PARAMETERS -- -- REPORT_GUID_IN - the GUID of the deleted report definition -- PROCEDURE REPORT_DEFINITION_DELETED(report_guid_in IN RAW) IS BEGIN -- Remove all grants DELETE FROM MGMT_PRIV_GRANTS WHERE guid = report_guid_in; -- Remove all cache entries DELETE FROM MGMT_USER_REPORT_DEFS WHERE report_guid = report_guid_in; END REPORT_DEFINITION_DELETED; -- -- PURPOSE -- -- To notify the user model that a template has been deleted. This allows -- the User Model to remove any grants for that job -- -- PARAMETERS -- -- TEMPLATE_GUID_IN - the GUID of the deleted template -- PROCEDURE TEMPLATE_DELETED(template_guid_in IN RAW) IS BEGIN -- Remove all grants DELETE FROM MGMT_PRIV_GRANTS WHERE guid = template_guid_in; -- Remove all cache entries DELETE FROM MGMT_USER_TEMPLATES WHERE template_guid = template_guid_in; END TEMPLATE_DELETED; -- -- PURPOSE -- -- To notify the user model that a template has been deleted. This allows -- the User Model to remove any grants for that job -- -- PARAMETERS -- -- JOB_GUID_IN - the GUID of the deleted corrective action -- PROCEDURE CORRECTIVE_ACTION_DELETED(job_guid_in IN RAW) IS BEGIN -- There are no grants for Corrective Actions since privileges are -- derived from other objects, so just remove all cache entries DELETE FROM MGMT_USER_CAS WHERE job_id = job_guid_in; END CORRECTIVE_ACTION_DELETED; -- -- -- PURPOSE -- -- To generate the list of targets guids for which a user has the VIEW_TARGET -- privilege -- PROCEDURE SET_TARGET_LIST(em_client_in IN VARCHAR2) IS l_tguids MGMT_USER_GUID_ARRAY; l_assocs MGMT_USER_GUID_ARRAY; l_rep_guids MGMT_USER_GUID_ARRAY; l_all_guids MGMT_USER_GUID_ARRAY; l_predicate NUMBER := CREATE_PREDICATE; l_client_identifier VARCHAR2(256); l_rep_guid RAW(16); l_guid RAW(16); l_has_rep_target BOOLEAN := FALSE; l_has_em_monitor BOOLEAN := FALSE; BEGIN -- If this target policy has been disabled, then just return IF G_TARGET_POLICY_IS_ENABLED = 'N' THEN RETURN; END IF; -- If the user is a SUPER_USER or the user has the VIEW_ANY_TARGET privilege -- then all targets are visible. There is no need to check explicitly -- for SUPER_USER since the call to HAS_PRIV for VIEW_ANY_TARGET will check -- if the user is a SUPER_USER IF HAS_PRIV(em_client_in, VIEW_ANY_TARGET) = USER_HAS_PRIV THEN -- Updates are more likely than inserts UPDATE MGMT_USER_CONTEXT SET value = ANY_PREDICATE WHERE client_identifier = em_client_in AND attribute = EM_TARGET_PREDICATE; IF SQL%ROWCOUNT = 0 THEN INSERT INTO MGMT_USER_CONTEXT (client_identifier, attribute, value) VALUES (em_client_in, EM_TARGET_PREDICATE, ANY_PREDICATE); END IF; DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_TARGET, ''); RETURN; END IF; -- Lock the context BEGIN SELECT client_identifier INTO l_client_identifier FROM MGMT_USER_CONTEXT WHERE client_identifier = em_client_in AND attribute = EM_TARGET_PREDICATE FOR UPDATE; EXCEPTION WHEN NO_DATA_FOUND THEN -- Context is not set up yet so insert row which will cause other sessions -- to wait INSERT INTO MGMT_USER_CONTEXT (client_identifier, attribute, value) VALUES (em_client_in, EM_TARGET_PREDICATE, USERENV('SESSIONID')); END; -- Get the targets that the user has been granted the privilege directly on -- or via a role SELECT guid BULK COLLECT INTO l_tguids FROM MGMT_PRIV_GRANTS g, MGMT_PRIVS p WHERE grantee = em_client_in AND p.priv_name = g.priv_name AND p.priv_type IN (TARGET_PRIVILEGE, TARGET_GROUP_PRIVILEGE) UNION SELECT guid FROM MGMT_PRIV_GRANTS g, MGMT_PRIVS p WHERE grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = em_client_in)) AND p.priv_name = g.priv_name AND p.priv_type IN (TARGET_PRIVILEGE, TARGET_GROUP_PRIVILEGE) UNION SELECT guid FROM MGMT_PRIV_GRANTS g, MGMT_PRIVS p WHERE grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = em_client_in) AND p.priv_name = g.priv_name AND p.priv_type IN (TARGET_PRIVILEGE, TARGET_GROUP_PRIVILEGE); -- Get all target associations SELECT assoc_target_guid BULK COLLECT INTO l_assocs FROM MGMT_FLAT_TARGET_ASSOC WHERE source_target_guid IN (SELECT * FROM TABLE(CAST(l_tguids AS MGMT_USER_GUID_ARRAY))); -- Check if the user has access to the Management Service and Repository -- target. G_RECURSIVE_TARGET_VPD := TRUE; BEGIN DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_TARGET, ''); BEGIN SELECT target_guid INTO l_rep_guid FROM MGMT_TARGETS WHERE target_type = MGMT_GLOBAL.G_REPOSITORY_TARGET_TYPE; BEGIN SELECT column_value INTO l_guid FROM TABLE(CAST(l_tguids AS MGMT_USER_GUID_ARRAY)) WHERE column_value = l_rep_guid; l_has_rep_target := TRUE; EXCEPTION WHEN NO_DATA_FOUND THEN BEGIN SELECT column_value INTO l_guid FROM TABLE(CAST(l_assocs AS MGMT_USER_GUID_ARRAY)) WHERE column_value = l_rep_guid; l_has_rep_target := TRUE; EXCEPTION WHEN NO_DATA_FOUND THEN NULL; END; END; EXCEPTION WHEN OTHERS THEN NULL; END; -- Check if the user has the EM_MONITOR privilege IF HAS_PRIV(em_client_in, EM_MONITOR) = USER_HAS_PRIV THEN l_has_em_monitor := TRUE; END IF; IF l_has_rep_target THEN -- If the user already has the repository target then include the -- target guids of the associated host and databases l_rep_guids := GET_REPOSITORY_TARGETS(0); ELSIF l_has_em_monitor THEN -- If the user has the EM_MONITOR privilege then include the repository -- target and the guids of the associated host and databases l_rep_guids := GET_REPOSITORY_TARGETS(1); END IF; G_RECURSIVE_TARGET_VPD := FALSE; EXCEPTION WHEN OTHERS THEN G_RECURSIVE_TARGET_VPD := FALSE; END; -- Create one collection for all available GUIDs so a bulk insert can be -- done. This also creates a distinct list SELECT * BULK COLLECT INTO l_all_guids FROM TABLE(CAST(l_tguids AS MGMT_USER_GUID_ARRAY)) UNION SELECT * FROM TABLE(CAST(l_assocs AS MGMT_USER_GUID_ARRAY)) UNION SELECT * FROM TABLE(CAST(l_rep_guids AS MGMT_USER_GUID_ARRAY)); -- Delete all previous rows for the user DELETE FROM MGMT_USER_TARGETS WHERE grantee = em_client_in; IF l_all_guids IS NOT NULL AND l_all_guids.COUNT > 0 THEN -- Update the table FORALL i IN l_all_guids.FIRST..l_all_guids.LAST SAVE EXCEPTIONS INSERT INTO MGMT_USER_TARGETS VALUES (em_client_in, l_all_guids(i)); END IF; -- Check if the user has the EM_MONITOR privilege because this allows -- access to all agents IF l_has_em_monitor THEN DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_TARGET, G_TARGET_EM_MON_PREDICATE); l_predicate := EM_MONITOR_PREDICATE; ELSE DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_TARGET, G_TARGET_PRIV_PREDICATE); l_predicate := PRIV_PREDICATE; END IF; UPDATE MGMT_USER_CONTEXT SET value = l_predicate WHERE client_identifier = em_client_in AND attribute = EM_TARGET_PREDICATE; IF SQL%ROWCOUNT = 0 THEN INSERT INTO MGMT_USER_CONTEXT (client_identifier, attribute, value) VALUES (em_client_in, EM_TARGET_PREDICATE, l_predicate); END IF; EXCEPTION WHEN DUP_VAL_ON_INDEX THEN -- Another session is setting the context RETURN; END SET_TARGET_LIST; -- PURPOSE -- Autonomous version of SET_TARGET_LIST to make sure an initial version -- of the user's visible target list is available PROCEDURE ASET_TARGET_LIST(em_client_in IN VARCHAR2) IS PRAGMA AUTONOMOUS_TRANSACTION; BEGIN SET_TARGET_LIST(em_client_in); COMMIT; END ASET_TARGET_LIST; -- -- PURPOSE -- -- To generate the list of job guids for which a user has the VIEW_JOB -- privilege -- PROCEDURE SET_JOB_LIST(em_client_in IN VARCHAR2) IS predicate NUMBER := CREATE_PREDICATE; l_client_identifier VARCHAR2(256); BEGIN -- If the target policy has been disabled, then just return as this means -- that VPD is not enabled in this repository IF G_TARGET_POLICY_IS_ENABLED = 'N' THEN RETURN; END IF; -- If the user is a SUPER_USER then all jobs are visible IF HAS_PRIV(em_client_in, SUPER_USER) = USER_HAS_PRIV THEN predicate := ANY_PREDICATE; DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_JOB, ''); ELSE -- Lock the context BEGIN SELECT client_identifier INTO l_client_identifier FROM MGMT_USER_CONTEXT WHERE client_identifier = em_client_in AND attribute = EM_JOB_PREDICATE FOR UPDATE; EXCEPTION WHEN NO_DATA_FOUND THEN -- Context is not set up yet so insert row which will cause other sessions -- to wait INSERT INTO MGMT_USER_CONTEXT (client_identifier, attribute, value) VALUES (em_client_in, EM_JOB_PREDICATE, USERENV('SESSIONID')); END; predicate := PRIV_PREDICATE; -- Delete all previous rows for the user DELETE FROM MGMT_USER_JOBS WHERE grantee = em_client_in; -- Get the list of jobs the user has been granted a job privilege -- on either directly or via a role INSERT INTO MGMT_USER_JOBS (grantee, job_id) SELECT em_client_in, guid FROM MGMT_PRIV_GRANTS WHERE priv_name IN (VIEW_JOB, FULL_JOB) AND grantee = em_client_in UNION SELECT em_client_in, guid FROM MGMT_PRIV_GRANTS WHERE priv_name IN (VIEW_JOB, FULL_JOB) AND grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = em_client_in)) UNION SELECT em_client_in, guid FROM MGMT_PRIV_GRANTS WHERE priv_name IN (VIEW_JOB, FULL_JOB) AND grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = em_client_in); -- Get all nested jobs G_RECURSIVE_JOB_VPD := TRUE; BEGIN -- Set the context so all jobs are visible DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_JOB, ''); INSERT INTO MGMT_USER_JOBS (grantee, job_id) SELECT DISTINCT em_client_in, job_id FROM MGMT_JOB WHERE nested = 1 START WITH parent_job_id IN (SELECT job_id FROM MGMT_USER_JOBS WHERE grantee = em_client_in) CONNECT BY prior job_id = parent_job_id; G_RECURSIVE_JOB_VPD := FALSE; EXCEPTION WHEN OTHERS THEN G_RECURSIVE_JOB_VPD := FALSE; RAISE; END; DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_JOB, G_JOB_PRIV_PREDICATE); END IF; UPDATE MGMT_USER_CONTEXT SET value = predicate WHERE client_identifier = em_client_in AND attribute = EM_JOB_PREDICATE; IF SQL%ROWCOUNT = 0 THEN INSERT INTO MGMT_USER_CONTEXT (client_identifier, attribute, value) VALUES (em_client_in, EM_JOB_PREDICATE, predicate); END IF; EXCEPTION WHEN DUP_VAL_ON_INDEX THEN -- Another session is setting the context RETURN; END SET_JOB_LIST; -- PURPOSE -- Autonomous version of SET_JOB_LIST to make sure an initial version -- of the user's visible job list is available PROCEDURE ASET_JOB_LIST(em_client_in IN VARCHAR2) IS PRAGMA AUTONOMOUS_TRANSACTION; BEGIN SET_JOB_LIST(em_client_in); COMMIT; END ASET_JOB_LIST; -- PURPOSE -- -- To generate the list of template guids for which a user has the -- VIEW_TEMPLATE privilege -- PROCEDURE SET_TEMPLATE_LIST(em_client_in IN VARCHAR2) IS predicate NUMBER := CREATE_PREDICATE; l_client_identifier VARCHAR2(256); BEGIN -- If the target policy has been disabled, then just return as this means -- that VPD is not enabled in this repository IF G_TARGET_POLICY_IS_ENABLED = 'N' THEN RETURN; END IF; -- If the user is a SUPER_USER then all templates are visible IF HAS_PRIV(em_client_in, SUPER_USER) = USER_HAS_PRIV THEN predicate := ANY_PREDICATE; DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_TEMPLATE, ''); ELSE -- Lock the context BEGIN SELECT client_identifier INTO l_client_identifier FROM MGMT_USER_CONTEXT WHERE client_identifier = em_client_in AND attribute = EM_TEMPLATE_PREDICATE FOR UPDATE; EXCEPTION WHEN NO_DATA_FOUND THEN -- Context is not set up yet so insert row which will cause other sessions -- to wait INSERT INTO MGMT_USER_CONTEXT (client_identifier, attribute, value) VALUES (em_client_in, EM_TEMPLATE_PREDICATE, USERENV('SESSIONID')); END; predicate := PRIV_PREDICATE; -- Delete all previous rows for the user DELETE FROM MGMT_USER_TEMPLATES WHERE grantee = em_client_in; -- Get the list of templates the user has been granted a template privilege -- on either directly or via a role INSERT INTO MGMT_USER_TEMPLATES (grantee, template_guid) SELECT em_client_in, guid FROM MGMT_PRIV_GRANTS WHERE priv_name IN (VIEW_TEMPLATE, FULL_TEMPLATE) AND grantee = em_client_in UNION SELECT em_client_in, guid FROM MGMT_PRIV_GRANTS WHERE priv_name IN (VIEW_TEMPLATE, FULL_TEMPLATE) AND grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = em_client_in)) UNION SELECT em_client_in, guid FROM MGMT_PRIV_GRANTS WHERE priv_name IN (VIEW_TEMPLATE, FULL_TEMPLATE) AND grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = em_client_in); DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_TEMPLATE, G_TEMPLATE_PRIV_PREDICATE); END IF; UPDATE MGMT_USER_CONTEXT SET value = predicate WHERE client_identifier = em_client_in AND attribute = EM_TEMPLATE_PREDICATE; IF SQL%ROWCOUNT = 0 THEN INSERT INTO MGMT_USER_CONTEXT (client_identifier, attribute, value) VALUES (em_client_in, EM_TEMPLATE_PREDICATE, predicate); END IF; EXCEPTION WHEN DUP_VAL_ON_INDEX THEN -- Another session is setting the context RETURN; END SET_TEMPLATE_LIST; -- PURPOSE -- Autonomous version of SET_TEMPLATE_LIST to make sure an initial version -- of the user's visible template list is available PROCEDURE ASET_TEMPLATE_LIST(em_client_in IN VARCHAR2) IS PRAGMA AUTONOMOUS_TRANSACTION; BEGIN SET_TEMPLATE_LIST(em_client_in); COMMIT; END ASET_TEMPLATE_LIST; -- PURPOSE -- -- To generate the list of report definition guids for which a user has the -- VIEW_REPORT privilege -- PROCEDURE SET_REPORT_DEF_LIST(em_client_in IN VARCHAR2) IS predicate NUMBER := CREATE_PREDICATE; l_client_identifier VARCHAR2(256); BEGIN -- If the target policy has been disabled, then just return as this means -- that VPD is not enabled in this repository IF G_TARGET_POLICY_IS_ENABLED = 'N' THEN RETURN; END IF; -- If the user is a SUPER_USER or has VIEW_ANY_REPORT then all report -- definitions are visible IF HAS_PRIV(em_client_in, SUPER_USER) = USER_HAS_PRIV OR HAS_PRIV(em_client_in, VIEW_ANY_REPORT) = USER_HAS_PRIV THEN predicate := ANY_PREDICATE; DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_REPORT_DEF, ''); DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_ST_REPORT, ''); ELSE -- Lock the context BEGIN SELECT client_identifier INTO l_client_identifier FROM MGMT_USER_CONTEXT WHERE client_identifier = em_client_in AND attribute = EM_REPORT_DEF_PREDICATE FOR UPDATE; EXCEPTION WHEN NO_DATA_FOUND THEN -- Context is not set up yet so insert row which will cause other sessions -- to wait INSERT INTO MGMT_USER_CONTEXT (client_identifier, attribute, value) VALUES (em_client_in, EM_REPORT_DEF_PREDICATE, USERENV('SESSIONID')); END; predicate := PRIV_PREDICATE; -- Delete all previous rows for the user DELETE FROM MGMT_USER_REPORT_DEFS WHERE grantee = em_client_in; -- Get the list of report definitions the user has been granted a report -- privilege on either directly or via a role INSERT INTO MGMT_USER_REPORT_DEFS (grantee, report_guid) SELECT em_client_in, guid FROM MGMT_PRIV_GRANTS WHERE priv_name = VIEW_REPORT AND grantee = em_client_in UNION SELECT em_client_in, guid FROM MGMT_PRIV_GRANTS WHERE priv_name = VIEW_REPORT AND grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = em_client_in)) UNION SELECT em_client_in, guid FROM MGMT_PRIV_GRANTS WHERE priv_name = VIEW_REPORT AND grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = em_client_in); DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_REPORT_DEF, G_REPORT_DEF_PRIV_PREDICATE); DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_ST_REPORT, G_ST_REPORT_PRIV_PREDICATE); END IF; UPDATE MGMT_USER_CONTEXT SET value = predicate WHERE client_identifier = em_client_in AND attribute = EM_REPORT_DEF_PREDICATE; IF SQL%ROWCOUNT = 0 THEN INSERT INTO MGMT_USER_CONTEXT (client_identifier, attribute, value) VALUES (em_client_in, EM_REPORT_DEF_PREDICATE, predicate); END IF; EXCEPTION WHEN DUP_VAL_ON_INDEX THEN -- Another session is setting the context RETURN; END SET_REPORT_DEF_LIST; -- PURPOSE -- Autonomous version of SET_REPORT_DEF_LIST to make sure an initial version -- of the user's visible report definition list is available PROCEDURE ASET_REPORT_DEF_LIST(em_client_in IN VARCHAR2) IS PRAGMA AUTONOMOUS_TRANSACTION; BEGIN SET_REPORT_DEF_LIST(em_client_in); COMMIT; END ASET_REPORT_DEF_LIST; -- PURPOSE -- -- To generate the list of corrective action job ids for which a user has the -- VIEW_CA privilege -- PROCEDURE SET_CA_LIST(em_client_in IN VARCHAR2) IS predicate NUMBER := CREATE_PREDICATE; l_current_user VARCHAR2(256) := GET_CURRENT_EM_USER; l_client_identifier VARCHAR2(256); BEGIN -- If the target policy has been disabled, then just return as this means -- that VPD is not enabled in this repository IF G_TARGET_POLICY_IS_ENABLED = 'N' THEN RETURN; END IF; -- If the user is a SUPER_USER then all report definitions are visible IF HAS_PRIV(em_client_in, SUPER_USER) = USER_HAS_PRIV THEN predicate := ANY_PREDICATE; DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_CA, ''); ELSE -- Lock the context BEGIN SELECT client_identifier INTO l_client_identifier FROM MGMT_USER_CONTEXT WHERE client_identifier = em_client_in AND attribute = EM_CA_PREDICATE FOR UPDATE; EXCEPTION WHEN NO_DATA_FOUND THEN -- Context is not set up yet so insert row which will cause other sessions -- to wait INSERT INTO MGMT_USER_CONTEXT (client_identifier, attribute, value) VALUES (em_client_in, EM_CA_PREDICATE, USERENV('SESSIONID')); END; predicate := PRIV_PREDICATE; -- Delete all previous rows for the user DELETE FROM MGMT_USER_CAS WHERE grantee = em_client_in; -- Corrective Actions have one of 4 scopes: Target, Template, Target type -- or User. -- -- A user will have view on a target CA if they have VIEW on the associated -- target. A user will have view on a template CA if they have VIEW on -- the associated template. All users can view Target type CAs and this -- is handled view the CA_SCOPE = 3 part of the predicate returned by -- GET_CA_PREDICATE. A user can view all of their own CAs. -- This flag will avoid infinite recursion and also allows the entire -- contents of the corrective actions table to be returned since no -- predicate is returned for the recursive call G_RECURSIVE_CA_VPD := TRUE; BEGIN DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_CA, ''); INSERT INTO MGMT_USER_CAS (grantee, job_id) SELECT em_client_in, ca.job_id FROM MGMT_CORRECTIVE_ACTION ca, MGMT_TARGETS tgt WHERE (ca.ca_scope = CA_SCOPE_TARGET and ca.ca_target_guid = tgt.target_guid) UNION ALL SELECT em_client_in, ca.job_id FROM MGMT_CORRECTIVE_ACTION ca, MGMT_TEMPLATES tm WHERE (ca.ca_scope = CA_SCOPE_TEMPLATE and ca.ca_template_guid = tm.template_guid) UNION ALL SELECT em_client_in, ca.job_id FROM MGMT_CORRECTIVE_ACTION ca, MGMT_JOB job WHERE (ca.ca_scope = CA_SCOPE_USER and ca.job_id = job.job_id and job.job_owner = em_client_in) UNION ALL SELECT em_client_in, ca.job_id FROM MGMT_CORRECTIVE_ACTION ca, MGMT_TEMPLATE_COPIES tcs WHERE (ca.ca_scope = CA_SCOPE_TEMPLATE_COPY and ca.ca_template_guid = tcs.template_guid and tcs.created_by = em_client_in); G_RECURSIVE_CA_VPD := FALSE; EXCEPTION WHEN OTHERS THEN G_RECURSIVE_CA_VPD := FALSE; RAISE; END; DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_CA, G_CA_PRIV_PREDICATE); END IF; UPDATE MGMT_USER_CONTEXT SET value = predicate WHERE client_identifier = em_client_in AND attribute = EM_CA_PREDICATE; IF SQL%ROWCOUNT = 0 THEN INSERT INTO MGMT_USER_CONTEXT (client_identifier, attribute, value) VALUES (em_client_in, EM_CA_PREDICATE, predicate); END IF; EXCEPTION WHEN DUP_VAL_ON_INDEX THEN -- Another session is setting the context RETURN; END SET_CA_LIST; -- PURPOSE -- Autonomous version of SET_CA_LIST to make sure an initial version -- of the user's visible report definition list is available PROCEDURE ASET_CA_LIST(em_client_in IN VARCHAR2) IS PRAGMA AUTONOMOUS_TRANSACTION; BEGIN SET_CA_LIST(em_client_in); COMMIT; END ASET_CA_LIST; -- Internal method to convert an existing database user into -- an EM user with the specified roles and privileges PROCEDURE MAKE_EM_USER_INTERNAL(user_name_in IN VARCHAR2, email_addresses_in IN SMP_EMD_STRING_ARRAY, roles_in IN SMP_EMD_STRING_ARRAY, privileges_in IN MGMT_USER_PRIVILEGES, user_type_in IN NUMBER) IS BEGIN -- Set up the notification profile INSERT INTO MGMT_NOTIFY_PROFILES (profile_name) VALUES (user_name_in); -- Set up the EMAIL notification devices IF email_addresses_in.COUNT > 0 THEN -- create a default notification schedule EMD_NOTIFICATION.SET_SCHEDULE(user_name_in, ' ', sysdate, 1); FOR i IN email_addresses_in.FIRST..email_addresses_in.LAST LOOP INSERT INTO MGMT_NOTIFY_DEVICES (device_name, profile_name, type, email_address) VALUES (email_addresses_in(i), user_name_in, 1, email_addresses_in(i)); -- 24x7 schedule for each email address EMD_NOTIFICATION.SET_DEVICE_SCHEDULE(user_name_in, ' ', email_addresses_in(i), user_name_in, MGMT_PREFERENCES.DEFAULT_SCHEDULE_VALUE); END LOOP; END IF; -- Grant the privileges G_CREATING_USER := TRUE; IF privileges_in IS NOT NULL AND privileges_in.COUNT > 0 THEN FOR i IN privileges_in.FIRST..privileges_in.LAST LOOP GRANT_PRIV(user_name_in, privileges_in(i)); END LOOP; END IF; -- Grant the roles IF roles_in IS NOT NULL AND roles_in.COUNT > 0 THEN FOR i IN roles_in.FIRST..roles_in.LAST LOOP -- Grant the role GRANT_ROLE(user_name_in, roles_in(i), 0); END LOOP; END IF; G_CREATING_USER := FALSE; -- Set the predicates so they will be created when MGMT_TARGETS is -- accessed BEGIN INSERT INTO MGMT_USER_CONTEXT (client_identifier, attribute, value) VALUES (user_name_in, EM_TARGET_PREDICATE, CREATE_PREDICATE); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN UPDATE MGMT_USER_CONTEXT SET value = CREATE_PREDICATE WHERE client_identifier = user_name_in AND attribute = EM_TARGET_PREDICATE; END; BEGIN INSERT INTO MGMT_USER_CONTEXT (client_identifier, attribute, value) VALUES (user_name_in, EM_JOB_PREDICATE, CREATE_PREDICATE); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN UPDATE MGMT_USER_CONTEXT SET value = CREATE_PREDICATE WHERE client_identifier = user_name_in AND attribute = EM_JOB_PREDICATE; END; -- Insert the user into MGMT_CREATED_USER BEGIN INSERT INTO MGMT_CREATED_USERS(user_name, system_user) VALUES (user_name_in, user_type_in); EXCEPTION WHEN OTHERS THEN -- If the username already exists, ignore the error IF (SQLCODE != -1) THEN RAISE; END IF; END; -- Finally, grant the MGMT_USER role if this is a database user IF user_type_in = EM_USER OR user_type_in = SYSTEM_USER THEN EXECUTE IMMEDIATE 'GRANT MGMT_USER TO ' || EM_CHECK.ENQUOTE_NAME(user_name_in); END IF; EXCEPTION WHEN OTHERS THEN G_CREATING_USER := FALSE; raise; END MAKE_EM_USER_INTERNAL; -- -- PURPOSE -- -- "Convert" an existing database user into an EM user, granting -- the user the specified privileges and roles -- -- PARAMETERS -- -- USER_NAME_IN - the name of the user -- EMAIL_ADDRESSES_IN - the email addresses of the user -- ROLES_IN - the roles to grant to the user -- PRIVILEGES_IN - the privileges to grant to the user -- -- NOTES -- -- The caller must have the SUPER_USER privilege. -- PROCEDURE MAKE_EM_USER(user_name_in IN VARCHAR2, email_addresses_in IN SMP_EMD_STRING_ARRAY, roles_in IN SMP_EMD_STRING_ARRAY, privileges_in IN MGMT_USER_PRIVILEGES) IS BEGIN -- Check that the caller has the SUPER_USER privilege IF (HAS_PRIV(GET_CURRENT_EM_USER, SUPER_USER) = USER_DOES_NOT_HAVE_PRIV) THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || SUPER_USER); END IF; CREATE_USER(user_name_in, NULL, email_addresses_in, roles_in, privileges_in, SYSTEM_USER); END MAKE_EM_USER; -- -- PURPOSE -- -- "Convert" an existing database user into an EM user, granting -- the user the specified privileges and roles -- -- PARAMETERS -- -- USER_NAME_IN - the name of the user -- EMAIL_ADDRESS_IN - the email address of the user -- ROLES_IN - the roles to grant to the user -- PRIVILEGES_IN - the privileges to grant to the user -- -- NOTES -- -- The caller must have the SUPER_USER privilege. -- PROCEDURE MAKE_EM_USER(user_name_in IN VARCHAR2, email_address_in IN VARCHAR2 DEFAULT '', roles_in IN SMP_EMD_STRING_ARRAY DEFAULT NULL, privileges_in IN MGMT_USER_PRIVILEGES DEFAULT NULL) IS BEGIN IF email_address_in IS NULL THEN MAKE_EM_USER(user_name_in, SMP_EMD_STRING_ARRAY(), roles_in, privileges_in); ELSE MAKE_EM_USER(user_name_in, SMP_EMD_STRING_ARRAY(email_address_in), roles_in, privileges_in); END IF; END MAKE_EM_USER; -- -- PURPOSE -- -- To create a user -- -- PARAMETERS -- -- USER_NAME_IN - the name of the user -- PASSWORD_IN - the password of the user -- EMAIL_ADDRESSES_IN - the email addresses of the user -- ROLES_IN - the roles to grant to the user -- PRIVILEGES_IN - the privileges to grant to the user -- USER_TYPE_IN - type of user -- 0 - EM_USER -- 1 - SYSTEM_USER -- 2 - SSO_USER -- 3 - ENTERPRISE_USER -- -- NOTES -- -- When a user is created, it is granted the MGMT_USER role. This role is -- used to give the CONNECT privilege to the user and any other privileges -- that are necessary. The caller cannot grant any privileges that are more -- powerful that those he/she has -- -- When converting an existing database user (SYSTEM_USER) to be an -- EM user, the MAKE_EM_USER api should be called. Note that calling -- CREATE_USER directly will work, however the password_in parameter will -- be ignored -- PROCEDURE CREATE_USER(user_name_in IN VARCHAR2, password_in IN VARCHAR2, email_addresses_in IN SMP_EMD_STRING_ARRAY, roles_in IN SMP_EMD_STRING_ARRAY, privileges_in IN MGMT_USER_PRIVILEGES, user_type_in IN NUMBER DEFAULT EM_USER) IS def_tablespace VARCHAR2(30); temp_tablespace VARCHAR2(30); l_user_name VARCHAR2(256); name VARCHAR2(256); password VARCHAR2(30); created BOOLEAN := FALSE; err VARCHAR2(1024); --Audit create_user l_em_user_type VARCHAR2(4000); CURSOR callbacks IS SELECT callback FROM MGMT_USER_CALLBACKS WHERE type = USER_CREATED_CALLBACK; BEGIN -- Check the user type IF user_type_in <> EM_USER AND user_type_in <> SYSTEM_USER AND user_type_in <> SSO_USER AND user_type_in <> ENTERPRISE_USER THEN raise_application_error(MGMT_GLOBAL.INVALID_PARAMS_ERR, 'Invalid user type'); END IF; -- Check that the caller is a super user IF IS_SUPER_USER = FALSE AND (HAS_PRIV(GET_CURRENT_EM_USER, SUPER_USER) = USER_DOES_NOT_HAVE_PRIV) THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || SUPER_USER); END IF; -- Remove extra spaces and convert to uppercase l_user_name := UPPER(TRIM(user_name_in)); password := TRIM(password_in); -- Make sure the user does not already exist BEGIN SELECT user_name INTO name FROM MGMT_CREATED_USERS WHERE user_name = l_user_name; IF l_user_name = name THEN raise_application_error(MGMT_GLOBAL.USER_EXISTS_ERR, MGMT_GLOBAL.USER_EXISTS_ERR_M || user_name_in); END IF; EXCEPTION WHEN NO_DATA_FOUND THEN -- No user exists NULL; END; BEGIN -- Make sure there is no role with the same name as the user SELECT role_name INTO name FROM MGMT_ROLES WHERE role_name = l_user_name; IF l_user_name = name THEN raise_application_error(MGMT_GLOBAL.ROLE_EXISTS_ERR, MGMT_GLOBAL.ROLE_EXISTS_ERR_M || user_name_in); END IF; EXCEPTION WHEN NO_DATA_FOUND THEN -- No role exists so go ahead and create the user NULL; END; -- For a SYSTEM_USER make sure the user is already in the database IF user_type_in = SYSTEM_USER THEN BEGIN SELECT username INTO name FROM ALL_USERS WHERE username = l_user_name AND ROWNUM < 2; EXCEPTION WHEN NO_DATA_FOUND THEN -- No user exists raise_application_error(MGMT_GLOBAL.USER_DOES_NOT_EXIST_ERR, MGMT_GLOBAL.USER_DOES_NOT_EXIST_ERR_M || user_name_in); END; END IF; BEGIN -- Get the default tablespace and temporary tablespace SELECT default_tablespace, temporary_tablespace INTO def_tablespace, temp_tablespace FROM user_users; IF user_type_in = EM_USER THEN -- Create the user EXECUTE IMMEDIATE 'CREATE USER ' || EM_CHECK.ENQUOTE_NAME(l_user_name) || ' IDENTIFIED BY ' || EM_CHECK.ENQUOTE_NAME(password,false) || ' DEFAULT TABLESPACE ' || EM_CHECK.ENQUOTE_NAME(def_tablespace) || ' TEMPORARY TABLESPACE ' || EM_CHECK.ENQUOTE_NAME(temp_tablespace); created := TRUE; END IF; MAKE_EM_USER_INTERNAL(l_user_name, email_addresses_in, roles_in, privileges_in, user_type_in); -- Execute the callbacks FOR c IN callbacks LOOP BEGIN EXECUTE IMMEDIATE 'CALL ' || EM_CHECK.QUALIFIED_SQL_NAME(c.callback) || '(:username, :op)' USING l_user_name, USER_CREATED_CALLBACK; EXCEPTION WHEN OTHERS THEN mgmt_log.log_error(MGMT_USER.USERMODEL_MODULE_NAME, MGMT_GLOBAL.CALLBACK_FAILED_ERR, 'CREATE_USER ' || MGMT_GLOBAL.CALLBACK_FAILED_ERR_M || c.callback || ': ' || SQLERRM); END; END LOOP; EXCEPTION WHEN OTHERS THEN err := SQLERRM; -- If the user exists already then return IF SQLCODE = -1920 THEN raise_application_error(MGMT_GLOBAL.CREATE_FAILED_ERR, MGMT_GLOBAL.CREATE_FAILED_ERR_M || user_name_in || '. ' || SQLERRM); END IF; -- Revoke the privileges, there is no need to all revoke_priv -- since there is no need for permission checks or callbacks DELETE FROM MGMT_PRIV_GRANTS WHERE grantee = l_user_name; -- Revoke the privileges, there is no need to all revoke_role -- since there is no need for permission checks or callbacks DELETE FROM MGMT_ROLE_GRANTS WHERE grantee = l_user_name; -- Remove the notification profile DELETE FROM MGMT_NOTIFY_PROFILES WHERE profile_name = l_user_name; -- Delete folders DELETE FROM MGMT_USER_FOLDERS WHERE user_name = l_user_name; -- Delete folders DELETE FROM MGMT_CREATED_USERS WHERE user_name = l_user_name; -- Delete licensing information DELETE FROM MGMT_LICENSES WHERE username = l_user_name; IF created THEN EXECUTE IMMEDIATE 'DROP USER ' || EM_CHECK.ENQUOTE_NAME(l_user_name) || ' CASCADE'; END IF; -- Note: enquote_name returns a misleading error message -- "ORA-06502: PL/SQL: numeric or value error" -- if the input name is not a valid name IF SQLCODE = -6502 THEN raise_application_error(MGMT_GLOBAL.CREATE_FAILED_ERR, MGMT_GLOBAL.CREATE_FAILED_ERR_M || user_name_in || '. ' || MGMT_GLOBAL.INVALID_USER_PWD_ERR_M); ELSE raise_application_error(MGMT_GLOBAL.CREATE_FAILED_ERR, MGMT_GLOBAL.CREATE_FAILED_ERR_M || user_name_in || '. ' || err); END IF; END; --Audit create_user IF (user_type_in =0) THEN l_em_user_type :='EM_USER'; ELSIF(user_type_in =1) THEN l_em_user_type :='SYSTEM_USER'; ELSIF(user_type_in =2) THEN l_em_user_type :='SSO_USER'; ELSIF(user_type_in =3) THEN l_em_user_type :='ENTERPRISE_USER'; END IF; mgmt_audit_log.audit_log(mgmt_audit_log.CREATE_USER, l_user_name, l_em_user_type); END CREATE_USER; -- -- PURPOSE -- -- To create a user -- -- PARAMETERS -- -- USER_NAME_IN - the name of the user -- PASSWORD_IN - the password of the user -- EMAIL_ADDRESS_IN - the email address of the user -- ROLES_IN - the roles to grant to the user -- PRIVILEGES_IN - the privileges to grant to the user -- USER_TYPE_IN - type of user -- 0 - EM_USER -- 1 - SYSTEM_USER -- 2 - SSO_USER -- 3 - ENTERPRISE_USER -- -- NOTES -- -- When a user is created, it is granted the MGMT_USER role. This role is -- used to give the CONNECT privilege to the user and any other privileges -- that are necessary. The caller cannot grant any privileges that are more -- powerful that those he/she has -- PROCEDURE CREATE_USER(user_name_in IN VARCHAR2, password_in IN VARCHAR2, email_address_in IN VARCHAR2 DEFAULT '', roles_in IN SMP_EMD_STRING_ARRAY DEFAULT NULL, privileges_in IN MGMT_USER_PRIVILEGES DEFAULT NULL, user_type_in IN NUMBER DEFAULT EM_USER) IS BEGIN IF email_address_in IS NULL THEN CREATE_USER(user_name_in, password_in, SMP_EMD_STRING_ARRAY(), roles_in, privileges_in, user_type_in); ELSE CREATE_USER(user_name_in, password_in, SMP_EMD_STRING_ARRAY(email_address_in), roles_in, privileges_in, user_type_in); END IF; END CREATE_USER; -- -- PURPOSE -- -- To modify a user -- -- PARAMETERS -- -- USER_NAME_IN - the name of the user -- PASSWORD_IN - the new password of the user -- EMAIL_ADDRESSES_IN - the new email addresses of the user -- NULL - no change -- SMP_EMD_STRING_ARRAY() - to remove existing addresses -- SMP_EMD_STRING_ARRAY('a','b') - to set the addresses -- to a and b -- ROLES_IN - the new roles to grant to the user -- PRIVILEGES_IN - the new privileges to grant to the user -- -- NOTES -- -- The caller cannot grant any privileges that are more powerful that those -- he/she has. All existing role and privileges are dropped before the new -- ones are granted provided all the new ones are valid -- PROCEDURE MODIFY_USER(user_name_in IN VARCHAR2, password_in IN VARCHAR2, email_addresses_in IN SMP_EMD_STRING_ARRAY, roles_in IN SMP_EMD_STRING_ARRAY, privileges_in IN MGMT_USER_PRIVILEGES) IS l_user_name VARCHAR2(256); password VARCHAR2(30); l_priv VARCHAR2(30); l_role VARCHAR2(30); rname VARCHAR2(30); l_ecount NUMBER; inv_ctx BOOLEAN := FALSE; user_type NUMBER; l_is_super BOOLEAN := FALSE; is_same_user BOOLEAN := FALSE; --Audit modify_user l_em_user_type VARCHAR2(30); BEGIN BEGIN -- Remove extra spaces and convert to uppercase l_user_name := UPPER(TRIM(user_name_in)); password := TRIM(password_in); -- cannot modify a non-existent user -- or a user locked by another session get_exclusive_lock(l_user_name,'MODIFY',user_type) ; IF IS_SUPER_USER = FALSE THEN IF HAS_PRIV(GET_CURRENT_EM_USER, SUPER_USER) = USER_HAS_PRIV THEN l_is_super := TRUE; END IF; ELSE l_is_super := TRUE; END IF; --Audit modify_user mgmt_audit_log.get_em_user_type(l_user_name, l_em_user_type); -- If the user to be modified is a SUPER_USER, then the user calling -- MODIFY_USER must also be a SUPER_USER IF HAS_PRIV(l_user_name, SUPER_USER) = USER_HAS_PRIV AND NOT l_is_super THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || SUPER_USER); END IF; -- Check if the caller is tring to modify themselves IF l_user_name = GET_CURRENT_EM_USER THEN is_same_user := TRUE; END IF; -- A user can modify their own password and email addresses -- but if the caller is modifying a different user, then make sure -- they have the SUPER_USER privilege -- If the email parameter is NULL then do nothing IF email_addresses_in IS NOT NULL THEN IF is_same_user = FALSE AND NOT l_is_super THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || SUPER_USER); END IF; -- If there is one email address set to ' ', then this is meant to -- be the same as having a NULL. This is to allow the version of -- MODIFY_USER that only takes one email address, indicate that no change -- should be made to the email addresses IF email_addresses_in.COUNT = 1 AND email_addresses_in(1) = ' ' THEN NULL; ELSE UPDATE_USER_PREF_EMAIL(l_user_name, email_addresses_in); END IF; END IF; -- Update the password IF password IS NOT NULL AND LENGTH(password) > 0 AND (user_type = EM_USER OR user_type = SYSTEM_USER) THEN IF is_same_user = FALSE AND NOT l_is_super THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || SUPER_USER); END IF; EXECUTE IMMEDIATE 'ALTER USER ' || EM_CHECK.ENQUOTE_NAME(l_user_name) || ' IDENTIFIED BY ' || EM_CHECK.ENQUOTE_NAME(password,false); --Audit change_password mgmt_audit_log.audit_log(mgmt_audit_log.CHANGE_PASSWORD, l_user_name, l_em_user_type); END IF; IF privileges_in IS NOT NULL THEN IF NOT l_is_super THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || SUPER_USER); END IF; -- Make sure the context is invalidated inv_ctx := TRUE; -- The Console UI passes in a list of privileges and makes no -- distinction between existing privileges and new ones. This procedure -- only grants new privileges and revokes any current privileges that -- are not in the new list GRANT_NEW_PRIVS(l_user_name, privileges_in); END IF; IF roles_in IS NOT NULL THEN IF NOT l_is_super THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || SUPER_USER); END IF; -- Make sure the context is invalidated inv_ctx := TRUE; -- The Console UI passes in a list of roles and makes no -- distinction between existing roles and new ones. This procedure -- only grants new rolees and revokes any current roles that -- are not in the new list GRANT_NEW_ROLES(l_user_name, roles_in); END IF; IF inv_ctx THEN -- Set the predicates so there are recreated next time MGMT_TARGETS -- and MGMT_JOB is accessed UPDATE MGMT_USER_CONTEXT SET value = CREATE_PREDICATE WHERE client_identifier = l_user_name; END IF; -- Update the user folders DELETE FROM MGMT_USER_FOLDERS WHERE user_name = l_user_name AND target_guid IS NOT NULL AND target_guid NOT IN ( SELECT target_guid FROM MGMT_USER_TARGETS WHERE grantee = l_user_name); EXCEPTION WHEN OTHERS THEN -- Note: enquote_name returns a misleading error message -- "ORA-06502: PL/SQL: numeric or value error" -- if the input name is not a valid name IF SQLCODE = -6502 THEN raise_application_error(MGMT_GLOBAL.MODIFY_FAILED_ERR, MGMT_GLOBAL.MODIFY_FAILED_ERR_M || user_name_in || '. ' || MGMT_GLOBAL.INVALID_USER_PWD_ERR_M); ELSE raise_application_error(MGMT_GLOBAL.MODIFY_FAILED_ERR, MGMT_GLOBAL.MODIFY_FAILED_ERR_M || user_name_in || '. ' || SQLERRM); END IF; END; --Audit modify_user mgmt_audit_log.audit_log(mgmt_audit_log.MODIFY_USER, l_user_name, l_em_user_type); END MODIFY_USER; PROCEDURE MODIFY_DBCONSOLE_USER ( user_name_in IN VARCHAR2, password_in IN VARCHAR2, email_addresses_in IN SMP_EMD_STRING_ARRAY, roles_in IN SMP_EMD_STRING_ARRAY, privileges_in IN MGMT_USER_PRIVILEGES, to_grant_db_role_in IN NUMBER) IS has_db_role NUMBER := 0; l_db_role_name VARCHAR2(20) := 'SELECT_CATALOG_ROLE'; BEGIN MODIFY_USER( user_name_in, password_in, email_addresses_in, roles_in, privileges_in ); -- Check if user has SELECT_CALATLOG_ROLE SELECT count(*) INTO has_db_role FROM DBA_ROLE_PRIVS WHERE granted_role= l_db_role_name AND grantee = user_name_in; IF has_db_role > 0 AND to_grant_db_role_in = MGMT_GLOBAL.G_FALSE THEN EXECUTE IMMEDIATE 'REVOKE SELECT_CATALOG_ROLE FROM ' || EM_CHECK.ENQUOTE_NAME(user_name_in); ELSIF has_db_role = MGMT_GLOBAL.G_FALSE AND to_grant_db_role_in = MGMT_GLOBAL.G_TRUE THEN EXECUTE IMMEDIATE 'GRANT SELECT_CATALOG_ROLE TO ' || EM_CHECK.ENQUOTE_NAME(user_name_in, false); END IF; END MODIFY_DBCONSOLE_USER; -- -- PURPOSE -- -- To modify a user -- -- PARAMETERS -- -- USER_NAME_IN - the name of the user -- PASSWORD_IN - the new password of the user -- EMAIL_ADDRESS_IN - the new email address of the user -- NULL - no change -- 'a@b.com' - set to a@b.com -- ' ' - clear email address -- ROLES_IN - the new roles to grant to the user -- PRIVILEGES_IN - the new privileges to grant to the user -- -- NOTES -- -- The caller cannot grant any privileges that are more powerful that those -- he/she has. All existing role and privileges are dropped before the new -- ones are granted provided all the new ones are valid -- PROCEDURE MODIFY_USER(user_name_in IN VARCHAR2, password_in IN VARCHAR2, email_address_in IN VARCHAR2 DEFAULT '', roles_in IN SMP_EMD_STRING_ARRAY DEFAULT NULL, privileges_in IN MGMT_USER_PRIVILEGES DEFAULT NULL) IS BEGIN IF email_address_in IS NULL THEN MODIFY_USER(user_name_in, password_in, SMP_EMD_STRING_ARRAY(' '), roles_in, privileges_in); ELSIF email_address_in = ' ' THEN MODIFY_USER(user_name_in, password_in, SMP_EMD_STRING_ARRAY(), roles_in, privileges_in); ELSE MODIFY_USER(user_name_in, password_in, SMP_EMD_STRING_ARRAY(email_address_in), roles_in, privileges_in); END IF; END MODIFY_USER; -- --PURPOSE -- -- Private procedure to Check privileges when dropping a user -- -- PARAMETERS -- -- USER_NAME_IN - the name of the user -- PROCEDURE CHECK_DROP_PRIVS(user_name_in IN VARCHAR2) IS l_user_name VARCHAR2(256); l_caller_name VARCHAR2(256); l_view_user_name VARCHAR2(256); BEGIN -- Check that the caller has the SUPER_USER privilege IF IS_SUPER_USER = FALSE AND (HAS_PRIV(GET_CURRENT_EM_USER, SUPER_USER) = USER_DOES_NOT_HAVE_PRIV) THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || SUPER_USER); END IF; -- Remove extra spaces and convert to uppercase l_user_name := UPPER(TRIM(user_name_in)); l_caller_name := GET_CURRENT_EM_USER; l_view_user_name := 'MGMT_VIEW'; -- Use this after fixing the circular dependency. -- MGMT_VIEW_PRIV.GET_VIEW_USER(l_view_user_name); IF ( (GET_REPOSITORY_OWNER = l_user_name) OR (l_user_name = l_view_user_name) OR (l_user_name = 'SYS') OR (l_user_name = 'SYSTEM')) THEN raise_application_error(mgmt_global.DELETE_SUPERUSER_ERR, mgmt_global.DELETE_SUPERUSER_ERR_M); END IF; -- You can't drop yourself IF l_user_name = l_caller_name THEN raise_application_error(MGMT_GLOBAL.CANT_DROP_YOURSELF_ERR, MGMT_GLOBAL.CANT_DROP_YOURSELF_ERR_M); END IF; END CHECK_DROP_PRIVS; -- --Execute a Physical Drop of the schema --Also delete from mgmt_created_users if asked for --Parameters -- user_name_in : Name of the oracle schema to be deleted -- delete_mgmt_user : TRUE : user is deleted from mgmt_created_users -- FALSE: user is not deleted from mgmt_created_users -- Assumption: The user_name passed is of type EM_USER PROCEDURE DROP_EMUSER_SCHEMA(user_name_in IN VARCHAR2, delete_mgmt_user IN BOOLEAN := FALSE ) IS BEGIN BEGIN EXECUTE IMMEDIATE 'DROP USER ' || EM_CHECK.ENQUOTE_NAME(user_name_in) || ' CASCADE'; EXCEPTION WHEN OTHERS THEN -- Check for the user not existing i.e. dropped by a DROP USER -- and if so then continue on with the other cleanup IF SQLCODE <> -1918 THEN -- enquote_name returns a misleading error message -- "ORA-06502: PL/SQL: numeric or value error" -- if the input name is not a valid name IF SQLCODE = -6502 THEN raise_application_error(MGMT_GLOBAL.INVALID_USER_PWD_ERR, MGMT_GLOBAL.INVALID_USER_PWD_ERR_M); END IF; RAISE; END IF; END ; -- Delete from mgmt_created_users BEGIN IF delete_mgmt_user then DELETE FROM MGMT_CREATED_USERS WHERE user_name = user_name_in; END IF ; END ; END ; -- -- PURPOSE -- -- To check if the user exists -- -- PARAMETERS -- -- USER_NAMES - the names of the user -- -- NOTES -- -- This routines checks if the user exests in the mgmt_created_users table -- raises an application error if not -- PROCEDURE CHECK_USER_EXISTS(user_name_in IN VARCHAR2) IS l_user_name VARCHAR2(256); l_user_type NUMBER; BEGIN l_user_name := UPPER(TRIM(user_name_in)); SELECT system_user INTO l_user_type FROM MGMT_CREATED_USERS WHERE user_name = l_user_name AND ROWNUM < 2; EXCEPTION WHEN NO_DATA_FOUND THEN raise_application_error(MGMT_GLOBAL.USER_DOES_NOT_EXIST_ERR, MGMT_GLOBAL.USER_DOES_NOT_EXIST_ERR_M || l_user_name); END CHECK_USER_EXISTS; -- -- PURPOSE -- -- To call all DROP_USER_CALLBACKS registered with the user model -- -- PARAMETERS -- -- USER_NAMES - the names of the user -- -- NOTES -- -- This routines call all the DROP_USER_CALLBACKS to drop the objects owned by -- the user in different module, like jobs, jobtypes, blackouts, targets, -- corrective action, templates, reports and report definition -- -- Each module has to register a call back of type DROP_USER_CALLBACK -- which will be called hear to clean up the objects owned by the user -- in the respective module -- -- PROCEDURE DROP_USER_CALLBACK( -- user_name_in IN VARCHAR2, -- type_in IN NUMBER); -- PROCEDURE CALL_DROP_USER_CALLBACKS(user_name_in IN VARCHAR2) IS CURSOR drop_user_callbacks IS SELECT callback FROM MGMT_USER_CALLBACKS WHERE type = MGMT_USER.USER_DROPPED_CALLBACK; l_user_name VARCHAR2(256); BEGIN l_user_name := UPPER(TRIM(user_name_in)); -- Execute the callbacks FOR crec IN drop_user_callbacks LOOP BEGIN EXECUTE IMMEDIATE 'CALL ' || EM_CHECK.QUALIFIED_SQL_NAME(crec.callback) || '(:username, :op)' USING l_user_name, MGMT_USER.USER_DROPPED_CALLBACK; EXCEPTION WHEN OTHERS THEN raise_application_error(MGMT_GLOBAL.CALLBACK_FAILED_ERR, MGMT_GLOBAL.CALLBACK_FAILED_ERR || ' error while executing user model callback ' || crec.callback || ' ' || SQLERRM); END; END LOOP; END CALL_DROP_USER_CALLBACKS; -- -- PURPOSE -- -- To call all REASSIGN_USER_CALLBACKS registered with the user model -- -- PARAMETERS -- -- USER_NAME - the names of the user -- NEW_USER_NAME - the name of the new user -- -- NOTES -- -- This routines call all the REASSIGN_USER_CALLBACKS to reassign the objects owned by -- the user to the new user in different module, like jobs, jobtypes, blackouts, targets, -- corrective action, templates, reports and report definition -- -- Each module has to register a call back of type REASSIGN_USER_CALLBACK -- which will be called hear to reassig the objects owned by the user -- to the new user in the respective module -- -- PROCEDURE REASSIGN_USER_CALLBACK( -- user_name_in IN VARCHAR2, -- new_user_name_in IN VARCHAR2, -- type_in IN NUMBER); -- PROCEDURE CALL_REASSIGN_USER_CALLBACKS(user_name_in IN VARCHAR2, new_user_name_in IN VARCHAR2) IS CURSOR reassign_user_callbacks IS SELECT callback FROM MGMT_USER_CALLBACKS WHERE type = MGMT_USER.USER_REASSIGN_CALLBACK; l_user_name VARCHAR2(256); l_new_user_name VARCHAR2(256); BEGIN l_user_name := UPPER(TRIM(user_name_in)); l_new_user_name := UPPER(TRIM(new_user_name_in)); -- Execute the callbacks FOR crec IN reassign_user_callbacks LOOP BEGIN EXECUTE IMMEDIATE 'CALL ' || EM_CHECK.QUALIFIED_SQL_NAME(crec.callback) || '(:username,:new_username, :op)' USING l_user_name, l_new_user_name, MGMT_USER.USER_REASSIGN_CALLBACK; EXCEPTION WHEN OTHERS THEN raise_application_error(MGMT_GLOBAL.CALLBACK_FAILED_ERR, MGMT_GLOBAL.CALLBACK_FAILED_ERR || ' error while executing user model callback ' || crec.callback || ' ' || SQLERRM); END; END LOOP; END CALL_REASSIGN_USER_CALLBACKS; -- -- PURPOSE -- -- To drop a user -- -- PARAMETERS -- -- USER_NAME_IN - the name of the user -- -- NOTES -- PROCEDURE DROP_USER(user_name_in IN VARCHAR2, new_user_name_in IN VARCHAR2 DEFAULT NULL) IS l_user_name VARCHAR2(256); l_new_user_name VARCHAR2(256); l_caller_name VARCHAR2(256); l_view_user_name VARCHAR2(256); l_user_type NUMBER; l_job_params MGMT_JOB_PARAM_LIST; l_job_targets MGMT_JOB_TARGET_LIST; l_schedule MGMT_JOB_SCHEDULE_RECORD; l_job_name VARCHAR2(64); l_job_id RAW(16); l_execution_id RAW(16); l_schedule_date DATE; l_delay NUMBER; l_async_drop_objects NUMBER := 0; --Audit drop_user l_em_user_type VARCHAR2(30); CURSOR callbacks IS SELECT callback FROM MGMT_USER_CALLBACKS WHERE type = USER_DROPPED_CALLBACK; l_user_objects MGMT_USER_OBJECTS; BEGIN l_user_name := UPPER(TRIM(user_name_in)); l_new_user_name := UPPER(TRIM(new_user_name_in)); --Audit drop_user mgmt_audit_log.get_em_user_type(l_user_name, l_em_user_type); check_user_exists(l_user_name); IF l_new_user_name IS NOT NULL THEN check_user_exists(l_new_user_name); END IF; l_caller_name := GET_CURRENT_EM_USER; check_drop_privs(user_name_in) ; -- Get exclusive lock to DROP the user and stop user activity get_exclusive_lock(l_user_name,'DROP',l_user_type) ; -- check if there are any conflicts in dropping the user IF l_new_user_name IS NULL THEN l_user_objects := check_drop_user_conflicts(l_user_name); ELSE l_user_objects := check_reassign_user_conflicts(l_user_name,l_new_user_name); END IF; IF l_user_objects.COUNT > 0 THEN IF l_new_user_name IS NULL THEN raise_application_error(MGMT_GLOBAL.DROP_FAILED_ERR, l_user_name||' owns '||to_char(l_user_objects.COUNT)|| ' object(s) which cant be droped') ; ELSE raise_application_error(MGMT_GLOBAL.DROP_FAILED_ERR, l_user_name||' owns '||to_char(l_user_objects.COUNT)|| ' object(s) which cant be reassigned to ' || l_new_user_name) ; END IF; END IF; -- check if the user has to dropped synchronsly or async. l_user_objects := get_user_objects(l_user_name); FOR i IN 1..l_user_objects.COUNT LOOP IF l_user_objects(i).async_drop = ASYNC_DROP_OBJECT THEN l_async_drop_objects := l_async_drop_objects + 1; EXIT; END IF; END LOOP; IF l_async_drop_objects = 0 THEN IF l_user_type = EM_USER THEN DROP_EMUSER_SCHEMA(l_user_name) ; END IF; ELSE UPDATE mgmt_created_users SET deleting = 1 WHERE user_name = l_user_name; END IF; -- Delete all privilege grants DELETE FROM MGMT_PRIV_GRANTS WHERE grantee = l_user_name; -- Delete all role grants DELETE FROM MGMT_ROLE_GRANTS WHERE grantee = l_user_name; -- Remove the notification profile DELETE FROM MGMT_NOTIFY_PROFILES WHERE profile_name = l_user_name; -- Delete folders DELETE FROM MGMT_USER_FOLDERS WHERE user_name = l_user_name; -- Delete metric preferences DELETE FROM MGMT_USER_SUBTAB_COL_PREFS WHERE user_name = l_user_name; -- Delete licensing information DELETE FROM MGMT_LICENSES WHERE username = l_user_name; -- This clears all caches for the user SETEMUSERCONTEXT(l_user_name, OP_CLEAR_CONTEXT); SETEMUSERCONTEXT(l_caller_name, OP_SET_IDENTIFIER); -- If the user does not owns any objects which has to be dropped asynchronsly -- then delete the user else schedule the deluser job IF l_async_drop_objects = 0 THEN IF l_new_user_name IS NULL THEN call_drop_user_callbacks(l_user_name); ELSE call_reassign_user_callbacks(l_user_name,l_new_user_name); END IF; -- Delete from mgmt_created_users DELETE FROM MGMT_CREATED_USERS WHERE user_name = l_user_name; ELSE BEGIN -- check for delayed job execution parameter set BEGIN SELECT parameter_value INTO l_delay FROM mgmt_parameters WHERE parameter_name='delete_user_delay'; EXCEPTION WHEN OTHERS THEN l_delay := 0; END; l_schedule_date := SYSDATE + (1/(24*60))*l_delay; -- This job has no targets. l_job_targets := MGMT_JOB_TARGET_LIST(); l_job_params := MGMT_JOB_PARAM_LIST(); l_job_params.extend(1); l_job_params(1) := MGMT_JOB_PARAM_RECORD('user_name', 1, l_user_name, null); IF l_new_user_name IS NOT NULL THEN l_job_params.extend(1); l_job_params(2) := MGMT_JOB_PARAM_RECORD('new_user_name', 1, l_new_user_name, null); END IF; l_schedule := MGMT_JOBS.get_job_schedule_record(MGMT_JOBS.ONE_TIME_FREQUENCY_CODE, l_schedule_date, null, 0, 0, 0, null, null, MGMT_JOBS.TIMEZONE_REPOSITORY, 0, 0, null); l_job_name := 'DELUSR_JOB_' || SYS_GUID(); -- Submit the job as a system job so that system thread pool is used MGMT_JOBS.submit_job(l_job_name, 'This is a delete user job', 'DeleteUser', l_job_targets, l_job_params, l_schedule, l_job_id, l_execution_id, null, MGMT_JOB_ENGINE.SYSTEM_JOB_RETRY); EXCEPTION WHEN OTHERS THEN raise_application_error(MGMT_GLOBAL.DROP_FAILED_ERR, MGMT_GLOBAL.DROP_FAILED_ERR_M || user_name_in || '. ' || SQLERRM); END; END IF; --Audit drop_user mgmt_audit_log.audit_log(mgmt_audit_log.DELETE_USER, l_user_name, l_em_user_type); EXCEPTION WHEN OTHERS THEN raise_application_error(MGMT_GLOBAL.DROP_FAILED_ERR, MGMT_GLOBAL.DROP_FAILED_ERR_M || user_name_in || '. ' || SQLERRM); END DROP_USER; -- -- PURPOSE -- -- To complete dropping a user, called from the drop user job -- -- PARAMETERS -- -- USER_NAME_IN - the name of the user -- -- NOTES -- -- The caller must have the SUPER_USER system privilege -- PROCEDURE DROP_USER_COMPLETE(user_name_in IN VARCHAR2, new_user_name_in IN VARCHAR2 DEFAULT NULL) IS l_user_name VARCHAR2(256); l_new_user_name VARCHAR2(256); l_caller_name VARCHAR2(256); l_view_user_name VARCHAR2(256); l_user_type NUMBER; BEGIN l_user_name := UPPER(TRIM(user_name_in)); l_new_user_name := UPPER(TRIM(new_user_name_in)); l_caller_name := GET_CURRENT_EM_USER; check_drop_privs(l_user_name) ; SELECT system_user INTO l_user_type FROM MGMT_CREATED_USERS WHERE user_name = l_user_name; -- cannot drop a non-existent user check_user_exists(l_user_name); IF l_new_user_name IS NOT NULL THEN check_user_exists(l_new_user_name); END IF; -- delete objects owned by the user IF l_new_user_name IS NULL THEN call_drop_user_callbacks(l_user_name); ELSE call_reassign_user_callbacks(l_user_name, l_new_user_name); END IF; -- Try dropping the user first. This could fail if the user was connected IF l_user_type = EM_USER THEN DROP_EMUSER_SCHEMA(l_user_name) ; END IF; -- Delete from mgmt_created_users DELETE FROM MGMT_CREATED_USERS WHERE user_name = l_user_name; END DROP_USER_COMPLETE; -- -- PURPOSE -- -- To get a list of users -- -- PARAMETERS -- -- USER_NAMES_OUT - the names of the user -- -- NOTES -- -- This routines searches for all users that have the MGMT_USER role. It -- will not return the repository owner, and will not return any -- users with the SUPER_USER privilege, if the caller is not a SUPER_USER. -- For em users returns 'valid'=1 for valid, '0' if emuser was dropped -- PROCEDURE GET_USERS(user_names_out OUT STRING_CURSOR, user_type_in IN NUMBER DEFAULT EM_USER, p_user_srch IN VARCHAR2 DEFAULT NULL) IS l_view_user_name VARCHAR2(256); uname VARCHAR2(256); l_user_srch MGMT_CREATED_USERS.USER_NAME%TYPE; BEGIN uname := GET_CURRENT_EM_USER; l_view_user_name := 'MGMT_VIEW'; -- Use the following procedure after fixing the circular dependency -- MGMT_VIEW_PRIV.GET_VIEW_USER(l_view_user_name); --Added to Handle Wilrdcard Search --If * is entered replace it by %, so that all record are retreived --The 'searchstring' entered is enclosed by % SELECT UPPER ( TRIM ( DECODE ( INSTR(p_user_srch,'*'), 0,DECODE(INSTR(p_user_srch,'%'), 0,'%'||p_user_srch||'%',p_user_srch), REPLACE(p_user_srch,'*','%') ) ) ) INTO l_user_srch FROM dual; --This was required if a name containing "_" was queried --To handle escape character "_" l_user_srch:=replace(l_user_srch,'^','^^'); l_user_srch:=replace(l_user_srch,'_','^_'); -- Check if the user is a SUPER_USER --Fix for 4270327 IF MGMT_USER.HAS_PRIV(MGMT_USER.GET_CURRENT_EM_USER, SUPER_USER) = USER_HAS_PRIV THEN IF user_type_in = EM_USER THEN OPEN user_names_out FOR SELECT user_name, deleting, super, valid FROM ( SELECT a.user_name, a.deleting, NVL(b.priv_name,'NON_SUPER') super, DECODE(NVL(c.username,'0'),'0','0','1') valid FROM mgmt_created_users a, mgmt_priv_grants b, all_users c WHERE a.user_name <> GET_REPOSITORY_OWNER AND a.user_name <> l_view_user_name AND a.user_name = b.grantee(+) AND b.priv_name(+)='SUPER_USER' AND c.username(+)=a.user_name UNION SELECT GET_REPOSITORY_OWNER user_name,0 deleting,'OWNER' super, '1' valid FROM DUAL ) WHERE UPPER(user_name) like nvl(l_user_srch,'%') escape '^' ORDER BY user_name; ELSE OPEN user_names_out FOR SELECT user_name, deleting, super, valid FROM ( SELECT a.user_name, a.deleting, NVL(b.priv_name,'NON_SUPER') super, '1' valid FROM mgmt_created_users a, mgmt_priv_grants b WHERE a.user_name <> GET_REPOSITORY_OWNER AND a.user_name <> l_view_user_name AND a.user_name = b.grantee(+) AND b.priv_name(+)='SUPER_USER' UNION SELECT GET_REPOSITORY_OWNER user_name,0 deleting,'OWNER' super, '1' valid FROM DUAL ) WHERE UPPER(user_name) like nvl(l_user_srch,'%') escape '^' ORDER BY user_name; END IF; ELSE OPEN user_names_out FOR SELECT user_name, deleting,'' super,'1' valid FROM mgmt_created_users WHERE user_name <> GET_REPOSITORY_OWNER AND user_name <> l_view_user_name AND user_name NOT IN (SELECT grantee FROM MGMT_PRIV_GRANTS WHERE priv_name = SUPER_USER) AND UPPER(user_name) like nvl(l_user_srch,'%') escape '^' ORDER BY user_name; END IF; END GET_USERS; -- -- PURPOSE -- -- To create a privilege -- -- PARAMETERS -- -- PRIV_NAME_IN - name of the privilege -- PRIV_TYPE_IN - the type of the privilege -- 1 - TARGET -- 2 - TARGET GROUP -- DESCRIPTION_IN - a description (max of 256 characters) of the privilege -- -- NOTES -- -- This should only be used to add user defined privileges. The caller -- must have the CREATE_ANY_PRIVILEGE system privilege and the type of -- privilege must be either 1 or 2 depending on whether this privilege -- applies to a target or a target group. An exception will be thrown if -- the type is any other value -- PROCEDURE CREATE_PRIV(priv_name_in IN VARCHAR2, priv_type_in IN NUMBER, description_in IN VARCHAR2 DEFAULT '') IS pname VARCHAR2(30); uname VARCHAR2(256); BEGIN -- Check that the caller has the CREATE_ANY_PRIVILEGE privilege IF IS_SUPER_USER = FALSE AND (HAS_PRIV(GET_CURRENT_EM_USER, CREATE_ANY_PRIVILEGE) = USER_DOES_NOT_HAVE_PRIV) THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || CREATE_ANY_PRIVILEGE); END IF; -- Make sure the privilege type is target or target group IF priv_type_in <> TARGET_PRIVILEGE AND priv_type_in <> TARGET_GROUP_PRIVILEGE THEN raise_application_error(MGMT_GLOBAL.INVALID_PRIVILEGE_TYPE_ERR, MGMT_GLOBAL.INVALID_PRIVILEGE_TYPE_ERR_M || priv_type_in); END IF; BEGIN -- Remove extra spaces and convert to uppercase pname := UPPER(TRIM(priv_name_in)); uname := GET_CURRENT_EM_USER; INSERT INTO MGMT_PRIVS (priv_name, priv_type, creator, description) VALUES (pname, priv_type_in, uname, description_in); -- Add an entry in the includes table so that VIEW_TARGET is included INSERT INTO MGMT_PRIV_INCLUDES (priv_name, ipriv_name) VALUES (pname, VIEW_TARGET); EXCEPTION WHEN OTHERS THEN IF SQLCODE = -1 THEN raise_application_error(MGMT_GLOBAL.ALREADY_EXISTS_ERR, priv_name_in || MGMT_GLOBAL.ALREADY_EXISTS_ERR_M); ELSE raise_application_error(MGMT_GLOBAL.CREATE_FAILED_ERR, MGMT_GLOBAL.CREATE_FAILED_ERR_M || priv_name_in || '. ' || SQLERRM); END IF; END; END CREATE_PRIV; -- -- PURPOSE -- -- To drop a privilege -- -- PARAMETERS -- -- PRIV_NAME_IN - name of the privilege -- -- NOTES -- -- The caller must have created the privilege -- PROCEDURE DROP_PRIV(priv_name_in IN VARCHAR2) IS pname VARCHAR2(30); uname VARCHAR2(256); cname VARCHAR2(30); deleted_pname VARCHAR2(30); su NUMBER := 0; grantees PRIV_GRANTEES; guids MGMT_USER_GUID_ARRAY; BEGIN -- Remove extra spaces and convert to uppercase pname := UPPER(TRIM(priv_name_in)); uname := GET_CURRENT_EM_USER; IF IS_SUPER_USER OR HAS_PRIV(uname, SUPER_USER) = USER_HAS_PRIV THEN su := 1; END IF; -- Get the grantees of this privilege SELECT grantee, guid BULK COLLECT INTO grantees, guids FROM MGMT_PRIV_GRANTS WHERE priv_name = pname; -- Revoke the privilege IF grantees IS NOT NULL and grantees.COUNT > 0 THEN FOR i IN grantees.FIRST..grantees.LAST LOOP REVOKE_PRIV(grantees(i), pname, guids(i)); END LOOP; END IF; DELETE FROM MGMT_PRIVS WHERE priv_name = pname AND priv_type <> SYSTEM_PRIVILEGE AND (su = 1 OR creator = uname) AND creator <> '' RETURNING priv_name INTO deleted_pname; -- Check that the privilege was removed IF deleted_pname IS NULL THEN BEGIN SELECT priv_name INTO cname FROM MGMT_PRIVS WHERE priv_name = pname AND ROWNUM < 2; EXCEPTION WHEN NO_DATA_FOUND THEN raise_application_error(MGMT_GLOBAL.PRIV_DOES_NOT_EXIST_ERR, MGMT_GLOBAL.PRIV_DOES_NOT_EXIST_ERR_M || priv_name_in); END; raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || priv_name_in); END IF; -- Remove the included privlege DELETE FROM MGMT_PRIV_INCLUDES WHERE priv_name = pname AND ipriv_name = VIEW_TARGET; END DROP_PRIV; PROCEDURE UPDATE_FLAT_ROLE_GRANTS(role_name_in IN VARCHAR2) IS BEGIN -- Cleanup old grants DELETE FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee = role_name_in; -- Insert new grants INSERT INTO MGMT_FLAT_ROLE_GRANTS (role_grantee, role_name) SELECT DISTINCT role_name_in, role_name from MGMT_ROLE_GRANTS START WITH grantee = role_name_in CONNECT BY PRIOR role_name = grantee; -- Update the grants for all roles that have been granted the modified role FOR r IN (SELECT role_grantee FROM MGMT_FLAT_ROLE_GRANTS WHERE role_name = role_name_in) LOOP -- Cleanup old grants DELETE FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee = r.role_grantee; -- Insert new grants INSERT INTO MGMT_FLAT_ROLE_GRANTS (role_grantee, role_name) SELECT DISTINCT r.role_grantee, role_name from MGMT_ROLE_GRANTS START WITH grantee = r.role_grantee CONNECT BY PRIOR role_name = grantee; END LOOP; END UPDATE_FLAT_ROLE_GRANTS; -- -- PURPOSE -- -- To create a role -- -- PARAMETERS -- -- ROLE_NAME_IN - name of the role -- DESCRIPTION_IN - a description (max of 256 characters) of the role -- -- NOTES -- -- The caller must have the CREATE_ANY_ROLE system privilege -- PROCEDURE CREATE_ROLE(role_name_in IN VARCHAR2, description_in IN VARCHAR2 DEFAULT '') IS rname VARCHAR2(30); uname VARCHAR2(256); BEGIN -- Check that the caller has the CREATE_ANY_ROLE privilege IF IS_SUPER_USER = FALSE AND (HAS_PRIV(GET_CURRENT_EM_USER, CREATE_ANY_ROLE) = USER_DOES_NOT_HAVE_PRIV) THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || CREATE_ANY_ROLE); END IF; -- Remove extra spaces and convert to uppercase rname := UPPER(TRIM(role_name_in)); BEGIN -- Make sure there is no user with the same name as the role SELECT username INTO uname FROM ALL_USERS WHERE username = rname; IF uname = rname THEN raise_application_error(MGMT_GLOBAL.USER_EXISTS_ERR, MGMT_GLOBAL.USER_EXISTS_ERR_M || role_name_in); END IF; EXCEPTION WHEN NO_DATA_FOUND THEN -- No user exists so go ahead and create the role NULL; END; BEGIN INSERT INTO MGMT_ROLES (role_name, description) VALUES (rname, description_in); uname := GET_CURRENT_EM_USER; --Audit create_role mgmt_audit_log.audit_log (mgmt_audit_log.CREATE_ROLE, rname, null, uname); -- Grant the role to the creator with the WITH_ADMIN flag INSERT INTO MGMT_ROLE_GRANTS (grantee, role_name, with_admin, grantee_is_role) VALUES (uname, rname, 1, 0); EXCEPTION WHEN OTHERS THEN IF SQLCODE = -1 THEN raise_application_error(MGMT_GLOBAL.ALREADY_EXISTS_ERR, role_name_in || MGMT_GLOBAL.ALREADY_EXISTS_ERR_M); ELSE raise_application_error(MGMT_GLOBAL.CREATE_FAILED_ERR, MGMT_GLOBAL.CREATE_FAILED_ERR_M || role_name_in || '. ' || SQLERRM); END IF; END; END CREATE_ROLE; -- -- PURPOSE -- -- To create a role, grant other roles to it, grant privileges to it and then -- grant the created role to a list of users -- -- PARAMETERS -- -- ROLE_NAME_IN - name of the role -- DESCRIPTION_IN - a description (max of 256 characters) of the role -- ROLES_IN - the names of the roles to grant to the created role -- PRIVILEGES_IN - the privileges to grant to the created role -- USERS_IN - the names of the user to grant the created role to -- -- NOTES -- -- The caller must have the CREATE_ANY_ROLE system privilege and have already -- been granted all the roles and privileges which are being assigned to the -- role being created. -- PROCEDURE CREATE_ROLE(role_name_in IN VARCHAR2, description_in IN VARCHAR2, roles_in IN SMP_EMD_STRING_ARRAY, privileges_in IN MGMT_USER_PRIVILEGES, users_in IN SMP_EMD_STRING_ARRAY) IS rname VARCHAR2(30); uname VARCHAR2(256); BEGIN -- Check that the caller has the CREATE_ANY_ROLE privilege IF IS_SUPER_USER = FALSE AND (HAS_PRIV(GET_CURRENT_EM_USER, CREATE_ANY_ROLE) = USER_DOES_NOT_HAVE_PRIV) THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || CREATE_ANY_ROLE); END IF; -- Remove extra spaces and convert to uppercase rname := UPPER(TRIM(role_name_in)); BEGIN -- Make sure there is no user with the same name as the role SELECT username INTO uname FROM ALL_USERS WHERE username = rname; IF uname = rname THEN raise_application_error(MGMT_GLOBAL.USER_EXISTS_ERR, MGMT_GLOBAL.USER_EXISTS_ERR_M || role_name_in); END IF; EXCEPTION WHEN NO_DATA_FOUND THEN -- No user exists so go ahead and create the role NULL; END; BEGIN INSERT INTO MGMT_ROLES (role_name, description) VALUES (rname, description_in); uname := GET_CURRENT_EM_USER; --Audit create_role mgmt_audit_log.audit_log (mgmt_audit_log.CREATE_ROLE, rname, description_in, uname); -- Grant the role to the creator with the WITH_ADMIN flag INSERT INTO MGMT_ROLE_GRANTS (grantee, role_name, with_admin, grantee_is_role) VALUES (uname, rname, 1, 0); -- Grant the privileges IF privileges_in IS NOT NULL AND privileges_in.COUNT > 0 THEN FOR i IN privileges_in.FIRST..privileges_in.LAST LOOP GRANT_PRIV(rname, privileges_in(i)); END LOOP; END IF; -- Grant the roles IF roles_in IS NOT NULL AND roles_in.COUNT > 0 THEN FOR i IN roles_in.FIRST..roles_in.LAST LOOP -- Grant the role GRANT_ROLE(rname, roles_in(i), 0); END LOOP; UPDATE_FLAT_ROLE_GRANTS(rname); END IF; -- Now grant the newly created role to the users IF users_in IS NOT NULL AND users_in.COUNT > 0 THEN FOR i IN users_in.FIRST..users_in.LAST LOOP GRANT_ROLE(users_in(i), rname); END LOOP; END IF; EXCEPTION WHEN OTHERS THEN IF SQLCODE = -1 THEN raise_application_error(MGMT_GLOBAL.ALREADY_EXISTS_ERR, role_name_in || MGMT_GLOBAL.ALREADY_EXISTS_ERR_M); ELSE raise_application_error(MGMT_GLOBAL.CREATE_FAILED_ERR, MGMT_GLOBAL.CREATE_FAILED_ERR_M || role_name_in || '. ' || SQLERRM); END IF; END; END CREATE_ROLE; -- -- PURPOSE -- -- To modify a role. grant other roles to it, grant privileges to it and then -- grant the created role to a list of users -- -- PARAMETERS -- -- ROLE_NAME_IN - name of the role -- -- Note that if any of the parameters are NULL, they are ignored. -- -- DESCRIPTION_IN - the new description (max of 256 characters) of the role. -- ROLES_IN - the names of the roles to grant to the role, all existing roles -- are revoked -- PRIVILEGES_IN - the privileges to grant to the role, all existing -- privileges are revoked -- USERS_IN - the names of the user to grant the role to, the role is -- revoked from all users that currently have the role -- -- NOTES -- -- -- The caller must have been granted the role with the with admin option and -- have already been granted all the roles and privileges which are being -- assigned to the role being modified. -- PROCEDURE MODIFY_ROLE(role_name_in IN VARCHAR2, description_in IN VARCHAR2, roles_in IN SMP_EMD_STRING_ARRAY, privileges_in IN MGMT_USER_PRIVILEGES, users_in IN SMP_EMD_STRING_ARRAY) IS rname VARCHAR2(30); res NUMBER; l_invalidate NUMBER; CURSOR users IS SELECT grantee FROM MGMT_ROLE_GRANTS WHERE role_name = rname AND grantee_is_role = 0 AND grantee <> GET_CURRENT_EM_USER; BEGIN l_invalidate := 0; -- Remove extra spaces and convert to uppercase rname := UPPER(TRIM(role_name_in)); --Audit modify_role mgmt_audit_log.audit_log (mgmt_audit_log.MODIFY_ROLE, rname, description_in, GET_CURRENT_EM_USER); -- Check if this user has been granted the role with the WITH_ADMIN -- flag set res := HAS_ROLE(GET_CURRENT_EM_USER, rname, 1); IF res = NO_SUCH_ROLE THEN raise_application_error(MGMT_GLOBAL.ROLE_DOES_NOT_EXIST_ERR, MGMT_GLOBAL.ROLE_DOES_NOT_EXIST_ERR_M || role_name_in); ELSIF res = USER_DOES_NOT_HAVE_ROLE THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || role_name_in || '/WITH_ADMIN'); END IF; BEGIN IF description_in IS NOT NULL THEN UPDATE MGMT_ROLES SET description = description_in WHERE role_name=rname; END IF; -- invalidate the old user set IF (privileges_in IS NOT NULL) OR (roles_in IS NOT NULL) OR (users_in IS NOT NULL) THEN INVALIDATE_USERS(rname); END IF; -- Revoke the modified role from users IF users_in IS NOT NULL THEN -- Revoke the role from the users who currently have been granted it FOR u IN users LOOP REVOKE_ROLE(u.grantee, rname, l_invalidate); END LOOP; END IF; -- Grant the privileges IF privileges_in IS NOT NULL THEN -- Revoke the old privilege grants DELETE FROM MGMT_PRIV_GRANTS WHERE grantee = rname AND grantee_is_role = 1 AND priv_name NOT IN (VIEW_REPORT, VIEW_TEMPLATE, FULL_TEMPLATE); IF privileges_in.COUNT > 0 THEN FOR i IN privileges_in.FIRST..privileges_in.LAST LOOP GRANT_PRIV(rname, privileges_in(i)); END LOOP; END IF; END IF; -- Grant the roles IF roles_in IS NOT NULL THEN -- Revoke the old role grants DELETE FROM MGMT_ROLE_GRANTS WHERE grantee = rname AND grantee_is_role = 1; IF roles_in.COUNT > 0 THEN FOR i IN roles_in.FIRST..roles_in.LAST LOOP -- Grant the new roles GRANT_ROLE(rname, roles_in(i), l_invalidate); END LOOP; END IF; UPDATE_FLAT_ROLE_GRANTS(rname); END IF; -- Grant the modified role to users IF users_in IS NOT NULL THEN -- For bug 5307664 fix, the role should be revoked from user before updating -- privileges from role -- -- Revoke the role from the users who currently have been granted it -- FOR u IN users -- LOOP -- REVOKE_ROLE(u.grantee, rname, l_invalidate); -- END LOOP; IF users_in.COUNT > 0 THEN -- Now grant the role to the users FOR i IN users_in.FIRST..users_in.LAST LOOP -- Grant the new roles GRANT_ROLE(users_in(i), rname, l_invalidate); END LOOP; END IF; END IF; -- invalidate the new user set IF (privileges_in IS NOT NULL) OR (roles_in IS NOT NULL) OR (users_in IS NOT NULL) THEN INVALIDATE_USERS(rname); END IF; EXCEPTION WHEN OTHERS THEN raise_application_error(MGMT_GLOBAL.MODIFY_FAILED_ERR, MGMT_GLOBAL.MODIFY_FAILED_ERR_M || role_name_in || '. ' || SQLERRM); END; END MODIFY_ROLE; -- -- PURPOSE -- -- To drop a role -- -- PARAMETERS -- -- ROLE_NAME_IN - name of the role -- -- NOTES -- -- The caller must have been granted the role with the WITH_ADMIN flag -- set -- PROCEDURE DROP_ROLE(role_name_in IN VARCHAR2) IS rname VARCHAR2(30); deleted_rname VARCHAR2(30); res NUMBER; grantees PRIV_GRANTEES; BEGIN -- Remove extra spaces and convert to uppercase rname := UPPER(TRIM(role_name_in)); -- Check if this user has been granted the role with the WITH_ADMIN -- flag set res := HAS_ROLE(GET_CURRENT_EM_USER, rname, 1); IF res = NO_SUCH_ROLE THEN raise_application_error(MGMT_GLOBAL.ROLE_DOES_NOT_EXIST_ERR, MGMT_GLOBAL.ROLE_DOES_NOT_EXIST_ERR_M || role_name_in); ELSIF res = USER_DOES_NOT_HAVE_ROLE THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || role_name_in || '/WITH_ADMIN'); END IF; -- Get the grantees SELECT grantee BULK COLLECT INTO grantees FROM MGMT_ROLE_GRANTS WHERE role_name = rname; -- Revoke the role from them IF grantees IS NOT NULL AND grantees.COUNT > 0 THEN FOR i IN grantees.FIRST..grantees.LAST LOOP REVOKE_ROLE(grantees(i), rname); END LOOP; END IF; --Audit drop_role mgmt_audit_log.audit_log (mgmt_audit_log.DROP_ROLE, rname, null, GET_CURRENT_EM_USER); DELETE FROM MGMT_ROLES WHERE role_name = rname RETURNING role_name INTO deleted_rname; -- Check that the role was removed IF deleted_rname IS NULL THEN raise_application_error(MGMT_GLOBAL.DROP_FAILED_ERR, MGMT_GLOBAL.DROP_FAILED_ERR_M || role_name_in); END IF; -- Remove the role and privileges granted to the role DELETE FROM MGMT_PRIV_GRANTS WHERE grantee = rname; DELETE FROM MGMT_ROLE_GRANTS WHERE grantee = rname; DELETE FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee = rname; -- Invalidate the contexts of the users who have been granted this role INVALIDATE_USERS(rname); END DROP_ROLE; -- -- PURPOSE -- -- To check whether something is a role -- -- PARAMETERS -- -- ROLE_NAME_IN - name of the role -- -- NOTES -- -- Returns 1 if role_name_in exists in MGMT_ROLES -- FUNCTION IS_ROLE(role_name_in IN VARCHAR2) RETURN NUMBER IS rname VARCHAR2(30); BEGIN -- Check if this is a user or a role SELECT role_name INTO rname FROM MGMT_ROLES WHERE role_name = role_name_in; IF role_name_in = rname THEN RETURN 1; ELSE RETURN 0; END IF; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN 0; END IS_ROLE; -- -- PURPOSE -- To get the list of targets associated with the repository target -- -- PARAMETERS -- INCLUDE_REPOSITORY_TARGET - flag to indicate whether the repository -- target itself should be included -- FUNCTION GET_REPOSITORY_TARGETS(include_repository_target IN NUMBER DEFAULT 1) RETURN MGMT_USER_GUID_ARRAY IS rep_guid RAW(16); rep_connect VARCHAR2(1024); l_host MGMT_TARGETS.target_name%TYPE := ''; l_guids MGMT_USER_GUID_ARRAY := MGMT_USER_GUID_ARRAY(); guids MGMT_USER_GUID_ARRAY := MGMT_USER_GUID_ARRAY(); l_this_guid RAW(16); l_host_array SMP_EMD_STRING_ARRAY; l_database_array SMP_EMD_STRING_ARRAY; l_found INTEGER :=0; l_domain_index INTEGER :=0; counter INTEGER := 0; counter1 INTEGER := 0; BEGIN -- Get the target guid of the repository target. There should only be -- one repository target but just make sure by using rownum SELECT target_guid INTO rep_guid FROM mgmt_targets WHERE target_type = MGMT_GLOBAL.G_REPOSITORY_TARGET_TYPE AND rownum = 1; BEGIN -- Get the ConnectDescriptor of the repository target SELECT LOWER(property_value) INTO rep_connect FROM mgmt_target_properties WHERE property_name = 'ConnectDescriptor' AND target_guid = rep_guid; EXCEPTION WHEN NO_DATA_FOUND THEN rep_connect := ''; END; -- get targets associated with repository database IF rep_connect IS NOT NULL AND LENGTH(rep_connect) > 0 THEN FOR crec IN (SELECT /*+ ORDERED INDEX(a) INDEX(b) */ b.target_guid, b.host_name FROM mgmt_target_properties a, mgmt_targets b WHERE b.target_type = MGMT_GLOBAL.G_DATABASE_TARGET_TYPE AND a.property_name = 'ConnectDescriptor' AND LOWER(a.property_value) = rep_connect AND a.target_guid = b.target_guid) LOOP guids.extend(1); guids(guids.LAST) := crec.target_guid; -- try to locate a target monitoring the host BEGIN SELECT target_guid INTO l_this_guid FROM mgmt_targets WHERE target_type = MGMT_GLOBAL.G_HOST_TARGET_TYPE AND LOWER(host_name) = LOWER(crec.host_name) AND ROWNUM = 1; guids.extend(1); guids(guids.LAST) := l_this_guid; EXCEPTION WHEN NO_DATA_FOUND THEN NULL; END; END LOOP; END IF; -- Now locate targets monitoring instances and add them to our arrays SELECT LOWER(host_name), LOWER(instance_name) BULK COLLECT INTO l_host_array, l_database_array FROM gv$instance; -- find instance host targets and related agents FOR i IN l_host_array.FIRST..l_host_array.LAST LOOP l_domain_index := INSTR(l_host_array(i), '.'); IF l_domain_index > 1 THEN l_host := SUBSTR(l_host_array(i), 1, l_domain_index -1); ELSE l_host := l_host_array(i); END IF; BEGIN SELECT target_guid INTO l_this_guid FROM mgmt_targets WHERE target_type = MGMT_GLOBAL.G_HOST_TARGET_TYPE AND LOWER(SUBSTR(host_name, 1, DECODE(INSTR(host_name,'.'), 0, LENGTH(host_name), INSTR(host_name,'.')-1))) = l_host AND ROWNUM = 1; guids.extend(1); guids(guids.LAST) := l_this_guid; EXCEPTION WHEN NO_DATA_FOUND THEN NULL; END; END LOOP; -- Find instance database targets and associated agents FOR i IN l_database_array.FIRST..l_database_array.LAST LOOP FOR crec IN (SELECT a.target_guid FROM mgmt_targets a, mgmt_target_properties b, mgmt_target_properties c WHERE a.target_type IN (MGMT_GLOBAL.G_DATABASE_TARGET_TYPE, MGMT_GLOBAL.G_RAC_DATABASE_TARGET_TYPE) AND a.target_guid = b.target_guid AND b.property_name = 'MachineName' AND LOWER(b.property_value) LIKE (l_host||'%') AND a.target_guid = c.target_guid AND c.property_name = 'SID' AND LOWER(c.property_value) = l_database_array(i) AND a.target_guid = b.target_guid) LOOP guids.extend(1); guids(guids.LAST) := crec.target_guid; END LOOP; END LOOP; counter := guids.COUNT; IF include_repository_target = 1 THEN -- Add the rep guid l_guids.extend(); l_guids(1) := rep_guid; END IF; -- add unique guids FOR i IN 1..counter LOOP counter1 := l_guids.count; l_found := 0; FOR j In 1..counter1 LOOP IF l_guids(j) = guids(i) THEN l_found := 1; EXIT; END IF; END LOOP; IF l_found = 0 THEN l_guids.extend(); l_guids(l_guids.LAST) := guids(i); END IF; END LOOP; RETURN l_guids; EXCEPTION WHEN NO_DATA_FOUND THEN RETURN MGMT_USER_GUID_ARRAY(); END GET_REPOSITORY_TARGETS; -- -- PURPOSE -- -- To grant a privilege to a user or role -- -- PARAMETERS -- -- GRANTEE_IN - the name of the user or role -- PRIV_NAME_IN - the name of the privilege which must be one of the supplied -- privileges (see list at top) or else the name of an -- Integrator defined privilege that was added using CREATE_PRIV -- GUID_IN - target guid in the case of a target privilege -- target group guid in the case of target group privilege -- job guid in the case of job privilege -- NULL in the case of system privilege -- INVALIDATE_IN - Whether or not to invalidate current users of a role if -- the privileges is being assigned to a role. Defaults to 1 -- (invalidate). A zero value bypasses invalidation. -- -- NOTES -- -- When granting to a role the user must have been granted the role with the -- WITH ADMIN option. The caller can not grant a privilege -- unless he/she has already been granted that privilege. This means that -- first time grants will have to be done by a SUPER_USER who has permission -- to do anything -- PROCEDURE GRANT_PRIV(grantee_in IN VARCHAR2, priv_name_in IN VARCHAR2, guid_in IN RAW DEFAULT NO_GUID, invalidate_in IN NUMBER DEFAULT 1) IS isrole NUMBER; isgroup NUMBER; gname VARCHAR2(256); uname VARCHAR2(256); oname VARCHAR2(256); pname VARCHAR2(30); res NUMBER := 0; dgrant NUMBER := 0; ptype NUMBER := 0; l_predicate NUMBER := -1; l_affected_users SMP_EMD_STRING_ARRAY := SMP_EMD_STRING_ARRAY(); l_callback_type NUMBER := 0; CURSOR callbacks IS SELECT callback FROM MGMT_USER_CALLBACKS WHERE type = PRIV_GRANTED_CALLBACK; BEGIN -- Remove extra spaces and convert to uppercase gname := UPPER(TRIM(grantee_in)); pname := UPPER(TRIM(priv_name_in)); -- Corrective Action privs cannot be granted as they are just for use -- in HAS_PRIV IF pname = VIEW_CA OR pname = FULL_CA THEN raise_application_error(MGMT_GLOBAL.INVALID_PRIVILEGE_TYPE_ERR, MGMT_GLOBAL.INVALID_PRIVILEGE_TYPE_ERR_M || priv_name_in); END IF; -- Check if this is a role isrole := IS_ROLE(gname); -- Only super users can grant privileges to the PUBLIC role IF isrole = 1 AND gname = PUBLIC_ROLE AND NOT IS_SUPER_USER AND HAS_PRIV(GET_CURRENT_EM_USER, SUPER_USER) = USER_DOES_NOT_HAVE_PRIV THEN raise_application_error(MGMT_GLOBAL.INVALID_GRANT_TO_PUBLIC_ERR, MGMT_GLOBAL.INVALID_GRANT_TO_PUBLIC_ERR_M); END IF; -- Make sure the user is valid IF isrole = 0 AND NOT G_CREATING_USER THEN BEGIN SELECT user_name INTO uname FROM MGMT_CREATED_USERS WHERE user_name = gname; EXCEPTION WHEN NO_DATA_FOUND THEN raise_application_error(MGMT_GLOBAL.USER_DOES_NOT_EXIST_ERR, MGMT_GLOBAL.USER_DOES_NOT_EXIST_ERR_M || gname); END; END IF; -- Check that the privilege and guid are ok and the user can grant the -- privilege VALIDATE_PRIVILEGE(gname, isrole, pname, guid_in, isgroup, ptype, oname ); -- don't grant job privs to job owner IF ptype = JOB_PRIVILEGE AND oname = gname THEN RETURN; END IF; BEGIN -- Grant the privilege INSERT INTO MGMT_PRIV_GRANTS (grantee, priv_name, guid, grantee_is_role) VALUES (gname, pname, guid_in, isrole); EXCEPTION WHEN OTHERS THEN IF SQLCODE = -1 THEN -- Duplicate index error which means the user already has the privilege -- but we need to check if the grant is direct SELECT direct_grant INTO dgrant FROM MGMT_PRIV_GRANTS WHERE grantee = gname AND priv_name = pname AND guid = guid_in; IF dgrant = 1 THEN -- The privilege is already granted directly so just return RETURN; ELSE -- The privilege has not been granted directly before so update -- the flag and continue on with the indirect grants UPDATE MGMT_PRIV_GRANTS SET direct_grant = 1 WHERE grantee = gname AND priv_name = pname AND guid = guid_in; END IF; ELSIF SQLCODE = -2291 THEN -- Foreign key violation which means this privilege does not exist raise_application_error(MGMT_GLOBAL.PRIV_DOES_NOT_EXIST_ERR, MGMT_GLOBAL.PRIV_DOES_NOT_EXIST_ERR_M || priv_name_in); ELSE raise_application_error(MGMT_GLOBAL.GRANT_FAILED_ERR, MGMT_GLOBAL.GRANT_FAILED_ERR_M || priv_name_in || '. ' || SQLERRM); END IF; END; IF invalidate_in = 1 THEN IF isrole = 0 THEN IF ptype = JOB_PRIVILEGE THEN l_predicate := EM_JOB_PREDICATE; ELSIF ptype = TEMPLATE_PRIVILEGE THEN UPDATE MGMT_USER_CONTEXT SET value = CREATE_PREDICATE WHERE client_identifier = gname AND attribute = EM_CA_PREDICATE; l_predicate := EM_TEMPLATE_PREDICATE; ELSIF ptype = REPORT_PRIVILEGE THEN l_predicate := EM_REPORT_DEF_PREDICATE; ELSE UPDATE MGMT_USER_CONTEXT SET value = CREATE_PREDICATE WHERE client_identifier = gname AND attribute = EM_CA_PREDICATE; l_predicate := EM_TARGET_PREDICATE; END IF; UPDATE MGMT_USER_CONTEXT SET value = CREATE_PREDICATE WHERE client_identifier = gname AND attribute = l_predicate; ELSE INVALIDATE_USERS(gname); END IF; END IF; -- Callbacks should not be issued when creating a new user and should -- only be issued for target privileges other than VIEW_TARGET. Do not -- issue callbacks for well known super users since they have access to -- all targets IF G_CREATING_USER OR pname NOT IN (MAINTAIN_TARGET, OPERATOR_TARGET, FULL_TARGET, SUPER_USER) OR gname IN (GET_REPOSITORY_OWNER, 'SYS', 'SYSTEM') THEN RETURN; END IF; -- For a role grant, get the list of affected users IF isrole = 1 THEN SELECT DISTINCT grantee BULK COLLECT INTO l_affected_users FROM MGMT_ROLE_GRANTS WHERE grantee_is_role = 0 AND grantee NOT IN (GET_REPOSITORY_OWNER, 'SYS', 'SYSTEM') AND (role_name = gname OR role_name IN (SELECT role_grantee FROM MGMT_FLAT_ROLE_GRANTS WHERE role_name = gname)); IF l_affected_users IS NULL OR l_affected_users.COUNT = 0 THEN RETURN; END IF; l_callback_type := ROLE_GRANTED_PRIV_CALLBACK; ELSE l_affected_users.extend; l_affected_users(1) := gname; l_callback_type := USER_GRANTED_PRIV_CALLBACK; END IF; FOR c IN callbacks LOOP BEGIN EXECUTE IMMEDIATE 'CALL ' || EM_CHECK.QUALIFIED_SQL_NAME(c.callback) || '(:usernames, :privs, :targ_guids, :op)' USING l_affected_users, SMP_EMD_STRING_ARRAY(pname), MGMT_USER_GUID_ARRAY(guid_in), l_callback_type; EXCEPTION WHEN OTHERS THEN mgmt_log.log_error(MGMT_USER.USERMODEL_MODULE_NAME, MGMT_GLOBAL.CALLBACK_FAILED_ERR, 'GRANT_PRIV ' || MGMT_GLOBAL.CALLBACK_FAILED_ERR_M || c.callback || ': ' || SQLERRM); END; END LOOP; END GRANT_PRIV; -- -- To grant FULL_JOB to the owner of a job -- -- NOTES -- The caller must be the job owner PROCEDURE GRANT_FULL_JOB_TO_OWNER(guid_in IN RAW) IS owner VARCHAR2(256); uname VARCHAR2(256); had_view BOOLEAN := FALSE; BEGIN uname := GET_CURRENT_EM_USER; BEGIN -- Update the cache so the caller can get the owner BEGIN INSERT INTO mgmt_user_jobs (grantee, job_id) VALUES (uname, guid_in); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN had_view := TRUE; END; -- Make sure the caller is the owner of the job SELECT job_owner INTO owner FROM MGMT_JOB WHERE job_id = guid_in; EXCEPTION WHEN NO_DATA_FOUND THEN IF NOT had_view THEN DELETE FROM MGMT_USER_JOBS WHERE grantee = uname AND job_id = guid_in; END IF; raise_application_error(MGMT_GLOBAL.INVALID_JOB_ERR, guid_in); END; IF owner <> uname THEN IF NOT had_view THEN DELETE FROM MGMT_USER_JOBS WHERE grantee = uname AND job_id = guid_in; END IF; raise_application_error(MGMT_GLOBAL.INVALID_JOB_ERR, 'Not owner'); END IF; -- Grant the privilege INSERT INTO MGMT_PRIV_GRANTS (grantee, priv_name, guid, grantee_is_role, direct_grant) VALUES (uname, FULL_JOB, guid_in, 0, 1); -- If this is a super user then there is no need for the cache entry IF HAS_PRIV(uname, SUPER_USER) = USER_HAS_PRIV THEN DELETE FROM MGMT_USER_JOBS WHERE grantee = uname AND job_id = guid_in; END IF; END GRANT_FULL_JOB_TO_OWNER; -- -- To grant FULL_JOB to the owner of a job -- -- NOTES -- The caller must be the job owner PROCEDURE GRANT_CA_PRIVS(p_guid_in IN RAW, p_scope_in IN NUMBER, p_target_guid_in IN RAW, p_template_guid_in IN RAW, p_owner_in IN VARCHAR2) IS l_users STRING_CURSOR; l_username VARCHAR2(256); BEGIN IF p_scope_in = CA_SCOPE_TARGET THEN l_users := GET_VIEW_TARGET_USERS(p_target_guid_in); LOOP FETCH l_users INTO l_username; EXIT WHEN l_users%NOTFOUND; INSERT INTO MGMT_USER_CAS (grantee, job_id) VALUES (l_username, p_guid_in); END LOOP; CLOSE l_users; ELSIF p_scope_in = CA_SCOPE_TEMPLATE THEN l_users := GET_VIEW_TEMPLATE_USERS(p_template_guid_in); LOOP FETCH l_users INTO l_username; EXIT WHEN l_users%NOTFOUND; INSERT INTO MGMT_USER_CAS (grantee, job_id) VALUES (l_username, p_guid_in); END LOOP; CLOSE l_users; BEGIN INSERT INTO MGMT_USER_CAS (grantee, job_id) VALUES (p_owner_in, p_guid_in); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN NULL; END; ELSIF p_scope_in = CA_SCOPE_TEMPLATE_COPY THEN l_users := GET_VIEW_TEMPLATE_USERS(p_template_guid_in); LOOP FETCH l_users INTO l_username; EXIT WHEN l_users%NOTFOUND; INSERT INTO MGMT_USER_CAS (grantee, job_id) VALUES (l_username, p_guid_in); END LOOP; CLOSE l_users; BEGIN INSERT INTO MGMT_USER_CAS (grantee, job_id) VALUES (p_owner_in, p_guid_in); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN NULL; END; ELSIF p_scope_in = CA_SCOPE_TARGET_TYPE THEN -- Only super users have privileges on a target-type ca, -- and they bypass the cache tables NULL; ELSIF p_scope_in = CA_SCOPE_USER THEN INSERT INTO MGMT_USER_CAS (grantee, job_id) VALUES (p_owner_in, p_guid_in); END IF; END GRANT_CA_PRIVS; -- -- PURPOSE -- Convenience procedure to resolve target name type into the target GUID -- PROCEDURE GRANT_PRIV(grantee_in IN VARCHAR2, priv_name_in IN VARCHAR2, target_name_in IN VARCHAR2, target_type_in IN VARCHAR2, invalidate_in IN NUMBER DEFAULT 1) IS tguid RAW(16); BEGIN IF priv_name_in = VIEW_JOB OR priv_name_in = FULL_JOB THEN raise_application_error(MGMT_GLOBAL.INVALID_PRIVILEGE_ERR, MGMT_GLOBAL.INVALID_PRIVILEGE_ERR_M || priv_name_in||' for grant_priv by target_name, target_type'); END IF; BEGIN SELECT target_guid INTO tguid FROM MGMT_TARGETS WHERE target_name = target_name_in AND target_type = target_type_in; EXCEPTION WHEN OTHERS THEN raise_application_error(MGMT_GLOBAL.TARGET_DOES_NOT_EXIST_ERR, MGMT_GLOBAL.TARGET_DOES_NOT_EXIST_ERR_M || target_name_in || ' (' || target_type_in || ')'); END; GRANT_PRIV(grantee_in, priv_name_in, tguid, invalidate_in); END GRANT_PRIV; -- -- PURPOSE -- -- To revoke a privilege from a user or role -- -- PARAMETERS -- -- GRANTEE_IN - the name of the user or role -- PRIV_NAME_IN - the name of the privilege which must be one of the supplied -- privileges (see list at top) or else the name of an -- Integrator defined privilege that was added using CREATE_PRIV -- GUID_IN - target guid in the case of a target privilege -- target group guid in the case of target group privilege -- job guid in the case of job privilege -- NULL in the case of system privilege -- INVALIDATE_IN - Whether or not to invalidate current users of a role if -- the privileges is being assigned to a role. Defaults to 1 -- (invalidate). A zero value bypasses invalidation. -- -- NOTES -- -- The caller must have been granted a role with -- the WITH_ADMIN option to be able to revoke a privilege from the role. -- The caller must either be the owner or a super user to revoke privileges -- of type target, job, report or template. Job privileges do not apply -- to the job owner. -- PROCEDURE REVOKE_PRIV(grantee_in IN VARCHAR2, priv_name_in IN VARCHAR2, guid_in IN RAW DEFAULT NO_GUID, invalidate_in IN NUMBER DEFAULT 1) IS isrole NUMBER; isgroup BOOLEAN := FALSE; rcnt NUMBER; res NUMBER; gname VARCHAR2(256); oname VARCHAR2(256); uname VARCHAR2(256); pname VARCHAR2(30); deleted_pname VARCHAR2(30); l_view_user_name VARCHAR2(256); l_predicate NUMBER := -1; l_priv_type NUMBER := -1; l_affected_users SMP_EMD_STRING_ARRAY := SMP_EMD_STRING_ARRAY(); l_callback_type NUMBER := 0; --Audit l_target_name VARCHAR2(4000); l_target_type VARCHAR2(4000); l_target_priv VARCHAR2(4000); l_job_name VARCHAR2(4000); l_job_type VARCHAR2(4000); CURSOR callbacks IS SELECT callback FROM MGMT_USER_CALLBACKS WHERE type = PRIV_REVOKED_CALLBACK; BEGIN -- Remove extra spaces and convert to uppercase gname := UPPER(TRIM(grantee_in)); pname := UPPER(TRIM(priv_name_in)); uname := GET_CURRENT_EM_USER; SELECT priv_type INTO l_priv_type FROM MGMT_PRIVS WHERE priv_name = pname; isrole := IS_ROLE(gname); IF isrole = 1 THEN IF gname = PUBLIC_ROLE AND NOT IS_SUPER_USER AND HAS_PRIV(GET_CURRENT_EM_USER, SUPER_USER) = USER_DOES_NOT_HAVE_PRIV THEN raise_application_error(MGMT_GLOBAL.INVALID_GRANT_TO_PUBLIC_ERR, MGMT_GLOBAL.INVALID_GRANT_TO_PUBLIC_ERR_M); END IF; END IF; IF l_priv_type = SYSTEM_PRIVILEGE THEN -- Only a SUPER_USER can revoke the SUPER_USER privilege, and it cannot -- be revoked from the repository owner IF pname = SUPER_USER THEN -- Check that the caller has the SUPER_USER privilege IF IS_SUPER_USER = FALSE AND (HAS_PRIV(GET_CURRENT_EM_USER, SUPER_USER) = USER_DOES_NOT_HAVE_PRIV) THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || SUPER_USER); END IF; l_view_user_name := 'MGMT_VIEW'; -- Use this after fixing the circular dependency. -- MGMT_VIEW_PRIV.GET_VIEW_USER(l_view_user_name); -- Cannot revoke the SUPER_USER privilege from the repository owner, -- SYS or SYSTEM IF gname IN (GET_REPOSITORY_OWNER, l_view_user_name, 'SYS', 'SYSTEM') THEN raise_application_error(MGMT_GLOBAL.INVALID_PRIVILEGE_ERR, MGMT_GLOBAL.INVALID_PRIVILEGE_ERR_M || SUPER_USER); END IF; END IF; ELSIF l_priv_type IN (TARGET_PRIVILEGE, TARGET_GROUP_PRIVILEGE) THEN IF guid_in = NO_GUID THEN raise_application_error(MGMT_GLOBAL.INVALID_TARGET_ERR, 'Null target ID'); END IF; BEGIN SELECT owner, target_name, target_type INTO oname, l_target_name, l_target_type FROM mgmt_targets WHERE target_guid = guid_in; EXCEPTION WHEN OTHERS THEN raise_application_error(MGMT_GLOBAL.INVALID_TARGET_ERR, MGMT_GLOBAL.INVALID_TARGET_ERR_M || guid_in); END; -- Only owners and superusers can revoke target privileges IF uname <> oname THEN IF NOT IS_SUPER_USER AND HAS_PRIV(uname, SUPER_USER) <> USER_HAS_PRIV THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || SUPER_USER); END IF; END IF; --Audit revoke_priv TARGET_PRIVILEGE OR TARGET_GROUP_PRIVILEGE IF(l_priv_type = TARGET_PRIVILEGE) THEN l_target_priv := 'TARGET_PRIVILEGE'; ELSIF (l_priv_type = TARGET_GROUP_PRIVILEGE) THEN l_target_priv := 'TARGET_GROUP_PRIVILEGE'; END IF; mgmt_audit_log.audit_log(mgmt_audit_log.REVOKE_TARGET_PRIV, pname, l_target_priv, null, gname, l_target_name, l_target_type, oname); ELSIF l_priv_type = JOB_PRIVILEGE THEN IF guid_in = NO_GUID THEN raise_application_error(MGMT_GLOBAL.INVALID_JOB_ERR, 'Null job ID'); END IF; BEGIN SELECT job_owner, job_name, job_type INTO oname, l_job_name, l_job_type FROM mgmt_job WHERE job_id = guid_in; EXCEPTION WHEN OTHERS THEN raise_application_error(MGMT_GLOBAL.INVALID_JOB_ERR, guid_in); END; -- only job owners and superusers can revoke job privileges IF uname <> oname THEN IF HAS_PRIV(uname, SUPER_USER) <> USER_HAS_PRIV THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || priv_name_in); END IF; END IF; --Audit revoke_priv JOB_PRIVILEGE mgmt_audit_log.audit_log(mgmt_audit_log.REVOKE_JOB_PRIV, pname, 'JOB_PRIVILEGE', null, gname, l_job_name, l_job_type, oname); ELSIF l_priv_type = REPORT_PRIVILEGE THEN IF guid_in = NO_GUID THEN raise_application_error(MGMT_GLOBAL.REPORT_DOES_NOT_EXIST_ERR, 'Null report ID'); END IF; BEGIN SELECT owner INTO oname FROM mgmt_ip_report_def WHERE report_guid = guid_in; EXCEPTION WHEN OTHERS THEN raise_application_error(MGMT_GLOBAL.REPORT_DOES_NOT_EXIST_ERR, guid_in); END; -- Only owners and superusers can revoke report privileges IF uname <> oname THEN IF NOT IS_SUPER_USER AND HAS_PRIV(uname, SUPER_USER) <> USER_HAS_PRIV THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || SUPER_USER); END IF; END IF; ELSIF l_priv_type = TEMPLATE_PRIVILEGE THEN IF guid_in = NO_GUID THEN raise_application_error(MGMT_GLOBAL.TEMPLATE_DOES_NOT_EXIST_ERR, 'Null template ID'); END IF; BEGIN SELECT owner INTO oname FROM mgmt_templates WHERE template_guid = guid_in; EXCEPTION WHEN OTHERS THEN raise_application_error(MGMT_GLOBAL.TEMPLATE_DOES_NOT_EXIST_ERR, guid_in); END; -- Only owners and superusers can revoke template privileges IF uname <> oname THEN IF NOT IS_SUPER_USER AND HAS_PRIV(uname, SUPER_USER) <> USER_HAS_PRIV THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || SUPER_USER); END IF; END IF; END IF; BEGIN -- Check if there are indirect grants SELECT ref_count INTO rcnt FROM MGMT_PRIV_GRANTS WHERE grantee = gname AND priv_name = pname AND guid = guid_in; EXCEPTION WHEN NO_DATA_FOUND THEN raise_application_error(MGMT_GLOBAL.PRIV_DOES_NOT_EXIST_ERR, MGMT_GLOBAL.PRIV_DOES_NOT_EXIST_ERR_M || priv_name_in); END; --Audit revoke_priv SYSTEM_PRIVILEGE IF(l_priv_type = SYSTEM_PRIVILEGE) THEN mgmt_audit_log.audit_log(mgmt_audit_log.REVOKE_SYSTEM_PRIV, pname, 'SYSTEM_PRIVILEGE', null, gname); END IF; IF rcnt > 0 THEN -- Update the direct_grant column UPDATE MGMT_PRIV_GRANTS SET direct_grant = 0 WHERE grantee = gname AND priv_name = pname AND guid = guid_in; ELSE -- Delete the privilege DELETE FROM MGMT_PRIV_GRANTS WHERE grantee = gname AND priv_name = pname AND guid = guid_in AND direct_grant = 1; END IF; -- If this is a revoke from a user rather than a role IF invalidate_in = 1 THEN IF isrole = 0 THEN IF l_priv_type = JOB_PRIVILEGE THEN l_predicate := EM_JOB_PREDICATE; ELSIF l_priv_type = TEMPLATE_PRIVILEGE THEN UPDATE MGMT_USER_CONTEXT SET value = CREATE_PREDICATE WHERE client_identifier = gname AND attribute = EM_CA_PREDICATE; l_predicate := EM_TEMPLATE_PREDICATE; ELSIF l_priv_type = REPORT_PRIVILEGE THEN l_predicate := EM_REPORT_DEF_PREDICATE; ELSE UPDATE MGMT_USER_CONTEXT SET value = CREATE_PREDICATE WHERE client_identifier = gname AND attribute = EM_CA_PREDICATE; l_predicate := EM_TARGET_PREDICATE; END IF; UPDATE MGMT_USER_CONTEXT SET value = CREATE_PREDICATE WHERE client_identifier = gname AND attribute = l_predicate; ELSE -- Get the list of user's who have been granted this role and -- invalidate their contexts INVALIDATE_USERS(gname); END IF; END IF; -- Execute the callbacks only if the privilege is OPERATOR or FULL -- and the user is not a well known super user since they have access -- to all targets. The only place currently using this callback is the -- blackout code so optimize for that IF gname IN (GET_REPOSITORY_OWNER, 'SYS', 'SYSTEM') OR pname NOT IN (MAINTAIN_TARGET, OPERATOR_TARGET, FULL_TARGET, SUPER_USER) THEN RETURN; END IF; -- For a role grant, get the list of affected users IF isrole = 1 THEN SELECT DISTINCT grantee BULK COLLECT INTO l_affected_users FROM MGMT_ROLE_GRANTS WHERE grantee_is_role = 0 AND grantee NOT IN (GET_REPOSITORY_OWNER, 'SYS', 'SYSTEM') AND (role_name = gname OR role_name IN (SELECT role_grantee FROM MGMT_FLAT_ROLE_GRANTS WHERE role_name = gname)); IF l_affected_users IS NULL OR l_affected_users.COUNT = 0 THEN RETURN; END IF; l_callback_type := ROLE_REVOKED_PRIV_CALLBACK; ELSE l_affected_users.extend; l_affected_users(1) := gname; l_callback_type := USER_REVOKED_PRIV_CALLBACK; END IF; FOR c IN callbacks LOOP BEGIN EXECUTE IMMEDIATE 'CALL ' || EM_CHECK.QUALIFIED_SQL_NAME(c.callback) || '(:users, :privs, :tguids, :op)' USING l_affected_users, SMP_EMD_STRING_ARRAY(pname), MGMT_USER_GUID_ARRAY(guid_in), l_callback_type; EXCEPTION WHEN OTHERS THEN mgmt_log.log_error(MGMT_USER.USERMODEL_MODULE_NAME, MGMT_GLOBAL.CALLBACK_FAILED_ERR, 'REVOKE_PRIV ' || MGMT_GLOBAL.CALLBACK_FAILED_ERR_M || c.callback || ': ' || SQLERRM); END; END LOOP; END REVOKE_PRIV; -- -- PURPOSE -- Convenience procedure to resolve target name type into the target GUID -- PROCEDURE REVOKE_PRIV(grantee_in IN VARCHAR2, priv_name_in IN VARCHAR2, target_name_in IN VARCHAR2, target_type_in IN VARCHAR2, invalidate_in IN NUMBER DEFAULT 1) IS tguid RAW(16); BEGIN IF priv_name_in = VIEW_JOB OR priv_name_in = FULL_JOB THEN raise_application_error(MGMT_GLOBAL.INVALID_PRIVILEGE_ERR, MGMT_GLOBAL.INVALID_PRIVILEGE_ERR_M || priv_name_in||' for revoke_priv by target_name, target_type'); END IF; BEGIN SELECT target_guid INTO tguid FROM MGMT_TARGETS WHERE target_name = target_name_in AND target_type = target_type_in; EXCEPTION WHEN OTHERS THEN raise_application_error(MGMT_GLOBAL.TARGET_DOES_NOT_EXIST_ERR, MGMT_GLOBAL.TARGET_DOES_NOT_EXIST_ERR_M || target_name_in || ' (' || target_type_in || ')'); END; REVOKE_PRIV(grantee_in, priv_name_in, tguid, invalidate_in); END REVOKE_PRIV; -- -- PURPOSE -- -- To grant a role to a user or another role -- -- PARAMETERS -- -- GRANTEE_IN - the name of the user or role -- ROLE_NAME_IN - the name of the role to grant -- WITH_ADMIN_IN - flag to indicate whether the role is to be granted -- allowing the grantee the ability to modify it and grant it -- to other users -- -- NOTES -- -- The caller must have already been granted the role with the -- WITH ADMIN flag set -- PROCEDURE GRANT_ROLE(grantee_in IN VARCHAR2, role_name_in IN VARCHAR2, with_admin_in IN NUMBER DEFAULT 0, invalidate_in IN NUMBER DEFAULT 1) IS isrole NUMBER; gname VARCHAR2(256); rname VARCHAR2(30); uname VARCHAR2(256); res NUMBER; got_privs BOOLEAN := FALSE; privs SMP_EMD_STRING_ARRAY := SMP_EMD_STRING_ARRAY(); guids MGMT_USER_GUID_ARRAY := MGMT_USER_GUID_ARRAY(); l_affected_users SMP_EMD_STRING_ARRAY := SMP_EMD_STRING_ARRAY(); l_callback_type NUMBER := 0; CURSOR priv_callbacks IS SELECT callback FROM MGMT_USER_CALLBACKS WHERE type = PRIV_GRANTED_CALLBACK; BEGIN -- Remove extra spaces and convert to uppercase gname := UPPER(TRIM(grantee_in)); rname := UPPER(TRIM(role_name_in)); IF gname = rname THEN raise_application_error(MGMT_GLOBAL.CIRCULAR_ROLE_ERR, MGMT_GLOBAL.CIRCULAR_ROLE_ERR_M); END IF; isrole := IS_ROLE(gname); IF isrole = 1 THEN -- Only super users can grant privileges to the PUBLIC role IF isrole = 1 AND gname = PUBLIC_ROLE AND NOT IS_SUPER_USER AND HAS_PRIV(GET_CURRENT_EM_USER, SUPER_USER) = USER_DOES_NOT_HAVE_PRIV THEN raise_application_error(MGMT_GLOBAL.INVALID_GRANT_TO_PUBLIC_ERR, MGMT_GLOBAL.INVALID_GRANT_TO_PUBLIC_ERR_M); END IF; -- Check if this user has been granted the role with the WITH_ADMIN -- flag set IF HAS_ROLE(GET_CURRENT_EM_USER, gname, 1) = USER_DOES_NOT_HAVE_ROLE THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || grantee_in || '/WITH_ADMIN'); END IF; -- Make sure the user already has the role that is being granted and has it -- with the WITH_ADMIN option res := HAS_ROLE(GET_CURRENT_EM_USER, rname, 1); IF res = NO_SUCH_ROLE THEN raise_application_error(MGMT_GLOBAL.ROLE_DOES_NOT_EXIST_ERR, MGMT_GLOBAL.ROLE_DOES_NOT_EXIST_ERR_M || role_name_in); ELSIF res = USER_DOES_NOT_HAVE_ROLE THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || role_name_in); END IF; -- Make sure this is not a circular role IF HAS_ROLE(rname, gname) = USER_HAS_ROLE THEN raise_application_error(MGMT_GLOBAL.CIRCULAR_ROLE_ERR, MGMT_GLOBAL.CIRCULAR_ROLE_ERR_M); END IF; ELSE -- Make sure the user is valid IF NOT G_CREATING_USER THEN BEGIN SELECT user_name INTO uname FROM MGMT_CREATED_USERS WHERE user_name = gname; EXCEPTION WHEN NO_DATA_FOUND THEN raise_application_error(MGMT_GLOBAL.USER_DOES_NOT_EXIST_ERR, MGMT_GLOBAL.USER_DOES_NOT_EXIST_ERR_M || gname); END; END IF; -- Check if this user has been granted the role with the WITH_ADMIN -- flag set res := HAS_ROLE(GET_CURRENT_EM_USER, rname, 1); IF res = NO_SUCH_ROLE THEN raise_application_error(MGMT_GLOBAL.ROLE_DOES_NOT_EXIST_ERR, MGMT_GLOBAL.ROLE_DOES_NOT_EXIST_ERR_M || role_name_in); ELSIF res = USER_DOES_NOT_HAVE_ROLE THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || role_name_in || '/WITH_ADMIN'); END IF; END IF; BEGIN --Audit grant_role mgmt_audit_log.audit_log(mgmt_audit_log.GRANT_ROLE, rname, null, null, gname); -- Grant the role INSERT INTO MGMT_ROLE_GRANTS (grantee, role_name, with_admin, grantee_is_role) VALUES (gname, rname, with_admin_in, isrole); EXCEPTION WHEN OTHERS THEN -- The role has already been granted IF SQLCODE = -1 THEN RETURN; ELSE raise_application_error(MGMT_GLOBAL.GRANT_FAILED_ERR, MGMT_GLOBAL.GRANT_FAILED_ERR_M || role_name_in || '. ' || SQLERRM); END IF; END; -- Update the flat table IF isrole = 1 THEN UPDATE_FLAT_ROLE_GRANTS(gname); END IF; -- Invalidate the affected user contexts IF invalidate_in = 1 THEN IF isrole = 0 THEN UPDATE MGMT_USER_CONTEXT SET value = CREATE_PREDICATE WHERE client_identifier = gname; ELSE -- Get the list of user's who have been granted this role and -- invalidate their contexts INVALIDATE_USERS(gname); END IF; END IF; -- Do not issue callback when creating a user or the user is not a well -- known super user since they have access to all targets. IF G_CREATING_USER OR gname IN (GET_REPOSITORY_OWNER, 'SYS', 'SYSTEM') THEN RETURN; END IF; -- Get the privs associated with the role including those privileges -- belonging to nested roles SELECT DISTINCT priv_name, guid BULK COLLECT INTO privs, guids FROM MGMT_PRIV_GRANTS WHERE (grantee = rname OR grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee = rname)) AND priv_name IN (FULL_TARGET, OPERATOR_TARGET, MAINTAIN_TARGET) AND direct_grant = 1; -- If there are no privileges then no need to issue callbacks IF privs IS NULL OR privs.COUNT = 0 THEN RETURN; END IF; -- If the grant is to a role then get all the affected users IF isrole = 1 THEN SELECT DISTINCT grantee BULK COLLECT INTO l_affected_users FROM MGMT_ROLE_GRANTS WHERE grantee_is_role = 0 AND grantee NOT IN (GET_REPOSITORY_OWNER, 'SYS', 'SYSTEM') AND (role_name = gname OR role_name IN (SELECT role_grantee FROM MGMT_FLAT_ROLE_GRANTS WHERE role_name = gname)); IF l_affected_users IS NULL OR l_affected_users.COUNT = 0 THEN RETURN; END IF; l_callback_type := ROLE_GRANTED_ROLE_CALLBACK; ELSE l_affected_users.extend; l_affected_users(1) := gname; l_callback_type := USER_GRANTED_ROLE_CALLBACK; END IF; -- This is a grant to a user FOR c IN priv_callbacks LOOP BEGIN EXECUTE IMMEDIATE 'CALL ' || EM_CHECK.QUALIFIED_SQL_NAME(c.callback) || '(:usernames, :privs, :targ_guids, :op)' USING l_affected_users, privs, guids, l_callback_type; EXCEPTION WHEN OTHERS THEN mgmt_log.log_error(MGMT_USER.USERMODEL_MODULE_NAME, MGMT_GLOBAL.CALLBACK_FAILED_ERR, 'GRANT_ROLE ' || MGMT_GLOBAL.CALLBACK_FAILED_ERR_M || c.callback || ': ' || SQLERRM); END; END LOOP; END GRANT_ROLE; -- -- PURPOSE -- -- To grant bulk roles to a user or another role -- -- PARAMETERS -- -- p_grantee - the name of the user or role -- p_roles - list of roles to be assigned -- -- NOTES -- -- The caller must have already been granted the role with the WITH ADMIN -- flag set -- PROCEDURE GRANT_ROLES ( p_grantee IN VARCHAR2, p_roles IN MGMT_SHORT_STRING_ARRAY) IS BEGIN IF (p_roles IS NOT NULL AND p_roles.COUNT > 0) AND p_grantee IS NOT NULL THEN FOR i IN 1.. p_roles.COUNT LOOP GRANT_ROLE( grantee_in=>p_grantee, role_name_in => p_roles(i), with_admin_in => 0, invalidate_in => 1); END LOOP; END IF; END GRANT_ROLES; -- -- PURPOSE -- -- To revoke a role from a user or another role -- -- PARAMETERS -- -- GRANTEE_IN - the name of the user or role -- ROLE_NAME_IN - the name of the role which can be one of the -- pre-defined roles, SECURITY_ADMIN or TARGET_GROUP_ADMIN -- NOTES -- -- The caller must have been granted the role with the -- WITH ADMIN option if revoking the role from another role -- -- PROCEDURE REVOKE_ROLE(grantee_in IN VARCHAR2, role_name_in IN VARCHAR2, invalidate_in IN NUMBER DEFAULT 1) IS isrole NUMBER; res NUMBER; gname VARCHAR2(256); rname VARCHAR2(30); deleted_rname VARCHAR2(30); privs SMP_EMD_STRING_ARRAY := SMP_EMD_STRING_ARRAY(); guids MGMT_USER_GUID_ARRAY := MGMT_USER_GUID_ARRAY(); l_affected_users SMP_EMD_STRING_ARRAY := SMP_EMD_STRING_ARRAY(); l_callback_type NUMBER := 0; CURSOR priv_callbacks IS SELECT callback FROM MGMT_USER_CALLBACKS WHERE type = PRIV_REVOKED_CALLBACK; BEGIN -- Remove extra spaces and convert to uppercase gname := UPPER(TRIM(grantee_in)); rname := UPPER(TRIM(role_name_in)); isrole := IS_ROLE(gname); IF isrole = 1 THEN IF gname = PUBLIC_ROLE AND NOT IS_SUPER_USER AND HAS_PRIV(GET_CURRENT_EM_USER, SUPER_USER) = USER_DOES_NOT_HAVE_PRIV THEN raise_application_error(MGMT_GLOBAL.INVALID_GRANT_TO_PUBLIC_ERR, MGMT_GLOBAL.INVALID_GRANT_TO_PUBLIC_ERR_M); END IF; -- Check if this user has been granted the role with the WITH_ADMIN -- flag set IF HAS_ROLE(GET_CURRENT_EM_USER, gname, 1) = USER_DOES_NOT_HAVE_ROLE THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || grantee_in || '/WITH_ADMIN'); END IF; ELSE -- Check that the caller has the role with the admin option -- revoking the role from another user IF gname <> GET_CURRENT_EM_USER THEN IF HAS_ROLE(GET_CURRENT_EM_USER, rname, 1) = USER_DOES_NOT_HAVE_ROLE THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || role_name_in || '/WITH_ADMIN'); END IF; END IF; -- Only a SUPER_USER can revoke a role from another SUPER_USER IF HAS_PRIV(gname, SUPER_USER) = USER_HAS_PRIV THEN IF IS_SUPER_USER = FALSE AND (HAS_PRIV(GET_CURRENT_EM_USER, SUPER_USER) = USER_DOES_NOT_HAVE_PRIV) THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || SUPER_USER); END IF; END IF; END IF; --Audit revoke_role mgmt_audit_log.audit_log(mgmt_audit_log.REVOKE_ROLE, rname, null, null, gname); -- Remove the role DELETE FROM MGMT_ROLE_GRANTS WHERE role_name = rname AND grantee = gname RETURNING role_name INTO deleted_rname; -- Make sure the role grant existed IF deleted_rname IS NULL THEN raise_application_error(MGMT_GLOBAL.ROLE_DOES_NOT_EXIST_ERR, MGMT_GLOBAL.ROLE_DOES_NOT_EXIST_ERR_M || role_name_in); END IF; -- Update the flat table IF isrole = 1 THEN UPDATE_FLAT_ROLE_GRANTS(gname); END IF; -- Invalidate the affected user contexts IF invalidate_in = 1 THEN IF isrole = 0 THEN UPDATE MGMT_USER_CONTEXT SET value = CREATE_PREDICATE WHERE client_identifier = gname; ELSE -- Get the list of user's who have been granted this role and -- invalidate their contexts INVALIDATE_USERS(gname); END IF; END IF; -- At the moment the blackout code is the only place using privilege revoke -- callbacks. The code checks to make sure the user having the privilege -- revoked still has OPERATOR on the target. Since Super Users will always -- have that privilege, there is no need to issue the callbacks. This -- may need to be removed in the future if callbacks are used more -- extensively IF gname IN (GET_REPOSITORY_OWNER, 'SYS', 'SYSTEM') THEN RETURN; END IF; -- Get the privs associated with the role including those privileges -- belonging to nested roles SELECT DISTINCT priv_name, guid BULK COLLECT INTO privs, guids FROM MGMT_PRIV_GRANTS WHERE (grantee = rname OR grantee IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee = rname)) AND priv_name IN (FULL_TARGET, OPERATOR_TARGET, MAINTAIN_TARGET) AND direct_grant = 1; IF privs IS NULL OR privs.COUNT = 0 THEN RETURN; END IF; IF isrole = 1 THEN SELECT DISTINCT grantee BULK COLLECT INTO l_affected_users FROM MGMT_ROLE_GRANTS WHERE grantee_is_role = 0 AND grantee NOT IN (GET_REPOSITORY_OWNER, 'SYS', 'SYSTEM') AND (role_name = gname OR role_name IN (SELECT role_grantee FROM MGMT_FLAT_ROLE_GRANTS WHERE role_name = gname)); IF l_affected_users IS NULL OR l_affected_users.COUNT = 0 THEN RETURN; END IF; l_callback_type := ROLE_REVOKED_ROLE_CALLBACK; ELSE l_affected_users.extend; l_affected_users(1) := gname; l_callback_type := USER_REVOKED_ROLE_CALLBACK; END IF; FOR c IN priv_callbacks LOOP BEGIN EXECUTE IMMEDIATE 'CALL ' || EM_CHECK.QUALIFIED_SQL_NAME(c.callback) || '(:usernames, :privs, :targ_guids, :op)' USING l_affected_users, privs, guids, l_callback_type; EXCEPTION WHEN OTHERS THEN mgmt_log.log_error(MGMT_USER.USERMODEL_MODULE_NAME, MGMT_GLOBAL.CALLBACK_FAILED_ERR, 'REVOKE_ROLE ' || MGMT_GLOBAL.CALLBACK_FAILED_ERR_M || c.callback || ': ' || SQLERRM); END; END LOOP; END REVOKE_ROLE; -- -- PURPOSE -- -- To revoke bulk roles from a user or another role -- -- PARAMETERS -- p_grantee - Name of user or role from which roles will be revoked -- p_roles - List of roles revokes from user or role -- -- NOTES -- -- The caller must have been granted the role with the WITH ADMIN option -- if revoking the role from another role -- -- PROCEDURE REVOKE_ROLES ( p_grantee IN VARCHAR2, p_roles IN MGMT_SHORT_STRING_ARRAY) IS BEGIN IF (p_roles IS NOT NULL AND p_roles.COUNT > 0) AND p_grantee IS NOT NULL THEN FOR i IN 1.. p_roles.COUNT LOOP REVOKE_ROLE( grantee_in=>p_grantee, role_name_in => p_roles(i), invalidate_in => 1); END LOOP; END IF; END REVOKE_ROLES; -- -- PURPOSE -- -- To get the list of available privileges of a given type -- -- PARAMETERS -- -- PRIV_TYPE_IN - the type of privilege -- 0 - SYSTEM -- 1 - TARGET -- 2 - TARGET_GROUP -- -1 - All privileges -- USER_DEFINED_IN - flag to indicate whether user defined privs should be -- returned. 0 => no, 1 => yes -- PRIVS_OUT - the privileges are returned here -- -- NOTES -- -- PROCEDURE GET_PRIVS(priv_type_in IN NUMBER, user_defined_in IN NUMBER, privs_out OUT SMP_EMD_STRING_ARRAY) IS BEGIN IF priv_type_in = -1 THEN SELECT priv_name BULK COLLECT INTO privs_out FROM MGMT_PRIVS; ELSE IF user_defined_in = 0 THEN SELECT priv_name BULK COLLECT INTO privs_out FROM MGMT_PRIVS WHERE priv_type = priv_type_in AND creator = ''; ELSE SELECT priv_name BULK COLLECT INTO privs_out FROM MGMT_PRIVS WHERE priv_type = priv_type_in AND creator <> ''; END IF; END IF; END GET_PRIVS; -- -- PURPOSE -- -- To get the list of available privileges of a given type for a particular -- user -- -- PARAMETERS -- -- USER_NAME_IN - the name of the user -- PRIV_TYPE_IN - the type of privilege -- 0 - SYSTEM -- 1 - TARGET -- 2 - TARGET_GROUP -- 3 - JOB -- -1 - All privileges -- USER_DEFINED_IN - flag to indicate whether user defined privs should be -- returned. 0 => no, 1 => yes -- PRIVS_OUT - the privileges are returned here -- -- NOTES -- -- PROCEDURE GET_USER_PRIVS(user_name_in IN VARCHAR2, priv_type_in IN NUMBER, user_defined_in IN NUMBER, privs_out OUT PRIVS_CURSOR) IS uname VARCHAR2(256); BEGIN uname := UPPER(user_name_in); IF priv_type_in = -1 THEN OPEN privs_out FOR SELECT up.priv_name, p.priv_type, DECODE(p.creator, '', 0, 1), t.target_name, t.target_type, up.guid, null, null FROM MGMT_PRIV_GRANTS up, MGMT_PRIVS p, MGMT_TARGETS t WHERE up.grantee = uname AND up.direct_grant=1 AND p.priv_name = up.priv_name AND priv_type <> JOB_PRIVILEGE AND up.guid = t.target_guid(+) UNION SELECT up.priv_name, p.priv_type, DECODE(p.creator, '', 0, 1), j.job_name, j.job_type, up.guid, j.job_owner, j.is_library FROM MGMT_PRIV_GRANTS up, MGMT_PRIVS p, MGMT_JOB j WHERE up.grantee = uname AND up.direct_grant=1 AND p.priv_name = up.priv_name AND p.priv_type = JOB_PRIVILEGE AND up.guid = j.job_id; ELSE IF user_defined_in = 0 THEN IF priv_type_in = JOB_PRIVILEGE THEN OPEN privs_out FOR SELECT up.priv_name, p.priv_type, 0, j.job_name, j.job_type, up.guid, j.job_owner, j.is_library FROM MGMT_PRIV_GRANTS up, MGMT_PRIVS p, MGMT_JOB j WHERE up.grantee = uname AND up.direct_grant=1 AND p.priv_name = up.priv_name AND p.creator = '' AND p.priv_type = JOB_PRIVILEGE AND up.guid = j.job_id; ELSE OPEN privs_out FOR SELECT up.priv_name, priv_type_in, 0, t.target_name, t.target_type, up.guid, null, null FROM MGMT_PRIV_GRANTS up, MGMT_PRIVS p, MGMT_TARGETS t WHERE up.grantee = uname AND up.direct_grant=1 AND p.priv_name = up.priv_name AND p.priv_type = priv_type_in AND p.creator = '' AND priv_type <> JOB_PRIVILEGE AND up.guid = t.target_guid(+); END IF; ELSE OPEN privs_out FOR SELECT up.priv_name, priv_type_in, 1, t.target_name, t.target_type, up.guid, null, null FROM MGMT_PRIV_GRANTS up, MGMT_PRIVS p, MGMT_TARGETS t WHERE up.grantee = uname AND up.direct_grant=1 AND p.priv_name = up.priv_name AND p.priv_type = priv_type_in AND p.creator <> '' AND priv_type <> JOB_PRIVILEGE AND up.guid = t.target_guid(+); END IF; END IF; END GET_USER_PRIVS; -- -- PURPOSE -- -- To get the list of available roles -- -- PARAMETERS -- -- ROLES_OUT - the roles are returned here -- -- NOTES -- -- The NAME component of the SMP_EMD_NVPAIR contains the name of the role -- and the VALUE component of the SMP_EMD_NVPAIR containst the description -- of the role -- PROCEDURE GET_ROLES(roles_out OUT ROLEDESC_CURSOR) IS BEGIN OPEN roles_out FOR SELECT role_name, description FROM MGMT_ROLES ORDER BY role_name; END GET_ROLES; -- -- PURPOSE -- -- To get the list of privileges of a given type for a particular role -- -- PARAMETERS -- -- ROLE_NAME_IN - the name of the role -- PRIV_TYPE_IN - the type of privilege -- 0 - SYSTEM -- 1 - TARGET -- 2 - TARGET_GROUP -- -1 - All privileges -- USER_DEFINED_IN - flag to indicate whether user defined privs should be -- returned. 0 => no, 1 => yes -- PRIVS_OUT - the privileges are returned here -- USER_NAMES_OUT - the list of users who have been granted the role -- -- NOTES -- -- PROCEDURE GET_ROLE_PRIVS(role_name_in IN VARCHAR2, priv_type_in IN NUMBER, user_defined_in IN NUMBER, privs_out OUT PRIVS_CURSOR, user_names_out OUT STRING_CURSOR) IS rname VARCHAR2(30); BEGIN rname := UPPER(role_name_in); -- Get the users who have been granted the role OPEN user_names_out FOR SELECT grantee FROM MGMT_ROLE_GRANTS WHERE role_name = rname AND grantee_is_role = 0; IF priv_type_in = -1 THEN OPEN privs_out FOR SELECT rp.priv_name, p.priv_type, DECODE(p.creator, '', 0, 1), t.target_name, t.target_type, rp.guid, null, null FROM MGMT_PRIV_GRANTS rp, MGMT_PRIVS p, MGMT_TARGETS t WHERE rp.grantee = rname AND rp.direct_grant=1 AND p.priv_name = rp.priv_name AND p.priv_type <> JOB_PRIVILEGE AND rp.guid = t.target_guid(+) UNION SELECT rp.priv_name, p.priv_type, DECODE(p.creator, '', 0, 1), j.job_name, j.job_type, rp.guid, j.job_owner, j.is_library FROM MGMT_PRIV_GRANTS rp, MGMT_PRIVS p, MGMT_JOB j WHERE rp.grantee = rname AND rp.direct_grant=1 AND p.priv_name = rp.priv_name AND p.priv_type = JOB_PRIVILEGE AND rp.guid = j.job_id; ELSE IF user_defined_in = 0 THEN IF priv_type_in = JOB_PRIVILEGE THEN OPEN privs_out FOR SELECT rp.priv_name, p.priv_type, 0, j.job_name, j.job_type, rp.guid, j.job_owner, j.is_library FROM MGMT_PRIV_GRANTS rp, MGMT_PRIVS p, MGMT_JOB j WHERE rp.grantee = rname AND rp.direct_grant=1 AND p.priv_name = rp.priv_name AND p.priv_type = JOB_PRIVILEGE AND rp.guid = j.job_id; ELSE OPEN privs_out FOR SELECT rp.priv_name, p.priv_type, 0, t.target_name, t.target_type, rp.guid, null, null FROM MGMT_PRIV_GRANTS rp, MGMT_PRIVS p, MGMT_TARGETS t WHERE rp.grantee = rname AND rp.direct_grant=1 AND p.priv_name = rp.priv_name AND p.priv_type <> JOB_PRIVILEGE AND p.creator = '' AND rp.guid = t.target_guid(+); END IF; ELSE OPEN privs_out FOR SELECT rp.priv_name, p.priv_type, 1, t.target_name, t.target_type, rp.guid, null, null FROM MGMT_PRIV_GRANTS rp, MGMT_PRIVS p, MGMT_TARGETS t WHERE rp.grantee = rname AND rp.direct_grant=1 AND p.priv_name = rp.priv_name AND p.priv_type <> JOB_PRIVILEGE AND p.creator <> '' AND rp.guid = t.target_guid(+); END IF; END IF; END GET_ROLE_PRIVS; -- -- PURPOSE -- -- To get the list of privileges and roles belonging to a role -- -- PARAMETERS -- -- ROLE_NAME_IN - the name of the roles -- PRIVS_OUT - the privileges are returned here -- ROLES_OUT - the roles are returned here -- -- NOTES -- -- If this procedure is used to get the list of permissions associated -- with a role for display in a UI then another call will have to be made -- to get the details of an included role i.e. this is not a flattened list -- PROCEDURE GET_ROLE_GRANTS(role_name_in IN VARCHAR2, privs_out OUT PRIVS_CURSOR, roles_out OUT STRING_CURSOR) IS rname VARCHAR2(30); BEGIN rname := UPPER(TRIM(role_name_in)); -- Get the privileges OPEN privs_out FOR SELECT rp.priv_name, p.priv_type, DECODE(p.creator, '', 0, 1), t.target_name, t.target_type, rp.guid, null, null FROM MGMT_PRIV_GRANTS rp, MGMT_PRIVS p, MGMT_TARGETS t WHERE rp.grantee = rname AND rp.direct_grant=1 AND p.priv_name = rp.priv_name AND p.priv_type <> JOB_PRIVILEGE AND rp.guid = t.target_guid(+) UNION SELECT rp.priv_name, p.priv_type, DECODE(p.creator, '', 0, 1), j.job_name, j.job_type, rp.guid, j.job_owner, j.is_library FROM MGMT_PRIV_GRANTS rp, MGMT_PRIVS p, MGMT_JOB j WHERE rp.grantee = rname AND rp.direct_grant=1 AND p.priv_name = rp.priv_name AND p.priv_type = JOB_PRIVILEGE AND rp.guid = j.job_id; -- Get the roles OPEN roles_out FOR SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = rname; END GET_ROLE_GRANTS; -- -- PURPOSE -- -- To get the list of users assigned a particular role -- -- PARAMETERS -- -- ROLE_NAME_IN - the name of the roles -- AVAILABLE_USERS_OUT - the users that are not currently granted the role are -- returned here -- GRANTED_USERS_OUT - the users that are currently granted the role are -- returned here -- -- NOTES -- PROCEDURE GET_ROLE_USERS(role_name_in IN VARCHAR2, available_users_out OUT STRING_CURSOR, granted_users_out OUT STRING_CURSOR) IS rname VARCHAR2(30); ok VARCHAR2(30); l_view_user_name VARCHAR2(256); BEGIN rname := UPPER(role_name_in); -- allow a null or empty rolename to return all non-superusers IF role_name_in IS NOT NULL and LENGTH(role_name_in) > 0 THEN BEGIN -- Make sure the role exists SELECT role_name INTO ok FROM MGMT_ROLES WHERE role_name = rname; EXCEPTION WHEN NO_DATA_FOUND THEN raise_application_error(MGMT_GLOBAL.ROLE_DOES_NOT_EXIST_ERR, MGMT_GLOBAL.ROLE_DOES_NOT_EXIST_ERR_M || role_name_in); END; END IF; l_view_user_name := 'MGMT_VIEW'; -- Use the following procedure after fixing the circular dependency -- MGMT_VIEW_PRIV.GET_VIEW_USER(l_view_user_name); OPEN available_users_out FOR SELECT user_name FROM mgmt_created_users WHERE user_name NOT IN (SELECT grantee FROM MGMT_PRIV_GRANTS WHERE priv_name = SUPER_USER) AND user_name <> GET_REPOSITORY_OWNER AND user_name <> l_view_user_name AND user_name NOT IN (SELECT grantee FROM MGMT_ROLE_GRANTS WHERE role_name = rname) ORDER BY user_name; -- Get the list of users who have this role excluding the package owner -- and all SUPER_USERs OPEN granted_users_out FOR SELECT grantee FROM MGMT_ROLE_GRANTS WHERE role_name = rname AND grantee_is_role = 0 AND grantee <> GET_REPOSITORY_OWNER AND grantee <> l_view_user_name AND grantee NOT IN (SELECT grantee FROM MGMT_PRIV_GRANTS WHERE priv_name = SUPER_USER) ORDER BY grantee; END GET_ROLE_USERS; -- -- PURPOSE -- -- To get the list of roles granted to a user -- -- PARAMETERS -- -- USER_NAME_IN - the name of the user -- ROLES_OUT - the roles are returned here -- -- NOTES -- -- PROCEDURE GET_USER_ROLES(user_name_in IN VARCHAR2, roles_out OUT STRING_CURSOR) IS uname VARCHAR2(256); BEGIN uname := UPPER(user_name_in); OPEN roles_out FOR SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname ORDER BY role_name; END GET_USER_ROLES; -- -- PURPOSE -- -- To get the list of roles currently granted to a role and the list of -- roles available for granting to that role -- -- PARAMETERS -- -- ROLE_NAME_IN - the name of the role -- AVAILABLE_ROLES_OUT - the roles available for granting to ROLE_NAME_IN -- are returned here -- GRANTED_ROLES_OUT - the roles currently granted to ROLE_NAME_IN are -- returned here -- -- NOTES -- PROCEDURE GET_ROLES_FOR_ROLE(role_name_in IN VARCHAR2, available_roles_out OUT STRING_CURSOR, granted_roles_out OUT STRING_CURSOR) IS rname VARCHAR2(30); BEGIN rname := UPPER(role_name_in); OPEN available_roles_out FOR SELECT role_name FROM (SELECT role_name FROM MGMT_ROLES WHERE -- Do not include the role itself role_name <> rname AND -- Do not include roles granted to the role itself role_name NOT IN (SELECT role_name FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee = rname) AND -- Do not include other roles that have the role granted to them role_name NOT IN (SELECT role_grantee FROM MGMT_FLAT_ROLE_GRANTS WHERE role_name = rname)) ORDER BY role_name; OPEN granted_roles_out FOR SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = rname; END GET_ROLES_FOR_ROLE; -- -- PURPOSE -- -- To get the list of targets that this role has FULL_TARGET privilege on -- -- PARAMETERS -- -- ROLE_NAME_IN - the name of the role -- TARGETS_OUT - the distinct array of targets that have privileges granted -- on them by this role. -- -- NOTES -- PROCEDURE GET_TARGETS_FOR_ROLE(role_name_in IN VARCHAR2, targets_out OUT TARGETS_CURSOR) IS rname VARCHAR2(30); BEGIN rname := UPPER(role_name_in); OPEN targets_out FOR SELECT target_name, target_type FROM MGMT_TARGETS WHERE target_guid IN (SELECT DISTINCT guid FROM MGMT_PRIV_GRANTS WHERE grantee = rname AND priv_name = FULL_TARGET); END GET_TARGETS_FOR_ROLE; -- -- PURPOSE -- -- To get the list of targets on which a user has been granted FULL_TARGET -- privilege -- -- PARAMETERS -- -- USER_NAME_IN - the name of the user -- TARGETS_OUT - the distinct array of targets that the user has been granted -- privileges on -- -- NOTES -- PROCEDURE GET_TARGETS_FOR_USER(user_name_in IN VARCHAR2, targets_out OUT TARGETS_CURSOR) IS uname VARCHAR2(256); BEGIN uname := UPPER(user_name_in); OPEN targets_out FOR SELECT target_name, target_type FROM MGMT_TARGETS WHERE target_guid IN (SELECT DISTINCT guid FROM MGMT_PRIV_GRANTS WHERE grantee = uname AND priv_name = FULL_TARGET); END GET_TARGETS_FOR_USER; -- -- PURPOSE -- -- To get the list of privileges for each target with an flag to indicate -- whether : -- -- * Privilege not granted to any of the roles passed in, or to the caller of -- the procedure -- * Privilege granted to caller of the procedure and not granted to any of -- the roles passed in -- * Privilege granted to any of the roles passed in -- -- PARAMETERS -- -- ROLES_IN - the roles to check -- TARGETS_IN - the list of target_guids -- PRIVS_OUT - a cursor returning: -- target_guid -- target_privilege -- privilege_state (one of the three states listed above -- -- NOTES -- -- The privilege state can be : -- 1 => GRANTED TO CALLER -- 2 => GRANTED TO ROLE -- -- PROCEDURE GET_TARGET_PRIVS(roles_in IN SMP_EMD_STRING_ARRAY, targets_in IN MGMT_USER_GUID_ARRAY, privs_out OUT TARGET_PRIVS_CURSOR) IS uname VARCHAR2(256); cname VARCHAR2(30); roles SMP_EMD_STRING_ARRAY; ret NUMBER := 0; vat_grant NUMBER := 0; BEGIN uname := GET_CURRENT_EM_USER; -- Get the complete list of roles SELECT DISTINCT role_name BULK COLLECT INTO roles FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT * FROM TABLE(CAST(roles_in AS SMP_EMD_STRING_ARRAY))); -- If the user has the VIEW_ANY_TARGET privilege, then return -- VIEW_TARGET on all the targets ret := HAS_PRIV(uname, VIEW_ANY_TARGET); IF ret = USER_HAS_PRIV THEN BEGIN -- Check if the VIEW_ANY_TARGET was granted directly SELECT priv_name INTO cname FROM MGMT_PRIV_GRANTS WHERE grantee = uname AND priv_name = VIEW_ANY_TARGET AND ROWNUM < 2; vat_grant := 1; EXCEPTION WHEN NO_DATA_FOUND THEN vat_grant := 0; END; IF vat_grant > 0 THEN OPEN privs_out FOR SELECT * FROM (SELECT t.target_type, t.target_name, p.priv_name, DECODE(p.grantee_is_role, 0, 1, 1, 2) FROM MGMT_PRIV_GRANTS p, MGMT_TARGETS t WHERE p.direct_grant = 1 AND p.guid IN (SELECT * FROM TABLE(CAST(targets_in AS MGMT_USER_GUID_ARRAY))) AND (p.grantee = uname OR p.grantee IN (SELECT * FROM TABLE(CAST(roles AS SMP_EMD_STRING_ARRAY))) OR p.grantee IN (SELECT * FROM TABLE(CAST(roles_in AS SMP_EMD_STRING_ARRAY)))) AND t.target_guid = p.guid UNION SELECT tgt.target_type, tgt.target_name, VIEW_TARGET, 1 FROM MGMT_TARGETS tgt WHERE tgt.target_guid IN (SELECT * FROM TABLE(CAST(targets_in AS MGMT_USER_GUID_ARRAY))) ) ORDER BY target_type, target_name, priv_name; ELSE OPEN privs_out FOR SELECT * FROM (SELECT t.target_type, t.target_name, p.priv_name, DECODE(p.grantee_is_role, 0, 1, 1, 2) FROM MGMT_PRIV_GRANTS p, MGMT_TARGETS t WHERE p.direct_grant = 1 AND p.guid IN (SELECT * FROM TABLE(CAST(targets_in AS MGMT_USER_GUID_ARRAY))) AND (p.grantee = uname OR p.grantee IN (SELECT * FROM TABLE(CAST(roles AS SMP_EMD_STRING_ARRAY))) OR p.grantee IN (SELECT * FROM TABLE(CAST(roles_in AS SMP_EMD_STRING_ARRAY)))) AND t.target_guid = p.guid UNION SELECT tgt.target_type, tgt.target_name, VIEW_TARGET, 2 FROM MGMT_TARGETS tgt WHERE tgt.target_guid IN (SELECT * FROM TABLE(CAST(targets_in AS MGMT_USER_GUID_ARRAY))) ) ORDER BY target_type, target_name, priv_name; END IF; ELSE OPEN privs_out FOR SELECT t.target_type, t.target_name, p.priv_name, DECODE(p.grantee_is_role, 0, 1, 1, 2) FROM MGMT_PRIV_GRANTS p, MGMT_TARGETS t WHERE p.direct_grant = 1 AND p.guid IN (SELECT * FROM TABLE(CAST(targets_in AS MGMT_USER_GUID_ARRAY))) AND (p.grantee = uname OR p.grantee IN (SELECT * FROM TABLE(CAST(roles AS SMP_EMD_STRING_ARRAY))) OR p.grantee IN (SELECT * FROM TABLE(CAST(roles_in AS SMP_EMD_STRING_ARRAY)))) AND t.target_guid = p.guid ORDER BY target_type, target_name, priv_name; END IF; END GET_TARGET_PRIVS; -- PURPOSE -- -- To get the max privilege a user has on any target. This will not include -- user defined privilege. The privilege can be granted the privilege -- directly, via a role, via a nested role or via a group privilege. -- -- PARAMETERS -- -- USER_NAME_IN - the name of the user -- FUNCTION GET_MAX_PRIV_INTERNAL(uname IN VARCHAR2) RETURN VARCHAR2 IS max_p NUMBER := 0; roles SMP_EMD_STRING_ARRAY; BEGIN -- Check if the user is a SUPER_USER IF HAS_PRIV(uname, SUPER_USER) = USER_HAS_PRIV THEN RETURN FULL_TARGET; END IF; -- Get the roles granted to the user SELECT role_name BULK COLLECT INTO roles FROM MGMT_FLAT_ROLE_GRANTS WHERE role_grantee IN (SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname) UNION SELECT role_name FROM MGMT_ROLE_GRANTS WHERE grantee = uname; SELECT MAX (DECODE (priv_name, VIEW_TARGET, 1, CLONE_FROM_TARGET, 2, OPERATOR_TARGET, 3, MAINTAIN_TARGET, 4, FULL_TARGET, 5, 0)) INTO max_p FROM MGMT_PRIV_GRANTS WHERE (grantee = uname OR grantee IN (SELECT * FROM TABLE(CAST(roles AS SMP_EMD_STRING_ARRAY)))) AND guid > NO_GUID; IF max_p = 0 OR max_p IS NULL THEN IF HAS_PRIV(uname, VIEW_ANY_TARGET) = USER_HAS_PRIV THEN RETURN VIEW_TARGET; END IF; IF HAS_PRIV(uname, EM_MONITOR) = USER_HAS_PRIV THEN RETURN VIEW_TARGET; END IF; RETURN NULL; ELSIF max_p = 1 THEN RETURN VIEW_TARGET; ELSIF max_p = 2 THEN RETURN CLONE_FROM_TARGET; ELSIF max_p = 3 THEN RETURN OPERATOR_TARGET; ELSIF max_p = 4 THEN RETURN MAINTAIN_TARGET; ELSIF max_p = 5 THEN RETURN FULL_TARGET; END IF; RETURN NULL; END GET_MAX_PRIV_INTERNAL; -- -- PURPOSE -- -- To get the max privilege a user has on any target. This will not include -- user defined privilege. The privilege can be granted the privilege -- directly, via a role, via a nested role or via a group privilege. -- -- PARAMETERS -- -- USER_NAME_IN - the name of the user -- -- NOTES -- -- Can only be called by a user with the SUPER_USER privilege -- FUNCTION GET_MAX_PRIV(user_name_in IN VARCHAR2) RETURN VARCHAR2 IS uname VARCHAR2(256); BEGIN -- The caller has to be a SUPER_USER IF NOT IS_SUPER_USER AND HAS_PRIV(GET_CURRENT_EM_USER, SUPER_USER) = USER_DOES_NOT_HAVE_PRIV THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M || SUPER_USER); END IF; uname := UPPER(user_name_in); RETURN GET_MAX_PRIV_INTERNAL(uname); END GET_MAX_PRIV; -- -- PURPOSE -- -- To get the max privilege the current user has on any target. This will not -- include user defined privilege. The privilege can be granted the privilege -- directly, via a role, via a nested role or via a group privilege. -- FUNCTION GET_MAX_PRIV RETURN VARCHAR2 IS BEGIN RETURN GET_MAX_PRIV_INTERNAL(GET_CURRENT_EM_USER); END GET_MAX_PRIV; -- -- PURPOSE -- -- To set the predicate for the current user PROCEDURE SET_PREDICATE(predicate_type IN NUMBER) IS l_is_super NUMBER; l_has_view_any NUMBER; l_has_em_monitor NUMBER; BEGIN IF predicate_type = EM_TARGET_PREDICATE THEN -- This implicitly checks for SUPER_USER l_has_view_any := HAS_PRIV(GET_CURRENT_EM_USER, VIEW_ANY_TARGET); -- If the user does not have the VIEW_ANY_TARGET privilege then check if -- the user has the EM_MONITOR privilege IF l_has_view_any = USER_HAS_PRIV THEN DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_TARGET, ''); ELSE l_has_em_monitor := HAS_PRIV(GET_CURRENT_EM_USER, EM_MONITOR); IF l_has_em_monitor = USER_HAS_PRIV THEN DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_TARGET, G_TARGET_EM_MON_PREDICATE); ELSE DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_TARGET, G_TARGET_PRIV_PREDICATE); END IF; END IF; RETURN; END IF; -- All the following depend on the user being a super user or not l_is_super := HAS_PRIV(GET_CURRENT_EM_USER, SUPER_USER); IF predicate_type = EM_JOB_PREDICATE THEN IF l_is_super = USER_HAS_PRIV THEN DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_JOB, ''); ELSE DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_JOB, G_JOB_PRIV_PREDICATE); END IF; ELSIF predicate_type = EM_TEMPLATE_PREDICATE THEN IF l_is_super = USER_HAS_PRIV THEN DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_TEMPLATE, ''); ELSE DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_TEMPLATE, G_TEMPLATE_PRIV_PREDICATE); END IF; ELSIF predicate_type = EM_REPORT_DEF_PREDICATE THEN IF l_is_super = USER_HAS_PRIV THEN DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_REPORT_DEF, ''); DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_ST_REPORT, ''); ELSE DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_REPORT_DEF, G_REPORT_DEF_PRIV_PREDICATE); DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_ST_REPORT, G_ST_REPORT_PRIV_PREDICATE); END IF; ELSIF predicate_type = EM_CA_PREDICATE THEN IF l_is_super = USER_HAS_PRIV THEN DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_CA, ''); ELSE DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_CA, G_CA_PRIV_PREDICATE); END IF; END IF; END SET_PREDICATE; -- -- PURPOSE -- -- To generate a security policy for a user accessing the MGMT_TARGETS table -- FUNCTION EM47455450524544494341544554(p_schema IN VARCHAR2, p_object in VARCHAR2) RETURN VARCHAR2 IS uname VARCHAR2(256); predicate NUMBER := CREATE_PREDICATE; BEGIN -- Check if this is as a result of the GET_REPOSITORY_TARGETS call in -- SET_TARGET_LIST IF G_RECURSIVE_TARGET_VPD THEN return SYS_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_TARGET); END IF; uname := GET_CURRENT_EM_USER; BEGIN SELECT /*+ INDEX (MGMT_USER_CONTEXT MGMT_USER_CONTEXT_PK) */ value INTO predicate FROM MGMT_USER_CONTEXT WHERE client_identifier = uname AND attribute = EM_TARGET_PREDICATE; EXCEPTION WHEN NO_DATA_FOUND THEN predicate := CREATE_PREDICATE; END; IF predicate = CREATE_PREDICATE THEN SETEMUSERCONTEXT(uname, OP_CREATE_TARGET_CONTEXT); END IF; return SYS_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_TARGET); END EM47455450524544494341544554; -- -- PURPOSE -- -- To generate a security policy for a user accessing the MGMT_JOB table -- FUNCTION EM4745545052454449434154454A(p_schema IN VARCHAR2, p_object in VARCHAR2) RETURN VARCHAR2 IS uname VARCHAR2(256); predicate NUMBER := CREATE_PREDICATE; BEGIN -- Check if this is as a result of the nested job check in SET_JOB_LIST IF G_RECURSIVE_JOB_VPD THEN return SYS_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_JOB); END IF; uname := GET_CURRENT_EM_USER; BEGIN SELECT /*+ INDEX (MGMT_USER_CONTEXT MGMT_USER_CONTEXT_PK) */ value INTO predicate FROM MGMT_USER_CONTEXT WHERE client_identifier = uname AND attribute = EM_JOB_PREDICATE; EXCEPTION WHEN NO_DATA_FOUND THEN predicate := CREATE_PREDICATE; END; IF predicate = CREATE_PREDICATE THEN SETEMUSERCONTEXT(uname, OP_CREATE_JOB_CONTEXT); END IF; return SYS_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_JOB); END EM4745545052454449434154454A; -- -- PURPOSE -- -- To generate a security policy for a user accessing the MGMT_TEMPLATES table -- FUNCTION GET_TEMPLATE_PREDICATE(p_schema IN VARCHAR2, p_object in VARCHAR2) RETURN VARCHAR2 IS uname VARCHAR2(256); predicate NUMBER := CREATE_PREDICATE; BEGIN uname := GET_CURRENT_EM_USER; BEGIN SELECT /*+ INDEX (MGMT_USER_CONTEXT MGMT_USER_CONTEXT_PK) */ value INTO predicate FROM MGMT_USER_CONTEXT WHERE client_identifier = uname AND attribute = EM_TEMPLATE_PREDICATE; EXCEPTION WHEN NO_DATA_FOUND THEN predicate := CREATE_PREDICATE; END; IF predicate = CREATE_PREDICATE THEN SETEMUSERCONTEXT(uname, OP_CREATE_TEMPLATE_CONTEXT); END IF; return SYS_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_TEMPLATE); END GET_TEMPLATE_PREDICATE; -- -- PURPOSE -- -- To generate a security policy for a user accessing the MGMT_IP_REPORT_DEF -- table -- FUNCTION GET_REPORT_DEF_PREDICATE(p_schema IN VARCHAR2, p_object in VARCHAR2) RETURN VARCHAR2 IS uname VARCHAR2(256); predicate NUMBER := CREATE_PREDICATE; BEGIN uname := GET_CURRENT_EM_USER; BEGIN SELECT /*+ INDEX (MGMT_USER_CONTEXT MGMT_USER_CONTEXT_PK) */ value INTO predicate FROM MGMT_USER_CONTEXT WHERE client_identifier = uname AND attribute = EM_REPORT_DEF_PREDICATE; EXCEPTION WHEN NO_DATA_FOUND THEN predicate := CREATE_PREDICATE; END; IF predicate = CREATE_PREDICATE THEN SETEMUSERCONTEXT(uname, OP_CREATE_REPORT_DEF_CONTEXT); END IF; return SYS_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_REPORT_DEF); END GET_REPORT_DEF_PREDICATE; -- -- PURPOSE -- -- To generate a security policy for a user accessing the -- MGMT_IP_STORED_REPORT table -- FUNCTION GET_STORED_REPORT_PREDICATE(p_schema IN VARCHAR2, p_object in VARCHAR2) RETURN VARCHAR2 IS uname VARCHAR2(256); predicate NUMBER := CREATE_PREDICATE; BEGIN uname := GET_CURRENT_EM_USER; BEGIN SELECT /*+ INDEX (MGMT_USER_CONTEXT MGMT_USER_CONTEXT_PK) */ value INTO predicate FROM MGMT_USER_CONTEXT WHERE client_identifier = uname AND attribute = EM_REPORT_DEF_PREDICATE; EXCEPTION WHEN NO_DATA_FOUND THEN predicate := CREATE_PREDICATE; END; IF predicate = CREATE_PREDICATE THEN SETEMUSERCONTEXT(uname, OP_CREATE_REPORT_DEF_CONTEXT); END IF; return SYS_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_ST_REPORT); END GET_STORED_REPORT_PREDICATE; -- -- PURPOSE -- -- To generate a security policy for a user accessing the -- MGMT_CORRECTIVE_ACTION table -- FUNCTION GET_CA_PREDICATE(p_schema IN VARCHAR2, p_object in VARCHAR2) RETURN VARCHAR2 IS uname VARCHAR2(256); predicate NUMBER := CREATE_PREDICATE; BEGIN IF G_RECURSIVE_CA_VPD THEN RETURN SYS_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_CA); END IF; uname := GET_CURRENT_EM_USER; BEGIN SELECT /*+ INDEX (MGMT_USER_CONTEXT MGMT_USER_CONTEXT_PK) */ value INTO predicate FROM MGMT_USER_CONTEXT WHERE client_identifier = uname AND attribute = EM_CA_PREDICATE; EXCEPTION WHEN NO_DATA_FOUND THEN predicate := CREATE_PREDICATE; END; IF predicate = CREATE_PREDICATE THEN SETEMUSERCONTEXT(uname, OP_CREATE_CA_CONTEXT); END IF; RETURN SYS_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_CA); END GET_CA_PREDICATE; -- -- PURPOSE -- -- Sets the user context for EM, calculates the security predicate and -- builds caches of visible objects based on user's privilege set -- PROCEDURE SET_EM_USER_CONTEXT(em_client_in IN VARCHAR2, op_in IN INTEGER) IS tgt_predicate NUMBER := CREATE_PREDICATE; job_predicate NUMBER := CREATE_PREDICATE; template_predicate NUMBER := CREATE_PREDICATE; report_predicate NUMBER := CREATE_PREDICATE; ca_predicate NUMBER := CREATE_PREDICATE; em_client VARCHAR2(256); users SMP_EMD_STRING_ARRAY; uname VARCHAR2(256); BEGIN -- The only way to set the current user is via SETEMUSERCONTEXT on which -- only the repository owner should have execute permission. -- The procedure MGMT_USER.SET_EM_USER_CONTEXT cannot be called directly to -- set the current user. em_client := UPPER(em_client_in); -- If the context is being recreated then make sure the user is valid -- and has not been deleted IF op_in IN (OP_CREATE_TARGET_CONTEXT, OP_CREATE_JOB_CONTEXT, OP_CREATE_REPORT_DEF_CONTEXT, OP_CREATE_TEMPLATE_CONTEXT, OP_CREATE_CA_CONTEXT) THEN BEGIN SELECT user_name INTO uname FROM MGMT_CREATED_USERS WHERE user_name = em_client; EXCEPTION WHEN NO_DATA_FOUND THEN raise_application_error(MGMT_GLOBAL.USER_DOES_NOT_EXIST_ERR, MGMT_GLOBAL.USER_DOES_NOT_EXIST_ERR_M || em_client); END; END IF; IF op_in = OP_SET_IDENTIFIER THEN IF em_client = SYS_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_USER) THEN RETURN; ELSIF em_client IS NULL THEN -- Clear the EM client name DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_USER, NULL); ELSE -- Set the EM client name and clear the super user flag DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_USER, em_client); IS_SUPER_USER := FALSE; CURRENT_SUPER_USER := NULL; -- Check the predicates that have been set FOR p IN (SELECT /*+ INDEX (MGMT_USER_CONTEXT MGMT_USER_CONTEXT_PK) */ attribute, value FROM MGMT_USER_CONTEXT WHERE client_identifier = em_client) LOOP IF p.attribute = EM_TARGET_PREDICATE THEN tgt_predicate := p.value; ELSIF p.attribute = EM_JOB_PREDICATE THEN job_predicate := p.value; ELSIF p.attribute = EM_TEMPLATE_PREDICATE THEN template_predicate := p.value; ELSIF p.attribute = EM_REPORT_DEF_PREDICATE THEN report_predicate := p.value; ELSIF p.attribute = EM_CA_PREDICATE THEN ca_predicate := p.value; END IF; END LOOP; -- The above loop may not get all predicates so check them here IF tgt_predicate = ANY_PREDICATE THEN DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_TARGET, ''); ELSIF tgt_predicate = PRIV_PREDICATE THEN DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_TARGET, G_TARGET_PRIV_PREDICATE); ELSIF tgt_predicate = EM_MONITOR_PREDICATE THEN DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_TARGET, G_TARGET_EM_MON_PREDICATE); ELSE SET_PREDICATE(EM_TARGET_PREDICATE); END IF; IF job_predicate = ANY_PREDICATE THEN DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_JOB, ''); ELSIF job_predicate = PRIV_PREDICATE THEN DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_JOB, G_JOB_PRIV_PREDICATE); ELSE SET_PREDICATE(EM_JOB_PREDICATE); END IF; IF template_predicate = ANY_PREDICATE THEN DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_TEMPLATE, ''); ELSIF template_predicate = PRIV_PREDICATE THEN DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_TEMPLATE, G_TEMPLATE_PRIV_PREDICATE); ELSE SET_PREDICATE(EM_TEMPLATE_PREDICATE); END IF; IF report_predicate = ANY_PREDICATE THEN DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_REPORT_DEF, ''); DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_ST_REPORT, ''); ELSIF report_predicate = PRIV_PREDICATE THEN DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_REPORT_DEF, G_REPORT_DEF_PRIV_PREDICATE); DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_ST_REPORT, G_ST_REPORT_PRIV_PREDICATE); ELSE SET_PREDICATE(EM_REPORT_DEF_PREDICATE); END IF; IF ca_predicate = ANY_PREDICATE THEN DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_CA, ''); ELSIF ca_predicate = PRIV_PREDICATE THEN DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_CA, G_CA_PRIV_PREDICATE); ELSE SET_PREDICATE(EM_CA_PREDICATE); END IF; END IF; ELSIF op_in = OP_CREATE_TARGET_CONTEXT THEN -- If this is not part of a transaction then set up the list -- in an asynchronous transasction so it is available to other -- sessions IF DBMS_TRANSACTION.LOCAL_TRANSACTION_ID IS NULL THEN ASET_TARGET_LIST(em_client); ELSE SET_TARGET_LIST(em_client); END IF; ELSIF op_in = OP_CREATE_JOB_CONTEXT THEN -- If this is not part of a transaction then set up the list -- in an asynchronous transasction so it is available to other -- sessions IF DBMS_TRANSACTION.LOCAL_TRANSACTION_ID IS NULL THEN ASET_JOB_LIST(em_client); ELSE SET_JOB_LIST(em_client); END IF; ELSIF op_in = OP_CREATE_TEMPLATE_CONTEXT THEN -- If this is not part of a transaction then set up the list -- in an asynchronous transasction so it is available to other -- sessions IF DBMS_TRANSACTION.LOCAL_TRANSACTION_ID IS NULL THEN ASET_TEMPLATE_LIST(em_client); ELSE SET_TEMPLATE_LIST(em_client); END IF; ELSIF op_in = OP_CREATE_REPORT_DEF_CONTEXT THEN -- If this is not part of a transaction then set up the list -- in an asynchronous transasction so it is available to other -- sessions IF DBMS_TRANSACTION.LOCAL_TRANSACTION_ID IS NULL THEN ASET_REPORT_DEF_LIST(em_client); ELSE SET_REPORT_DEF_LIST(em_client); END IF; ELSIF op_in = OP_CREATE_CA_CONTEXT THEN -- If this is not part of a transaction then set up the list -- in an asynchronous transasction so it is available to other -- sessions IF DBMS_TRANSACTION.LOCAL_TRANSACTION_ID IS NULL THEN ASET_CA_LIST(em_client); ELSE SET_CA_LIST(em_client); END IF; ELSIF op_in = OP_INVALIDATE_TARGET_CONTEXT THEN UPDATE MGMT_USER_CONTEXT SET value = CREATE_PREDICATE WHERE client_identifier = em_client AND attribute = EM_TARGET_PREDICATE; ELSIF op_in = OP_INVALIDATE_JOB_CONTEXT THEN UPDATE MGMT_USER_CONTEXT SET value = CREATE_PREDICATE WHERE client_identifier = em_client AND attribute = EM_JOB_PREDICATE; ELSIF op_in = OP_INVALIDATE_TEMPLATE_CONTEXT THEN UPDATE MGMT_USER_CONTEXT SET value = CREATE_PREDICATE WHERE client_identifier = em_client AND attribute = EM_TEMPLATE_PREDICATE; ELSIF op_in = OP_INVALIDATE_REPORT_CONTEXT THEN UPDATE MGMT_USER_CONTEXT SET value = CREATE_PREDICATE WHERE client_identifier = em_client AND attribute = EM_REPORT_DEF_PREDICATE; ELSIF op_in = OP_INVALIDATE_CA_CONTEXT THEN UPDATE MGMT_USER_CONTEXT SET value = CREATE_PREDICATE WHERE client_identifier = em_client AND attribute = EM_CA_PREDICATE; ELSIF op_in = OP_CLEAR_IDENTIFIER THEN -- Clear the EM client name and unset the super user flag DBMS_SESSION.SET_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_USER, NULL); IS_SUPER_USER := FALSE; CURRENT_SUPER_USER := NULL; ELSIF op_in = OP_CLEAR_CONTEXT THEN IF IS_SUPER_USER and CURRENT_SUPER_USER = em_client THEN IS_SUPER_USER := FALSE; CURRENT_SUPER_USER := NULL; END IF; DELETE FROM MGMT_USER_CONTEXT WHERE client_identifier = em_client; DELETE FROM MGMT_USER_TARGETS WHERE grantee = em_client; DELETE FROM MGMT_USER_JOBS WHERE grantee = em_client; DELETE FROM MGMT_USER_REPORT_DEFS WHERE grantee = em_client; DELETE FROM MGMT_USER_CAS WHERE grantee = em_client; DELETE FROM MGMT_USER_TEMPLATES WHERE grantee = em_client; ELSIF op_in = OP_CLEAR_CONTEXTS THEN EXECUTE IMMEDIATE 'TRUNCATE TABLE MGMT_USER_CONTEXT'; EXECUTE IMMEDIATE 'TRUNCATE TABLE MGMT_USER_TARGETS'; EXECUTE IMMEDIATE 'TRUNCATE TABLE MGMT_USER_JOBS'; EXECUTE IMMEDIATE 'TRUNCATE TABLE MGMT_USER_REPORT_DEFS'; EXECUTE IMMEDIATE 'TRUNCATE TABLE MGMT_USER_TEMPLATES'; EXECUTE IMMEDIATE 'TRUNCATE TABLE MGMT_USER_CAS'; END IF; EXCEPTION WHEN OTHERS THEN IS_SUPER_USER := FALSE; CURRENT_SUPER_USER := NULL; raise; END SET_EM_USER_CONTEXT; FUNCTION GET_REPOSITORY_OWNER RETURN VARCHAR2 IS BEGIN RETURN G_REPOSITORY_OWNER; END GET_REPOSITORY_OWNER; -- Return the current *EM* user FUNCTION GET_CURRENT_EM_USER RETURN VARCHAR2 IS l_current_user VARCHAR2(256); BEGIN l_current_user := SYS_CONTEXT(EM_USER_CONTEXT, EM_USER_CONTEXT_USER); IF l_current_user IS NULL THEN SETEMUSERCONTEXT(USER, OP_SET_IDENTIFIER); RETURN USER; END IF; RETURN l_current_user; END GET_CURRENT_EM_USER; -- -- PURPOSE -- -- To return all nodes in the repository, and specify, for each node, -- whether there is at least one target on the node that the current user -- has the specified privilege on. -- -- INPUT PARAMETERS -- p_privilege The privilege to check for -- -- RETURN -- A cursor that lists the nodes that have at least -- one target that the user has the specified privilege on. This is a -- cursor with three columns: the host name, emd url, and the last -- time any data was uploaded from that emd -- -- NOTES -- FUNCTION GET_NODE_LIST_WITH_PRIVILEGE(p_privilege IN VARCHAR2) RETURN NODELIST_CURSOR IS l_tguids MGMT_USER_GUID_ARRAY; l_hosts_with_priv NODELIST_CURSOR; l_current_user VARCHAR2(256) := GET_CURRENT_EM_USER; BEGIN -- First, get a list of all targets that the user has the specified -- privilege on l_tguids := GET_TARGET_LIST(p_privilege); BEGIN -- We need to assume super-user privilege since the user may -- not be able to see the host itself SETEMUSERCONTEXT(MGMT_USER.GET_REPOSITORY_OWNER, OP_SET_IDENTIFIER); -- Open a cursor for a unique set of hosts that the targets are on. -- Filter out targets that do not have valid emd urls OPEN l_hosts_with_priv FOR SELECT /*+ INDEX(t) INDEX(t2) INDEX(tp) */ t.host_name, t.target_name emd_name, LOWER(t.emd_url) emd_url, MAX(ping.status) status, MAX(t2.last_load_time) last_load_time, MAX(tp.property_value) emd_version, SUM(DECODE(t2.broken_reason,0,1,0)) unbroken_targets, SUM(DECODE(t2.broken_reason,0,0,1)) broken_targets, MAX(ROUND(NVL(cpu.value, -1), 2)) total_cpu, MAX(NVL(mem.value, -1)) total_mem FROM mgmt_targets t, mgmt_targets t2, mgmt_target_properties tp, (SELECT /*+ INDEX(mc) */ mc.target_guid, mc.value FROM (SELECT metric_guid FROM mgmt_metrics WHERE target_type = 'oracle_emd' AND metric_name = 'ProcessInfo' AND metric_column = 'HostInfocpu') m_cpu, mgmt_current_metrics mc WHERE mc.metric_guid = m_cpu.metric_guid ) cpu, (SELECT /*+ INDEX(mc) */ mc.target_guid, mc.value FROM (SELECT metric_guid FROM mgmt_metrics WHERE target_type = 'oracle_emd' AND metric_name = 'ProcessInfo' AND metric_column = 'HostInfovsz') m_mem, mgmt_current_metrics mc WHERE mc.metric_guid = m_mem.metric_guid ) mem, mgmt_emd_ping ping WHERE t.target_type='oracle_emd' AND t.emd_url IS NOT NULL AND tp.target_guid=t.target_guid AND tp.property_name='Version' AND tp.property_type='INSTANCE' AND t.emd_url = t2.emd_url AND t.target_guid=cpu.target_guid (+) AND t.target_guid=mem.target_guid (+) AND t.target_guid=ping.target_guid (+) GROUP BY t.host_name, t.emd_url, t.target_name; SETEMUSERCONTEXT(l_current_user, OP_SET_IDENTIFIER); EXCEPTION WHEN OTHERS THEN SETEMUSERCONTEXT(l_current_user, OP_SET_IDENTIFIER); RAISE; END; RETURN l_hosts_with_priv; END; -- -- PURPOSE -- To invalidate the cached security contexts of all users that have -- been granted a role that has been modified -- PROCEDURE INVALIDATE_USERS(modified_role_name_in IN VARCHAR2) IS rname VARCHAR2(30); counter INTEGER := 0; BEGIN -- Remove extra spaces and convert to uppercase rname := UPPER(TRIM(modified_role_name_in)); /* FOR crec IN (SELECT DISTINCT grantee FROM MGMT_ROLE_GRANTS WHERE (grantee_is_role = 0 AND grantee <> GET_REPOSITORY_OWNER) AND (role_name = rname OR role_name IN (SELECT DISTINCT role_grantee FROM MGMT_FLAT_ROLE_GRANTS WHERE role_name = rname))) */ -- -- Modified the query for performance as fix of bug 4578684 -- FOR crec IN ( SELECT DISTINCT grantee FROM MGMT_ROLE_GRANTS g WHERE (grantee_is_role = 0 AND grantee <> GET_REPOSITORY_OWNER) AND role_name = rname UNION SELECT grantee FROM MGMT_ROLE_GRANTS g WHERE (grantee_is_role = 0 AND grantee <> GET_REPOSITORY_OWNER) AND EXISTS (SELECT DISTINCT role_grantee FROM MGMT_FLAT_ROLE_GRANTS f WHERE f.role_name = rname AND f.role_grantee = g.role_name) ) LOOP -- Invalidate all contexts UPDATE MGMT_USER_CONTEXT SET value = CREATE_PREDICATE WHERE client_identifier = crec.grantee; END LOOP; END INVALIDATE_USERS; -- -- PURPOSE -- -- To return the management privileges for the logged on user -- -- PARAMETERS -- -- SUPER_USER_OUT - true if the user is a superuser -- EMREP_USER_OUT - true if the user has access to the emrep target -- EMD_USER_OUT - true if the user has access to any emd target -- PROCEDURE GET_MGMT_PRIVS(super_user_out OUT INTEGER, emrep_user_out OUT INTEGER, emd_user_out OUT INTEGER, valid_em_user_out OUT INTEGER) IS uname VARCHAR2(256); counter INTEGER :=0; BEGIN uname := GET_CURRENT_EM_USER; -- First of all, check if the user is a valid EM user SELECT count(user_name) INTO counter FROM MGMT_CREATED_USERS WHERE user_name=upper(uname); IF counter = 0 THEN -- The user is not a valid EM user. super_user_out := MGMT_GLOBAL.G_FALSE; emrep_user_out := MGMT_GLOBAL.G_FALSE; emd_user_out := MGMT_GLOBAL.G_FALSE; valid_em_user_out := MGMT_GLOBAL.G_FALSE; RETURN; END IF; IF HAS_PRIV(uname, SUPER_USER) = USER_HAS_PRIV THEN -- Note: this covers database users such as SYS and SYSTEM super_user_out := MGMT_GLOBAL.G_TRUE; emrep_user_out := MGMT_GLOBAL.G_TRUE; emd_user_out := MGMT_GLOBAL.G_TRUE; valid_em_user_out := MGMT_GLOBAL.G_TRUE; ELSE super_user_out := MGMT_GLOBAL.G_FALSE; valid_em_user_out := MGMT_GLOBAL.G_TRUE; BEGIN SELECT 1 INTO counter FROM mgmt_targets WHERE target_type = MGMT_GLOBAL.G_REPOSITORY_TARGET_TYPE AND rownum < 2; emrep_user_out := MGMT_GLOBAL.G_TRUE; EXCEPTION WHEN NO_DATA_FOUND THEN emrep_user_out := MGMT_GLOBAL.G_FALSE; END; BEGIN SELECT 1 INTO counter FROM mgmt_targets WHERE target_type = MGMT_GLOBAL.G_AGENT_TARGET_TYPE AND rownum < 2; emd_user_out := MGMT_GLOBAL.G_TRUE; EXCEPTION WHEN NO_DATA_FOUND THEN emd_user_out := MGMT_GLOBAL.G_FALSE; END; END IF; END GET_MGMT_PRIVS; -- ============================================================================ -- a private util function to determine if element_in exists in array - -- element_array_in -- returns G_FALSE if the element does not exists, G_TRUE if it exists -- ============================================================================ FUNCTION element_exists (element_in IN VARCHAR2, element_array_in IN SMP_EMD_STRING_ARRAY) RETURN NUMBER IS BEGIN FOR i in 1..element_array_in.COUNT LOOP IF( element_in = element_array_in(i) ) THEN RETURN MGMT_GLOBAL.G_TRUE; END IF; END LOOP; RETURN MGMT_GLOBAL.G_FALSE; END element_exists; -- ============================================================================ -- a private util function to determine if element_in exists in array - -- element_array_in -- returns G_FALSE if the element does not exists, G_TRUE if it exists -- ============================================================================ FUNCTION element_exists (element_in IN VARCHAR2, element_array_in IN SMP_EMD_NVPAIR_ARRAY) RETURN NUMBER IS BEGIN FOR i in 1..element_array_in.COUNT LOOP IF( element_in = element_array_in(i).name ) THEN RETURN MGMT_GLOBAL.G_TRUE; END IF; END LOOP; RETURN MGMT_GLOBAL.G_FALSE; END element_exists; -- PURPOSE -- -- To update the pref email of the current user -- -- PARAMETERS -- user_name_in - the name of the user -- user_email_in - the new list of email addresses -- PROCEDURE UPDATE_USER_PREF_EMAIL( user_name_in IN VARCHAR2, user_email_in IN SMP_EMD_STRING_ARRAY ) IS l_email_format SMP_EMD_INTEGER_ARRAY := SMP_EMD_INTEGER_ARRAY(); BEGIN FOR i IN 1..user_email_in.COUNT LOOP l_email_format.extend(); -- use the existing format if the email address exists BEGIN SELECT type INTO l_email_format(i) FROM mgmt_notify_devices WHERE device_name = user_email_in(i) AND profile_name = user_name_in AND type IN (EMD_NOTIFICATION.SHORT_EMAIL_DEVICE_TYPE, EMD_NOTIFICATION.LONG_EMAIL_DEVICE_TYPE) AND device_name = email_address; EXCEPTION WHEN NO_DATA_FOUND THEN -- default to LONG format l_email_format(i) := 1; END; END LOOP; update_user_pref_email(user_name_in, user_email_in, l_email_format); END UPDATE_USER_PREF_EMAIL; -- PURPOSE -- -- To update the pref email (its format) of the current user -- -- PARAMETERS -- user_name_in - the name of the user -- user_email_in - the new list of email addresses -- user_email_format_in - the format of the new list of email addresses -- PROCEDURE UPDATE_USER_PREF_EMAIL ( user_name_in IN VARCHAR2, user_email_in IN SMP_EMD_STRING_ARRAY, user_email_format_in IN SMP_EMD_INTEGER_ARRAY ) IS l_send_email_rules SMP_EMD_STRING_ARRAY := SMP_EMD_STRING_ARRAY(); l_send_email_owners SMP_EMD_STRING_ARRAY := SMP_EMD_STRING_ARRAY(); CURSOR c_delete_email_addresses IS SELECT email_address FROM mgmt_notify_devices WHERE profile_name = user_name_in AND type IN (EMD_NOTIFICATION.SHORT_EMAIL_DEVICE_TYPE, EMD_NOTIFICATION.LONG_EMAIL_DEVICE_TYPE) AND device_name = email_address AND email_address NOT IN (SELECT * FROM TABLE(CAST(user_email_in AS SMP_EMD_STRING_ARRAY))); CURSOR c_send_email_rules IS SELECT rules.rule_name, rules.owner FROM mgmt_notify_rules rules WHERE EXISTS (SELECT notifyees.device_name FROM mgmt_notify_devices devices, mgmt_notify_notifyees notifyees WHERE devices.profile_name = user_name_in AND devices.device_name = notifyees.device_name AND devices.type IN (EMD_NOTIFICATION.LONG_EMAIL_DEVICE_TYPE, EMD_NOTIFICATION.SHORT_EMAIL_DEVICE_TYPE) AND notifyees.profile_name = user_name_in AND notifyees.owner = rules.owner AND notifyees.rule_name = rules.rule_name ); BEGIN -- get the rules with Send Email checked -- If a rule has any preferred email address, it means Send Email was -- checked when the rule was created or updated. OPEN c_send_email_rules; FETCH c_send_email_rules BULK COLLECT INTO l_send_email_rules, l_send_email_owners; CLOSE c_send_email_rules; -- update the user email addresses -- step 1: delete old email addresses not in the new list FOR delete_email IN c_delete_email_addresses LOOP emd_notification.delete_device(user_name_in, delete_email.email_address); END LOOP; -- step 2: add new email addresses (OK if it already exists) AND -- update the email format (type) FOR i IN 1..user_email_in.COUNT LOOP emd_notification.add_email_device(user_email_in(i), user_name_in, user_email_in(i), user_email_format_in(i)); -- update the email format (for those email addresses whose email formats -- were changed) emd_notification.edit_email_device(user_email_in(i), user_name_in, user_email_in(i), user_email_format_in(i)); -- add this email address to notifyee (OK if it already exists) FOR j IN 1..l_send_email_rules.COUNT LOOP BEGIN emd_notification.add_device_to_rule( l_send_email_rules(j), l_send_email_owners(j), user_email_in(i), user_name_in ); EXCEPTION WHEN DUP_VAL_ON_INDEX THEN -- ignore errors NULL; END; END LOOP; END LOOP; END UPDATE_USER_PREF_EMAIL; FUNCTION GET_SUBTAB_PREFS_ALIAS(user_name_in IN VARCHAR2, subtab_name_in IN VARCHAR2) RETURN VARCHAR2 AS user_name_alias mgmt_user_subtab_col_prefs.user_name%TYPE; BEGIN SELECT CASE WHEN EXISTS (SELECT 1 FROM mgmt_user_subtab_col_prefs WHERE user_name = user_name_in AND subtab_name = subtab_name_in) THEN user_name_in ELSE WILDCARD_USER_NAME_ALIAS END INTO user_name_alias FROM dual; RETURN user_name_alias; END GET_SUBTAB_PREFS_ALIAS; FUNCTION GET_METRIC_PREFS_ALIAS(user_name_in IN VARCHAR2, target_type_in IN VARCHAR2) RETURN VARCHAR2 AS BEGIN RETURN(get_subtab_prefs_alias(user_name_in, target_type_in)); END GET_METRIC_PREFS_ALIAS; -- PURPOSE -- -- Returns the Admin status of a user and the highest assigned privileges to a particular job. -- -- PARAMETERS -- job_id_in - the job_id -- user_name_in - the user name -- admin_out - either 'ADMIN' or 'SUPER' -- priv_out - either 'FULL_JOB', 'VIEW_JOB' or 'NONE' -- PROCEDURE GET_USER_JOB_PRIV (job_id_in IN RAW, user_name_in IN VARCHAR2, admin_out OUT VARCHAR2, priv_out OUT VARCHAR2) IS BEGIN IF job_id_in = NO_GUID THEN raise_application_error(MGMT_GLOBAL.INVALID_JOB_ERR, 'Null job ID'); END IF; IF has_priv(user_name_in, SUPER_USER, NO_GUID) = 1 THEN admin_out := 'SUPER'; ELSE admin_out := 'ADMIN'; END IF; IF has_priv(user_name_in, FULL_JOB, job_id_in) = 1 THEN priv_out := FULL_JOB; ELSE IF has_priv(user_name_in, VIEW_JOB, job_id_in) = 1 THEN priv_out := VIEW_JOB; ELSE priv_out := 'NONE'; END IF; END IF; END GET_USER_JOB_PRIV; -- PURPOSE -- -- To return a list of users and roles assigned the VIEW_REPORT privilege -- for a particular report. -- -- PARAMETERS -- report_id_in - the report_id -- owner_out - the name of the report owner -- grantees_out - a cursor - user/role name, type (ROLE,ADMIN) and -- privilege -- PROCEDURE GET_REPORT_GRANTS (report_id_in IN RAW, owner_out OUT VARCHAR2, grantees_out OUT GRANT_CURSOR) IS BEGIN IF report_id_in = NO_GUID THEN raise_application_error(MGMT_GLOBAL.INVALID_IP_REPORT_ERR, 'Null report ID'); END IF; BEGIN SELECT owner INTO owner_out FROM MGMT_IP_REPORT_DEF WHERE report_guid = report_id_in; EXCEPTION WHEN OTHERS THEN raise_application_error(MGMT_GLOBAL.IP_REPORT_DOES_NOT_EXIST_ERR, report_id_in); END; OPEN grantees_out FOR SELECT a.grantee, 'VIEW_REPORT', DECODE(a.grantee_is_role, 1, 'ROLE', 0, 'ADMIN') type FROM mgmt_priv_grants a WHERE a.priv_name = 'VIEW_REPORT' AND a.grantee != owner_out AND a.guid = report_id_in; END GET_REPORT_GRANTS; -- PURPOSE -- -- To revoke the VIEW_REPORT privilege for a particular report to -- any users that currently have that privilege -- for a particular report. -- -- PARAMETERS -- report_id_in - the report_id -- PROCEDURE REVOKE_VIEW_REPORT_ALL(report_id_in IN RAW, owner_in IN VARCHAR2) IS CURSOR grantee_cursor IS SELECT grantee FROM MGMT_PRIV_GRANTS WHERE guid = report_id_in AND priv_name = 'VIEW_REPORT' AND grantee != owner_in; grantee VARCHAR2(256) := ''; BEGIN FOR c IN grantee_cursor LOOP DBMS_OUTPUT.put_line('revoking VIEW_REPORT privilege from ' || c.grantee || ' for report guid ' || report_id_in); REVOKE_PRIV(c.grantee, VIEW_REPORT, report_id_in); END LOOP; REVOKE_PRIV(owner_in, VIEW_REPORT, report_id_in); END REVOKE_VIEW_REPORT_ALL; -- PURPOSE -- -- To modify privileges for a particular job. -- -- PARAMETERS -- job_id_in - IN the job_id -- replace_in - IN whether or not to replace the existing grants with the new set -- Valid values 'Y' 'N' - defaults to 'Y' -- grant_name_in - IN - an array of name/value grants. The first is the user or role -- name, the value is the privilege being granted (VIEW_JOB or FULL_JOB) -- PROCEDURE MODIFY_JOB_GRANTS (job_id_in IN RAW, replace_in IN VARCHAR2 DEFAULT 'Y', grant_name_in IN SMP_EMD_NVPAIR_ARRAY) IS l_name VARCHAR2(256); l_owner VARCHAR2(256); l_priv VARCHAR2(30); uname VARCHAR2(256); rcount NUMBER; BEGIN IF job_id_in = NO_GUID THEN raise_application_error(MGMT_GLOBAL.INVALID_JOB_ERR, 'Null job ID'); END IF; BEGIN SELECT job_owner INTO l_owner FROM mgmt_job WHERE job_id = job_id_in; EXCEPTION WHEN OTHERS THEN raise_application_error(MGMT_GLOBAL.INVALID_JOB_ERR, job_id_in); END; uname := GET_CURRENT_EM_USER; -- only the owner or superusers can grant privs IF uname <> l_owner THEN IF HAS_PRIV(uname, SUPER_USER, NO_GUID) <> USER_HAS_PRIV THEN raise_application_error(MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR, MGMT_GLOBAL.INSUFFICIENT_PRIVILEGES_ERR_M); END IF; END IF; IF replace_in = 'Y' THEN FOR pg IN (SELECT grantee, priv_name FROM MGMT_PRIV_GRANTS WHERE guid = job_id_in AND direct_grant = 1) LOOP BEGIN REVOKE_PRIV(pg.grantee, pg.priv_name, job_id_in, 1); EXCEPTION WHEN OTHERS THEN NULL; END; END LOOP; END IF; BEGIN FOR i IN 1..grant_name_in.COUNT LOOP l_name := grant_name_in(i).name; l_priv := grant_name_in(i).value; -- If this is the the owner, ignore the grant IF l_name <> l_owner THEN IF l_priv IS NOT NULL AND LENGTH(l_priv) > 0 THEN -- Revoke FULL if granting VIEW - but not the reverse since FULL grants VIEW IF l_priv = VIEW_JOB AND replace_in = 'N' THEN IF HAS_PRIV(l_name, FULL_JOB, job_id_in) = USER_HAS_PRIV THEN REVOKE_PRIV(l_name, FULL_JOB, job_id_in, 1); END IF; END IF; IF l_priv = FULL_JOB THEN -- disallow granting FULL_JOB to roles, and disallow SUPER that are not owner SELECT COUNT(role_name) INTO rcount FROM mgmt_roles WHERE role_name = l_name; IF rcount = 0 AND uname = l_owner THEN GRANT_PRIV(l_name, l_priv, job_id_in, 1); ELSE raise_application_error(MGMT_GLOBAL.GRANT_FAILED_ERR, MGMT_GLOBAL.GRANT_FAILED_ERR_M || 'FULL_JOB cannot be granted to role - '||l_name); END IF; ELSE -- don't grant VIEW_JOB to super users - they already have it IF HAS_PRIV(l_name, SUPER_USER, NO_GUID) <> USER_HAS_PRIV THEN IF l_priv = VIEW_JOB THEN GRANT_PRIV(l_name, l_priv, job_id_in, 1); END IF; END IF; END IF; -- Privileges are being removed for this user ELSE IF HAS_PRIV(l_name, FULL_JOB, job_id_in) = USER_HAS_PRIV THEN REVOKE_PRIV(l_name, FULL_JOB, job_id_in, 1); END IF; -- If this is a super user, they don't explicitely have VIEW_JOB IF HAS_PRIV(l_name, SUPER_USER, NO_GUID) <> USER_HAS_PRIV THEN IF HAS_PRIV(l_name, VIEW_JOB, job_id_in) = USER_HAS_PRIV THEN REVOKE_PRIV(l_name, VIEW_JOB, job_id_in, 1); END IF; END IF; END IF; END IF; END LOOP; END; END MODIFY_JOB_GRANTS; -- -- PURPOSE -- -- To create a user in db console mode -- -- PARAMETERS -- -- USER_NAME_IN - the name of the user -- PASSWORD_IN - the password of the user -- EMAIL_ADDRESSES_IN - the email addresses of the user -- ROLES_IN - the roles to grant to the user -- PRIVILEGES_IN - the privileges to grant to the user -- For more details, please look at CREATE_USER -- PROCEDURE CREATE_USER_DBCONSOLE(user_name_in IN VARCHAR2, password_in IN VARCHAR2, email_addresses_in IN SMP_EMD_STRING_ARRAY, roles_in IN SMP_EMD_STRING_ARRAY DEFAULT NULL, privileges_in IN MGMT_USER_PRIVILEGES DEFAULT NULL) IS l_user_name VARCHAR2(256); BEGIN l_user_name := UPPER(TRIM(user_name_in)); CREATE_USER(user_name_in,password_in,email_addresses_in, roles_in,privileges_in,EM_USER); EXECUTE IMMEDIATE 'GRANT SELECT_CATALOG_ROLE TO ' || EM_CHECK.ENQUOTE_NAME(l_user_name); EXCEPTION WHEN OTHERS THEN -- enquote_name returns a misleading error message -- "ORA-06502: PL/SQL: numeric or value error" -- if the input name is not a valid name IF SQLCODE = -6502 THEN raise_application_error(MGMT_GLOBAL.INVALID_USER_PWD_ERR, MGMT_GLOBAL.INVALID_USER_PWD_ERR_M); END IF; RAISE; END CREATE_USER_DBCONSOLE; -- -- PURPOSE -- -- "Convert" an existing database user into an EM user -- in DB Console mode -- On top of MAKE_EM_USER, it grants the database user -- SELECT ANY DICTIONARY system privilege. -- PARAMETERS -- -- USER_NAME_IN - the name of the user -- EMAIL_ADDRESSES_IN - the email addresses of the user -- ROLES_IN - the roles to grant to the user -- PRIVILEGES_IN - the privileges to grant to the user -- TO_GRANT_DB_PRIV_IN - whether to grant SELECT ANY DICTIONARY -- System privilege to the database user, DEFAULT is TRUE -- PROCEDURE MAKE_EM_USER_DBCONSOLE(user_name_in IN VARCHAR2, email_addresses_in IN SMP_EMD_STRING_ARRAY, roles_in IN SMP_EMD_STRING_ARRAY, privileges_in IN MGMT_USER_PRIVILEGES, to_grant_db_priv_in IN NUMBER DEFAULT 1) IS l_user_name VARCHAR2(256); l_has_sel_cata_role NUMBER := 0; BEGIN l_user_name := UPPER(TRIM(user_name_in)); MAKE_EM_USER(user_name_in,email_addresses_in, roles_in,privileges_in); IF to_grant_db_priv_in = 1 THEN -- Check of current logged in user already has it -- if not then grant SELECT count(granted_role) INTO l_has_sel_cata_role FROM DBA_ROLE_PRIVS WHERE grantee = l_user_name AND granted_role = 'SELECT_CATALOG_ROLE'; IF l_has_sel_cata_role < 1 THEN EXECUTE IMMEDIATE 'GRANT SELECT_CATALOG_ROLE TO ' || EM_CHECK.ENQUOTE_NAME(l_user_name); END IF; END IF; EXCEPTION WHEN OTHERS THEN -- enquote_name returns a misleading error message -- "ORA-06502: PL/SQL: numeric or value error" -- if the input name is not a valid name IF SQLCODE = -6502 THEN raise_application_error(MGMT_GLOBAL.INVALID_USER_PWD_ERR, MGMT_GLOBAL.INVALID_USER_PWD_ERR_M); -- Realm voilation case ELSIF SQLCODE = -47410 THEN mgmt_user.DROP_USER (l_user_name); -- Why this commit is here? -- As GRANT select_catalog_role is commiting -- to rollback the changes we are calling the -- drop user and as after that we will be raiseing -- excpetion again, we have to commit to make drop user -- changes effective COMMIT; END IF; RAISE; END MAKE_EM_USER_DBCONSOLE; -- -- PURPOSE -- -- To get a list of users -- -- PARAMETERS -- -- USER_NAMES_OUT - the names of the user -- -- NOTES -- -- This routines searches for all users that have the MGMT_USER role -- and are Database users. It -- will not return the repository owner, and will not return any -- users with the SUPER_USER privilege, if the caller is not a SUPER_USER. -- PROCEDURE GET_USERS_DBCONSOLE(user_names_out OUT STRING_CURSOR, p_user_srch IN VARCHAR2 DEFAULT NULL) IS uname VARCHAR2(256); l_view_user_name VARCHAR2(256); l_user_srch MGMT_CREATED_USERS.USER_NAME%TYPE; BEGIN uname := GET_CURRENT_EM_USER; l_view_user_name := 'MGMT_VIEW'; -- Use the following procedure after fixing the circular dependency -- MGMT_VIEW_PRIV.GET_VIEW_USER(l_view_user_name); --Added To handle Wildcard search SELECT UPPER ( TRIM ( DECODE ( INSTR(p_user_srch,'*'), 0,DECODE(INSTR(p_user_srch,'%'), 0,'%'||p_user_srch||'%',p_user_srch), REPLACE(p_user_srch,'*','%') ) ) ) INTO l_user_srch FROM dual; --This was required if a name containing "_" was queried --To handle escape character "_" l_user_srch:=replace(l_user_srch,'^','^^'); l_user_srch:=replace(l_user_srch,'_','^_'); -- Check if the user is a SUPER_USER --Fix for 4270327 IF MGMT_USER.HAS_PRIV(MGMT_USER.GET_CURRENT_EM_USER, SUPER_USER) = USER_HAS_PRIV THEN OPEN user_names_out FOR SELECT user_name,deleting,super,valid FROM ( SELECT admusers.user_name, admusers.deleting, NVL(b.priv_name,'NON_SUPER') super, '1' valid FROM mgmt_created_users admusers, dba_users dbausers, mgmt_priv_grants b WHERE admusers.user_name = dbausers.username AND admusers.user_name <> GET_REPOSITORY_OWNER AND admusers.user_name <> l_view_user_name AND admusers.user_name = b.grantee(+) AND b.priv_name(+)='SUPER_USER' UNION SELECT GET_REPOSITORY_OWNER user_name,0 deleting,'OWNER' super, '1' valid FROM DUAL ) WHERE UPPER(user_name) like nvl(l_user_srch,'%') escape '^' ORDER BY user_name; ELSE OPEN user_names_out FOR SELECT user_name, deleting,'' super, '1' valid FROM mgmt_created_users admusers, dba_users dbausers WHERE admusers.user_name = dbausers.username AND admusers.user_name <> GET_REPOSITORY_OWNER AND admusers.user_name <> l_view_user_name AND admusers.user_name NOT IN (SELECT grantee FROM MGMT_PRIV_GRANTS WHERE priv_name = SUPER_USER) AND UPPER(user_name) like nvl(l_user_srch,'%') escape '^' ORDER BY user_name; END IF; END GET_USERS_DBCONSOLE; -- -- PURPOSE -- -- To get a list of objects owned by the users -- -- PARAMETERS -- -- USER_NAMES - the names of the user -- -- NOTES -- -- This routines return a list of objects owned by the user. which include -- jobs, jobtypes, blackouts, targets, corrective action, templates, reports -- and report definition -- -- Each module has to register a call back of type GET_USER_OBJECT_CALLBACK -- which will be called hear to get all the objects owned by this user in -- that module -- -- PROCEDURE GET_USER_OBJECTS_CALLBACK( -- user_name_in IN VARCHAR2, -- user_objects_out OUT MGMT_USER_OBJECTS, -- type_in IN NUMBER); -- FUNCTION GET_USER_OBJECTS(user_name_in IN VARCHAR2) RETURN MGMT_USER_OBJECTS IS CURSOR get_user_object_callbacks IS SELECT callback FROM MGMT_USER_CALLBACKS WHERE type = MGMT_USER.GET_USER_OBJECTS_CALLBACK; l_user_objects MGMT_USER_OBJECTS; user_objects_ret MGMT_USER_OBJECTS; l_user_name VARCHAR2(256); BEGIN user_objects_ret := MGMT_USER_OBJECTS(); l_user_name := UPPER(TRIM(user_name_in)); -- Execute the callbacks FOR crec IN get_user_object_callbacks LOOP BEGIN l_user_objects := null; EXECUTE IMMEDIATE 'CALL ' || EM_CHECK.QUALIFIED_SQL_NAME(crec.callback) || '(:username, :user_objects, :op)' USING l_user_name, OUT l_user_objects, MGMT_USER.GET_USER_OBJECTS_CALLBACK; FOR i IN 1..l_user_objects.COUNT LOOP user_objects_ret.extend(1); user_objects_ret(user_objects_ret.LAST) := l_user_objects(i); END LOOP; EXCEPTION WHEN OTHERS THEN raise_application_error(MGMT_GLOBAL.CALLBACK_FAILED_ERR, MGMT_GLOBAL.CALLBACK_FAILED_ERR || ' error while executing user model callback ' || crec.callback || ' ' || SQLERRM); END; END LOOP; RETURN user_objects_ret; END GET_USER_OBJECTS; -- -- PURPOSE -- -- To check weather the user owns some objects which cant be droped -- Returns a list of all conflicting objects -- -- PARAMETERS -- -- USER_NAME_IN - the names of the user -- -- NOTES -- This routines return a list of objects owned by the user which cant be droped -- -- Each module has to register a call back of type CHECK_DROP_USER_CALLBACK -- which will be called hear to get all the conflicting objects owned by this user in -- that module -- -- PROCEDURE CHECK_DROP_USER_CALLBACK( -- user_name_in IN VARCHAR2, -- user_objects_out OUT MGMT_USER_OBJECTS, -- type_in IN NUMBER); -- FUNCTION CHECK_DROP_USER_CONFLICTS(user_name_in IN VARCHAR2) RETURN MGMT_USER_OBJECTS IS CURSOR check_drop_user_callbacks IS SELECT callback FROM MGMT_USER_CALLBACKS WHERE type = MGMT_USER.CHECK_USER_DROPPED_CALLBACK; l_user_objects MGMT_USER_OBJECTS; user_objects_ret MGMT_USER_OBJECTS; l_user_name VARCHAR2(256); BEGIN user_objects_ret := MGMT_USER_OBJECTS(); l_user_name := UPPER(TRIM(user_name_in)); -- Execute the callbacks FOR crec IN check_drop_user_callbacks LOOP BEGIN l_user_objects := null; EXECUTE IMMEDIATE 'CALL ' || EM_CHECK.QUALIFIED_SQL_NAME(crec.callback) || '(:username, :user_objects, :op)' USING l_user_name, OUT l_user_objects, MGMT_USER.CHECK_USER_DROPPED_CALLBACK; FOR i IN 1..l_user_objects.COUNT LOOP user_objects_ret.extend(1); user_objects_ret(user_objects_ret.LAST) := l_user_objects(i); END LOOP; EXCEPTION WHEN OTHERS THEN raise_application_error(MGMT_GLOBAL.CALLBACK_FAILED_ERR, MGMT_GLOBAL.CALLBACK_FAILED_ERR || ' error while executing user model callback ' || crec.callback || ' ' || SQLERRM); END; END LOOP; RETURN user_objects_ret; END CHECK_DROP_USER_CONFLICTS; -- -- PURPOSE -- -- To check weather the user owns some objects which cant be reassigned to the -- new user. Returns a list of all conflicting objects -- -- PARAMETERS -- -- USER_NAME_IN - the names of the user -- -- NOTES -- This routines return a list of objects owned by the user which cant be reassigned -- to the new user -- -- Each module has to register a call back of type CHECK_REASSIGN_USER_CALLBACK -- which will be called hear to get all the conflicting objects owned by this user in -- that module -- -- PROCEDURE CHECK_REASSIGN_USER_CALLBACK( -- user_name_in IN VARCHAR2, -- new_user_name_in IN VARCHAR2, -- user_objects_out OUT MGMT_USER_OBJECTS, -- type_in IN NUMBER); -- FUNCTION CHECK_REASSIGN_USER_CONFLICTS(user_name_in IN VARCHAR2, new_user_name_in IN VARCHAR2) RETURN MGMT_USER_OBJECTS IS CURSOR check_reassign_user_callbacks IS SELECT callback FROM MGMT_USER_CALLBACKS WHERE type = MGMT_USER.CHECK_USER_REASSIGN_CALLBACK; l_user_objects MGMT_USER_OBJECTS; user_objects_ret MGMT_USER_OBJECTS; l_user_name VARCHAR2(256); l_new_user_name VARCHAR2(256); BEGIN user_objects_ret := MGMT_USER_OBJECTS(); l_user_name := UPPER(TRIM(user_name_in)); l_new_user_name := UPPER(TRIM(new_user_name_in)); -- Execute the callbacks FOR crec IN check_reassign_user_callbacks LOOP BEGIN l_user_objects := null; EXECUTE IMMEDIATE 'CALL ' || EM_CHECK.QUALIFIED_SQL_NAME(crec.callback) || '(:username,:new_username, :user_objects, :op)' USING l_user_name, l_new_user_name, OUT l_user_objects, MGMT_USER.CHECK_USER_REASSIGN_CALLBACK; FOR i IN 1..l_user_objects.COUNT LOOP user_objects_ret.extend(1); user_objects_ret(user_objects_ret.LAST) := l_user_objects(i); END LOOP; EXCEPTION WHEN OTHERS THEN raise_application_error(MGMT_GLOBAL.CALLBACK_FAILED_ERR, MGMT_GLOBAL.CALLBACK_FAILED_ERR || ' error while executing user model callback ' || crec.callback || ' ' || SQLERRM); END; END LOOP; RETURN user_objects_ret; END CHECK_REASSIGN_USER_CONFLICTS; -- -- PURPOSE -- -- To get the list of users and roles. -- -- PARAMETERS -- -- p_given_object_name - the names of the user -- p_object_name - Array of user/role names -- p_object_description - Array of description for user/role -- -- -- -- PROCEDURE GET_USER_ROLE_LIST(p_given_object_name IN VARCHAR2, p_object_name OUT VARCHAR2_TABLE, p_object_description OUT VARCHAR2_TABLE) IS l_count NUMBER; l_counter NUMBER; l_is_super NUMBER; l_public_role VARCHAR2(6); l_given_object_name mgmt_created_users.user_name%TYPE:='%'||p_given_object_name||'%'; CURSOR c1(public_role VARCHAR2) IS SELECT user_name grantee, 'User' description FROM mgmt_created_users WHERE upper(user_name) LIKE upper(nvl(l_given_object_name,'%')) escape '^' AND DELETING = 0 UNION SELECT role_name grantee, description description FROM mgmt_roles WHERE upper(role_name) LIKE upper(nvl(l_given_object_name,'%')) escape '^' AND upper(role_name) <> upper(public_role) ORDER BY 1; BEGIN l_count := 1; p_object_name := varchar2_table(); p_object_description := varchar2_table(); l_is_super := MGMT_USER.HAS_PRIV(MGMT_USER.GET_CURRENT_EM_USER, 'SUPER_USER'); --Added to handle Wildcard search -- if either % or * is entered , all records should be retreived -- Else the Search string is enclosed by % SELECT TRIM ( DECODE ( INSTR(p_given_object_name,'*'), 0,DECODE(INSTR(p_given_object_name,'%'), 0,'%'||p_given_object_name||'%',p_given_object_name), REPLACE(p_given_object_name,'*','%') ) ) INTO l_given_object_name FROM dual; --This was required if a name containing "_" was queried --To handle escape character "_" l_given_object_name:=replace(l_given_object_name,'^','^^'); l_given_object_name:=replace(l_given_object_name,'_','^_'); IF(l_is_super = MGMT_USER.USER_DOES_NOT_HAVE_PRIV) THEN l_public_role := PUBLIC_ROLE; ELSE l_public_role := ' '; END IF; FOR rec IN c1(l_public_role) LOOP p_object_name.extend(1); p_object_description.extend(1); p_object_name(l_count) := rec.grantee; IF (rec.description='User') THEN -- Determine whether he is a Admin oR a Super Admin SELECT count(*) INTO l_counter FROM mgmt_priv_grants WHERE grantee=rec.grantee AND priv_name='SUPER_USER'; IF (l_counter=1) then p_object_description(l_count):='1'; ELSE p_object_description(l_count):='0'; END IF; ELSE -- this is a role, display first 30 characters of description IF (length(rec.description)>30) THEN p_object_description(l_count):=substr(rec.description,1,28)||'..'; ELSE p_object_description(l_count):=nvl(rec.description, 'ROLE'); END IF; END IF; l_count := l_count+1; END LOOP; END GET_USER_ROLE_LIST; -- -- PURPOSE -- -- To get the access info for targets.. -- -- PARAMETERS -- -- p_target_name - Name of the target -- p_target_type - Type of target -- p_error_message - Error Message -- p_user_name - Array of user/role names -- p_user_description - Array of description of user/role -- p_user_privilege - Array of privileges -- -- -- PROCEDURE get_access_info(p_target_name IN varchar2,p_target_type IN varchar2, p_error_message OUT varchar2,p_super_or_owner OUT varchar2,p_user_name OUT varchar2_table, p_user_description OUT varchar2_table,p_user_privilege OUT varchar2_table) IS l_counter number; l_count number; l_guid raw(16); l_owner varchar2(100); l_is_super number; l_current_em_user varchar2(64); BEGIN l_guid := mgmt_target.get_target_guid(p_target_name, p_target_type); IF (l_guid IS NULL) THEN p_error_message:='Object GUID cannot be NULL'; RETURN; END IF; p_super_or_owner := 'false'; select owner into l_owner from mgmt_targets where target_guid=l_guid; l_current_em_user := MGMT_USER.GET_CURRENT_EM_USER(); l_is_super := MGMT_USER.HAS_PRIV(MGMT_USER.GET_CURRENT_EM_USER, 'SUPER_USER'); IF(l_is_super = MGMT_USER.USER_DOES_NOT_HAVE_PRIV) THEN if( l_owner = l_current_em_user) then p_super_or_owner := 'true'; end if; ELSE p_super_or_owner := 'true'; END IF; p_user_name := varchar2_table(); p_user_description := varchar2_table(); p_user_privilege := varchar2_table(); l_counter:=0; FOR c1 IN ( SELECT user_name grantee, 'User' TYPE FROM mgmt_created_users WHERE deleting=0 and user_name IN ( SELECT DISTINCT(grantee) FROM mgmt_priv_grants WHERE grantee_is_role=0 AND guid=l_guid ) UNION SELECT role_name grantee, description TYPE FROM mgmt_roles WHERE role_name IN ( SELECT DISTINCT(grantee) FROM mgmt_priv_grants WHERE grantee_is_role=1 AND guid=l_guid ) ORDER BY 1 ) LOOP l_counter:=l_counter+1; p_user_name.extend(1); p_user_name(l_counter):=c1.grantee; p_user_description.extend(1); IF (c1.type='User') THEN -- Determine whether he is a Admin oR a Super Admin SELECT count(*) INTO l_count FROM mgmt_priv_grants WHERE grantee=c1.grantee AND priv_name='SUPER_USER'; IF (l_count=1) THEN p_user_description(l_counter):='1'; ELSE p_user_description(l_counter):='0'; END IF; ELSE -- this is a role, display first 60 characters of description IF (length(c1.type)>60) THEN p_user_description(l_counter):=substr(c1.type,1,58)||'..'; ELSE p_user_description(l_counter):=nvl(c1.type, 'ROLE'); END IF; END IF; -- if (c1.type='User') ends FOR c2 IN ( SELECT priv_name FROM mgmt_priv_grants WHERE grantee=c1.grantee AND guid = l_guid AND direct_grant=1 ) LOOP p_user_privilege.extend(1); p_user_privilege(l_counter):=c2.priv_name; END LOOP; -- c2 end END LOOP; --c1 ends END get_access_info; -- -- PURPOSE -- -- To get the access info for templates.. -- -- PARAMETERS -- -- p_target_name - Name of the target -- p_target_type - Type of target -- p_error_message - Error Message -- p_user_name - Array of user/role names -- p_user_description - Array of description of user/role -- p_user_privilege - Array of privileges -- -- -- PROCEDURE get_access_info_template(p_target_name IN varchar2,p_target_type IN varchar2, p_error_message OUT varchar2,p_super_or_owner OUT varchar2,p_user_name OUT varchar2_table, p_user_description OUT varchar2_table,p_user_privilege OUT varchar2_table) IS l_counter number; l_count number; l_guid raw(16); l_owner varchar2(100); l_current_em_user varchar2(64); BEGIN l_guid := mgmt_template.get_template_guid(p_target_type,p_target_name); IF (l_guid IS NULL) THEN p_error_message:='Object GUID cannot be NULL'; RETURN; END IF; p_user_name := varchar2_table(); p_user_description := varchar2_table(); p_user_privilege := varchar2_table(); p_super_or_owner := 'false'; select owner into l_owner from mgmt_templates where template_guid=l_guid; l_current_em_user := MGMT_USER.GET_CURRENT_EM_USER(); if( l_owner = l_current_em_user) then p_super_or_owner := 'true'; end if; l_counter:=0; FOR c1 IN ( SELECT user_name grantee, 'User' TYPE FROM mgmt_created_users WHERE deleting=0 and user_name IN ( SELECT DISTINCT(grantee) FROM mgmt_priv_grants WHERE grantee_is_role=0 AND guid=l_guid ) UNION SELECT role_name grantee, description TYPE FROM mgmt_roles WHERE role_name IN ( SELECT DISTINCT(grantee) FROM mgmt_priv_grants WHERE grantee_is_role=1 AND guid=l_guid ) ORDER BY 1 ) LOOP l_counter:=l_counter+1; p_user_name.extend(1); p_user_name(l_counter):=c1.grantee; p_user_description.extend(1); IF (c1.type='User') THEN -- Determine whether he is a Admin oR a Super Admin SELECT count(*) INTO l_count FROM mgmt_priv_grants WHERE grantee=c1.grantee AND priv_name='SUPER_USER'; IF (l_count=1) THEN p_user_description(l_counter):='1'; ELSE p_user_description(l_counter):='0'; END IF; ELSE -- this is a role, display first 30 characters of description IF (length(c1.type)>30) THEN p_user_description(l_counter):=substr(c1.type,1,28)||'..'; ELSE p_user_description(l_counter):=nvl(c1.type, 'ROLE'); END IF; END IF; -- if (c1.type='User') ends FOR c2 IN ( SELECT priv_name FROM mgmt_priv_grants WHERE grantee=c1.grantee AND guid = l_guid AND direct_grant=1 ) LOOP p_user_privilege.extend(1); p_user_privilege(l_counter):=c2.priv_name; END LOOP; -- c2 end END LOOP; --c1 ends END get_access_info_template; -- -- PURPOSE -- -- To update the privileges. -- -- PARAMETERS -- -- p_target_name - Name of the target -- p_target_type - Type of target -- p_type - Either type is target or template -- p_object_name - Array of user/role names -- p_object_priv - Array of privileges of user/role -- -- -- PROCEDURE update_privilige(p_target_name IN varchar2, p_target_type IN varchar2, p_type IN varchar2, p_object_name IN varchar2_table, p_object_priv IN varchar2_table) IS l_name varchar2(500); l_privilege varchar2(20); l_length number; l_index_value number; l_grantee_is_role number; l_ipriv_name varchar2(20); l_guid raw(16); BEGIN IF(p_type = 'target') THEN l_guid := mgmt_target.get_target_guid(p_target_name, p_target_type); ELSIF(p_type = 'template') THEN l_guid := mgmt_template.generate_template_guid(p_target_type, p_target_name); END IF; DELETE FROM mgmt_priv_grants WHERE guid=l_guid; l_index_value := 1; l_length:= p_object_name.count; IF(l_length>0) THEN LOOP l_name := p_object_name(l_index_value); l_privilege := p_object_priv(l_index_value); MGMT_USER.GRANT_PRIV ( grantee_in=>l_name, priv_name_in=>l_privilege, guid_in=>l_guid ); --Increase the counter l_index_value := l_index_value+1; EXIT WHEN l_index_value > l_length; END LOOP; END IF; END update_privilige; -- -- PURPOSE -- -- To update the privileges. This Procedure takes arrays as parameters and grant/update or revoke the -- privileges according to the condition. -- -- PARAMETERS -- -- p_target_name - Name of the target -- p_target_type - Type of target -- p_type - Either type is target or template -- p_new_object_name - Array of new user/role names -- p_new_object_priv - Array of new privileges of user/role -- p_changed_object_name - Array of changed user/role names -- p_changed_object_priv - Array of changed privileges of user/role -- p_previous_object_name - Array of previous user/role names needed to revoke the privilege -- p_previous_object_priv - Array of previous privileges of user/role needed to revoke the privilege -- p_revoked_object_name - Array of revoked user/role names -- p_revoked_object_priv - Array of revoked privileges of user/role -- -- PROCEDURE update_privilege(p_target_name IN VARCHAR2, p_target_type IN VARCHAR2, p_type IN VARCHAR2, p_new_object_name IN VARCHAR2_TABLE DEFAULT NULL, p_new_object_priv IN VARCHAR2_TABLE DEFAULT NULL, p_changed_object_name IN VARCHAR2_TABLE DEFAULT NULL, p_changed_object_priv IN VARCHAR2_TABLE DEFAULT NULL, p_previous_object_name IN VARCHAR2_TABLE DEFAULT NULL, p_previous_object_priv IN VARCHAR2_TABLE DEFAULT NULL, p_revoked_object_name IN VARCHAR2_TABLE DEFAULT NULL, p_revoked_object_priv IN VARCHAR2_TABLE DEFAULT NULL) IS l_name varchar2(500); l_privilege varchar2(20); l_length number; l_index_value number; l_grantee_is_role number; l_ipriv_name varchar2(20); l_guid raw(16); BEGIN IF(p_type = 'target') THEN l_guid := mgmt_target.get_target_guid(p_target_name, p_target_type); ELSIF(p_type = 'template') THEN l_guid := mgmt_template.generate_template_guid(p_target_type, p_target_name); END IF; IF (p_new_object_name is not NULL) THEN update_revoke_grant_privilege(p_guid => l_guid, p_revoke_or_grant => 'GRANT', p_object_name => p_new_object_name, p_object_priv => p_new_object_priv); END IF; IF (p_changed_object_name is not NULL) THEN update_revoke_grant_privilege(p_guid => l_guid, p_revoke_or_grant => 'REVOKE', p_object_name => p_previous_object_name, p_object_priv => p_previous_object_priv); update_revoke_grant_privilege(p_guid => l_guid, p_revoke_or_grant => 'GRANT', p_object_name => p_changed_object_name, p_object_priv => p_changed_object_priv); END IF; IF (p_revoked_object_name is not NULL) THEN update_revoke_grant_privilege(p_guid => l_guid, p_revoke_or_grant => 'REVOKE', p_object_name => p_revoked_object_name, p_object_priv => p_revoked_object_priv); END IF; END update_privilege; -- -- PURPOSE -- -- To update the privileges. This Procedure is like an api which will be called from the MGMT_USER.update_privilege -- procedure and according to the condition it will either grant or revoke the privilege. -- -- PARAMETERS -- -- p_guid - guid -- p_revoke_or_grant - Either revoke or grant -- p_object_name - Array of user/role name -- p_object_priv - Array of new user/role privileges -- -- PROCEDURE update_revoke_grant_privilege(p_guid in RAW, p_revoke_or_grant IN VARCHAR2, p_object_name IN VARCHAR2_TABLE, p_object_priv IN VARCHAR2_TABLE) IS l_name varchar2(500); l_privilege varchar2(20); l_length number; l_index_value number; BEGIN l_index_value := 1; l_length:= p_object_name.count; IF(l_length>0) THEN LOOP l_name := p_object_name(l_index_value); l_privilege := p_object_priv(l_index_value); IF(p_revoke_or_grant = 'GRANT') THEN MGMT_USER.GRANT_PRIV ( grantee_in=>l_name, priv_name_in=>l_privilege, guid_in=>p_guid ); ELSIF(p_revoke_or_grant = 'REVOKE') THEN MGMT_USER.REVOKE_PRIV ( grantee_in=>l_name, priv_name_in=>l_privilege, guid_in=>p_guid ); END IF; --Increase the counter l_index_value := l_index_value+1; EXIT WHEN l_index_value > l_length; END LOOP; END IF; END update_revoke_grant_privilege; BEGIN -- Set up the repository name BEGIN SELECT parameter_value INTO G_REPOSITORY_OWNER FROM mgmt_parameters WHERE parameter_name = MGMT_GLOBAL.G_SCHEMA_OWNER_PARAM_NAME ; EXCEPTION WHEN NO_DATA_FOUND THEN SELECT owner INTO G_REPOSITORY_OWNER FROM dba_procedures WHERE object_name = 'MGMT_USER' AND procedure_name = 'DROP_USER'; END; -- Set up the propagate flag BEGIN SELECT parameter_value INTO G_PROPAGATE_PRIVS FROM MGMT_PARAMETERS WHERE parameter_name = PROPAGATE_GROUP_PRIVILEGES; EXCEPTION WHEN NO_DATA_FOUND THEN G_PROPAGATE_PRIVS := 0; END; -- Check if the target policy has been disabled BEGIN SELECT parameter_value INTO G_TARGET_POLICY_IS_ENABLED FROM MGMT_PARAMETERS WHERE parameter_name = TARGET_POLICY_ENABLED; EXCEPTION WHEN NO_DATA_FOUND THEN G_TARGET_POLICY_IS_ENABLED := 'Y'; END; END MGMT_USER; / show errors;