URL: https://github.com/SSSD/sssd/pull/5251
Author: pbrezina
 Title: #5251: subdomains: allow to inherit case_sensitive=Preserving
Action: synchronized

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/5251/head:pr5251
git checkout pr5251
From 69d4e0d269d732b054688e6b18cf4ecf247a7170 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com>
Date: Mon, 20 Jul 2020 13:06:51 +0200
Subject: [PATCH 1/6] man: add auto_private_groups to subdomain_inherit

This option can be inherited since 41c497b8b9e6efb9f2aa8e4cc869d465c3b954b3
---
 src/man/sssd.conf.5.xml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index 8b330de584..16632f9900 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -3371,6 +3371,9 @@ pam_gssapi_services = sudo, sudo-i
                             ldap_krb5_keytab (the value of krb5_keytab will be
                             used if ldap_krb5_keytab is not set explicitly)
                         </para>
+                        <para>
+                            auto_private_groups
+                        </para>
                         <para>
                             Example:
                             <programlisting>

From 2222cbadf93782593cec3528c70817cee0d53dc1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com>
Date: Tue, 21 Jul 2020 12:08:27 +0200
Subject: [PATCH 2/6] subdomains: allow to inherit case_sensitive=Preserving

Resolves: https://github.com/SSSD/sssd/issues/5250

:feature: `case_sensitive` option can be now inherited by subdomains
---
 src/db/sysdb_subdomains.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
index 03ba121646..ed3e7055c3 100644
--- a/src/db/sysdb_subdomains.c
+++ b/src/db/sysdb_subdomains.c
@@ -157,6 +157,14 @@ struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx,
         dom->ignore_group_members = parent->ignore_group_members;
     }
 
+    /* Inherit case_sensitive. All subdomains are always case insensitive,
+     * but we want to inherit case preserving which is set with
+     * case_sensitive=Preserving. */
+    inherit_option = string_in_list(CONFDB_DOMAIN_CASE_SENSITIVE,
+                                    parent->sd_inherit, false);
+    dom->case_sensitive = false;
+    dom->case_preserve = inherit_option ? parent->case_preserve : false;
+
     dom->trust_direction = trust_direction;
     /* If the parent domain explicitly limits ID ranges, the subdomain
      * should honour the limits as well.
@@ -168,14 +176,12 @@ struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx,
     dom->cache_credentials_min_ff_length =
                                         parent->cache_credentials_min_ff_length;
     dom->cached_auth_timeout = parent->cached_auth_timeout;
-    dom->case_sensitive = false;
     dom->user_timeout = parent->user_timeout;
     dom->group_timeout = parent->group_timeout;
     dom->netgroup_timeout = parent->netgroup_timeout;
     dom->service_timeout = parent->service_timeout;
     dom->resolver_timeout = parent->resolver_timeout;
     dom->names = parent->names;
-
     dom->override_homedir = parent->override_homedir;
     dom->fallback_homedir = parent->fallback_homedir;
     dom->subdomain_homedir = parent->subdomain_homedir;

From 07766c76282a8904d14be73fd33c1257d6ee45f5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com>
Date: Tue, 21 Jul 2020 12:35:20 +0200
Subject: [PATCH 3/6] subdomains: allow to set case_sensitive=Preserving in
 subdomain section

Resolves: https://github.com/SSSD/sssd/issues/5250

:feature: `case_sensitive` can be now set separately for each
  subdomain in `[domain/parent/subdomain]` section
:feature: `case_sensitive=Preserving` can now be set for trusted domains with AD provider
---
 src/db/sysdb_subdomains.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
index ed3e7055c3..c0a676d491 100644
--- a/src/db/sysdb_subdomains.c
+++ b/src/db/sysdb_subdomains.c
@@ -221,6 +221,7 @@ check_subdom_config_file(struct confdb_ctx *confdb,
                          struct sss_domain_info *subdomain)
 {
     char *sd_conf_path;
+    char *case_sensitive_opt;
     TALLOC_CTX *tmp_ctx;
     errno_t ret;
 
@@ -272,6 +273,38 @@ check_subdom_config_file(struct confdb_ctx *confdb,
         goto done;
     }
 
+    /* case_sensitive=Preserving */
+    ret = confdb_get_string(confdb, tmp_ctx, sd_conf_path,
+                            CONFDB_DOMAIN_CASE_SENSITIVE, NULL,
+                            &case_sensitive_opt);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_OP_FAILURE,
+              "Failed to get %s option for the subdomain: %s\n",
+              CONFDB_DOMAIN_CASE_SENSITIVE, subdomain->name);
+        goto done;
+    }
+
+    if (case_sensitive_opt != NULL) {
+        DEBUG(SSSDBG_CONF_SETTINGS, "%s/%s has value %s\n", sd_conf_path,
+              CONFDB_DOMAIN_CASE_SENSITIVE, case_sensitive_opt);
+        if (strcasecmp(case_sensitive_opt, "true") == 0) {
+            DEBUG(SSSDBG_CRIT_FAILURE,
+                  "Warning: subdomain can not be set as case-sensitive.\n");
+            subdomain->case_sensitive = false;
+            subdomain->case_preserve = false;
+        } else if (strcasecmp(case_sensitive_opt, "false") == 0) {
+            subdomain->case_sensitive = false;
+            subdomain->case_preserve = false;
+        } else if (strcasecmp(case_sensitive_opt, "preserving") == 0) {
+            subdomain->case_sensitive = false;
+            subdomain->case_preserve = true;
+        } else {
+            DEBUG(SSSDBG_FATAL_FAILURE,
+                "Invalid value for %s\n", CONFDB_DOMAIN_CASE_SENSITIVE);
+            goto done;
+        }
+    }
+
     ret = EOK;
 done:
     talloc_free(tmp_ctx);

