On 9.12.2015 16:38, Jan Cholasta wrote:
On 9.12.2015 14:52, Jan Cholasta wrote:
On 9.12.2015 10:02, Jan Cholasta wrote:
Hi,

the attached patches fix <https://fedorahosted.org/freeipa/ticket/5497>.

Note that this needs selinux-policy fix to work, so put SELinux into
permissive mode for testing:
<https://bugzilla.redhat.com/show_bug.cgi?id=1289930>.

Updated patches attached.

I screwed up a change in patch 524 and accidentally included a chunk of code in patch 525 that doesn't belong in it.

Updated patches attached.

--
Jan Cholasta
From f807735945e95f13259faf5c8e952a324466c376 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Wed, 9 Dec 2015 08:17:07 +0100
Subject: [PATCH 1/3] build: put oddjob scripts into separate directory

https://fedorahosted.org/freeipa/ticket/5497
---
 freeipa.spec.in                                          | 3 ++-
 install/oddjob/Makefile.am                               | 2 +-
 install/oddjob/etc/oddjobd.conf.d/oddjobd-ipa-trust.conf | 2 +-
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/freeipa.spec.in b/freeipa.spec.in
index a60d9b6..95948e7 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -740,6 +740,7 @@ fi
 %{_libexecdir}/ipa/ipa-dnskeysync-replica
 %{_libexecdir}/ipa/ipa-ods-exporter
 %{_libexecdir}/ipa/ipa-httpd-kdcproxy
+%dir %{_libexecdir}/ipa/oddjob
 %ghost %verify(not owner group) %dir %{_sharedstatedir}/kdcproxy
 %dir %attr(0755,root,root) %{_sysconfdir}/ipa/kdcproxy
 %config(noreplace) %{_sysconfdir}/sysconfig/ipa_memcached
@@ -914,7 +915,7 @@ fi
 %ghost %{_libdir}/krb5/plugins/libkrb5/winbind_krb5_locator.so
 %{_sysconfdir}/dbus-1/system.d/oddjob-ipa-trust.conf
 %{_sysconfdir}/oddjobd.conf.d/oddjobd-ipa-trust.conf
-%%attr(755,root,root) %{_libexecdir}/ipa/com.redhat.idm.trust-fetch-domains
+%attr(755,root,root) %{_libexecdir}/ipa/oddjob/com.redhat.idm.trust-fetch-domains
 
 %endif # ONLY_CLIENT
 
diff --git a/install/oddjob/Makefile.am b/install/oddjob/Makefile.am
index 9dde10c..5cdaf2b 100644
--- a/install/oddjob/Makefile.am
+++ b/install/oddjob/Makefile.am
@@ -1,6 +1,6 @@
 NULL =
 
-oddjobdir = $(libexecdir)/ipa
+oddjobdir = $(libexecdir)/ipa/oddjob
 oddjobconfdir = $(sysconfdir)/oddjobd.conf.d
 dbusconfdir = $(sysconfdir)/dbus-1/system.d
 
diff --git a/install/oddjob/etc/oddjobd.conf.d/oddjobd-ipa-trust.conf b/install/oddjob/etc/oddjobd.conf.d/oddjobd-ipa-trust.conf
index 17817de..bc2e8d1 100644
--- a/install/oddjob/etc/oddjobd.conf.d/oddjobd-ipa-trust.conf
+++ b/install/oddjob/etc/oddjobd.conf.d/oddjobd-ipa-trust.conf
@@ -10,7 +10,7 @@
       </interface>
       <interface name="com.redhat.idm.trust">
         <method name="fetch_domains">
-          <helper exec="/usr/libexec/ipa/com.redhat.idm.trust-fetch-domains"
+          <helper exec="/usr/libexec/ipa/oddjob/com.redhat.idm.trust-fetch-domains"
 		  arguments="1"
                   argument_passing_method="cmdline"
 		  prepend_user_name="no"/>
-- 
2.4.3

From b1b4bd0f6c2485e6b019455133a87db329b9f85c Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Wed, 9 Dec 2015 08:18:21 +0100
Subject: [PATCH 2/3] replica install: add remote connection check over API

Add server_conncheck command which calls ipa-replica-conncheck --replica
over oddjob.

