Blob Blame History Raw
From 931c7fc1ada309a2d0fe832c95e5a5bf4a89edac Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Mon, 8 Apr 2019 11:43:59 +0300
Subject: [PATCH] Bypass D-BUS interface definition deficiences for
 trust-fetch-domains

In oddjobd it is possible to pass arguments as command line or on the
stdin. We use command line to pass them but the way oddjobd registers
the D-BUS method signatures is by specifying all arguments as mandatory.

Internally, oddjobd simply ignores if you passed less arguments than
specified in the D-BUS defition. Unfortunately, it is not possible to
specify less than maximum due to D-BUS seeing all arguments in the
list (30 is defined for the trust-fetch-domains).

To pass options, have to pad a list of arguments to maximum with empty
strings and then filter out unneeded ones in the script. Option parser
already removes all options from the list of arguments so all we need to
do is to take our actual arguments. In case of trust-fetch-domains, it
is the name of the domain so we can only care about args[0].

Fixes: https://pagure.io/freeipa/issue/7903
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
(cherry picked from commit add6180ae5c5771b0b0f1c743df069ece4256512)

Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
---
 .../oddjob/com.redhat.idm.trust-fetch-domains | 21 ++++++++++++-------
 ipaserver/plugins/trust.py                    | 11 ++++++++--
 2 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/install/oddjob/com.redhat.idm.trust-fetch-domains b/install/oddjob/com.redhat.idm.trust-fetch-domains
index 1e90759e0e6e7be36745ec12f4478bfec0f0358e..029de781b2a1f94b1fd281b79aa69a1e9422dede 100755
--- a/install/oddjob/com.redhat.idm.trust-fetch-domains
+++ b/install/oddjob/com.redhat.idm.trust-fetch-domains
@@ -5,6 +5,7 @@ from ipaserver.install.installutils import is_ipa_configured, ScriptError
 from ipapython import config, ipautil
 from ipalib import api
 from ipapython.dn import DN
+from ipapython.dnsutil import DNSName
 from ipaplatform.constants import constants
 from ipaplatform.paths import paths
 import sys
@@ -37,7 +38,17 @@ def parse_options():
     options, args = parser.parse_args()
     safe_options = parser.get_safe_opts(options)
 
-    return safe_options, options, args
+    # We only use first argument of the passed args but as D-BUS interface
+    # in oddjobd cannot expose optional, we fill in empty slots from IPA side
+    # and filter them here.
+    trusted_domain = ipautil.fsdecode(args[0]).lower()
+
+    # Accept domain names that at least have two labels. We do not support
+    # single label Active Directory domains. This also catches empty args.
+    if len(DNSName(trusted_domain).labels) < 2:
+        # LSB status code 2: invalid or excess argument(s)
+        raise ScriptError("You must specify a valid trusted domain name", 2)
+    return safe_options, options, trusted_domain
 
 def retrieve_keytab(api, ccache_name, oneway_keytab_name, oneway_principal):
     getkeytab_args = ["/usr/sbin/ipa-getkeytab",
@@ -87,13 +98,7 @@ if not os.getegid() == 0:
     # LSB status code 4: user had insufficient privilege
     raise ScriptError("You must be root to run ipactl.", 4)
 
-safe_options, options, args = parse_options()
-
-if len(args) != 1:
-    # LSB status code 2: invalid or excess argument(s)
-    raise ScriptError("You must specify trusted domain name", 2)
-
-trusted_domain = ipautil.fsdecode(args[0]).lower()
+safe_options, options, trusted_domain = parse_options()
 
 api.bootstrap(in_server=True, log=None,
               context='server', confdir=paths.ETC_IPA)
diff --git a/ipaserver/plugins/trust.py b/ipaserver/plugins/trust.py
index bb9e0fe3303989c49cf339df6e5aeeb4ce1435cf..5de363bda6fdee081d3e4c98e731cecfa9585d21 100644
--- a/ipaserver/plugins/trust.py
+++ b/ipaserver/plugins/trust.py
@@ -446,8 +446,15 @@ def fetch_trusted_domains_over_dbus(myapi, *keys, **options):
         fetch_domains_method = intf.get_dbus_method(
                 'fetch_domains',
                 dbus_interface=DBUS_IFACE_TRUST)
-        (_ret, _stdout, _stderr) = fetch_domains_method(
-            [forest_name] + method_options)
+        # Oddjobd D-BUS method definition only accepts fixed number
+        # of arguments on the command line. Thus, we need to pass
+        # remaining ones as ''. There are 30 slots to allow for extension
+        # and the number comes from the 'arguments' definition in
+        # install/oddjob/etc/oddjobd.conf.d/oddjobd-ipa-trust.conf
+        method_arguments = [forest_name]
+        method_arguments.extend(method_options)
+        method_arguments.extend([''] * (30 - len(method_arguments)))
+        (_ret, _stdout, _stderr) = fetch_domains_method(*method_arguments)
     except dbus.DBusException as e:
         logger.error('Failed to call %s.fetch_domains helper.'
                      'DBus exception is %s.', DBUS_IFACE_TRUST, str(e))
-- 
2.20.1