[Freeipa-devel] [PATCH] trust CLI: add ID range for new trusted domain

Sumit Bose sbose at redhat.com
Tue Aug 14 13:38:26 UTC 2012


Hi,

currently only a default ID range was used for users from trusted
domains. With these two patches an individual range is created during
ipa trust-add and it will be used by the extdom plugin to calculate the
Poisx UID for the users from the trusted domain.

'ipa trust-add' is getting two new options, --base-id and --range-size
to specify the first Posix ID of the range and the size of the range
respectively. If --range-size is not given the default will be 200000
and if --base-id is not given it will be calculated with the help of a
hash of the domain SID. To be compatible with the AD provider of SSSD
murmurhash3 is used here. The python binding for the hash will be
provided by SSSD, the patch is currently under review. But since it is
not required to have murmurhash3, an error message will be send if it is
not installed on the server, I think this patch can be pushed
independently of the SSSD patch.

bye,
Sumit
-------------- next part --------------
From f9515cb32526a078a01604c072a7bc6e9b265b19 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Mon, 6 Aug 2012 14:30:38 +0200
Subject: [PATCH 1/2] extdom: read ranges from LDAP

---
 .../ipa-extdom-extop/ipa_extdom_common.c           |   72 ++++++++++++++++++++
 1 Datei ge?ndert, 72 Zeilen hinzugef?gt(+)

diff --git a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
index 294b00d50dd76c6541831b5c53bf70a4d377dcc3..f48bead04cbb18b040557b7b78a6cb27a3368422 100644
--- a/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
+++ b/daemons/ipa-slapi-plugins/ipa-extdom-extop/ipa_extdom_common.c
@@ -162,6 +162,72 @@ static void free_domain_info(struct domain_info *domain_info)
     free(domain_info);
 }
 