https://fedorahosted.org/freeipa/ticket/5497
---
 API.txt                                            |   8 ++
 VERSION                                            |   4 +-
 freeipa.spec.in                                    |   9 +-
 install/oddjob/Makefile.am                         |   3 +
 .../etc/dbus-1/system.d/org.freeipa.server.conf    |  21 ++++
 install/oddjob/etc/oddjobd.conf.d/ipa-server.conf  |  20 ++++
 install/oddjob/org.freeipa.server.conncheck        |   2 +
 install/tools/ipa-ca-install                       |   6 +
 install/tools/ipa-replica-conncheck                | 131 ++++++++++++++++++---
 install/updates/90-post_upgrade_plugins.update     |   1 -
 ipalib/errors.py                                   |   1 +
 ipalib/messages.py                                 |  10 ++
 ipalib/plugins/server.py                           |  70 ++++++++++-
 ipaserver/install/adtrustinstance.py               |  19 ---
 ipaserver/install/ca.py                            |   2 +-
 ipaserver/install/httpinstance.py                  |  26 ++++
 ipaserver/install/installutils.py                  |  12 --
 ipaserver/install/plugins/adtrust.py               |  21 ----
 ipaserver/install/replication.py                   |   6 +-
 ipaserver/install/server/replicainstall.py         |   6 +-
 ipaserver/install/server/upgrade.py                |   1 +
 21 files changed, 301 insertions(+), 78 deletions(-)
 create mode 100644 install/oddjob/etc/dbus-1/system.d/org.freeipa.server.conf
 create mode 100644 install/oddjob/etc/oddjobd.conf.d/ipa-server.conf
 create mode 100755 install/oddjob/org.freeipa.server.conncheck

diff --git a/API.txt b/API.txt
index 60c98c3..15be32c 100644
--- a/API.txt
+++ b/API.txt
@@ -3812,6 +3812,14 @@ option: Str('version?', exclude='webui')
 output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: PrimaryKey('value', None, None)
+command: server_conncheck
+args: 2,1,3
+arg: Str('cn', attribute=True, cli_name='name', multivalue=False, primary_key=True, query=True, required=True)
+arg: Str('remote_cn', cli_name='remote_name')
+option: Str('version?', exclude='webui')
+output: Output('result', <type 'bool'>, None)
+output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
+output: PrimaryKey('value', None, None)
 command: server_del
 args: 1,2,3
 arg: Str('cn', attribute=True, cli_name='name', multivalue=True, primary_key=True, query=True, required=True)
diff --git a/VERSION b/VERSION
index b7f261b..df12ec0 100644
--- a/VERSION
+++ b/VERSION
@@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
 #                                                      #
 ########################################################
 IPA_API_VERSION_MAJOR=2
-IPA_API_VERSION_MINOR=161
-# Last change: pvoborni - topologysuffix: change iparepltopomanagedsuffix type
+IPA_API_VERSION_MINOR=162
+# Last change: jcholast - replica install: add remote connection check over API
diff --git a/freeipa.spec.in b/freeipa.spec.in
index 95948e7..d3e0d56 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -165,6 +165,7 @@ Requires: %{etc_systemd_dir}
 Requires: gzip
 Requires: python-gssapi >= 1.1.0
 Requires: custodia
+Requires: oddjob
 
 Provides: %{alt_name}-server = %{version}
 Conflicts: %{alt_name}-server
@@ -229,7 +230,6 @@ Requires: samba >= %{samba_version}
 Requires: samba-winbind
 Requires: libsss_idmap
 Requires: python-libsss_nss_idmap
-Requires: oddjob
 Requires: python-sss
 # We use alternatives to divert winbind_krb5_locator.so plugin to libkrb5
 # on the installes where server-trust-ad subpackage is installed because
@@ -570,6 +570,8 @@ rm -rf %{buildroot}
 if [ $1 -gt 1 ] ; then
     /bin/systemctl condrestart certmonger.service 2>&1 || :
 fi
+/bin/systemctl reload-or-try-restart dbus
+/bin/systemctl reload-or-try-restart oddjobd
 
 %posttrans server
 # This must be run in posttrans so that updates from previous
@@ -593,6 +595,8 @@ if [ $1 = 0 ]; then
 # NOTE: systemd specific section
     /bin/systemctl --quiet stop ipa.service || :
     /bin/systemctl --quiet disable ipa.service || :
+    /bin/systemctl reload-or-try-restart dbus
+    /bin/systemctl reload-or-try-restart oddjobd
 # END
 fi
 
@@ -741,12 +745,15 @@ fi
 %{_libexecdir}/ipa/ipa-ods-exporter
 %{_libexecdir}/ipa/ipa-httpd-kdcproxy
 %dir %{_libexecdir}/ipa/oddjob
