From 3f9bdf2e67c50d9cfde39229926a7b4fd4de7549 Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgallagh@redhat.com>
Date: Sat, 21 Apr 2012 09:09:43 -0400
Subject: [PATCH 08/20] LDAP: Add autorid compatibility mode

---
 src/config/SSSDConfig.py                 |    1 +
 src/config/etc/sssd.api.d/sssd-ipa.conf  |    1 +
 src/config/etc/sssd.api.d/sssd-ldap.conf |    1 +
 src/providers/ipa/ipa_opts.h             |    1 +
 src/providers/ldap/ldap_opts.h           |    1 +
 src/providers/ldap/sdap.h                |    1 +
 src/providers/ldap/sdap_idmap.c          |   22 ++++++++++++++--------
 7 files changed, 20 insertions(+), 8 deletions(-)

diff --git a/src/config/SSSDConfig.py b/src/config/SSSDConfig.py
index a4eef0cbfa370362135b6c12f50f91efa914d9cd..24b0ff49a8583ae52020c07a3d2b03a96be6c630 100644
--- a/src/config/SSSDConfig.py
+++ b/src/config/SSSDConfig.py
@@ -263,6 +263,7 @@ option_strings = {
     'ldap_idmap_range_min' : _('Lower bound for ID-mapping'),
     'ldap_idmap_range_max' : _('Upper bound for ID-mapping'),
     'ldap_idmap_range_size' : _('Number of IDs for each slice when ID-mapping'),
+    'ldap_idmap_autorid_compat' : _('Use autorid-compatible algorithm for ID-mapping'),
 
     # [provider/ldap/auth]
     'ldap_pwd_policy' : _('Policy to evaluate the password expiration'),
diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf
index 1cad031fc053fd748549630fadb3f7428c0877c5..0447d0c45cfcd28a52e2573b4455124b1ceaeb7d 100644
--- a/src/config/etc/sssd.api.d/sssd-ipa.conf
+++ b/src/config/etc/sssd.api.d/sssd-ipa.conf
@@ -113,6 +113,7 @@ ipa_host_ssh_public_key = str, None, false
 ldap_idmap_range_min = int, None, false
 ldap_idmap_range_max = int, None, false
 ldap_idmap_range_size = int, None, false
+ldap_idmap_autorid_compat = bool, None, false
 
 [provider/ipa/auth]
 krb5_ccachedir = str, None, false
diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf
index 795181554dff969c910ac1fee1ef35f0ca61bf61..1ea1c948ba29151d7a32723dd4312e3e673d7950 100644
--- a/src/config/etc/sssd.api.d/sssd-ldap.conf
+++ b/src/config/etc/sssd.api.d/sssd-ldap.conf
@@ -107,6 +107,7 @@ ldap_service_entry_usn = str, None, false
 ldap_idmap_range_min = int, None, false
 ldap_idmap_range_max = int, None, false
 ldap_idmap_range_size = int, None, false
+ldap_idmap_autorid_compat = bool, None, false
 
 [provider/ldap/auth]
 ldap_pwd_policy = str, None, false
diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h
index 866bd3ce0a21ade58f79ba05504c837296eae4bf..ee9ff15f3ea8324487a798718912e1ffb5ba87f7 100644
--- a/src/providers/ipa/ipa_opts.h
+++ b/src/providers/ipa/ipa_opts.h
@@ -117,6 +117,7 @@ struct dp_option ipa_def_ldap_opts[] = {
     { "ldap_idmap_range_min", DP_OPT_NUMBER, { .number = 100001 }, NULL_NUMBER },
     { "ldap_idmap_range_max", DP_OPT_NUMBER, { .number = 2000100000LL }, NULL_NUMBER },
     { "ldap_idmap_range_size", DP_OPT_NUMBER, { .number = 200000 }, NULL_NUMBER },
+    { "ldap_idmap_autorid_compat", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
     DP_OPTION_TERMINATOR
 };
 
diff --git a/src/providers/ldap/ldap_opts.h b/src/providers/ldap/ldap_opts.h
index a4c780691f46a77bd8068ed21bd1e1d84d510087..8b8ea25c63d5445d500a205541f471e1342f2b55 100644
--- a/src/providers/ldap/ldap_opts.h
+++ b/src/providers/ldap/ldap_opts.h
@@ -99,6 +99,7 @@ struct dp_option default_basic_opts[] = {
     { "ldap_idmap_range_min", DP_OPT_NUMBER, { .number = 100001 }, NULL_NUMBER },
     { "ldap_idmap_range_max", DP_OPT_NUMBER, { .number = 2000100000LL }, NULL_NUMBER },
     { "ldap_idmap_range_size", DP_OPT_NUMBER, { .number = 200000 }, NULL_NUMBER },
+    { "ldap_idmap_autorid_compat", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
     DP_OPTION_TERMINATOR
 };
 
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index d72a0edd9e79bb2fa20ed890d6dde975a5c4ba75..7c55ad5a0430aaab6176b9312f2e03ea82c02080 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -214,6 +214,7 @@ enum sdap_basic_opt {
     SDAP_IDMAP_LOWER,
     SDAP_IDMAP_UPPER,
     SDAP_IDMAP_RANGESIZE,
+    SDAP_IDMAP_AUTORID_COMPAT,
 
     SDAP_OPTS_BASIC /* opts counter */
 };
diff --git a/src/providers/ldap/sdap_idmap.c b/src/providers/ldap/sdap_idmap.c
index ea65195ace1b93379b4cfe698618b5286f7dcbe1..24e7ef37113305c707ce3f6526a5ddb448c88f12 100644
--- a/src/providers/ldap/sdap_idmap.c
+++ b/src/providers/ldap/sdap_idmap.c
@@ -196,15 +196,21 @@ sdap_idmap_add_domain(struct sdap_idmap_ctx *idmap_ctx,
     } else {
         /* If slice is -1, we're being asked to pick a new slice */
 
-        /* Hash the domain sid string */
-        hash_val = murmurhash3(dom_sid, strlen(dom_sid), 0xdeadbeef);
-
-        /* Now get take the modulus of the hash val and the max_slices
-         * to determine its optimal position in the range.
-         */
-        new_slice->slice_num = hash_val % max_slices;
-        orig_slice = new_slice->slice_num;
+        if (dp_opt_get_bool(idmap_ctx->id_ctx->opts->basic, SDAP_IDMAP_AUTORID_COMPAT)) {
+            /* In autorid compatibility mode, always start at 0 and find the first
+             * free value.
+             */
+            orig_slice = 0;
+        } else {
+            /* Hash the domain sid string */
+            hash_val = murmurhash3(dom_sid, strlen(dom_sid), 0xdeadbeef);
 
+            /* Now get take the modulus of the hash val and the max_slices
+             * to determine its optimal position in the range.
+             */
+            new_slice->slice_num = hash_val % max_slices;
+            orig_slice = new_slice->slice_num;
+        }
         /* Verify that this slice is not already in use */
         do {
             DLIST_FOR_EACH(s, idmap_ctx->slices) {
-- 
1.7.10

