diff --git a/SOURCES/0196-sssd_client-add-mutex-protected-call-to-the-PAC-resp.patch b/SOURCES/0196-sssd_client-add-mutex-protected-call-to-the-PAC-resp.patch
new file mode 100644
index 0000000..2fe32d6
--- /dev/null
+++ b/SOURCES/0196-sssd_client-add-mutex-protected-call-to-the-PAC-resp.patch
@@ -0,0 +1,461 @@
+From daa59b79602cfeff81223a7461e18f513178c9d4 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Mon, 18 Sep 2017 15:00:53 +0200
+Subject: [PATCH 196/196] sssd_client: add mutex protected call to the PAC
+ responder
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+SSSD's plugin for MIT Kerberos to send the PAC to the PAC responder
+currently uses sss_pac_make_request() which does not protect the
+communication with the PAC responder with a mutex as e.g. the NSS and
+PAM clients.
+
+If an application using threads loads this plugin via libkrb5 in
+different threads and is heavily processing Kerberos tickets with PACs
+chances are that two threads try to communicate with SSSD at once. In
+this case one of the threads will miss a reply and will wait for it
+until the default client timeout of 300s is passed.
+
+This patch adds a call which uses a mutex to protect the communication
+which will avoid the 300s delay mentioned above.
+
+Resolves:
+https://pagure.io/SSSD/sssd/issue/3518
+
+Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
+Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
+(cherry picked from commit 1f331476e7d33bb03cc35a2a9064ee1cc5bed6cf)
+---
+ Makefile.am                               |  16 ++++
+ src/sss_client/common.c                   |  30 +++++++
+ src/sss_client/sss_cli.h                  |   7 ++
+ src/sss_client/sss_pac_responder_client.c | 137 ++++++++++++++++++++++++++++++
+ src/sss_client/sssd_pac.c                 |   4 +-
+ src/tests/intg/Makefile.am                |   1 +
+ src/tests/intg/test_pac_responder.py      | 120 ++++++++++++++++++++++++++
+ 7 files changed, 313 insertions(+), 2 deletions(-)
+ create mode 100644 src/sss_client/sss_pac_responder_client.c
+ create mode 100644 src/tests/intg/test_pac_responder.py
+
+diff --git a/Makefile.am b/Makefile.am
+index 907c3256a154ebe2aae5a1667744e1dfbe8abaae..cdd517d50679b876814303fb7d6c63d49bcd8d38 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -3501,6 +3501,9 @@ endif
+ if BUILD_WITH_LIBCURL
+ noinst_PROGRAMS += tcurl-test-tool
+ endif
++if BUILD_PAC_RESPONDER
++    noinst_PROGRAMS += sssd_pac_test_client
++endif
+ 
+ if BUILD_AUTOFS
+ autofs_test_client_SOURCES = \
+@@ -4210,6 +4213,19 @@ sssd_pac_plugin_la_LDFLAGS = \
+     -avoid-version \
+     -module
+ 
++sssd_pac_test_client_SOURCES = \
++    src/sss_client/sss_pac_responder_client.c \
++    src/sss_client/common.c \
++    src/util/strtonum.c \
++    $(NULL)
++sssd_pac_test_client_CFLAGS = \
++    $(AM_CFLAGS) \
++    $(NULL)
++sssd_pac_test_client_LDADD = \
++    $(CLIENT_LIBS) \
++    -lpthread \
++    $(NULL)
++
+ # python[23] bindings
+ pysss_la_SOURCES = \
+     $(SSSD_TOOLS_OBJ) \
+diff --git a/src/sss_client/common.c b/src/sss_client/common.c
+index b7a5ed760ca379acdfd8f1d2bf95cee1aa271fd8..b527c046e2e3369934b4f9ea7efc1b52eb8c57ea 100644
+--- a/src/sss_client/common.c
++++ b/src/sss_client/common.c
+@@ -821,6 +821,22 @@ int sss_pac_make_request(enum sss_cli_command cmd,
+     }
+ }
+ 
++int sss_pac_make_request_with_lock(enum sss_cli_command cmd,
++                                   struct sss_cli_req_data *rd,
++                                   uint8_t **repbuf, size_t *replen,
++                                   int *errnop)
++{
++    int ret;
++
++    sss_pac_lock();
++
++    ret = sss_pac_make_request(cmd, rd, repbuf, replen, errnop);
++
++    sss_pac_unlock();
++
++    return ret;
++}
++
+ errno_t check_server_cred(int sockfd)
+ {
+ #ifdef HAVE_UCRED
+@@ -1079,6 +1095,8 @@ static struct sss_mutex sss_pam_mtx = { .mtx  = PTHREAD_MUTEX_INITIALIZER };
+ 
+ static struct sss_mutex sss_nss_mc_mtx = { .mtx  = PTHREAD_MUTEX_INITIALIZER };
+ 
++static struct sss_mutex sss_pac_mtx = { .mtx  = PTHREAD_MUTEX_INITIALIZER };
++
+ static void sss_mt_lock(struct sss_mutex *m)
+ {
+     pthread_mutex_lock(&m->mtx);
+@@ -1121,6 +1139,16 @@ void sss_nss_mc_unlock(void)
+     sss_mt_unlock(&sss_nss_mc_mtx);
+ }
+ 
++/* PAC mutex wrappers */
++void sss_pac_lock(void)
++{
++    sss_mt_lock(&sss_pac_mtx);
++}
++void sss_pac_unlock(void)
++{
++    sss_mt_unlock(&sss_pac_mtx);
++}
++
+ #else
+ 
+ /* sorry no mutexes available */
+@@ -1130,6 +1158,8 @@ void sss_pam_lock(void) { return; }
+ void sss_pam_unlock(void) { return; }
+ void sss_nss_mc_lock(void) { return; }
+ void sss_nss_mc_unlock(void) { return; }
++void sss_pac_lock(void) { return; }
++void sss_pac_unlock(void) { return; }
+ #endif
+ 
+ 
+diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h
+index d4198407f2f86c6594aee6a2a43775e429692df0..337fe9803d2df3167cd2da77107dbd077f35a51b 100644
+--- a/src/sss_client/sss_cli.h
++++ b/src/sss_client/sss_cli.h
+@@ -585,6 +585,11 @@ int sss_pac_make_request(enum sss_cli_command cmd,
+                          uint8_t **repbuf, size_t *replen,
+                          int *errnop);
+ 
++int sss_pac_make_request_with_lock(enum sss_cli_command cmd,
++                                   struct sss_cli_req_data *rd,
++                                   uint8_t **repbuf, size_t *replen,
++                                   int *errnop);
++
+ int sss_sudo_make_request(enum sss_cli_command cmd,
+                           struct sss_cli_req_data *rd,
+                           uint8_t **repbuf, size_t *replen,
+@@ -634,6 +639,8 @@ void sss_pam_lock(void);
+ void sss_pam_unlock(void);
+ void sss_nss_mc_lock(void);
+ void sss_nss_mc_unlock(void);
++void sss_pac_lock(void);
++void sss_pac_unlock(void);
+ 
+ errno_t sss_readrep_copy_string(const char *in,
+                                 size_t *offset,
+diff --git a/src/sss_client/sss_pac_responder_client.c b/src/sss_client/sss_pac_responder_client.c
+new file mode 100644
+index 0000000000000000000000000000000000000000..9eb0cbea6175ee273b23d9a975529d85c02fc603
+--- /dev/null
++++ b/src/sss_client/sss_pac_responder_client.c
+@@ -0,0 +1,137 @@
++
++#include <stdio.h>
++#include <stdbool.h>
++#include <pthread.h>
++#include <pwd.h>
++#include <unistd.h>
++#include <sys/types.h>
++#include <errno.h>
++
++#include <unistd.h>
++#include <sys/syscall.h>
++
++#include "sss_client/sss_cli.h"
++
++const uint8_t pac[] = {
++0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10,
++0x02, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
++0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x68, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x0c, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x78, 0x02, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xb8,
++0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10, 0x00,
++0x00, 0x00, 0xc8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x10, 0x08,
++0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x02, 0x00, 0x30, 0xe3, 0xd6, 0x9e, 0x99, 0x2b, 0xd3, 0x01, 0xff,
++0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
++0xff, 0x7f, 0xe2, 0xf7, 0x8a, 0xaf, 0x00, 0x0f, 0xd0, 0x01, 0xe2, 0xb7, 0xf4,
++0xd9, 0xc9, 0x0f, 0xd0, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f,
++0x06, 0x00, 0x06, 0x00, 0x04, 0x00, 0x02, 0x00, 0x06, 0x00, 0x06, 0x00, 0x08,
++0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x02, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x02, 0x00, 0x45, 0x02, 0x00, 0x00,
++0x50, 0x04, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x1c,
++0x00, 0x02, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x14,
++0x00, 0x20, 0x00, 0x02, 0x00, 0x04, 0x00, 0x06, 0x00, 0x24, 0x00, 0x02, 0x00,
++0x28, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
++0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x02, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x74, 0x00,
++0x75, 0x00, 0x31, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x03, 0x00, 0x00, 0x00, 0x74, 0x00, 0x20, 0x00, 0x75, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
++0xfd, 0xa2, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x07,
++0x00, 0x00, 0x00, 0x5c, 0x04, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x56, 0x04,
++0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x89, 0xa6, 0x00, 0x00, 0x07, 0x00, 0x00,
++0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
++0x41, 0x00, 0x44, 0x00, 0x2d, 0x00, 0x53, 0x00, 0x45, 0x00, 0x52, 0x00, 0x56,
++0x00, 0x45, 0x00, 0x52, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
++0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x41, 0x00, 0x44, 0x00, 0x04, 0x00, 0x00,
++0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x15, 0x00, 0x00, 0x00,
++0xf8, 0x12, 0x13, 0xdc, 0x47, 0xf3, 0x1c, 0x76, 0x47, 0x2f, 0x2e, 0xd7, 0x02,
++0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x34, 0x00,
++0x02, 0x00, 0x07, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x05, 0x00,
++0x00, 0x00, 0x00, 0x00, 0x05, 0x15, 0x00, 0x00, 0x00, 0x29, 0xc9, 0x4f, 0xd9,
++0xc2, 0x3c, 0xc3, 0x78, 0x36, 0x55, 0x87, 0xf8, 0x54, 0x04, 0x00, 0x00, 0x05,
++0x00, 0x00, 0x00, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x15, 0x00,
++0x00, 0x00, 0x25, 0xe1, 0xff, 0x1c, 0xf7, 0x87, 0x6b, 0x2c, 0x25, 0xd2, 0x0c,
++0xe3, 0xf2, 0x03, 0x00, 0x00, 0x00, 0x2c, 0x29, 0x89, 0x65, 0x2d, 0xd3, 0x01,
++0x06, 0x00, 0x74, 0x00, 0x75, 0x00, 0x31, 0x00, 0x20, 0x00, 0x10, 0x00, 0x10,
++0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x00,
++0x75, 0x00, 0x31, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x40,
++0x00, 0x61, 0x00, 0x64, 0x00, 0x2e, 0x00, 0x64, 0x00, 0x65, 0x00, 0x76, 0x00,
++0x65, 0x00, 0x6c, 0x00, 0x41, 0x00, 0x44, 0x00, 0x2e, 0x00, 0x44, 0x00, 0x45,
++0x00, 0x56, 0x00, 0x45, 0x00, 0x4c, 0x00, 0x10, 0x00, 0x00, 0x00, 0x76, 0x8e,
++0x25, 0x32, 0x7c, 0x85, 0x00, 0x32, 0xac, 0x8f, 0x02, 0x2c, 0x10, 0x00, 0x00,
++0x00, 0x6b, 0xe8, 0x51, 0x03, 0x30, 0xed, 0xca, 0x7d, 0xe2, 0x12, 0xa5, 0xde};
++
++enum nss_status _nss_sss_getpwuid_r(uid_t uid, struct passwd *result,
++                                    char *buffer, size_t buflen, int *errnop);
++static void *pac_client(void *arg)
++{
++    struct sss_cli_req_data sss_data = { sizeof(pac), pac };
++    int errnop = -1;
++    int ret;
++    size_t c;
++
++    fprintf(stderr, "[%ld][%d][%ld][%s] started\n", time(NULL), getpid(),
++                                                    syscall(SYS_gettid),
++                                                    (char *) arg);
++    for (c = 0; c < 1000; c++) {
++        /* sss_pac_make_request() does not protect the client's file
++         * descriptor to the PAC responder. With this one thread will miss a
++         * reply for a SSS_GET_VERSION request and will wait until
++         * SSS_CLI_SOCKET_TIMEOUT is passed.
++
++        ret = sss_pac_make_request(SSS_PAC_ADD_PAC_USER, &sss_data,
++                                   NULL, NULL, &errnop);
++         */
++        ret = sss_pac_make_request_with_lock(SSS_PAC_ADD_PAC_USER, &sss_data,
++                                             NULL, NULL, &errnop);
++        if (ret != NSS_STATUS_SUCCESS
++                && !(ret == NSS_STATUS_UNAVAIL && errnop != ECONNREFUSED)) {
++                /* NSS_STATUS_UNAVAIL is returned if the PAC responder rejects
++                 * the request which is ok becasue the client is waiting for a
++                 * response here as well. Only errnop == ECONNREFUSED should
++                 * be treated as error becasue this means that the PAC
++                 * responder is not running. */
++            fprintf(stderr, "pac: [%s][%d][%d]\n", (char *)arg, ret, errnop);
++            return ((void *)((uintptr_t)("X")));
++        }
++    }
++
++    fprintf(stderr, "[%ld][%s] done\n", time(NULL),(char *) arg);
++    return NULL;
++}
++
++int main(void)
++{
++    pthread_t thread1;
++    pthread_t thread2;
++    int ret;
++    void *t_ret;
++
++    pthread_create(&thread1, NULL, pac_client,
++                   ((void *)((uintptr_t)("Thread 1"))));
++    pthread_create(&thread2, NULL, pac_client,
++                   ((void *)((uintptr_t)("Thread 2"))));
++
++    ret = pthread_join(thread1, &t_ret);
++    if (ret != 0 || t_ret != NULL) {
++        fprintf(stderr, "Thread 1 failed.\n");
++        return EIO;
++    }
++
++    ret = pthread_join(thread2, &t_ret);
++    if (ret != 0 || t_ret != NULL) {
++        fprintf(stderr, "Thread 1 failed.\n");
++        return EIO;
++    }
++
++    return 0;
++}
+diff --git a/src/sss_client/sssd_pac.c b/src/sss_client/sssd_pac.c
+index 1d98e38826b36aed199b32880a7e27de905a4592..8444834a7f148787e847f5e8e21186c8701b2de7 100644
+--- a/src/sss_client/sssd_pac.c
++++ b/src/sss_client/sssd_pac.c
+@@ -169,8 +169,8 @@ static krb5_error_code sssdpac_verify(krb5_context kcontext,
+     sss_data.len = sssdctx->data.length;
+     sss_data.data = sssdctx->data.data;
+ 
+-    ret = sss_pac_make_request(SSS_PAC_ADD_PAC_USER, &sss_data,
+-                               NULL, NULL, &errnop);
++    ret = sss_pac_make_request_with_lock(SSS_PAC_ADD_PAC_USER, &sss_data,
++                                         NULL, NULL, &errnop);
+     if (ret != 0) {
+         /* Ignore the error */
+     }
+diff --git a/src/tests/intg/Makefile.am b/src/tests/intg/Makefile.am
+index 8566106e9017a8d3c9e7a3898a3a886e2966e346..0af7c62ca243822d919619f3d0ebc852a317efc4 100644
+--- a/src/tests/intg/Makefile.am
++++ b/src/tests/intg/Makefile.am
+@@ -29,6 +29,7 @@ dist_noinst_DATA = \
+     kdc.py \
+     krb5utils.py \
+     test_kcm.py \
++    test_pac_responder.py \
+     $(NULL)
+ 
+ config.py: config.py.m4
+diff --git a/src/tests/intg/test_pac_responder.py b/src/tests/intg/test_pac_responder.py
+new file mode 100644
+index 0000000000000000000000000000000000000000..4354a5d78da6a6627a27d0ca85c8a1d47419cedf
+--- /dev/null
++++ b/src/tests/intg/test_pac_responder.py
+@@ -0,0 +1,120 @@
++#
++# SSSD PAC responder tests
++#
++# Copyright (c) 2017 Red Hat, Inc.
++# Author: Sumit Bose <sbose@redhat.com>
++#
++# This is free software; you can redistribute it and/or modify it
++# under the terms of the GNU General Public License as published by
++# the Free Software Foundation; version 2 only
++#
++# This program is distributed in the hope that it will be useful, but
++# WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++# General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program.  If not, see <http://www.gnu.org/licenses/>.
++#
++import os
++import stat
++import time
++import config
++import signal
++import subprocess
++import pytest
++from util import unindent
++
++
++def stop_sssd():
++    with open(config.PIDFILE_PATH, "r") as pid_file:
++        pid = int(pid_file.read())
++    os.kill(pid, signal.SIGTERM)
++    while True:
++        try:
++            os.kill(pid, signal.SIGCONT)
++        except:
++            break
++        time.sleep(1)
++
++
++def create_conf_fixture(request, contents):
++    """Generate sssd.conf and add teardown for removing it"""
++    conf = open(config.CONF_PATH, "w")
++    conf.write(contents)
++    conf.close()
++    os.chmod(config.CONF_PATH, stat.S_IRUSR | stat.S_IWUSR)
++    request.addfinalizer(lambda: os.unlink(config.CONF_PATH))
++
++
++def create_sssd_fixture(request):
++    """Start sssd and add teardown for stopping it and removing state"""
++    if subprocess.call(["sssd", "-D", "-f"]) != 0:
++        raise Exception("sssd start failed")
++
++    def teardown():
++        try:
++            stop_sssd()
++        except:
++            pass
++        for path in os.listdir(config.DB_PATH):
++            os.unlink(config.DB_PATH + "/" + path)
++        for path in os.listdir(config.MCACHE_PATH):
++            os.unlink(config.MCACHE_PATH + "/" + path)
++    request.addfinalizer(teardown)
++
++
++@pytest.fixture
++def local_domain_only(request):
++    conf = unindent("""\
++        [sssd]
++        domains = LOCAL
++        services = nss, pac
++
++        [nss]
++        memcache_timeout = 0
++
++        [domain/LOCAL]
++        id_provider = local
++        min_id = 10000
++        max_id = 20000
++    """).format(**locals())
++    create_conf_fixture(request, conf)
++    create_sssd_fixture(request)
++    return None
++
++
++@pytest.fixture
++def sssd_pac_test_client(request):
++    path = os.path.join(config.ABS_BUILDDIR,
++                        "..", "..", "..", "sssd_pac_test_client")
++    if os.access(path, os.X_OK):
++        return path
++
++    return None
++
++
++def timeout_handler(signum, frame):
++    raise Exception("Timeout")
++
++
++def test_multithreaded_pac_client(local_domain_only, sssd_pac_test_client):
++    """
++    Test for ticket
++    https://pagure.io/SSSD/sssd/issue/3518
++    """
++
++    if not sssd_pac_test_client:
++        pytest.skip("The sssd_pac_test_client is not available, skipping test")
++
++    signal.signal(signal.SIGALRM, timeout_handler)
++    signal.alarm(10)
++
++    try:
++        subprocess.check_call(sssd_pac_test_client)
++    except:
++        # cancel alarm
++        signal.alarm(0)
++        raise Exception("sssd_pac_test_client failed")
++
++    signal.alarm(0)
+-- 
+2.13.5
+
diff --git a/SOURCES/0197-sysdb-sanitize-search-filter-input.patch b/SOURCES/0197-sysdb-sanitize-search-filter-input.patch
new file mode 100644
index 0000000..0b2134d
--- /dev/null
+++ b/SOURCES/0197-sysdb-sanitize-search-filter-input.patch
@@ -0,0 +1,140 @@
+From 944295de4cf4eeba75d4f6bd476a4f59743e1813 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Thu, 5 Oct 2017 11:07:38 +0200
+Subject: [PATCH 197/197] sysdb: sanitize search filter input
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This patch sanitizes the input for sysdb searches by UPN/email, SID and
+UUID.
+
+This security issue was assigned CVE-2017-12173
+
+Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
+Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
+(cherry picked from commit 1f2662c8f97c9c0fa250055d4b6750abfc6d0835)
+---
+ src/db/sysdb_ops.c      | 43 +++++++++++++++++++++++++++++++++++--------
+ src/tests/sysdb-tests.c |  7 +++++++
+ 2 files changed, 42 insertions(+), 8 deletions(-)
+
+diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
+index 7ca6575ce75dab7805236c9f48dbf28a2f3946d2..408af9f389edbe0aff0fb8b96f49f0c4463a620a 100644
+--- a/src/db/sysdb_ops.c
++++ b/src/db/sysdb_ops.c
+@@ -601,6 +601,7 @@ int sysdb_search_user_by_upn_res(TALLOC_CTX *mem_ctx,
+     int ret;
+     const char *def_attrs[] = { SYSDB_NAME, SYSDB_UPN, SYSDB_CANONICAL_UPN,
+                                 SYSDB_USER_EMAIL, NULL };
++    char *sanitized;
+ 
+     tmp_ctx = talloc_new(NULL);
+     if (tmp_ctx == NULL) {
+@@ -608,6 +609,12 @@ int sysdb_search_user_by_upn_res(TALLOC_CTX *mem_ctx,
+         goto done;
+     }
+ 
++    ret = sss_filter_sanitize(tmp_ctx, upn, &sanitized);
++    if (ret != EOK) {
++        DEBUG(SSSDBG_OP_FAILURE, "sss_filter_sanitize failed.\n");
++        goto done;
++    }
++
+     if (domain_scope == true) {
+         base_dn = sysdb_user_base_dn(tmp_ctx, domain);
+     } else {
+@@ -620,7 +627,7 @@ int sysdb_search_user_by_upn_res(TALLOC_CTX *mem_ctx,
+ 
+     ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res,
+                      base_dn, LDB_SCOPE_SUBTREE, attrs ? attrs : def_attrs,
+-                     SYSDB_PWUPN_FILTER, upn, upn, upn);
++                     SYSDB_PWUPN_FILTER, sanitized, sanitized, sanitized);
+     if (ret != EOK) {
+         ret = sysdb_error_to_errno(ret);
+         goto done;
+@@ -4757,17 +4764,31 @@ static errno_t sysdb_search_object_by_str_attr(TALLOC_CTX *mem_ctx,
+                                                bool expect_only_one_result,
+                                                struct ldb_result **_res)
+ {
+-    char *filter;
++    char *filter = NULL;
+     errno_t ret;
++    char *sanitized = NULL;
+ 
+-    filter = talloc_asprintf(NULL, filter_tmpl, str);
++    if (str == NULL) {
++        return EINVAL;
++    }
++
++    ret = sss_filter_sanitize(NULL, str, &sanitized);
++    if (ret != EOK || sanitized == NULL) {
++        DEBUG(SSSDBG_OP_FAILURE, "sss_filter_sanitize failed.\n");
++        goto done;
++    }
++
++    filter = talloc_asprintf(NULL, filter_tmpl, sanitized);
+     if (filter == NULL) {
+-        return ENOMEM;
++        ret = ENOMEM;
++        goto done;
+     }
+ 
+     ret = sysdb_search_object_attr(mem_ctx, domain, filter, attrs,
+                                    expect_only_one_result, _res);
+ 
++done:
++    talloc_free(sanitized);
+     talloc_free(filter);
+     return ret;
+ }
+@@ -4856,7 +4877,8 @@ errno_t sysdb_search_object_by_cert(TALLOC_CTX *mem_ctx,
+                                     struct ldb_result **res)
+ {
+     int ret;
+-    char *user_filter;
++    char *user_filter = NULL;
++    char *filter = NULL;
+ 
+     ret = sss_cert_derb64_to_ldap_filter(mem_ctx, cert, SYSDB_USER_MAPPED_CERT,
+                                          NULL, NULL, &user_filter);
+@@ -4865,10 +4887,15 @@ errno_t sysdb_search_object_by_cert(TALLOC_CTX *mem_ctx,
+         return ret;
+     }
+ 
+-    ret = sysdb_search_object_by_str_attr(mem_ctx, domain,
+-                                          SYSDB_USER_CERT_FILTER,
+-                                          user_filter, attrs, false, res);
++    filter = talloc_asprintf(NULL, SYSDB_USER_CERT_FILTER, user_filter);
+     talloc_free(user_filter);
++    if (filter == NULL) {
++        return ENOMEM;
++    }
++
++    ret = sysdb_search_object_attr(mem_ctx, domain, filter, attrs, false, res);
++
++    talloc_free(filter);
+ 
+     return ret;
+ }
+diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c
+index 6ec82ce4ca5c4f918bc9f3144c21f33b270ea47e..588eb9ef02033ec061b4187964fe562da84e86c8 100644
+--- a/src/tests/sysdb-tests.c
++++ b/src/tests/sysdb-tests.c
+@@ -6444,6 +6444,13 @@ START_TEST(test_upn_basic)
+     fail_unless(strcmp(str, UPN_PRINC) == 0,
+                 "Expected [%s], got [%s].", UPN_PRINC, str);
+ 
++    /* check if input is sanitized */
++    ret = sysdb_search_user_by_upn(test_ctx, test_ctx->domain, false,
++                                   "abc@def.ghi)(name="UPN_USER_NAME")(abc=xyz",
++                                   NULL, &msg);
++    fail_unless(ret == ENOENT,
++                "sysdb_search_user_by_upn failed with un-sanitized input.");
++
+     talloc_free(test_ctx);
+ }
+ END_TEST
+-- 
+2.13.5
+
diff --git a/SOURCES/0198-ipa-make-sure-view-name-is-initialized-at-startup.patch b/SOURCES/0198-ipa-make-sure-view-name-is-initialized-at-startup.patch
new file mode 100644
index 0000000..25422d6
--- /dev/null
+++ b/SOURCES/0198-ipa-make-sure-view-name-is-initialized-at-startup.patch
@@ -0,0 +1,60 @@
+From 2d39f46386fb36b5a68f41644ce22c15bf6ccb67 Mon Sep 17 00:00:00 2001
+From: Sumit Bose <sbose@redhat.com>
+Date: Thu, 31 Aug 2017 22:30:25 +0200
+Subject: [PATCH 198/199] ipa: make sure view name is initialized at startup
+
+sysdb_master_domain_update() can only set the view name properly if it was not
+set before but it might be called multiple times before the view name is
+available if the cache is empty. Since ipa_apply_view() keeps track if
+the view name was already set at startup or not the name can safely be
+cleaned here before sysdb_master_domain_update() is called.
+
+Resolves:
+https://pagure.io/SSSD/sssd/issue/3501
+
+Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
+(cherry picked from commit f00591a4615720640cf01b1c408315b57dd397dc)
+---
+ src/providers/ipa/ipa_subdomains.c | 19 ++++++++++++++++++-
+ 1 file changed, 18 insertions(+), 1 deletion(-)
+
+diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
+index 6f0ff50bde234f72d62f43635d9a787316c78430..0cb4d405e45689e9548ad3652e7260f2265bd1fe 100644
+--- a/src/providers/ipa/ipa_subdomains.c
++++ b/src/providers/ipa/ipa_subdomains.c
+@@ -739,6 +739,18 @@ done:
+     return ret;
+ }
+ 
++static void clean_view_name(struct sss_domain_info *domain)
++{
++    struct sss_domain_info *dom = domain;
++
++    while (dom) {
++        dom->has_views = false;
++        talloc_free(discard_const(dom->view_name));
++        dom->view_name = NULL;
++        dom = get_next_domain(dom, SSS_GND_DESCEND);
++    }
++}
++
+ static errno_t ipa_apply_view(struct sss_domain_info *domain,
+                               struct ipa_id_ctx *ipa_id_ctx,
+                               const char *view_name,
+@@ -831,7 +843,12 @@ static errno_t ipa_apply_view(struct sss_domain_info *domain,
+     }
+ 
+     if (!read_at_init) {
+-        /* refresh view data of all domains at startup */
++        /* refresh view data of all domains at startup, since
++         * sysdb_master_domain_update and sysdb_update_subdomains might have
++         * been called earlier without the proper view name the name is
++         * cleaned here before the calls. This is acceptable because this is
++         * the initial setup (!read_at_init).  */
++        clean_view_name(domain);
+         ret = sysdb_master_domain_update(domain);
+         if (ret != EOK) {
+             DEBUG(SSSDBG_OP_FAILURE, "sysdb_master_domain_update failed "
+-- 
+2.13.5
+
diff --git a/SOURCES/0199-CACHE_REQ-Copy-the-cr_domain-list-for-each-request.patch b/SOURCES/0199-CACHE_REQ-Copy-the-cr_domain-list-for-each-request.patch
new file mode 100644
index 0000000..ba0c504
--- /dev/null
+++ b/SOURCES/0199-CACHE_REQ-Copy-the-cr_domain-list-for-each-request.patch
@@ -0,0 +1,142 @@
+From a1634a3c4b977364fd7612efa3ee21872a8d578e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
+Date: Fri, 20 Oct 2017 09:26:43 +0200
+Subject: [PATCH 199/199] CACHE_REQ: Copy the cr_domain list for each request
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Let's copy the cr_domain list for each request as this list may be
+free'd due to a refresh domains request.
+
+Resolves: https://pagure.io/SSSD/sssd/issue/3551
+
+Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
+
+Reviewed-by: Pavel Březina <pbrezina@redhat.com>
+(cherry picked from commit 0f44eefe2ce75a0814c8688495477f6c57f3d39a)
+---
+ src/responder/common/cache_req/cache_req.c        | 14 +++++++--
+ src/responder/common/cache_req/cache_req_domain.c | 38 +++++++++++++++++++++++
+ src/responder/common/cache_req/cache_req_domain.h |  5 +++
+ 3 files changed, 55 insertions(+), 2 deletions(-)
+
+diff --git a/src/responder/common/cache_req/cache_req.c b/src/responder/common/cache_req/cache_req.c
+index 7d77eb7dd72a7ccf3d687eee8f746ab84176b487..83eab8ed2de0b5c7d25306d853aadc9b53cb4842 100644
+--- a/src/responder/common/cache_req/cache_req.c
++++ b/src/responder/common/cache_req/cache_req.c
+@@ -688,6 +688,7 @@ struct cache_req_state {
+     const char *domain_name;
+ 
+     /* work data */
++    struct cache_req_domain *cr_domains;
+     struct cache_req_result **results;
+     size_t num_results;
+     bool first_iteration;
+@@ -940,6 +941,7 @@ static errno_t cache_req_select_domains(struct tevent_req *req,
+     bool bypass_cache;
+     bool bypass_dp;
+     bool search;
++    errno_t ret;
+ 
+     state = tevent_req_data(req, struct cache_req_state);
+ 
+@@ -951,12 +953,20 @@ static errno_t cache_req_select_domains(struct tevent_req *req,
+         return EOK;
+     }
+ 
++    ret = cache_req_domain_copy_cr_domains(state,
++                                           state->cr->rctx->cr_domains,
++                                           &state->cr_domains);
++    if (ret != EOK) {
++        DEBUG(SSSDBG_CRIT_FAILURE, "cache_req_copy_cr_domains() failed\n");
++        return EINVAL;
++    }
++
+     if (domain_name != NULL) {
+         CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr,
+                         "Performing a single domain search\n");
+ 
+         cr_domain = cache_req_domain_get_domain_by_name(
+-                                    state->cr->rctx->cr_domains, domain_name);
++                                    state->cr_domains, domain_name);
+         if (cr_domain == NULL) {
+             return ERR_DOMAIN_NOT_FOUND;
+         }
+@@ -965,7 +975,7 @@ static errno_t cache_req_select_domains(struct tevent_req *req,
+         CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr,
+                         "Performing a multi-domain search\n");
+ 
+-        cr_domain = state->cr->rctx->cr_domains;
++        cr_domain = state->cr_domains;
+         check_next = true;
+     }
+ 
+diff --git a/src/responder/common/cache_req/cache_req_domain.c b/src/responder/common/cache_req/cache_req_domain.c
+index c2b5abb74f3bd3d5055f29a4523f29b05feb2014..8c9f155303b174f16b884eb66ba1c88a0256719d 100644
+--- a/src/responder/common/cache_req/cache_req_domain.c
++++ b/src/responder/common/cache_req/cache_req_domain.c
+@@ -47,6 +47,44 @@ cache_req_domain_get_domain_by_name(struct cache_req_domain *domains,
+     return ret;
+ }
+ 
++errno_t
++cache_req_domain_copy_cr_domains(TALLOC_CTX *mem_ctx,
++                                 struct cache_req_domain *src,
++                                 struct cache_req_domain **_dest)
++{
++    struct cache_req_domain *cr_domains = NULL;
++    struct cache_req_domain *cr_domain;
++    struct cache_req_domain *iter;
++    errno_t ret;
++
++    if (src == NULL) {
++        return EINVAL;
++    }
++
++    DLIST_FOR_EACH(iter, src) {
++        cr_domain = talloc_zero(mem_ctx, struct cache_req_domain);
++        if (cr_domain == NULL) {
++            ret = ENOMEM;
++            goto done;
++        }
++
++        cr_domain->domain = iter->domain;
++        cr_domain->fqnames = iter->fqnames;
++
++        DLIST_ADD_END(cr_domains, cr_domain, struct cache_req_domain *);
++    }
++
++    *_dest = cr_domains;
++    ret = EOK;
++
++done:
++    if (ret != EOK) {
++        cache_req_domain_list_zfree(&cr_domains);
++    }
++
++    return ret;
++}
++
+ void cache_req_domain_list_zfree(struct cache_req_domain **cr_domains)
+ {
+     struct cache_req_domain *p, *q, *r;
+diff --git a/src/responder/common/cache_req/cache_req_domain.h b/src/responder/common/cache_req/cache_req_domain.h
+index 3780a5d8d88d76e100738d28d1dd0e697edf5eae..ebdc71dd635d5d8a5d06e30e96c5d4101b6d98bf 100644
+--- a/src/responder/common/cache_req/cache_req_domain.h
++++ b/src/responder/common/cache_req/cache_req_domain.h
+@@ -50,6 +50,11 @@ cache_req_domain_new_list_from_domain_resolution_order(
+                                         const char *domain_resolution_order,
+                                         struct cache_req_domain **_cr_domains);
+ 
++errno_t
++cache_req_domain_copy_cr_domains(TALLOC_CTX *mem_ctx,
++                                 struct cache_req_domain *src,
++                                 struct cache_req_domain **_dest);
++
+ void cache_req_domain_list_zfree(struct cache_req_domain **cr_domains);
+ 
+ 
+-- 
+2.13.5
+
diff --git a/SPECS/sssd.spec b/SPECS/sssd.spec
index af001cd..b6134a5 100644
--- a/SPECS/sssd.spec
+++ b/SPECS/sssd.spec
@@ -40,7 +40,7 @@
 
 Name: sssd
 Version: 1.15.2
-Release: 50%{?dist}.6
+Release: 50%{?dist}.8
 Group: Applications/System
 Summary: System Security Services Daemon
 License: GPLv3+
@@ -244,6 +244,10 @@ Patch0192: 0192-libwbclient-Change-return-code-for-wbcAuthenticateUs.patch
 Patch0193: 0193-IPA-fix-handling-of-certmap_ctx.patch
 Patch0194: 0194-certmap-make-sure-eku_oid_list-is-always-allocated.patch
 Patch0195: 0195-cache_req-Look-for-name-attribute-also-in-nss_cmd_ge.patch
+Patch0196: 0196-sssd_client-add-mutex-protected-call-to-the-PAC-resp.patch
+Patch0197: 0197-sysdb-sanitize-search-filter-input.patch
+Patch0198: 0198-ipa-make-sure-view-name-is-initialized-at-startup.patch
+Patch0199: 0199-CACHE_REQ-Copy-the-cr_domain-list-for-each-request.patch
 
 #This patch should not be removed in RHEL-7
 Patch999: 0999-NOUPSTREAM-Default-to-root-if-sssd-user-is-not-spec
@@ -340,6 +344,9 @@ License: GPLv3+
 # Conflicts
 Conflicts: selinux-policy < 3.10.0-46
 Conflicts: sssd < 1.10.0-8%{?dist}.beta2
+# Due to ABI changes in rhel-7,5 (1.1.30/1.2.0)
+# rhel-7.4 <= will never have libldb 1.2.0 due to samba-4.6.x
+Conflicts: libldb >= 1.1.30
 # Requires
 Requires: sssd-client%{?_isa} = %{version}-%{release}
 Requires: libsss_idmap%{?_isa} = %{version}-%{release}
@@ -1380,6 +1387,21 @@ fi
 }
 
 %changelog
+* Fri Nov 03 2017 Fabiano Fidêncio <fidencio@redhat.com> - 1.15.2-50.8
+- Resolves: rhbz#1508972 - Accessing IdM kerberos ticket fails while id
+                           mapping is applied [rhel-7.4.z]
+- Resolves: rhbz#1509177 - Race condition between refreshing the cr_domain
+                           list and a request that is using the list can
+                           cause a segfault is sssd_nss [rhel-7.4.z]
+
+* Fri Oct 27 2017 Fabiano Fidêncio <fidencio@redhat.com> - 1.15.2-50.7
+- Resolves: rhbz#1506142 - SSSD can crash due to ABI changes in
+                           libldb >= 1.2.0 (1.1.30) [rhel-7.4.z]
+- Resolves: rhbz#1506682 - sssd_client: add mutex protected call to the
+                           PAC responder [rhel-7.4.z]
+- Resolves: rhbz#1499658 - CVE-2017-12173 sssd: unsanitized input when
+                           searching in local cache database [rhel-7.4.z]
+
 * Wed Sep 27 2017 Fabiano Fidêncio <fidencio@redhat.com> - 1.15.2-50.6
 - Add a patch that was missed in 1.15.2-50.4
 - Related: rhbz#1489290 - samba shares with sssd authentication broken