+%attr(0755,root,root) %{_libexecdir}/ipa/oddjob/org.freeipa.server.conncheck
 %ghost %verify(not owner group) %dir %{_sharedstatedir}/kdcproxy
 %dir %attr(0755,root,root) %{_sysconfdir}/ipa/kdcproxy
 %config(noreplace) %{_sysconfdir}/sysconfig/ipa_memcached
 %config(noreplace) %{_sysconfdir}/sysconfig/ipa-dnskeysyncd
 %config(noreplace) %{_sysconfdir}/sysconfig/ipa-ods-exporter
 %config(noreplace) %{_sysconfdir}/ipa/kdcproxy/kdcproxy.conf
+%config(noreplace) %{_sysconfdir}/dbus-1/system.d/org.freeipa.server.conf
+%config(noreplace) %{_sysconfdir}/oddjobd.conf.d/ipa-server.conf
 %dir %attr(0700,apache,apache) %{_localstatedir}/run/ipa_memcached/
 %dir %attr(0700,root,root) %{_localstatedir}/run/ipa/
 %dir %attr(0700,apache,apache) %{_localstatedir}/run/httpd/ipa/
diff --git a/install/oddjob/Makefile.am b/install/oddjob/Makefile.am
index 5cdaf2b..fb64f6c 100644
--- a/install/oddjob/Makefile.am
+++ b/install/oddjob/Makefile.am
@@ -6,14 +6,17 @@ dbusconfdir = $(sysconfdir)/dbus-1/system.d
 
 oddjob_SCRIPTS =				\
 	com.redhat.idm.trust-fetch-domains	\
+	org.freeipa.server.conncheck		\
 	$(NULL)
 
 dbusconf_DATA =						\
 	etc/dbus-1/system.d/oddjob-ipa-trust.conf	\
+	etc/dbus-1/system.d/org.freeipa.server.conf	\
 	$(NULL)
 
 oddjobconf_DATA =					\
 	etc/oddjobd.conf.d/oddjobd-ipa-trust.conf	\
+	etc/oddjobd.conf.d/ipa-server.conf		\
 	$(NULL)
 
 
diff --git a/install/oddjob/etc/dbus-1/system.d/org.freeipa.server.conf b/install/oddjob/etc/dbus-1/system.d/org.freeipa.server.conf
new file mode 100644
index 0000000..b2cbf74
--- /dev/null
+++ b/install/oddjob/etc/dbus-1/system.d/org.freeipa.server.conf
@@ -0,0 +1,21 @@
+<!DOCTYPE busconfig PUBLIC
+ "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd";>
+
+<busconfig>
+
+  <policy user="root">
+    <allow own="org.freeipa.server"/>
+
+    <allow send_destination="org.freeipa.server" send_interface="org.freeipa.server"/>
+  </policy>
+
+  <policy user="apache">
+    <allow send_destination="org.freeipa.server" send_interface="org.freeipa.server"/>
+  </policy>
+
+  <policy context="default">
+    <allow send_destination="org.freeipa.server" send_interface="org.freedesktop.DBus.Introspectable"/>
+  </policy>
+
+</busconfig>
diff --git a/install/oddjob/etc/oddjobd.conf.d/ipa-server.conf b/install/oddjob/etc/oddjobd.conf.d/ipa-server.conf
new file mode 100644
index 0000000..3f80696
--- /dev/null
+++ b/install/oddjob/etc/oddjobd.conf.d/ipa-server.conf
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<oddjobconfig>
+  <service name="org.freeipa.server">
+    <allow user="root"/>
+    <allow user="apache"/>
+    <object name="/">
+      <interface name="org.freeipa.server">
+        <method name="conncheck">
+          <helper exec="/usr/libexec/ipa/oddjob/org.freeipa.server.conncheck"
+                  arguments="1"
+                  prepend_user_name="no"
+                  argument_passing_method="cmdline"/>
+        </method>
+      </interface>
+      <interface name="org.freedesktop.DBus.Introspectable">
+        <allow min_uid="0" max_uid="0"/>
+      </interface>
+    </object>
+  </service>
+</oddjobconfig>
diff --git a/install/oddjob/org.freeipa.server.conncheck b/install/oddjob/org.freeipa.server.conncheck
new file mode 100755
index 0000000..ab7a46a
--- /dev/null
+++ b/install/oddjob/org.freeipa.server.conncheck
@@ -0,0 +1,2 @@
+#!/bin/sh
+exec /usr/sbin/ipa-replica-conncheck --replica "$1" 2>&1
diff --git a/install/tools/ipa-ca-install b/install/tools/ipa-ca-install
index b1d58f7..0b8f28c 100755
--- a/install/tools/ipa-ca-install
+++ b/install/tools/ipa-ca-install
@@ -149,8 +149,10 @@ def install_replica(safe_options, options, filename):
         config.ca_ds_port = 389
         config.top_dir = tempfile.mkdtemp("ipa")
         config.dir = config.top_dir
