[SSSD] [PATCH] Allow using POSIX attributes for AD subdomain users

Jakub Hrozek jhrozek at redhat.com
Thu Sep 26 12:15:42 UTC 2013


Hi,

the attached patches implement ticket #2070 where subdomain users have
POSIX attributes and the SSSD honors them.

So far I only tested with AD provider, not with trust environment, but I
wanted to sent the patches for review anyway.

The patches mostly amend the search filters and bases which presumed
strictly ID mapping in AD domains before. I also implemented Sumit's
idea on how to handle the SFU attributes as a new map. I think it's the
right thing to do, because if SFU is configured on the server, then the
POSIX clients should honour it if ID mapping is off.

One question I have is whether we should explicitly document that the
POSIX attributes must be replicated in the man page?
-------------- next part --------------
>From c6ca4c3be7f96eb637700ef88836846e8a32152d Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Wed, 25 Sep 2013 18:33:11 +0200
Subject: [PATCH 1/5] LDAP: Require ID numbers when ID mapping is off

Related: https://fedorahosted.org/sssd/ticket/2070

When searching for users and groups without the use of ID mapping, make
sure the UIDs and GIDs are included in the search. This will make the
SSSD seemigly "miss" entries when searching in Global Catalog in the
scenario where the POSIX attributes are not replicated to the GC.
---
 src/providers/ldap/ldap_id.c               | 25 +++++++++++--
 src/providers/ldap/sdap_async_initgroups.c | 59 ++++++++++++++++++++++++++++--
 2 files changed, 77 insertions(+), 7 deletions(-)

diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index 5fd05ebbd2c95d1e8362c916feee2f4f9dfd4ffc..162d987b60d76af2e18b96b14b56a5dde3311b3b 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -169,9 +169,28 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
         goto fail;
     }
 