From 1fdf75b1143f094c2f06848a74948337d199f5b6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com>
Date: Tue, 21 Jul 2020 12:35:50 +0200
Subject: [PATCH 4/6] subdomains: allow to inherit case_sensitive=Preserving
 for IPA

Resolves: https://github.com/SSSD/sssd/issues/5250
---
 src/providers/ipa/ipa_s2n_exop.c | 81 +++++++++++++++++++-------------
 1 file changed, 48 insertions(+), 33 deletions(-)

diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c
index fb93c6233a..08b1113fa0 100644
--- a/src/providers/ipa/ipa_s2n_exop.c
+++ b/src/providers/ipa/ipa_s2n_exop.c
@@ -844,6 +844,46 @@ static errno_t add_v1_group_data(BerElement *ber,
     return ret;
 }
 
+static char *s2n_response_to_attrs_fqname(TALLOC_CTX *mem_ctx,
+                                          enum extdom_protocol protocol,
+                                          const char *domain_name,
+                                          const char *name)
+{
+    char *lc_name;
+    char *out_name;
+
+    if (protocol == EXTDOM_V0) {
+        /* Compatibility with older IPA servers that may use winbind instead
+         * of SSSD's server mode.
+         *
+         * Winbind is not consistent with the case of the returned user
+         * name. In general all names should be lower case but there are
+         * bug in some version of winbind which might lead to upper case
+         * letters in the name. To be on the safe side we explicitly
+         * lowercase the name.
+         */
+
+        lc_name = sss_tc_utf8_str_tolower(NULL, name);
+        if (lc_name == NULL) {
+            DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory!\n");
+            return NULL;
+        }
+
+        out_name = sss_create_internal_fqname(mem_ctx, lc_name, domain_name);
+        talloc_free(lc_name);
+    } else {
+        /* Keep the original casing to support case_sensitive=Preserving */
+        out_name = sss_create_internal_fqname(mem_ctx, name, domain_name);
+    }
+
+    if (out_name == NULL) {
+        DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory!\n");
+        return NULL;
+    }
+
+    return out_name;
+}
+
 static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
                                     struct req_input *req_input,
                                     struct resp_attrs *attrs,
@@ -865,7 +905,6 @@ static errno_t s2n_response_to_attrs(TALLOC_CTX *mem_ctx,
     enum response_types type;
     char *domain_name = NULL;
     char *name = NULL;
-    char *lc_name = NULL;
     uid_t uid;
     gid_t gid;
     struct resp_attrs *attrs = NULL;
@@ -920,23 +959,11 @@ static errno_t s2n_response_to_attrs(TALLOC_CTX *mem_ctx,
                 goto done;
             }
 
-            /* Winbind is not consistent with the case of the returned user
-             * name. In general all names should be lower case but there are
-             * bug in some version of winbind which might lead to upper case
-             * letters in the name. To be on the safe side we explicitly
-             * lowercase the name. */
-            lc_name = sss_tc_utf8_str_tolower(attrs, name);
-            if (lc_name == NULL) {
-                ret = ENOMEM;
-                goto done;
-            }
-
-            attrs->a.user.pw_name = sss_create_internal_fqname(attrs,
-                                                               lc_name,
-                                                               domain_name);
-            talloc_free(lc_name);
+            attrs->a.user.pw_name = s2n_response_to_attrs_fqname(attrs,
+                                                                 protocol,
+                                                                 domain_name,
+                                                                 name);
             if (attrs->a.user.pw_name == NULL) {
-                DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
                 ret = ENOMEM;
                 goto done;
             }
@@ -969,23 +996,11 @@ static errno_t s2n_response_to_attrs(TALLOC_CTX *mem_ctx,
                 goto done;
             }
 
-            /* Winbind is not consistent with the case of the returned user
-             * name. In general all names should be lower case but there are
-             * bug in some version of winbind which might lead to upper case
-             * letters in the name. To be on the safe side we explicitly
-             * lowercase the name. */
-            lc_name = sss_tc_utf8_str_tolower(attrs, name);
-            if (lc_name == NULL) {
-                ret = ENOMEM;
-                goto done;
-            }
-
-            attrs->a.group.gr_name = sss_create_internal_fqname(attrs,
-                                                                lc_name,
-                                                                domain_name);
-            talloc_free(lc_name);
+            attrs->a.group.gr_name = s2n_response_to_attrs_fqname(attrs,
+                                                                  protocol,
+                                                                  domain_name,
+                                                                  name);
             if (attrs->a.group.gr_name == NULL) {
-                DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
                 ret = ENOMEM;
                 goto done;
             }

From dbdc7ef8835d743f03d426485026d59cf536de01 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com>
Date: Thu, 12 Nov 2020 12:27:50 +0100
Subject: [PATCH 5/6] allow to override domain's case_preserve in
 size_output_name

---
 src/providers/data_provider/dp_target_id.c            | 5 +++--
 src/responder/common/cache_req/cache_req_sr_overlay.c | 1 +
 src/responder/common/responder.h                      | 1 +
 src/responder/common/responder_common.c               | 9 +++++----
 src/responder/nss/nss_cmd.c                           | 1 +
 src/responder/nss/nss_get_object.c                    | 3 ++-
 src/responder/nss/nss_iface.c                         | 3 ++-
 src/responder/nss/nss_protocol_grent.c                | 3 ++-
 src/responder/nss/nss_protocol_pwent.c                | 3 ++-
 src/responder/nss/nss_protocol_sid.c                  | 3 ++-
 src/responder/pam/pamsrv_p11.c                        | 4 +++-
 src/responder/sudo/sudosrv_get_sudorules.c            | 4 ++--
 src/tests/cmocka/test_responder_common.c              | 3 ++-
 src/util/usertools.c                                  | 4 ++--
 src/util/util.h                                       | 1 +
 15 files changed, 31 insertions(+), 17 deletions(-)

diff --git a/src/providers/data_provider/dp_target_id.c b/src/providers/data_provider/dp_target_id.c
index 36606d73f6..a98ec0a4e9 100644
--- a/src/providers/data_provider/dp_target_id.c
+++ b/src/providers/data_provider/dp_target_id.c
@@ -225,8 +225,8 @@ static void dp_req_initgr_pp_sr_overlay(struct data_provider *provider,
 
     /* Format output username */
     name = sss_get_name_from_msg(ctx->domain_info, res->msgs[0]);
-    ret = sss_output_fqname(tmp_ctx, ctx->domain_info, name,
-                            be->override_space, &output_name);
+    ret = sss_output_fqname(tmp_ctx, ctx->domain_info, name, be->override_space,
+                            ctx->domain_info->case_preserve, &output_name);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE,
               "Failed formatting output username from \"%s\": %s\n",
@@ -303,6 +303,7 @@ static void dp_req_initgr_pp_sr_overlay(struct data_provider *provider,
             }
             ret = sss_output_fqname(tmp_ctx, ctx->domain_info,
                                     name, be->override_space,
+                                    ctx->domain_info->case_preserve,
                                     &output_name);
             if (ret != EOK) {
                 DEBUG(SSSDBG_CRIT_FAILURE,
diff --git a/src/responder/common/cache_req/cache_req_sr_overlay.c b/src/responder/common/cache_req/cache_req_sr_overlay.c
index 8deb06a603..7b7c2feca6 100644
--- a/src/responder/common/cache_req/cache_req_sr_overlay.c
+++ b/src/responder/common/cache_req/cache_req_sr_overlay.c
@@ -162,6 +162,7 @@ static errno_t cache_req_sr_overlay_match_users(
             name = sss_get_name_from_msg(result->domain, msg);
             ret = sss_output_fqname(tmp_ctx, result->domain, name,
                                     rctx->override_space,
+                                    result->domain->case_preserve,
                                     &output_name);
             if (ret != EOK) {
                 CACHE_REQ_DEBUG(SSSDBG_CRIT_FAILURE, cr,
diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h
index f83ba1bc05..844a1196a1 100644
--- a/src/responder/common/responder.h
+++ b/src/responder/common/responder.h
@@ -415,6 +415,7 @@ int sized_output_name(TALLOC_CTX *mem_ctx,
                       struct resp_ctx *rctx,
                       const char *orig_name,
                       struct sss_domain_info *name_dom,
+                      bool case_preserve,
                       struct sized_string **_name);
 
 /* Format orig_name into a sized_string in output format as prescribed
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index 7061d018a6..91b1166380 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -1888,6 +1888,7 @@ int sized_output_name(TALLOC_CTX *mem_ctx,
                       struct resp_ctx *rctx,
                       const char *orig_name,
                       struct sss_domain_info *name_dom,
+                      bool case_preserve,
                       struct sized_string **_name)
 {
     TALLOC_CTX *tmp_ctx = NULL;
@@ -1906,8 +1907,8 @@ int sized_output_name(TALLOC_CTX *mem_ctx,
         goto done;
     }
 
-    ret = sss_output_fqname(name, name_dom, orig_name,
-                            rctx->override_space, &name_str);
+    ret = sss_output_fqname(name, name_dom, orig_name, rctx->override_space,
+                            case_preserve, &name_str);
     if (ret != EOK) {
         goto done;
     }
@@ -1953,8 +1954,8 @@ int sized_domain_name(TALLOC_CTX *mem_ctx,
         goto done;
     }
 
-    ret = sized_output_name(mem_ctx, rctx, member_name,
-                            member_dom, _name);
+    ret = sized_output_name(mem_ctx, rctx, member_name, member_dom,
+                            member_dom->case_preserve, _name);
 done:
     talloc_free(tmp_ctx);
     return ret;
diff --git a/src/responder/nss/nss_cmd.c b/src/responder/nss/nss_cmd.c
index 844776c5fd..1ac0e4b38f 100644
--- a/src/responder/nss/nss_cmd.c
+++ b/src/responder/nss/nss_cmd.c
@@ -545,6 +545,7 @@ static errno_t invalidate_cache(struct nss_cmd_ctx *cmd_ctx,
     }
     ret = sss_output_fqname(cmd_ctx, result->domain, name,
                             cmd_ctx->nss_ctx->rctx->override_space,
+                            result->domain->case_preserve,
                             &output_name);
     if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE, "sss_output_fqname failed.\n");
diff --git a/src/responder/nss/nss_get_object.c b/src/responder/nss/nss_get_object.c
index 3a8a7c3ea5..d658a86a42 100644
--- a/src/responder/nss/nss_get_object.c
+++ b/src/responder/nss/nss_get_object.c
@@ -109,7 +109,8 @@ memcache_delete_entry(struct nss_ctx *nss_ctx,
         }
 
         if (name != NULL) {
-            ret = sized_output_name(NULL, rctx, name, dom, &sized_name);
+            ret = sized_output_name(NULL, rctx, name, dom, dom->case_preserve,
+                                    &sized_name);
             if (ret != EOK) {
                 DEBUG(SSSDBG_OP_FAILURE,
                       "Unable to create sized name [%d]: %s\n",
diff --git a/src/responder/nss/nss_iface.c b/src/responder/nss/nss_iface.c
index ab2ba926d7..14ac4c6750 100644
--- a/src/responder/nss/nss_iface.c
+++ b/src/responder/nss/nss_iface.c
@@ -56,7 +56,8 @@ nss_update_initgr_memcache(struct nss_ctx *nctx,
         return;
     }
 
-    ret = sized_output_name(tmp_ctx, nctx->rctx, fq_name, dom, &delete_name);
+    ret = sized_output_name(tmp_ctx, nctx->rctx, fq_name, dom,
+                            dom->case_preserve, &delete_name);
     if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE,
               "sized_output_name failed for '%s': %d [%s]\n",
diff --git a/src/responder/nss/nss_protocol_grent.c b/src/responder/nss/nss_protocol_grent.c
index 135b392f74..7531b1b2f2 100644
--- a/src/responder/nss/nss_protocol_grent.c
+++ b/src/responder/nss/nss_protocol_grent.c
@@ -52,7 +52,8 @@ nss_get_grent(TALLOC_CTX *mem_ctx,
     }
 
     /* Convert to sized strings. */
-    ret = sized_output_name(mem_ctx, nss_ctx->rctx, name, domain, _name);
+    ret = sized_output_name(mem_ctx, nss_ctx->rctx, name, domain,
+                            domain->case_preserve, _name);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE,
               "sized_output_name failed, skipping [%d]: %s\n",
diff --git a/src/responder/nss/nss_protocol_pwent.c b/src/responder/nss/nss_protocol_pwent.c
index c9926cdc99..e9d3c86b01 100644
--- a/src/responder/nss/nss_protocol_pwent.c
+++ b/src/responder/nss/nss_protocol_pwent.c
@@ -207,7 +207,8 @@ nss_get_pwent(TALLOC_CTX *mem_ctx,
     }
 
     /* Convert to sized strings. */
-    ret = sized_output_name(mem_ctx, nss_ctx->rctx, name, domain, _name);
+    ret = sized_output_name(mem_ctx, nss_ctx->rctx, name, domain,
+                            domain->case_preserve, _name);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE,
               "sized_output_name failed, skipping [%d]: %s\n",
diff --git a/src/responder/nss/nss_protocol_sid.c b/src/responder/nss/nss_protocol_sid.c
index 96cb8617bc..4f86420585 100644
--- a/src/responder/nss/nss_protocol_sid.c
+++ b/src/responder/nss/nss_protocol_sid.c
@@ -379,7 +379,8 @@ nss_get_ad_name(TALLOC_CTX *mem_ctx,
         return EINVAL;
     }
 
-    ret = sized_output_name(mem_ctx, rctx, name, result->domain, _sz_name);
+    ret = sized_output_name(mem_ctx, rctx, name, result->domain,
+                            result->domain->case_preserve, _sz_name);
     if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE,
               "Unable to create sized name [%d]: %s\n",
diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c
index bf285c264f..3c22a442f8 100644
--- a/src/responder/pam/pamsrv_p11.c
+++ b/src/responder/pam/pamsrv_p11.c
@@ -1221,7 +1221,9 @@ errno_t add_pam_cert_response(struct pam_data *pd, struct sss_domain_info *dom,
 
                 if (user_dom != NULL) {
                     ret = sss_output_fqname(short_name, user_dom,
-                                            sysdb_username, false, &nss_name);
+                                            sysdb_username, false,
+                                            user_dom->case_preserve,
+                                            &nss_name);
                     if (ret != EOK) {
                         nss_name = NULL;
                     }
diff --git a/src/responder/sudo/sudosrv_get_sudorules.c b/src/responder/sudo/sudosrv_get_sudorules.c
index bfc3497043..ad84990bd4 100644
--- a/src/responder/sudo/sudosrv_get_sudorules.c
+++ b/src/responder/sudo/sudosrv_get_sudorules.c
@@ -153,8 +153,8 @@ static errno_t sudosrv_format_runas(struct resp_ctx *rctx,
             continue;
         }
 
-        ret = sss_output_fqname(tmp_ctx, dom, value,
-                                rctx->override_space, &fqname);
+        ret = sss_output_fqname(tmp_ctx, dom, value, rctx->override_space,
+                                dom->case_preserve, &fqname);
         if (ret != EOK) {
             DEBUG(SSSDBG_CRIT_FAILURE, "Unable to convert %s to output fqname "
                   "[%d]: %s\n", value, ret, sss_strerror(ret));
diff --git a/src/tests/cmocka/test_responder_common.c b/src/tests/cmocka/test_responder_common.c
index 5fc0d712df..431990afa2 100644
--- a/src/tests/cmocka/test_responder_common.c
+++ b/src/tests/cmocka/test_responder_common.c
@@ -281,7 +281,8 @@ void test_sss_output_fqname(void **state)
     struct sized_string *res = NULL;
 
     ret = sized_output_name(parse_inp_ctx, parse_inp_ctx->rctx, "dummy",
-                            parse_inp_ctx->tctx->dom, &res);
+                            parse_inp_ctx->tctx->dom,
+                            parse_inp_ctx->tctx->dom->case_preserve, &res);
     assert_int_equal(ret, EOK);
     assert_non_null(res);
     assert_string_equal("dummy", res->str);
diff --git a/src/util/usertools.c b/src/util/usertools.c
index c2adc64fea..48f2fe5dff 100644
--- a/src/util/usertools.c
+++ b/src/util/usertools.c
@@ -819,6 +819,7 @@ int sss_output_fqname(TALLOC_CTX *mem_ctx,
                       struct sss_domain_info *domain,
                       const char *name,
                       char override_space,
+                      bool case_preserve,
                       char **_output_name)
 {
     TALLOC_CTX *tmp_ctx = NULL;
@@ -831,8 +832,7 @@ int sss_output_fqname(TALLOC_CTX *mem_ctx,
         goto done;
     }
 
-    output_name = sss_output_name(tmp_ctx, name, domain->case_preserve,
-                                  override_space);
+    output_name = sss_output_name(tmp_ctx, name, case_preserve, override_space);
     if (output_name == NULL) {
         ret = EIO;
         goto done;
diff --git a/src/util/util.h b/src/util/util.h
index 581c0edfbc..11f556f7ff 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -317,6 +317,7 @@ int sss_output_fqname(TALLOC_CTX *mem_ctx,
                       struct sss_domain_info *domain,
                       const char *name,
                       char override_space,
+                      bool case_preserve,
                       char **_output_name);
 
 const char *sss_get_name_from_msg(struct sss_domain_info *domain,

From 7d2a47a377699efe599cb268061fa98029a34b4c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com>
Date: Thu, 12 Nov 2020 12:53:53 +0100
Subject: [PATCH 6/6] nss: return names in original casing for extended
 operations

To allow case_sensitive=Preserving for trusted domain without the need
to set this option also on the server.

Resolves: https://github.com/SSSD/sssd/issues/5250

:feature: `case_sensitive=Preserving` can now be set for trusted domains
  with IPA provider. However, this also requires SSSD update on the
  server side.
---
 src/responder/nss/nss_cmd.c            |  8 +++---
 src/responder/nss/nss_protocol.h       | 12 ++++++++
 src/responder/nss/nss_protocol_grent.c | 36 +++++++++++++++++++-----
 src/responder/nss/nss_protocol_pwent.c | 39 ++++++++++++++++++++------
 4 files changed, 76 insertions(+), 19 deletions(-)

diff --git a/src/responder/nss/nss_cmd.c b/src/responder/nss/nss_cmd.c
index 1ac0e4b38f..21b0fb54cc 100644
--- a/src/responder/nss/nss_cmd.c
+++ b/src/responder/nss/nss_cmd.c
@@ -988,13 +988,13 @@ static errno_t nss_cmd_getpwuid(struct cli_ctx *cli_ctx)
 static errno_t nss_cmd_getpwnam_ex(struct cli_ctx *cli_ctx)
 {
     return nss_getby_name(cli_ctx, true, CACHE_REQ_USER_BY_NAME, NULL,
-                          SSS_MC_PASSWD, nss_protocol_fill_pwent);
+                          SSS_MC_PASSWD, nss_protocol_fill_pwent_ex);
 }
 
 static errno_t nss_cmd_getpwuid_ex(struct cli_ctx *cli_ctx)
 {
     return nss_getby_id(cli_ctx, true, CACHE_REQ_USER_BY_ID, NULL,
-                        SSS_MC_PASSWD, nss_protocol_fill_pwent);
+                        SSS_MC_PASSWD, nss_protocol_fill_pwent_ex);
 }
 
 static errno_t nss_cmd_setpwent(struct cli_ctx *cli_ctx)
@@ -1043,13 +1043,13 @@ static errno_t nss_cmd_getgrgid(struct cli_ctx *cli_ctx)
 static errno_t nss_cmd_getgrnam_ex(struct cli_ctx *cli_ctx)
 {
     return nss_getby_name(cli_ctx, true, CACHE_REQ_GROUP_BY_NAME, NULL,
-                          SSS_MC_GROUP, nss_protocol_fill_grent);
+                          SSS_MC_GROUP, nss_protocol_fill_grent_ex);
 }
 
 static errno_t nss_cmd_getgrgid_ex(struct cli_ctx *cli_ctx)
 {
     return nss_getby_id(cli_ctx, true, CACHE_REQ_GROUP_BY_ID, NULL,
-                        SSS_MC_GROUP, nss_protocol_fill_grent);
+                        SSS_MC_GROUP, nss_protocol_fill_grent_ex);
 }
 
 
diff --git a/src/responder/nss/nss_protocol.h b/src/responder/nss/nss_protocol.h
index 357017e768..7e81cd27b3 100644
--- a/src/responder/nss/nss_protocol.h
+++ b/src/responder/nss/nss_protocol.h
@@ -135,12 +135,24 @@ nss_protocol_fill_pwent(struct nss_ctx *nss_ctx,
                         struct sss_packet *packet,
                         struct cache_req_result *result);
 
+errno_t
+nss_protocol_fill_pwent_ex(struct nss_ctx *nss_ctx,
+                           struct nss_cmd_ctx *cmd_ctx,
+                           struct sss_packet *packet,
+                           struct cache_req_result *result);
+
 errno_t
 nss_protocol_fill_grent(struct nss_ctx *nss_ctx,
                         struct nss_cmd_ctx *cmd_ctx,
                         struct sss_packet *packet,
                         struct cache_req_result *result);
 
+errno_t
+nss_protocol_fill_grent_ex(struct nss_ctx *nss_ctx,
+                           struct nss_cmd_ctx *cmd_ctx,
+                           struct sss_packet *packet,
+                           struct cache_req_result *result);
+
 errno_t
 nss_protocol_fill_initgr(struct nss_ctx *nss_ctx,
                          struct nss_cmd_ctx *cmd_ctx,
diff --git a/src/responder/nss/nss_protocol_grent.c b/src/responder/nss/nss_protocol_grent.c
index 7531b1b2f2..1bffe872c8 100644
--- a/src/responder/nss/nss_protocol_grent.c
+++ b/src/responder/nss/nss_protocol_grent.c
@@ -25,6 +25,7 @@ nss_get_grent(TALLOC_CTX *mem_ctx,
               struct nss_ctx *nss_ctx,
               struct sss_domain_info *domain,
               struct ldb_message *msg,
+              bool case_preserve,
               uint32_t *_gid,
               struct sized_string **_name)
 {
@@ -53,7 +54,7 @@ nss_get_grent(TALLOC_CTX *mem_ctx,
 
     /* Convert to sized strings. */
     ret = sized_output_name(mem_ctx, nss_ctx->rctx, name, domain,
-                            domain->case_preserve, _name);
+                            case_preserve, _name);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE,
               "sized_output_name failed, skipping [%d]: %s\n",
@@ -209,11 +210,12 @@ nss_protocol_fill_members(struct sss_packet *packet,
     return ret;
 }
 
-errno_t
-nss_protocol_fill_grent(struct nss_ctx *nss_ctx,
-                        struct nss_cmd_ctx *cmd_ctx,
-                        struct sss_packet *packet,
-                        struct cache_req_result *result)
+static errno_t
+nss_protocol_fill_grent_internal(struct nss_ctx *nss_ctx,
+                                 struct nss_cmd_ctx *cmd_ctx,
+                                 struct sss_packet *packet,
+                                 struct cache_req_result *result,
+                                 bool case_preserve)
 {
     TALLOC_CTX *tmp_ctx;
     struct ldb_message *msg;
@@ -254,7 +256,7 @@ nss_protocol_fill_grent(struct nss_ctx *nss_ctx,
         to_sized_string(&pwfield, nss_get_pwfield(nss_ctx, result->domain));
 
         ret = nss_get_grent(tmp_ctx, nss_ctx, result->domain, msg,
-                            &gid, &name);
+                            case_preserve, &gid, &name);
         if (ret != EOK) {
             continue;
         }
@@ -355,6 +357,26 @@ static bool is_group_filtered(struct sss_nc_ctx *ncache,
     return false;
 }
 
+errno_t
+nss_protocol_fill_grent(struct nss_ctx *nss_ctx,
+                        struct nss_cmd_ctx *cmd_ctx,
+                        struct sss_packet *packet,
+                        struct cache_req_result *result)
+{
+    return nss_protocol_fill_grent_internal(nss_ctx, cmd_ctx, packet, result,
+                                            result->domain->case_preserve);
+}
+
+errno_t
+nss_protocol_fill_grent_ex(struct nss_ctx *nss_ctx,
+                           struct nss_cmd_ctx *cmd_ctx,
+                           struct sss_packet *packet,
+                           struct cache_req_result *result)
+{
+    return nss_protocol_fill_grent_internal(nss_ctx, cmd_ctx, packet, result,
+                                            true);
+}
+
 errno_t
 nss_protocol_fill_initgr(struct nss_ctx *nss_ctx,
                          struct nss_cmd_ctx *cmd_ctx,
diff --git a/src/responder/nss/nss_protocol_pwent.c b/src/responder/nss/nss_protocol_pwent.c
index e9d3c86b01..772a99ae9f 100644
--- a/src/responder/nss/nss_protocol_pwent.c
+++ b/src/responder/nss/nss_protocol_pwent.c
@@ -166,6 +166,7 @@ nss_get_pwent(TALLOC_CTX *mem_ctx,
               struct nss_ctx *nss_ctx,
               struct sss_domain_info *domain,
               struct ldb_message *msg,
+              bool case_preserve,
               uint32_t *_uid,
               uint32_t *_gid,
               struct sized_string **_name,
@@ -208,7 +209,7 @@ nss_get_pwent(TALLOC_CTX *mem_ctx,
 
     /* Convert to sized strings. */
     ret = sized_output_name(mem_ctx, nss_ctx->rctx, name, domain,
-                            domain->case_preserve, _name);
+                            case_preserve, _name);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE,
               "sized_output_name failed, skipping [%d]: %s\n",
@@ -226,11 +227,12 @@ nss_get_pwent(TALLOC_CTX *mem_ctx,
     return EOK;
 }
 
-errno_t
-nss_protocol_fill_pwent(struct nss_ctx *nss_ctx,
-                        struct nss_cmd_ctx *cmd_ctx,
-                        struct sss_packet *packet,
-                        struct cache_req_result *result)
+static errno_t
+nss_protocol_fill_pwent_internal(struct nss_ctx *nss_ctx,
+                                 struct nss_cmd_ctx *cmd_ctx,
+                                 struct sss_packet *packet,
+                                 struct cache_req_result *result,
+                                 bool case_preserve)
 {
     TALLOC_CTX *tmp_ctx;
     struct ldb_message *msg;
@@ -269,8 +271,9 @@ nss_protocol_fill_pwent(struct nss_ctx *nss_ctx,
         /* Password field content. */
         to_sized_string(&pwfield, nss_get_pwfield(nss_ctx, result->domain));
 
-        ret = nss_get_pwent(tmp_ctx, nss_ctx, result->domain, msg, &uid, &gid,
-                            &name, &gecos, &homedir, &shell);
+        ret = nss_get_pwent(tmp_ctx, nss_ctx, result->domain, msg,
+                            case_preserve, &uid, &gid, &name,
+                            &gecos, &homedir, &shell);
         if (ret != EOK) {
             continue;
         }
@@ -329,3 +332,23 @@ nss_protocol_fill_pwent(struct nss_ctx *nss_ctx,
 
     return EOK;
 }
+
+errno_t
+nss_protocol_fill_pwent(struct nss_ctx *nss_ctx,
+                        struct nss_cmd_ctx *cmd_ctx,
+                        struct sss_packet *packet,
+                        struct cache_req_result *result)
+{
+    return nss_protocol_fill_pwent_internal(nss_ctx, cmd_ctx, packet, result,
+                                            result->domain->case_preserve);
+}
+
+errno_t
+nss_protocol_fill_pwent_ex(struct nss_ctx *nss_ctx,
+                           struct nss_cmd_ctx *cmd_ctx,
+                           struct sss_packet *packet,
+                           struct cache_req_result *result)
+{
+    return nss_protocol_fill_pwent_internal(nss_ctx, cmd_ctx, packet, result,
+                                            true);
+}
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedorahosted.org/archives/list/sssd-devel@lists.fedorahosted.org

Reply via email to