diff --git a/SOURCES/0148-IPA-AD-check-auth-ctx-before-using-it.patch b/SOURCES/0148-IPA-AD-check-auth-ctx-before-using-it.patch
new file mode 100644
index 0000000..d6ad243
--- /dev/null
+++ b/SOURCES/0148-IPA-AD-check-auth-ctx-before-using-it.patch
@@ -0,0 +1,92 @@
+From 1083c5f195ecf29435f24e136cf6470992614494 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Tue, 8 Nov 2016 11:51:57 +0100
+Subject: [PATCH 148/149] IPA/AD: check auth ctx before using it
+
+In e6b6b9fa79c67d7d2698bc7e33d2e2f6bb53d483 a feature was introduced to
+set the 'canonicalize' option in the system-wide Kerberos configuration
+according to the settings in SSSD if the AD or IPA provider were used.
+Unfortunately the patch implied that the auth provider is the same as
+the id provider which might not always be the case. A different auth
+provider caused a crash in the backend which is fixed by this patch.
+
+Resolves https://fedorahosted.org/sssd/ticket/3234
+
+Reviewed-by: Petr Cech <pcech@redhat.com>
+(cherry picked from commit ea11ed3ea6291488dd762033246edc4ce3951aeb)
+---
+ src/providers/ad/ad_subdomains.c   | 13 +++++++++++--
+ src/providers/ipa/ipa_subdomains.c | 20 +++++++++++++++++---
+ 2 files changed, 28 insertions(+), 5 deletions(-)
+
+diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
+index 52bf5361fa8de02c7165cbc3513a923ec018fc15..5e57d218c072a2627f165ae072cb761e1a146048 100644
+--- a/src/providers/ad/ad_subdomains.c
++++ b/src/providers/ad/ad_subdomains.c
+@@ -618,14 +618,23 @@ static errno_t ad_subdom_reinit(struct ad_subdomains_ctx *subdoms_ctx)
+ {
+     const char *path;
+     errno_t ret;
+-    bool canonicalize;
++    bool canonicalize = false;
+ 
+     path = dp_opt_get_string(subdoms_ctx->ad_id_ctx->ad_options->basic,
+                              AD_KRB5_CONFD_PATH);
+ 
+-    canonicalize = dp_opt_get_bool(
++    if (subdoms_ctx->ad_id_ctx->ad_options->auth_ctx != NULL
++            && subdoms_ctx->ad_id_ctx->ad_options->auth_ctx->opts != NULL) {
++        canonicalize = dp_opt_get_bool(
+                              subdoms_ctx->ad_id_ctx->ad_options->auth_ctx->opts,
+                              KRB5_CANONICALIZE);
++    } else {
++        DEBUG(SSSDBG_CONF_SETTINGS, "Auth provider data is not available, "
++                                    "most probably because the auth provider "
++                                    "is not 'ad'. Kerberos configuration "
++                                    "snippet to set the 'canonicalize' option "
++                                    "will not be created.\n");
++    }
+ 
+     ret = sss_write_krb5_conf_snippet(path, canonicalize);
+     if (ret != EOK) {
+diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
+index d02d2d5c05904c54c5e1997aece82f940b7334ee..eb1bc92691da9e82e07595ed84eea35fff78d1a5 100644
+--- a/src/providers/ipa/ipa_subdomains.c
++++ b/src/providers/ipa/ipa_subdomains.c
+@@ -73,16 +73,30 @@ static errno_t
+ ipa_subdom_reinit(struct ipa_subdomains_ctx *ctx)
+ {
+     errno_t ret;
++    bool canonicalize = false;
+ 
+     DEBUG(SSSDBG_TRACE_INTERNAL,
+           "Re-initializing domain %s\n", ctx->be_ctx->domain->name);
+ 
++    if (ctx->ipa_id_ctx->ipa_options->auth_ctx != NULL
++          && ctx->ipa_id_ctx->ipa_options->auth_ctx->krb5_auth_ctx != NULL
++          && ctx->ipa_id_ctx->ipa_options->auth_ctx->krb5_auth_ctx->opts != NULL
++       ) {
++        canonicalize = dp_opt_get_bool(
++                    ctx->ipa_id_ctx->ipa_options->auth_ctx->krb5_auth_ctx->opts,
++                    KRB5_CANONICALIZE);
++    } else {
++        DEBUG(SSSDBG_CONF_SETTINGS, "Auth provider data is not available, "
++                                    "most probably because the auth provider "
++                                    "is not 'ipa'. Kerberos configuration "
++                                    "snippet to set the 'canonicalize' option "
++                                    "will not be created.\n");
++    }
++
+     ret = sss_write_krb5_conf_snippet(
+                           dp_opt_get_string(ctx->ipa_id_ctx->ipa_options->basic,
+                                             IPA_KRB5_CONFD_PATH),
+-                          dp_opt_get_bool(
+-                    ctx->ipa_id_ctx->ipa_options->auth_ctx->krb5_auth_ctx->opts,
+-                    KRB5_CANONICALIZE));
++                          canonicalize);
+     if (ret != EOK) {
+         DEBUG(SSSDBG_MINOR_FAILURE, "sss_write_krb5_conf_snippet failed.\n");
+         /* Just continue */
+-- 
+2.7.4
+
diff --git a/SOURCES/0149-Qualify-ghost-user-attribute-in-case-ldap_group_nest.patch b/SOURCES/0149-Qualify-ghost-user-attribute-in-case-ldap_group_nest.patch
new file mode 100644
index 0000000..9809cf2
--- /dev/null
+++ b/SOURCES/0149-Qualify-ghost-user-attribute-in-case-ldap_group_nest.patch
@@ -0,0 +1,60 @@
+From 362911a85e3aa244cdbdf75b8b4131bb26396d19 Mon Sep 17 00:00:00 2001
+From: Jakub Hrozek <jhrozek@redhat.com>
+Date: Wed, 9 Nov 2016 11:59:10 +0100
+Subject: [PATCH 149/149] Qualify ghost user attribute in case
+ ldap_group_nesting_level is set to 0
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When the sssd is set to not resolve nested groups with RFC2307bis, then
+the LDAP provider takes a different path. We didn't qualify the ghost
+users in this case.
+
+Resolves:
+https://fedorahosted.org/sssd/ticket/3236
+
+Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
+(cherry picked from commit 538a7f1dd8339b90e0cfc64e7919a34d1d5c10d3)
+---
+ src/providers/ldap/sdap_async_groups.c | 15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
+index 72760b75acae4cb6ce15c72f16dae8e859d89847..49a1934b2604e6a6af8ee8e8b3d1f88d2029658d 100644
+--- a/src/providers/ldap/sdap_async_groups.c
++++ b/src/providers/ldap/sdap_async_groups.c
+@@ -1659,7 +1659,7 @@ static void sdap_process_group_members(struct tevent_req *subreq)
+     struct sdap_process_group_state *state =
+                         tevent_req_data(req, struct sdap_process_group_state);
+     struct ldb_message_element *el;
+-    uint8_t* name_string;
++    char *name_string;
+ 
+     state->check_count--;
+     DEBUG(SSSDBG_TRACE_ALL, "Members remaining: %zu\n", state->check_count);
+@@ -1685,11 +1685,18 @@ static void sdap_process_group_members(struct tevent_req *subreq)
+         goto next;
+     }
+ 
+-    name_string = el[0].values[0].data;
++    name_string = sss_create_internal_fqname(state,
++                                            (const char *) el[0].values[0].data,
++                                            state->dom->name);
++    if (name_string == NULL) {
++        ret = ENOMEM;
++        goto next;
++    }
++
+     state->ghost_dns->values[state->ghost_dns->num_values].data =
+-            talloc_steal(state->ghost_dns->values, name_string);
++            talloc_steal(state->ghost_dns->values, (uint8_t *) name_string);
+     state->ghost_dns->values[state->ghost_dns->num_values].length =
+-            strlen((char *)name_string);
++            strlen(name_string);
+     state->ghost_dns->num_values++;
+ 
+ next:
+-- 
+2.7.4
+
diff --git a/SOURCES/0150-SYSDB-Split-sysdb_try_to_find_expected_dn-into-small.patch b/SOURCES/0150-SYSDB-Split-sysdb_try_to_find_expected_dn-into-small.patch
new file mode 100644
index 0000000..ee1e343
--- /dev/null
+++ b/SOURCES/0150-SYSDB-Split-sysdb_try_to_find_expected_dn-into-small.patch
@@ -0,0 +1,342 @@
+From 57a070724f42bb01b8bb3f866e906f40643e0421 Mon Sep 17 00:00:00 2001
+From: Jakub Hrozek <jhrozek@redhat.com>
+Date: Fri, 28 Oct 2016 13:46:02 +0200
+Subject: [PATCH 150/151] SYSDB: Split sysdb_try_to_find_expected_dn() into
+ smaller functions
+
+The function sysdb_try_to_find_expected_dn was performing several matching
+algorithms and thus it was getting big and hard to extend. This patch
+doesn't contain any functional changes, only shuffles the code around
+and splits the monolithic sysdb_try_to_find_expected_dn function into
+smaller blocks.
+
+Reviewed-by: Sumit Bose <sbose@redhat.com>
+(cherry picked from commit e5a984093ad7921c83da75272cede2b0e52ba2d6)
+---
+ src/db/sysdb_subdomains.c | 278 +++++++++++++++++++++++++++++-----------------
+ 1 file changed, 179 insertions(+), 99 deletions(-)
+
+diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
+index ff83f914f31d566e050c74a3ef5f5745f8c93add..b011bad6c988db952622e7ddaabf015ec24e54ba 100644
+--- a/src/db/sysdb_subdomains.c
++++ b/src/db/sysdb_subdomains.c
+@@ -1145,74 +1145,29 @@ done:
+     return ret;
+ }
+ 
+-errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
+-                                      const char *domain_component_name,
+-                                      struct sysdb_attrs **usr_attrs,
+-                                      size_t count,
+-                                      struct sysdb_attrs **exp_usr)
++static errno_t match_cn_users(TALLOC_CTX *tmp_ctx,
++                              struct sysdb_attrs **usr_attrs,
++                              size_t count,
++                              const char *dom_basedn,
++                              struct sysdb_attrs **_result)
+ {
+-    char *dom_basedn;
+-    size_t dom_basedn_len;
+-    char *expected_basedn;
+-    size_t expected_basedn_len;
++    errno_t ret;
++    const char *orig_dn;
+     size_t dn_len;
+-    const char *orig_dn;
+-    size_t c = 0;
+-    int ret;
+-    TALLOC_CTX *tmp_ctx;
+-    struct ldb_context *ldb_ctx;
+-    struct ldb_dn *ldb_dom_basedn;
+-    int dom_basedn_comp_num;
+-    struct ldb_dn *ldb_dn;
+-    int dn_comp_num;
+-    const char *component_name;
+     struct sysdb_attrs *result = NULL;
+     const char *result_dn_str = NULL;
++    char *cn_users_basedn;
++    size_t cn_users_basedn_len;
+ 
+-    if (dom == NULL || domain_component_name == NULL || usr_attrs == NULL
+-            || count == 0) {
+-        return EINVAL;
+-    }
+-
+-    tmp_ctx = talloc_new(NULL);
+-    if (tmp_ctx == NULL) {
+-        DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
+-        return ENOMEM;
+-    }
+-
+-    ret = domain_to_basedn(tmp_ctx, dom->name, &dom_basedn);
+-    if (ret != EOK) {
+-        DEBUG(SSSDBG_OP_FAILURE, "domain_to_basedn failed.\n");
+-        goto done;
+-    }
+-    expected_basedn = talloc_asprintf(tmp_ctx, "%s%s", "cn=users,", dom_basedn);
+-    if (expected_basedn == NULL) {
++    cn_users_basedn = talloc_asprintf(tmp_ctx, "%s%s", "cn=users,", dom_basedn);
++    if (cn_users_basedn == NULL) {
+         ret = ENOMEM;
+         goto done;
+     }
++    cn_users_basedn_len = strlen(cn_users_basedn);
++    DEBUG(SSSDBG_TRACE_ALL, "cn=users baseDN is [%s].\n", cn_users_basedn);
+ 
+-    ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb);
+-    if (ldb_ctx == NULL) {
+-        DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n");
+-        ret = EINVAL;
+-        goto done;
+-    }
+-
+-    ldb_dom_basedn = ldb_dn_new(tmp_ctx, ldb_ctx, dom_basedn);
+-    if (ldb_dom_basedn == NULL) {
+-        DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n");
+-        ret = ENOMEM;
+-        goto done;
+-    }
+-
+-    dom_basedn_comp_num = ldb_dn_get_comp_num(ldb_dom_basedn);
+-    dom_basedn_comp_num++;
+-
+-    DEBUG(SSSDBG_TRACE_ALL, "Expected BaseDN is [%s].\n", expected_basedn);
+-    expected_basedn_len = strlen(expected_basedn);
+-    dom_basedn_len = strlen(dom_basedn);
+-
+-    for (c = 0; c < count; c++) {
++    for (size_t c = 0; c < count; c++) {
+         ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn);
+         if (ret != EOK) {
+             DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
+@@ -1220,9 +1175,9 @@ errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
+         }
+         dn_len = strlen(orig_dn);
+ 
+-        if (dn_len > expected_basedn_len
+-                && strcasecmp(orig_dn + (dn_len - expected_basedn_len),
+-                              expected_basedn) == 0) {
++        if (dn_len > cn_users_basedn_len
++                && strcasecmp(orig_dn + (dn_len - cn_users_basedn_len),
++                              cn_users_basedn) == 0) {
+             DEBUG(SSSDBG_TRACE_ALL,
+                   "Found matching dn [%s].\n", orig_dn);
+             if (result != NULL) {
+@@ -1237,52 +1192,177 @@ errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
+         }
+     }
+ 
+-    if (result == NULL) {
+-        for (c = 0; c < count; c++) {
+-            ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn);
+-            if (ret != EOK) {
+-                DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
++    ret = EOK;
++done:
++    *_result = result;
++    return ret;
++}
++
++static errno_t match_non_dc_comp(TALLOC_CTX *tmp_ctx,
++                                 struct sss_domain_info *dom,
++                                 struct sysdb_attrs **usr_attrs,
++                                 size_t count,
++                                 struct ldb_dn *ldb_basedn,
++                                 const char *basedn,
++                                 const char *domain_component_name,
++                                 struct sysdb_attrs **_result)
++{
++    errno_t ret;
++    const char *orig_dn;
++    size_t orig_dn_len;
++    size_t basedn_len;
++    struct ldb_context *ldb_ctx;
++    struct ldb_dn *ldb_orig_dn;
++    int dn_comp_num;
++    int basedn_comp_num;
++    const char *component_name;
++    struct sysdb_attrs *result = NULL;
++    const char *result_dn_str = NULL;
++
++    ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb);
++    if (ldb_ctx == NULL) {
++        DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n");
++        ret = EINVAL;
++        goto done;
++    }
++
++    basedn_len = strlen(basedn);
++
++    basedn_comp_num = ldb_dn_get_comp_num(ldb_basedn);
++    basedn_comp_num++;
++
++    for (size_t c = 0; c < count; c++) {
++        ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn);
++        if (ret != EOK) {
++            DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
++            goto done;
++        }
++        orig_dn_len = strlen(orig_dn);
++
++        if (orig_dn_len > basedn_len
++                /* Does the user's original DN with the non-domain part
++                 * stripped match the domain base DN?
++                 */
++                && strcasecmp(orig_dn + (orig_dn_len - basedn_len),
++                              basedn) == 0) {
++            ldb_orig_dn = ldb_dn_new(tmp_ctx, ldb_ctx, orig_dn);
++            if (ldb_orig_dn == NULL) {
++                DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed");
++                ret = ENOMEM;
+                 goto done;
+             }
+-            dn_len = strlen(orig_dn);
+ 
+-            if (dn_len > dom_basedn_len
+-                    && strcasecmp(orig_dn + (dn_len - dom_basedn_len),
+-                                  dom_basedn) == 0) {
+-                ldb_dn = ldb_dn_new(tmp_ctx, ldb_ctx, orig_dn);
+-                if (ldb_dn == NULL) {
+-                    DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed");
+-                    ret = ENOMEM;
+-                    goto done;
+-                }
+-
+-                dn_comp_num = ldb_dn_get_comp_num(ldb_dn);
+-                if (dn_comp_num > dom_basedn_comp_num) {
+-                    component_name = ldb_dn_get_component_name(ldb_dn,
+-                                           (dn_comp_num - dom_basedn_comp_num));
+-                    DEBUG(SSSDBG_TRACE_ALL, "Comparing [%s] and [%s].\n",
+-                                            component_name,
+-                                            domain_component_name);
+-                    if (component_name != NULL
+-                            && strcasecmp(component_name,
+-                                          domain_component_name) != 0) {
+-                        DEBUG(SSSDBG_TRACE_ALL,
+-                              "Found matching dn [%s].\n", orig_dn);
+-                        if (result != NULL) {
+-                            DEBUG(SSSDBG_OP_FAILURE,
+-                                 "Found 2 matching DN [%s] and [%s], "
+-                                 "expecting only 1.\n", result_dn_str, orig_dn);
+-                            ret = EINVAL;
+-                            goto done;
+-                        }
+-                        result = usr_attrs[c];
+-                        result_dn_str = orig_dn;
++            dn_comp_num = ldb_dn_get_comp_num(ldb_orig_dn);
++            if (dn_comp_num > basedn_comp_num) {
++                component_name = ldb_dn_get_component_name(ldb_orig_dn,
++                        (dn_comp_num - basedn_comp_num));
++                DEBUG(SSSDBG_TRACE_ALL, "Comparing [%s] and [%s].\n",
++                      component_name,
++                      domain_component_name);
++                /* If the component is NOT a DC component, then the entry
++                 * must come from our domain, perhaps from a child container.
++                 * If it matched the DC component, the entry was from a child
++                 * subdomain different from this one.
++                 */
++                if (component_name != NULL
++                        && strcasecmp(component_name,
++                                      domain_component_name) != 0) {
++                    DEBUG(SSSDBG_TRACE_ALL,
++                            "Found matching dn [%s].\n", orig_dn);
++                    if (result != NULL) {
++                        DEBUG(SSSDBG_OP_FAILURE,
++                                "Found 2 matching DN [%s] and [%s], "
++                                "expecting only 1.\n", result_dn_str, orig_dn);
++                        ret = EINVAL;
++                        goto done;
+                     }
++                    result = usr_attrs[c];
++                    result_dn_str = orig_dn;
+                 }
+             }
+         }
+     }
+ 
++    ret = EOK;
++    *_result = result;
++done:
++    return ret;
++}
++
++static errno_t match_basedn(TALLOC_CTX *tmp_ctx,
++                            struct sss_domain_info *dom,
++                            struct sysdb_attrs **usr_attrs,
++                            size_t count,
++                            const char *dom_basedn,
++                            const char *domain_component_name,
++                            struct sysdb_attrs **_result)
++{
++    struct ldb_context *ldb_ctx;
++    struct ldb_dn *ldb_dom_basedn;
++
++    ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb);
++    if (ldb_ctx == NULL) {
++        DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n");
++        return EINVAL;
++    }
++
++
++    ldb_dom_basedn = ldb_dn_new(tmp_ctx, ldb_ctx, dom_basedn);
++    if (ldb_dom_basedn == NULL) {
++        DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n");
++        return ENOMEM;
++    }
++
++    return match_non_dc_comp(tmp_ctx, dom,
++                             usr_attrs, count,
++                             ldb_dom_basedn, dom_basedn,
++                             domain_component_name,
++                             _result);
++}
++
++errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
++                                      const char *domain_component_name,
++                                      struct sysdb_attrs **usr_attrs,
++                                      size_t count,
++                                      struct sysdb_attrs **exp_usr)
++{
++    char *dom_basedn;
++    int ret;
++    TALLOC_CTX *tmp_ctx;
++    struct sysdb_attrs *result = NULL;
++
++    if (dom == NULL || domain_component_name == NULL
++            || usr_attrs == NULL || count == 0) {
++        return EINVAL;
++    }
++
++    tmp_ctx = talloc_new(NULL);
++    if (tmp_ctx == NULL) {
++        DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
++        return ENOMEM;
++    }
++
++    ret = domain_to_basedn(tmp_ctx, dom->name, &dom_basedn);
++    if (ret != EOK) {
++        DEBUG(SSSDBG_OP_FAILURE, "domain_to_basedn failed.\n");
++        ret = EINVAL;
++        goto done;
++    }
++
++    ret = match_cn_users(tmp_ctx, usr_attrs, count, dom_basedn, &result);
++    if (ret != EOK) {
++        goto done;
++    }
++
++    if (result == NULL) {
++        ret = match_basedn(tmp_ctx, dom, usr_attrs,
++                           count, dom_basedn, domain_component_name,
++                           &result);
++        if (ret != EOK) {
++            goto done;
++        }
++    }
++
+     if (result == NULL) {
+         DEBUG(SSSDBG_OP_FAILURE, "No matching DN found.\n");
+         ret = ENOENT;
+-- 
+2.7.4
+
diff --git a/SOURCES/0151-SYSDB-Augment-sysdb_try_to_find_expected_dn-to-match.patch b/SOURCES/0151-SYSDB-Augment-sysdb_try_to_find_expected_dn-to-match.patch
new file mode 100644
index 0000000..d4e0758
--- /dev/null
+++ b/SOURCES/0151-SYSDB-Augment-sysdb_try_to_find_expected_dn-to-match.patch
@@ -0,0 +1,283 @@
+From a315e923a930e743de51c05183de383245f1c83e Mon Sep 17 00:00:00 2001
+From: Jakub Hrozek <jhrozek@redhat.com>
+Date: Mon, 31 Oct 2016 21:39:57 +0100
+Subject: [PATCH 151/151] SYSDB: Augment sysdb_try_to_find_expected_dn to match
+ search base as well
+
+In cases where the domain name in sssd.conf does not match the AD
+domain, our previous matching process wouldn't match. This patch
+augments the matching as follows:
+    - the search base is known to sysdb_try_to_find_expected_dn and is
+      expected to be non-NULL
+    - the existing matching is ran first
+    - during the search base, matching, all the non-DC components are
+      stripped from the search base to 'canonicalize' the search base
+    - if only a single entry that matches with a non-DC DN component
+      (matching with a DC component would mean the DN comes from a
+      different domain) then this entry is a match and is returned
+
+Resolves:
+https://fedorahosted.org/sssd/ticket/3199
+
+Reviewed-by: Sumit Bose <sbose@redhat.com>
+(cherry picked from commit 24d8c85fae253f988165c112af208198cf48eef6)
+---
+ src/db/sysdb.h                             |  1 +
+ src/db/sysdb_subdomains.c                  | 99 ++++++++++++++++++++++++++++++
+ src/providers/ldap/sdap_async_initgroups.c |  8 ++-
+ src/tests/cmocka/test_sysdb_subdomains.c   | 43 +++++++++++--
+ 4 files changed, 144 insertions(+), 7 deletions(-)
+
+diff --git a/src/db/sysdb.h b/src/db/sysdb.h
+index a0279fb249e1258c9cb73a4fcab55e4b242c61f3..6a1bbf089206970892590e85ae1f5c741a79f969 100644
+--- a/src/db/sysdb.h
++++ b/src/db/sysdb.h
+@@ -1296,6 +1296,7 @@ errno_t sysdb_handle_original_uuid(const char *orig_name,
+ 
+ errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
+                                       const char *domain_component_name,
++                                      const char *ldap_search_base,
+                                       struct sysdb_attrs **usr_attrs,
+                                       size_t count,
+                                       struct sysdb_attrs **exp_usr);
+diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
+index b011bad6c988db952622e7ddaabf015ec24e54ba..780140484f6f023bc6e8c12266e3b81ff016ec10 100644
+--- a/src/db/sysdb_subdomains.c
++++ b/src/db/sysdb_subdomains.c
+@@ -1320,8 +1320,97 @@ static errno_t match_basedn(TALLOC_CTX *tmp_ctx,
+                              _result);
+ }
+ 
++static errno_t match_search_base(TALLOC_CTX *tmp_ctx,
++                                 struct sss_domain_info *dom,
++                                 const char *domain_component_name,
++                                 const char *domain_search_base,
++                                 struct sysdb_attrs **usr_attrs,
++                                 size_t count,
++                                 struct sysdb_attrs **_result)
++{
++    errno_t ret;
++    bool ok;
++    const char *search_base;
++    struct ldb_context *ldb_ctx;
++    struct sysdb_attrs *result = NULL;
++    struct ldb_dn *ldb_search_base;
++    int search_base_comp_num;
++    int non_dc_comp_num;
++    const char *component_name;
++
++    ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb);
++    if (ldb_ctx == NULL) {
++        DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n");
++        ret = EINVAL;
++        goto done;
++    }
++
++    ldb_search_base = ldb_dn_new(tmp_ctx, ldb_ctx, domain_search_base);
++    if (ldb_search_base == NULL) {
++        DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n");
++        ret = ENOMEM;
++        goto done;
++    }
++
++    /* strip non-DC components from the search base */
++    search_base_comp_num = ldb_dn_get_comp_num(ldb_search_base);
++    for (non_dc_comp_num = 0;
++         non_dc_comp_num < search_base_comp_num;
++         non_dc_comp_num++) {
++
++        component_name = ldb_dn_get_component_name(ldb_search_base,
++                                                   non_dc_comp_num);
++        if (strcasecmp(domain_component_name, component_name) == 0) {
++            break;
++        }
++    }
++
++    if (non_dc_comp_num == search_base_comp_num) {
++        /* The search base does not have any non-DC components, the search wouldn't
++         * match anyway
++         */
++        ret = EOK;
++        *_result = NULL;
++        goto done;
++    }
++
++    ok = ldb_dn_remove_child_components(ldb_search_base, non_dc_comp_num);
++    if (!ok) {
++        ret = EINVAL;
++        goto done;
++    }
++
++    search_base = ldb_dn_get_linearized(ldb_search_base);
++    if (search_base == NULL) {
++        ret = ENOMEM;
++        goto done;
++    }
++
++    ret = match_cn_users(tmp_ctx, usr_attrs, count, search_base, &result);
++    if (ret != EOK) {
++        goto done;
++    }
++
++    if (result == NULL) {
++        ret = match_non_dc_comp(tmp_ctx, dom,
++                                usr_attrs, count,
++                                ldb_search_base, search_base,
++                                domain_component_name,
++                                &result);
++        if (ret != EOK) {
++            goto done;
++        }
++    }
++
++    ret = EOK;
++    *_result = result;
++done:
++    return ret;
++}
++
+ errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
+                                       const char *domain_component_name,
++                                      const char *domain_search_base,
+                                       struct sysdb_attrs **usr_attrs,
+                                       size_t count,
+                                       struct sysdb_attrs **exp_usr)
+@@ -1332,6 +1421,7 @@ errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
+     struct sysdb_attrs *result = NULL;
+ 
+     if (dom == NULL || domain_component_name == NULL
++            || domain_search_base == NULL
+             || usr_attrs == NULL || count == 0) {
+         return EINVAL;
+     }
+@@ -1364,6 +1454,15 @@ errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
+     }
+ 
+     if (result == NULL) {
++        ret = match_search_base(tmp_ctx, dom, domain_component_name,
++                                   domain_search_base, usr_attrs, count,
++                                   &result);
++        if (ret != EOK) {
++            goto done;
++        }
++    }
++
++    if (result == NULL) {
+         DEBUG(SSSDBG_OP_FAILURE, "No matching DN found.\n");
+         ret = ENOENT;
+         goto done;
+diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
+index 8eaba261c49082d086df9f19464ac0f40fae71fb..1173f4a875a1ea79990ff491ee7f2512f8435ac7 100644
+--- a/src/providers/ldap/sdap_async_initgroups.c
++++ b/src/providers/ldap/sdap_async_initgroups.c
+@@ -2947,7 +2947,13 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
+         DEBUG(SSSDBG_OP_FAILURE,
+               "Expected one user entry and got %zu\n", count);
+ 
+-        ret = sysdb_try_to_find_expected_dn(state->dom, "dc", usr_attrs, count,
++        /* When matching against a search base, it's sufficient to pick only
++         * the first search base because all bases in a single domain would
++         * have the same DC= components
++         */
++        ret = sysdb_try_to_find_expected_dn(state->dom, "dc",
++                                            state->sdom->search_bases[0]->basedn,
++                                            usr_attrs, count,
+                                             &state->orig_user);
+         if (ret != EOK) {
+             DEBUG(SSSDBG_OP_FAILURE,
+diff --git a/src/tests/cmocka/test_sysdb_subdomains.c b/src/tests/cmocka/test_sysdb_subdomains.c
+index c9db56841e841472c81d00a79f475dbbd975ccb0..52056e0435d2793893f1a4e336f38acf7a70b2c0 100644
+--- a/src/tests/cmocka/test_sysdb_subdomains.c
++++ b/src/tests/cmocka/test_sysdb_subdomains.c
+@@ -520,7 +520,9 @@ static void test_try_to_find_expected_dn(void **state)
+     int ret;
+     struct sysdb_attrs *result;
+     struct sysdb_attrs *usr_attrs[10] = { NULL };
++    struct sysdb_attrs *dom_usr_attrs[10] = { NULL };
+     struct sss_domain_info *dom;
++    char *dom_basedn;
+     struct subdom_test_ctx *test_ctx =
+         talloc_get_type(*state, struct subdom_test_ctx);
+ 
+@@ -528,6 +530,9 @@ static void test_try_to_find_expected_dn(void **state)
+                               "child2.test_sysdb_subdomains_2", true);
+     assert_non_null(dom);
+ 
++    ret = domain_to_basedn(test_ctx, dom->name, &dom_basedn);
++    assert_int_equal(ret, EOK);
++
+     usr_attrs[0] = sysdb_new_attrs(test_ctx);
+     assert_non_null(usr_attrs[0]);
+ 
+@@ -535,13 +540,13 @@ static void test_try_to_find_expected_dn(void **state)
+                   "uid=user,cn=abc,dc=c2,dc=child2,dc=test_sysdb_subdomains_2");
+     assert_int_equal(ret, EOK);
+ 
+-    ret = sysdb_try_to_find_expected_dn(NULL, NULL, NULL, 0, NULL);
++    ret = sysdb_try_to_find_expected_dn(NULL, NULL, NULL, NULL, 0, NULL);
+     assert_int_equal(ret, EINVAL);
+ 
+-    ret = sysdb_try_to_find_expected_dn(dom, "dc", usr_attrs, 1, &result);
++    ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, usr_attrs, 1, &result);
+     assert_int_equal(ret, ENOENT);
+ 
+-    ret = sysdb_try_to_find_expected_dn(dom, "xy", usr_attrs, 1, &result);
++    ret = sysdb_try_to_find_expected_dn(dom, "xy", dom_basedn, usr_attrs, 1, &result);
+     assert_int_equal(ret, EOK);
+     assert_ptr_equal(result, usr_attrs[0]);
+ 
+@@ -559,11 +564,11 @@ static void test_try_to_find_expected_dn(void **state)
+                  "uid=user2,cn=abc,dc=c2,dc=child2,dc=test_sysdb_subdomains_2");
+     assert_int_equal(ret, EOK);
+ 
+-    ret = sysdb_try_to_find_expected_dn(dom, "dc", usr_attrs, 3, &result);
++    ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, usr_attrs, 3, &result);
+     assert_int_equal(ret, EOK);
+     assert_ptr_equal(result, usr_attrs[1]);
+ 
+-    ret = sysdb_try_to_find_expected_dn(dom, "xy", usr_attrs, 3, &result);
++    ret = sysdb_try_to_find_expected_dn(dom, "xy", dom_basedn, usr_attrs, 3, &result);
+     assert_int_equal(ret, EINVAL);
+ 
+     /* Make sure cn=users match is preferred */
+@@ -575,10 +580,36 @@ static void test_try_to_find_expected_dn(void **state)
+                  "uid=user2,cn=abc,cn=users,dc=child2,dc=test_sysdb_subdomains_2");
+     assert_int_equal(ret, EOK);
+ 
+-    ret = sysdb_try_to_find_expected_dn(dom, "dc", usr_attrs, 3, &result);
++    ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, usr_attrs, 3, &result);
+     assert_int_equal(ret, EOK);
+     assert_ptr_equal(result, usr_attrs[2]);
+ 
++    /* test a case where the domain name does not match the basedn */
++    dom->name = discard_const("default");
++    dom_usr_attrs[0] = usr_attrs[0];
++
++    ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, dom_usr_attrs, 1, &result);
++    assert_int_equal(ret, ENOENT);
++
++    dom_usr_attrs[1] = usr_attrs[1];
++    dom_usr_attrs[2] = usr_attrs[2];
++
++    /* Make sure cn=users match is preferred */
++    ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, dom_usr_attrs, 3, &result);
++    assert_int_equal(ret, EOK);
++    assert_ptr_equal(result, dom_usr_attrs[2]);
++
++    talloc_free(usr_attrs[2]);
++    usr_attrs[2] = sysdb_new_attrs(test_ctx);
++    assert_non_null(usr_attrs[2]);
++    ret = sysdb_attrs_add_string(usr_attrs[2], SYSDB_ORIG_DN,
++                 "uid=user2,cn=abc,dc=c2,dc=child2,dc=test_sysdb_subdomains_2");
++    assert_int_equal(ret, EOK);
++
++    dom_usr_attrs[2] = usr_attrs[2];
++    ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, dom_usr_attrs, 3, &result);
++    assert_int_equal(ret, EOK);
++    assert_ptr_equal(result, usr_attrs[1]);
+ 
+     talloc_free(usr_attrs[0]);
+     talloc_free(usr_attrs[1]);
+-- 
+2.7.4
+
diff --git a/SOURCES/0152-SYSDB-Adding-lowercase-sudoUser-form.patch b/SOURCES/0152-SYSDB-Adding-lowercase-sudoUser-form.patch
new file mode 100644
index 0000000..504689e
--- /dev/null
+++ b/SOURCES/0152-SYSDB-Adding-lowercase-sudoUser-form.patch
@@ -0,0 +1,106 @@
+From 81ae14a34ad568b39b0077cc88112941802df27d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20=C4=8Cech?= <pcech@redhat.com>
+Date: Wed, 12 Oct 2016 16:48:38 +0200
+Subject: [PATCH 152/153] SYSDB: Adding lowercase sudoUser form
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If domain is not case sensitive we add lowercase form of usernames
+to sudoUser attributes. So we actually able to apply sudoRule on
+user Administrator@... with login admnistrator@...
+
+Resolves:
+https://fedorahosted.org/sssd/ticket/3203
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+(cherry picked from commit f4a1046bb88d7a0ab3617e49ae94bfa849d10645)
+---
+ src/db/sysdb_sudo.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 64 insertions(+)
+
+diff --git a/src/db/sysdb_sudo.c b/src/db/sysdb_sudo.c
+index 601fb63f236a7ed9eede130fd8cf4c3a1559fc4b..4bd93ffc60caa1ce48b72ee207899da0c4196d61 100644
+--- a/src/db/sysdb_sudo.c
++++ b/src/db/sysdb_sudo.c
+@@ -852,6 +852,65 @@ sysdb_sudo_add_sss_attrs(struct sysdb_attrs *rule,
+     return EOK;
+ }
+ 
++static errno_t sysdb_sudo_add_lowered_users(struct sss_domain_info *domain,
++                                            struct sysdb_attrs *rule)
++{
++    TALLOC_CTX *tmp_ctx;
++    const char **users = NULL;
++    const char *lowered = NULL;
++    errno_t ret;
++
++    if (domain->case_sensitive == true || rule == NULL) {
++        return EOK;
++    }
++
++    tmp_ctx = talloc_new(NULL);
++    if (tmp_ctx == NULL) {
++        return ENOMEM;
++    }
++
++    ret = sysdb_attrs_get_string_array(rule, SYSDB_SUDO_CACHE_AT_USER, tmp_ctx,
++                                       &users);
++    if (ret != EOK) {
++        DEBUG(SSSDBG_OP_FAILURE, "Unable to get %s attribute [%d]: %s\n",
++              SYSDB_SUDO_CACHE_AT_USER, ret, strerror(ret));
++        goto done;
++    }
++
++    if (users == NULL) {
++        ret =  EOK;
++        goto done;
++    }
++
++    for (int i = 0; users[i] != NULL; i++) {
++        lowered = sss_tc_utf8_str_tolower(tmp_ctx, users[i]);
++        if (lowered == NULL) {
++            DEBUG(SSSDBG_OP_FAILURE, "Cannot convert name to lowercase.\n");
++            ret = ENOMEM;
++            goto done;
++        }
++
++        if (strcmp(users[i], lowered) == 0) {
++            /* It protects us from adding duplicate. */
++            continue;
++        }
++
++        ret = sysdb_attrs_add_string(rule, SYSDB_SUDO_CACHE_AT_USER, lowered);
++        if (ret != EOK) {
++            DEBUG(SSSDBG_OP_FAILURE,
++                  "Unable to add %s attribute [%d]: %s\n",
++                  SYSDB_SUDO_CACHE_AT_USER, ret, strerror(ret));
++            goto done;
++        }
++    }
++
++    ret = EOK;
++
++done:
++    talloc_zfree(tmp_ctx);
++    return ret;
++}
++
+ static errno_t
+ sysdb_sudo_store_rule(struct sss_domain_info *domain,
+                       struct sysdb_attrs *rule,
+@@ -868,6 +927,11 @@ sysdb_sudo_store_rule(struct sss_domain_info *domain,
+ 
+     DEBUG(SSSDBG_TRACE_FUNC, "Adding sudo rule %s\n", name);
+ 
++    ret = sysdb_sudo_add_lowered_users(domain, rule);
++    if (ret != EOK) {
++        return ret;
++    }
++
+     ret = sysdb_sudo_add_sss_attrs(rule, name, cache_timeout, now);
+     if (ret != EOK) {
+         return ret;
+-- 
+2.7.4
+
diff --git a/SOURCES/0153-SYSDB-Fixing-of-sudorule-without-a-sudoUser.patch b/SOURCES/0153-SYSDB-Fixing-of-sudorule-without-a-sudoUser.patch
new file mode 100644
index 0000000..ea2bc3f
--- /dev/null
+++ b/SOURCES/0153-SYSDB-Fixing-of-sudorule-without-a-sudoUser.patch
@@ -0,0 +1,47 @@
+From aed255dd1ae6ec40ca15a53c38a13354dd5c88e8 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Petr=20=C4=8Cech?= <pcech@redhat.com>
+Date: Wed, 16 Nov 2016 10:09:18 +0100
+Subject: [PATCH 153/153] SYSDB: Fixing of sudorule without a sudoUser
+
+This patch solved a regression caused by the recent patches
+to lowercase sudoUser -- in case sudoUser is missing completely,
+we abort the processing of this rule and all others.
+
+With this patch, we return ERR_MALFORMED_ENTRY and gracefully
+skip the malformed rule instead.
+
+Resolves:
+https://fedorahosted.org/sssd/ticket/3241
+
+Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
+(cherry picked from commit 7e23edbaa7a6bbd0b461d5792535896b6a77928b)
+---
+ src/db/sysdb_sudo.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/src/db/sysdb_sudo.c b/src/db/sysdb_sudo.c
+index 4bd93ffc60caa1ce48b72ee207899da0c4196d61..f5160f19012028f92723b9012fad85d803aa5137 100644
+--- a/src/db/sysdb_sudo.c
++++ b/src/db/sysdb_sudo.c
+@@ -874,6 +874,7 @@ static errno_t sysdb_sudo_add_lowered_users(struct sss_domain_info *domain,
+     if (ret != EOK) {
+         DEBUG(SSSDBG_OP_FAILURE, "Unable to get %s attribute [%d]: %s\n",
+               SYSDB_SUDO_CACHE_AT_USER, ret, strerror(ret));
++        ret = ERR_MALFORMED_ENTRY;
+         goto done;
+     }
+ 
+@@ -977,6 +978,10 @@ sysdb_sudo_store(struct sss_domain_info *domain,
+             /* Multiple CNs are error on server side, we can just ignore this
+              * rule and save the others. Loud debug message is in logs. */
+             continue;
++        } else if (ret == ERR_MALFORMED_ENTRY) {
++            /* Attribute SYSDB_SUDO_CACHE_AT_USER is missing but we can
++             * continue with next sudoRule. */
++            continue;
+         } else if (ret != EOK) {
+             goto done;
+         }
+-- 
+2.7.4
+
diff --git a/SOURCES/0154-MONITOR-Do-not-set-up-watchdog-for-monitor.patch b/SOURCES/0154-MONITOR-Do-not-set-up-watchdog-for-monitor.patch
new file mode 100644
index 0000000..20ec5e1
--- /dev/null
+++ b/SOURCES/0154-MONITOR-Do-not-set-up-watchdog-for-monitor.patch
@@ -0,0 +1,73 @@
+From c7edf2dabc1cc3fc5298c872babf60a3001dfc2f Mon Sep 17 00:00:00 2001
+From: Jakub Hrozek <jhrozek@redhat.com>
+Date: Mon, 7 Nov 2016 11:58:20 +0100
+Subject: [PATCH 154/154] MONITOR: Do not set up watchdog for monitor
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+It makes little sense to set up watchdog for monitor because there is no
+entity that would restart the monitor. Therefore we should disable the
+watchdog for monitor process.
+
+Resolves:
+https://fedorahosted.org/sssd/ticket/3232
+
+Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
+(cherry picked from commit fbe6644aa28d93f492434950680c5618eb567712)
+---
+ src/monitor/monitor.c |  2 ++
+ src/util/server.c     | 11 +++++++----
+ src/util/util.h       |  1 +
+ 3 files changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
+index 89dd0a91d1fbd41dd853cf8745de732b7059d02b..0f01580e01b6a0a9ab507a54183e5813133be5a9 100644
+--- a/src/monitor/monitor.c
++++ b/src/monitor/monitor.c
+@@ -2880,6 +2880,8 @@ int main(int argc, const char *argv[])
+ 
+     /* we want a pid file check */
+     flags |= FLAGS_PID_FILE;
++    /* the monitor should not run a watchdog on itself */
++    flags |= FLAGS_NO_WATCHDOG;
+ 
+     /* Open before server_setup() does to have logging
+      * during configuration checking */
+diff --git a/src/util/server.c b/src/util/server.c
+index 953cd3d6171bf2fbcefd9b9138c679100d5153c3..013e572e6284b16534910088f7801219251896d8 100644
+--- a/src/util/server.c
++++ b/src/util/server.c
+@@ -666,10 +666,13 @@ int server_setup(const char *name, int flags,
+                                      ret, strerror(ret));
+         return ret;
+     }
+-    ret = setup_watchdog(ctx->event_ctx, watchdog_interval);
+-    if (ret != EOK) {
+-        DEBUG(SSSDBG_CRIT_FAILURE, "Watchdog setup failed.\n");
+-        return ret;
++
++    if ((flags & FLAGS_NO_WATCHDOG) == 0) {
++        ret = setup_watchdog(ctx->event_ctx, watchdog_interval);
++        if (ret != EOK) {
++            DEBUG(SSSDBG_CRIT_FAILURE, "Watchdog setup failed.\n");
++            return ret;
++        }
+     }
+ 
+     sss_log(SSS_LOG_INFO, "Starting up");
+diff --git a/src/util/util.h b/src/util/util.h
+index 4449315f8b1a79ec915bc340b46188c440a27fa3..0cbd88bd5bdb7741148dcc40aeb5ee2abaa4ff98 100644
+--- a/src/util/util.h
++++ b/src/util/util.h
+@@ -84,6 +84,7 @@
+ #define FLAGS_INTERACTIVE 0x0002
+ #define FLAGS_PID_FILE 0x0004
+ #define FLAGS_GEN_CONF 0x0008
++#define FLAGS_NO_WATCHDOG 0x0010
+ 
+ #define PIPE_INIT { -1, -1 }
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/0155-AUTOFS-Fix-offline-resolution-of-autofs-maps.patch b/SOURCES/0155-AUTOFS-Fix-offline-resolution-of-autofs-maps.patch
new file mode 100644
index 0000000..b8ccb04
--- /dev/null
+++ b/SOURCES/0155-AUTOFS-Fix-offline-resolution-of-autofs-maps.patch
@@ -0,0 +1,57 @@
+From 3f911325b21c53d3a932c48bc1bac328ec716268 Mon Sep 17 00:00:00 2001
+From: Jakub Hrozek <jhrozek@redhat.com>
+Date: Thu, 4 Aug 2016 17:58:32 +0200
+Subject: [PATCH 155/155] AUTOFS: Fix offline resolution of autofs maps
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If talking to the Data Provider failed, we never re-tried looking into
+the cache. We should consult the cache on DP failures and return cached
+results, if possible.
+
+Resolves:
+https://fedorahosted.org/sssd/ticket/3080
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+---
+ src/responder/autofs/autofssrv_cmd.c | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/src/responder/autofs/autofssrv_cmd.c b/src/responder/autofs/autofssrv_cmd.c
+index 9666ab2d195a581f18eaa7ff9bbc4c8167a71b15..f5aa25a483c3b3352f40e8cc66dfd3a24a60af0d 100644
+--- a/src/responder/autofs/autofssrv_cmd.c
++++ b/src/responder/autofs/autofssrv_cmd.c
+@@ -871,17 +871,25 @@ static void lookup_automntmap_cache_updated(uint16_t err_maj, uint32_t err_min,
+     if (err_maj) {
+         DEBUG(SSSDBG_CRIT_FAILURE,
+               "Unable to get information from Data Provider\n"
+-               "Error: %u, %u, %s\n"
+-               "Will try to return what we have in cache\n",
++              "Error: %u, %u, %s\n"
++              "Will try to return what we have in cache\n",
+                (unsigned int)err_maj, (unsigned int)err_min, err_msg);
+-        /* Loop to the next domain if possible */
++
++        /* Try to fall back to cache */
++        ret = lookup_automntmap_step(lookup_ctx);
++        if (ret == EOK) {
++            /* We have cached results to return */
++            autofs_setent_notify(lookup_ctx->map, ret);
++            return;
++        }
++
++        /* Otherwise try the next domain */
+         if (dctx->cmd_ctx->check_next
+                 && (dctx->domain = get_next_domain(dctx->domain, 0))) {
+             dctx->check_provider = NEED_CHECK_PROVIDER(dctx->domain->provider);
+         }
+     }
+ 
+-    /* ok the backend returned, search to see if we have updated results */
+     ret = lookup_automntmap_step(lookup_ctx);
+     if (ret != EOK) {
+         if (ret == EAGAIN) {
+-- 
+2.7.4
+
diff --git a/SOURCES/0156-Prevent-use-after-free-in-fd_input_available.patch b/SOURCES/0156-Prevent-use-after-free-in-fd_input_available.patch
new file mode 100644
index 0000000..ef0555c
--- /dev/null
+++ b/SOURCES/0156-Prevent-use-after-free-in-fd_input_available.patch
@@ -0,0 +1,71 @@
+From f8ecb57dcb7ce41b572cb67e6d2554296a54e738 Mon Sep 17 00:00:00 2001
+From: Carl Henrik Lunde <chlunde@ifi.uio.no>
+Date: Thu, 1 Dec 2016 00:09:00 +0100
+Subject: [PATCH 156/156] Prevent use after free in fd_input_available
+
+When both TEVENT_FD_WRITE and TEVENT_FD_READ are set, and an error/EOF
+occurs when reading from the socket, we will get a use after free
+in the second call ares_process_fd.  The first call will free the watch
+structure via a callback.
+
+Prevent this by calling ares_process_fd only once.
+
+Invalid read of size 4
+   at fd_input_available (async_resolv.c:147)
+   by epoll_event_loop (tevent_epoll.c:728)
+   by epoll_event_loop_once (tevent_epoll.c:926)
+   by std_event_loop_once (tevent_standard.c:114)
+   by _tevent_loop_once (tevent.c:533)
+   by tevent_common_loop_wait (tevent.c:637)
+   by std_event_loop_wait (tevent_standard.c:140)
+   by server_loop (server.c:702)
+   by main (data_provider_be.c:587)
+ Address ... is 112 bytes inside a block of size 136 free'd
+   at free (vg_replace_malloc.c:530)
+   by _talloc_free_internal (talloc.c:1116)
+   by _talloc_free (talloc.c:1647)
+   by ares__close_sockets (ares__close_sockets.c:50)
+   by handle_error (ares_process.c:679)
+   by read_tcp_data (ares_process.c:391)
+   by processfds (ares_process.c:138)
+   by fd_input_available (async_resolv.c:144)
+   by epoll_event_loop (tevent_epoll.c:728)
+   by epoll_event_loop_once (tevent_epoll.c:926)
+   by std_event_loop_once (tevent_standard.c:114)
+   by _tevent_loop_once (tevent.c:533)
+   by tevent_common_loop_wait (tevent.c:637)
+   by std_event_loop_wait (tevent_standard.c:140)
+   by server_loop (server.c:702)
+
+Resolves:
+https://fedorahosted.org/sssd/ticket/3250
+
+Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
+(cherry picked from commit 9676b464dd428557ff5a648e1351a3972440396f)
+---
+ src/resolv/async_resolv.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+diff --git a/src/resolv/async_resolv.c b/src/resolv/async_resolv.c
+index 58d5c6e550bb34cbaa50517323133fad4f900980..e29f679423eeccae1c8fb7af5fdafc69f051741a 100644
+--- a/src/resolv/async_resolv.c
++++ b/src/resolv/async_resolv.c
+@@ -140,12 +140,9 @@ fd_input_available(struct tevent_context *ev, struct tevent_fd *fde,
+         return;
+     }
+ 
+-    if (flags & TEVENT_FD_READ) {
+-        ares_process_fd(watch->ctx->channel, watch->fd, ARES_SOCKET_BAD);
+-    }
+-    if (flags & TEVENT_FD_WRITE) {
+-        ares_process_fd(watch->ctx->channel, ARES_SOCKET_BAD, watch->fd);
+-    }
++    ares_process_fd(watch->ctx->channel,
++                    flags & TEVENT_FD_READ ? watch->fd : ARES_SOCKET_BAD,
++                    flags & TEVENT_FD_WRITE ? watch->fd : ARES_SOCKET_BAD);
+ }
+ 
+ static void
+-- 
+2.9.3
+
diff --git a/SPECS/sssd.spec b/SPECS/sssd.spec
index 39bed2c..7cc3dc1 100644
--- a/SPECS/sssd.spec
+++ b/SPECS/sssd.spec
@@ -33,7 +33,7 @@
 
 Name: sssd
 Version: 1.14.0
-Release: 43%{?dist}.4
+Release: 43%{?dist}.11
 Group: Applications/System
 Summary: System Security Services Daemon
 License: GPLv3+
@@ -188,6 +188,15 @@ Patch0144: 0144-sysdb-add-parent_dom-to-sysdb_get_direct_parents.patch
 Patch0145: 0145-sdap-make-some-nested-group-related-calls-public.patch
 Patch0146: 0146-LDAP-AD-resolve-domain-local-groups-for-remote-users.patch
 Patch0147: 0147-IPA-Initialize-a-boolean-control-value.patch
+Patch0148: 0148-IPA-AD-check-auth-ctx-before-using-it.patch
+Patch0149: 0149-Qualify-ghost-user-attribute-in-case-ldap_group_nest.patch
+Patch0150: 0150-SYSDB-Split-sysdb_try_to_find_expected_dn-into-small.patch
+Patch0151: 0151-SYSDB-Augment-sysdb_try_to_find_expected_dn-to-match.patch
+Patch0152: 0152-SYSDB-Adding-lowercase-sudoUser-form.patch
+Patch0153: 0153-SYSDB-Fixing-of-sudorule-without-a-sudoUser.patch
+Patch0154: 0154-MONITOR-Do-not-set-up-watchdog-for-monitor.patch
+Patch0155: 0155-AUTOFS-Fix-offline-resolution-of-autofs-maps.patch
+Patch0156: 0156-Prevent-use-after-free-in-fd_input_available.patch
 
 #This patch should not be removed in RHEL-7
 Patch999: 0999-NOUPSTREAM-Default-to-root-if-sssd-user-is-not-spec
@@ -1182,6 +1191,32 @@ fi
 /usr/bin/rm -f /var/tmp/sssd.upgrade || :
 
 %changelog
+* Tue Dec 13 2016 Jakub Hrozek <jhrozek@redhat.com> - 1.14.0-43.11
+- Resolves: rhbz#1404340 - Use-after free in resolver in case the fd is
+                           writeable and readable at the same time
+
+* Fri Nov 25 2016 Jakub Hrozek <jhrozek@redhat.com> - 1.14.0-43.10
+- Resolves: rhbz#1398673 - autofs map resolution doesn't work offline
+
+* Thu Nov 24 2016 Jakub Hrozek <jhrozek@redhat.com> - 1.14.0-43.9
+- Resolves: rhbz#1398169 - sssd fails to start after upgrading to RHEL 7.3
+
+* Wed Nov 23 2016 Jakub Hrozek <jhrozek@redhat.com> - 1.14.0-43.8
+- Resolves: rhbz#1392946 - sudo: ignore case on case insensitive domains
+
+* Wed Nov 23 2016 Jakub Hrozek <jhrozek@redhat.com> - 1.14.0-43.7
+- Resolves: rhbz#1393730 - No supplementary groups are resolved for users
+                           in nested OUs when domain stanza differs from AD
+                           domain
+
+* Fri Nov 18 2016 Jakub Hrozek <jhrozek@redhat.com> - 1.14.0-43.6
+- Related: rhbz#1396486 - bz - ldap group names don't resolve after
+                          upgrading sssd to 1.14.0 if ldap_nesting_level
+                          is set to 0
+
+* Fri Nov 18 2016 Jakub Hrozek <jhrozek@redhat.com> - 1.14.0-43.5
+- Related: rhbz#1396485 - sssd_be keeps crashing
+
 * Mon Nov 14 2016 Jakub Hrozek <jhrozek@redhat.com> - 1.14.0-43.4
 - Revert the fix for ignoring sudoUser case as it breaks processing
   of rules that completely lack a sudoUser attribute