+        cafile = paths.IPA_CA_CRT
     else:
         config = create_replica_config(dirman_password, filename, options)
+        cafile = config.dir + '/ca.crt'
 
     global REPLICA_INFO_TOP_DIR
     REPLICA_INFO_TOP_DIR = config.top_dir
@@ -176,6 +178,10 @@ def install_replica(safe_options, options, filename):
     options.dm_password = config.dirman_password
     options.host_name = config.host_name
     options.subject = config.subject_base
+    if os.path.exists(cafile):
+        options.ca_cert_file = cafile
+    else:
+        options.ca_cert_file = None
 
     ca.install_check(True, config, options)
     if options.promote:
diff --git a/install/tools/ipa-replica-conncheck b/install/tools/ipa-replica-conncheck
index a67837c..10e3437 100755
--- a/install/tools/ipa-replica-conncheck
+++ b/install/tools/ipa-replica-conncheck
@@ -22,11 +22,12 @@ from __future__ import print_function
 
 from ipapython.config import IPAOptionParser
 from ipapython import version
-from ipapython import ipautil
+from ipapython import ipautil, certdb
 from ipapython.ipautil import CalledProcessError
+from ipalib import api, errors, x509
 from ipaserver.install import installutils
 import ipaclient.ipachangeconf
-from optparse import OptionGroup
+from optparse import OptionGroup, OptionValueError
 from ipapython.ipa_log_manager import *
 import sys
 import os
@@ -40,6 +41,7 @@ from socket import SOCK_STREAM, SOCK_DGRAM
 import distutils.spawn
 from ipaplatform.paths import paths
 import gssapi
+from nss import nss
 
 CONNECT_TIMEOUT = 5
 RESPONDERS = [ ]
@@ -106,6 +108,30 @@ def print_info(msg):
         print(msg)
 
 def parse_options():
+    def ca_cert_file_callback(option, opt, value, parser):
+        if not os.path.exists(value):
+            raise OptionValueError(
+                "%s option '%s' does not exist" % (opt, value))
+        if not os.path.isfile(value):
+            raise OptionValueError(
+                "%s option '%s' is not a file" % (opt, value))
+        if not os.path.isabs(value):
+            raise OptionValueError(
+                "%s option '%s' is not an absolute file path" % (opt, value))
+
+        initialized = nss.nss_is_initialized()
+        try:
+            x509.load_certificate_list_from_file(value)
+        except Exception:
+            raise OptionValueError(
+                "%s option '%s' is not a valid certificate file" %
+                (opt, value))
+        finally:
+            if not initialized:
+                nss.nss_shutdown()
+
+        parser.values.ca_cert_file = value
+
     parser = IPAOptionParser(version=version.VERSION)
 
     replica_group = OptionGroup(parser, "on-replica options")
@@ -123,6 +149,10 @@ def parse_options():
                       default=None, help="Principal to use to log in to remote master")
     replica_group.add_option("-w", "--password", dest="password", sensitive=True,
                       help="Password for the principal"),
+    replica_group.add_option("--ca-cert-file", dest="ca_cert_file",
+                             type="string", action="callback",
+                             callback=ca_cert_file_callback,
+                             help="load the CA certificate from this file")
     parser.add_option_group(replica_group)
 
 
@@ -418,22 +448,89 @@ def main():
                 if returncode != 0:
                     raise RuntimeError("Could not get ticket for master server: %s" % stderr)
 
-            user = principal.partition('@')[0]
-            ssh = SshExec(user, options.master)
+            try:
+                print_info("Check RPC connection to remote master")
+
+                xmlrpc_uri = ('https://%s/ipa/xml' %
+                              ipautil.format_netloc(options.master))
+                api.bootstrap(context='client', xmlrpc_uri=xmlrpc_uri)
+                api.finalize()
 
