On 03/07/15 08:46, Martin Kosek wrote:
On 07/03/2015 08:41 AM, Jan Cholasta wrote:
Dne 2.7.2015 v 14:34 David Kupka napsal(a):
On 01/07/15 16:31, David Kupka wrote:
Updated patch attached.
Client install works, but uninstall does not:
# ipa-client-install --uninstall -U
certmonger failed to start: Command ''/bin/systemctl' 'start'
'certmonger.service'' returned non-zero exit status 1
certmonger failed to stop tracking certificate: Failed to start
certmonger:
Timeouted
2015-07-03 02:38:15 [17242] Error reading PIN from
"/etc/ipa/nssdb/pwdfile.txt": No such file or directory.
Failed to start certmonger: Timeouted
The patch needs a rebase.
Also, "Timeouted" is not a word, try "Timed out" instead :-)
Updated patch attached. Also attaching patch that removes unneeded
certmonger (re)starting and DBus starting from ipa-client-install.
--
David Kupka
From e4a04d2f1c6ceb73306d5c417172eba38257dd11 Mon Sep 17 00:00:00 2001
From: David Kupka <dku...@redhat.com>
Date: Tue, 7 Jul 2015 15:49:27 +0200
Subject: [PATCH] cermonger: Use private unix socket when DBus SystemBus is not
available.
---
ipaplatform/base/paths.py | 4 ++
ipapython/certmonger.py | 128 ++++++++++++++++++++++++++++++++--------------
2 files changed, 94 insertions(+), 38 deletions(-)
diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
index 9fef3e7a1351dd42895fe560bb3c1bc5a1c852b4..5756040172126438d42275b734f4d766d53048fe 100644
--- a/ipaplatform/base/paths.py
+++ b/ipaplatform/base/paths.py
@@ -348,3 +348,7 @@ class BasePathNamespace(object):
BAK2DB = '/usr/sbin/bak2db'
DB2BAK = '/usr/sbin/db2bak'
KDCPROXY_CONFIG = '/etc/ipa/kdcproxy/kdcproxy.conf'
+ CERTMONGER = '/usr/sbin/certmonger'
+
+
+path_namespace = BasePathNamespace
diff --git a/ipapython/certmonger.py b/ipapython/certmonger.py
index 4baaaa85da08bb943d6b9f0091a1d2acc36b18d6..9914481a6c9ceccdfbfebcd294a60c827acf801f 100644
--- a/ipapython/certmonger.py
+++ b/ipapython/certmonger.py
@@ -27,6 +27,8 @@ import sys
import time
import dbus
import shlex
+import subprocess
+import tempfile
from ipapython import ipautil
from ipapython import dogtag
from ipapython.ipa_log_manager import *
@@ -35,6 +37,7 @@ from ipaplatform import services
DBUS_CM_PATH = '/org/fedorahosted/certmonger'
DBUS_CM_IF = 'org.fedorahosted.certmonger'
+DBUS_CM_NAME = 'org.fedorahosted.certmonger'
DBUS_CM_REQUEST_IF = 'org.fedorahosted.certmonger.request'
DBUS_CM_CA_IF = 'org.fedorahosted.certmonger.ca'
DBUS_PROPERTY_IF = 'org.freedesktop.DBus.Properties'
@@ -44,7 +47,7 @@ class _cm_dbus_object(object):
"""
Auxiliary class for convenient DBus object handling.
"""
- def __init__(self, bus, object_path, object_dbus_interface,
+ def __init__(self, bus, parent, object_path, object_dbus_interface,
parent_dbus_interface=None, property_interface=False):
"""
bus - DBus bus object, result of dbus.SystemBus() or dbus.SessionBus()
@@ -60,6 +63,7 @@ class _cm_dbus_object(object):
if parent_dbus_interface is None:
parent_dbus_interface = object_dbus_interface
self.bus = bus
+ self.parent = parent
self.path = object_path
self.obj_dbus_if = object_dbus_interface
self.parent_dbus_if = parent_dbus_interface
@@ -69,36 +73,83 @@ class _cm_dbus_object(object):
self.prop_if = dbus.Interface(self.obj, DBUS_PROPERTY_IF)
-def _start_certmonger():
+class _certmonger(_cm_dbus_object):
"""
- Start certmonger daemon. If it's already running systemctl just ignores
- the command.
+ Create a connection to certmonger.
+ By default use SystemBus. When not available use private connection
+ over Unix socket.
+ This solution is really ugly and should be removed as soon as DBus
+ SystemBus is available at system install time.
"""
- if not services.knownservices.certmonger.is_running():
+ _bus = None
+ _proc = None
+ timeout = 300
+
+ def _start_private_conn(self):
+ sock_filename = os.path.join(tempfile.mkdtemp(), 'certmonger')
+ self._proc = subprocess.Popen([paths.CERTMONGER, '-n', '-L', '-P',
+ sock_filename])
+ for t in range(0, self.timeout, 5):
+ if os.path.exists(sock_filename):
+ return "unix:path=%s" % sock_filename
+ time.sleep(5)
+ self._stop_private_conn()
+ raise RuntimeError("Failed to start certmonger: Timed out")
+
+ def _stop_private_conn(self):
+ if self._proc:
+ retcode = self._proc.poll()
+ if retcode is not None:
+ return
+ self._proc.terminate()
+ for t in range(0, self.timeout, 5):
+ retcode = self._proc.poll()
+ if retcode is not None:
+ return
+ time.sleep(5)
+ root_logger.error("Failed to stop certmonger.")
+
+ def __del__(self):
+ self._stop_private_conn()
+
+ def __init__(self):
try:
- services.knownservices.certmonger.start()
- except Exception, e:
- root_logger.error('Failed to start certmonger: %s' % e)
- raise
+ self._bus = dbus.SystemBus()
+ except dbus.DBusException as e:
+ err_name = e.get_dbus_name()
+ if err_name not in ['org.freedesktop.DBus.Error.NoServer',
+ 'org.freedesktop.DBus.Error.FileNotFound']:
+ root_logger.error("Failed to connect to certmonger over "
+ "SystemBus: %s" % e)
+ raise
+ try:
+ self._private_sock = self._start_private_conn()
+ self._bus = dbus.connection.Connection(self._private_sock)
+ except dbus.DBusException as e:
+ root_logger.error("Failed to connect to certmonger over "
+ "private socket: %s" % e)
+ raise
+ else:
+ try:
+ self._bus.get_name_owner(DBUS_CM_NAME)
+ except dbus.DBusException:
+ try:
+ services.knownservices.certmonger.start()
+ except Exception as e:
+ root_logger.error("Failed to start certmonger: %s" % e)
+ raise
+ for t in range(0, self.timeout, 5):
+ try:
+ self._bus.get_name_owner(DBUS_CM_NAME)
+ break
+ except dbus.DBusException:
+ pass
+ time.sleep(5)
+ raise RuntimeError('Failed to start certmonger')
-def _connect_to_certmonger():
- """
- Start certmonger daemon and connect to it via DBus.
- """
- try:
- _start_certmonger()
- except (KeyboardInterrupt, OSError), e:
- root_logger.error('Failed to start certmonger: %s' % e)
- raise
-
- try:
- bus = dbus.SystemBus()
- cm = _cm_dbus_object(bus, DBUS_CM_PATH, DBUS_CM_IF)
- except dbus.DBusException, e:
- root_logger.error("Failed to access certmonger over DBus: %s", e)
- raise
- return cm
+ super(_certmonger, self).__init__(self._bus, None, DBUS_CM_PATH,
+ DBUS_CM_IF)
def _get_requests(criteria=dict()):
@@ -108,7 +159,7 @@ def _get_requests(criteria=dict()):
if not isinstance(criteria, dict):
raise TypeError('"criteria" must be dict.')
- cm = _connect_to_certmonger()
+ cm = _certmonger()
requests = []
requests_paths = []
if 'nickname' in criteria:
@@ -119,12 +170,12 @@ def _get_requests(criteria=dict()):
requests_paths = cm.obj_if.get_requests()
for request_path in requests_paths:
- request = _cm_dbus_object(cm.bus, request_path, DBUS_CM_REQUEST_IF,
+ request = _cm_dbus_object(cm.bus, cm, request_path, DBUS_CM_REQUEST_IF,
DBUS_CM_IF, True)
for criterion in criteria:
if criterion == 'ca-name':
ca_path = request.obj_if.get_ca()
- ca = _cm_dbus_object(cm.bus, ca_path, DBUS_CM_CA_IF,
+ ca = _cm_dbus_object(cm.bus, cm, ca_path, DBUS_CM_CA_IF,
DBUS_CM_IF)
value = ca.obj_if.get_nickname()
else:
@@ -133,6 +184,7 @@ def _get_requests(criteria=dict()):
break
else:
requests.append(request)
+
return requests
@@ -166,7 +218,7 @@ def get_request_value(request_id, directive):
if request:
if directive == 'ca-name':
ca_path = request.obj_if.get_ca()
- ca = _cm_dbus_object(request.bus, ca_path, DBUS_CM_CA_IF,
+ ca = _cm_dbus_object(request.bus, request, ca_path, DBUS_CM_CA_IF,
DBUS_CM_IF)
return ca.obj_if.get_nickname()
else:
@@ -250,7 +302,7 @@ def request_cert(nssdb, nickname, subject, principal, passwd_fname=None):
"""
Execute certmonger to request a server certificate.
"""
- cm = _connect_to_certmonger()
+ cm = _certmonger()
ca_path = cm.obj_if.find_ca_by_nickname('IPA')
if not ca_path:
raise RuntimeError('IPA CA not found')
@@ -264,7 +316,7 @@ def request_cert(nssdb, nickname, subject, principal, passwd_fname=None):
result = cm.obj_if.add_request(request_parameters)
try:
if result[0]:
- request = _cm_dbus_object(cm.bus, result[1], DBUS_CM_REQUEST_IF,
+ request = _cm_dbus_object(cm.bus, cm, result[1], DBUS_CM_REQUEST_IF,
DBUS_CM_IF, True)
except TypeError:
root_logger.error('Failed to get create new request.')
@@ -283,7 +335,7 @@ def start_tracking(nickname, secdir, password_file=None, command=None):
Returns certificate nickname.
"""
- cm = _connect_to_certmonger()
+ cm = _certmonger()
params = {'TRACK': True}
params['cert-nickname'] = nickname
params['cert-database'] = os.path.abspath(secdir)
@@ -302,7 +354,7 @@ def start_tracking(nickname, secdir, password_file=None, command=None):
result = cm.obj_if.add_request(params)
try:
if result[0]:
- request = _cm_dbus_object(cm.bus, result[1], DBUS_CM_REQUEST_IF,
+ request = _cm_dbus_object(cm.bus, cm, result[1], DBUS_CM_REQUEST_IF,
DBUS_CM_IF, True)
except TypeError, e:
root_logger.error('Failed to add new request.')
@@ -330,7 +382,7 @@ def stop_tracking(secdir, request_id=None, nickname=None):
root_logger.error('Failed to get request: %s' % e)
raise
if request:
- cm = _connect_to_certmonger()
+ cm = _certmonger()
cm.obj_if.remove_request(request.path)
@@ -357,9 +409,9 @@ def _find_IPA_ca():
We can use find_request_value because the ca files have the
same file format.
"""
- cm = _connect_to_certmonger()
+ cm = _certmonger()
ca_path = cm.obj_if.find_ca_by_nickname('IPA')
- return _cm_dbus_object(cm.bus, ca_path, DBUS_CM_CA_IF, DBUS_CM_IF, True)
+ return _cm_dbus_object(cm.bus, cm, ca_path, DBUS_CM_CA_IF, DBUS_CM_IF, True)
def add_principal_to_cas(principal):
@@ -423,7 +475,7 @@ def dogtag_start_tracking(ca, nickname, pin, pinfile, secdir, pre_command,
Both commands can be None.
"""
- cm = _connect_to_certmonger()
+ cm = _certmonger()
certmonger_cmd_template = paths.CERTMONGER_COMMAND_TEMPLATE
params = {'TRACK': True}
--
2.4.3
From eb2091470d44de1b8e98fe5578b515ec3703b2b9 Mon Sep 17 00:00:00 2001
From: David Kupka <dku...@redhat.com>
Date: Tue, 7 Jul 2015 15:49:51 +0200
Subject: [PATCH] ipa-client-install: Do not (re)start certmonger and DBus
daemons.
When DBus is present in the system it is always running.
Starting of certmomger is handled in ipapython/certmonger.py module if
necessary. Restarting is no longer needed since freeipa is not changing
certmonger's files.
---
ipa-client/ipa-install/ipa-client-install | 75 +++++++------------------------
1 file changed, 17 insertions(+), 58 deletions(-)
diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install
index 8bc3fbe9aa0f8f24e3ddf9818f4047d2d803c991..306a5c3117c746876974e8183eefa7f6a0e62b06 100755
--- a/ipa-client/ipa-install/ipa-client-install
+++ b/ipa-client/ipa-install/ipa-client-install
@@ -517,20 +517,7 @@ def uninstall(options, env):
ipa_db = certdb.NSSDatabase(paths.IPA_NSSDB_DIR)
sys_db = certdb.NSSDatabase(paths.NSS_DB_DIR)
- # Always start certmonger. We can't untrack something if it isn't
- # running
- messagebus = services.knownservices.messagebus
- try:
- messagebus.start()
- except Exception, e:
- log_service_error(messagebus.service_name, 'start', e)
-
cmonger = services.knownservices.certmonger
- try:
- cmonger.start()
- except Exception, e:
- log_service_error(cmonger.service_name, 'start', e)
-
if ipa_db.has_nickname('Local IPA host'):
try:
certmonger.stop_tracking(paths.IPA_NSSDB_DIR,
@@ -571,15 +558,15 @@ def uninstall(options, env):
nickname, sys_db.secdir, e)
break
- try:
- cmonger.stop()
- except Exception, e:
- log_service_error(cmonger.service_name, 'stop', e)
-
# Remove any special principal names we added to the IPA CA helper
certmonger.remove_principal_from_cas()
try:
+ cmonger.stop()
+ except Exception, e:
+ log_service_error(cmonger.service_name, 'stop', e)
+
+ try:
cmonger.disable()
except Exception, e:
root_logger.error(
@@ -1133,41 +1120,14 @@ def configure_certmonger(fstore, subject_base, cli_realm, hostname, options,
"Not requesting host certificate.")
return
- started = True
principal = 'host/%s@%s' % (hostname, cli_realm)
- messagebus = services.knownservices.messagebus
- try:
- messagebus.start()
- except Exception, e:
- log_service_error(messagebus.service_name, 'start', e)
-
- # Ensure that certmonger has been started at least once to generate the
- # cas files in /var/lib/certmonger/cas.
- cmonger = services.knownservices.certmonger
- try:
- cmonger.restart()
- except Exception, e:
- log_service_error(cmonger.service_name, 'restart', e)
-
if options.hostname:
- # It needs to be stopped if we touch them
- try:
- cmonger.stop()
- except Exception, e:
- log_service_error(cmonger.service_name, 'stop', e)
# If the hostname is explicitly set then we need to tell certmonger
# which principal name to use when requesting certs.
certmonger.add_principal_to_cas(principal)
- try:
- cmonger.restart()
- except Exception, e:
- log_service_error(cmonger.service_name, 'restart', e)
- root_logger.warning(
- "Automatic certificate management will not be available")
- started = False
-
+ cmonger = services.knownservices.certmonger
try:
cmonger.enable()
except Exception, e:
@@ -1178,18 +1138,17 @@ def configure_certmonger(fstore, subject_base, cli_realm, hostname, options,
"Automatic certificate management will not be available")
# Request our host cert
- if started:
- subject = str(DN(('CN', hostname), subject_base))
- passwd_fname = os.path.join(paths.IPA_NSSDB_DIR, 'pwdfile.txt')
- try:
- certmonger.request_cert(nssdb=paths.IPA_NSSDB_DIR,
- nickname='Local IPA host',
- subject=subject,
- principal=principal,
- passwd_fname=passwd_fname)
- except Exception:
- root_logger.error("%s request for host certificate failed",
- cmonger.service_name)
+ subject = str(DN(('CN', hostname), subject_base))
+ passwd_fname = os.path.join(paths.IPA_NSSDB_DIR, 'pwdfile.txt')
+ try:
+ certmonger.request_cert(nssdb=paths.IPA_NSSDB_DIR,
+ nickname='Local IPA host',
+ subject=subject,
+ principal=principal,
+ passwd_fname=passwd_fname)
+ except Exception:
+ root_logger.error("%s request for host certificate failed",
+ cmonger.service_name)
def configure_sssd_conf(fstore, cli_realm, cli_domain, cli_server, options, client_domain, client_hostname):
try:
--
2.4.3
--
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code