>From cd3498587b70f3b694629caf6c981ce2473100c6 Mon Sep 17 00:00:00 2001
From: Michal Zidek <mzidek@redhat.com>
Date: Tue, 15 Jul 2014 12:10:34 -0400
Subject: [PATCH 2/4] case_sensitivity = preserving

If case_sensitivity is set to 'preserving', getXXnam
returns name attribute in the same format as
stored in LDAP.

Fixes:
https://fedorahosted.org/sssd/ticket/2367
---
 src/confdb/confdb.c             | 27 +++++++++++++++++++++------
 src/confdb/confdb.h             |  1 +
 src/providers/ad/ad_common.c    | 30 +++++++++++++++++++++++++++---
 src/providers/ipa/ipa_selinux.c |  2 +-
 src/responder/nss/nsssrv_cmd.c  |  4 ++--
 5 files changed, 52 insertions(+), 12 deletions(-)

diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
index ae7abd7..c899202 100644
--- a/src/confdb/confdb.c
+++ b/src/confdb/confdb.c
@@ -1218,12 +1218,27 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb,
         }
     }
 
-    ret = get_entry_as_bool(res->msgs[0], &domain->case_sensitive,
-                            CONFDB_DOMAIN_CASE_SENSITIVE, true);
-    if(ret != EOK) {
-        DEBUG(SSSDBG_FATAL_FAILURE,
-              "Invalid value for %s\n", CONFDB_DOMAIN_CASE_SENSITIVE);
-        goto done;
+    tmp = ldb_msg_find_attr_as_string(res->msgs[0],
+                                      CONFDB_DOMAIN_CASE_SENSITIVE, "true");
+    if (tmp != NULL) {
+        if (strcasecmp(tmp, "true") == 0) {
+            domain->case_sensitive = true;
+            domain->case_preserve = true;
+        } else if (strcasecmp(tmp, "false") == 0) {
+            domain->case_sensitive = false;
+            domain->case_preserve = false;
+        } else if (strcasecmp(tmp, "preserving") == 0) {
+            domain->case_sensitive = false;
+            domain->case_preserve = true;
+        } else {
+            DEBUG(SSSDBG_FATAL_FAILURE,
+                  "Invalid value for %s\n", CONFDB_DOMAIN_CASE_SENSITIVE);
+            goto done;
+        }
+    } else {
+        /* default */
+        domain->case_sensitive = true;
+        domain->case_preserve = true;
     }
     if (domain->case_sensitive == false &&
         strcasecmp(domain->provider, "local") == 0) {
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index 7c51518..3dd6f95 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -217,6 +217,7 @@ struct sss_domain_info {
     bool cache_credentials;
     bool legacy_passwords;
     bool case_sensitive;
+    bool case_preserve;
 
     gid_t override_gid;
     const char *override_homedir;
diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c
index 67ded36..7b08c2b 100644
--- a/src/providers/ad/ad_common.c
+++ b/src/providers/ad/ad_common.c
@@ -263,6 +263,7 @@ ad_get_common_options(TALLOC_CTX *mem_ctx,
     char *realm;
     char *ad_hostname;
     char hostname[HOST_NAME_MAX + 1];
+    char *case_sensitive_opt;
 
     opts = talloc_zero(mem_ctx, struct ad_options);
     if (!opts) return ENOMEM;
@@ -333,13 +334,36 @@ ad_get_common_options(TALLOC_CTX *mem_ctx,
     }
 
     /* Active Directory is always case-insensitive */
-    dom->case_sensitive = false;
+    ret = confdb_get_string(cdb, mem_ctx, conf_path,
+                            CONFDB_DOMAIN_CASE_SENSITIVE, "false",
+                            &case_sensitive_opt);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "condb_get_string failed.\n");
+        goto done;
+    }
+
+    if (strcasecmp(case_sensitive_opt, "true") == 0) {
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              "Warning: AD domain can not be set as case-sensitive.\n");
+        dom->case_sensitive = false;
+        dom->case_preserve = false;
+    } else if (strcasecmp(case_sensitive_opt, "false") == 0) {
+        dom->case_sensitive = false;
+        dom->case_preserve = false;
+    } else if (strcasecmp(case_sensitive_opt, "preserving") == 0) {
+        dom->case_sensitive = false;
+        dom->case_preserve = true;
+    } else {
+        DEBUG(SSSDBG_FATAL_FAILURE,
+              "Invalid value for %s\n", CONFDB_DOMAIN_CASE_SENSITIVE);
+        goto done;
+    }
 
     /* Set this in the confdb so that the responders pick it
      * up when they start up.
      */
-    ret = confdb_set_bool(cdb, conf_path, "case_sensitive",
-                          dom->case_sensitive);
+    ret = confdb_set_string(cdb, conf_path, "case_sensitive",
+                            case_sensitive_opt);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE,
               "Could not set domain case-sensitive: [%s]\n",
diff --git a/src/providers/ipa/ipa_selinux.c b/src/providers/ipa/ipa_selinux.c
index 927e545..3cd1cc1 100644
--- a/src/providers/ipa/ipa_selinux.c
+++ b/src/providers/ipa/ipa_selinux.c
@@ -757,7 +757,7 @@ static errno_t write_selinux_login_file(const char *orig_name,
     /* pam_selinux needs the username in the same format getpwnam() would
      * return it
      */
-    username = sss_get_cased_name(tmp_ctx, orig_name, dom->case_sensitive);
+    username = sss_get_cased_name(tmp_ctx, orig_name, dom->case_preserve);
     if (username == NULL) {
         ret = ENOMEM;
         goto done;
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index a168a3e..c201d3a 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -365,7 +365,7 @@ static int fill_pwent(struct sss_packet *packet,
             packet_initialized = true;
         }
 
-        tmpstr = sss_get_cased_name(tmp_ctx, orig_name, dom->case_sensitive);
+        tmpstr = sss_get_cased_name(tmp_ctx, orig_name, dom->case_preserve);
         if (tmpstr == NULL) {
             DEBUG(SSSDBG_CRIT_FAILURE,
                   "sss_get_cased_name failed, skipping\n");
@@ -2492,7 +2492,7 @@ static int fill_grent(struct sss_packet *packet,
             }
         }
 
-        tmpstr = sss_get_cased_name(tmp_ctx, orig_name, dom->case_sensitive);
+        tmpstr = sss_get_cased_name(tmp_ctx, orig_name, dom->case_preserve);
         if (tmpstr == NULL) {
             DEBUG(SSSDBG_CRIT_FAILURE,
                   "sss_get_cased_name failed, skipping\n");
-- 
1.9.3