-    state->filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",
-                                    attr_name, clean_name,
-                                    ctx->opts->user_map[SDAP_OC_USER].name);
+    if (use_id_mapping || filter_type == BE_FILTER_SECID) {
+        /* When mapping IDs or looking for SIDs, we don't want to limit
+         * ourselves to users with a UID value. But there must be a SID to map
+         * from.
+         */
+        state->filter = talloc_asprintf(state,
+                                        "(&(%s=%s)(objectclass=%s)(%s=*)(%s=*))",
+                                        attr_name, clean_name,
+                                        ctx->opts->user_map[SDAP_OC_USER].name,
+                                        ctx->opts->user_map[SDAP_AT_USER_NAME].name,
+                                        ctx->opts->user_map[SDAP_AT_USER_OBJECTSID].name);
+    } else {
+        /* When not ID-mapping, make sure there is a non-NULL UID */
+        state->filter = talloc_asprintf(state,
+                                        "(&(%s=%s)(objectclass=%s)(%s=*)(&(%s=*)(!(%s=0))))",
+                                        attr_name, clean_name,
+                                        ctx->opts->user_map[SDAP_OC_USER].name,
+                                        ctx->opts->user_map[SDAP_AT_USER_NAME].name,
+                                        ctx->opts->user_map[SDAP_AT_USER_UID].name,
+                                        ctx->opts->user_map[SDAP_AT_USER_UID].name);
+    }
+
     talloc_zfree(clean_name);
     if (!state->filter) {
         DEBUG(2, ("Failed to build the base filter\n"));
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index a0df82ca54c89f1df0e301d4e0bae439c97f20f7..875bf7115648058333e5ff170b5621e51ec12dc9 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -1442,7 +1442,7 @@ struct sdap_initgr_rfc2307bis_state {
     struct sss_domain_info *dom;
     struct sdap_handle *sh;
     const char *name;
-    const char *base_filter;
+    char *base_filter;
     char *filter;
     const char **attrs;
     const char *orig_dn;
@@ -1493,6 +1493,7 @@ static struct tevent_req *sdap_initgr_rfc2307bis_send(
     struct sdap_initgr_rfc2307bis_state *state;
     const char **attr_filter;
     char *clean_orig_dn;
+    bool use_id_mapping;
 
     req = tevent_req_create(memctx, &state, struct sdap_initgr_rfc2307bis_state);
     if (!req) return NULL;
@@ -1540,8 +1541,11 @@ static struct tevent_req *sdap_initgr_rfc2307bis_send(
     ret = sss_filter_sanitize(state, orig_dn, &clean_orig_dn);
     if (ret != EOK) goto done;
 
+    use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(opts->idmap_ctx,
+                                                               dom->domain_id);
+
     state->base_filter =
-            talloc_asprintf(state, "(&(%s=%s)(objectclass=%s)(%s=*))",
+            talloc_asprintf(state, "(&(%s=%s)(objectclass=%s)(%s=*)",
                             opts->group_map[SDAP_AT_GROUP_MEMBER].name,
                             clean_orig_dn,
                             opts->group_map[SDAP_OC_GROUP].name,
@@ -1550,6 +1554,28 @@ static struct tevent_req *sdap_initgr_rfc2307bis_send(
         ret = ENOMEM;
         goto done;
     }
+
+    if (use_id_mapping) {
+        /* When mapping IDs or looking for SIDs, we don't want to limit
+         * ourselves to groups with a GID value. But there must be a SID to map
+         * from.
+         */
+        state->base_filter = talloc_asprintf_append(state->base_filter,
+                                        "(%s=*))",
+                                        opts->group_map[SDAP_AT_GROUP_OBJECTSID].name);
+    } else {
+        /* When not ID-mapping, make sure there is a non-NULL UID */
+        state->base_filter = talloc_asprintf_append(state->base_filter,
+                                        "(&(%s=*)(!(%s=0))))",
+                                        opts->group_map[SDAP_AT_GROUP_GID].name,
+                                        opts->group_map[SDAP_AT_GROUP_GID].name);
+    }
+    if (!state->base_filter) {
+        talloc_zfree(req);
+        return NULL;
+    }
+
+
     talloc_zfree(clean_orig_dn);
 
     ret = sdap_initgr_rfc2307bis_next_base(req);
@@ -2551,7 +2577,7 @@ struct sdap_get_initgr_state {
     const char *name;
     const char **grp_attrs;
     const char **user_attrs;
-    const char *user_base_filter;
+    char *user_base_filter;
     char *filter;
     int timeout;
 
@@ -2580,6 +2606,7 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
     struct sdap_get_initgr_state *state;
     int ret;
     char *clean_name;
+    bool use_id_mapping;
 
     DEBUG(9, ("Retrieving info for initgroups call\n"));
 
@@ -2606,6 +2633,10 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
         goto done;
     }
 
+    use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(
+                                                          id_ctx->opts->idmap_ctx,
+                                                          sdom->dom->domain_id);
+
     ret = sss_filter_sanitize(state, name, &clean_name);
     if (ret != EOK) {
         talloc_zfree(req);
@@ -2613,7 +2644,7 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
     }
 
     state->user_base_filter =
-            talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",
+            talloc_asprintf(state, "(&(%s=%s)(objectclass=%s)",
                             state->opts->user_map[SDAP_AT_USER_NAME].name,
                             clean_name,
                             state->opts->user_map[SDAP_OC_USER].name);
@@ -2622,6 +2653,26 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
         return NULL;
     }
 
+    if (use_id_mapping) {
+        /* When mapping IDs or looking for SIDs, we don't want to limit
+         * ourselves to users with a UID value. But there must be a SID to map
+         * from.
+         */
+        state->user_base_filter = talloc_asprintf_append(state->user_base_filter,
+                                        "(%s=*))",
+                                        id_ctx->opts->user_map[SDAP_AT_USER_OBJECTSID].name);
+    } else {
+        /* When not ID-mapping, make sure there is a non-NULL UID */
+        state->user_base_filter = talloc_asprintf_append(state->user_base_filter,
+                                        "(&(%s=*)(!(%s=0))))",
+                                        id_ctx->opts->user_map[SDAP_AT_USER_UID].name,
+                                        id_ctx->opts->user_map[SDAP_AT_USER_UID].name);
+    }
+    if (!state->user_base_filter) {
+        talloc_zfree(req);
+        return NULL;
+    }
+
     ret = build_attrs_from_map(state, state->opts->user_map, SDAP_OPTS_USER,
                                NULL, &state->user_attrs, NULL);
     if (ret) {
-- 
1.8.3.1

-------------- next part --------------
>From 6de7291ae18b1094dddee82bb5ac25e8aa9a9098 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Thu, 26 Sep 2013 13:37:30 +0200
Subject: [PATCH 2/5] LDAP: Allow searching subdomain during RFC2307bis
 initgroups

Related: https://fedorahosted.org/sssd/ticket/2070

Until now, the POSIX-compliant initgroups would only be able to search
the parent domain. Since we want to allow using POSIX attributes from AD
subdomains as well, we should allow searching a custom sdap_domain.
---
 src/providers/ldap/sdap_async_initgroups.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index 875bf7115648058333e5ff170b5621e51ec12dc9..b38bb61a9cbe30136200df7989c63ecd200dcf92 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -1482,8 +1482,7 @@ static struct tevent_req *sdap_initgr_rfc2307bis_send(
         TALLOC_CTX *memctx,
         struct tevent_context *ev,
         struct sdap_options *opts,
-        struct sysdb_ctx *sysdb,
-        struct sss_domain_info *dom,
+        struct sdap_domain *sdom,
         struct sdap_handle *sh,
         const char *name,
         const char *orig_dn)
@@ -1500,8 +1499,8 @@ static struct tevent_req *sdap_initgr_rfc2307bis_send(
 
     state->ev = ev;
     state->opts = opts;
-    state->sysdb = sysdb;
-    state->dom = dom;
+    state->sysdb = sdom->dom->sysdb;
+    state->dom = sdom->dom;
     state->sh = sh;
     state->op = NULL;
     state->name = name;
@@ -1509,7 +1508,7 @@ static struct tevent_req *sdap_initgr_rfc2307bis_send(
     state->num_direct_parents = 0;
     state->timeout = dp_opt_get_int(state->opts->basic, SDAP_SEARCH_TIMEOUT);
     state->base_iter = 0;
-    state->search_bases = opts->sdom->group_search_bases;
+    state->search_bases = sdom->group_search_bases;
     state->orig_dn = orig_dn;
 
     if (!state->search_bases) {
@@ -1541,8 +1540,9 @@ static struct tevent_req *sdap_initgr_rfc2307bis_send(
     ret = sss_filter_sanitize(state, orig_dn, &clean_orig_dn);
     if (ret != EOK) goto done;
 
-    use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(opts->idmap_ctx,
-                                                               dom->domain_id);
+    use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(
+                                                        opts->idmap_ctx,
+                                                        sdom->dom->domain_id);
 
     state->base_filter =
             talloc_asprintf(state, "(&(%s=%s)(objectclass=%s)(%s=*)",
@@ -2571,6 +2571,7 @@ struct sdap_get_initgr_state {
     struct sysdb_ctx *sysdb;
     struct sdap_options *opts;
     struct sss_domain_info *dom;
+    struct sdap_domain *sdom;
     struct sdap_handle *sh;
     struct sdap_id_ctx *id_ctx;
     struct sdap_id_conn_ctx *conn;
@@ -2617,6 +2618,7 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx,
     state->opts = id_ctx->opts;
     state->dom = sdom->dom;
     state->sysdb = sdom->dom->sysdb;
+    state->sdom = sdom;
     state->sh = sh;
     state->id_ctx = id_ctx;
     state->conn = conn;
@@ -2873,8 +2875,8 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
                                                             state->timeout);
         } else {
             subreq = sdap_initgr_rfc2307bis_send(
-                    state, state->ev, state->opts, state->sysdb,
-                    state->dom, state->sh,
+                    state, state->ev, state->opts,
+                    state->sdom, state->sh,
                     cname, orig_dn);
         }
         if (!subreq) {
-- 
1.8.3.1

-------------- next part --------------
>From 648da666ea909118fa8b7ad50e4d8886823029b2 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Tue, 24 Sep 2013 17:41:42 +0200
Subject: [PATCH 3/5] AD: talk to GC first even for local domain objects

Related: https://fedorahosted.org/sssd/ticket/2070

Since we are recommending to configure the POSIX attributes so that they
are replicated to the Global Catalog, we can start connecting to the GC
by default even for local users. If the object is not matches in the GC,
there is a possibility to fall back to LDAP.
---
 src/providers/ad/ad_id.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c
index 9ee639a75c386045d7e80d8a80b1237b1383417e..f09b9c6fe239b9b602f53e8afce641a4d07be6e9 100644
--- a/src/providers/ad/ad_id.c
+++ b/src/providers/ad/ad_id.c
@@ -178,7 +178,6 @@ get_conn_list(struct be_req *breq, struct ad_id_ctx *ad_ctx,
               struct sss_domain_info *dom, struct be_acct_req *ar)
 {
     struct sdap_id_conn_ctx **clist;
-    int i=0;
 
     /* LDAP, GC, sentinel */
     clist = talloc_zero_array(breq, struct sdap_id_conn_ctx *, 3);
@@ -190,12 +189,18 @@ get_conn_list(struct be_req *breq, struct ad_id_ctx *ad_ctx,
     case BE_REQ_USER_AND_GROUP: /* get SID */
     case BE_REQ_GROUP: /* group */
     case BE_REQ_INITGROUPS: /* init groups for user */
-        if (ad_ctx->gc_ctx && IS_SUBDOMAIN(dom)) {
-            clist[i] = ad_ctx->gc_ctx;
-            i++;
-        } else {
-            clist[i] = ad_ctx->ldap_ctx;
+        /* Always try GC first */
+        clist[0] = ad_ctx->gc_ctx;
+        if (IS_SUBDOMAIN(dom) == true) {
+            /* Subdomain users are only present in GC. */
+            break;
         }
+
+        /* With root domain users we have the option to
+         * fall back to LDAP in case ie POSIX attributes
+         * are used but not replicated to GC
+         */
+        clist[1] = ad_ctx->ldap_ctx;
         break;
 
     default:
-- 
1.8.3.1

-------------- next part --------------
>From 88f2e35b3ef9cbf0655093d80c297ada0da47e09 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Wed, 25 Sep 2013 23:05:48 +0200
Subject: [PATCH 4/5] AD: Add new option map ad_2008r2_sfu_user_map

Resolves: https://fedorahosted.org/sssd/ticket/2070

By default, the Active Directory SFU configures different attributes for
POSIX memberships that the ones used when ID mapping. This patch adds a
new map that is autoselected when the AD provider is configured not to
perform ID mapping.
---
 src/providers/ad/ad_common.c  | 12 ++++++++--
 src/providers/ad/ad_opts.h    | 52 +++++++++++++++++++++++++++++++++++++++++++
 src/tests/ad_ldap_opt-tests.c | 10 +++++++++
 3 files changed, 72 insertions(+), 2 deletions(-)

diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c
index 700ac033f42ac700b4e255a74350d774a3340358..1849549726fda3fa7eb62c752738d0a833f866b2 100644
--- a/src/providers/ad/ad_common.c
+++ b/src/providers/ad/ad_common.c
@@ -164,6 +164,7 @@ ad_create_sdap_options(TALLOC_CTX *mem_ctx,
 {
     struct sdap_options *id_opts;
     errno_t ret;
+    struct sdap_attr_map *user_map, *group_map;
 
     id_opts = talloc_zero(mem_ctx, struct sdap_options);
     if (!id_opts) {
@@ -180,6 +181,13 @@ ad_create_sdap_options(TALLOC_CTX *mem_ctx,
     }
 
     /* Get sdap option maps */
+    if (dp_opt_get_bool(id_opts->basic, SDAP_ID_MAPPING)) {
+        user_map = ad_2008r2_user_map;
+        group_map = ad_2008r2_group_map;
+    } else {
+        user_map = ad_2008r2_sfu_user_map;
+        group_map = ad_2008r2_sfu_group_map;
+    }
 
     /* General Attribute Map */
     ret = sdap_get_map(id_opts,
@@ -194,7 +202,7 @@ ad_create_sdap_options(TALLOC_CTX *mem_ctx,
     /* User map */
     ret = sdap_get_map(id_opts,
                        cdb, conf_path,
-                       ad_2008r2_user_map,
+                       user_map,
                        SDAP_OPTS_USER,
                        &id_opts->user_map);
     if (ret != EOK) {
@@ -204,7 +212,7 @@ ad_create_sdap_options(TALLOC_CTX *mem_ctx,
     /* Group map */
     ret = sdap_get_map(id_opts,
                        cdb, conf_path,
-                       ad_2008r2_group_map,
+                       group_map,
                        SDAP_OPTS_GROUP,
                        &id_opts->group_map);
     if (ret != EOK) {
diff --git a/src/providers/ad/ad_opts.h b/src/providers/ad/ad_opts.h
index f3b6cd61632601ec92a408a6a73cff6446fd48bf..f3c3c9cc3c3037fe2a41602893151b81a9664147 100644
--- a/src/providers/ad/ad_opts.h
+++ b/src/providers/ad/ad_opts.h
@@ -210,6 +210,58 @@ struct sdap_attr_map ad_2008r2_group_map[] = {
     SDAP_ATTR_MAP_TERMINATOR
 };
 
+struct sdap_attr_map ad_2008r2_sfu_user_map[] = {
+    { "ldap_user_object_class", "user", SYSDB_USER_CLASS, NULL },
+    { "ldap_user_name", "msSFU30Name", SYSDB_NAME, NULL },
+    { "ldap_user_pwd", "unixUserPassword", SYSDB_PWD, NULL },
+    { "ldap_user_uid_number", "uidNumber", SYSDB_UIDNUM, NULL },
+    { "ldap_user_gid_number", "gidNumber", SYSDB_GIDNUM, NULL },
+    { "ldap_user_gecos", "gecos", SYSDB_GECOS, NULL },
+    { "ldap_user_home_directory", "unixHomeDirectory", SYSDB_HOMEDIR, NULL },
+    { "ldap_user_shell", "loginShell", SYSDB_SHELL, NULL },
+    { "ldap_user_principal", "userPrincipalName", SYSDB_UPN, NULL },
+    { "ldap_user_fullname", "name", SYSDB_FULLNAME, NULL },
+    { "ldap_user_member_of", "msSFU30PosixMemberOf", SYSDB_MEMBEROF, NULL },
+    { "ldap_user_uuid", "objectGUID", SYSDB_UUID, NULL },
+    { "ldap_user_objectsid", "objectSID", SYSDB_SID, NULL },
+    { "ldap_user_primary_group", "primaryGroupID", SYSDB_PRIMARY_GROUP, NULL },
+    { "ldap_user_modify_timestamp", "whenChanged", SYSDB_ORIG_MODSTAMP, NULL },
+    { "ldap_user_entry_usn", SDAP_AD_USN, SYSDB_USN, NULL },
+    { "ldap_user_shadow_last_change", NULL, SYSDB_SHADOWPW_LASTCHANGE, NULL },
+    { "ldap_user_shadow_min", NULL, SYSDB_SHADOWPW_MIN, NULL },
+    { "ldap_user_shadow_max", NULL, SYSDB_SHADOWPW_MAX, NULL },
+    { "ldap_user_shadow_warning", NULL, SYSDB_SHADOWPW_WARNING, NULL },
+    { "ldap_user_shadow_inactive", NULL, SYSDB_SHADOWPW_INACTIVE, NULL },
+    { "ldap_user_shadow_expire", NULL, SYSDB_SHADOWPW_EXPIRE, NULL },
+    { "ldap_user_shadow_flag", NULL, SYSDB_SHADOWPW_FLAG, NULL },
+    { "ldap_user_krb_last_pwd_change", NULL, SYSDB_KRBPW_LASTCHANGE, NULL },
+    { "ldap_user_krb_password_expiration", NULL, SYSDB_KRBPW_EXPIRATION, NULL },
+    { "ldap_pwd_attribute", NULL, SYSDB_PWD_ATTRIBUTE, NULL },
+    { "ldap_user_authorized_service", NULL, SYSDB_AUTHORIZED_SERVICE, NULL },
+    { "ldap_user_ad_account_expires", "accountExpires", SYSDB_AD_ACCOUNT_EXPIRES, NULL},
+    { "ldap_user_ad_user_account_control", "userAccountControl", SYSDB_AD_USER_ACCOUNT_CONTROL, NULL},
+    { "ldap_ns_account_lock", NULL, SYSDB_NS_ACCOUNT_LOCK, NULL},
+    { "ldap_user_authorized_host", NULL, SYSDB_AUTHORIZED_HOST, NULL },
+    { "ldap_user_nds_login_disabled", NULL, SYSDB_NDS_LOGIN_DISABLED, NULL },
+    { "ldap_user_nds_login_expiration_time", NULL, SYSDB_NDS_LOGIN_EXPIRATION_TIME, NULL },
+    { "ldap_user_nds_login_allowed_time_map", NULL, SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL },
+    { "ldap_user_ssh_public_key", NULL, SYSDB_SSH_PUBKEY, NULL },
+    SDAP_ATTR_MAP_TERMINATOR
+};
+
+struct sdap_attr_map ad_2008r2_sfu_group_map[] = {
+    { "ldap_group_object_class", "group", SYSDB_GROUP_CLASS, NULL },
+    { "ldap_group_name", "msSFU30Name", SYSDB_NAME, NULL },
+    { "ldap_group_pwd", NULL, SYSDB_PWD, NULL },
+    { "ldap_group_gid_number", "gidNumber", SYSDB_GIDNUM, NULL },
+    { "ldap_group_member", "msSFU30PosixMember", SYSDB_MEMBER, NULL },
+    { "ldap_group_uuid", "objectGUID", SYSDB_UUID, NULL },
+    { "ldap_group_objectsid", "objectSID", SYSDB_SID, NULL },
+    { "ldap_group_modify_timestamp", "whenChanged", SYSDB_ORIG_MODSTAMP, NULL },
+    { "ldap_group_entry_usn", SDAP_AD_USN, SYSDB_USN, NULL },
+    SDAP_ATTR_MAP_TERMINATOR
+};
+
 struct sdap_attr_map ad_netgroup_map[] = {
     { "ldap_netgroup_object_class", "nisNetgroup", SYSDB_NETGROUP_CLASS, NULL },
     { "ldap_netgroup_name", "cn", SYSDB_NAME, NULL },
diff --git a/src/tests/ad_ldap_opt-tests.c b/src/tests/ad_ldap_opt-tests.c
index e9ce9d02bd10eb9c8abb8dd3f33b2853e699be22..61b9c549e7ddad24c1f9e58b447c46e55572db6a 100644
--- a/src/tests/ad_ldap_opt-tests.c
+++ b/src/tests/ad_ldap_opt-tests.c
@@ -63,11 +63,21 @@ START_TEST(test_compare_sdap_attrs)
                                  ad_2008r2_user_map);
     fail_unless(ret == EOK, "[%s]", strerror(ret));
 
+    /* User Attributes - SFU */
+    ret = compare_sdap_attr_maps(rfc2307_user_map, SDAP_OPTS_USER,
+                                 ad_2008r2_sfu_user_map);
+    fail_unless(ret == EOK, "[%s]", strerror(ret));
+
     /* Group Attributes */
     ret = compare_sdap_attr_maps(rfc2307_group_map, SDAP_OPTS_GROUP,
                                  ad_2008r2_group_map);
     fail_unless(ret == EOK, "[%s]", strerror(ret));
 
+    /* Group Attributes - SFU */
+    ret = compare_sdap_attr_maps(rfc2307_group_map, SDAP_OPTS_GROUP,
+                                 ad_2008r2_sfu_group_map);
+    fail_unless(ret == EOK, "[%s]", strerror(ret));
+
     /* Netgroup Attributes */
     ret = compare_sdap_attr_maps(netgroup_map, SDAP_OPTS_NETGROUP,
                                  ad_netgroup_map);
-- 
1.8.3.1

-------------- next part --------------
>From e88383846ee63339173878536072d1f82f85c3d3 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Thu, 26 Sep 2013 12:34:31 +0200
Subject: [PATCH 5/5] AD: Inherit MPG flag from parent domain

Resolves: https://fedorahosted.org/sssd/ticket/2070

When ID mapping is not configured in the parent domain, the sudomains
are perceived as using POSIX attributes as well and must not be set as
MPG domains.
---
 src/providers/ad/ad_subdomains.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
index b95f4e46ad7f20382cbc07470e41ff56790f0263..1644fb4788c0eb61734d90d6687175ab91fcb40b 100644
--- a/src/providers/ad/ad_subdomains.c
+++ b/src/providers/ad/ad_subdomains.c
@@ -25,6 +25,7 @@
 #include "providers/ldap/sdap_async.h"
 #include "providers/ad/ad_subdomains.h"
 #include "providers/ad/ad_domain_info.h"
+#include "providers/ldap/sdap_idmap.h"
 #include "util/util_sss_idmap.h"
 #include <ctype.h>
 #include <ndr.h>
@@ -108,6 +109,7 @@ ad_subdom_store(struct ad_subdomains_ctx *ctx,
     struct ldb_message_element *el;
     char *sid_str;
     uint32_t trust_type;
+    bool mpg;
 
     tmp_ctx = talloc_new(NULL);
     if (tmp_ctx == NULL) {
@@ -158,9 +160,13 @@ ad_subdom_store(struct ad_subdomains_ctx *ctx,
         goto done;
     }
 
+    mpg = sdap_idmap_domain_has_algorithmic_mapping(
+                                             ctx->sdap_id_ctx->opts->idmap_ctx,
+                                             domain->domain_id);
+
     /* AD subdomains are currently all mpg and do not enumerate */
     ret = sysdb_subdomain_store(domain->sysdb, name, realm, flat, sid_str,
-                                true, false);
+                                mpg, false);
     if (ret != EOK) {
         DEBUG(SSSDBG_OP_FAILURE, ("sysdb_subdomain_store failed.\n"));
         goto done;
-- 
1.8.3.1



More information about the sssd-devel mailing list