-            print_info("Check SSH connection to remote master")
-            stdout, stderr, returncode = ssh('echo OK', verbose=True)
-            if returncode != 0:
-                print('Could not SSH into remote host. Error output:')
-                for line in stderr.splitlines():
-                    print('    %s' % line)
-                raise RuntimeError('Could not SSH to remote host.')
-
-            print_info("Execute check on remote master")
-            stdout, stderr, returncode = ssh(
-                "/usr/sbin/ipa-replica-conncheck " +
-                    " ".join(remote_check_opts))
-            print_info(stdout)
+                if options.ca_cert_file:
+                    nss_dir = None
+                else:
+                    nss_dir = paths.IPA_NSSDB_DIR
+
+                with certdb.NSSDatabase(nss_dir) as nss_db:
+                    if options.ca_cert_file:
+                        nss_dir = nss_db.secdir
+
+                        password = ipautil.ipa_generate_password()
+                        password_file = ipautil.write_tmp_file(password)
+                        nss_db.create_db(password_file.name)
+
+                        ca_certs = x509.load_certificate_list_from_file(
+                            options.ca_cert_file, dbdir=nss_db.secdir)
+                        for ca_cert in ca_certs:
+                            nss_db.add_cert(
+                                ca_cert.der_data, str(ca_cert.subject), 'C,,')
+                            del ca_cert
+                        del ca_certs
+                    else:
+                        nss_dir = None
+
+                    try:
+                        api.Backend.rpcclient.connect(nss_dir=nss_dir)
+                        api.Command.ping()
+                    except Exception as e:
+                        print_info(
+                            "Could not connect to the remote host: %s" % e)
+                        raise
+
+                    print_info("Execute check on remote master")
+                    try:
+                        result = api.Backend.rpcclient.forward(
+                            'server_conncheck',
+                            ipautil.fsdecode(options.master),
+                            ipautil.fsdecode(options.hostname),
+                            version=u'2.162',
+                        )
+                    except (errors.CommandError, errors.NetworkError) as e:
+                        print_info(
+                            "Remote master does not support check over RPC: "
+                            "%s" % e)
+                        raise
+                    except errors.PublicError as e:
+                        returncode = 1
+                        stderr = e
+                    else:
+                        for message in result['messages']:
+                            print_info(message['message'])
+                        returncode = int(not result['result'])
+                        stderr = ("ipa-replica-conncheck returned non-zero "
+                                  "exit code")
+                    finally:
+                        if api.Backend.rpcclient.isconnected():
+                            api.Backend.rpcclient.disconnect()
+            except Exception:
+                print_info("Retrying using SSH...")
+
+                user = principal.partition('@')[0]
+                ssh = SshExec(user, options.master)
+
+                print_info("Check SSH connection to remote master")
+                stdout, stderr, returncode = ssh('echo OK', verbose=True)
+                if returncode != 0:
+                    print('Could not SSH into remote host. Error output:')
+                    for line in stderr.splitlines():
+                        print('    %s' % line)
+                    raise RuntimeError('Could not SSH to remote host.')
+
+                print_info("Execute check on remote master")
+                stdout, stderr, returncode = ssh(
+                    "/usr/sbin/ipa-replica-conncheck " +
+                        " ".join(remote_check_opts))
+                print_info(stdout)
             if returncode != 0:
                 raise RuntimeError("Remote master check failed with following error message(s):\n%s" % stderr)
         else:
diff --git a/install/updates/90-post_upgrade_plugins.update b/install/updates/90-post_upgrade_plugins.update
index 2089b33..626255a 100644
--- a/install/updates/90-post_upgrade_plugins.update
+++ b/install/updates/90-post_upgrade_plugins.update
@@ -19,4 +19,3 @@ plugin: update_managed_post
 plugin: update_managed_permissions
 plugin: update_idrange_baserid
 plugin: update_passync_privilege_update
-plugin: update_oddjobd_for_adtrust
diff --git a/ipalib/errors.py b/ipalib/errors.py
index b82d199..0fa540b 100644
--- a/ipalib/errors.py
+++ b/ipalib/errors.py
@@ -1372,6 +1372,7 @@ class InvalidDomainLevelError(ExecutionError):
     errno = 4032
     format = _('%(reason)s')
 
+
 class BuiltinError(ExecutionError):
     """
     **4100** Base class for builtin execution errors (*4100 - 4199*).
diff --git a/ipalib/messages.py b/ipalib/messages.py
index 44fee6d..078e13f 100644
--- a/ipalib/messages.py
+++ b/ipalib/messages.py
@@ -321,6 +321,16 @@ class CommandDeprecatedWarning(PublicMessage):
     format = _(u"'%(command)s' is deprecated. %(additional_info)s")
 
 
+class ExternalCommandOutput(PublicMessage):
+    """
+    **13016** Line of output from an external command.
+    """
+
+    errno = 13016
+    type = "info"
+    format = _("%(line)s")
+
+
 def iter_messages(variables, base):
     """Return a tuple with all subclasses
     """
diff --git a/ipalib/plugins/server.py b/ipalib/plugins/server.py
index 8284a58..6286c59 100644
--- a/ipalib/plugins/server.py
+++ b/ipalib/plugins/server.py
@@ -5,11 +5,15 @@
 import string
 import os
 
-from ipalib import api
+import dbus
+import dbus.mainloop.glib
+
+from ipalib import api, crud, errors, messages
 from ipalib import Int, Str
 from ipalib.plugable import Registry
 from ipalib.plugins.baseldap import *
 from ipalib.plugins import baseldap
+from ipalib.request import context
 from ipalib import _, ngettext
 
 __doc__ = _("""
