From 10a658c38bfda08de4474cc22e018f939c6d63ba Mon Sep 17 00:00:00 2001
From: Sergey V. Kovylov <serejka@gmail.com>
Date: Wed, 23 Feb 2011 17:11:44 +0300
Subject: [PATCH] This path fixes the issue when ldap server sends DN string with lower case attributes
 and memberuid string without modifications. In this case LDB will not be able to find
 entry, because of case sensitive logic.
 This means that:
 STRING1: uid=user1,dc=domain,dc=com
 STRING2: uid=user1,DC=domain,dc=com

STRING1 and STRING2 are not equal in LDB, but equal in LDAP.
---
 src/providers/ldap/sdap_async_accounts.c |   25 ++++++++++++++++++++++++
 src/util/util.c                          |   31 ++++++++++++++++++++++++++++++
 src/util/util.h                          |    7 ++++++
 3 files changed, 63 insertions(+), 0 deletions(-)

diff --git a/src/providers/ldap/sdap_async_accounts.c b/src/providers/ldap/sdap_async_accounts.c
index 8e45959..2533f3f 100644
--- a/src/providers/ldap/sdap_async_accounts.c
+++ b/src/providers/ldap/sdap_async_accounts.c
@@ -139,6 +139,12 @@ static int sdap_save_user(TALLOC_CTX *memctx,
     if (ret) {
         goto fail;
     }
+
+    ret = sss_sanitize_dn_lowercase((char *)&el->values[0].data);
+    if (ret != EOK) {
+        goto fail;
+    }
+
     if (el->num_values == 0) {
         DEBUG(7, ("Original DN is not available for [%s].\n", name));
     } else {
@@ -598,6 +604,13 @@ static int sdap_fill_memberships(struct sysdb_attrs *group_attrs,
 
         for (i = 0, j = el->num_values; i < num_values; i++) {
 
+           /* convert DN attibutes to lower case before search */
+           ret = sss_sanitize_dn_lowercase((char *)&values[i].data);
+            if (ret != EOK) {
+                ret = ENOMEM;
+                goto done;
+            }
+
             /* sync search entry with this as origDN */
             ret = sdap_find_entry_by_origDN(el->values, ctx, domain,
                                             (char *)values[i].data,
@@ -693,6 +706,12 @@ static int sdap_save_group(TALLOC_CTX *memctx,
     if (ret) {
         goto fail;
     }
+    /* convert DN attibutes to lower case */
+    ret = sss_sanitize_dn_lowercase((char *)&el->values[0].data); 
+    if (ret != EOK){
+       goto fail;
+    }
+
     if (el->num_values == 0) {
         DEBUG(7, ("Original DN is not available for [%s].\n", name));
     } else {
@@ -2933,6 +2952,12 @@ static errno_t sdap_nested_group_process_step(struct tevent_req *req)
             goto error;
         }
 
+       ret = sss_sanitize_dn_lowercase(&member_dn);
+       if (ret != EOK){
+           goto error;
+        }
+
+
         /* Check for the specified origDN in the sysdb */
         filter = talloc_asprintf(NULL, "(%s=%s)",
                                  SYSDB_ORIG_DN,
diff --git a/src/util/util.c b/src/util/util.c
index 39275ef..db6d588 100644
--- a/src/util/util.c
+++ b/src/util/util.c
@@ -581,3 +581,34 @@ errno_t sss_filter_sanitize(TALLOC_CTX *mem_ctx,
 
     return EOK;
 }
+
+errno_t sss_sanitize_dn_lowercase(char **string)
+{
+    char *output;
+
+    size_t i = 0;
+
+    output = strdup(*string);
+
+    if (!output) {
+        return ENOMEM;
+    }
+
+    while(output[i])
+    {    
+        if(output[i] == '=')
+        {
+           i++;
+            while((output[i] != ',') && (output[i]))
+                i++;
+        }else{
+            output[i] = tolower(output[i]);
+            i++;
+        }
+    }
+
+    memcpy(*string, output, i);
+    free(output);
+
+    return EOK;
+}
diff --git a/src/util/util.h b/src/util/util.h
index 61fe7f6..66588b1 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -403,4 +403,11 @@ errno_t sss_filter_sanitize(TALLOC_CTX *mem_ctx,
                             const char *input,
                             char **sanitized);
 
+/* convert ldap attributes to lower case this is necessary
+ * to have consistent data in both ldap and ldb databases.
+ * The values "uid=user,DC=domain,dc=com" and "uid=user,dc=domain,dc=com"
+ * are not the same in LDB database instead of LDAP
+ */
+errno_t sss_sanitize_dn_lowercase(char **string);
+
 #endif /* __SSSD_UTIL_H__ */
-- 
1.7.1