+static int set_domain_range(struct ipa_extdom_ctx *ctx, const char *dom_sid_str,
+                            struct sss_idmap_range *range)
+{
+    Slapi_PBlock *pb = NULL;
+    Slapi_Entry **e = NULL;
+    char *filter = NULL;
+    int ret;
+    unsigned long ulong_val;
+
+    pb = slapi_pblock_new();
+    if (pb == NULL) {
+        return ENOMEM;
+    }
+
+    ret = asprintf(&filter, "(&(ipaNTTrustedDomainSID=%s)" \
+                              "(objectclass=ipaTrustedADDomainRange))",
+                            dom_sid_str);
+    if (ret == -1) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    slapi_search_internal_set_pb(pb, ctx->base_dn,
+                                 LDAP_SCOPE_SUBTREE, filter,
+                                 NULL, 0, NULL, NULL, ctx->plugin_id, 0);
+
+    slapi_search_internal_pb(pb);
+    slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &ret);
+
+    if (ret != EOK) {
+        ret = ENOENT;
+        goto done;
+    }
+
+    slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &e);
+    if (!e || !e[0]) {
+        /* no matches */
+        ret = ENOENT;
+        goto done;
+    }
+
+    /* TODO: handle more than one range per domain */
+    ulong_val = slapi_entry_attr_get_ulong(e[0], "ipaBaseID");
+    if (ulong_val >= UINT32_MAX) {
+        ret = EINVAL;
+        goto done;
+    }
+    range->min = (uint32_t) ulong_val;
+
+    ulong_val = slapi_entry_attr_get_ulong(e[0], "ipaIDRangeSize");
+    if ((range->min + ulong_val -1) >= UINT32_MAX) {
+        ret = EINVAL;
+        goto done;
+    }
+    range->max = (range->min + ulong_val -1);
+
+    ret = 0;
+
+done:
+    slapi_free_search_results_internal(pb);
+    slapi_pblock_destroy(pb);
+    free(filter);
+
+    return ret;
+}
+
 /* TODO: A similar call is used in ipa_cldap_netlogon.c, maybe a candidate for
  * a common library */
 static int get_domain_info(struct ipa_extdom_ctx *ctx, const char *domain_name,
@@ -219,8 +285,14 @@ static int get_domain_info(struct ipa_extdom_ctx *ctx, const char *domain_name,
                                                           "ipaNTFlatName");
 
     /* TODO: read range from LDAP server */
+/*
     range.min = 200000;
     range.max = 400000;
+*/
+    ret = set_domain_range(ctx, domain_info->sid, &range);
+    if (ret != 0) {
+        goto done;
+    }
 
     err = sss_idmap_init(NULL, NULL, NULL, &domain_info->idmap_ctx);
     if (err == IDMAP_SUCCESS) {
-- 
1.7.10.2

-------------- next part --------------
From 87b0656de9c7faebfdb0eb25cd0d2fd8f236abe4 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Wed, 8 Aug 2012 13:45:55 +0200
Subject: [PATCH 2/2] trust CLI: add ID range for new trusted domain

---
 API.txt                 |    4 ++-
 ipalib/plugins/range.py |    1 +
 ipalib/plugins/trust.py |   63 ++++++++++++++++++++++++++++++++++++++++++++++-
 3 Dateien ge?ndert, 66 Zeilen hinzugef?gt(+), 2 Zeilen entfernt(-)

diff --git a/API.txt b/API.txt
index d32d6393b0fc2ba9f1a9fe23d01d92d552c10302..aef12b7eb6e458d614c84ba20d782ef3154c09f0 100644
--- a/API.txt
+++ b/API.txt
@@ -3200,7 +3200,7 @@ output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
 output: Output('value', <type 'unicode'>, None)
 command: trust_add
-args: 1,10,3
+args: 1,12,3
 arg: Str('cn', attribute=True, cli_name='realm', multivalue=False, primary_key=True, required=True)
 option: Str('setattr*', cli_name='setattr', exclude='webui')
 option: Str('addattr*', cli_name='addattr', exclude='webui')
@@ -3209,6 +3209,8 @@ option: Str('realm_admin?', cli_name='admin')
 option: Password('realm_passwd?', cli_name='password', confirm=False)
 option: Str('realm_server?', cli_name='server')
 option: Password('trust_secret?', cli_name='trust_secret', confirm=False)
+option: Int('base_id?', cli_name='base_id')
+option: Int('range_size?', autofill=True, cli_name='range_size', default=200000)
 option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
 option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
 option: Str('version?', exclude='webui')
diff --git a/ipalib/plugins/range.py b/ipalib/plugins/range.py
index c1d91867996cb0df863ecd82ad4c56f6fbb0cbaf..95b00b39bc64723829a5d17ed22590199d1d516f 100644
--- a/ipalib/plugins/range.py
+++ b/ipalib/plugins/range.py
@@ -24,6 +24,7 @@ from ipalib import Command
 from ipalib import errors
 from ipapython import ipautil
 from ipalib import util
+from ipapython.dn import DN
 
 
 __doc__ = _("""
diff --git a/ipalib/plugins/trust.py b/ipalib/plugins/trust.py
index a70293bff4fb0ce087d5e5f157b352aaab8439ff..1064a06783892f27c56f0310046216881db5b42a 100644
--- a/ipalib/plugins/trust.py
+++ b/ipalib/plugins/trust.py
@@ -24,6 +24,12 @@ from ipalib import Command
 from ipalib import errors
 from ipapython import ipautil
 from ipalib import util
+try:
+    import pysss_murmur
+    _murmur_installed = True
+except Exception, e:
+    _murmur_installed = False
+
 if api.env.in_server and api.env.context in ['lite', 'server']:
     try:
         import ipaserver.dcerpc
@@ -142,9 +148,18 @@ class trust_add(LDAPCreate):
             label=_('Shared secret for the trust'),
             confirm=False,
         ),
+        Int('base_id?',
+            cli_name='base_id',
+            label=_('First Posix ID of the range reserved for the trusted domain'),
+        ),
+        Int('range_size?',
+            cli_name='range_size',
+            label=_('Size of the ID range reserved for the trusted domain'),
+            default=200000,
+            autofill=True
+        ),
     )
 
-
     msg_summary = _('Added Active Directory trust for realm "%(value)s"')
 
     def execute(self, *keys, **options):
@@ -155,8 +170,54 @@ class trust_add(LDAPCreate):
                 raise errors.ValidationError(name=_('trust type'), error=_('only "ad" is supported'))
         else:
             raise errors.RequirementError(name=_('trust type'))
+
+        self.add_range(*keys, **options)
+
         return result
 
+    def add_range(self, *keys, **options):
+        new_obj = api.Command['trust_show'](keys[-1])
+        dom_sid = new_obj['result']['ipanttrusteddomainsid'][0];
+
+        range_name = keys[-1].upper()+'_id_range'
+
+        try:
+            old_range = api.Command['range_show'](range_name)
+        except errors.NotFound, e:
+            old_range = None
+
+        if old_range:
+            old_dom_sid = old_range['result']['ipanttrusteddomainsid'][0];
+
+            if old_dom_sid == dom_sid:
+                return
+
+            raise errors.ValidationError(name=_('range exists'),
+                    error=_('ID range with the same name but different ' \
+                            'domain SID already exists. The ID range for ' \
+                            'the new trusted domain must be created manually.'))
+
+        if 'base_id' in options:
+            base_id = options['base_id']
+        else:
+            if not _murmur_installed:
+                raise errors.ValidationError(name=_('missing base_id'),
+                    error=_('pysss_murmur is not available on the server ' \
+                            'and no base_id is given, ' \
+                            'ID range must be create manually'))
+
+            base_id = 200000 + (pysss_murmur.murmurhash3(dom_sid, len(dom_sid), 0xdeadbeef) % 10000) * 200000
+
+        try:
+            new_range = api.Command['range_add'](range_name,
+                                                 ipabaseid=base_id,
+                                                 ipaidrangesize=options['range_size'],
+                                                 ipabaserid=0,
+                                                 ipanttrusteddomainsid=dom_sid)
+        except Exception, e:
+            raise errors.ValidationError(name=_('ID range exists'),
+                   error = _('ID range already exists, must be added manually'))
+
     def execute_ad(self, *keys, **options):
         # Join domain using full credentials and with random trustdom
         # secret (will be generated by the join method)
-- 
1.7.10.2



More information about the Freeipa-devel mailing list