On 11.12.2015 07:08, Jan Cholasta wrote:
On 10.12.2015 15:56, Martin Babinsky wrote:
On 12/10/2015 09:48 AM, Jan Cholasta wrote:
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.




Patches work as expected and I was not able to find any functional
problem.

I have a question about the naming of the oddjob helper script: the one
related to trusts is named 'com.redhat.idm.trust-fetch-domains', and the
conncheck runner is named 'org.freeipa.server.conncheck'. I don't want
to start another bikeshedding conversation but shouldn't we named them
in a consistent fashion (either rename the first one in separate patch
or rename the new helper to com.redhat.idm.server.conncheck)?

I understand that as an upstream, we should go with the 'org.freeipa.*'
convention, but having two helpers with different prefixes makes me sad.

If you look at the larger picture, org.freeipa is the consistent name.
It makes me sad as well, but mistakes should be corrected. This is
similar to how we use PEP8 in new code, but do not fix it in old code
just for the sake of fixing it.


That is a nitpick though, it does not affect the overall functionality
of the patches so ACK.

Thanks for the review. The current patch 523 breaks the trusts oddjob
with SELinux in enforcing mode, I will send an update which corrects
that, until bug 1289930 is fixed.

Updated patches attached.

--
Jan Cholasta
From efe9776a0484fb0bc2faa528ac2d104f6d28e1ca 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            | 4 ++++
 install/oddjob/Makefile.am | 2 +-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/freeipa.spec.in b/freeipa.spec.in
index a60d9b6..cd986d1 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -434,6 +434,9 @@ make client-install DESTDIR=%{buildroot}
 mkdir -p %{buildroot}%{_usr}/share/ipa
 
 %if ! %{ONLY_CLIENT}
+# FIXME: https://bugzilla.redhat.com/show_bug.cgi?id=1289930
+mv %{buildroot}%{_libexecdir}/ipa/oddjob/com.redhat.idm.trust-fetch-domains %{buildroot}%{_libexecdir}/ipa/com.redhat.idm.trust-fetch-domains
+
 # Remove .la files from libtool - we don't want to package
 # these files
 rm %{buildroot}/%{plugin_dir}/libipa_pwd_extop.la
@@ -740,6 +743,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
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
 
-- 
2.4.3

From 60fdccb6618536d92384ccde5553c5ca2650ea7c 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/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 +
 20 files changed, 300 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 cd986d1..43c5129 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
@@ -573,6 +573,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
@@ -596,6 +598,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
 
@@ -744,12 +748,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/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 97f19c7..eab837b 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 4a08ed7759c774628bd63172deed73ec6f0d834e 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 eab837b..9447b97 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