Oracle ACL
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:
- UTL_TCP
- UTL_SMTP
- UTL_MAIL
- UTL_HTTP
- UTL_INADDR
Create ACL
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;
Drop ACL
BEGIN
DBMS_NETWORK_ACL_ADMIN.DROP_ACL(acl => 'ACLNAME');
END
/
Check
To list ACLs...
SELECT ACL
FROM DBA_NETWORK_ACLS
/
To see which users have ACLs granted…
COLUMN acl FORMAT a30
COLUMN principal FORMAT a30
SELECT acl,
principal,
privilege
FROM dba_network_acl_privileges
ORDER BY principal
/
To check which ACL domains allow MYUSER to connect to mail.mydomain.com…
COLUMN host FORMAT a10
COLUMN acl FORMAT a40
SET LINESIZE 132
SELECT 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) privilege
FROM dba_network_acls dna
WHERE 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
/
Useful Queries
Example - Changing Mail Server
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 200
COLUMN host FORMAT a30
COLUMN acl FORMAT a60
SELECT 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;
/
Example - Revoking an ACL from a user
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
/
To view an XML ACL file
SET LONG 4000
SET PAGESIZE 4000
SELECT a.OBJECT_VALUE
FROM RESOURCE_VIEW r,
XDB.XDB$ACL a
WHERE ref(a) = extractValue(r.RES, '/Resource/XMLRef')
AND equals_path(r.RES, '/sys/acls/aclname.xml') = 1;
Useful Views
- DBA_NETWORK_ACLS
- DBA_NETWORK_ACL_PRIVILEGES
Bibliography
https://dba12c.wordpress.com/2015/08/18/understanding-dbms_network_acl_admin-with-example/
Note 453786.1 ORA-24247 When Executing UTL_HTTP UTL_INADDR Packages1080105.1-Understanding DBMS_NETWORK_ACL_ADMIN With Example http://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_networkacl_adm.htm - Oracle® Database PL/SQL Packages and Types Reference 11g Release 1 (11.1)http://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_networkacl_adm.htm#BABCJDGChttp://docs.oracle.com/cd/B28359_01/network.111/b28531/authorization.htm#DBSEG40012 - Oracle® Database Security Guide 11g Release 1 (11.1)http://docs.oracle.com/cd/B28359_01/appdev.111/b28369/xdb21sec.htm#ADXDB2400 - Oracle® XML DB Developer's Guide 11g Release 1 (11.1)