To avoid "ORA-24247: network access denied by access control list (ACL)" when executing UTL packages (Network related Packages), access has to be granted to user using these packages. Affected packages include:
At its simplest...
BEGIN DBMS_NETWORK_ACL_ADMIN.CREATE_ACL(acl => 'ACLNAME.xml', description => 'Description of this ACL', principal => 'MYUSER', is_grant => true, privilege => 'connect', start_date => null, end_date => null ); COMMIT;END;/The following example first looks for any ACL currently assigned to host_name. If one is found, then the example grants user_name the CONNECT privilege in the ACL only if that user does not already have it. If no ACL exists for host_name, then the example creates a new ACL called ACL_name, grants the CONNECT privilege to user_name, and assigns the ACL to host_name.
DECLARE ACL_PATH VARCHAR2(4000); ACL_ID RAW(16);BEGIN -- Look for the ACL currently assigned to '*' and give MYUSER -- the "connect" privilege if MYUSER does not have the privilege yet. SELECT ACL INTO ACL_PATH FROM DBA_NETWORK_ACLS WHERE HOST = '*' AND LOWER_PORT IS NULL AND UPPER_PORT IS NULL; -- Before checking the privilege, make sure that the ACL is valid -- (for example, does not contain stale references to dropped users). -- If it does, the following exception will be raised: -- -- ORA-44416: Invalid ACL: Unresolved principal 'MYUSER' -- ORA-06512: at "XDB.DBMS_XDBZ", line ... SELECT SYS_OP_R2O(extractValue(P.RES, '/Resource/XMLRef')) INTO ACL_ID FROM XDB.XDB$ACL A, PATH_VIEW P WHERE extractValue(P.RES, '/Resource/XMLRef') = REF(A) AND EQUALS_PATH(P.RES, ACL_PATH) = 1; DBMS_XDBZ.ValidateACL(ACL_ID); IF DBMS_NETWORK_ACL_ADMIN.CHECK_PRIVILEGE(acl => ACL_PATH, user => 'MYUSER', privilege => 'connect') IS NULL THEN DBMS_NETWORK_ACL_ADMIN.ADD_PRIVILEGE(acl => ACL_PATH, principal => 'MYUSER', is_grant => TRUE, privilege => 'connect'); END IF; EXCEPTION -- When no ACL has been assigned to '*'. WHEN NO_DATA_FOUND THEN DBMS_NETWORK_ACL_ADMIN.CREATE_ACL(acl => 'aclname.xml', description => 'ACL description', principal => 'MYUSER', is_grant => TRUE, privilege => 'connect'); DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL(acl => 'aclname.xml', host => '*');END;/COMMIT;BEGIN DBMS_NETWORK_ACL_ADMIN.DROP_ACL(acl => 'ACLNAME');END/To list ACLs...
SELECT ACLFROM DBA_NETWORK_ACLS/To see which users have ACLs granted…
COLUMN acl FORMAT a30COLUMN principal FORMAT a30SELECT acl, principal, privilege FROM dba_network_acl_privilegesORDER BY principal/To check which ACL domains allow MYUSER to connect to mail.mydomain.com…
COLUMN host FORMAT a10COLUMN acl FORMAT a40SET LINESIZE 132SELECT dna.host, dna.lower_port, dna.upper_port, dna.acl, DECODE(DBMS_NETWORK_ACL_ADMIN.CHECK_PRIVILEGE_ACLID(dna.aclid, 'MYUSER', 'connect'), 1, 'GRANTED', 0, 'DENIED', null) privilegeFROM dba_network_acls dnaWHERE host IN (SELECT * FROM TABLE(DBMS_NETWORK_ACL_UTILITY.DOMAINS('mail.mydomain.com')))ORDER BY DBMS_NETWORK_ACL_UTILITY.DOMAIN_LEVEL(host) desc, lower_port, upper_port/If you need to change the your mail server for database outgoing mail...
(e.g. you need to change SMTP_OUT_SERVER from mail.mydomain.com to relay.newdomain.com)First we need to identify how the ACLs are defined for the existing host...
SET LINESIZE 200COLUMN host FORMAT a30COLUMN acl FORMAT a60SELECT host, acl, lower_port, upper_port FROM dba_network_acls;Any ACLs that explicitly point to the old mail server will need to be associated with the new mail server...
It is possible for an ACL to use a wildcard (e.g. * or *.domain.com). You should be mindful of giving non-privileged users access to wildcard ACLs.BEGIN DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL (acl => '&ACLNAME', host => '&newhost', lower_port => &lowport, upper_port => &hiport); commit;END;/At this point it should be possible to send mails through mail.mydomain.com or relay.newdomain.com dependent on your setting for SMTP_OUT_SERVER. Once the change is considered permanent, then you should remove any redundant ACL assignments...
BEGIN DBMS_NETWORK_ACL_ADMIN.UNASSIGN_ACL (acl => '&ACLNAME', host => '&oldhost', lower_port => &lowport, upper_port => &hiport); commit;END;/If you need to stop a user from sending mails using UTL_MAIL via a mail server when that user can currently do so
(e.g. you need to stop USER1 sending mails using UTL_MAIL via relay.newdomain.com, but you don't want to revoke access to UTL_MAIL)BEGIN DBMS_NETWORK_ACL_ADMIN.DELETE_PRIVILEGE(acl => 'ACLNAME', principal => 'USER1')END/SET LONG 4000SET PAGESIZE 4000SELECT a.OBJECT_VALUEFROM RESOURCE_VIEW r, XDB.XDB$ACL aWHERE ref(a) = extractValue(r.RES, '/Resource/XMLRef')AND equals_path(r.RES, '/sys/acls/aclname.xml') = 1;