@@ -188,3 +192,67 @@ class server_del(LDAPDelete):
     __doc__ = _('Delete IPA server.')
     NO_CLI = True
     msg_summary = _('Deleted IPA server "%(value)s"')
+
+
+@register()
+class server_conncheck(crud.PKQuery):
+    __doc__ = _("Check connection to remote IPA server.")
+
+    NO_CLI = True
+
+    takes_args = (
+        Str(
+            'remote_cn',
+            cli_name='remote_name',
+            label=_('Remote server name'),
+            doc=_('Remote IPA server hostname'),
+        ),
+    )
+
+    has_output = output.standard_value
+
+    def execute(self, *keys, **options):
+        # the server must be the local host
+        if keys[-2] != api.env.host:
+            raise errors.ValidationError(
+                name='cn', error=_("must be \"%s\"") % api.env.host)
+
+        # the server entry must exist
+        try:
+            self.obj.get_dn_if_exists(*keys[:-1])
+        except errors.NotFound:
+            self.obj.handle_not_found(keys[-2])
+
+        # the user must have the Replication Administrators privilege
+        privilege = u'Replication Administrators'
+        privilege_dn = self.api.Object.privilege.get_dn(privilege)
+        ldap = self.obj.backend
+        filter = ldap.make_filter(
+            {'krbprincipalname': context.principal, 'memberof': privilege_dn},
+            rules=ldap.MATCH_ALL)
+        try:
+            ldap.find_entries(base_dn=self.api.env.basedn, filter=filter)
+        except errors.NotFound:
+            raise errors.ACIError(
+                info=_("not allowed to perform server connection check"))
+
+        dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+
+        bus = dbus.SystemBus()
+        obj = bus.get_object('org.freeipa.server', '/',
+                             follow_name_owner_changes=True)
+        server = dbus.Interface(obj, 'org.freeipa.server')
+
+        ret, stdout, stderr = server.conncheck(keys[-1])
+
+        result = dict(
+            result=(ret == 0),
+            value=keys[-2],
+        )
+
+        for line in stdout.splitlines():
+            messages.add_message(options['version'],
+                                 result,
+                                 messages.ExternalCommandOutput(line=line))
+
+        return result
diff --git a/ipaserver/install/adtrustinstance.py b/ipaserver/install/adtrustinstance.py
index 813d48e..118f848 100644
--- a/ipaserver/install/adtrustinstance.py
+++ b/ipaserver/install/adtrustinstance.py
@@ -726,9 +726,6 @@ class ADTRUSTInstance(service.Service):
         except Exception as e:
             root_logger.critical("Enabling nsswitch support in slapi-nis failed with error '%s'" % e)
 
-    def  __enable_and_start_oddjobd(self):
-        installutils.enable_and_start_oddjobd(self.sstore)
-
     def __start(self):
         try:
             self.start()
@@ -881,7 +878,6 @@ class ADTRUSTInstance(service.Service):
         self.step("adding Default Trust View", self.__add_default_trust_view)
         self.step("setting SELinux booleans", \
                   self.__configure_selinux_for_smbd)
-        self.step("enabling oddjobd", self.__enable_and_start_oddjobd)
         self.step("starting CIFS services", self.__start)
 
         if self.add_sids:
@@ -911,21 +907,6 @@ class ADTRUSTInstance(service.Service):
         except Exception:
             pass
 
-        # Restore oddjobd to its original state
-        oddjobd = services.service('oddjobd')
-
-        if not self.sstore.restore_state('oddjobd', 'running'):
-            try:
-                oddjobd.stop()
-            except Exception:
-                pass
-
-        if not self.sstore.restore_state('oddjobd', 'enabled'):
-            try:
-                oddjobd.disable()
-            except Exception:
-                pass
-
         # Since we do not guarantee restoring back to working samba state,
         # we should not restore smb.conf
 
diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py
index 1a51ebc..36a7d57 100644
--- a/ipaserver/install/ca.py
+++ b/ipaserver/install/ca.py
@@ -40,7 +40,7 @@ def install_check(standalone, replica_config, options):
             replica_conn_check(
                 replica_config.master_host_name, host_name, realm_name, True,
                 replica_config.ca_ds_port, options.admin_password,
-                principal=principal)
+                principal=principal, ca_cert_file=options.ca_cert_file)
 
         if options.skip_schema_check or options.promote:
             root_logger.info("Skipping CA DS schema check")
diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
index 1b68573..b51cc4a 100644
--- a/ipaserver/install/httpinstance.py
+++ b/ipaserver/install/httpinstance.py
@@ -163,6 +163,7 @@ class HTTPInstance(service.Service):
             self.step("enable KDC proxy", self.enable_kdcproxy)
         self.step("restarting httpd", self.__start)
         self.step("configuring httpd to start on boot", self.__enable)
+        self.step("enabling oddjobd", self.enable_and_start_oddjobd)
 
         self.start_creation(runtime=60)
 
@@ -441,6 +442,17 @@ class HTTPInstance(service.Service):
             f.write(http_txt)
         os.chmod(target_fname, 0o644)
 
+    def enable_and_start_oddjobd(self):
+        oddjobd = services.service('oddjobd')
+        self.sstore.backup_state('oddjobd', 'running', oddjobd.is_running())
+        self.sstore.backup_state('oddjobd', 'enabled', oddjobd.is_enabled())
+
+        try:
+            oddjobd.enable()
+            oddjobd.start()
+        except Exception as e:
+            root_logger.critical("Unable to start oddjobd: {0}".format(str(e)))
+
     def uninstall(self):
         if self.is_configured():
             self.print_msg("Unconfiguring web server")
@@ -448,6 +460,20 @@ class HTTPInstance(service.Service):
         running = self.restore_state("running")
         enabled = self.restore_state("enabled")
 
+        # Restore oddjobd to its original state
+        oddjobd = services.service('oddjobd')
+
+        if not self.sstore.restore_state('oddjobd', 'running'):
+            try:
+                oddjobd.stop()
+            except Exception:
+                pass
+
+        if not self.sstore.restore_state('oddjobd', 'enabled'):
+            try:
+                oddjobd.disable()
+            except Exception:
+                pass
 
         self.stop_tracking_certificates()
 
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
index 156c8a5..bdbe2e3 100644
--- a/ipaserver/install/installutils.py
+++ b/ipaserver/install/installutils.py
@@ -1103,18 +1103,6 @@ def realm_to_ldapi_uri(realm_name):
     return 'ldapi://' + ldapurl.ldapUrlEscape(socketname)
 
 
-def enable_and_start_oddjobd(sstore):
-    oddjobd = services.service('oddjobd')
-    sstore.backup_state('oddjobd', 'running', oddjobd.is_running())
-    sstore.backup_state('oddjobd', 'enabled', oddjobd.is_enabled())
-
-    try:
-        oddjobd.enable()
-        oddjobd.start()
-    except Exception as e:
-        root_logger.critical("Unable to start oddjobd: {0}".format(str(e)))
-
-
 def install_service_keytab(principal, server, path, force_service_add=False):
 
     try:
diff --git a/ipaserver/install/plugins/adtrust.py b/ipaserver/install/plugins/adtrust.py
index 45bcc5f..5510dfd 100644
--- a/ipaserver/install/plugins/adtrust.py
+++ b/ipaserver/install/plugins/adtrust.py
@@ -164,26 +164,5 @@ class update_default_trust_view(Updater):
 
         return False, [update]
 
-
-class update_oddjobd_for_adtrust(Updater):
-    """
-    Enables and starts oddjobd daemon if ipa-adtrust-install has been run
-    on this system.
-    """
-
-    def execute(self, **options):
-        adtrust_is_enabled = self.api.Command['adtrust_is_enabled']()['result']
-
-        if adtrust_is_enabled:
-            self.log.debug('Try to enable and start oddjobd')
-            sstore = sysrestore.StateFile(paths.SYSRESTORE)
-            installutils.enable_and_start_oddjobd(sstore)
-        else:
-            self.log.debug('ADTrust not configured on this server, do not '
-                           'start and enable oddjobd')
-
-        return False, []
-
 api.register(update_default_range)
 api.register(update_default_trust_view)
