Introduction
This article is based on real problems I had in a production environment in Oracle 11g.
Oracle Database provides powerful networking capabilities, allowing PL/SQL programs to interact with external systems over the network. To enhance security, Oracle introduced Access Control Lists (ACLs) starting from Oracle Database 11g. ACLs enable fine-grained control over network access, ensuring that only authorized users and programs can communicate with specified external hosts and services.
This article provides a comprehensive guide to understanding ACL capabilities in Oracle, how to configure them, and how to send emails using the UTL_MAIL
package. We will walk through the steps involved, incorporating practical examples and troubleshooting tips based on common issues encountered.
Table of Contents
- Understanding Oracle ACL Capabilities
- Configuring ACLs for Network Access
- Sending Emails Using UTL_MAIL
- Troubleshooting Common Issues
- Conclusion
1. Understanding Oracle ACL Capabilities
Access Control Lists (ACLs) in Oracle Database are a security feature that controls network access for database users and roles. ACLs are stored as XML files in the Oracle XML DB repository and are managed using the DBMS_NETWORK_ACL_ADMIN
and DBMS_NETWORK_ACL_UTILITY
packages.
Key Features of ACLs:
- Fine-Grained Control: Specify which users or roles can connect to specific network hosts and ports.
-
Privilege Types: Control privileges like
connect
(TCP connections) andresolve
(DNS name resolution). - Security Enhancement: Prevent unauthorized network access from PL/SQL code, reducing the risk of external attacks.
2. Configuring ACLs for Network Access
To send emails using PL/SQL packages like UTL_MAIL
, you need to configure ACLs to allow network access to your SMTP server. Below are the detailed steps to set up ACLs.
2.1 Prerequisites
-
Administrative Privileges: You need to execute these steps as a user with administrative privileges (e.g.,
SYSDBA
). -
SMTP Server Details:
-
Host: The hostname or IP address of your SMTP server (e.g.,
smtp.example.com
). -
Port: The port number used by the SMTP server (commonly
25
,465
, or587
).
-
Host: The hostname or IP address of your SMTP server (e.g.,
-
Database User: The database user that will execute the
UTL_MAIL
package (e.g.,APP_USER
).
2.2 Creating an ACL
Use the DBMS_NETWORK_ACL_ADMIN.CREATE_ACL
procedure to create a new ACL.
BEGIN
DBMS_NETWORK_ACL_ADMIN.create_acl(
acl => 'utl_mail_acl.xml',
description => 'ACL for UTL_MAIL to access SMTP server',
principal => 'APP_USER', -- Replace with your database username
is_grant => TRUE,
privilege => 'connect',
position => NULL
);
END;
/
Explanation:
-
acl
: The name of the ACL file. -
description
: A brief description of the ACL’s purpose. -
principal
: The database user or role to which the privilege is granted. -
is_grant
: Set toTRUE
to grant the privilege. -
privilege
: The network privilege (connect
orresolve
). -
position
: Specifies the order of the ACE (Access Control Entry) in the ACL.
2.3 Assigning the ACL to a Host
Associate the ACL with your SMTP server’s host and port using DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL
.
BEGIN
DBMS_NETWORK_ACL_ADMIN.assign_acl(
acl => 'utl_mail_acl.xml',
host => 'smtp.example.com', -- Replace with your SMTP server host
lower_port => 25, -- Replace with your SMTP server port
upper_port => 25
);
END;
/
Note: If you want to allow access to all ports, you can omit lower_port
and upper_port
.
2.4 Granting Privileges to Users
If you need to grant additional privileges (e.g., resolve
for DNS resolution), use DBMS_NETWORK_ACL_ADMIN.ADD_PRIVILEGE
.
BEGIN
DBMS_NETWORK_ACL_ADMIN.add_privilege(
acl => 'utl_mail_acl.xml',
principal => 'APP_USER', -- Replace with your database username
is_grant => TRUE,
privilege => 'resolve',
position => NULL
);
END;
/
2.5 Verifying ACL Configuration
Commit the Changes:
COMMIT;
Verify the ACL Assignments:
SELECT acl, host, lower_port, upper_port
FROM dba_network_acls
WHERE acl = '/sys/acls/utl_mail_acl.xml';
Verify the Privileges:
SELECT acl, principal, privilege, is_grant
FROM dba_network_acl_privileges
WHERE acl = '/sys/acls/utl_mail_acl.xml';
3. Sending Emails Using UTL_MAIL
The UTL_MAIL
package simplifies sending emails from PL/SQL code. It is a wrapper around UTL_SMTP
and provides a higher-level API.
3.1 Enabling UTL_MAIL
Before you can use UTL_MAIL
, you need to ensure it’s installed and configured.
1. Install UTL_MAIL (if not already installed):
Run the utlmail.sql
script as the SYS
user:
@$ORACLE_HOME/rdbms/admin/utlmail.sql
2. Grant Execute Privilege:
GRANT EXECUTE ON UTL_MAIL TO APP_USER;
3. Set SMTP_OUT_SERVER Parameter:
Set the SMTP_OUT_SERVER
parameter to your SMTP server:
ALTER SYSTEM SET SMTP_OUT_SERVER='smtp.example.com:25' SCOPE=SPFILE;
Alternatively, set it in your init.ora
or spfile
.
4. Restart the Database (if necessary):
If you changed the SMTP_OUT_SERVER
in the SPFILE, you might need to restart the database for the change to take effect.
3.2 Sending a Simple Email
Here’s how to send a simple email using UTL_MAIL
.
BEGIN
UTL_MAIL.send(
sender => 'sender@example.com',
recipients => 'recipient@example.com',
subject => 'Test Email',
message => 'Hello, this is a test email sent using UTL_MAIL.'
);
DBMS_OUTPUT.put_line('Email sent successfully.');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.put_line('Failed to send email: ' || SQLERRM);
END;
/
Explanation:
-
sender
: The email address of the sender. -
recipients
: The email address of the recipient. You can specify multiple recipients separated by commas. -
subject
: The subject line of the email. -
message
: The body of the email.
3.3 Sending Emails with Attachments
To send emails with attachments, use the UTL_MAIL.send_attach_varchar2
procedure.
BEGIN
UTL_MAIL.send_attach_varchar2(
sender => 'sender@example.com',
recipients => 'recipient@example.com',
subject => 'Email with Attachment',
message => 'Please find the attached file.',
attachment => 'This is the content of the attachment.',
att_filename => 'attachment.txt',
mime_type => 'text/plain; charset=UTF-8'
);
DBMS_OUTPUT.put_line('Email with attachment sent successfully.');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.put_line('Failed to send email with attachment: ' || SQLERRM);
END;
/
Explanation:
-
attachment
: The content of the attachment. -
att_filename
: The name of the attachment file. -
mime_type
: The MIME type of the attachment (e.g.,text/plain
for plain text files).
4. Troubleshooting Common Issues
4.1 ORA-24247: Network Access Denied by ACL
Error Message:
ORA-24247: network access denied by access control list (ACL)
Cause:
This error occurs when the database user lacks the necessary privileges in the ACL to access the specified network host or port.
Solution:
SELECT acl, host, lower_port, upper_port
FROM dba_network_acls
WHERE host = 'smtp.example.com';
- Ensure User Has Privileges:
SELECT acl, principal, privilege, is_grant
FROM dba_network_acl_privileges
WHERE principal = 'APP_USER';
- Grant Necessary Privileges:
BEGIN
DBMS_NETWORK_ACL_ADMIN.add_privilege(
acl => 'utl_mail_acl.xml',
principal => 'APP_USER',
is_grant => TRUE,
privilege => 'connect'
);
END;
/
COMMIT;
4.2 Function-Based Index Disabled
Error Message:
ORA-30554: function-based index XDB.XDB$ACL_XIDX is disabled
Cause:
The function-based index XDB.XDB$ACL_XIDX
is disabled, which is essential for ACL operations.
Solution:
ALTER INDEX XDB.XDB$ACL_XIDX REBUILD;
SELECT index_name, status
FROM dba_indexes
WHERE owner = 'XDB' AND index_name = 'XDB$ACL_XIDX';
4.3 Issues with Cron Jobs and Background Processes
When executing PL/SQL code via cron jobs or background processes, you might encounter ACL errors even if the code runs fine interactively.
Possible Causes:
- Different Database User: The cron job might use a different database user without the necessary ACL privileges.
-
Environment Variables: The cron job environment may lack required environment variables like
ORACLE_HOME
andORACLE_SID
. - Definer’s vs. Invoker’s Rights: The stored procedure’s execution rights might affect privilege recognition.
Solutions:
#!/bin/bash
export ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1
export ORACLE_SID=ORCL
export PATH=$ORACLE_HOME/bin:$PATH
sqlplus -s username/password@database <<EOF
-- PL/SQL code here
EOF
- Modify Procedure to Use Invoker’s Rights:
CREATE OR REPLACE PROCEDURE your_procedure_name
AUTHID CURRENT_USER
AS
-- Procedure code here
END;
/
5. Conclusion
Configuring Access Control Lists (ACLs) in Oracle Database is essential for securing network operations performed by PL/SQL code. By carefully setting up ACLs, you can control which users have access to external network services like SMTP servers for sending emails.
This article provided a detailed walkthrough of ACL capabilities, how to configure them, and how to send emails using the UTL_MAIL
package. We’ve covered common issues and their solutions to help you troubleshoot problems you might encounter.
Key Takeaways:
- Understand ACLs: Know how ACLs enhance security by controlling network access.
- Configure ACLs Properly: Assign ACLs to the correct hosts and grant necessary privileges to users.
-
Use UTL_MAIL for Email: Simplify email sending in PL/SQL with
UTL_MAIL
. - Troubleshoot Effectively: Be prepared to diagnose and fix common issues related to ACLs and email sending.
References:
Stay connected
If you enjoyed this article, feel free to connect with me on various platforms:
Your feedback and questions are always welcome.
If you like, you can support my work here: