[SSSD] [PATCH] Backport extending the LDAP maps to 1.11

Jakub Hrozek jhrozek at redhat.com
Mon Jun 2 18:18:40 UTC 2014


Hi,

this time it's not a straight cherry-pick but a rebase, because starting
with 1.10 the LDAP provider files were split bit differently. But the
code itself is the same, just moved elsewhere.

The attached patches also include fixes we found after we pushed the
original patches.
-------------- next part --------------
>From 7b9ad4d28e0cdd1ef7d7ea6053aa4f67bd2d9a33 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Mon, 21 Apr 2014 21:33:36 +0200
Subject: [PATCH 1/4] LDAP: Fix off-by-one bug in sdap_copy_opts
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The sdap_copy_opts function copied all the arguments except for the
sentinel.

Reviewed-by: Simo Sorce <simo at redhat.com>
Reviewed-by: Pavel Březina <pbrezina at redhat.com>
(cherry picked from commit fcb8e3f1f49bb34c409d8dbd75889eb72be05517)
---
 Makefile.am                    |  3 +++
 src/providers/ldap/sdap.c      |  5 +++-
 src/tests/ipa_ldap_opt-tests.c | 55 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/Makefile.am b/Makefile.am
index f9183f914d134040b9c2435f8c4ab6e92dde332e..3a4e5857f5bf88623394125ae65e141acdcbe0af 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1182,6 +1182,9 @@ auth_tests_LDADD = \
 
 ipa_ldap_opt_tests_SOURCES = \
     src/providers/data_provider_opts.c \
+    src/providers/ldap/sdap.c \
+    src/providers/ldap/sdap_range.c \
+    src/util/sss_ldap.c \
     src/tests/ipa_ldap_opt-tests.c
 ipa_ldap_opt_tests_CFLAGS = \
     $(AM_CFLAGS) \
diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
index aa6b0e921767ab97f025998276e16ec9abdfc03f..b303547a4524f5dc90eaf16dc6ca0e579a8240ae 100644
--- a/src/providers/ldap/sdap.c
+++ b/src/providers/ldap/sdap.c
@@ -36,7 +36,7 @@ int sdap_copy_map(TALLOC_CTX *memctx,
     struct sdap_attr_map *map;
     int i;
 
-    map = talloc_array(memctx, struct sdap_attr_map, num_entries);
+    map = talloc_array(memctx, struct sdap_attr_map, num_entries + 1);
     if (!map) {
         return ENOMEM;
     }
@@ -64,6 +64,9 @@ int sdap_copy_map(TALLOC_CTX *memctx,
               map[i].name ? map[i].name : "");
     }
 
+    /* Include the sentinel */
+    memset(&map[num_entries], 0, sizeof(struct sdap_attr_map));
+
     *_map = map;
     return EOK;
 }
diff --git a/src/tests/ipa_ldap_opt-tests.c b/src/tests/ipa_ldap_opt-tests.c
index 25a094082dc369092f10ad823d98909027dd9a7e..bbb49935dec47983c4d04ef73385a4ed8a1ea372 100644
--- a/src/tests/ipa_ldap_opt-tests.c
+++ b/src/tests/ipa_ldap_opt-tests.c
@@ -48,6 +48,14 @@ struct test_domain test_domains[] = {
     { NULL, NULL}
 };
 
+/* Mock parsing search base without overlinking the test */
+errno_t sdap_parse_search_base(TALLOC_CTX *mem_ctx,
+                               struct dp_option *opts, int class,
+                               struct sdap_search_base ***_search_bases)
+{
+    return EOK;
+}
+
 START_TEST(test_domain_to_basedn)
 {
     int ret;
@@ -226,6 +234,49 @@ START_TEST(test_copy_opts)
 }
 END_TEST
 
+START_TEST(test_copy_sdap_map)
+{
+    errno_t ret;
+    struct sdap_attr_map *out_map;
+
+    ret = sdap_copy_map(global_talloc_context,
+                        rfc2307_user_map, SDAP_OPTS_USER, &out_map);
+    fail_unless(ret == EOK, "[%s]", strerror(ret));
+    fail_unless(out_map[SDAP_OPTS_USER].name == NULL);
+    fail_unless(out_map[SDAP_OPTS_USER].def_name == NULL);
+    fail_unless(out_map[SDAP_OPTS_USER].sys_name == NULL);
+    fail_unless(out_map[SDAP_OPTS_USER].opt_name == NULL);
+    talloc_free(out_map);
+
+    ret = sdap_copy_map(global_talloc_context,
+                        rfc2307bis_user_map, SDAP_OPTS_USER, &out_map);
+    fail_unless(ret == EOK, "[%s]", strerror(ret));
+    fail_unless(out_map[SDAP_OPTS_USER].name == NULL);
+    fail_unless(out_map[SDAP_OPTS_USER].def_name == NULL);
+    fail_unless(out_map[SDAP_OPTS_USER].sys_name == NULL);
+    fail_unless(out_map[SDAP_OPTS_USER].opt_name == NULL);
+    talloc_free(out_map);
+
+    ret = sdap_copy_map(global_talloc_context,
+                        ipa_user_map, SDAP_OPTS_USER, &out_map);
+    fail_unless(ret == EOK, "[%s]", strerror(ret));
+    fail_unless(out_map[SDAP_OPTS_USER].name == NULL);
+    fail_unless(out_map[SDAP_OPTS_USER].def_name == NULL);
+    fail_unless(out_map[SDAP_OPTS_USER].sys_name == NULL);
+    fail_unless(out_map[SDAP_OPTS_USER].opt_name == NULL);
+    talloc_free(out_map);
+
+    ret = sdap_copy_map(global_talloc_context,
+                        gen_ad2008r2_user_map, SDAP_OPTS_USER, &out_map);
+    fail_unless(ret == EOK, "[%s]", strerror(ret));
+    fail_unless(out_map[SDAP_OPTS_USER].name == NULL);
+    fail_unless(out_map[SDAP_OPTS_USER].def_name == NULL);
+    fail_unless(out_map[SDAP_OPTS_USER].sys_name == NULL);
+    fail_unless(out_map[SDAP_OPTS_USER].opt_name == NULL);
+    talloc_free(out_map);
+}
+END_TEST
+
 Suite *ipa_ldap_opt_suite (void)
 {
     Suite *s = suite_create ("ipa_ldap_opt");
@@ -245,6 +296,10 @@ Suite *ipa_ldap_opt_suite (void)
     tcase_add_test (tc_dp_opts, test_copy_opts);
     suite_add_tcase (s, tc_dp_opts);
 
+    TCase *tc_sdap_opts = tcase_create ("sdap_opts");
+    tcase_add_test (tc_sdap_opts, test_copy_sdap_map);
+    suite_add_tcase (s, tc_sdap_opts);
+
     return s;
 }
 
-- 
1.9.0

-------------- next part --------------
>From 3800097bae37578d8cf379186689c32fe0e64b4b Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Wed, 31 Jul 2013 10:59:43 +0200
Subject: [PATCH 2/4] LDAP: Make it possible to extend an attribute map
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

https://fedorahosted.org/sssd/ticket/2073

This commit adds a new option ldap_user_extra_attrs that is unset by
default. When set, the option contains a list of LDAP attributes the LDAP
provider would download and store in addition to the usual set.

The list can either contain LDAP attribute names only, or colon-separated
tuples of LDAP attribute and SSSD cache attribute name. In case only LDAP
attribute name is specified, the attribute is saved to the cache verbatim.
Using a custom SSSD attribute name might be required by environments that
configure several SSSD domains with different LDAP schemas.

Reviewed-by: Simo Sorce <simo at redhat.com>
Reviewed-by: Pavel Březina <pbrezina at redhat.com>
---
 src/config/SSSDConfig/__init__.py.in          |   1 +
 src/config/etc/sssd.api.d/sssd-ldap.conf      |   1 +
 src/man/sssd-ldap.5.xml                       |  48 +++++++++++
 src/providers/ad/ad_common.c                  |   9 ++
 src/providers/ad/ad_opts.h                    |   1 +
 src/providers/ipa/ipa_common.c                |   9 ++
 src/providers/ipa/ipa_netgroups.c             |   3 +-
 src/providers/ipa/ipa_opts.h                  |   1 +
 src/providers/ldap/ldap_common.c              |  45 ++++++++++
 src/providers/ldap/ldap_id.c                  |   3 +-
 src/providers/ldap/ldap_opts.h                |   1 +
 src/providers/ldap/sdap.c                     | 116 ++++++++++++++++++++++++++
 src/providers/ldap/sdap.h                     |   9 ++
 src/providers/ldap/sdap_async_enum.c          |   3 +-
 src/providers/ldap/sdap_async_groups.c        |   6 +-
 src/providers/ldap/sdap_async_groups_ad.c     |   4 +-
 src/providers/ldap/sdap_async_initgroups.c    |   6 +-
 src/providers/ldap/sdap_async_nested_groups.c |   5 +-
 src/providers/ldap/sdap_async_users.c         |   6 +-
 src/util/util_errors.c                        |   2 +
 src/util/util_errors.h                        |   2 +
 21 files changed, 266 insertions(+), 15 deletions(-)

diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index 7029f5bc18dbaa1426d1baa48a7b035eac984340..de0348b1de0f2f4a8e91a6567300440d25eec8d6 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -272,6 +272,7 @@ option_strings = {
     'ldap_user_nds_login_expiration_time' : _('loginExpirationTime attribute of NDS'),
     'ldap_user_nds_login_allowed_time_map' : _('loginAllowedTimeMap attribute of NDS'),
     'ldap_user_ssh_public_key' : _('SSH public key attribute'),
+    'ldap_user_extra_attrs' : _('A list of extra attributes to download along with the user entry'),
 
     'ldap_group_search_base' : _('Base DN for group lookups'),
     # not used # 'ldap_group_search_scope' : _('Scope of group lookups'),
diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf
index 91eeadf3e0dfbd763b91698adde84c96a66bddbf..af9dfa841654904692998e7283aa38026418174e 100644
--- a/src/config/etc/sssd.api.d/sssd-ldap.conf
+++ b/src/config/etc/sssd.api.d/sssd-ldap.conf
@@ -48,6 +48,7 @@ ldap_id_mapping = bool, None, false
 ldap_user_search_base = str, None, false
 ldap_user_search_scope = str, None, false
 ldap_user_search_filter = str, None, false
+ldap_user_extra_attrs = str, None, false
 ldap_user_object_class = str, None, false
 ldap_user_name = str, None, false
 ldap_user_uid_number = str, None, false
diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml
index 06511d202de1c28319755a7d060e971a18cb87a5..6306b26199884f2f17c71eb93af10c96c6a704a7 100644
--- a/src/man/sssd-ldap.5.xml
+++ b/src/man/sssd-ldap.5.xml
@@ -616,6 +616,54 @@
                     </listitem>
                 </varlistentry>
 
+                <varlistentry>
+                    <term>ldap_user_extra_attrs (string)</term>
+                    <listitem>
+                        <para>
+                            Comma-separated list of LDAP attributes that SSSD
+                            would fetch along with the usual set of user
+                            attributes.
+                        </para>
+                        <para>
+                            The list can either contain LDAP attribute names
+                            only, or colon-separated tuples of SSSD cache
+                            attribute name and LDAP attribute name. In
+                            case only LDAP attribute name is specified,
+                            the attribute is saved to the cache verbatim.
+                            Using a custom SSSD attribute name might be
+                            required by environments that configure several
+                            SSSD domains with different LDAP schemas.
+                        </para>
+                        <para>
+                            Please note that several attribute names are
+                            reserved by SSSD, notably the <quote>name</quote>
+                            attribute. SSSD would report an error if any of
+                            the reserved attribute names is used as an extra
+                            attribute name.
+                        </para>
+                        <para>
+                            Examples:
+                        </para>
+                        <para>
+                            ldap_user_extra_attrs = telephoneNumber
+                        </para>
+                        <para>
+                            Save the <quote>telephoneNumber</quote> attribute from LDAP
+                            as <quote>telephoneNumber</quote> to the cache.
+                        </para>
+                        <para>
+                            ldap_user_extra_attrs = phone:telephoneNumber
+                        </para>
+                        <para>
+                            Save the <quote>telephoneNumber</quote> attribute from LDAP
+                            as <quote>phone</quote> to the cache.
+                        </para>
+                        <para>
+                            Default: not set
+                        </para>
+                    </listitem>
+                </varlistentry>
+
                 <varlistentry condition="with_ssh">
                     <term>ldap_user_ssh_public_key (string)</term>
                     <listitem>
diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c
index f5b01def208129c26339bd2d6a48e08ffac3fd47..af738bc82ba016759dd9a951a4b7b1832b61489d 100644
--- a/src/providers/ad/ad_common.c
+++ b/src/providers/ad/ad_common.c
@@ -201,6 +201,15 @@ ad_create_sdap_options(TALLOC_CTX *mem_ctx,
         goto done;
     }
 
+    ret = sdap_extend_map(id_opts,
+                          id_opts->user_map,
+                          SDAP_OPTS_USER, NULL,
+                          &id_opts->user_map,
+                          &id_opts->user_map_cnt);
+    if (ret != EOK) {
+        goto done;
+    }
+
     /* Group map */
     ret = sdap_get_map(id_opts,
                        cdb, conf_path,
diff --git a/src/providers/ad/ad_opts.h b/src/providers/ad/ad_opts.h
index 2657f728eb89c178439d5a8568e20cc0e71c69e8..feb7ba124fbcb5e2f506d157c0efba2722aa24ea 100644
--- a/src/providers/ad/ad_opts.h
+++ b/src/providers/ad/ad_opts.h
@@ -54,6 +54,7 @@ struct dp_option ad_def_ldap_opts[] = {
     { "ldap_user_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "ldap_user_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING },
     { "ldap_user_search_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+    { "ldap_user_extra_attrs", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "ldap_group_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "ldap_group_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING },
     { "ldap_group_search_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING },
diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c
index f84748267d65bedbadf39db3466d28502bfa0e3e..19de10d8bb92a4b3d0c8353eae128f3b4709a7af 100644
--- a/src/providers/ipa/ipa_common.c
+++ b/src/providers/ipa/ipa_common.c
@@ -547,6 +547,15 @@ int ipa_get_id_options(struct ipa_options *ipa_opts,
         goto done;
     }
 
+    ret = sdap_extend_map(ipa_opts->id,
+                          ipa_opts->id->user_map,
+                          SDAP_OPTS_USER, NULL,
+                          &ipa_opts->id->user_map,
+                          &ipa_opts->id->user_map_cnt);
+    if (ret != EOK) {
+        goto done;
+    }
+
     ret = sdap_get_map(ipa_opts->id,
                        cdb, conf_path,
                        ipa_group_map,
diff --git a/src/providers/ipa/ipa_netgroups.c b/src/providers/ipa/ipa_netgroups.c
index 9be8eae00c824e97118bf0d764ea21b199aadba0..89bb098dc7978edab51b2a0fe6d5d4657de7df82 100644
--- a/src/providers/ipa/ipa_netgroups.c
+++ b/src/providers/ipa/ipa_netgroups.c
@@ -493,7 +493,8 @@ static int ipa_netgr_fetch_users(struct ipa_get_netgroups_state *state,
                                                      SDAP_USER_SEARCH_BASE),
                                    LDAP_SCOPE_SUBTREE,
                                    filter, attrs, state->opts->user_map,
-                                   SDAP_OPTS_USER, state->timeout, true);
+                                   state->opts->user_map_cnt,
+                                   state->timeout, true);
 
     state->current_entity = ENTITY_USER;
     if (subreq == NULL) {
diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h
index 71bcfb2b2192de0ce4f933b4aecc8e5efde519b3..2b97044b405fa2d7a93c2b33cb04271e0f2dc98b 100644
--- a/src/providers/ipa/ipa_opts.h
+++ b/src/providers/ipa/ipa_opts.h
@@ -77,6 +77,7 @@ struct dp_option ipa_def_ldap_opts[] = {
     { "ldap_user_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "ldap_user_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING },
     { "ldap_user_search_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+    { "ldap_user_extra_attrs", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "ldap_group_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "ldap_group_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING },
     { "ldap_group_search_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING },
diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c
index 59487dec1ceaa21e18b55373575e4133248aa1ff..49468bf4bb8a0d5cecda9b8eca886293583ef8a9 100644
--- a/src/providers/ldap/ldap_common.c
+++ b/src/providers/ldap/ldap_common.c
@@ -215,6 +215,44 @@ sdap_domain_remove(struct sdap_options *opts,
     DLIST_REMOVE(*(sdom->head), sdom);
 }
 
+static int sdap_extend_map_with_list(TALLOC_CTX *mem_ctx,
+                                     struct sdap_options *opts,
+                                     int extra_attr_index,
+                                     struct sdap_attr_map *src_map,
+                                     size_t num_entries,
+                                     struct sdap_attr_map **_map,
+                                     size_t *_new_size)
+{
+    const char *extra_attrs;
+    char **extra_attrs_list;
+    errno_t ret;
+
+    extra_attrs = dp_opt_get_string(opts->basic, extra_attr_index);
+    if (extra_attrs == NULL) {
+        *_map = src_map;
+        *_new_size = num_entries;
+        return EOK;
+    }
+
+    /* split server parm into a list */
+    ret = split_on_separator(mem_ctx, extra_attrs, ',', true, true,
+                             &extra_attrs_list, NULL);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_OP_FAILURE, "Failed to parse server list!\n");
+        return ret;
+    }
+
+    ret = sdap_extend_map(mem_ctx, src_map,
+                          num_entries, extra_attrs_list,
+                          _map, _new_size);
+    talloc_free(extra_attrs_list);
+    if (ret != EOK) {
+        return ret;
+    }
+
+    return EOK;
+}
+
 int ldap_get_options(TALLOC_CTX *memctx,
                      struct sss_domain_info *dom,
                      struct confdb_ctx *cdb,
@@ -449,6 +487,13 @@ int ldap_get_options(TALLOC_CTX *memctx,
         goto done;
     }
 
+    ret = sdap_extend_map_with_list(opts, opts, SDAP_USER_EXTRA_ATTRS,
+                                    opts->user_map, SDAP_OPTS_USER,
+                                    &opts->user_map, &opts->user_map_cnt);
+    if (ret != EOK) {
+        goto done;
+    }
+
     ret = sdap_get_map(opts, cdb, conf_path,
                        default_group_map,
                        SDAP_OPTS_GROUP,
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index 9dd682de277a4e92b883e06011751b93d32c3525..2d1ba5b5ac6c5b9d7306985ed56dc1d512a82b96 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -216,7 +216,8 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
     }
 
     /* TODO: handle attrs_type */
-    ret = build_attrs_from_map(state, ctx->opts->user_map, SDAP_OPTS_USER,
+    ret = build_attrs_from_map(state, ctx->opts->user_map,
+                               ctx->opts->user_map_cnt,
                                NULL, &state->attrs, NULL);
     if (ret != EOK) goto fail;
 
diff --git a/src/providers/ldap/ldap_opts.h b/src/providers/ldap/ldap_opts.h
index 5552c22cfed17a1cb07c8c6b77f1c501bc7273a3..3da5274746741c9ee3e975958555028d056729c9 100644
--- a/src/providers/ldap/ldap_opts.h
+++ b/src/providers/ldap/ldap_opts.h
@@ -43,6 +43,7 @@ struct dp_option default_basic_opts[] = {
     { "ldap_user_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "ldap_user_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING },
     { "ldap_user_search_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+    { "ldap_user_extra_attrs", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "ldap_group_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "ldap_group_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING },
     { "ldap_group_search_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING },
diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
index b303547a4524f5dc90eaf16dc6ca0e579a8240ae..37a187436a6e17e9e41f981970b9c5ab5e685f46 100644
--- a/src/providers/ldap/sdap.c
+++ b/src/providers/ldap/sdap.c
@@ -71,6 +71,122 @@ int sdap_copy_map(TALLOC_CTX *memctx,
     return EOK;
 }
 
+static errno_t split_extra_attr(TALLOC_CTX *mem_ctx,
+                                char *conf_attr,
+                                char **_sysdb_attr,
+                                char **_ldap_attr)
+{
+    char *ldap_attr;
+    char *sysdb_attr;
+    char *sep;
+
+    ldap_attr = conf_attr;
+
+    sep = strchr(conf_attr, ':');
+    if (sep == NULL) {
+        sysdb_attr = talloc_strdup(mem_ctx, conf_attr);
+        ldap_attr = talloc_strdup(mem_ctx, conf_attr);
+    } else {
+        if (sep == conf_attr || *(sep + 1) == '\0') {
+            return ERR_INVALID_EXTRA_ATTR;
+        }
+
+        sysdb_attr = talloc_strndup(mem_ctx, ldap_attr,
+                                    sep - ldap_attr);
+        ldap_attr = talloc_strdup(mem_ctx, sep+1);
+    }
+
+    if (sysdb_attr == NULL || ldap_attr == NULL) {
+        return ENOMEM;
+    }
+
+    *_sysdb_attr = sysdb_attr;
+    *_ldap_attr = ldap_attr;
+    return EOK;
+}
+
+static bool is_sysdb_duplicate(struct sdap_attr_map *map,
+                               int num_entries,
+                               const char *sysdb_attr)
+{
+    int i;
+
+    for (i = 0; i < num_entries; i++) {
+        if (strcmp(map[i].sys_name, sysdb_attr) == 0) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+int sdap_extend_map(TALLOC_CTX *memctx,
+                    struct sdap_attr_map *src_map,
+                    size_t num_entries,
+                    char **extra_attrs,
+                    struct sdap_attr_map **_map,
+                    size_t *_new_size)
+{
+    struct sdap_attr_map *map;
+    size_t nextra = 0;
+    size_t i;
+    char *ldap_attr;
+    char *sysdb_attr;
+    errno_t ret;
+
+    if (extra_attrs == NULL) {
+        DEBUG(SSSDBG_FUNC_DATA, "No extra attributes\n");
+        *_map = src_map;
+        *_new_size = num_entries;
+        return EOK;
+    }
+
+    for (nextra = 0; extra_attrs[nextra]; nextra++) ;
+    DEBUG(SSSDBG_FUNC_DATA, "%zu extra attributes\n", nextra);
+
+    map = talloc_realloc(memctx, src_map, struct sdap_attr_map,
+                         num_entries + nextra + 1);
+    if (map == NULL) {
+        return ENOMEM;
+    }
+
+    for (i = 0; extra_attrs[i]; i++) {
+        ret = split_extra_attr(map, extra_attrs[i], &sysdb_attr, &ldap_attr);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_MINOR_FAILURE, "Cannot split %s\n", extra_attrs[i]);
+            continue;
+        }
+
+        if (is_sysdb_duplicate(map, num_entries, sysdb_attr)) {
+            DEBUG(SSSDBG_FATAL_FAILURE,
+                  "Attribute %s (%s in LDAP) is already used by SSSD, please "
+                  "choose a different cache name\n", sysdb_attr, ldap_attr);
+            return ERR_DUP_EXTRA_ATTR;
+        }
+
+        map[num_entries+i].name = ldap_attr;
+        map[num_entries+i].sys_name = sysdb_attr;
+        map[num_entries+i].opt_name = talloc_strdup(map,
+                                                map[num_entries+i].name);
+        map[num_entries+i].def_name = talloc_strdup(map,
+                                                map[num_entries+i].name);
+        if (map[num_entries+i].opt_name == NULL ||
+            map[num_entries+i].sys_name == NULL ||
+            map[num_entries+i].name == NULL ||
+            map[num_entries+i].def_name == NULL) {
+            return ENOMEM;
+        }
+        DEBUG(SSSDBG_TRACE_FUNC, "Extending map with %s\n", extra_attrs[i]);
+    }
+
+    /* Sentinel */
+    memset(&map[num_entries+nextra], 0, sizeof(struct sdap_attr_map));
+
+    *_map = map;
+    *_new_size = num_entries + nextra;
+    return EOK;
+}
+
 int sdap_get_map(TALLOC_CTX *memctx,
                  struct confdb_ctx *cdb,
                  const char *conf_path,
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index 460f400563b81a522e078d758a7dfc5b02ec5c96..7f8911744a8a9877ef2e48c66f36505c949349c5 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -159,6 +159,7 @@ enum sdap_basic_opt {
     SDAP_USER_SEARCH_BASE,
     SDAP_USER_SEARCH_SCOPE,
     SDAP_USER_SEARCH_FILTER,
+    SDAP_USER_EXTRA_ATTRS,
     SDAP_GROUP_SEARCH_BASE,
     SDAP_GROUP_SEARCH_SCOPE,
     SDAP_GROUP_SEARCH_FILTER,
@@ -412,6 +413,7 @@ struct sdap_options {
     struct dp_option *basic;
     struct sdap_attr_map *gen_map;
     struct sdap_attr_map *user_map;
+    size_t user_map_cnt;
     struct sdap_attr_map *group_map;
     struct sdap_attr_map *netgroup_map;
     struct sdap_attr_map *service_map;
@@ -467,6 +469,13 @@ int sdap_copy_map(TALLOC_CTX *memctx,
                  int num_entries,
                  struct sdap_attr_map **_map);
 
+int sdap_extend_map(TALLOC_CTX *memctx,
+                    struct sdap_attr_map *src_map,
+                    size_t num_entries,
+                    char **extra_attrs,
+                    struct sdap_attr_map **_map,
+                    size_t *_new_size);
+
 int sdap_get_map(TALLOC_CTX *memctx,
                  struct confdb_ctx *cdb,
                  const char *conf_path,
diff --git a/src/providers/ldap/sdap_async_enum.c b/src/providers/ldap/sdap_async_enum.c
index 73169052ebb4b9f5be6cf873618fbb8c28505757..16ba953bbf8d6f5755bc0689d0e6542526c0e1dd 100644
--- a/src/providers/ldap/sdap_async_enum.c
+++ b/src/providers/ldap/sdap_async_enum.c
@@ -617,7 +617,8 @@ static struct tevent_req *enum_users_send(TALLOC_CTX *memctx,
     }
 
     /* TODO: handle attrs_type */
-    ret = build_attrs_from_map(state, ctx->opts->user_map, SDAP_OPTS_USER,
+    ret = build_attrs_from_map(state, ctx->opts->user_map,
+                               ctx->opts->user_map_cnt,
                                NULL, &state->attrs, NULL);
     if (ret != EOK) goto fail;
 
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
index d40c1eaa198ff49106f149ffa2a016a695e7816a..2f568c472cc1eab10c69794cd12c10faf53ed8b1 100644
--- a/src/providers/ldap/sdap_async_groups.c
+++ b/src/providers/ldap/sdap_async_groups.c
@@ -1057,7 +1057,7 @@ struct tevent_req *sdap_process_group_send(TALLOC_CTX *memctx,
                             struct sdap_process_group_state);
     if (!req) return NULL;
 
-    ret = build_attrs_from_map(grp_state, opts->user_map, SDAP_OPTS_USER,
+    ret = build_attrs_from_map(grp_state, opts->user_map, opts->user_map_cnt,
                                NULL, &attrs, NULL);
     if (ret) {
         goto done;
@@ -1207,7 +1207,7 @@ sdap_process_missing_member_2307bis(struct tevent_req *req,
                                        grp_state->filter,
                                        grp_state->attrs,
                                        grp_state->opts->user_map,
-                                       SDAP_OPTS_USER,
+                                       grp_state->opts->user_map_cnt,
                                        dp_opt_get_int(grp_state->opts->basic,
                                                       SDAP_SEARCH_TIMEOUT),
                                        false);
@@ -1528,7 +1528,7 @@ next:
                                        state->filter,
                                        state->attrs,
                                        state->opts->user_map,
-                                       SDAP_OPTS_USER,
+                                       state->opts->user_map_cnt,
                                        dp_opt_get_int(state->opts->basic,
                                                       SDAP_SEARCH_TIMEOUT),
                                        false);
diff --git a/src/providers/ldap/sdap_async_groups_ad.c b/src/providers/ldap/sdap_async_groups_ad.c
index 9bb21d29bdde4bb9402d8b49f69b184969c94550..8db587c96d569fc691486b252ff8f2c7d96e29c2 100644
--- a/src/providers/ldap/sdap_async_groups_ad.c
+++ b/src/providers/ldap/sdap_async_groups_ad.c
@@ -72,7 +72,7 @@ sdap_get_ad_match_rule_members_send(TALLOC_CTX *mem_ctx,
     state->search_bases = opts->sdom->user_search_bases;
 
     /* Request all of the user attributes that we know about. */
-    ret = build_attrs_from_map(state, opts->user_map, SDAP_OPTS_USER,
+    ret = build_attrs_from_map(state, opts->user_map, opts->user_map_cnt,
                                NULL, &state->attrs, NULL);
     if (ret != EOK) {
         DEBUG(SSSDBG_MINOR_FAILURE,
@@ -157,7 +157,7 @@ sdap_get_ad_match_rule_members_next_base(struct tevent_req *req)
             state->search_bases[state->base_iter]->basedn,
             state->search_bases[state->base_iter]->scope,
             state->filter, state->attrs,
-            state->opts->user_map, SDAP_OPTS_USER,
+            state->opts->user_map, state->opts->user_map_cnt,
             state->timeout, true);
     if (!subreq) {
         return ENOMEM;
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index b1dd2f514e52ca6263a32ea8f85f30a5c7d81a9f..712811f83210bbde55760b13b959d7167e6e3e5c 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -2705,7 +2705,9 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
         return NULL;
     }
 
-    ret = build_attrs_from_map(state, state->opts->user_map, SDAP_OPTS_USER,
+    ret = build_attrs_from_map(state,
+                               state->opts->user_map,
+                               state->opts->user_map_cnt,
                                NULL, &state->user_attrs, NULL);
     if (ret) {
         talloc_zfree(req);
@@ -2753,7 +2755,7 @@ static errno_t sdap_get_initgr_next_base(struct tevent_req *req)
             state->user_search_bases[state->user_base_iter]->basedn,
             state->user_search_bases[state->user_base_iter]->scope,
             state->filter, state->user_attrs,
-            state->opts->user_map, SDAP_OPTS_USER,
+            state->opts->user_map, state->opts->user_map_cnt,
             state->timeout,
             false);
     if (!subreq) {
diff --git a/src/providers/ldap/sdap_async_nested_groups.c b/src/providers/ldap/sdap_async_nested_groups.c
index 8095eb6d5b517dbafd64dd5c93a92ad652bbabc0..3dc2a9fd3c3759be0958b55de78284634bf3e8c0 100644
--- a/src/providers/ldap/sdap_async_nested_groups.c
+++ b/src/providers/ldap/sdap_async_nested_groups.c
@@ -1586,7 +1586,8 @@ sdap_nested_group_lookup_user_send(TALLOC_CTX *mem_ctx,
     /* search */
     subreq = sdap_get_generic_send(state, ev, group_ctx->opts, group_ctx->sh,
                                    member->dn, LDAP_SCOPE_BASE, filter, attrs,
-                                   group_ctx->opts->user_map, SDAP_OPTS_USER,
+                                   group_ctx->opts->user_map,
+                                   group_ctx->opts->user_map_cnt,
                                    dp_opt_get_int(group_ctx->opts->basic,
                                                   SDAP_SEARCH_TIMEOUT),
                                    false);
@@ -2028,7 +2029,7 @@ sdap_nested_group_deref_send(TALLOC_CTX *mem_ctx,
     }
 
     maps[0].map = opts->user_map;
-    maps[0].num_attrs = SDAP_OPTS_USER;
+    maps[0].num_attrs = opts->user_map_cnt;
     maps[1].map = opts->group_map;
     maps[1].num_attrs = SDAP_OPTS_GROUP;
 
diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c
index ea9e858d9722c89fd0041968aacebeac423ad5df..1ef082ed0873a9685c462da8757cc3622873b373 100644
--- a/src/providers/ldap/sdap_async_users.c
+++ b/src/providers/ldap/sdap_async_users.c
@@ -431,7 +431,7 @@ int sdap_save_user(TALLOC_CTX *memctx,
         }
     }
 
-    for (i = SDAP_FIRST_EXTRA_USER_AT; i < SDAP_OPTS_USER; i++) {
+    for (i = SDAP_FIRST_EXTRA_USER_AT; i < opts->user_map_cnt; i++) {
         ret = sdap_attrs_add_list(attrs, opts->user_map[i].sys_name,
                                   NULL, user_name, user_attrs);
         if (ret) {
@@ -459,7 +459,7 @@ int sdap_save_user(TALLOC_CTX *memctx,
     /* Make sure that any attributes we requested from LDAP that we
      * did not receive are also removed from the sysdb
      */
-    ret = list_missing_attrs(user_attrs, opts->user_map, SDAP_OPTS_USER,
+    ret = list_missing_attrs(user_attrs, opts->user_map, opts->user_map_cnt,
                              attrs, &missing);
     if (ret != EOK) {
         goto done;
@@ -679,7 +679,7 @@ static errno_t sdap_search_user_next_base(struct tevent_req *req)
             state->search_bases[state->base_iter]->basedn,
             state->search_bases[state->base_iter]->scope,
             state->filter, state->attrs,
-            state->opts->user_map, SDAP_OPTS_USER,
+            state->opts->user_map, state->opts->user_map_cnt,
             state->timeout,
             state->enumeration); /* If we're enumerating, we need paging */
     if (subreq == NULL) {
diff --git a/src/util/util_errors.c b/src/util/util_errors.c
index 8dd4380b423ef75cd246933ec739e232094e9b37..d27d20b0a511cfd9090707c62064c7d11ebc68cc 100644
--- a/src/util/util_errors.c
+++ b/src/util/util_errors.c
@@ -54,6 +54,8 @@ struct err_string error_to_str[] = {
     { "Missing configuration file" }, /* ERR_MISSING_CONF */
     { "Malformed search filter" }, /* ERR_INVALID_FILTER, */
     { "No POSIX attributes detected" }, /* ERR_NO_POSIX */
+    { "Extra attribute is a duplicate" }, /* ERR_DUP_EXTRA_ATTR */
+    { "Malformed extra attribute" }, /* ERR_INVALID_EXTRA_ATTR */
 };
 
 
diff --git a/src/util/util_errors.h b/src/util/util_errors.h
index 23048990da1e101397ae6bc9d5957133c1ea65af..f03fc16b1444d7e1370c22044b248585f076f32a 100644
--- a/src/util/util_errors.h
+++ b/src/util/util_errors.h
@@ -76,6 +76,8 @@ enum sssd_errors {
     ERR_MISSING_CONF,
     ERR_INVALID_FILTER,
     ERR_NO_POSIX,
+    ERR_DUP_EXTRA_ATTR,
+    ERR_INVALID_EXTRA_ATTR,
     ERR_LAST            /* ALWAYS LAST */
 };
 
-- 
1.9.0

-------------- next part --------------
>From 56d2d89c9a7ecf12729019bc44d50723eb3bf1e4 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Mon, 12 Aug 2013 15:06:18 +0000
Subject: [PATCH 3/4] Make LDAP extra attributes available to IPA and AD
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

https://fedorahosted.org/sssd/ticket/2073

Reviewed-by: Simo Sorce <simo at redhat.com>
Reviewed-by: Pavel Březina <pbrezina at redhat.com>
---
 src/config/etc/sssd.api.d/sssd-ad.conf  |  1 +
 src/config/etc/sssd.api.d/sssd-ipa.conf |  1 +
 src/providers/ad/ad_common.c            | 11 +++++-----
 src/providers/ipa/ipa_common.c          | 11 +++++-----
 src/providers/ldap/ldap_common.c        | 38 --------------------------------
 src/providers/ldap/sdap.c               | 39 +++++++++++++++++++++++++++++++++
 src/providers/ldap/sdap.h               |  8 +++++++
 7 files changed, 61 insertions(+), 48 deletions(-)

diff --git a/src/config/etc/sssd.api.d/sssd-ad.conf b/src/config/etc/sssd.api.d/sssd-ad.conf
index 303ed840ddb52c5a60c9df80931e3fe6cf852388..5d526326879aae868b1b178e6e339ee2fd4fe96a 100644
--- a/src/config/etc/sssd.api.d/sssd-ad.conf
+++ b/src/config/etc/sssd.api.d/sssd-ad.conf
@@ -54,6 +54,7 @@ ldap_id_mapping = bool, None, false
 ldap_user_search_base = str, None, false
 ldap_user_search_scope = str, None, false
 ldap_user_search_filter = str, None, false
+ldap_user_extra_attrs = str, None, false
 ldap_user_object_class = str, None, false
 ldap_user_name = str, None, false
 ldap_user_uid_number = str, None, false
diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf
index f57bfea5002eac30d93e5430855aea6f94a2292a..c1cedf088d9b1795956af67fe9410e7bb2f27413 100644
--- a/src/config/etc/sssd.api.d/sssd-ipa.conf
+++ b/src/config/etc/sssd.api.d/sssd-ipa.conf
@@ -61,6 +61,7 @@ ldap_id_mapping = bool, None, false
 ldap_user_search_base = str, None, false
 ldap_user_search_scope = str, None, false
 ldap_user_search_filter = str, None, false
+ldap_user_extra_attrs = str, None, false
 ldap_user_object_class = str, None, false
 ldap_user_name = str, None, false
 ldap_user_uid_number = str, None, false
diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c
index af738bc82ba016759dd9a951a4b7b1832b61489d..8523fe5b49a7434c20c4730aae92eebb62b92397 100644
--- a/src/providers/ad/ad_common.c
+++ b/src/providers/ad/ad_common.c
@@ -201,11 +201,12 @@ ad_create_sdap_options(TALLOC_CTX *mem_ctx,
         goto done;
     }
 
-    ret = sdap_extend_map(id_opts,
-                          id_opts->user_map,
-                          SDAP_OPTS_USER, NULL,
-                          &id_opts->user_map,
-                          &id_opts->user_map_cnt);
+    ret = sdap_extend_map_with_list(id_opts, id_opts,
+                                    SDAP_USER_EXTRA_ATTRS,
+                                    id_opts->user_map,
+                                    SDAP_OPTS_USER,
+                                    &id_opts->user_map,
+                                    &id_opts->user_map_cnt);
     if (ret != EOK) {
         goto done;
     }
diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c
index 19de10d8bb92a4b3d0c8353eae128f3b4709a7af..f594de27a65ab1ff702d0c593a57e89bfd469532 100644
--- a/src/providers/ipa/ipa_common.c
+++ b/src/providers/ipa/ipa_common.c
@@ -547,11 +547,12 @@ int ipa_get_id_options(struct ipa_options *ipa_opts,
         goto done;
     }
 
-    ret = sdap_extend_map(ipa_opts->id,
-                          ipa_opts->id->user_map,
-                          SDAP_OPTS_USER, NULL,
-                          &ipa_opts->id->user_map,
-                          &ipa_opts->id->user_map_cnt);
+    ret = sdap_extend_map_with_list(ipa_opts->id, ipa_opts->id,
+                                    SDAP_USER_EXTRA_ATTRS,
+                                    ipa_opts->id->user_map,
+                                    SDAP_OPTS_USER,
+                                    &ipa_opts->id->user_map,
+                                    &ipa_opts->id->user_map_cnt);
     if (ret != EOK) {
         goto done;
     }
diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c
index 49468bf4bb8a0d5cecda9b8eca886293583ef8a9..4bee960b5413e1f5be4dd68383456cc35b854370 100644
--- a/src/providers/ldap/ldap_common.c
+++ b/src/providers/ldap/ldap_common.c
@@ -215,44 +215,6 @@ sdap_domain_remove(struct sdap_options *opts,
     DLIST_REMOVE(*(sdom->head), sdom);
 }
 
-static int sdap_extend_map_with_list(TALLOC_CTX *mem_ctx,
-                                     struct sdap_options *opts,
-                                     int extra_attr_index,
-                                     struct sdap_attr_map *src_map,
-                                     size_t num_entries,
-                                     struct sdap_attr_map **_map,
-                                     size_t *_new_size)
-{
-    const char *extra_attrs;
-    char **extra_attrs_list;
-    errno_t ret;
-
-    extra_attrs = dp_opt_get_string(opts->basic, extra_attr_index);
-    if (extra_attrs == NULL) {
-        *_map = src_map;
-        *_new_size = num_entries;
-        return EOK;
-    }
-
-    /* split server parm into a list */
-    ret = split_on_separator(mem_ctx, extra_attrs, ',', true, true,
-                             &extra_attrs_list, NULL);
-    if (ret != EOK) {
-        DEBUG(SSSDBG_OP_FAILURE, "Failed to parse server list!\n");
-        return ret;
-    }
-
-    ret = sdap_extend_map(mem_ctx, src_map,
-                          num_entries, extra_attrs_list,
-                          _map, _new_size);
-    talloc_free(extra_attrs_list);
-    if (ret != EOK) {
-        return ret;
-    }
-
-    return EOK;
-}
-
 int ldap_get_options(TALLOC_CTX *memctx,
                      struct sss_domain_info *dom,
                      struct confdb_ctx *cdb,
diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
index 37a187436a6e17e9e41f981970b9c5ab5e685f46..e8d23c9dc5eac34fc5182305dc4be9180f8be176 100644
--- a/src/providers/ldap/sdap.c
+++ b/src/providers/ldap/sdap.c
@@ -187,6 +187,45 @@ int sdap_extend_map(TALLOC_CTX *memctx,
     return EOK;
 }
 
+int sdap_extend_map_with_list(TALLOC_CTX *mem_ctx,
+                              struct sdap_options *opts,
+                              int extra_attr_index,
+                              struct sdap_attr_map *src_map,
+                              size_t num_entries,
+                              struct sdap_attr_map **_map,
+                              size_t *_new_size)
+{
+    const char *extra_attrs;
+    char **extra_attrs_list;
+    errno_t ret;
+
+    extra_attrs = dp_opt_get_string(opts->basic, extra_attr_index);
+    if (extra_attrs == NULL) {
+        *_map = src_map;
+        *_new_size = num_entries;
+        return EOK;
+    }
+
+    /* split server parm into a list */
+    ret = split_on_separator(mem_ctx, extra_attrs, ',', true, true,
+                             &extra_attrs_list, NULL);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_OP_FAILURE, ("Failed to parse server list!\n"));
+        return ret;
+    }
+
+
+    ret = sdap_extend_map(mem_ctx, src_map,
+                          num_entries, extra_attrs_list,
+                          _map, _new_size);
+    talloc_free(extra_attrs_list);
+    if (ret != EOK) {
+        return ret;
+    }
+
+    return EOK;
+}
+
 int sdap_get_map(TALLOC_CTX *memctx,
                  struct confdb_ctx *cdb,
                  const char *conf_path,
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index 7f8911744a8a9877ef2e48c66f36505c949349c5..178aecce1bf8b51dc8f1931aa07d989b8f31f11d 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -476,6 +476,14 @@ int sdap_extend_map(TALLOC_CTX *memctx,
                     struct sdap_attr_map **_map,
                     size_t *_new_size);
 
+int sdap_extend_map_with_list(TALLOC_CTX *mem_ctx,
+                              struct sdap_options *opts,
+                              int extra_attr_index,
+                              struct sdap_attr_map *src_map,
+                              size_t num_entries,
+                              struct sdap_attr_map **_map,
+                              size_t *_new_size);
+
 int sdap_get_map(TALLOC_CTX *memctx,
                  struct confdb_ctx *cdb,
                  const char *conf_path,
-- 
1.9.0

-------------- next part --------------
>From f0badde4f80fca1b17d3a3c760aae9866a99e988 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Tue, 20 May 2014 17:04:51 +0200
Subject: [PATCH 4/4] AD: Initialize user_map_cnt in server mode

user_map_cnt was initialized when all the traditional back ends are
initialized. However, for the server mode, we simply copy the defaults
and the count was left zeroed, which led to crashes.

Down the road, we should consider tying the map and the attribute count
together (see ticket #2336)

Reviewed-by: Pavel Reichl <preichl at redhat.com>
(cherry picked from commit 35d420c5d4609b6e999920e38a9b2ec40a0e1ac4)
---
 src/providers/ad/ad_common.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c
index 8523fe5b49a7434c20c4730aae92eebb62b92397..4bc07e0b6d5aa69b23dad46fc6c0d85a05c26604 100644
--- a/src/providers/ad/ad_common.c
+++ b/src/providers/ad/ad_common.c
@@ -71,6 +71,7 @@ ad_create_default_sdap_options(TALLOC_CTX *mem_ctx)
     if (ret != EOK) {
         goto fail;
     }
+    id_opts->user_map_cnt = SDAP_OPTS_USER;
 
     /* Group map */
     ret = sdap_copy_map(id_opts,
-- 
1.9.0



More information about the sssd-devel mailing list