From dc8870ea03084189367545f6b66424662453173f Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Tue, 19 Jan 2016 06:28:37 -0500
Subject: [PATCH 4/4] IDMAP: change seed for hash of secondary slices

Resolves:
https://fedorahosted.org/sssd/ticket/2188
---
 src/lib/idmap/sss_idmap.c         | 24 +++++++++++-------------
 src/tests/cmocka/test_sss_idmap.c |  2 +-
 src/tests/sss_idmap-tests.c       | 21 ++++++++++++---------
 3 files changed, 24 insertions(+), 23 deletions(-)

diff --git a/src/lib/idmap/sss_idmap.c b/src/lib/idmap/sss_idmap.c
index a2272e6882355912afa122e9a208c4d530e6600a..63caab4eca2a5ff45d9027f4f219c66efef079f1 100644
--- a/src/lib/idmap/sss_idmap.c
+++ b/src/lib/idmap/sss_idmap.c
@@ -540,13 +540,13 @@ idmap_error_code dom_check_collision(struct idmap_domain_info *dom_list,
 
 static char*
 generate_sec_slice_name(struct sss_idmap_ctx *ctx,
-                        const char *domain_name, int slice_index)
+                        const char *domain_name, uint32_t rid)
 {
-    const char *SEC_SLICE_NAME_FMT = "%s#%d";
+    const char *SEC_SLICE_NAME_FMT = "%s-%d";
     char *slice_name;
     int len, len2;
 
-    len = snprintf(NULL, 0, SEC_SLICE_NAME_FMT, domain_name, slice_index + 1);
+    len = snprintf(NULL, 0, SEC_SLICE_NAME_FMT, domain_name, rid);
     if (len <= 0) {
         return NULL;
     }
@@ -557,7 +557,7 @@ generate_sec_slice_name(struct sss_idmap_ctx *ctx,
     }
 
     len2 = snprintf(slice_name, len + 1, SEC_SLICE_NAME_FMT, domain_name,
-                    slice_index + 1);
+                    rid);
     if (len != len2) {
         ctx->free_func(slice_name, ctx->alloc_pvt);
         return NULL;
@@ -598,7 +598,7 @@ generate_slice(struct sss_idmap_ctx *ctx, char *slice_name, uint32_t first_rid,
 
 static enum idmap_error_code
 get_sec_slices(struct sss_idmap_ctx *ctx,
-               const char *domain_name,
+               const char *domain_sid,
                uint32_t first_rid,
                struct idmap_range_params **_sec_slices)
 {
@@ -609,7 +609,7 @@ get_sec_slices(struct sss_idmap_ctx *ctx,
     char *secondary_name;
 
     for (int i = 0; i < ctx->idmap_opts.extra_slice_init; i++) {
-        secondary_name = generate_sec_slice_name(ctx, domain_name, i + 1);
+        secondary_name = generate_sec_slice_name(ctx, domain_sid, first_rid);
         if (secondary_name == NULL) {
             return IDMAP_OUT_OF_MEMORY;
         }
@@ -756,7 +756,7 @@ sss_idmap_add_auto_domain_ex(struct sss_idmap_ctx *ctx,
 
     /* Add size of primary slice for first_rid of secondary slices. */
     rid += ctx->idmap_opts.rangesize;
-    err = get_sec_slices(ctx, domain_name, rid,
+    err = get_sec_slices(ctx, domain_sid, rid,
                          &ctx->idmap_domain_info->sec_ranges);
     if (err == IDMAP_SUCCESS) {
         ctx->idmap_domain_info->use_sec_ranges = true;
@@ -844,20 +844,18 @@ static bool comp_id(struct idmap_range_params *range_params, long long rid,
 
 static enum idmap_error_code
 get_new_sec_slide(struct sss_idmap_ctx *ctx,
-                  const char *dom_name,
+                  const char *dom_sid,
                   long long rid,
                   struct idmap_range_params **_slice)
 {
     char *secondary_name;
     enum idmap_error_code err;
-    int index;
     int first_rid;
     struct idmap_range_params *slice;
 
-    index = rid / ctx->idmap_opts.rangesize;
-    first_rid = index * ctx->idmap_opts.rangesize;
+    first_rid = (rid / ctx->idmap_opts.rangesize) * ctx->idmap_opts.rangesize;
 
-    secondary_name = generate_sec_slice_name(ctx, dom_name, index);
+    secondary_name = generate_sec_slice_name(ctx, dom_sid, first_rid);
     if (secondary_name == NULL) {
         return IDMAP_OUT_OF_MEMORY;
     }
@@ -899,7 +897,7 @@ try_secondary_slices(struct sss_idmap_ctx *ctx,
     }
 
     /* If no secondary slide matched then new slide is added. */
-    err = get_new_sec_slide(ctx, matched_dom->name, rid, &new_slice);
+    err = get_new_sec_slide(ctx, matched_dom->sid, rid, &new_slice);
     if (err != IDMAP_SUCCESS) {
         return err;
     }
diff --git a/src/tests/cmocka/test_sss_idmap.c b/src/tests/cmocka/test_sss_idmap.c
index 91e38546436bb3c248e63dcba0bbc3ba425c3483..807a6ea173b84031c5ba6034ae59d7bed97bc6f5 100644
--- a/src/tests/cmocka/test_sss_idmap.c
+++ b/src/tests/cmocka/test_sss_idmap.c
@@ -314,7 +314,7 @@ void test_map_id_sec_slices(void **state)
     err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx, TEST_DOM_SID"-4000000",
                                 &id);
     assert_int_equal(err, IDMAP_SUCCESS);
-    assert_int_equal(id, 351800000);
+    assert_int_equal(id, 575600000);
 
     err = sss_idmap_unix_to_sid(test_ctx->idmap_ctx, TEST_OFFSET - 1, &sid);
     assert_int_equal(err, IDMAP_NO_DOMAIN);
diff --git a/src/tests/sss_idmap-tests.c b/src/tests/sss_idmap-tests.c
index a1d1659f7152960f002d84eb16d244fa83618079..d3aa691fa79ca1060bd1f49b14bcbecb47448335 100644
--- a/src/tests/sss_idmap-tests.c
+++ b/src/tests/sss_idmap-tests.c
@@ -257,6 +257,8 @@ START_TEST(idmap_test_sid2uid_ss)
 {
     enum idmap_error_code err;
     uint32_t id;
+    const uint32_t exp_id = 351800000;
+    const uint32_t exp_id2 = 832610000;
 
     err = sss_idmap_sid_to_unix(idmap_ctx, "S-1-5-21-1-2-3333-1000", &id);
     fail_unless(err == IDMAP_NO_DOMAIN, "sss_idmap_sid_to_unix did not detect "
@@ -265,9 +267,9 @@ START_TEST(idmap_test_sid2uid_ss)
     /* RID out of primary and secondary range */
     err = sss_idmap_sid_to_unix(idmap_ctx, "S-1-5-21-1-2-3-4000000", &id);
     fail_unless(err == IDMAP_SUCCESS, "sss_idmap_sid_to_unix failed.");
-    fail_unless(id == 351800000,
+    fail_unless(id == exp_id,
                 "sss_idmap_sid_to_unix returned wrong id, "
-                "got [%d], expected [%d].", id, 351800000);
+                "got [%d], expected [%d].", id, exp_id);
 
     err = sss_idmap_sid_to_unix(idmap_ctx, "S-1-5-21-1-2-3-1000", &id);
     fail_unless(err == IDMAP_SUCCESS, "sss_idmap_sid_to_unix failed.");
@@ -277,9 +279,9 @@ START_TEST(idmap_test_sid2uid_ss)
 
     err = sss_idmap_sid_to_unix(idmap_ctx, "S-1-5-21-1-2-3-210000", &id);
     fail_unless(err == IDMAP_SUCCESS, "sss_idmap_sid_to_unix failed.");
-    fail_unless(id == 1638210000,
+    fail_unless(id == exp_id2,
                 "sss_idmap_sid_to_unix returned wrong id, "
-                "got [%d], expected [%d].", id, 1638210000);
+                "got [%d], expected [%d].", id, exp_id2);
 }
 END_TEST
 
@@ -288,20 +290,21 @@ START_TEST(idmap_test_sid2uid_ext_sec_slices)
     enum idmap_error_code err;
     uint32_t id;
     char *sid;
+    const uint32_t exp_id = 351800000;
 
-    err = sss_idmap_unix_to_sid(idmap_ctx, 351800000, &sid);
+    err = sss_idmap_unix_to_sid(idmap_ctx, exp_id, &sid);
     fail_unless(err == IDMAP_NO_DOMAIN, "sss_idmap_unix_to_sid did not detect "
                                         "id out of range");
 
     /* RID out of primary and secondary range */
     err = sss_idmap_sid_to_unix(idmap_ctx, "S-1-5-21-1-2-3-4000000", &id);
     fail_unless(err == IDMAP_SUCCESS, "sss_idmap_sid_to_unix failed.");
-    fail_unless(id == 351800000,
+    fail_unless(id == exp_id,
                 "sss_idmap_sid_to_unix returned wrong id, "
-                "got [%d], expected [%d].", id, 351800000);
+                "got [%d], expected [%d].", id, exp_id);
 
     /* Secondary ranges were expanded by sid_to_unix call */
-    err = sss_idmap_unix_to_sid(idmap_ctx, 351800000, &sid);
+    err = sss_idmap_unix_to_sid(idmap_ctx, exp_id, &sid);
     fail_unless(err == IDMAP_SUCCESS, "sss_idmap_unix_to_sid failed.");
     fail_unless(strcmp(sid, "S-1-5-21-1-2-3-4000000") == 0,
                 "sss_idmap_unix_to_sid returned wrong SID, "
@@ -427,7 +430,7 @@ START_TEST(idmap_test_uid2sid_ss)
 
     /* Secondary ranges */
     err = sss_idmap_unix_to_sid(idmap_ctx,
-                                111400000,
+                                313800000,
                                 &sid);
     fail_unless(err == IDMAP_SUCCESS, "sss_idmap_unix_to_sid failed.");
     fail_unless(strcmp(sid, "S-1-5-21-1-2-3-400000") == 0,
-- 
2.4.3

