freeipa/daemons/dnssec/ipa-dnskeysyncd
Martin Babinsky 3506938a75 improve the handling of krb5-related errors in dnssec daemons
ipa-dnskeysync* and ipa-ods-exporter handle kerberos errors more gracefully
instead of crashing with tracebacks.

https://fedorahosted.org/freeipa/ticket/5229

Reviewed-By: Martin Basti <mbasti@redhat.com>
2015-08-18 21:11:58 +02:00

117 lines
3.3 KiB
Python
Executable File

#!/usr/bin/python2
#
# Copyright (C) 2014 FreeIPA Contributors see COPYING for license
#
import sys
import ldap
import ldapurl
import logging
import os
import signal
import systemd.journal
import time
from ipalib import api
from ipapython.dn import DN
from ipapython.ipa_log_manager import root_logger, standard_logging_setup
from ipapython import ipaldap
from ipapython import ipautil
from ipaplatform.paths import paths
from ipapython.dnssec.keysyncer import KeySyncer
# IPA framework initialization
api.bootstrap(in_server=True, log=None) # no logging to file
api.finalize()
standard_logging_setup(verbose=True, debug=api.env.debug)
log = root_logger
#log.addHandler(systemd.journal.JournalHandler())
# Global state
watcher_running = True
ldap_connection = False
DAEMONNAME = 'ipa-dnskeysyncd'
PRINCIPAL = None # not initialized yet
WORKDIR = '/tmp' # private temp
KEYTAB_FB = paths.IPA_DNSKEYSYNCD_KEYTAB
# Shutdown handler
def commenceShutdown(signum, stack):
# Declare the needed global variables
global watcher_running, ldap_connection, log
log.info('Signal %s received: Shutting down!', signum)
# We are no longer running
watcher_running = False
# Tear down the server connection
if ldap_connection:
ldap_connection.close_db()
del ldap_connection
# Shutdown
sys.exit(0)
os.umask(0o07)
# Signal handlers
signal.signal(signal.SIGTERM, commenceShutdown)
signal.signal(signal.SIGINT, commenceShutdown)
# Kerberos initialization
PRINCIPAL = str('%s/%s' % (DAEMONNAME, api.env.host))
log.debug('Kerberos principal: %s', PRINCIPAL)
ccache_filename = os.path.join(WORKDIR, 'ipa-dnskeysyncd.ccache')
try:
ipautil.kinit_keytab(PRINCIPAL, KEYTAB_FB, ccache_filename, attempts=5)
except Exception as ex:
log.critical("Kerberos authentication failed: %s", ex)
# signal failure and let init system to restart the daemon
sys.exit(1)
os.environ['KRB5CCNAME'] = ccache_filename
# LDAP initialization
basedn = DN(api.env.container_dns, api.env.basedn)
ldap_url = ldapurl.LDAPUrl(api.env.ldap_uri)
ldap_url.dn = str(basedn)
ldap_url.scope = ldapurl.LDAP_SCOPE_SUBTREE
ldap_url.filterstr = '(|(objectClass=idnsZone)(objectClass=idnsSecKey)(objectClass=ipk11PublicKey))'
log.debug('LDAP URL: %s', ldap_url.unparse())
# Real work
while watcher_running:
# Prepare the LDAP server connection (triggers the connection as well)
ldap_connection = KeySyncer(ldap_url.initializeUrl(), ipa_api=api)
# Now we login to the LDAP server
try:
log.info('LDAP bind...')
ldap_connection.sasl_interactive_bind_s("", ipaldap.SASL_GSSAPI)
except ldap.INVALID_CREDENTIALS as e:
log.exception('Login to LDAP server failed: %s', e)
sys.exit(1)
except ldap.SERVER_DOWN as e:
log.exception('LDAP server is down, going to retry: %s', e)
time.sleep(5)
continue
# Commence the syncing
log.info('Commencing sync process')
ldap_search = ldap_connection.syncrepl_search(
ldap_url.dn,
ldap_url.scope,
mode='refreshAndPersist',
attrlist=ldap_url.attrs,
filterstr=ldap_url.filterstr
)
try:
while ldap_connection.syncrepl_poll(all=1, msgid=ldap_search):
pass
except (ldap.SERVER_DOWN, ldap.CONNECT_ERROR) as e:
log.exception('syncrepl_poll: LDAP error (%s)', e)
sys.exit(1)