mirror of
https://github.com/marcus-alicia/iRedAdmin-Pro-SQL.git
synced 2026-05-26 15:13:38 +00:00
191 lines
5.9 KiB
Python
191 lines
5.9 KiB
Python
#!/usr/bin/env python3
|
|
|
|
# Author: Zhang Huangbin <zhb@iredmail.org>
|
|
# Updated: 2012.07.01
|
|
# Purpose: Dump disclaimer text from OpenLDAP directory server or SQL servers.
|
|
# Requirements: iRedMail-0.5.0 or later releases
|
|
#
|
|
# Shipped within iRedAdmin-Pro: http://www.iredmail.org/admin_panel.html
|
|
|
|
# USAGE:
|
|
#
|
|
# - Make sure you have correct backend related settings in iRedAdmin config
|
|
# file, settings.ini.
|
|
#
|
|
# - Test this script in command line directly, make sure no errors in output
|
|
# message.
|
|
#
|
|
# # python /path/to/dump_disclaimer.py /etc/postfix/disclaimer/
|
|
#
|
|
# - Setup a cron job to execute this script daily. For example: execute
|
|
# this script at 2:01AM every day.
|
|
#
|
|
# 1 2 * * * python /path/to/dump_disclaimer.py /etc/postfix/disclaimer/
|
|
#
|
|
# That's all.
|
|
|
|
import os
|
|
import sys
|
|
|
|
# Directory used to store disclaimer files.
|
|
# Default directory is /etc/postfix/disclaimer/.
|
|
# Default disclaimer file name is [domain_name].txt
|
|
if len(sys.argv) != 2:
|
|
sys.exit('Error: Please specify a directory used to store disclaimer, default is /etc/postfix/disclaimer/')
|
|
else:
|
|
DISCLAIMER_DIR = sys.argv[1]
|
|
DISCLAIMER_FILE_EXT = '.txt'
|
|
|
|
os.environ['LC_ALL'] = 'C'
|
|
rootdir = os.path.abspath(os.path.dirname(__file__)) + '/../'
|
|
sys.path.insert(0, rootdir)
|
|
|
|
import web
|
|
import settings
|
|
from libs import iredutils
|
|
from tools import ira_tool_lib
|
|
logger = ira_tool_lib.logger
|
|
|
|
web.config.debug = False
|
|
|
|
if settings.backend == 'ldap':
|
|
import ldap
|
|
elif settings.backend == 'mysql':
|
|
sql_dbn = 'mysql'
|
|
elif settings.backend == 'pgsql':
|
|
sql_dbn = 'postgres'
|
|
|
|
|
|
def write_disclaimer(text, filename, file_type='txt'):
|
|
# Write plain text
|
|
try:
|
|
f = open(filename, 'w')
|
|
|
|
if file_type == 'html':
|
|
html = """<div id="disclaimer_separator"><p>----------</p><br /></div>"""
|
|
html += """<div id="disclaimer_text"><p>""" + text + """</p></div>"""
|
|
|
|
f.write('\n' + html + '\n')
|
|
else:
|
|
f.write('\n---------\n' + text + '\n')
|
|
logger.info(" + %s" % filename)
|
|
f.close()
|
|
except Exception as e:
|
|
logger.info('<<< ERROR >>> %s' % str(e))
|
|
|
|
|
|
def handle_disclaimer(domain, disclaimer_text):
|
|
"""Dump or remove disclaimer text."""
|
|
txt = os.path.join(DISCLAIMER_DIR, domain + '.txt')
|
|
html = os.path.join(DISCLAIMER_DIR, domain + '.html')
|
|
|
|
if disclaimer_text:
|
|
write_disclaimer(text=disclaimer_text,
|
|
filename=txt,
|
|
file_type='txt')
|
|
|
|
write_disclaimer(text=disclaimer_text,
|
|
filename=html,
|
|
file_type='html')
|
|
else:
|
|
# Remove old disclaimer file if no disclaimer setting
|
|
try:
|
|
for f in [txt, html]:
|
|
if os.path.isfile(f):
|
|
os.remove(f)
|
|
logger.info(" - Remove %s." % f)
|
|
except OSError:
|
|
pass
|
|
except Exception as e:
|
|
# Other errors.
|
|
logger.info("<<< ERROR >>> {}: {}.".format(domain, str(e)))
|
|
|
|
|
|
def dump_from_ldap():
|
|
"""Dump disclaimer text from LDAP server."""
|
|
logger.info('Connecting to LDAP server')
|
|
conn = ldap.initialize(uri=settings.ldap_uri,
|
|
trace_level=0,
|
|
bytes_strictness='silent')
|
|
conn.set_option(ldap.OPT_PROTOCOL_VERSION, 3)
|
|
|
|
logger.info('Binding with dn: %s' % settings.ldap_basedn)
|
|
conn.bind_s(settings.ldap_bind_dn, settings.ldap_bind_password)
|
|
|
|
# Search and get disclaimer.
|
|
logger.info('Searching all domains')
|
|
qr = conn.search_s(
|
|
settings.ldap_basedn,
|
|
ldap.SCOPE_ONELEVEL,
|
|
'(objectClass=mailDomain)',
|
|
['domainName', 'domainAliasName', 'disclaimer'],
|
|
)
|
|
|
|
logger.info('Dumping ...')
|
|
|
|
for (_dn, _ldif) in qr:
|
|
_ldif = iredutils.bytes2str(_ldif)
|
|
|
|
# Get domain names.
|
|
_domains = _ldif['domainName']
|
|
_alias_domains = _ldif.get('domainAliasName', [])
|
|
disclaimer_text = _ldif.get('disclaimer', [''])[0]
|
|
|
|
domains = _domains + _alias_domains
|
|
|
|
for domain in domains:
|
|
handle_disclaimer(domain, disclaimer_text)
|
|
|
|
conn.unbind()
|
|
logger.info('Connection closed.')
|
|
|
|
|
|
def dump_from_sql():
|
|
"""Dump disclaimer text from MySQL or PostgreSQL server."""
|
|
logger.info("Connecting to SQL server '%s:%d' as user '%s' ..." % (settings.vmail_db_host,
|
|
int(settings.vmail_db_port),
|
|
settings.vmail_db_user))
|
|
|
|
conn = web.database(dbn=sql_dbn,
|
|
host=settings.vmail_db_host,
|
|
port=int(settings.vmail_db_port),
|
|
db=settings.vmail_db_name,
|
|
user=settings.vmail_db_user,
|
|
pw=settings.vmail_db_password)
|
|
|
|
logger.info('Get all alias domains')
|
|
qr = conn.select('alias_domain', what='alias_domain, target_domain')
|
|
alias_domains = {}
|
|
for i in qr:
|
|
_alias_domain = str(i.alias_domain).lower()
|
|
_target_domain = str(i.target_domain).lower()
|
|
|
|
if _target_domain in alias_domains:
|
|
alias_domains[_target_domain].append(_alias_domain)
|
|
else:
|
|
alias_domains[_target_domain] = [_alias_domain]
|
|
|
|
# Search and get disclaimer.
|
|
logger.info('Get all primary domains')
|
|
qr = conn.select('domain', what='domain, disclaimer')
|
|
|
|
# Dump disclaimer for every domain.
|
|
logger.info('Dumping...')
|
|
for r in qr:
|
|
domain = str(r.domain).lower()
|
|
disclaimer_text = r.disclaimer
|
|
|
|
domains = [domain] + alias_domains.get(domain, [])
|
|
|
|
logger.info(domain)
|
|
for domain in domains:
|
|
handle_disclaimer(domain, disclaimer_text)
|
|
|
|
logger.info('Completed.')
|
|
|
|
|
|
if settings.backend == 'ldap':
|
|
dump_from_ldap()
|
|
elif settings.backend in ['mysql', 'pgsql']:
|
|
dump_from_sql()
|