diff --git a/SOURCES/sudo-1.8.6p3-authinterrupt.patch b/SOURCES/sudo-1.8.6p3-authinterrupt.patch
new file mode 100644
index 0000000..18923d4
--- /dev/null
+++ b/SOURCES/sudo-1.8.6p3-authinterrupt.patch
@@ -0,0 +1,26 @@
+diff -up sudo-1.8.6p3/plugins/sudoers/auth/pam.c.authinterrupt sudo-1.8.6p3/plugins/sudoers/auth/pam.c
+--- sudo-1.8.6p3/plugins/sudoers/auth/pam.c.authinterrupt	2014-05-22 13:46:31.204706184 +0200
++++ sudo-1.8.6p3/plugins/sudoers/auth/pam.c	2014-05-22 13:47:06.729830043 +0200
+@@ -167,13 +167,13 @@ sudo_pam_verify(struct passwd *pw, char
+ 	    /* FALLTHROUGH */
+ 	case PAM_AUTH_ERR:
+ 	case PAM_AUTHINFO_UNAVAIL:
++	case PAM_PERM_DENIED:
+ 	    if (getpass_error) {
+ 		/* error or ^C from tgetpass() */
+ 		debug_return_int(AUTH_INTR);
+ 	    }
+ 	    /* FALLTHROUGH */
+ 	case PAM_MAXTRIES:
+-	case PAM_PERM_DENIED:
+ 	    debug_return_int(AUTH_FAILURE);
+ 	default:
+ 	    if ((s = pam_strerror(pamh, *pam_status)))
+@@ -343,6 +343,7 @@ converse(int num_msg, PAM_CONST struct p
+ 		if (pass == NULL) {
+ 		    /* Error (or ^C) reading password, don't try again. */
+ 		    getpass_error = 1;
++		    ret = PAM_CONV_ERR;
+ #if (defined(__darwin__) || defined(__APPLE__)) && !defined(OPENPAM_VERSION)
+ 		    pass = "";
+ #else
diff --git a/SOURCES/sudo-1.8.6p3-doublequotefix.patch b/SOURCES/sudo-1.8.6p3-doublequotefix.patch
new file mode 100644
index 0000000..4ac2d50
--- /dev/null
+++ b/SOURCES/sudo-1.8.6p3-doublequotefix.patch
@@ -0,0 +1,24 @@
+diff -up sudo-1.8.6p3/plugins/sudoers/toke.c.doublequotefix sudo-1.8.6p3/plugins/sudoers/toke.c
+--- sudo-1.8.6p3/plugins/sudoers/toke.c.doublequotefix	2014-05-19 14:28:27.536399410 +0200
++++ sudo-1.8.6p3/plugins/sudoers/toke.c	2014-05-19 14:29:51.084714355 +0200
+@@ -1851,7 +1851,7 @@ YY_RULE_SETUP
+ 				LEXTRACE("ERROR "); /* empty string */
+ 				LEXRETURN(ERROR);
+ 			    }
+-			    if (prev_state == INITIAL) {
++			    if (prev_state == INITIAL || prev_state == GOTDEFS) {
+ 				switch (yylval.string[0]) {
+ 				case '%':
+ 				    if (yylval.string[1] == '\0' ||
+diff -up sudo-1.8.6p3/plugins/sudoers/toke.l.doublequotefix sudo-1.8.6p3/plugins/sudoers/toke.l
+--- sudo-1.8.6p3/plugins/sudoers/toke.l.doublequotefix	2014-05-19 14:28:36.932438977 +0200
++++ sudo-1.8.6p3/plugins/sudoers/toke.l	2014-05-19 14:29:27.769626995 +0200
+@@ -197,7 +197,7 @@ DEFVAR			[a-z_]+
+ 				LEXTRACE("ERROR "); /* empty string */
+ 				LEXRETURN(ERROR);
+ 			    }
+-			    if (prev_state == INITIAL) {
++			    if (prev_state == INITIAL || prev_state == GOTDEFS) {
+ 				switch (yylval.string[0]) {
+ 				case '%':
+ 				    if (yylval.string[1] == '\0' ||
diff --git a/SOURCES/sudo-1.8.6p3-netgrfilterfix.patch b/SOURCES/sudo-1.8.6p3-netgrfilterfix.patch
new file mode 100644
index 0000000..0118511
--- /dev/null
+++ b/SOURCES/sudo-1.8.6p3-netgrfilterfix.patch
@@ -0,0 +1,92 @@
+diff -up sudo-1.8.6p3/plugins/sudoers/sssd.c.netgrfilterfix sudo-1.8.6p3/plugins/sudoers/sssd.c
+--- sudo-1.8.6p3/plugins/sudoers/sssd.c.netgrfilterfix	2014-07-30 13:29:47.713823996 +0200
++++ sudo-1.8.6p3/plugins/sudoers/sssd.c	2014-07-30 13:30:08.917436088 +0200
+@@ -614,16 +615,13 @@ sudo_sss_check_host(struct sudo_sss_hand
+ }
+ 
+ /*
+- * Look for netgroup specifcations in the sudoUser attribute and
+- * if found, filter according to netgroup membership.
+- *  returns:
+- *   true -> netgroup spec found && negroup member
+- *  false -> netgroup spec found && not a meber of netgroup
+- *   true -> netgroup spec not found (filtered by SSSD already, netgroups are an exception)
++ * SSSD doesn't handle netgroups, we have to ensure they are correctly filtered
++ * in sudo. The rules may contain mixed sudoUser specification so we have to check
++ * not only for netgroup membership but also for user and group matches.
+  */
+-bool sudo_sss_filter_user_netgroup(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
++bool sudo_sss_filter_sudoUser(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
+ {
+-	bool ret = false, netgroup_spec_found = false;
++	bool ret = false;
+ 	char **val_array, *val;
+ 	int i;
+ 	debug_decl(sudo_sss_check_user_netgroup, SUDO_DEBUG_SSSD);
+@@ -641,21 +639,48 @@ bool sudo_sss_filter_user_netgroup(struc
+ 			sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_get_values(sudoUser): != 0");
+ 			debug_return_bool(ret);
+ 	}
+-
++	/*
++	 * Scan sudoUser values and look for netgroup specs.
++	 * Netgroup-only rule specification should be filtered
++	 * out if the user isn't member of any specified netgroup.
++	 */
+ 	for (i = 0; val_array[i] != NULL && !ret; ++i) {
+ 		val = val_array[i];
+-		if (*val == '+') {
+-			netgroup_spec_found = true;
+-		}
+ 		sudo_debug_printf(SUDO_DEBUG_DEBUG, "val[%d]=%s", i, val);
+-		if (strcmp(val, "ALL") == 0 || netgr_matches(val, NULL, NULL, user_name)) {
+-			ret = true;
+-			sudo_debug_printf(SUDO_DEBUG_DIAG,
+-			                  "sssd/ldap sudoUser '%s' ... MATCH! (%s)", val, user_name);
++		if (*val == '+') {
++			/* Netgroup spec found, check netgroup membership */
++			if (netgr_matches(val, NULL, NULL, handle->pw->pw_name)) {
++				ret = true;
++				sudo_debug_printf(SUDO_DEBUG_DIAG,
++						  "sssd/ldap sudoUser '%s' ... MATCH! (%s)", val, handle->pw->pw_name);
++			}
++		} else {
++			/*
++			 * Non-netgroup sudoUser value
++			 */
++			if (strcmp(val, "ALL") == 0) {
++				ret = true;
++			} else {
++				const char *match_val = (*val == '!' ? val + 1 : val);
++				const bool negated = (*val == '!' ? true : false);
++				const bool group_spec = (*match_val == '%' ? true : false);
++
++				if (group_spec) {
++					if (usergr_matches(match_val,
++							   handle->pw->pw_name, handle->pw)) {
++						ret = !negated;
++					}
++				} else {
++					if (userpw_matches(match_val,
++							   handle->pw->pw_name, handle->pw)) {
++						ret = !negated;
++					}
++				}
++			}
+ 		}
+ 	}
+ 	handle->fn_free_values(val_array);
+-	debug_return_bool(netgroup_spec_found ? ret : true);
++	debug_return_bool(ret);
+ }
+ 
+ static int
+@@ -666,7 +691,7 @@ sudo_sss_result_filterp(struct sudo_sss_
+     debug_decl(sudo_sss_result_filterp, SUDO_DEBUG_SSSD);
+ 
+     if (sudo_sss_check_host(handle, rule) &&
+-        sudo_sss_filter_user_netgroup(handle, rule))
++        sudo_sss_filter_sudoUser(handle, rule))
+ 	debug_return_int(1);
+     else
+ 	debug_return_int(0);
diff --git a/SOURCES/sudo-1.8.6p3-nonehostname.patch b/SOURCES/sudo-1.8.6p3-nonehostname.patch
new file mode 100644
index 0000000..5e170d2
--- /dev/null
+++ b/SOURCES/sudo-1.8.6p3-nonehostname.patch
@@ -0,0 +1,13 @@
+diff -up sudo-1.8.6p3/plugins/sudoers/match.c.nonehostname sudo-1.8.6p3/plugins/sudoers/match.c
+--- sudo-1.8.6p3/plugins/sudoers/match.c.nonehostname	2014-05-19 12:50:08.412313041 +0200
++++ sudo-1.8.6p3/plugins/sudoers/match.c	2014-05-19 12:50:17.787348134 +0200
+@@ -727,7 +727,8 @@ netgr_matches(char *netgr, char *lhost,
+     /* get the domain name (if any) */
+     if (!initialized) {
+ 	domain = (char *) emalloc(MAXHOSTNAMELEN + 1);
+-	if (getdomainname(domain, MAXHOSTNAMELEN + 1) == -1 || *domain == '\0') {
++	if (getdomainname(domain, MAXHOSTNAMELEN + 1) == -1 || *domain == '\0'
++	    || strncmp (domain, "(none)", 7) == 0) {
+ 	    efree(domain);
+ 	    domain = NULL;
+ 	}
diff --git a/SOURCES/sudo-1.8.6p3-sssdrulenames.patch b/SOURCES/sudo-1.8.6p3-sssdrulenames.patch
new file mode 100644
index 0000000..84081d1
--- /dev/null
+++ b/SOURCES/sudo-1.8.6p3-sssdrulenames.patch
@@ -0,0 +1,22 @@
+diff -up sudo-1.8.6p3/plugins/sudoers/sssd.c.rulenames sudo-1.8.6p3/plugins/sudoers/sssd.c
+--- sudo-1.8.6p3/plugins/sudoers/sssd.c.rulenames	2014-05-21 12:33:21.000768420 +0200
++++ sudo-1.8.6p3/plugins/sudoers/sssd.c	2014-05-21 12:38:13.779864718 +0200
+@@ -1180,6 +1180,18 @@ sudo_sss_display_entry_long(struct sudo_
+     int count = 0, i;
+     debug_decl(sudo_sss_display_entry_long, SUDO_DEBUG_SSSD);
+ 
++    switch(handle->fn_get_values(rule, "cn", &val_array)) {
++    case 0:
++	if (val_array[0]) {
++	    lbuf_append(lbuf, _("\nSSSD Role: %s\n"), val_array[0]);
++	}
++	handle->fn_free_values(val_array);
++	val_array = NULL;
++	break;
++    default:
++	lbuf_append(lbuf, _("\nSSSD Role: UNKNOWN\n"));
++    }
++
+     /* get the RunAsUser Values from the entry */
+     lbuf_append(lbuf, "    RunAsUsers: ");
+     switch (handle->fn_get_values(rule, "sudoRunAsUser", &val_array)) {
diff --git a/SOURCES/sudo-1.8.6p7-clangfixes.patch b/SOURCES/sudo-1.8.6p7-clangfixes.patch
new file mode 100644
index 0000000..70d9aff
--- /dev/null
+++ b/SOURCES/sudo-1.8.6p7-clangfixes.patch
@@ -0,0 +1,46 @@
+diff -up sudo-1.8.6p7/plugins/sudoers/sssd.c.clangfixes sudo-1.8.6p7/plugins/sudoers/sssd.c
+--- sudo-1.8.6p7/plugins/sudoers/sssd.c.clangfixes	2014-09-30 10:31:43.920885432 +0200
++++ sudo-1.8.6p7/plugins/sudoers/sssd.c	2014-09-30 10:32:39.413228871 +0200
+@@ -313,9 +313,9 @@ static int sudo_sss_close(struct sudo_ns
+     if (nss && nss->handle) {
+ 	handle = nss->handle;
+ 	dlclose(handle->ssslib);
++	efree(nss->handle);
+     }
+ 
+-    efree(nss->handle);
+     debug_return_int(0);
+ }
+ 
+@@ -755,12 +755,15 @@ sudo_sss_result_get(struct sudo_nss *nss
+ 		*state |= _SUDO_SSS_STATE_HOSTMATCH;
+ 	    }
+ 	}
++	sudo_debug_printf(SUDO_DEBUG_DEBUG,
++	    "u_sss_result=(%p, %u) => f_sss_result=(%p, %u)", u_sss_result,
++	    u_sss_result->num_rules, f_sss_result, f_sss_result->num_rules);
++    } else {
++	sudo_debug_printf(SUDO_DEBUG_DEBUG,
++	    "u_sss_result=(%p, %u) => f_sss_result=NULL", u_sss_result,
++	    u_sss_result->num_rules);
+     }
+ 
+-    sudo_debug_printf(SUDO_DEBUG_DEBUG,
+-	"u_sss_result=(%p, %u) => f_sss_result=(%p, %u)", u_sss_result,
+-	u_sss_result->num_rules, f_sss_result, f_sss_result->num_rules);
+-
+     handle->fn_free_result(u_sss_result);
+ 
+     debug_return_ptr(f_sss_result);
+diff -up sudo-1.8.6p7/plugins/sudoers/visudo.c.clangfixes sudo-1.8.6p7/plugins/sudoers/visudo.c
+--- sudo-1.8.6p7/plugins/sudoers/visudo.c.clangfixes	2014-09-30 10:34:08.689174020 +0200
++++ sudo-1.8.6p7/plugins/sudoers/visudo.c	2014-09-30 11:00:15.215654285 +0200
+@@ -544,7 +544,7 @@ reparse_sudoers(char *editor, char *args
+ 		    continue;
+ 	    edit_sudoers(sp, editor, args, errorlineno);
+ 	}
+-    } while (parse_error);
++    } while (parse_error && sp != NULL);
+ 
+     debug_return;
+ }
diff --git a/SOURCES/sudo-1.8.6p7-constwarnfix.patch b/SOURCES/sudo-1.8.6p7-constwarnfix.patch
new file mode 100644
index 0000000..5e3a6f6
--- /dev/null
+++ b/SOURCES/sudo-1.8.6p7-constwarnfix.patch
@@ -0,0 +1,104 @@
+diff -up sudo-1.8.6p7/plugins/sudoers/match.c.constwarnfix sudo-1.8.6p7/plugins/sudoers/match.c
+--- sudo-1.8.6p7/plugins/sudoers/match.c.constwarnfix	2014-09-29 15:55:50.996485025 +0200
++++ sudo-1.8.6p7/plugins/sudoers/match.c	2014-09-29 15:55:51.002484954 +0200
+@@ -599,7 +599,7 @@ command_matches_dir(char *sudoers_dir, s
+  * Returns true if the hostname matches the pattern, else false
+  */
+ bool
+-hostname_matches(char *shost, char *lhost, char *pattern)
++hostname_matches(const char *shost, const char *lhost, const char *pattern)
+ {
+     debug_decl(hostname_matches, SUDO_DEBUG_MATCH)
+ 
+@@ -621,7 +621,7 @@ hostname_matches(char *shost, char *lhos
+  *  else returns false.
+  */
+ bool
+-userpw_matches(char *sudoers_user, char *user, struct passwd *pw)
++userpw_matches(const char *sudoers_user, const char *user, const struct passwd *pw)
+ {
+ 	debug_decl(userpw_matches, SUDO_DEBUG_MATCH)
+ 	if (pw != NULL && *sudoers_user == '#') {
+@@ -640,7 +640,7 @@ userpw_matches(char *sudoers_user, char
+  *  else returns false.
+  */
+ bool
+-group_matches(char *sudoers_group, struct group *gr)
++group_matches(const char *sudoers_group, const struct group *gr)
+ {
+ 	debug_decl(group_matches, SUDO_DEBUG_MATCH)
+ 	if (*sudoers_group == '#') {
+@@ -659,7 +659,7 @@ group_matches(char *sudoers_group, struc
+  *  else returns false.
+  */
+ bool
+-usergr_matches(char *group, char *user, struct passwd *pw)
++usergr_matches(const char *group, const char *user, const struct passwd *pw)
+ {
+     int matched = false;
+     struct passwd *pw0 = NULL;
+@@ -707,7 +707,7 @@ done:
+  * XXX - swap order of host & shost
+  */
+ bool
+-netgr_matches(char *netgr, char *lhost, char *shost, char *user)
++netgr_matches(const char *netgr, const char *lhost, const char *shost, const char *user)
+ {
+     static char *domain;
+ #ifdef HAVE_GETDOMAINNAME
+diff -up sudo-1.8.6p7/plugins/sudoers/parse.h.constwarnfix sudo-1.8.6p7/plugins/sudoers/parse.h
+--- sudo-1.8.6p7/plugins/sudoers/parse.h.constwarnfix	2014-09-29 15:55:50.992485072 +0200
++++ sudo-1.8.6p7/plugins/sudoers/parse.h	2014-09-29 15:55:51.002484954 +0200
+@@ -188,11 +188,11 @@ bool addr_matches(char *n);
+ 
+ /* match.c */
+ bool command_matches(char *sudoers_cmnd, char *sudoers_args);
+-bool group_matches(char *sudoers_group, struct group *gr);
+-bool hostname_matches(char *shost, char *lhost, char *pattern);
+-bool netgr_matches(char *netgr, char *lhost, char *shost, char *user);
+-bool usergr_matches(char *group, char *user, struct passwd *pw);
+-bool userpw_matches(char *sudoers_user, char *user, struct passwd *pw);
++bool group_matches(const char *sudoers_group, const struct group *gr);
++bool hostname_matches(const char *shost, const char *lhost, const char *pattern);
++bool netgr_matches(const char *netgr, const char *lhost, const char *shost, const char *user);
++bool usergr_matches(const char *group, const char *user, const struct passwd *pw);
++bool userpw_matches(const char *sudoers_user, const char *user, const struct passwd *pw);
+ int cmnd_matches(struct member *m);
+ int cmndlist_matches(struct member_list *list);
+ int hostlist_matches(struct member_list *list);
+diff -up sudo-1.8.6p7/plugins/sudoers/pwutil.c.constwarnfix sudo-1.8.6p7/plugins/sudoers/pwutil.c
+--- sudo-1.8.6p7/plugins/sudoers/pwutil.c.constwarnfix	2013-02-25 20:42:44.000000000 +0100
++++ sudo-1.8.6p7/plugins/sudoers/pwutil.c	2014-09-29 15:55:51.003484942 +0200
+@@ -841,7 +841,7 @@ sudo_endgrent(void)
+ }
+ 
+ struct group_list *
+-sudo_get_grlist(struct passwd *pw)
++sudo_get_grlist(const struct passwd *pw)
+ {
+     struct cache_item key, *item;
+     struct rbnode *node;
+@@ -905,7 +905,7 @@ done:
+ }
+ 
+ bool
+-user_in_group(struct passwd *pw, const char *group)
++user_in_group(const struct passwd *pw, const char *group)
+ {
+     struct group_list *grlist;
+     struct group *grp = NULL;
+diff -up sudo-1.8.6p7/plugins/sudoers/sudoers.h.constwarnfix sudo-1.8.6p7/plugins/sudoers/sudoers.h
+--- sudo-1.8.6p7/plugins/sudoers/sudoers.h.constwarnfix	2013-02-25 20:49:09.000000000 +0100
++++ sudo-1.8.6p7/plugins/sudoers/sudoers.h	2014-09-29 15:55:51.003484942 +0200
+@@ -288,9 +288,9 @@ __dso_public struct group *sudo_getgrgid
+ __dso_public struct group *sudo_getgrnam(const char *);
+ __dso_public void sudo_gr_addref(struct group *);
+ __dso_public void sudo_gr_delref(struct group *);
+-bool user_in_group(struct passwd *, const char *);
++bool user_in_group(const struct passwd *, const char *);
+ struct group *sudo_fakegrnam(const char *);
+-struct group_list *sudo_get_grlist(struct passwd *pw);
++struct group_list *sudo_get_grlist(const struct passwd *pw);
+ struct passwd *sudo_fakepwnam(const char *, gid_t);
+ struct passwd *sudo_fakepwnamid(const char *user, uid_t uid, gid_t gid);
+ struct passwd *sudo_getpwnam(const char *);
diff --git a/SOURCES/sudo-1.8.6p7-duplicatenssfix.patch b/SOURCES/sudo-1.8.6p7-duplicatenssfix.patch
new file mode 100644
index 0000000..547eb41
--- /dev/null
+++ b/SOURCES/sudo-1.8.6p7-duplicatenssfix.patch
@@ -0,0 +1,47 @@
+diff -up sudo-1.8.6p7/plugins/sudoers/sudo_nss.c.duplicatenssfix sudo-1.8.6p7/plugins/sudoers/sudo_nss.c
+--- sudo-1.8.6p7/plugins/sudoers/sudo_nss.c.duplicatenssfix	2014-09-29 15:30:35.243303099 +0200
++++ sudo-1.8.6p7/plugins/sudoers/sudo_nss.c	2014-09-29 15:33:13.669439300 +0200
+@@ -88,16 +88,16 @@ sudo_read_nss(void)
+ 	for ((cp = strtok(cp + 8, " \t")); cp != NULL; (cp = strtok(NULL, " \t"))) {
+ 	    if (strcasecmp(cp, "files") == 0 && !saw_files) {
+ 		tq_append(&snl, &sudo_nss_file);
+-		got_match = true;
++		got_match = saw_files = true;
+ #ifdef HAVE_LDAP
+ 	    } else if (strcasecmp(cp, "ldap") == 0 && !saw_ldap) {
+ 		tq_append(&snl, &sudo_nss_ldap);
+-		got_match = true;
++		got_match = saw_ldap = true;
+ #endif
+ #ifdef HAVE_SSSD
+ 	    } else if (strcasecmp(cp, "sss") == 0 && !saw_sss) {
+ 		tq_append(&snl, &sudo_nss_sss);
+-		got_match = true;
++		got_match = saw_sss = true;
+ #endif
+ 	    } else if (strcasecmp(cp, "[NOTFOUND=return]") == 0 && got_match) {
+ 		/* NOTFOUND affects the most recent entry */
+@@ -171,20 +171,20 @@ sudo_read_nss(void)
+ 	    if (!saw_files && strncasecmp(cp, "files", 5) == 0 &&
+ 		(isspace((unsigned char)cp[5]) || cp[5] == '\0')) {
+ 		tq_append(&snl, &sudo_nss_file);
+-		got_match = true;
++		got_match = saw_files = true;
+ 		ep = &cp[5];
+ #ifdef HAVE_LDAP
+ 	    } else if (!saw_ldap && strncasecmp(cp, "ldap", 4) == 0 &&
+ 		(isspace((unsigned char)cp[4]) || cp[4] == '\0')) {
+ 		tq_append(&snl, &sudo_nss_ldap);
+-		got_match = true;
++		got_match = saw_ldap = true;
+ 		ep = &cp[4];
+ #endif
+ #ifdef HAVE_SSSD
+ 	    } else if (!saw_sss && strncasecmp(cp, "sss", 3) == 0 &&
+ 		(isspace((unsigned char)cp[3]) || cp[3] == '\0')) {
+ 		tq_append(&snl, &sudo_nss_sss);
+-		got_match = true;
++		got_match = saw_sss = true;
+ 		ep = &cp[3];
+ #endif
+ 	    } else {
diff --git a/SOURCES/sudo-1.8.6p7-ipahostname.patch b/SOURCES/sudo-1.8.6p7-ipahostname.patch
new file mode 100644
index 0000000..c17b78b
--- /dev/null
+++ b/SOURCES/sudo-1.8.6p7-ipahostname.patch
@@ -0,0 +1,192 @@
+diff -up sudo-1.8.6p7/configure.in.ipahostname sudo-1.8.6p7/configure.in
+--- sudo-1.8.6p7/configure.in.ipahostname	2014-09-29 11:14:38.393846226 +0200
++++ sudo-1.8.6p7/configure.in	2014-09-29 11:14:38.428845807 +0200
+@@ -309,7 +309,7 @@ dnl Handle SSSD support.
+ dnl
+ AC_ARG_WITH(sssd, [AS_HELP_STRING([--with-sssd], [enable SSSD support])],
+ [case $with_sssd in
+-    yes)	SUDOERS_OBJS="${SUDOERS_OBJS} sssd.lo"
++    yes)	SUDOERS_OBJS="${SUDOERS_OBJS} sssd.lo ipa_hostname.lo"
+ 		AC_DEFINE(HAVE_SSSD)
+ 		;;
+     no)		;;
+diff -up sudo-1.8.6p7/plugins/sudoers/ipa_hostname.c.ipahostname sudo-1.8.6p7/plugins/sudoers/ipa_hostname.c
+--- sudo-1.8.6p7/plugins/sudoers/ipa_hostname.c.ipahostname	2014-09-29 11:14:38.429845795 +0200
++++ sudo-1.8.6p7/plugins/sudoers/ipa_hostname.c	2014-09-29 11:14:38.429845795 +0200
+@@ -0,0 +1,88 @@
++/*
++ * Copyright 2013 Red Hat Inc., Durham, North Carolina.
++ * All Rights Reserved.
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
++ * Authors:
++ *      Daniel Kopecek <dkopecek@redhat.com>
++ */
++#define _GNU_SOURCE
++#include <stdio.h>
++#include <stdlib.h>
++#include <resolv.h>
++#include <string.h>
++#include <ctype.h>
++
++static const char *sssd_conf_path = "/etc/sssd/sssd.conf";
++
++char *ipa_hostname(void)
++{
++	static char hname[MAXHOSTNAMELEN+1];
++	size_t hname_len = 0;
++	char *line = NULL;
++	ssize_t line_len = 0;
++	size_t line_buflen = 0;
++	FILE *fp;
++
++	if ((fp = fopen(sssd_conf_path, "r")) == NULL)
++		return NULL;
++	while ((line_len = getline(&line, &line_buflen, fp)) > 0) {
++		char *keyword_loc;
++		if ((keyword_loc = strstr(line, "ipa_hostname")) != NULL) {
++			size_t i;
++			char *value_loc;
++			size_t value_len;
++
++			value_loc = keyword_loc + strlen("ipa_hostname") + 1;
++			value_len = line_len - (size_t)(value_loc - line);
++
++			/* Skip spaces and the assignment operator */
++			for (i = 0; i < value_len; ++i) {
++				if (isspace(value_loc[i]) || value_loc[i] == '=') {
++					continue;
++				} else {
++					break;
++				}
++			}
++
++			value_loc += i;
++			value_len -= i;
++
++			if (value_len <= MAXHOSTNAMELEN) {
++				memcpy(hname, value_loc, value_len * sizeof(char));
++				free(line);
++				fclose(fp);
++				hname_len = value_len;
++				hname[hname_len] = '\0';
++				/* Remove spaces from the end of the string */
++				for (i = hname_len - 1; i > 0; --i) {
++					if (isspace(hname[i])) {
++						hname[i] = '\0';
++						--hname_len;
++					} else {
++						break;
++					}
++				}
++				return hname;
++			}
++		}
++		free(line);
++		line = NULL;
++	}
++
++	fclose(fp);
++	return NULL;
++}
+diff -up sudo-1.8.6p7/plugins/sudoers/ipa_hostname.h.ipahostname sudo-1.8.6p7/plugins/sudoers/ipa_hostname.h
+--- sudo-1.8.6p7/plugins/sudoers/ipa_hostname.h.ipahostname	2014-09-29 11:14:38.429845795 +0200
++++ sudo-1.8.6p7/plugins/sudoers/ipa_hostname.h	2014-09-29 11:14:38.429845795 +0200
+@@ -0,0 +1,27 @@
++/*
++ * Copyright 2013 Red Hat Inc., Durham, North Carolina.
++ * All Rights Reserved.
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * This library 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
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with this library; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
++ * Authors:
++ *      Daniel Kopecek <dkopecek@redhat.com>
++ */
++#ifndef _IPA_HOSTNAME_H_
++#define _IPA_HOSTNAME_H_
++
++char *ipa_hostname(void);
++
++#endif /* _IPA_HOSTNAME_H_ */
+diff -up sudo-1.8.6p7/plugins/sudoers/Makefile.in.ipahostname sudo-1.8.6p7/plugins/sudoers/Makefile.in
+--- sudo-1.8.6p7/plugins/sudoers/Makefile.in.ipahostname	2014-09-29 11:14:38.429845795 +0200
++++ sudo-1.8.6p7/plugins/sudoers/Makefile.in	2014-09-29 11:16:54.923210160 +0200
+@@ -728,6 +728,9 @@ sia.lo: $(authdir)/sia.c $(top_builddir)
+         $(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
+         $(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
+ 	$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(authdir)/sia.c
++ipa_hostname.lo: $(srcdir)/ipa_hostname.c $(srcdir)/ipa_hostname.h
++	$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/ipa_hostname.c
++
+ sssd.lo: $(srcdir)/sssd.c $(top_builddir)/config.h \
+          $(top_srcdir)/compat/dlfcn.h $(srcdir)/sudoers.h \
+          $(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
+diff -up sudo-1.8.6p7/plugins/sudoers/sssd.c.ipahostname sudo-1.8.6p7/plugins/sudoers/sssd.c
+--- sudo-1.8.6p7/plugins/sudoers/sssd.c.ipahostname	2014-09-29 11:14:38.424845855 +0200
++++ sudo-1.8.6p7/plugins/sudoers/sssd.c	2014-09-29 11:14:38.429845795 +0200
+@@ -60,6 +60,7 @@
+ #include "parse.h"
+ #include "lbuf.h"
+ #include "sudo_debug.h"
++#include "ipa_hostname.h"
+ 
+ /* SSSD <--> SUDO interface - do not change */
+ struct sss_sudo_attr {
+@@ -549,6 +550,24 @@ sudo_sss_check_runas(struct sudo_sss_han
+     debug_return_bool(ret);
+ }
+ 
++static bool sudo_sss_ipa_hostname_matches(const char *hostname_val)
++{
++	bool ret = false;
++	char *ipa_hostname_val;
++	debug_decl(sudo_sss_ipa_hostname_matches, SUDO_DEBUG_SSSD)
++
++	if ((ipa_hostname_val = ipa_hostname()) != NULL) {
++		ret = hostname_matches(ipa_hostname_val, ipa_hostname_val, hostname_val) || \
++		      netgr_matches(hostname_val, ipa_hostname_val, ipa_hostname_val, NULL);
++	}
++
++	sudo_debug_printf(SUDO_DEBUG_TRACE, "IPA hostname (%s) matches %s => %s",
++	                  ipa_hostname_val ? ipa_hostname_val : "<none>", hostname_val,
++	                  ret ? "true" : "false");
++
++	debug_return_bool(ret);
++}
++
+ static bool
+ sudo_sss_check_host(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
+ {
+@@ -580,6 +599,7 @@ sudo_sss_check_host(struct sudo_sss_hand
+ 
+ 	/* match any or address or netgroup or hostname */
+ 	if (!strcmp(val, "ALL") || addr_matches(val) ||
++	    sudo_sss_ipa_hostname_matches(val) ||
+ 	    netgr_matches(val, user_host, user_shost, NULL) ||
+ 	    hostname_matches(user_shost, user_host, val))
+ 	    ret = true;
diff --git a/SPECS/sudo.spec b/SPECS/sudo.spec
index cbde546..2884d13 100644
--- a/SPECS/sudo.spec
+++ b/SPECS/sudo.spec
@@ -1,7 +1,7 @@
 Summary: Allows restricted root access for specified users
 Name: sudo
 Version: 1.8.6p7
-Release: 11%{?dist}
+Release: 13%{?dist}
 License: ISC
 Group: Applications/System
 URL: http://www.courtesan.com/sudo/
@@ -69,6 +69,27 @@ Patch20: sudo-1.8.6p3-lbufexpandcode.patch
 Patch21: sudo-1.8.6p3-cycledetect.patch
 # 1065418 - -sesh replaces /path/to/myshell with /path/to-myshell instead of -myshell
 Patch22: sudo-1.8.6p7-sesh_loginshell.patch
+# 1084488 - sudo should use ipa_hostname in IPA backend when defined
+Patch23: sudo-1.8.6p7-ipahostname.patch
+# 1096813 - sudo does not handle the "(none)" string, when no domainname is set, which
+#           breaks when nscd is enabled
+Patch24: sudo-1.8.6p3-nonehostname.patch
+# 1092499 - Regression in sudo 1.8.6p3-7 package, double quotes are not accepted in sudoers
+Patch25: sudo-1.8.6p3-doublequotefix.patch
+# 1088464 - sudo -ll does not list the rule names when sssd is used.
+Patch26: sudo-1.8.6p3-sssdrulenames.patch
+# 1088825 - With sudo-1.8.6p3-12.el6.x86_64 version, If a sudo rules contains +netgroup
+#           in sudoUser attribute it result in access denied
+# 1147557 - sudo -U <user> listing shows incorrect list when sssd is used.
+Patch27: sudo-1.8.6p3-netgrfilterfix.patch
+# 1093099 - pam_faillock causes sudo to lock user when user aborts password prompt
+Patch28: sudo-1.8.6p3-authinterrupt.patch
+# 1147497 - duplicate sss module in nsswitch breaks sudo
+Patch29: sudo-1.8.6p7-duplicatenssfix.patch
+# Fix compiler warnings about discarting const qualifiers
+Patch30: sudo-1.8.6p7-constwarnfix.patch
+# 1147616 - New defect found in sudo-1.8.6p7-12.el7
+Patch31: sudo-1.8.6p7-clangfixes.patch
 
 %description
 Sudo (superuser do) allows a system administrator to give certain
@@ -115,6 +136,15 @@ plugins that use %{name}.
 %patch20 -p1 -b .lbufexpandcode
 %patch21 -p1 -b .cycledetect
 %patch22 -p1 -b .sesh_loginshell
+%patch23 -p1 -b .ipahostname
+%patch24 -p1 -b .nonehostname
+%patch25 -p1 -b .doublequotefix
+%patch26 -p1 -b .sssdrulenames
+%patch27 -p1 -b .netgrfilterfix
+%patch28 -p1 -b .authinterrupt
+%patch29 -p1 -b .duplicatenssfix
+%patch30 -p1 -b .constwarnfix
+%patch31 -p1 -b .clangfixes
 
 %build
 autoreconf -I m4 -fv --install
@@ -235,6 +265,30 @@ rm -rf $RPM_BUILD_ROOT
 %{_mandir}/man8/sudo_plugin.8*
 
 %changelog
+* Tue Sep 30 2014 Daniel Kopecek <dkopecek@redhat.com> - 1.8.6p7-13
+- RHEL 7.1 erratum
+  - fixed issues found by covscan/clang-analyzer
+  Resolves: rhbz#1147616
+
+* Mon Sep 29 2014 Daniel Kopecek <dkopecek@redhat.com> - 1.8.6p7-12
+- RHEL 7.1 erratum
+  - don't retry authentication when ctrl-c pressed
+  - fix double-quote processing in Defaults options
+  - handle the "(none)" hostname correctly
+  - SSSD: fix sudoUser netgroup specification filtering
+  - SSSD: list correct user when -U <user> -l specified
+  - SSSD: show rule names on long listing (-ll)
+  - fix infinite loop when duplicate entries are specified on the
+    sudoers nsswitch.conf line
+  Resolves: rhbz#1084488
+  Resolves: rhbz#1088464
+  Resolves: rhbz#1088825
+  Resolves: rhbz#1092499
+  Resolves: rhbz#1093099
+  Resolves: rhbz#1096813
+  Resolves: rhbz#1147497
+  Resolves: rhbz#1147557
+
 * Wed Feb 26 2014 Daniel Kopecek <dkopecek@redhat.com> - 1.8.6p7-11
 - Fixed incorrect login shell path construction in sesh
   (thanks fkrska@redhat.com for the patch)