[sudo] added patches that fix & improve SSSD support (thanks to pbrezina at redhat.com)

Daniel Kopeček mildew at fedoraproject.org
Thu Jul 26 07:33:12 UTC 2012


commit 049d9661dd94152389ae93e60e0a2a8e31937fbc
Author: Daniel Kopecek <dkopecek at redhat.com>
Date:   Thu Jul 26 09:32:44 2012 +0200

    added patches that fix & improve SSSD support (thanks to pbrezina at redhat.com)
    
    - re-enabled SSSD support
    - removed libsss_sudo dependency

 sudo-1.8.5-add-sssd-debug-subsystem.patch       |  290 ++++++++
 sudo-1.8.5-remove-source-when-open-failed.patch |   33 +
 sudo-1.8.5-sssd-dlopen-lib.patch                |  905 +++++++++++++++++++++++
 sudo-1.8.5-sssd-handle-sss_ret-correctly.patch  |   43 ++
 sudo-1.8.5-sssd-use-sudo_debug_printf.patch     |  600 +++++++++++++++
 sudo.spec                                       |   29 +-
 6 files changed, 1895 insertions(+), 5 deletions(-)
---
diff --git a/sudo-1.8.5-add-sssd-debug-subsystem.patch b/sudo-1.8.5-add-sssd-debug-subsystem.patch
new file mode 100644
index 0000000..2af83c3
--- /dev/null
+++ b/sudo-1.8.5-add-sssd-debug-subsystem.patch
@@ -0,0 +1,290 @@
+diff -rup original/common/sudo_debug.c new/common/sudo_debug.c
+--- original/common/sudo_debug.c	2012-05-15 18:22:01.000000000 +0200
++++ new/common/sudo_debug.c	2012-07-17 10:24:05.389397245 +0200
+@@ -101,6 +101,7 @@ const char *const sudo_debug_subsystems[
+     "perms",
+     "plugin",
+     "hooks",
++    "sssd",
+     NULL
+ };
+ 
+diff -rup original/include/sudo_debug.h new/include/sudo_debug.h
+--- original/include/sudo_debug.h	2012-05-15 18:22:02.000000000 +0200
++++ new/include/sudo_debug.h	2012-07-17 10:49:43.470809390 +0200
+@@ -71,6 +71,7 @@
+ #define SUDO_DEBUG_PERMS	(23<<6)	/* uid/gid swapping functions */
+ #define SUDO_DEBUG_PLUGIN	(24<<6)	/* main plugin functions */
+ #define SUDO_DEBUG_HOOKS	(25<<6)	/* hook functions */
++#define SUDO_DEBUG_SSSD		(26<<6) /* sudoers SSSD */
+ #define SUDO_DEBUG_ALL		0xfff0	/* all subsystems */
+ 
+ /* Flag to include string version of errno in debug info. */
+diff -rup original/plugins/sudoers/sssd.c new/plugins/sudoers/sssd.c
+--- original/plugins/sudoers/sssd.c	2012-07-17 10:13:42.366133003 +0200
++++ new/plugins/sudoers/sssd.c	2012-07-17 10:24:05.383397175 +0200
+@@ -86,7 +86,7 @@ static struct sss_sudo_result *sudo_sss_
+ static void sudo_sss_attrcpy(struct sss_sudo_attr *dst, const struct sss_sudo_attr *src)
+ {
+      int i;
+-     debug_decl(sudo_sss_attrcpy, SUDO_DEBUG_LDAP)
++     debug_decl(sudo_sss_attrcpy, SUDO_DEBUG_SSSD)
+ 
+      DPRINTF(3, "dst=%p, src=%p", dst, src);
+      DPRINTF(2, "emalloc: cnt=%d", src->num_values);
+@@ -104,8 +104,8 @@ static void sudo_sss_attrcpy(struct sss_
+ static void sudo_sss_rulecpy(struct sss_sudo_rule *dst, const struct sss_sudo_rule *src)
+ {
+      int i;
+-     debug_decl(sudo_sss_rulecpy, SUDO_DEBUG_LDAP)
+-     
++     debug_decl(sudo_sss_rulecpy, SUDO_DEBUG_SSSD)
++
+      DPRINTF(3, "dst=%p, src=%p", dst, src);
+      DPRINTF(2, "emalloc: cnt=%d", src->num_attrs);
+ 
+@@ -130,7 +130,7 @@ static struct sss_sudo_result *sudo_sss_
+ {
+      struct sss_sudo_result *out_res;
+      int i, l, r;
+-     debug_decl(sudo_sss_filter_result, SUDO_DEBUG_LDAP)
++     debug_decl(sudo_sss_filter_result, SUDO_DEBUG_SSSD)
+ 
+      DPRINTF(3, "in_res=%p, count=%u, act=%s",
+ 	     in_res, in_res->num_rules, act == _SUDO_SSS_FILTER_EXCLUDE ? "EXCLUDE" : "INCLUDE");
+@@ -193,7 +193,7 @@ struct sudo_nss sudo_nss_sss = {
+ static int sudo_sss_open(struct sudo_nss *nss)
+ {
+      struct sudo_sss_handle *handle;
+-     debug_decl(sudo_sss_open, SUDO_DEBUG_LDAP);
++     debug_decl(sudo_sss_open, SUDO_DEBUG_SSSD);
+ 
+      /* Create a handle container. */
+      handle = emalloc(sizeof(struct sudo_sss_handle));
+@@ -209,7 +209,7 @@ static int sudo_sss_open(struct sudo_nss
+ // ok
+ static int sudo_sss_close(struct sudo_nss *nss)
+ {
+-     debug_decl(sudo_sss_close, SUDO_DEBUG_LDAP);
++     debug_decl(sudo_sss_close, SUDO_DEBUG_SSSD);
+      efree(nss->handle);
+      debug_return_int(0);
+ }
+@@ -217,7 +217,7 @@ static int sudo_sss_close(struct sudo_ns
+ // ok
+ static int sudo_sss_parse(struct sudo_nss *nss)
+ {
+-     debug_decl(sudo_sss_parse, SUDO_DEBUG_LDAP);
++     debug_decl(sudo_sss_parse, SUDO_DEBUG_SSSD);
+      debug_return_int(0);
+ }
+ 
+@@ -229,7 +229,7 @@ static int sudo_sss_setdefs(struct sudo_
+      struct sss_sudo_rule   *sss_rule;
+      uint32_t sss_error;
+      int i;
+-     debug_decl(sudo_sss_setdefs, SUDO_DEBUG_LDAP);
++     debug_decl(sudo_sss_setdefs, SUDO_DEBUG_SSSD);
+ 
+      if (handle == NULL)
+ 	  debug_return_int(-1);
+@@ -257,7 +257,7 @@ static int sudo_sss_setdefs(struct sudo_
+ static int sudo_sss_checkpw(struct sudo_nss *nss, struct passwd *pw)
+ {
+      struct sudo_sss_handle *handle = nss->handle;
+-     debug_decl(sudo_sss_checkpw, SUDO_DEBUG_LDAP);
++     debug_decl(sudo_sss_checkpw, SUDO_DEBUG_SSSD);
+ 
+      if (pw->pw_name != handle->pw->pw_name ||
+ 	 pw->pw_uid  != handle->pw->pw_uid)
+@@ -278,13 +278,13 @@ sudo_sss_check_runas_user(struct sss_sud
+      char **val_array = NULL;
+      char *val;
+      int ret = false, i;
+-     debug_decl(sudo_sss_check_runas_user, SUDO_DEBUG_LDAP);
++     debug_decl(sudo_sss_check_runas_user, SUDO_DEBUG_SSSD);
+ 
+      if (!runas_pw)
+ 	  debug_return_int(UNSPEC);
+ 
+      /* get the runas user from the entry */
+-     switch (sss_sudo_get_values(sss_rule, "sudoRunAsUser", &val_array)) 
++     switch (sss_sudo_get_values(sss_rule, "sudoRunAsUser", &val_array))
+      {
+      case 0:
+ 	  break;
+@@ -315,18 +315,18 @@ sudo_sss_check_runas_user(struct sss_sud
+ 
+      /*
+       * BUG:
+-      * 
++      *
+       * if runas is not specified on the command line, the only information
+       * as to which user to run as is in the runas_default option.  We should
+       * check to see if we have the local option present.  Unfortunately we
+       * don't parse these options until after this routine says yes or no.
+       * The query has already returned, so we could peek at the attribute
+       * values here though.
+-      * 
++      *
+       * For now just require users to always use -u option unless its set
+       * in the global defaults. This behaviour is no different than the global
+       * /etc/sudoers.
+-      * 
++      *
+       * Sigh - maybe add this feature later
+       */
+ 
+@@ -381,7 +381,7 @@ sudo_sss_check_runas_group(struct sss_su
+      char **val_array = NULL;
+      char *val;
+      int ret = false, i;
+-     debug_decl(sudo_sss_check_runas_group, SUDO_DEBUG_LDAP);
++     debug_decl(sudo_sss_check_runas_group, SUDO_DEBUG_SSSD);
+ 
+      /* runas_gr is only set if the user specified the -g flag */
+      if (!runas_gr)
+@@ -424,7 +424,7 @@ static int
+ sudo_sss_check_runas(struct sss_sudo_rule *rule)
+ {
+     int ret;
+-    debug_decl(sudo_sss_check_runas, SUDO_DEBUG_LDAP);
++    debug_decl(sudo_sss_check_runas, SUDO_DEBUG_SSSD);
+ 
+     if (rule == NULL)
+ 	 debug_return_int(false);
+@@ -439,7 +439,7 @@ static int sudo_sss_check_host(struct ss
+ {
+     char **val_array, *val;
+     int ret = false, i;
+-    debug_decl(sudo_sss_check_host, SUDO_DEBUG_LDAP);
++    debug_decl(sudo_sss_check_host, SUDO_DEBUG_SSSD);
+ 
+     if (rule == NULL)
+ 	 debug_return_int(ret);
+@@ -479,7 +479,7 @@ static int sudo_sss_check_host(struct ss
+ static int sudo_sss_result_filterp(struct sss_sudo_rule *rule, void *unused)
+ {
+      (void)unused;
+-     debug_decl(sudo_sss_result_filterp, SUDO_DEBUG_LDAP);
++     debug_decl(sudo_sss_result_filterp, SUDO_DEBUG_SSSD);
+ 
+      if (sudo_sss_check_host(rule))
+ 	  debug_return_int(1);
+@@ -492,7 +492,7 @@ static struct sss_sudo_result *sudo_sss_
+      struct sudo_sss_handle *handle = nss->handle;
+      struct sss_sudo_result *u_sss_result, *f_sss_result;
+      uint32_t sss_error = 0, ret;
+-     debug_decl(sudo_sss_result_get, SUDO_DEBUG_LDAP);
++     debug_decl(sudo_sss_result_get, SUDO_DEBUG_SSSD);
+ 
+      if (sudo_sss_checkpw(nss, pw) != 0)
+ 	  debug_return_ptr(NULL);
+@@ -558,7 +558,7 @@ sudo_sss_check_bool(struct sss_sudo_rule
+ {
+      char ch, *var, **val_array = NULL;
+      int i, ret = UNSPEC;
+-     debug_decl(sudo_sss_check_bool, SUDO_DEBUG_LDAP);
++     debug_decl(sudo_sss_check_bool, SUDO_DEBUG_SSSD);
+ 
+      if (rule == NULL)
+ 	  debug_return_int(ret);
+@@ -601,7 +601,7 @@ sudo_sss_check_command(struct sss_sudo_r
+      char **val_array = NULL, *val;
+      char *allowed_cmnd, *allowed_args;
+      int i, foundbang, ret = UNSPEC;
+-     debug_decl(sudo_sss_check_command, SUDO_DEBUG_LDAP);
++     debug_decl(sudo_sss_check_command, SUDO_DEBUG_SSSD);
+ 
+      if (rule == NULL)
+ 	  debug_return_int(ret);
+@@ -670,7 +670,7 @@ sudo_sss_parse_options(struct sss_sudo_r
+      int i;
+      char op, *v, *val;
+      char **val_array = NULL;
+-     debug_decl(sudo_sss_parse_options, SUDO_DEBUG_LDAP);
++     debug_decl(sudo_sss_parse_options, SUDO_DEBUG_SSSD);
+ 
+      if (rule == NULL)
+ 	  debug_return;
+@@ -726,7 +726,7 @@ static int sudo_sss_lookup(struct sudo_n
+     struct sss_sudo_result *sss_result = NULL;
+     struct sss_sudo_rule   *rule;
+     uint32_t i, state = 0;
+-    debug_decl(sudo_sss_lookup, SUDO_DEBUG_LDAP);
++    debug_decl(sudo_sss_lookup, SUDO_DEBUG_SSSD);
+ 
+     /* Fetch list of sudoRole entries that match user and host. */
+     sss_result = sudo_sss_result_get(nss, sudo_user.pw, &state);
+@@ -738,7 +738,7 @@ static int sudo_sss_lookup(struct sudo_n
+     if (pwflag) {
+ 	int doauth = UNSPEC;
+ 	int matched = UNSPEC;
+-	enum def_tuple pwcheck = 
++	enum def_tuple pwcheck =
+ 	    (pwflag == -1) ? never : sudo_defs_table[pwflag].sd_un.tuple;
+ 
+ 	DPRINTF(2, "perform search for pwflag %d", pwflag);
+@@ -842,7 +842,7 @@ static int sudo_sss_display_cmnd(struct 
+      struct sss_sudo_result *sss_result = NULL;
+      struct sss_sudo_rule *rule;
+      int i, found = false;
+-     debug_decl(sudo_sss_display_cmnd, SUDO_DEBUG_LDAP);
++     debug_decl(sudo_sss_display_cmnd, SUDO_DEBUG_SSSD);
+ 
+      if (handle == NULL)
+ 	  goto done;
+@@ -893,7 +893,7 @@ static int sudo_sss_display_defaults(str
+      char *prefix, *val, **val_array = NULL;
+      int count = 0, i, j;
+ 
+-     debug_decl(sudo_sss_display_defaults, SUDO_DEBUG_LDAP);
++     debug_decl(sudo_sss_display_defaults, SUDO_DEBUG_SSSD);
+ 
+      if (handle == NULL)
+ 	  goto done;
+@@ -934,7 +934,7 @@ static int sudo_sss_display_defaults(str
+ 	       prefix = ", ";
+ 	       count++;
+ 	  }
+-	  
++
+ 	  sss_sudo_free_values(val_array);
+ 	  val_array = NULL;
+      }
+@@ -948,7 +948,7 @@ done:
+ static int sudo_sss_display_bound_defaults(struct sudo_nss *nss,
+ 					    struct passwd *pw, struct lbuf *lbuf)
+ {
+-     debug_decl(sudo_sss_display_bound_defaults, SUDO_DEBUG_LDAP);
++     debug_decl(sudo_sss_display_bound_defaults, SUDO_DEBUG_SSSD);
+      debug_return_int(0);
+ }
+ 
+@@ -956,7 +956,7 @@ static int sudo_sss_display_entry_long(s
+ {
+      char **val_array = NULL;
+      int count = 0, i;
+-     debug_decl(sudo_sss_display_entry_long, SUDO_DEBUG_LDAP);
++     debug_decl(sudo_sss_display_entry_long, SUDO_DEBUG_SSSD);
+ 
+      /* get the RunAsUser Values from the entry */
+      lbuf_append(lbuf, "    RunAsUsers: ");
+@@ -1051,7 +1051,7 @@ static int sudo_sss_display_entry_short(
+ {
+      char **val_array = NULL;
+      int count = 0, i;
+-     debug_decl(sudo_sss_display_entry_short, SUDO_DEBUG_LDAP);
++     debug_decl(sudo_sss_display_entry_short, SUDO_DEBUG_SSSD);
+ 
+      lbuf_append(lbuf, "    (");
+ 
+@@ -1164,7 +1164,7 @@ static int sudo_sss_display_privs(struct
+      struct sss_sudo_result *sss_result = NULL;
+      struct sss_sudo_rule *rule;
+      unsigned int i, count = 0;
+-     debug_decl(sudo_sss_display_privs, SUDO_DEBUG_LDAP);
++     debug_decl(sudo_sss_display_privs, SUDO_DEBUG_SSSD);
+ 
+      if (handle == NULL)
+ 	  debug_return_int(-1);
diff --git a/sudo-1.8.5-remove-source-when-open-failed.patch b/sudo-1.8.5-remove-source-when-open-failed.patch
new file mode 100644
index 0000000..0267f39
--- /dev/null
+++ b/sudo-1.8.5-remove-source-when-open-failed.patch
@@ -0,0 +1,33 @@
+diff -rup original/plugins/sudoers/sudoers.c new/plugins/sudoers/sudoers.c
+--- original/plugins/sudoers/sudoers.c	2012-07-19 12:13:31.292479203 +0200
++++ new/plugins/sudoers/sudoers.c	2012-07-19 12:14:02.898844521 +0200
+@@ -145,6 +145,7 @@ sudoers_policy_open(unsigned int version
+     volatile int sources = 0;
+     sigaction_t sa;
+     struct sudo_nss *nss;
++    struct sudo_nss *nss_next;
+     debug_decl(sudoers_policy_open, SUDO_DEBUG_PLUGIN)
+ 
+     sudo_version = version;
+@@ -201,12 +202,15 @@ sudoers_policy_open(unsigned int version
+     set_perms(PERM_ROOT);
+ 
+     /* Open and parse sudoers, set global defaults */
+-    tq_foreach_fwd(snl, nss) {
+-	if (nss->open(nss) == 0 && nss->parse(nss) == 0) {
+-	    sources++;
+-	    if (nss->setdefs(nss) != 0)
+-		log_error(NO_STDERR, _("problem with defaults entries"));
+-	}
++    for (nss = snl->first; nss != NULL; nss = nss_next) {
++        nss_next = nss->next;
++        if (nss->open(nss) == 0 && nss->parse(nss) == 0) {
++            sources++;
++            if (nss->setdefs(nss) != 0)
++                log_error(NO_STDERR, _("problem with defaults entries"));
++        } else {
++            tq_remove(snl, nss);
++        }
+     }
+     if (sources == 0) {
+ 	warningx(_("no valid sudoers sources found, quitting"));
diff --git a/sudo-1.8.5-sssd-dlopen-lib.patch b/sudo-1.8.5-sssd-dlopen-lib.patch
new file mode 100644
index 0000000..e9b1914
--- /dev/null
+++ b/sudo-1.8.5-sssd-dlopen-lib.patch
@@ -0,0 +1,905 @@
+diff -rup original/configure.in new/configure.in
+--- original/configure.in	2012-07-19 12:13:15.872301022 +0200
++++ new/configure.in	2012-07-23 11:31:42.821466529 +0200
+@@ -101,6 +101,7 @@ AC_SUBST([root_sudo])
+ AC_SUBST([path_info])
+ AC_SUBST([ldap_conf])
+ AC_SUBST([ldap_secret])
++AC_SUBST([sssd_lib])
+ AC_SUBST([nsswitch_conf])
+ AC_SUBST([netsvc_conf])
+ AC_SUBST([secure_path])
+@@ -290,8 +291,6 @@ dnl
+ AC_ARG_WITH(sssd, [AS_HELP_STRING([--with-sssd], [enable SSSD support])],
+ [case $with_sssd in
+     yes)
+-		SUDO_LIBS="${SUDO_LIBS} `pkg-config libsss_sudo --libs`"
+-		SUDOERS_LIBS="${SUDO_LIBS} `pkg-config libsss_sudo --libs`"
+ 		SUDOERS_OBJS="${SUDOERS_OBJS} sssd.lo"
+ 		AC_DEFINE(HAVE_SSSD)
+ 		;;
+@@ -300,6 +299,11 @@ AC_ARG_WITH(sssd, [AS_HELP_STRING([--wit
+ 		;;
+ esac])
+ 
++AC_ARG_WITH(sssd-lib, [AS_HELP_STRING([--with-sssd-lib], [path to the SSSD library])])
++sssd_lib="\"LIBDIR\""
++test -n "$with_sssd_lib" && sssd_lib="$with_sssd_lib"
++SUDO_DEFINE_UNQUOTED(_PATH_SSSD_LIB, "$sssd_lib", [Path to the SSSD library])
++
+ AC_ARG_WITH(incpath, [AS_HELP_STRING([--with-incpath], [additional places to look for include files])],
+ [case $with_incpath in
+     yes)	AC_MSG_ERROR(["must give --with-incpath an argument."])
+diff -rup original/pathnames.h.in new/pathnames.h.in
+--- original/pathnames.h.in	2012-07-19 12:13:15.779299949 +0200
++++ new/pathnames.h.in	2012-07-19 15:58:49.454653685 +0200
+@@ -157,6 +157,10 @@
+ #undef	_PATH_LDAP_SECRET
+ #endif /* _PATH_LDAP_SECRET */
+ 
++#ifndef _PATH_SSSD_LIB
++#undef  _PATH_SSSD_LIB
++#endif /* _PATH_SSSD_LIB */
++
+ #ifndef _PATH_NSSWITCH_CONF
+ #undef	_PATH_NSSWITCH_CONF
+ #endif /* _PATH_NSSWITCH_CONF */
+diff -rup original/plugins/sudoers/Makefile.in new/plugins/sudoers/Makefile.in
+--- original/plugins/sudoers/Makefile.in	2012-07-19 12:13:15.756299680 +0200
++++ new/plugins/sudoers/Makefile.in	2012-07-23 11:31:56.084610531 +0200
+@@ -32,6 +32,7 @@ top_srcdir = @top_srcdir@
+ incdir = $(top_srcdir)/include
+ docdir = @docdir@
+ timedir = @timedir@
++libdir = @libdir@
+ 
+ # Compiler & tools to use
+ CC = @CC@
+@@ -51,7 +52,7 @@ SUDOERS_LIBS = @SUDOERS_LIBS@ @AFS_LIBS@
+ REPLAY_LIBS = @REPLAY_LIBS@ @ZLIB@
+ 
+ # C preprocessor flags
+-CPPFLAGS = -I$(incdir) -I$(top_builddir) -I$(devdir) -I$(srcdir) -I$(top_srcdir) @CPPFLAGS@
++CPPFLAGS = -I$(incdir) -I$(top_builddir) -I$(devdir) -I$(srcdir) -I$(top_srcdir) -DLIBDIR=\"$(libdir)\" @CPPFLAGS@
+ 
+ # Usually -O and/or -g
+ CFLAGS = @CFLAGS@
+diff -rup original/plugins/sudoers/sssd.c new/plugins/sudoers/sssd.c
+--- original/plugins/sudoers/sssd.c	2012-07-19 12:13:15.667298652 +0200
++++ new/plugins/sudoers/sssd.c	2012-07-23 11:32:04.260699269 +0200
+@@ -44,23 +44,70 @@
+ #if TIME_WITH_SYS_TIME
+ # include <time.h>
+ #endif
++#ifdef HAVE_DLOPEN
++# include <dlfcn.h>
++#else
++# include "compat/dlfcn.h"
++#endif
+ #include <ctype.h>
+ #include <pwd.h>
+ #include <grp.h>
+ 
+-#include <sss_sudo.h>
+ #include <errno.h>
++#include <stdint.h>
+ 
+ #include "sudoers.h"
+ #include "parse.h"
+ #include "lbuf.h"
+ #include "sudo_debug.h"
+ 
++/* SSSD <--> SUDO interface - do not change */
++struct sss_sudo_attr {
++    char *name;
++    char **values;
++    unsigned int num_values;
++};
++
++struct sss_sudo_rule {
++    unsigned int num_attrs;
++    struct sss_sudo_attr *attrs;
++};
++
++struct sss_sudo_result {
++    unsigned int num_rules;
++    struct sss_sudo_rule *rules;
++};
++
++typedef int  (*sss_sudo_send_recv_t)(uid_t, const char*, const char*,
++                                     uint32_t*, struct sss_sudo_result**);
++
++typedef int  (*sss_sudo_send_recv_defaults_t)(uid_t, const char*, uint32_t*,
++                                              char**, struct sss_sudo_result**);
++
++typedef void (*sss_sudo_free_result_t)(struct sss_sudo_result*);
++
++typedef int  (*sss_sudo_get_values_t)(struct sss_sudo_rule*, const char*,
++                                      char***);
++
++typedef void (*sss_sudo_free_values_t)(char**);
++
+ /* sudo_nss implementation */
++
++struct sudo_sss_handle {
++     char *domainname;
++     struct passwd *pw;
++     void *ssslib;
++     sss_sudo_send_recv_t fn_send_recv;
++     sss_sudo_send_recv_defaults_t fn_send_recv_defaults;
++     sss_sudo_free_result_t fn_free_result;
++     sss_sudo_get_values_t fn_get_values;
++     sss_sudo_free_values_t fn_free_values;
++};
++
+ static int sudo_sss_open(struct sudo_nss *nss);
+ static int sudo_sss_close(struct sudo_nss *nss);
+ static int sudo_sss_parse(struct sudo_nss *nss);
+-static void sudo_sss_parse_options(struct sss_sudo_rule *rule);
++static void sudo_sss_parse_options(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule);
+ static int sudo_sss_setdefs(struct sudo_nss *nss);
+ static int sudo_sss_lookup(struct sudo_nss *nss, int ret, int pwflag);
+ static int sudo_sss_display_cmnd(struct sudo_nss *nss, struct passwd *pw);
+@@ -121,7 +168,7 @@ static void sudo_sss_rulecpy(struct sss_
+ #define _SUDO_SSS_STATE_HOSTMATCH 0x01
+ #define _SUDO_SSS_STATE_USERMATCH 0x02
+ 
+-static struct sss_sudo_result *sudo_sss_filter_result(struct sss_sudo_result *in_res, int (*filterp)(struct sss_sudo_rule *, void *), int act, void *filterp_arg)
++static struct sss_sudo_result *sudo_sss_filter_result(struct sudo_sss_handle *handle, struct sss_sudo_result *in_res, int (*filterp)(struct sudo_sss_handle *, struct sss_sudo_rule *, void *), int act, void *filterp_arg)
+ {
+      struct sss_sudo_result *out_res;
+      int i, l, r;
+@@ -140,7 +187,7 @@ static struct sss_sudo_result *sudo_sss_
+      out_res->num_rules = 0;
+ 
+      for (i = l = 0; i < in_res->num_rules; ++i) {
+-	  r = filterp(in_res->rules + i, filterp_arg);
++	  r = filterp(handle, in_res->rules + i, filterp_arg);
+ 
+ 	  if (( r && act == _SUDO_SSS_FILTER_INCLUDE) ||
+ 	      (!r && act == _SUDO_SSS_FILTER_EXCLUDE))
+@@ -164,11 +211,6 @@ static struct sss_sudo_result *sudo_sss_
+      debug_return_ptr(out_res);
+ }
+ 
+-struct sudo_sss_handle {
+-     char *domainname;
+-     struct passwd *pw;
+-};
+-
+ struct sudo_nss sudo_nss_sss = {
+     &sudo_nss_sss,
+     NULL,
+@@ -188,10 +230,50 @@ struct sudo_nss sudo_nss_sss = {
+ static int sudo_sss_open(struct sudo_nss *nss)
+ {
+      struct sudo_sss_handle *handle;
++     static const char path[] = _PATH_SSSD_LIB"/libsss_sudo.so";
+      debug_decl(sudo_sss_open, SUDO_DEBUG_SSSD);
+ 
+      /* Create a handle container. */
+      handle = emalloc(sizeof(struct sudo_sss_handle));
++
++     /* Load symbols */
++     handle->ssslib = dlopen(path, RTLD_LAZY);
++     if (handle->ssslib == NULL) {
++         warningx(_("Unable to dlopen %s: %s"), path, dlerror());
++         warningx(_("Unable to initialize SSS source. Is SSSD installed on your machine?"));
++         debug_return_int(EFAULT);
++     }
++
++     handle->fn_send_recv = dlsym(handle->ssslib, "sss_sudo_send_recv");
++     if (handle->fn_send_recv == NULL) {
++         warningx(_("unable to find symbol \"sss_sudo_send_recv\" in %s"), path);
++         debug_return_int(EFAULT);
++     }
++
++     handle->fn_send_recv_defaults = dlsym(handle->ssslib, "sss_sudo_send_recv_defaults");
++     if (handle->fn_send_recv_defaults == NULL) {
++         warningx(_("unable to find symbol \"sss_sudo_send_recv_defaults\" in %s"), path);
++         debug_return_int(EFAULT);
++     }
++
++     handle->fn_free_result = dlsym(handle->ssslib, "sss_sudo_free_result");
++     if (handle->fn_free_result == NULL) {
++         warningx(_("unable to find symbol \"sss_sudo_free_result\" in %s"), path);
++         debug_return_int(EFAULT);
++     }
++
++     handle->fn_get_values = dlsym(handle->ssslib, "sss_sudo_get_values");
++     if (handle->fn_get_values == NULL) {
++         warningx(_("unable to find symbol \"sss_sudo_get_values\" in %s"), path);
++         debug_return_int(EFAULT);
++     }
++
++     handle->fn_free_values = dlsym(handle->ssslib, "sss_sudo_free_values");
++     if (handle->fn_free_values == NULL) {
++         warningx(_("unable to find symbol \"sss_sudo_free_values\" in %s"), path);
++         debug_return_int(EFAULT);
++     }
++
+      handle->domainname = NULL;
+      handle->pw = sudo_user.pw;
+      nss->handle = handle;
+@@ -204,7 +286,14 @@ static int sudo_sss_open(struct sudo_nss
+ // ok
+ static int sudo_sss_close(struct sudo_nss *nss)
+ {
++     struct sudo_sss_handle *handle;
+      debug_decl(sudo_sss_close, SUDO_DEBUG_SSSD);
++
++     if (nss && nss->handle) {
++         handle = nss->handle;
++         dlclose(handle->ssslib);
++     }
++
+      efree(nss->handle);
+      debug_return_int(0);
+ }
+@@ -231,11 +320,11 @@ static int sudo_sss_setdefs(struct sudo_
+ 
+      sudo_debug_printf(1, "Looking for cn=defaults");
+ 
+-     if (sss_sudo_send_recv_defaults(handle->pw->pw_uid, handle->pw->pw_name,
++     if (handle->fn_send_recv_defaults(handle->pw->pw_uid, handle->pw->pw_name,
+ 				     &sss_error, &handle->domainname,
+ 				     &sss_result) != 0)
+      {
+-	  sudo_debug_printf(2, "sss_sudo_send_recv_defaults: != 0, sss_error=%u", sss_error);
++	  sudo_debug_printf(2, "handle->fn_send_recv_defaults: != 0, sss_error=%u", sss_error);
+ 	  debug_return_int(-1);
+      }
+ 
+@@ -250,10 +339,10 @@ static int sudo_sss_setdefs(struct sudo_
+      for (i = 0; i < sss_result->num_rules; ++i) {
+ 	  sudo_debug_printf(1, "Parsing cn=defaults, %d/%d", i, sss_result->num_rules);
+ 	  sss_rule = sss_result->rules + i;
+-	  sudo_sss_parse_options(sss_rule);
++	  sudo_sss_parse_options(handle, sss_rule);
+      }
+ 
+-     sss_sudo_free_result(sss_result);
++     handle->fn_free_result(sss_result);
+      debug_return_int(0);
+ }
+ 
+@@ -276,7 +365,7 @@ static int sudo_sss_checkpw(struct sudo_
+ }
+ 
+ static int
+-sudo_sss_check_runas_user(struct sss_sudo_rule *sss_rule)
++sudo_sss_check_runas_user(struct sudo_sss_handle *handle, struct sss_sudo_rule *sss_rule)
+ {
+      char **val_array = NULL;
+      char *val;
+@@ -287,7 +376,7 @@ sudo_sss_check_runas_user(struct sss_sud
+ 	  debug_return_int(UNSPEC);
+ 
+      /* get the runas user from the entry */
+-     switch (sss_sudo_get_values(sss_rule, "sudoRunAsUser", &val_array))
++     switch (handle->fn_get_values(sss_rule, "sudoRunAsUser", &val_array))
+      {
+      case 0:
+ 	  break;
+@@ -295,7 +384,7 @@ sudo_sss_check_runas_user(struct sss_sud
+ 	  sudo_debug_printf(2, "No result. Trying old style (sudoRunAs)");
+ 
+ 	  /* try old style */
+-	  switch (sss_sudo_get_values(sss_rule, "sudoRunAs", &val_array))
++	  switch (handle->fn_get_values(sss_rule, "sudoRunAs", &val_array))
+ 	  {
+ 	  case 0:
+ 	       break;
+@@ -307,12 +396,12 @@ sudo_sss_check_runas_user(struct sss_sud
+ 		*/
+ 	       return !strcasecmp(runas_pw->pw_name, def_runas_default);
+ 	  default:
+-	       sudo_debug_printf(2, "sss_sudo_get_values(sudoRunAs): != 0");
++	       sudo_debug_printf(2, "handle->fn_get_values(sudoRunAs): != 0");
+ 	       debug_return_int(UNSPEC);
+ 	  }
+ 	  break;
+      default:
+-	  sudo_debug_printf(2, "sss_sudo_get_values(sudoRunAsUser): != 0");
++	  sudo_debug_printf(2, "handle->fn_get_values(sudoRunAsUser): != 0");
+ 	  debug_return_int(UNSPEC);
+      }
+ 
+@@ -373,13 +462,13 @@ sudo_sss_check_runas_user(struct sss_sud
+ 	  sudo_debug_printf(2, "sssd/ldap sudoRunAsUser '%s' ... %s", val, ret ? "MATCH!" : "not");
+      }
+ 
+-     sss_sudo_free_values(val_array); /* cleanup */
++     handle->fn_free_values(val_array); /* cleanup */
+ 
+      debug_return_int(ret);
+ }
+ 
+ static int
+-sudo_sss_check_runas_group(struct sss_sudo_rule *rule)
++sudo_sss_check_runas_group(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
+ {
+      char **val_array = NULL;
+      char *val;
+@@ -391,7 +480,7 @@ sudo_sss_check_runas_group(struct sss_su
+ 	  debug_return_int(UNSPEC);
+ 
+      /* get the values from the entry */
+-     switch (sss_sudo_get_values(rule, "sudoRunAsGroup", &val_array))
++     switch (handle->fn_get_values(rule, "sudoRunAsGroup", &val_array))
+      {
+      case 0:
+ 	  break;
+@@ -399,7 +488,7 @@ sudo_sss_check_runas_group(struct sss_su
+ 	  sudo_debug_printf(2, "No result.");
+ 	  debug_return_int(false);
+      default:
+-	  sudo_debug_printf(2, "sss_sudo_get_values(sudoRunAsGroup): != 0");
++	  sudo_debug_printf(2, "handle->fn_get_values(sudoRunAsGroup): != 0");
+ 	  debug_return_int(UNSPEC);
+      }
+ 
+@@ -414,7 +503,7 @@ sudo_sss_check_runas_group(struct sss_su
+ 	  sudo_debug_printf(2, "sssd/ldap sudoRunAsGroup '%s' ... %s", val, ret ? "MATCH!" : "not");
+      }
+ 
+-     sss_sudo_free_values(val_array);
++     handle->fn_free_values(val_array);
+ 
+      debug_return_int(ret);
+ }
+@@ -424,7 +513,7 @@ sudo_sss_check_runas_group(struct sss_su
+  * else false.  RunAs info is optional.
+  */
+ static int
+-sudo_sss_check_runas(struct sss_sudo_rule *rule)
++sudo_sss_check_runas(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
+ {
+     int ret;
+     debug_decl(sudo_sss_check_runas, SUDO_DEBUG_SSSD);
+@@ -432,13 +521,13 @@ sudo_sss_check_runas(struct sss_sudo_rul
+     if (rule == NULL)
+ 	 debug_return_int(false);
+ 
+-    ret = sudo_sss_check_runas_user(rule) != false &&
+-	 sudo_sss_check_runas_group(rule) != false;
++    ret = sudo_sss_check_runas_user(handle, rule) != false &&
++	 sudo_sss_check_runas_group(handle, rule) != false;
+ 
+     debug_return_int(ret);
+ }
+ 
+-static int sudo_sss_check_host(struct sss_sudo_rule *rule)
++static int sudo_sss_check_host(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
+ {
+     char **val_array, *val;
+     int ret = false, i;
+@@ -448,7 +537,7 @@ static int sudo_sss_check_host(struct ss
+ 	 debug_return_int(ret);
+ 
+     /* get the values from the rule */
+-    switch (sss_sudo_get_values(rule, "sudoHost", &val_array))
++    switch (handle->fn_get_values(rule, "sudoHost", &val_array))
+     {
+     case 0:
+ 	 break;
+@@ -456,7 +545,7 @@ static int sudo_sss_check_host(struct ss
+ 	 sudo_debug_printf(2, "No result.");
+ 	 debug_return_int(false);
+     default:
+-	 sudo_debug_printf(2, "sss_sudo_get_values(sudoHost): != 0");
++	 sudo_debug_printf(2, "handle->fn_get_values(sudoHost): != 0");
+ 	 debug_return_int(ret);
+     }
+ 
+@@ -474,17 +563,17 @@ static int sudo_sss_check_host(struct ss
+ 	 sudo_debug_printf(2, "sssd/ldap sudoHost '%s' ... %s", val, ret ? "MATCH!" : "not");
+     }
+ 
+-    sss_sudo_free_values(val_array);
++    handle->fn_free_values(val_array);
+ 
+     debug_return_int(ret);
+ }
+ 
+-static int sudo_sss_result_filterp(struct sss_sudo_rule *rule, void *unused)
++static int sudo_sss_result_filterp(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule, void *unused)
+ {
+      (void)unused;
+      debug_decl(sudo_sss_result_filterp, SUDO_DEBUG_SSSD);
+ 
+-     if (sudo_sss_check_host(rule))
++     if (sudo_sss_check_host(handle, rule))
+ 	  debug_return_int(1);
+      else
+ 	  debug_return_int(0);
+@@ -505,7 +594,7 @@ static struct sss_sudo_result *sudo_sss_
+ 
+      u_sss_result = f_sss_result = NULL;
+ 
+-     switch (ret = sss_sudo_send_recv(handle->pw->pw_uid, handle->pw->pw_name,
++     switch (ret = handle->fn_send_recv(handle->pw->pw_uid, handle->pw->pw_name,
+ 				      handle->domainname, &sss_error, &u_sss_result))
+      {
+      case 0:
+@@ -530,11 +619,11 @@ static struct sss_sudo_result *sudo_sss_
+ 	  }
+ 	  break;
+      default:
+-	  sudo_debug_printf(2, "sss_sudo_send_recv: != 0: ret=%d", ret);
++	  sudo_debug_printf(2, "handle->fn_send_recv: != 0: ret=%d", ret);
+ 	  debug_return_ptr(NULL);
+      }
+ 
+-     f_sss_result = sudo_sss_filter_result(u_sss_result, sudo_sss_result_filterp,
++     f_sss_result = sudo_sss_filter_result(handle, u_sss_result, sudo_sss_result_filterp,
+ 					   _SUDO_SSS_FILTER_INCLUDE, NULL);
+ 
+      if (f_sss_result != NULL)
+@@ -547,7 +636,7 @@ static struct sss_sudo_result *sudo_sss_
+      sudo_debug_printf(3, "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);
+ 
+-     sss_sudo_free_result(u_sss_result);
++     handle->fn_free_result(u_sss_result);
+ 
+      debug_return_ptr(f_sss_result);
+ }
+@@ -557,7 +646,7 @@ static struct sss_sudo_result *sudo_sss_
+  * Returns true if found and allowed, false if negated, else UNSPEC.
+  */
+ static int
+-sudo_sss_check_bool(struct sss_sudo_rule *rule, char *option)
++sudo_sss_check_bool(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule, char *option)
+ {
+      char ch, *var, **val_array = NULL;
+      int i, ret = UNSPEC;
+@@ -566,7 +655,7 @@ sudo_sss_check_bool(struct sss_sudo_rule
+      if (rule == NULL)
+ 	  debug_return_int(ret);
+ 
+-     switch (sss_sudo_get_values(rule, "sudoOption", &val_array))
++     switch (handle->fn_get_values(rule, "sudoOption", &val_array))
+      {
+      case 0:
+ 	  break;
+@@ -574,7 +663,7 @@ sudo_sss_check_bool(struct sss_sudo_rule
+ 	  sudo_debug_printf(2, "No result.");
+ 	  debug_return_int(ret);
+      default:
+-	  sudo_debug_printf(2, "sss_sudo_get_values: != 0");
++	  sudo_debug_printf(2, "handle->fn_get_values: != 0");
+ 	  debug_return_int(ret);
+      }
+ 
+@@ -589,7 +678,7 @@ sudo_sss_check_bool(struct sss_sudo_rule
+ 	       ret = (ch != '!');
+      }
+ 
+-     sss_sudo_free_values(val_array);
++     handle->fn_free_values(val_array);
+ 
+      debug_return_int(ret);
+ }
+@@ -599,7 +688,7 @@ sudo_sss_check_bool(struct sss_sudo_rule
+  * false if disallowed and UNSPEC if not matched.
+  */
+ static int
+-sudo_sss_check_command(struct sss_sudo_rule *rule, int *setenv_implied)
++sudo_sss_check_command(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule, int *setenv_implied)
+ {
+      char **val_array = NULL, *val;
+      char *allowed_cmnd, *allowed_args;
+@@ -609,7 +698,7 @@ sudo_sss_check_command(struct sss_sudo_r
+      if (rule == NULL)
+ 	  debug_return_int(ret);
+ 
+-     switch (sss_sudo_get_values(rule, "sudoCommand", &val_array))
++     switch (handle->fn_get_values(rule, "sudoCommand", &val_array))
+      {
+      case 0:
+ 	  break;
+@@ -617,7 +706,7 @@ sudo_sss_check_command(struct sss_sudo_r
+ 	  sudo_debug_printf(2, "No result.");
+ 	  debug_return_int(ret);
+      default:
+-	  sudo_debug_printf(2, "sss_sudo_get_values: != 0");
++	  sudo_debug_printf(2, "handle->fn_get_values: != 0");
+ 	  debug_return_int(ret);
+      }
+ 
+@@ -662,13 +751,13 @@ sudo_sss_check_command(struct sss_sudo_r
+ 	  efree(allowed_cmnd);	/* cleanup */
+      }
+ 
+-     sss_sudo_free_values(val_array); /* more cleanup */
++     handle->fn_free_values(val_array); /* more cleanup */
+ 
+      debug_return_int(ret);
+ }
+ 
+ static void
+-sudo_sss_parse_options(struct sss_sudo_rule *rule)
++sudo_sss_parse_options(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
+ {
+      int i;
+      char op, *v, *val;
+@@ -678,7 +767,7 @@ sudo_sss_parse_options(struct sss_sudo_r
+      if (rule == NULL)
+ 	  debug_return;
+ 
+-     switch (sss_sudo_get_values(rule, "sudoOption", &val_array))
++     switch (handle->fn_get_values(rule, "sudoOption", &val_array))
+      {
+      case 0:
+ 	  break;
+@@ -686,7 +775,7 @@ sudo_sss_parse_options(struct sss_sudo_r
+ 	  sudo_debug_printf(2, "No result.");
+ 	  debug_return;
+      default:
+-	  sudo_debug_printf(2, "sss_sudo_get_values(sudoOption): != 0");
++	  sudo_debug_printf(2, "handle->fn_get_values(sudoOption): != 0");
+ 	  debug_return;
+      }
+ 
+@@ -718,7 +807,7 @@ sudo_sss_parse_options(struct sss_sudo_r
+ 	  efree(v);
+      }
+ 
+-     sss_sudo_free_values(val_array);
++     handle->fn_free_values(val_array);
+      debug_return;
+ }
+ 
+@@ -726,6 +815,7 @@ static int sudo_sss_lookup(struct sudo_n
+ {
+     int rc, setenv_implied;
+ 
++    struct sudo_sss_handle *handle = nss->handle;
+     struct sss_sudo_result *sss_result = NULL;
+     struct sss_sudo_rule   *rule;
+     uint32_t i, state = 0;
+@@ -750,12 +840,12 @@ static int sudo_sss_lookup(struct sudo_n
+ 		  rule = sss_result->rules + i;
+ 		  if ((pwcheck == any && doauth != false) ||
+ 		      (pwcheck == all && doauth == false)) {
+-		       doauth = sudo_sss_check_bool(rule, "authenticate");
++		       doauth = sudo_sss_check_bool(handle, rule, "authenticate");
+ 		  }
+ 		  /* Only check the command when listing another user. */
+ 		  if (user_uid == 0 || list_pw == NULL ||
+ 		      user_uid == list_pw->pw_uid ||
+-		      sudo_sss_check_command(rule, NULL)) {
++		      sudo_sss_check_command(handle, rule, NULL)) {
+ 		       matched = true;
+ 		       break;
+ 		  }
+@@ -791,9 +881,9 @@ static int sudo_sss_lookup(struct sudo_n
+     if (sss_result != NULL) {
+ 	 for (i = 0; i < sss_result->num_rules; i++) {
+ 	      rule = sss_result->rules + i;
+-	      if (!sudo_sss_check_runas(rule))
++	      if (!sudo_sss_check_runas(handle, rule))
+ 		   continue;
+-	      rc = sudo_sss_check_command(rule, &setenv_implied);
++	      rc = sudo_sss_check_command(handle, rule, &setenv_implied);
+ 	      if (rc != UNSPEC) {
+ 		   /* We have a match. */
+ 		   sudo_debug_printf(1, "Command %sallowed", rc == true ? "" : "NOT ");
+@@ -802,7 +892,7 @@ static int sudo_sss_lookup(struct sudo_n
+ 			/* Apply entry-specific options. */
+ 			if (setenv_implied)
+ 			     def_setenv = true;
+-			sudo_sss_parse_options(rule);
++			sudo_sss_parse_options(handle, rule);
+ #ifdef HAVE_SELINUX
+ 			/* Set role and type if not specified on command line. */
+ 			if (user_role == NULL)
+@@ -865,8 +955,8 @@ static int sudo_sss_display_cmnd(struct 
+ 
+      for (i = 0; i < sss_result->num_rules; i++) {
+ 	  rule = sss_result->rules + i;
+-	  if (sudo_sss_check_command(rule, NULL) &&
+-	      sudo_sss_check_runas(rule)) {
++	  if (sudo_sss_check_command(handle, rule, NULL) &&
++	      sudo_sss_check_runas(handle, rule)) {
+ 	       found = true;
+ 	       goto done;
+ 	  }
+@@ -878,7 +968,7 @@ done:
+ 		 user_args ? " " : "", user_args ? user_args : "");
+ 
+      if (sss_result != NULL)
+-	  sss_sudo_free_result(sss_result);
++	  handle->fn_free_result(sss_result);
+ 
+      debug_return_int(!found);
+ }
+@@ -901,11 +991,11 @@ static int sudo_sss_display_defaults(str
+      if (handle == NULL)
+ 	  goto done;
+ 
+-     if (sss_sudo_send_recv_defaults(pw->pw_uid, pw->pw_name,
++     if (handle->fn_send_recv_defaults(pw->pw_uid, pw->pw_name,
+ 				     &sss_error, &handle->domainname,
+ 				     &sss_result) != 0)
+      {
+-	  sudo_debug_printf(2, "sss_sudo_send_recv_defaults: !=0, sss_error=%u", sss_error);
++	  sudo_debug_printf(2, "handle->fn_send_recv_defaults: !=0, sss_error=%u", sss_error);
+ 	  goto done;
+      }
+ 
+@@ -922,7 +1012,7 @@ static int sudo_sss_display_defaults(str
+      for (i = 0; i < sss_result->num_rules; ++i) {
+ 	  rule = sss_result->rules + i;
+ 
+-	  switch (sss_sudo_get_values(rule, "sudoOption", &val_array))
++	  switch (handle->fn_get_values(rule, "sudoOption", &val_array))
+ 	  {
+ 	  case 0:
+ 	       break;
+@@ -930,7 +1020,7 @@ static int sudo_sss_display_defaults(str
+ 	       sudo_debug_printf(2, "No result.");
+ 	       continue;
+ 	  default:
+-	       sudo_debug_printf(2, "sss_sudo_get_values: != 0");
++	       sudo_debug_printf(2, "handle->fn_get_values: != 0");
+ 	       continue;
+ 	  }
+ 
+@@ -946,11 +1036,11 @@ static int sudo_sss_display_defaults(str
+ 	       count++;
+ 	  }
+ 
+-	  sss_sudo_free_values(val_array);
++	  handle->fn_free_values(val_array);
+ 	  val_array = NULL;
+      }
+ 
+-     sss_sudo_free_result(sss_result);
++     handle->fn_free_result(sss_result);
+ done:
+      debug_return_int(count);
+ }
+@@ -963,7 +1053,7 @@ static int sudo_sss_display_bound_defaul
+      debug_return_int(0);
+ }
+ 
+-static int sudo_sss_display_entry_long(struct sss_sudo_rule *rule, struct lbuf *lbuf)
++static int sudo_sss_display_entry_long(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule, struct lbuf *lbuf)
+ {
+      char **val_array = NULL;
+      int count = 0, i;
+@@ -971,94 +1061,94 @@ static int sudo_sss_display_entry_long(s
+ 
+      /* get the RunAsUser Values from the entry */
+      lbuf_append(lbuf, "    RunAsUsers: ");
+-     switch (sss_sudo_get_values(rule, "sudoRunAsUser", &val_array))
++     switch (handle->fn_get_values(rule, "sudoRunAsUser", &val_array))
+      {
+      case 0:
+ 	  for (i = 0; val_array[i] != NULL; ++i)
+ 	       lbuf_append(lbuf, "%s%s", i != 0 ? ", " : "", val_array[i]);
+-	  sss_sudo_free_values(val_array);
++	  handle->fn_free_values(val_array);
+ 	  break;
+      case ENOENT:
+-	  switch (sss_sudo_get_values(rule, "sudoRunAs", &val_array))
++	  switch (handle->fn_get_values(rule, "sudoRunAs", &val_array))
+ 	  {
+ 	  case 0:
+ 	       for (i = 0; val_array[i] != NULL; ++i)
+ 		    lbuf_append(lbuf, "%s%s", i != 0 ? ", " : "", val_array[i]);
+-	       sss_sudo_free_values(val_array);
++	       handle->fn_free_values(val_array);
+ 	       break;
+ 	  case ENOENT:
+ 	       sudo_debug_printf(2, "No result.");
+ 	       lbuf_append(lbuf, "%s", def_runas_default);
+ 	       break;
+ 	  default:
+-	       sudo_debug_printf(2, "sss_sudo_get_values(sudoRunAs): != 0");
++	       sudo_debug_printf(2, "handle->fn_get_values(sudoRunAs): != 0");
+ 	       debug_return_int(count);
+ 	  }
+ 	  break;
+      default:
+-	  sudo_debug_printf(2, "sss_sudo_get_values(sudoRunAsUser): != 0");
++	  sudo_debug_printf(2, "handle->fn_get_values(sudoRunAsUser): != 0");
+ 	  debug_return_int(count);
+      }
+      lbuf_append(lbuf, "\n");
+ 
+      /* get the RunAsGroup Values from the entry */
+-     switch (sss_sudo_get_values(rule, "sudoRunAsGroup", &val_array))
++     switch (handle->fn_get_values(rule, "sudoRunAsGroup", &val_array))
+      {
+      case 0:
+ 	  lbuf_append(lbuf, "    RunAsGroups: ");
+ 	  for (i = 0; val_array[i] != NULL; ++i)
+ 	       lbuf_append(lbuf, "%s%s", i != 0 ? ", " : "", val_array[i]);
+-	  sss_sudo_free_values(val_array);
++	  handle->fn_free_values(val_array);
+ 	  lbuf_append(lbuf, "\n");
+ 	  break;
+      case ENOENT:
+ 	  sudo_debug_printf(2, "No result.");
+ 	  break;
+      default:
+-	  sudo_debug_printf(2, "sss_sudo_get_values(sudoRunAsGroup): != 0");
++	  sudo_debug_printf(2, "handle->fn_get_values(sudoRunAsGroup): != 0");
+ 	  debug_return_int(count);
+      }
+ 
+      /* get the Option Values from the entry */
+-     switch (sss_sudo_get_values(rule, "sudoOption", &val_array))
++     switch (handle->fn_get_values(rule, "sudoOption", &val_array))
+      {
+      case 0:
+ 	  lbuf_append(lbuf, "    Options: ");
+ 	  for (i = 0; val_array[i] != NULL; ++i)
+ 	       lbuf_append(lbuf, "%s%s", i != 0 ? ", " : "", val_array[i]);
+-	  sss_sudo_free_values(val_array);
++	  handle->fn_free_values(val_array);
+ 	  lbuf_append(lbuf, "\n");
+ 	  break;
+      case ENOENT:
+ 	  sudo_debug_printf(2, "No result.");
+ 	  break;
+      default:
+-	  sudo_debug_printf(2, "sss_sudo_get_values(sudoOption): != 0");
++	  sudo_debug_printf(2, "handle->fn_get_values(sudoOption): != 0");
+ 	  debug_return_int(count);
+      }
+ 
+      /* Get the command values from the entry. */
+-     switch (sss_sudo_get_values(rule, "sudoCommand", &val_array)) {
++     switch (handle->fn_get_values(rule, "sudoCommand", &val_array)) {
+      case 0:
+ 	  lbuf_append(lbuf, _("    Commands:\n"));
+ 	  for (i = 0; val_array[i] != NULL; ++i) {
+ 	       lbuf_append(lbuf, "\t%s\n", val_array[i]);
+ 	       count++;
+ 	  }
+-	  sss_sudo_free_values(val_array);
++	  handle->fn_free_values(val_array);
+ 	  break;
+      case ENOENT:
+ 	  sudo_debug_printf(2, "No result.");
+ 	  break;
+      default:
+-	  sudo_debug_printf(2, "sss_sudo_get_values(sudoCommand): != 0");
++	  sudo_debug_printf(2, "handle->fn_get_values(sudoCommand): != 0");
+ 	  debug_return_int(count);
+      }
+ 
+      debug_return_int(count);
+ }
+ 
+-static int sudo_sss_display_entry_short(struct sss_sudo_rule *rule, struct lbuf *lbuf)
++static int sudo_sss_display_entry_short(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule, struct lbuf *lbuf)
+ {
+      char **val_array = NULL;
+      int count = 0, i;
+@@ -1067,58 +1157,58 @@ static int sudo_sss_display_entry_short(
+      lbuf_append(lbuf, "    (");
+ 
+      /* get the RunAsUser Values from the entry */
+-     switch (sss_sudo_get_values(rule, "sudoRunAsUser", &val_array))
++     switch (handle->fn_get_values(rule, "sudoRunAsUser", &val_array))
+      {
+      case 0:
+ 	  for (i = 0; val_array[i] != NULL; ++i)
+ 	       lbuf_append(lbuf, "%s%s", i != 0 ? ", " : "", val_array[i]);
+-	  sss_sudo_free_values(val_array);
++	  handle->fn_free_values(val_array);
+ 	  break;
+      case ENOENT:
+ 	  sudo_debug_printf(2, "No result. Trying old style (sudoRunAs).");
+ 	  /* try old style */
+-	  switch (sss_sudo_get_values(rule, "sudoRunAs", &val_array))
++	  switch (handle->fn_get_values(rule, "sudoRunAs", &val_array))
+ 	  {
+ 	  case 0:
+ 	       for (i = 0; val_array[i] != NULL; ++i)
+ 		    lbuf_append(lbuf, "%s%s", i != 0 ? ", " : "", val_array[i]);
+-	       sss_sudo_free_values(val_array);
++	       handle->fn_free_values(val_array);
+ 	       break;
+ 	  case ENOENT:
+ 	       sudo_debug_printf(2, "No result.");
+ 	       lbuf_append(lbuf, "%s", def_runas_default);
+ 	       break;
+ 	  default:
+-	       sudo_debug_printf(2, "sss_sudo_get_values(sudoRunAs): != 0");
++	       sudo_debug_printf(2, "handle->fn_get_values(sudoRunAs): != 0");
+ 	       debug_return_int(count);
+ 	  }
+ 	  break;
+      default:
+-	  sudo_debug_printf(2, "sss_sudo_get_values(sudoRunAsUser): != 0");
++	  sudo_debug_printf(2, "handle->fn_get_values(sudoRunAsUser): != 0");
+ 	  debug_return_int(count);
+      }
+ 
+      /* get the RunAsGroup Values from the entry */
+-     switch (sss_sudo_get_values(rule, "sudoRunAsGroup", &val_array))
++     switch (handle->fn_get_values(rule, "sudoRunAsGroup", &val_array))
+      {
+      case 0:
+ 	  lbuf_append(lbuf, " : ");
+ 	  for (i = 0; val_array[i] != NULL; ++i)
+ 	       lbuf_append(lbuf, "%s%s", i != 0 ? ", " : "", val_array[i]);
+-	  sss_sudo_free_values(val_array);
++	  handle->fn_free_values(val_array);
+ 	  break;
+      case ENOENT:
+ 	  sudo_debug_printf(2, "No result.");
+ 	  break;
+      default:
+-	  sudo_debug_printf(2, "sss_sudo_get_values(sudoRunAsGroup): != 0");
++	  sudo_debug_printf(2, "handle->fn_get_values(sudoRunAsGroup): != 0");
+ 	  debug_return_int(count);
+      }
+ 
+      lbuf_append(lbuf, ") ");
+ 
+      /* get the Option Values from the entry */
+-     switch (sss_sudo_get_values(rule, "sudoOption", &val_array))
++     switch (handle->fn_get_values(rule, "sudoOption", &val_array))
+      {
+      case 0:
+ 	  for (i = 0; val_array[i] != NULL; ++i) {
+@@ -1136,30 +1226,30 @@ static int sudo_sss_display_entry_short(
+ 				"NOSETENV: " : "SETENV: ");
+ 	  }
+ 
+-	  sss_sudo_free_values(val_array);
++	  handle->fn_free_values(val_array);
+ 	  break;
+      case ENOENT:
+ 	  sudo_debug_printf(2, "No result.");
+ 	  break;
+      default:
+-	  sudo_debug_printf(2, "sss_sudo_get_values(sudoOption): != 0");
++	  sudo_debug_printf(2, "handle->fn_get_values(sudoOption): != 0");
+ 	  debug_return_int(count);
+      }
+ 
+      /* get the Command Values from the entry */
+-     switch (sss_sudo_get_values(rule, "sudoCommand", &val_array)) {
++     switch (handle->fn_get_values(rule, "sudoCommand", &val_array)) {
+      case 0:
+ 	  for (i = 0; val_array[i] != NULL; ++i) {
+ 	       lbuf_append(lbuf, "%s%s", i != 0 ? ", " : "", val_array[i]);
+ 	       count++;
+ 	  }
+-	  sss_sudo_free_values(val_array);
++	  handle->fn_free_values(val_array);
+ 	  break;
+      case ENOENT:
+ 	  sudo_debug_printf(2, "No result.");
+ 	  break;
+      default:
+-	  sudo_debug_printf(2, "sss_sudo_get_values(sudoCommand): != 0");
++	  sudo_debug_printf(2, "handle->fn_get_values(sudoCommand): != 0");
+ 	  debug_return_int(count);
+      }
+      lbuf_append(lbuf, "\n");
+@@ -1193,13 +1283,13 @@ static int sudo_sss_display_privs(struct
+      for (i = 0; i < sss_result->num_rules; ++i) {
+ 	  rule = sss_result->rules + i;
+ 	  if (long_list)
+-	       count += sudo_sss_display_entry_long(rule, lbuf);
++	       count += sudo_sss_display_entry_long(handle, rule, lbuf);
+ 	  else
+-	       count += sudo_sss_display_entry_short(rule, lbuf);
++	       count += sudo_sss_display_entry_short(handle, rule, lbuf);
+      }
+ 
+      if (sss_result != NULL)
+-	  sss_sudo_free_result(sss_result);
++	  handle->fn_free_result(sss_result);
+ 
+      debug_return_int(count);
+ }
diff --git a/sudo-1.8.5-sssd-handle-sss_ret-correctly.patch b/sudo-1.8.5-sssd-handle-sss_ret-correctly.patch
new file mode 100644
index 0000000..b03592a
--- /dev/null
+++ b/sudo-1.8.5-sssd-handle-sss_ret-correctly.patch
@@ -0,0 +1,43 @@
+diff -rup original/plugins/sudoers/sssd.c new/plugins/sudoers/sssd.c
+--- original/plugins/sudoers/sssd.c	2012-07-18 13:17:53.026208728 +0200
++++ new/plugins/sudoers/sssd.c	2012-07-18 13:35:59.780623153 +0200
+@@ -239,6 +239,14 @@ static int sudo_sss_setdefs(struct sudo_
+ 	  debug_return_int(-1);
+      }
+ 
++     if (sss_error == ENOENT) {
++         sudo_debug_printf(2, "The user was not found in SSSD.");
++         debug_return_int(-1);
++     } else if(sss_error != 0) {
++         sudo_debug_printf(2, "sss_error=%u\n", sss_error);
++         debug_return_int(-1);
++     }
++
+      for (i = 0; i < sss_result->num_rules; ++i) {
+ 	  sudo_debug_printf(1, "Parsing cn=defaults, %d/%d", i, sss_result->num_rules);
+ 	  sss_rule = sss_result->rules + i;
+@@ -515,7 +523,7 @@ static struct sss_sudo_result *sudo_sss_
+ 	       }
+ 	       break;
+ 	  case ENOENT:
+-	       sudo_debug_printf(2, "No result.");
++	       sudo_debug_printf(2, "The user was not found in SSSD.");
+ 	  default:
+ 	       sudo_debug_printf(2, "sss_error=%u\n", sss_error);
+ 	       debug_return_ptr(NULL);
+@@ -901,6 +909,14 @@ static int sudo_sss_display_defaults(str
+ 	  goto done;
+      }
+ 
++     if (sss_error == ENOENT) {
++         sudo_debug_printf(2, "The user was not found in SSSD.");
++         goto done;
++     } else if(sss_error != 0) {
++         sudo_debug_printf(2, "sss_error=%u\n", sss_error);
++         goto done;
++     }
++
+      handle->pw = pw;
+ 
+      for (i = 0; i < sss_result->num_rules; ++i) {
+
diff --git a/sudo-1.8.5-sssd-use-sudo_debug_printf.patch b/sudo-1.8.5-sssd-use-sudo_debug_printf.patch
new file mode 100644
index 0000000..25ac0ad
--- /dev/null
+++ b/sudo-1.8.5-sssd-use-sudo_debug_printf.patch
@@ -0,0 +1,600 @@
+diff -rup original/plugins/sudoers/sssd.c new/plugins/sudoers/sssd.c
+--- original/plugins/sudoers/sssd.c	2012-07-17 10:50:20.110201384 +0200
++++ new/plugins/sudoers/sssd.c	2012-07-17 11:09:31.213626613 +0200
+@@ -56,11 +56,6 @@
+ #include "lbuf.h"
+ #include "sudo_debug.h"
+ 
+-extern int debug_level;
+-#define __sssd_debug debug_level
+-
+-#define	DPRINTF(level, fmt, ...) if (__sssd_debug >= (level)) warningx("%s:%d: "fmt, __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__)
+-
+ /* sudo_nss implementation */
+ static int sudo_sss_open(struct sudo_nss *nss);
+ static int sudo_sss_close(struct sudo_nss *nss);
+@@ -88,8 +83,8 @@ static void sudo_sss_attrcpy(struct sss_
+      int i;
+      debug_decl(sudo_sss_attrcpy, SUDO_DEBUG_SSSD)
+ 
+-     DPRINTF(3, "dst=%p, src=%p", dst, src);
+-     DPRINTF(2, "emalloc: cnt=%d", src->num_values);
++     sudo_debug_printf(3, "dst=%p, src=%p", dst, src);
++     sudo_debug_printf(2, "emalloc: cnt=%d", src->num_values);
+ 
+      dst->name = strdup(src->name);
+      dst->num_values = src->num_values;
+@@ -106,8 +101,8 @@ static void sudo_sss_rulecpy(struct sss_
+      int i;
+      debug_decl(sudo_sss_rulecpy, SUDO_DEBUG_SSSD)
+ 
+-     DPRINTF(3, "dst=%p, src=%p", dst, src);
+-     DPRINTF(2, "emalloc: cnt=%d", src->num_attrs);
++     sudo_debug_printf(3, "dst=%p, src=%p", dst, src);
++     sudo_debug_printf(2, "emalloc: cnt=%d", src->num_attrs);
+ 
+      dst->num_attrs = src->num_attrs;
+      dst->attrs = emalloc(sizeof(struct sss_sudo_attr) * dst->num_attrs);
+@@ -132,13 +127,13 @@ static struct sss_sudo_result *sudo_sss_
+      int i, l, r;
+      debug_decl(sudo_sss_filter_result, SUDO_DEBUG_SSSD)
+ 
+-     DPRINTF(3, "in_res=%p, count=%u, act=%s",
++     sudo_debug_printf(3, "in_res=%p, count=%u, act=%s",
+ 	     in_res, in_res->num_rules, act == _SUDO_SSS_FILTER_EXCLUDE ? "EXCLUDE" : "INCLUDE");
+ 
+      if (in_res == NULL)
+        debug_return_ptr(NULL);
+ 
+-     DPRINTF(3, "emalloc: cnt=%d", in_res->num_rules);
++     sudo_debug_printf(3, "emalloc: cnt=%d", in_res->num_rules);
+ 
+      out_res = emalloc(sizeof(struct sss_sudo_result));
+      out_res->rules = in_res->num_rules > 0 ? emalloc(sizeof(struct sss_sudo_rule) * in_res->num_rules) : NULL;
+@@ -150,7 +145,7 @@ static struct sss_sudo_result *sudo_sss_
+ 	  if (( r && act == _SUDO_SSS_FILTER_INCLUDE) ||
+ 	      (!r && act == _SUDO_SSS_FILTER_EXCLUDE))
+ 	  {
+-	       DPRINTF(3, "COPY (%s): %p[%u] => %p[%u] (= %p)",
++	       sudo_debug_printf(3, "COPY (%s): %p[%u] => %p[%u] (= %p)",
+ 		       act == _SUDO_SSS_FILTER_EXCLUDE ? "not excluded" : "included",
+ 		       in_res->rules, i, out_res->rules, l, in_res->rules + i);
+ 
+@@ -160,7 +155,7 @@ static struct sss_sudo_result *sudo_sss_
+      }
+ 
+      if (l < in_res->num_rules) {
+-	  DPRINTF(3, "reallocating result: %p (count: %u -> %u)", out_res->rules, in_res->num_rules, l);
++	  sudo_debug_printf(3, "reallocating result: %p (count: %u -> %u)", out_res->rules, in_res->num_rules, l);
+ 	  out_res->rules = realloc(out_res->rules, sizeof(struct sss_sudo_rule) * l);
+      }
+ 
+@@ -201,7 +196,7 @@ static int sudo_sss_open(struct sudo_nss
+      handle->pw = sudo_user.pw;
+      nss->handle = handle;
+ 
+-     DPRINTF(3, "handle=%p", handle);
++     sudo_debug_printf(3, "handle=%p", handle);
+ 
+      debug_return_int(0);
+ }
+@@ -234,18 +229,18 @@ static int sudo_sss_setdefs(struct sudo_
+      if (handle == NULL)
+ 	  debug_return_int(-1);
+ 
+-     DPRINTF(1, "Looking for cn=defaults");
++     sudo_debug_printf(1, "Looking for cn=defaults");
+ 
+      if (sss_sudo_send_recv_defaults(handle->pw->pw_uid, handle->pw->pw_name,
+ 				     &sss_error, &handle->domainname,
+ 				     &sss_result) != 0)
+      {
+-	  DPRINTF(2, "sss_sudo_send_recv_defaults: != 0, sss_error=%u", sss_error);
++	  sudo_debug_printf(2, "sss_sudo_send_recv_defaults: != 0, sss_error=%u", sss_error);
+ 	  debug_return_int(-1);
+      }
+ 
+      for (i = 0; i < sss_result->num_rules; ++i) {
+-	  DPRINTF(1, "Parsing cn=defaults, %d/%d", i, sss_result->num_rules);
++	  sudo_debug_printf(1, "Parsing cn=defaults, %d/%d", i, sss_result->num_rules);
+ 	  sss_rule = sss_result->rules + i;
+ 	  sudo_sss_parse_options(sss_rule);
+      }
+@@ -262,7 +257,7 @@ static int sudo_sss_checkpw(struct sudo_
+      if (pw->pw_name != handle->pw->pw_name ||
+ 	 pw->pw_uid  != handle->pw->pw_uid)
+      {
+-	  DPRINTF(1, "Requested name or uid don't match the initial once, reinitializing...");
++	  sudo_debug_printf(1, "Requested name or uid don't match the initial once, reinitializing...");
+ 	  handle->pw = pw;
+ 
+ 	  if (sudo_sss_setdefs(nss) != 0)
+@@ -289,7 +284,7 @@ sudo_sss_check_runas_user(struct sss_sud
+      case 0:
+ 	  break;
+      case ENOENT:
+-	  DPRINTF(2, "No result. Trying old style (sudoRunAs)");
++	  sudo_debug_printf(2, "No result. Trying old style (sudoRunAs)");
+ 
+ 	  /* try old style */
+ 	  switch (sss_sudo_get_values(sss_rule, "sudoRunAs", &val_array))
+@@ -297,19 +292,19 @@ sudo_sss_check_runas_user(struct sss_sud
+ 	  case 0:
+ 	       break;
+ 	  case ENOENT:
+-	       DPRINTF(2, "No result. Matching against runas_default");
++	       sudo_debug_printf(2, "No result. Matching against runas_default");
+ 	       /*
+ 		* If there are no runas entries, match runas_default against
+ 		* what the user specified on the command line.
+ 		*/
+ 	       return !strcasecmp(runas_pw->pw_name, def_runas_default);
+ 	  default:
+-	       DPRINTF(2, "sss_sudo_get_values(sudoRunAs): != 0");
++	       sudo_debug_printf(2, "sss_sudo_get_values(sudoRunAs): != 0");
+ 	       debug_return_int(UNSPEC);
+ 	  }
+ 	  break;
+      default:
+-	  DPRINTF(2, "sss_sudo_get_values(sudoRunAsUser): != 0");
++	  sudo_debug_printf(2, "sss_sudo_get_values(sudoRunAsUser): != 0");
+ 	  debug_return_int(UNSPEC);
+      }
+ 
+@@ -334,40 +329,40 @@ sudo_sss_check_runas_user(struct sss_sud
+      for (i = 0; val_array[i] != NULL && !ret; ++i) {
+ 	  val = val_array[i];
+ 
+-	  DPRINTF(3, "val[%d]=%s", i, val);
++	  sudo_debug_printf(3, "val[%d]=%s", i, val);
+ 
+ 	  switch (val[0]) {
+ 	  case '+':
+-	       DPRINTF(3, "netgr_");
++	       sudo_debug_printf(3, "netgr_");
+ 	       if (netgr_matches(val, NULL, NULL, runas_pw->pw_name)) {
+-		    DPRINTF(3, "=> match");
++		    sudo_debug_printf(3, "=> match");
+ 		    ret = true;
+ 	       }
+ 	       break;
+ 	  case '%':
+-	       DPRINTF(3, "usergr_");
++	       sudo_debug_printf(3, "usergr_");
+ 	       if (usergr_matches(val, runas_pw->pw_name, runas_pw)) {
+-		    DPRINTF(3, "=> match");
++		    sudo_debug_printf(3, "=> match");
+ 		    ret = true;
+ 	       }
+ 	       break;
+ 	  case 'A':
+ 	       if (strcmp(val, "ALL") == 0) {
+-		    DPRINTF(3, "ALL => match");
++		    sudo_debug_printf(3, "ALL => match");
+ 		    ret = true;
+ 		    break;
+ 	       }
+ 	       /* FALLTHROUGH */
+-	       DPRINTF(3, "FALLTHROUGH");
++	       sudo_debug_printf(3, "FALLTHROUGH");
+ 	  default:
+ 	       if (strcasecmp(val, runas_pw->pw_name) == 0) {
+-		    DPRINTF(3, "%s == %s (pw_name) => match", val, runas_pw->pw_name);
++		    sudo_debug_printf(3, "%s == %s (pw_name) => match", val, runas_pw->pw_name);
+ 		    ret = true;
+ 	       }
+ 	       break;
+ 	  }
+ 
+-	  DPRINTF(2, "sssd/ldap sudoRunAsUser '%s' ... %s", val, ret ? "MATCH!" : "not");
++	  sudo_debug_printf(2, "sssd/ldap sudoRunAsUser '%s' ... %s", val, ret ? "MATCH!" : "not");
+      }
+ 
+      sss_sudo_free_values(val_array); /* cleanup */
+@@ -393,22 +388,22 @@ sudo_sss_check_runas_group(struct sss_su
+      case 0:
+ 	  break;
+      case ENOENT:
+-	  DPRINTF(2, "No result.");
++	  sudo_debug_printf(2, "No result.");
+ 	  debug_return_int(false);
+      default:
+-	  DPRINTF(2, "sss_sudo_get_values(sudoRunAsGroup): != 0");
++	  sudo_debug_printf(2, "sss_sudo_get_values(sudoRunAsGroup): != 0");
+ 	  debug_return_int(UNSPEC);
+      }
+ 
+      /* walk through values returned, looking for a match */
+      for (i = 0; val_array[i] != NULL; ++i) {
+ 	  val = val_array[i];
+-	  DPRINTF(3, "val[%d]=%s", i, val);
++	  sudo_debug_printf(3, "val[%d]=%s", i, val);
+ 
+ 	  if (strcmp(val, "ALL") == 0 || group_matches(val, runas_gr))
+ 	       ret = true;
+ 
+-	  DPRINTF(2, "sssd/ldap sudoRunAsGroup '%s' ... %s", val, ret ? "MATCH!" : "not");
++	  sudo_debug_printf(2, "sssd/ldap sudoRunAsGroup '%s' ... %s", val, ret ? "MATCH!" : "not");
+      }
+ 
+      sss_sudo_free_values(val_array);
+@@ -450,17 +445,17 @@ static int sudo_sss_check_host(struct ss
+     case 0:
+ 	 break;
+     case ENOENT:
+-	 DPRINTF(2, "No result.");
++	 sudo_debug_printf(2, "No result.");
+ 	 debug_return_int(false);
+     default:
+-	 DPRINTF(2, "sss_sudo_get_values(sudoHost): != 0");
++	 sudo_debug_printf(2, "sss_sudo_get_values(sudoHost): != 0");
+ 	 debug_return_int(ret);
+     }
+ 
+     /* walk through values */
+     for (i = 0; val_array[i] != NULL; ++i) {
+ 	 val = val_array[i];
+-	 DPRINTF(3, "val[%d]=%s", i, val);
++	 sudo_debug_printf(3, "val[%d]=%s", i, val);
+ 
+ 	 /* match any or address or netgroup or hostname */
+ 	 if (!strcmp(val, "ALL") || addr_matches(val) ||
+@@ -468,7 +463,7 @@ static int sudo_sss_check_host(struct ss
+ 	     hostname_matches(user_shost, user_host, val))
+ 	      ret = true;
+ 
+-	 DPRINTF(2, "sssd/ldap sudoHost '%s' ... %s", val, ret ? "MATCH!" : "not");
++	 sudo_debug_printf(2, "sssd/ldap sudoHost '%s' ... %s", val, ret ? "MATCH!" : "not");
+     }
+ 
+     sss_sudo_free_values(val_array);
+@@ -497,8 +492,8 @@ static struct sss_sudo_result *sudo_sss_
+      if (sudo_sss_checkpw(nss, pw) != 0)
+ 	  debug_return_ptr(NULL);
+ 
+-     DPRINTF(1, "  username=%s", handle->pw->pw_name);
+-     DPRINTF(1, "domainname=%s", handle->domainname);
++     sudo_debug_printf(1, "  username=%s", handle->pw->pw_name);
++     sudo_debug_printf(1, "domainname=%s", handle->domainname);
+ 
+      u_sss_result = f_sss_result = NULL;
+ 
+@@ -510,24 +505,24 @@ static struct sss_sudo_result *sudo_sss_
+ 	  case 0:
+ 	       if (u_sss_result != NULL) {
+ 		    if (state != NULL) {
+-			 DPRINTF(3, "state |= USERMATCH");
++			 sudo_debug_printf(3, "state |= USERMATCH");
+ 			 *state |= _SUDO_SSS_STATE_USERMATCH;
+ 		    }
+-		    DPRINTF(2, "Received %u rule(s)", u_sss_result->num_rules);
++		    sudo_debug_printf(2, "Received %u rule(s)", u_sss_result->num_rules);
+ 	       } else {
+-		    DPRINTF(2, "Internal error: u_sss_result == NULL && sss_error == 0");
++		    sudo_debug_printf(2, "Internal error: u_sss_result == NULL && sss_error == 0");
+ 		    debug_return_ptr(NULL);
+ 	       }
+ 	       break;
+ 	  case ENOENT:
+-	       DPRINTF(2, "No result.");
++	       sudo_debug_printf(2, "No result.");
+ 	  default:
+-	       DPRINTF(2, "sss_error=%u\n", sss_error);
++	       sudo_debug_printf(2, "sss_error=%u\n", sss_error);
+ 	       debug_return_ptr(NULL);
+ 	  }
+ 	  break;
+      default:
+-	  DPRINTF(2, "sss_sudo_send_recv: != 0: ret=%d", ret);
++	  sudo_debug_printf(2, "sss_sudo_send_recv: != 0: ret=%d", ret);
+ 	  debug_return_ptr(NULL);
+      }
+ 
+@@ -537,11 +532,11 @@ static struct sss_sudo_result *sudo_sss_
+      if (f_sss_result != NULL)
+ 	  if (f_sss_result->num_rules > 0)
+ 	       if (state != NULL) {
+-		    DPRINTF(3, "state |= HOSTMATCH");
++		    sudo_debug_printf(3, "state |= HOSTMATCH");
+ 		    *state |= _SUDO_SSS_STATE_HOSTMATCH;
+ 	       }
+ 
+-     DPRINTF(3, "u_sss_result=(%p, %u) => f_sss_result=(%p, %u)",
++     sudo_debug_printf(3, "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);
+ 
+      sss_sudo_free_result(u_sss_result);
+@@ -568,17 +563,17 @@ sudo_sss_check_bool(struct sss_sudo_rule
+      case 0:
+ 	  break;
+      case ENOENT:
+-	  DPRINTF(2, "No result.");
++	  sudo_debug_printf(2, "No result.");
+ 	  debug_return_int(ret);
+      default:
+-	  DPRINTF(2, "sss_sudo_get_values: != 0");
++	  sudo_debug_printf(2, "sss_sudo_get_values: != 0");
+ 	  debug_return_int(ret);
+      }
+ 
+      /* walk through options */
+      for (i = 0; val_array[i] != NULL; ++i) {
+ 	  var = val_array[i];
+-	  DPRINTF(2, "sssd/ldap sudoOption: '%s'", var);
++	  sudo_debug_printf(2, "sssd/ldap sudoOption: '%s'", var);
+ 
+ 	  if ((ch = *var) == '!')
+ 	       var++;
+@@ -611,24 +606,24 @@ sudo_sss_check_command(struct sss_sudo_r
+      case 0:
+ 	  break;
+      case ENOENT:
+-	  DPRINTF(2, "No result.");
++	  sudo_debug_printf(2, "No result.");
+ 	  debug_return_int(ret);
+      default:
+-	  DPRINTF(2, "sss_sudo_get_values: != 0");
++	  sudo_debug_printf(2, "sss_sudo_get_values: != 0");
+ 	  debug_return_int(ret);
+      }
+ 
+      for (i = 0; val_array[i] != NULL && ret != false; ++i) {
+ 	  val = val_array[i];
+ 
+-	  DPRINTF(3, "val[%d]=%s", i, val);
++	  sudo_debug_printf(3, "val[%d]=%s", i, val);
+ 
+ 	  /* Match against ALL ? */
+ 	  if (!strcmp(val, "ALL")) {
+ 	       ret = true;
+ 	       if (setenv_implied != NULL)
+ 		    *setenv_implied = true;
+-	       DPRINTF(2, "sssd/ldap sudoCommand '%s' ... MATCH!", val);
++	       sudo_debug_printf(2, "sssd/ldap sudoCommand '%s' ... MATCH!", val);
+ 	       continue;
+ 	  }
+ 
+@@ -655,7 +650,7 @@ sudo_sss_check_command(struct sss_sudo_r
+ 	       ret = foundbang ? false : true;
+ 	  }
+ 
+-	  DPRINTF(2, "sssd/ldap sudoCommand '%s' ... %s", val, ret == true ? "MATCH!" : "not");
++	  sudo_debug_printf(2, "sssd/ldap sudoCommand '%s' ... %s", val, ret == true ? "MATCH!" : "not");
+ 	  efree(allowed_cmnd);	/* cleanup */
+      }
+ 
+@@ -680,16 +675,16 @@ sudo_sss_parse_options(struct sss_sudo_r
+      case 0:
+ 	  break;
+      case ENOENT:
+-	  DPRINTF(2, "No result.");
++	  sudo_debug_printf(2, "No result.");
+ 	  debug_return;
+      default:
+-	  DPRINTF(2, "sss_sudo_get_values(sudoOption): != 0");
++	  sudo_debug_printf(2, "sss_sudo_get_values(sudoOption): != 0");
+ 	  debug_return;
+      }
+ 
+      /* walk through options */
+      for (i = 0; val_array[i] != NULL; i++) {
+-	  DPRINTF(2, "sssd/ldap sudoOption: '%s'", val_array[i]);
++	  sudo_debug_printf(2, "sssd/ldap sudoOption: '%s'", val_array[i]);
+ 	  v = estrdup(val_array[i]);
+ 
+ 	  /* check for equals sign past first char */
+@@ -741,7 +736,7 @@ static int sudo_sss_lookup(struct sudo_n
+ 	enum def_tuple pwcheck =
+ 	    (pwflag == -1) ? never : sudo_defs_table[pwflag].sd_un.tuple;
+ 
+-	DPRINTF(2, "perform search for pwflag %d", pwflag);
++	sudo_debug_printf(2, "perform search for pwflag %d", pwflag);
+ 	if (sss_result != NULL) {
+ 	     for (i = 0; i < sss_result->num_rules; i++) {
+ 		  rule = sss_result->rules + i;
+@@ -782,7 +777,7 @@ static int sudo_sss_lookup(struct sudo_n
+ 	goto done;
+     }
+ 
+-    DPRINTF(1, "searching SSSD/LDAP for sudoers entries");
++    sudo_debug_printf(1, "searching SSSD/LDAP for sudoers entries");
+ 
+     setenv_implied = false;
+     if (sss_result != NULL) {
+@@ -793,9 +788,9 @@ static int sudo_sss_lookup(struct sudo_n
+ 	      rc = sudo_sss_check_command(rule, &setenv_implied);
+ 	      if (rc != UNSPEC) {
+ 		   /* We have a match. */
+-		   DPRINTF(1, "Command %sallowed", rc == true ? "" : "NOT ");
++		   sudo_debug_printf(1, "Command %sallowed", rc == true ? "" : "NOT ");
+ 		   if (rc == true) {
+-			DPRINTF(3, "SSSD rule: %p", rule);
++			sudo_debug_printf(3, "SSSD rule: %p", rule);
+ 			/* Apply entry-specific options. */
+ 			if (setenv_implied)
+ 			     def_setenv = true;
+@@ -818,7 +813,7 @@ static int sudo_sss_lookup(struct sudo_n
+ 	 }
+     }
+ done:
+-    DPRINTF(1, "Done with LDAP searches");
++    sudo_debug_printf(1, "Done with LDAP searches");
+ 
+     if (!ISSET(ret, VALIDATE_OK)) {
+ 	/* No matching entries. */
+@@ -831,7 +826,7 @@ done:
+     if (state & _SUDO_SSS_STATE_HOSTMATCH)
+ 	 CLR(ret, FLAG_NO_HOST);
+ 
+-    DPRINTF(3, "sudo_sss_lookup(%d)=0x%02x", pwflag, ret);
++    sudo_debug_printf(3, "sudo_sss_lookup(%d)=0x%02x", pwflag, ret);
+ 
+     debug_return_int(ret);
+ }
+@@ -854,7 +849,7 @@ static int sudo_sss_display_cmnd(struct 
+       * The sudo_sss_result_get() function returns all nodes that match
+       * the user and the host.
+       */
+-     DPRINTF(1, "sssd/ldap search for command list");
++     sudo_debug_printf(1, "sssd/ldap search for command list");
+      sss_result = sudo_sss_result_get(nss, pw, NULL);
+ 
+      if (sss_result == NULL)
+@@ -902,7 +897,7 @@ static int sudo_sss_display_defaults(str
+ 				     &sss_error, &handle->domainname,
+ 				     &sss_result) != 0)
+      {
+-	  DPRINTF(2, "sss_sudo_send_recv_defaults: !=0, sss_error=%u", sss_error);
++	  sudo_debug_printf(2, "sss_sudo_send_recv_defaults: !=0, sss_error=%u", sss_error);
+ 	  goto done;
+      }
+ 
+@@ -916,10 +911,10 @@ static int sudo_sss_display_defaults(str
+ 	  case 0:
+ 	       break;
+ 	  case ENOENT:
+-	       DPRINTF(2, "No result.");
++	       sudo_debug_printf(2, "No result.");
+ 	       continue;
+ 	  default:
+-	       DPRINTF(2, "sss_sudo_get_values: != 0");
++	       sudo_debug_printf(2, "sss_sudo_get_values: != 0");
+ 	       continue;
+ 	  }
+ 
+@@ -976,16 +971,16 @@ static int sudo_sss_display_entry_long(s
+ 	       sss_sudo_free_values(val_array);
+ 	       break;
+ 	  case ENOENT:
+-	       DPRINTF(2, "No result.");
++	       sudo_debug_printf(2, "No result.");
+ 	       lbuf_append(lbuf, "%s", def_runas_default);
+ 	       break;
+ 	  default:
+-	       DPRINTF(2, "sss_sudo_get_values(sudoRunAs): != 0");
++	       sudo_debug_printf(2, "sss_sudo_get_values(sudoRunAs): != 0");
+ 	       debug_return_int(count);
+ 	  }
+ 	  break;
+      default:
+-	  DPRINTF(2, "sss_sudo_get_values(sudoRunAsUser): != 0");
++	  sudo_debug_printf(2, "sss_sudo_get_values(sudoRunAsUser): != 0");
+ 	  debug_return_int(count);
+      }
+      lbuf_append(lbuf, "\n");
+@@ -1001,10 +996,10 @@ static int sudo_sss_display_entry_long(s
+ 	  lbuf_append(lbuf, "\n");
+ 	  break;
+      case ENOENT:
+-	  DPRINTF(2, "No result.");
++	  sudo_debug_printf(2, "No result.");
+ 	  break;
+      default:
+-	  DPRINTF(2, "sss_sudo_get_values(sudoRunAsGroup): != 0");
++	  sudo_debug_printf(2, "sss_sudo_get_values(sudoRunAsGroup): != 0");
+ 	  debug_return_int(count);
+      }
+ 
+@@ -1019,10 +1014,10 @@ static int sudo_sss_display_entry_long(s
+ 	  lbuf_append(lbuf, "\n");
+ 	  break;
+      case ENOENT:
+-	  DPRINTF(2, "No result.");
++	  sudo_debug_printf(2, "No result.");
+ 	  break;
+      default:
+-	  DPRINTF(2, "sss_sudo_get_values(sudoOption): != 0");
++	  sudo_debug_printf(2, "sss_sudo_get_values(sudoOption): != 0");
+ 	  debug_return_int(count);
+      }
+ 
+@@ -1037,10 +1032,10 @@ static int sudo_sss_display_entry_long(s
+ 	  sss_sudo_free_values(val_array);
+ 	  break;
+      case ENOENT:
+-	  DPRINTF(2, "No result.");
++	  sudo_debug_printf(2, "No result.");
+ 	  break;
+      default:
+-	  DPRINTF(2, "sss_sudo_get_values(sudoCommand): != 0");
++	  sudo_debug_printf(2, "sss_sudo_get_values(sudoCommand): != 0");
+ 	  debug_return_int(count);
+      }
+ 
+@@ -1064,7 +1059,7 @@ static int sudo_sss_display_entry_short(
+ 	  sss_sudo_free_values(val_array);
+ 	  break;
+      case ENOENT:
+-	  DPRINTF(2, "No result. Trying old style (sudoRunAs).");
++	  sudo_debug_printf(2, "No result. Trying old style (sudoRunAs).");
+ 	  /* try old style */
+ 	  switch (sss_sudo_get_values(rule, "sudoRunAs", &val_array))
+ 	  {
+@@ -1074,16 +1069,16 @@ static int sudo_sss_display_entry_short(
+ 	       sss_sudo_free_values(val_array);
+ 	       break;
+ 	  case ENOENT:
+-	       DPRINTF(2, "No result.");
++	       sudo_debug_printf(2, "No result.");
+ 	       lbuf_append(lbuf, "%s", def_runas_default);
+ 	       break;
+ 	  default:
+-	       DPRINTF(2, "sss_sudo_get_values(sudoRunAs): != 0");
++	       sudo_debug_printf(2, "sss_sudo_get_values(sudoRunAs): != 0");
+ 	       debug_return_int(count);
+ 	  }
+ 	  break;
+      default:
+-	  DPRINTF(2, "sss_sudo_get_values(sudoRunAsUser): != 0");
++	  sudo_debug_printf(2, "sss_sudo_get_values(sudoRunAsUser): != 0");
+ 	  debug_return_int(count);
+      }
+ 
+@@ -1097,10 +1092,10 @@ static int sudo_sss_display_entry_short(
+ 	  sss_sudo_free_values(val_array);
+ 	  break;
+      case ENOENT:
+-	  DPRINTF(2, "No result.");
++	  sudo_debug_printf(2, "No result.");
+ 	  break;
+      default:
+-	  DPRINTF(2, "sss_sudo_get_values(sudoRunAsGroup): != 0");
++	  sudo_debug_printf(2, "sss_sudo_get_values(sudoRunAsGroup): != 0");
+ 	  debug_return_int(count);
+      }
+ 
+@@ -1128,10 +1123,10 @@ static int sudo_sss_display_entry_short(
+ 	  sss_sudo_free_values(val_array);
+ 	  break;
+      case ENOENT:
+-	  DPRINTF(2, "No result.");
++	  sudo_debug_printf(2, "No result.");
+ 	  break;
+      default:
+-	  DPRINTF(2, "sss_sudo_get_values(sudoOption): != 0");
++	  sudo_debug_printf(2, "sss_sudo_get_values(sudoOption): != 0");
+ 	  debug_return_int(count);
+      }
+ 
+@@ -1145,10 +1140,10 @@ static int sudo_sss_display_entry_short(
+ 	  sss_sudo_free_values(val_array);
+ 	  break;
+      case ENOENT:
+-	  DPRINTF(2, "No result.");
++	  sudo_debug_printf(2, "No result.");
+ 	  break;
+      default:
+-	  DPRINTF(2, "sss_sudo_get_values(sudoCommand): != 0");
++	  sudo_debug_printf(2, "sss_sudo_get_values(sudoCommand): != 0");
+ 	  debug_return_int(count);
+      }
+      lbuf_append(lbuf, "\n");
+@@ -1171,7 +1166,7 @@ static int sudo_sss_display_privs(struct
+      if (sudo_sss_checkpw(nss, pw) != 0)
+ 	  debug_return_int(-1);
+ 
+-     DPRINTF(2, "sssd/ldap search for command list");
++     sudo_debug_printf(2, "sssd/ldap search for command list");
+ 
+      sss_result = sudo_sss_result_get(nss, pw, NULL);
+ 
diff --git a/sudo.spec b/sudo.spec
index 8132bf4..3e5df6b 100644
--- a/sudo.spec
+++ b/sudo.spec
@@ -1,7 +1,7 @@
 Summary: Allows restricted root access for specified users
 Name: sudo
 Version: 1.8.5
-Release: 3%{?dist}
+Release: 4%{?dist}
 License: ISC
 Group: Applications/System
 URL: http://www.courtesan.com/sudo/
@@ -20,7 +20,6 @@ BuildRequires: audit-libs-devel libcap-devel
 BuildRequires: libselinux-devel
 BuildRequires: sendmail
 BuildRequires: gettext
-BuildRequires: libsss_sudo-devel
 
 # don't strip
 Patch1: sudo-1.6.7p5-strip.patch
@@ -32,6 +31,17 @@ Patch3: sudo-1.7.4p3-m4path.patch
 Patch4: sudo-1.8.5-pipelist.patch
 # SSSD support
 Patch5: sudo-1.8.5-sssd-support.patch
+# Add SSSD debug subsystem
+Patch6: sudo-1.8.5-add-sssd-debug-subsystem.patch
+# Use sudo_debug_printf instead of DPRINTF in sssd.c
+Patch7: sudo-1.8.5-sssd-use-sudo_debug_printf.patch
+# Handle sss_ret correctly in sssd.c to avoid segfault
+# when user is not found in sssd
+Patch8: sudo-1.8.5-sssd-handle-sss_ret-correctly.patch
+# dlopen libsss_sudo
+Patch9: sudo-1.8.5-sssd-dlopen-lib.patch
+# remove source when nss->open() fails
+Patch10: sudo-1.8.5-remove-source-when-open-failed.patch
 
 %description
 Sudo (superuser do) allows a system administrator to give certain
@@ -61,7 +71,11 @@ plugins that use %{name}.
 %patch3 -p1 -b .m4path
 %patch4 -p1 -b .pipelist
 %patch5 -p1 -b .sssd-support
-
+%patch6 -p1
+%patch7 -p1
+%patch8 -p1
+%patch9 -p1
+%patch10 -p1
 
 %build
 autoreconf -fv --install
@@ -90,8 +104,8 @@ export CFLAGS="$RPM_OPT_FLAGS $F_PIE" LDFLAGS="-pie -Wl,-z,relro -Wl,-z,now"
         --with-ldap \
 	--with-selinux \
 	--with-passprompt="[sudo] password for %p: " \
-	--with-linux-audit
-#	--with-sssd
+	--with-linux-audit \
+	--with-sssd
 #	--without-kerb5 \
 #	--without-kerb4
 make
@@ -171,6 +185,11 @@ rm -rf $RPM_BUILD_ROOT
 %{_mandir}/man8/sudo_plugin.8*
 
 %changelog
+* Thu Jul 26 2012 Daniel Kopecek <dkopecek at redhat.com> - 1.8.5-4
+- added patches that fix & improve SSSD support (thanks to pbrezina at redhat.com)
+- re-enabled SSSD support
+- removed libsss_sudo dependency
+
 * Tue Jul 24 2012 Bill Nottingham <notting at redhat.com> - 1.8.5-3
 - flip sudoers2ldif executable bit after make install, not in setup
 


More information about the scm-commits mailing list