diff --git a/SOURCES/0055-krb5_locator-always-use-port-88-for-master-KDC.patch b/SOURCES/0055-krb5_locator-always-use-port-88-for-master-KDC.patch
new file mode 100644
index 0000000..1bd571e
--- /dev/null
+++ b/SOURCES/0055-krb5_locator-always-use-port-88-for-master-KDC.patch
@@ -0,0 +1,402 @@
+From 941a381d7a7be2af73e41bd584aca4d22675d765 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Fri, 15 Feb 2019 16:54:19 +0100
+Subject: [PATCH] krb5_locator: always use port 88 for master KDC
+
+If the kpasswdinfo file exists and the found IP address includes a port
+number as well the master KDC lookup will use this port number which is
+most probably wrong. Better use the default port 88 always for master
+KDC lookups.
+
+This patch also updates the man page for the locator plugin which was
+quite outdated.
+
+Related to https://pagure.io/SSSD/sssd/issue/3958
+
+Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
+(cherry picked from commit 05350abdf2ab98770ca296b9485578218644a2a7)
+---
+ src/krb5_plugin/sssd_krb5_locator_plugin.c    |  43 +++--
+ src/man/sssd_krb5_locator_plugin.8.xml        |  76 +++++----
+ .../cmocka/test_sssd_krb5_locator_plugin.c    | 156 ++++++++++++++++++
+ 3 files changed, 233 insertions(+), 42 deletions(-)
+
+diff --git a/src/krb5_plugin/sssd_krb5_locator_plugin.c b/src/krb5_plugin/sssd_krb5_locator_plugin.c
+index 952d487c2..fc5a4235d 100644
+--- a/src/krb5_plugin/sssd_krb5_locator_plugin.c
++++ b/src/krb5_plugin/sssd_krb5_locator_plugin.c
+@@ -80,6 +80,7 @@ struct sssd_ctx {
+     struct addr_port *kpasswd_addr;
+     bool debug;
+     bool disabled;
++    bool kpasswdinfo_used;
+ };
+ 
+ void plugin_debug_fn(const char *format, ...)
+@@ -411,6 +412,7 @@ krb5_error_code sssd_krb5_locator_init(krb5_context context,
+         ctx->disabled = true;
+         PLUGIN_DEBUG(("SSSD KRB5 locator plugin is disabled.\n"));
+     }
++    ctx->kpasswdinfo_used = false;
+ 
+     *private_data = ctx;
+ 
+@@ -451,6 +453,7 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
+     struct addr_port *addr = NULL;
+     char port_str[PORT_STR_SIZE];
+     size_t c;
++    bool force_port = false;
+ 
+     if (private_data == NULL) return KRB5_PLUGIN_NO_HANDLE;
+     ctx = (struct sssd_ctx *) private_data;
+@@ -478,20 +481,24 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
+             return KRB5_PLUGIN_NO_HANDLE;
+         }
+ 
+-        if (svc == locate_service_kadmin || svc == locate_service_kpasswd ||
+-            svc == locate_service_master_kdc) {
+-            ret = get_krb5info(realm, ctx, locate_service_kpasswd);
++    }
++
++    if (ctx->kpasswd_addr == NULL
++            && (svc == locate_service_kadmin || svc == locate_service_kpasswd ||
++                svc == locate_service_master_kdc)) {
++        ret = get_krb5info(realm, ctx, locate_service_kpasswd);
++        if (ret != EOK) {
++            PLUGIN_DEBUG(("reading kpasswd address failed, "
++                          "using kdc address.\n"));
++            free_addr_port_list(&(ctx->kpasswd_addr));
++            ret = copy_addr_port_list(ctx->kdc_addr, true,
++                                      &(ctx->kpasswd_addr));
+             if (ret != EOK) {
+-                PLUGIN_DEBUG(("reading kpasswd address failed, "
+-                              "using kdc address.\n"));
+-                free_addr_port_list(&(ctx->kpasswd_addr));
+-                ret = copy_addr_port_list(ctx->kdc_addr, true,
+-                                          &(ctx->kpasswd_addr));
+-                if (ret != EOK) {
+-                    PLUGIN_DEBUG(("copying address list failed.\n"));
+-                    return KRB5_PLUGIN_NO_HANDLE;
+-                }
++                PLUGIN_DEBUG(("copying address list failed.\n"));
++                return KRB5_PLUGIN_NO_HANDLE;
+             }
++        } else {
++            ctx->kpasswdinfo_used = true;
+         }
+     }
+ 
+@@ -507,6 +514,12 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
+         case locate_service_master_kdc:
+             addr = ctx->kpasswd_addr;
+             default_port = DEFAULT_KERBEROS_PORT;
++            if (ctx->kpasswdinfo_used) {
++                /* Use default port if the addresses from the kpasswdinfo
++                 * files are used because the port numbers from the file will
++                 * most probably not be suitable. */
++                force_port = true;
++            }
+             break;
+         case locate_service_kadmin:
+             addr = ctx->kpasswd_addr;
+@@ -539,11 +552,13 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
+             return KRB5_PLUGIN_NO_HANDLE;
+     }
+ 
+-    if (strcmp(realm, ctx->sssd_realm) != 0)
++    if (strcmp(realm, ctx->sssd_realm) != 0 || addr == NULL) {
+         return KRB5_PLUGIN_NO_HANDLE;
++    }
+ 
+     for (c = 0; addr[c].addr != NULL; c++) {
+-        port = (addr[c].port == 0 ? default_port : addr[c].port);
++        port = ((addr[c].port == 0 || force_port) ? default_port
++                                                  : addr[c].port);
+         memset(port_str, 0, PORT_STR_SIZE);
+         ret = snprintf(port_str, PORT_STR_SIZE-1, "%u", port);
+         if (ret < 0 || ret >= (PORT_STR_SIZE-1)) {
+diff --git a/src/man/sssd_krb5_locator_plugin.8.xml b/src/man/sssd_krb5_locator_plugin.8.xml
+index d28546012..d77f59d6a 100644
+--- a/src/man/sssd_krb5_locator_plugin.8.xml
++++ b/src/man/sssd_krb5_locator_plugin.8.xml
+@@ -20,40 +20,60 @@
+         <title>DESCRIPTION</title>
+         <para>
+             The Kerberos locator plugin
+-            <command>sssd_krb5_locator_plugin</command> is used by the Kerberos
+-            provider of
+-            <citerefentry>
+-                <refentrytitle>sssd</refentrytitle>
+-                <manvolnum>8</manvolnum>
+-            </citerefentry>
+-            to tell the Kerberos libraries what Realm and which KDC to use.
+-            Typically this is done in
++            <command>sssd_krb5_locator_plugin</command> is used by libkrb5 to
++            find KDCs for a given Kerberos realm. SSSD provides such a plugin to
++            guide all Kerberos clients on a system to a single KDC. In general
++            it should not matter to which KDC a client process is talking to.
++            But there are cases, e.g. after a password change, where not all
++            KDCs are in the same state because the new data has to be replicated
++            first. To avoid unexpected authentication failures and maybe even
++            account lockings it would be good to talk to a single KDC as long as
++            possible.
++        </para>
++        <para>
++            libkrb5 will search the locator plugin in the libkrb5 sub-directory
++            of the Kerberos plugin directory, see plugin_base_dir in
+             <citerefentry>
+                 <refentrytitle>krb5.conf</refentrytitle>
+                 <manvolnum>5</manvolnum>
+             </citerefentry>
+-            which is always read by the Kerberos libraries. To simplify the
+-            configuration the Realm and the KDC can be defined in
+-            <citerefentry>
+-                <refentrytitle>sssd.conf</refentrytitle>
+-                <manvolnum>5</manvolnum>
+-            </citerefentry>
+-            as described in
+-            <citerefentry>
+-                <refentrytitle>sssd-krb5</refentrytitle>
+-                <manvolnum>5</manvolnum>
+-            </citerefentry>
++            for details. The plugin can only be disabled by removing the plugin
++            file. There is no option in the Kerberos configuration to disable
++            it. But the SSSD_KRB5_LOCATOR_DISABLE environment variable can be
++            used to disable the plugin for individual commands. Alternatively
++            the SSSD option krb5_use_kdcinfo=False can be used to not generate
++            the data needed by the plugin. With this the plugin is still
++            called but will provide no data to the caller so that libkrb5 can
++            fall back to other methods defined in krb5.conf.
+         </para>
+         <para>
+-            <citerefentry>
+-                <refentrytitle>sssd</refentrytitle>
+-                <manvolnum>8</manvolnum>
+-            </citerefentry>
+-            puts the Realm and the name or IP address of the KDC into the
+-            environment variables SSSD_KRB5_REALM and SSSD_KRB5_KDC respectively.
+-            When <command>sssd_krb5_locator_plugin</command> is called by the
+-            kerberos libraries it reads and evaluates these variables and returns
+-            them to the libraries.
++            The plugin reads the information about the KDCs of a given realm
++            from a file called <filename>kdcinfo.REALM</filename>. The file
++            should contain one or more IP addresses either in dotted-decimal
++            IPv4 notation or the hexadecimal IPv6 notation. An optional port
++            number can be added to the end separated with a colon, the IPv6
++            address has to be enclosed in squared brackets in this case as
++            usual. Valid entries are:
++            <itemizedlist>
++                <listitem><para>1.2.3.4</para></listitem>
++                <listitem><para>5.6.7.8:99</para></listitem>
++                <listitem><para>2001:db8:85a3::8a2e:370:7334</para></listitem>
++                <listitem><para>[2001:db8:85a3::8a2e:370:7334]:321</para></listitem>
++            </itemizedlist>
++            SSSD's krb5 auth-provider which is used by the IPA and AD providers
++            as well adds the address of the current KDC or domain controller
++            SSSD is using to this file.
++        </para>
++        <para>
++            In environments with read-only and read-write KDCs where clients are
++            expected to use the read-only instances for the general operations
++            and only the read-write KDC for config changes like password changes
++            a <filename>kpasswdinfo.REALM</filename> is used as well to identify
++            read-write KDCs. If this file exists for the given realm the content
++            will be used by the plugin to reply to requests for a kpasswd or
++            kadmin server or for the MIT Kerberos specific master KDC. If the
++            address contains a port number the default KDC port 88 will be used
++            for the latter.
+         </para>
+     </refsect1>
+ 
+diff --git a/src/tests/cmocka/test_sssd_krb5_locator_plugin.c b/src/tests/cmocka/test_sssd_krb5_locator_plugin.c
+index 3e7d00632..1b6838345 100644
+--- a/src/tests/cmocka/test_sssd_krb5_locator_plugin.c
++++ b/src/tests/cmocka/test_sssd_krb5_locator_plugin.c
+@@ -44,6 +44,9 @@
+ #define TEST_IP_1_WITH_SERVICE TEST_IP_1":"TEST_SERVICE_1
+ #define TEST_IPV6_1_WITH_SERVICE TEST_IPV6_1":"TEST_SERVICE_2
+ 
++#define TEST_IP_1_WITH_SERVICE_2 TEST_IP_1":"TEST_SERVICE_2
++#define TEST_IPV6_1_WITH_SERVICE_1 TEST_IPV6_1":"TEST_SERVICE_1
++
+ struct test_state {
+     void *dummy;
+ };
+@@ -61,6 +64,7 @@ static int setup(void **state)
+     *state = (void *)ts;
+ 
+     unlink(TEST_PUBCONF_PATH"/kdcinfo."TEST_REALM);
++    unlink(TEST_PUBCONF_PATH"/kpasswdinfo."TEST_REALM);
+     rmdir(TEST_PUBCONF_PATH);
+ 
+     return 0;
+@@ -574,7 +578,157 @@ void test_service(void **state)
+ 
+     k5_free_serverlist(&list);
+ 
++    /* locate_service_master_kdc should get the default port 88 if kpasswdinfo
++     * does not exists. */
++    kerr = sssd_krb5_locator_lookup(priv, locate_service_master_kdc, TEST_REALM,
++                                    SOCK_DGRAM, AF_INET, module_callback,
++                                    &cbdata);
++    assert_int_equal(kerr, 0);
++    assert_int_equal(list.nservers, 1);
++    assert_non_null(list.servers);
++    ret = getnameinfo((struct sockaddr *) &list.servers[0].addr,
++                      list.servers[0].addrlen,
++                      host, sizeof(host), service, sizeof(service),
++                      NI_NUMERICHOST|NI_NUMERICSERV);
++    assert_int_equal(ret, 0);
++    assert_string_equal(TEST_IP_1, host);
++    assert_string_equal("88", service);
++
++    k5_free_serverlist(&list);
++
++    kerr = sssd_krb5_locator_lookup(priv, locate_service_master_kdc, TEST_REALM,
++                                    SOCK_DGRAM, AF_INET6, module_callback,
++                                    &cbdata);
++    assert_int_equal(kerr, 0);
++    assert_int_equal(list.nservers, 1);
++    assert_non_null(list.servers);
++    ret = getnameinfo((struct sockaddr *) &list.servers[0].addr,
++                      list.servers[0].addrlen,
++                      host, sizeof(host), service, sizeof(service),
++                      NI_NUMERICHOST|NI_NUMERICSERV);
++    assert_int_equal(ret, 0);
++    assert_string_equal(TEST_IPV6_1_PURE, host);
++    assert_string_equal("88", service);
++
++    k5_free_serverlist(&list);
++
++    unlink(TEST_PUBCONF_PATH"/kdcinfo."TEST_REALM);
++    rmdir(TEST_PUBCONF_PATH);
++    sssd_krb5_locator_close(priv);
++
++    krb5_free_context(ctx);
++}
++
++void test_kpasswd_and_master_kdc(void **state)
++{
++    krb5_context ctx;
++    krb5_error_code kerr;
++    void *priv;
++    int fd;
++    struct serverlist list = SERVERLIST_INIT;
++    struct module_callback_data cbdata = { 0 };
++    ssize_t s;
++    int ret;
++    char host[NI_MAXHOST];
++    char service[NI_MAXSERV];
++
++    cbdata.list = &list;
++
++    kerr = krb5_init_context (&ctx);
++    assert_int_equal(kerr, 0);
++
++    kerr = sssd_krb5_locator_init(ctx, &priv);
++    assert_int_equal(kerr, 0);
++
++    mkdir(TEST_PUBCONF_PATH, 0777);
++    fd = open(TEST_PUBCONF_PATH"/kdcinfo."TEST_REALM, O_CREAT|O_RDWR, 0777);
++    assert_int_not_equal(fd, -1);
++    s = write(fd, TEST_IP_1_WITH_SERVICE, sizeof(TEST_IP_1_WITH_SERVICE));
++    assert_int_equal(s, sizeof(TEST_IP_1_WITH_SERVICE));
++    s = write(fd, "\n", 1);
++    assert_int_equal(s, 1);
++    s = write(fd, TEST_IPV6_1_WITH_SERVICE, sizeof(TEST_IPV6_1_WITH_SERVICE));
++    assert_int_equal(s, sizeof(TEST_IPV6_1_WITH_SERVICE));
++    close(fd);
++    fd = open(TEST_PUBCONF_PATH"/kpasswdinfo."TEST_REALM, O_CREAT|O_RDWR, 0777);
++    assert_int_not_equal(fd, -1);
++    s = write(fd, TEST_IP_1_WITH_SERVICE_2, sizeof(TEST_IP_1_WITH_SERVICE_2));
++    assert_int_equal(s, sizeof(TEST_IP_1_WITH_SERVICE_2));
++    s = write(fd, "\n", 1);
++    assert_int_equal(s, 1);
++    s = write(fd, TEST_IPV6_1_WITH_SERVICE_1,
++              sizeof(TEST_IPV6_1_WITH_SERVICE_1));
++    assert_int_equal(s, sizeof(TEST_IPV6_1_WITH_SERVICE_1));
++    close(fd);
++
++    kerr = sssd_krb5_locator_lookup(priv, locate_service_kpasswd, TEST_REALM,
++                                    SOCK_DGRAM, AF_INET, module_callback,
++                                    &cbdata);
++    assert_int_equal(kerr, 0);
++    assert_int_equal(list.nservers, 1);
++    assert_non_null(list.servers);
++    ret = getnameinfo((struct sockaddr *) &list.servers[0].addr,
++                      list.servers[0].addrlen,
++                      host, sizeof(host), service, sizeof(service),
++                      NI_NUMERICHOST|NI_NUMERICSERV);
++    assert_int_equal(ret, 0);
++    assert_string_equal(TEST_IP_1, host);
++    assert_string_equal(TEST_SERVICE_2, service);
++
++    k5_free_serverlist(&list);
++
++    kerr = sssd_krb5_locator_lookup(priv, locate_service_kpasswd , TEST_REALM,
++                                    SOCK_DGRAM, AF_INET6, module_callback,
++                                    &cbdata);
++    assert_int_equal(kerr, 0);
++
++    assert_int_equal(list.nservers, 1);
++    assert_non_null(list.servers);
++    ret = getnameinfo((struct sockaddr *) &list.servers[0].addr,
++                      list.servers[0].addrlen,
++                      host, sizeof(host), service, sizeof(service),
++                      NI_NUMERICHOST|NI_NUMERICSERV);
++    assert_int_equal(ret, 0);
++    assert_string_equal(TEST_IPV6_1_PURE, host);
++    assert_string_equal(TEST_SERVICE_1, service);
++
++    k5_free_serverlist(&list);
++
++    /* locate_service_master_kdc should use the default KDC port 88 and not
++     * the one set in the kpasswdinfo file. */
++    kerr = sssd_krb5_locator_lookup(priv, locate_service_master_kdc, TEST_REALM,
++                                    SOCK_DGRAM, AF_INET, module_callback,
++                                    &cbdata);
++    assert_int_equal(kerr, 0);
++    assert_int_equal(list.nservers, 1);
++    assert_non_null(list.servers);
++    ret = getnameinfo((struct sockaddr *) &list.servers[0].addr,
++                      list.servers[0].addrlen,
++                      host, sizeof(host), service, sizeof(service),
++                      NI_NUMERICHOST|NI_NUMERICSERV);
++    assert_int_equal(ret, 0);
++    assert_string_equal(TEST_IP_1, host);
++    assert_string_equal("88", service);
++
++    k5_free_serverlist(&list);
+ 
++    kerr = sssd_krb5_locator_lookup(priv, locate_service_master_kdc, TEST_REALM,
++                                    SOCK_DGRAM, AF_INET6, module_callback,
++                                    &cbdata);
++    assert_int_equal(kerr, 0);
++    assert_int_equal(list.nservers, 1);
++    assert_non_null(list.servers);
++    ret = getnameinfo((struct sockaddr *) &list.servers[0].addr,
++                      list.servers[0].addrlen,
++                      host, sizeof(host), service, sizeof(service),
++                      NI_NUMERICHOST|NI_NUMERICSERV);
++    assert_int_equal(ret, 0);
++    assert_string_equal(TEST_IPV6_1_PURE, host);
++    assert_string_equal("88", service);
++
++    k5_free_serverlist(&list);
++
++    unlink(TEST_PUBCONF_PATH"/kpasswdinfo."TEST_REALM);
+     unlink(TEST_PUBCONF_PATH"/kdcinfo."TEST_REALM);
+     rmdir(TEST_PUBCONF_PATH);
+     sssd_krb5_locator_close(priv);
+@@ -606,6 +760,8 @@ int main(int argc, const char *argv[])
+                                         setup, teardown),
+         cmocka_unit_test_setup_teardown(test_service,
+                                         setup, teardown),
++        cmocka_unit_test_setup_teardown(test_kpasswd_and_master_kdc,
++                                        setup, teardown),
+     };
+ 
+     /* Set debug level to invalid value so we can decide if -d 0 was used. */
+-- 
+2.19.1
+
diff --git a/SOURCES/0056-NSS-Avoid-changing-the-memory-cache-ownership-away-f.patch b/SOURCES/0056-NSS-Avoid-changing-the-memory-cache-ownership-away-f.patch
new file mode 100644
index 0000000..ca07f08
--- /dev/null
+++ b/SOURCES/0056-NSS-Avoid-changing-the-memory-cache-ownership-away-f.patch
@@ -0,0 +1,358 @@
+From 118c44f90c9c901ffbf1b676be57b7a83a190399 Mon Sep 17 00:00:00 2001
+From: Jakub Hrozek <jhrozek@redhat.com>
+Date: Fri, 30 Nov 2018 13:06:13 +0100
+Subject: [PATCH] NSS: Avoid changing the memory cache ownership away from the
+ sssd user
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Resolves:
+https://pagure.io/SSSD/sssd/issue/3890
+
+In case SSSD is compiled --with-sssd-user but run as root (which is the
+default on RHEL and derivatives), then the memory cache will be owned by
+the user that sssd_nss runs as, so root.
+
+This conflicts with the packaging which specifies sssd.sssd as the owner. And
+in turn, this means that users can't reliably assess the package integrity
+using rpm -V.
+
+This patch makes sure that the memory cache files are chowned to sssd.sssd
+even if the nss responder runs as root.
+
+Also, this patch changes the sssd_nss responder so that is becomes a member
+of the supplementary sssd group. Even though in traditional UNIX sense,
+a process running as root could write to a file owned by sssd:sssd, with
+SELinux enforcing mode this becomes problematic as SELinux emits an error
+such as:
+
+type=AVC msg=audit(1543524888.125:1495): avc:  denied  { fsetid } for
+pid=7706 comm="sssd_nss" capability=4  scontext=system_u:system_r:sssd_t:s0
+tcontext=system_u:system_r:sssd_t:s0 tclass=capability
+
+To make it possible for the sssd_nss process to write to the files, the
+files are also made group-writable. The 'others' permission is still set
+to read only.
+
+Reviewed-by: Michal Židek <mzidek@redhat.com>
+(cherry picked from commit 61e4ba58934b20a950255e05797aca25aadc1242)
+---
+ src/responder/nss/nss_private.h       |   2 +
+ src/responder/nss/nsssrv.c            | 106 ++++++++++++++++++++++++--
+ src/responder/nss/nsssrv_mmap_cache.c |  51 ++++++++++++-
+ src/responder/nss/nsssrv_mmap_cache.h |   5 +-
+ 5 files changed, 154 insertions(+), 10 deletions(-)
+
+diff --git a/src/responder/nss/nss_private.h b/src/responder/nss/nss_private.h
+index cd0d35517..bae5fe074 100644
+--- a/src/responder/nss/nss_private.h
++++ b/src/responder/nss/nss_private.h
+@@ -87,6 +87,8 @@ struct nss_ctx {
+     struct sss_mc_ctx *pwd_mc_ctx;
+     struct sss_mc_ctx *grp_mc_ctx;
+     struct sss_mc_ctx *initgr_mc_ctx;
++    uid_t mc_uid;
++    gid_t mc_gid;
+ };
+ 
+ struct sss_cmd_table *get_nss_cmds(void);
+diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
+index d6c5a08a9..87a3f1d50 100644
+--- a/src/responder/nss/nsssrv.c
++++ b/src/responder/nss/nsssrv.c
+@@ -101,7 +101,8 @@ static int nss_clear_memcache(struct sbus_request *dbus_req, void *data)
+ 
+     /* TODO: read cache sizes from configuration */
+     DEBUG(SSSDBG_TRACE_FUNC, "Clearing memory caches.\n");
+-    ret = sss_mmap_cache_reinit(nctx, SSS_MC_CACHE_ELEMENTS,
++    ret = sss_mmap_cache_reinit(nctx, nctx->mc_uid, nctx->mc_gid,
++                                SSS_MC_CACHE_ELEMENTS,
+                                 (time_t) memcache_timeout,
+                                 &nctx->pwd_mc_ctx);
+     if (ret != EOK) {
+@@ -110,7 +111,8 @@ static int nss_clear_memcache(struct sbus_request *dbus_req, void *data)
+         return ret;
+     }
+ 
+-    ret = sss_mmap_cache_reinit(nctx, SSS_MC_CACHE_ELEMENTS,
++    ret = sss_mmap_cache_reinit(nctx, nctx->mc_uid, nctx->mc_gid,
++                                SSS_MC_CACHE_ELEMENTS,
+                                 (time_t) memcache_timeout,
+                                 &nctx->grp_mc_ctx);
+     if (ret != EOK) {
+@@ -119,7 +121,8 @@ static int nss_clear_memcache(struct sbus_request *dbus_req, void *data)
+         return ret;
+     }
+ 
+-    ret = sss_mmap_cache_reinit(nctx, SSS_MC_CACHE_ELEMENTS,
++    ret = sss_mmap_cache_reinit(nctx, nctx->mc_uid, nctx->mc_gid,
++                                SSS_MC_CACHE_ELEMENTS,
+                                 (time_t)memcache_timeout,
+                                 &nctx->initgr_mc_ctx);
+     if (ret != EOK) {
+@@ -284,21 +287,27 @@ static int setup_memcaches(struct nss_ctx *nctx)
+     }
+ 
+     /* TODO: read cache sizes from configuration */
+-    ret = sss_mmap_cache_init(nctx, "passwd", SSS_MC_PASSWD,
++    ret = sss_mmap_cache_init(nctx, "passwd",
++                              nctx->mc_uid, nctx->mc_gid,
++                              SSS_MC_PASSWD,
+                               SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout,
+                               &nctx->pwd_mc_ctx);
+     if (ret) {
+         DEBUG(SSSDBG_CRIT_FAILURE, "passwd mmap cache is DISABLED\n");
+     }
+ 
+-    ret = sss_mmap_cache_init(nctx, "group", SSS_MC_GROUP,
++    ret = sss_mmap_cache_init(nctx, "group",
++                              nctx->mc_uid, nctx->mc_gid,
++                              SSS_MC_GROUP,
+                               SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout,
+                               &nctx->grp_mc_ctx);
+     if (ret) {
+         DEBUG(SSSDBG_CRIT_FAILURE, "group mmap cache is DISABLED\n");
+     }
+ 
+-    ret = sss_mmap_cache_init(nctx, "initgroups", SSS_MC_INITGROUPS,
++    ret = sss_mmap_cache_init(nctx, "initgroups",
++                              nctx->mc_uid, nctx->mc_gid,
++                              SSS_MC_INITGROUPS,
+                               SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout,
+                               &nctx->initgr_mc_ctx);
+     if (ret) {
+@@ -308,6 +317,79 @@ static int setup_memcaches(struct nss_ctx *nctx)
+     return EOK;
+ }
+ 
++static int sssd_supplementary_group(struct nss_ctx *nss_ctx)
++{
++    errno_t ret;
++    int size;
++    gid_t *supp_gids = NULL;
++
++    /*
++     * We explicitly read the IDs of the SSSD user even though the server
++     * receives --uid and --gid by parameters to account for the case where
++     * the SSSD is compiled --with-sssd-user=sssd but the default of the
++     * user option is root (this is what RHEL does)
++     */
++    ret = sss_user_by_name_or_uid(SSSD_USER,
++                                  &nss_ctx->mc_uid,
++                                  &nss_ctx->mc_gid);
++    if (ret != EOK) {
++        DEBUG(SSSDBG_MINOR_FAILURE, "Cannot get info on "SSSD_USER);
++        return ret;
++    }
++
++    if (getgid() == nss_ctx->mc_gid) {
++        DEBUG(SSSDBG_TRACE_FUNC, "Already running as the sssd group\n");
++        return EOK;
++    }
++
++    size = getgroups(0, NULL);
++    if (size == -1) {
++        ret = errno;
++        DEBUG(SSSDBG_CRIT_FAILURE, "Getgroups failed! (%d, %s)\n",
++                                    ret, sss_strerror(ret));
++        return ret;
++    }
++
++    if (size > 0) {
++        supp_gids = talloc_zero_array(NULL, gid_t, size);
++        if (supp_gids == NULL) {
++            DEBUG(SSSDBG_CRIT_FAILURE, "Allocation failed!\n");
++            ret = ENOMEM;
++            goto done;
++        }
++    }
++
++    size = getgroups(size, supp_gids);
++    if (size == -1) {
++        ret = errno;
++        DEBUG(SSSDBG_CRIT_FAILURE, "Getgroups failed! (%d, %s)\n",
++                                    ret, sss_strerror(ret));
++        goto done;
++    }
++
++    for (int i = 0; i < size; i++) {
++        if (supp_gids[i] == nss_ctx->mc_gid) {
++            DEBUG(SSSDBG_TRACE_FUNC,
++                  "Already assigned to the SSSD supplementary group\n");
++            ret = EOK;
++            goto done;
++        }
++    }
++
++    ret = setgroups(1, &nss_ctx->mc_gid);
++    if (ret != EOK) {
++        ret = errno;
++        DEBUG(SSSDBG_OP_FAILURE,
++              "Cannot setgroups [%d]: %s\n", ret, sss_strerror(ret));
++        goto done;
++    }
++
++    ret = EOK;
++done:
++    talloc_free(supp_gids);
++    return ret;
++}
++
+ int nss_process_init(TALLOC_CTX *mem_ctx,
+                      struct tevent_context *ev,
+                      struct confdb_ctx *cdb)
+@@ -405,6 +487,18 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
+         ret = EFAULT;
+         goto fail;
+     }
++    /*
++     * Adding the NSS process to the SSSD supplementary group avoids
++     * dac_override AVC messages from SELinux in case sssd_nss runs
++     * as root and tries to write to memcache owned by sssd:sssd
++     */
++    ret = sssd_supplementary_group(nctx);
++    if (ret != EOK) {
++        DEBUG(SSSDBG_MINOR_FAILURE,
++              "Cannot add process to the sssd supplementary group [%d]: %s\n",
++              ret, sss_strerror(ret));
++        goto fail;
++    }
+ 
+     ret = setup_memcaches(nctx);
+     if (ret != EOK) {
+diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c
+index de9e67513..d5181d771 100644
+--- a/src/responder/nss/nsssrv_mmap_cache.c
++++ b/src/responder/nss/nsssrv_mmap_cache.c
+@@ -57,6 +57,9 @@ struct sss_mc_ctx {
+     char *file;             /* mmap cache file name */
+     int fd;                 /* file descriptor */
+ 
++    uid_t uid;              /* User ID of owner */
++    gid_t gid;              /* Group ID of owner */
++
+     uint32_t seed;          /* pseudo-random seed to avoid collision attacks */
+     time_t valid_time_slot; /* maximum time the entry is valid in seconds */
+ 
+@@ -623,7 +626,9 @@ static errno_t sss_mc_get_record(struct sss_mc_ctx **_mcc,
+         if (ret == EFAULT) {
+             DEBUG(SSSDBG_CRIT_FAILURE,
+                   "Fatal internal mmap cache error, invalidating cache!\n");
+-            (void)sss_mmap_cache_reinit(talloc_parent(mcc), -1, -1, _mcc);
++            (void)sss_mmap_cache_reinit(talloc_parent(mcc),
++                                        -1, -1, -1, -1,
++                                        _mcc);
+         }
+         return ret;
+     }
+@@ -1144,6 +1149,26 @@ static errno_t sss_mc_create_file(struct sss_mc_ctx *mc_ctx)
+         return ret;
+     }
+ 
++    /* Make sure that the memory cache files are chowned to sssd.sssd even
++     * if the nss responder runs as root. This is because the specfile
++     * has the ownership recorded as sssd.sssd
++     */
++    ret = fchown(mc_ctx->fd, mc_ctx->uid, mc_ctx->gid);
++    if (ret != 0) {
++        ret = errno;
++        DEBUG(SSSDBG_CRIT_FAILURE, "Failed to chown mmap file %s: %d(%s)\n",
++                                   mc_ctx->file, ret, strerror(ret));
++        return ret;
++    }
++
++    ret = fchmod(mc_ctx->fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
++    if (ret == -1) {
++        ret = errno;
++        DEBUG(SSSDBG_CRIT_FAILURE, "Failed to chmod mmap file %s: %d(%s)\n",
++                                   mc_ctx->file, ret, strerror(ret));
++        return ret;
++    }
++
+     ret = sss_br_lock_file(mc_ctx->fd, 0, 1, retries, t);
+     if (ret != EOK) {
+         DEBUG(SSSDBG_FATAL_FAILURE,
+@@ -1224,6 +1249,7 @@ static int mc_ctx_destructor(struct sss_mc_ctx *mc_ctx)
+ }
+ 
+ errno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name,
++                            uid_t uid, gid_t gid,
+                             enum sss_mc_type type, size_t n_elem,
+                             time_t timeout, struct sss_mc_ctx **mcc)
+ {
+@@ -1259,6 +1285,9 @@ errno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name,
+         goto done;
+     }
+ 
++    mc_ctx->uid = uid;
++    mc_ctx->gid = gid;
++
+     mc_ctx->type = type;
+ 
+     mc_ctx->valid_time_slot = timeout;
+@@ -1352,7 +1381,9 @@ done:
+     return ret;
+ }
+ 
+-errno_t sss_mmap_cache_reinit(TALLOC_CTX *mem_ctx, size_t n_elem,
++errno_t sss_mmap_cache_reinit(TALLOC_CTX *mem_ctx,
++                              uid_t uid, gid_t gid,
++                              size_t n_elem,
+                               time_t timeout, struct sss_mc_ctx **mc_ctx)
+ {
+     errno_t ret;
+@@ -1389,12 +1420,26 @@ errno_t sss_mmap_cache_reinit(TALLOC_CTX *mem_ctx, size_t n_elem,
+         timeout = (*mc_ctx)->valid_time_slot;
+     }
+ 
++    if (uid == (uid_t)-1) {
++        uid = (*mc_ctx)->uid;
++    }
++
++    if (gid == (gid_t)-1) {
++        gid = (*mc_ctx)->gid;
++    }
++
+     talloc_free(*mc_ctx);
+ 
+     /* make sure we do not leave a potentially freed pointer around */
+     *mc_ctx = NULL;
+ 
+-    ret = sss_mmap_cache_init(mem_ctx, name, type, n_elem, timeout, mc_ctx);
++    ret = sss_mmap_cache_init(mem_ctx,
++                              name,
++                              uid, gid,
++                              type,
++                              n_elem,
++                              timeout,
++                              mc_ctx);
+     if (ret != EOK) {
+         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to re-initialize mmap cache.\n");
+         goto done;
+diff --git a/src/responder/nss/nsssrv_mmap_cache.h b/src/responder/nss/nsssrv_mmap_cache.h
+index b84fbc8ed..e06257949 100644
+--- a/src/responder/nss/nsssrv_mmap_cache.h
++++ b/src/responder/nss/nsssrv_mmap_cache.h
+@@ -34,6 +34,7 @@ enum sss_mc_type {
+ };
+ 
+ errno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name,
++                            uid_t uid, gid_t gid,
+                             enum sss_mc_type type, size_t n_elem,
+                             time_t valid_time, struct sss_mc_ctx **mcc);
+ 
+@@ -70,7 +71,9 @@ errno_t sss_mmap_cache_gr_invalidate_gid(struct sss_mc_ctx *mcc, gid_t gid);
+ errno_t sss_mmap_cache_initgr_invalidate(struct sss_mc_ctx *mcc,
+                                          struct sized_string *name);
+ 
+-errno_t sss_mmap_cache_reinit(TALLOC_CTX *mem_ctx, size_t n_elem,
++errno_t sss_mmap_cache_reinit(TALLOC_CTX *mem_ctx,
++                              uid_t uid, gid_t gid,
++                              size_t n_elem,
+                               time_t timeout, struct sss_mc_ctx **mc_ctx);
+ 
+ void sss_mmap_cache_reset(struct sss_mc_ctx *mc_ctx);
+-- 
+2.19.1
+
diff --git a/SPECS/sssd.spec b/SPECS/sssd.spec
index 75d23a1..ca52f84 100644
--- a/SPECS/sssd.spec
+++ b/SPECS/sssd.spec
@@ -48,7 +48,7 @@
 
 Name: sssd
 Version: 1.16.2
-Release: 13%{?dist}.5
+Release: 13%{?dist}.8
 Group: Applications/System
 Summary: System Security Services Daemon
 License: GPLv3+
@@ -111,6 +111,8 @@ Patch0051: 0051-ipa-use-only-the-global-catalog-service-of-the-fores.patch
 Patch0052: 0052-LDAP-minor-refactoring-in-auth_send-to-conform-to-ou.patch
 Patch0053: 0053-LDAP-Only-authenticate-the-auth-connection-if-we-nee.patch
 Patch0054: 0054-LDAP-Log-the-encryption-used-during-LDAP-authenticat.patch
+Patch0055: 0055-krb5_locator-always-use-port-88-for-master-KDC.patch
+Patch0056: 0056-NSS-Avoid-changing-the-memory-cache-ownership-away-f.patch
 
 #This patch should not be removed in RHEL-7
 Patch999: 0999-NOUPSTREAM-Default-to-root-if-sssd-user-is-not-spec
@@ -834,12 +836,12 @@ done
 %dir %{sssdstatedir}
 %dir %{_localstatedir}/cache/krb5rcache
 %attr(700,sssd,sssd) %dir %{dbpath}
-%attr(755,sssd,sssd) %dir %{mcpath}
+%attr(775,sssd,sssd) %dir %{mcpath}
 %attr(700,root,root) %dir %{secdbpath}
 %attr(755,root,root) %dir %{deskprofilepath}
-%ghost %attr(0644,sssd,sssd) %verify(not md5 size mtime) %{mcpath}/passwd
-%ghost %attr(0644,sssd,sssd) %verify(not md5 size mtime) %{mcpath}/group
-%ghost %attr(0644,sssd,sssd) %verify(not md5 size mtime) %{mcpath}/initgroups
+%ghost %attr(0664,sssd,sssd) %verify(not md5 size mtime) %{mcpath}/passwd
+%ghost %attr(0664,sssd,sssd) %verify(not md5 size mtime) %{mcpath}/group
+%ghost %attr(0664,sssd,sssd) %verify(not md5 size mtime) %{mcpath}/initgroups
 %attr(755,sssd,sssd) %dir %{pipepath}
 %attr(750,sssd,root) %dir %{pipepath}/private
 %attr(755,sssd,sssd) %dir %{pubconfpath}
@@ -847,7 +849,7 @@ done
 %attr(750,sssd,sssd) %dir %{_var}/log/%{name}
 %attr(711,sssd,sssd) %dir %{_sysconfdir}/sssd
 %attr(711,sssd,sssd) %dir %{_sysconfdir}/sssd/conf.d
-%ghost %attr(0600,sssd,sssd) %config(noreplace) %{_sysconfdir}/sssd/sssd.conf
+%ghost %attr(0600,root,root) %config(noreplace) %{_sysconfdir}/sssd/sssd.conf
 %dir %{_sysconfdir}/logrotate.d
 %config(noreplace) %{_sysconfdir}/logrotate.d/sssd
 %dir %{_sysconfdir}/rwtab.d
@@ -1263,22 +1265,33 @@ systemctl try-restart sssd >/dev/null 2>&1 || :
 }
 
 %changelog
-* Tue Dec 18 2018 Michal Židek <mzidek@redhat.com> - 1.16.3-5
+* Tue Mar 26 2019 Michal Židek <mzidek@redhat.com> - 1.16.2-13.8
+- Resolves: rhbz#1690759 - RHEL STIG pointing sssd Packaging issue [rhel-7.6.z]
+                         - Part 2.
+
+* Tue Mar 26 2019 Michal Židek <mzidek@redhat.com> - 1.16.2-13.7
+- Resolves: rhbz#1690759 - RHEL STIG pointing sssd Packaging issue [rhel-7.6.z]
+
+* Tue Dec 18 2018 Michal Židek <mzidek@redhat.com> - 1.16.2-13.6
+- Resolves: rhbz#1683578 - sssd_krb5_locator_plugin introduces delay in
+                           cifs.upcall krb5 calls [rhel-7.6.z]
+
+* Tue Dec 18 2018 Michal Židek <mzidek@redhat.com> - 1.16.2-13.5
 - Resolves: rhbz#1659507 - SSSD's LDAP authentication provider does not work
                            if ID provider is authenticated with GSSAPI [rhel-7.6.z] 
 
-* Tue Dec 18 2018 Michal Židek <mzidek@redhat.com> - 1.16.3-4
+* Tue Dec 18 2018 Michal Židek <mzidek@redhat.com> - 1.16.2-13.4
 - Resolves: rhbz#1659083 - SSSD must be cleared/restarted periodically in
             order to retrieve AD users through IPA Trust [rhel-7.6.z]
 
-* Tue Dec 18 2018 Michal Židek <mzidek@redhat.com> - 1.16.3-3
+* Tue Dec 18 2018 Michal Židek <mzidek@redhat.com> - 1.16.2-13.3
 - Resolves: rhbz#1656833 - sssd_nss memory leak [rhel-7.6.z]
 
-* Wed Nov 28 2018 Michal Židek <mzidek@redhat.com> - 1.16.3-2
+* Wed Nov 28 2018 Michal Židek <mzidek@redhat.com> - 1.16.2-13.2
 - Resolves: Bug 1649784 - SSSD not fetching all sudo rules from
                           AD [rhel-7.6.z] 
 
-* Wed Nov 14 2018 Michal Židek <mzidek@redhat.com> - 1.16.3-1
+* Wed Nov 14 2018 Michal Židek <mzidek@redhat.com> - 1.16.2-13.1
 - Resolves: rhbz#1645047 - sssd only sets the SELinux login context if it
                            differs from the default [rhel-7.6.z]