-api.register(update_oddjobd_for_adtrust)
diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py
index aaa841c..ee1b507 100644
--- a/ipaserver/install/replication.py
+++ b/ipaserver/install/replication.py
@@ -67,7 +67,7 @@ STRIP_ATTRS = ('modifiersName',
 
 def replica_conn_check(master_host, host_name, realm, check_ca,
                        dogtag_master_ds_port, admin_password=None,
-                       principal="admin"):
+                       principal="admin", ca_cert_file=None):
     """
     Check the ports used by the replica both locally and remotely to be sure
     that replication will work.
@@ -89,6 +89,10 @@ def replica_conn_check(master_host, host_name, realm, check_ca,
 
     if check_ca and dogtag_master_ds_port == 7389:
         args.append('--check-ca')
+
+    if ca_cert_file:
+        args.extend(["--ca-cert-file", ca_cert_file])
+
     (stdin, stderr, returncode) = ipautil.run(
         args, raiseonerr=False, capture_output=False, nolog=nolog)
 
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
index 4f239aa..9c6b6e3 100644
--- a/ipaserver/install/server/replicainstall.py
+++ b/ipaserver/install/server/replicainstall.py
@@ -636,7 +636,8 @@ def install_check(installer):
     if not options.skip_conncheck:
         replica_conn_check(
             config.master_host_name, config.host_name, config.realm_name,
-            options.setup_ca, config.ca_ds_port, options.admin_password)
+            options.setup_ca, config.ca_ds_port, options.admin_password,
+            ca_cert_file=cafile)
 
     installer._remote_api = remote_api
     installer._fstore = fstore
@@ -1165,7 +1166,8 @@ def promote_check(installer):
             replica_conn_check(
                 config.master_host_name, config.host_name, config.realm_name,
                 options.setup_ca, 389,
-                options.admin_password, principal=options.principal)
+                options.admin_password, principal=options.principal,
+                ca_cert_file=cafile)
         finally:
             os.environ['KRB5CCNAME'] = ccache
 
diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py
index e193b85..8ac2355 100644
--- a/ipaserver/install/server/upgrade.py
+++ b/ipaserver/install/server/upgrade.py
@@ -1478,6 +1478,7 @@ def upgrade_configuration():
     http.configure_selinux_for_httpd()
     http.change_mod_nss_port_from_http()
     http.configure_certmonger_renewal_guard()
+    http.enable_and_start_oddjobd()
 
     ds.configure_dirsrv_ccache()
 
-- 
2.4.3

From 820d62bce2c64ecee6c0b1456ad8494577f9f958 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Wed, 9 Dec 2015 09:25:13 +0100
Subject: [PATCH 3/3] replica promotion: use host credentials for connection
 check

https://fedorahosted.org/freeipa/ticket/5497
---
 ipaserver/install/server/replicainstall.py | 25 ++++++++-----------------
 1 file changed, 8 insertions(+), 17 deletions(-)

diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
index 9c6b6e3..4720697 100644
--- a/ipaserver/install/server/replicainstall.py
+++ b/ipaserver/install/server/replicainstall.py
@@ -946,18 +946,6 @@ def promote_check(installer):
                          paths.KRB5_KEYTAB,
                          ccache)
 
-    if not options.skip_conncheck:
-        if installer._ccache is None:
-            del os.environ['KRB5CCNAME']
-        else:
-            os.environ['KRB5CCNAME'] = installer._ccache
-
-        try:
-            installutils.check_creds(options, config.realm_name)
-            installer._ccache = os.environ.get('KRB5CCNAME')
-        finally:
-            os.environ['KRB5CCNAME'] = ccache
-
     cafile = paths.IPA_CA_CRT
     if not ipautil.file_exists(cafile):
         raise RuntimeError("CA cert file is not available! Please reinstall"
@@ -1157,10 +1145,12 @@ def promote_check(installer):
 
     # check connection
     if not options.skip_conncheck:
-        if installer._ccache is None:
-            del os.environ['KRB5CCNAME']
-        else:
-            os.environ['KRB5CCNAME'] = installer._ccache
+        if add_to_ipaservers:
+            # use user's credentials when the server host is not ipaservers
+            if installer._ccache is None:
+                del os.environ['KRB5CCNAME']
+            else:
+                os.environ['KRB5CCNAME'] = installer._ccache
 
         try:
             replica_conn_check(
@@ -1169,7 +1159,8 @@ def promote_check(installer):
                 options.admin_password, principal=options.principal,
                 ca_cert_file=cafile)
         finally:
-            os.environ['KRB5CCNAME'] = ccache
+            if add_to_ipaservers:
+                os.environ['KRB5CCNAME'] = ccache
 
     if not ipautil.file_exists(cafile):
         raise RuntimeError("CA cert file is not available.")
-- 
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

Reply via email to