--- embedaddon/sudo/plugins/sudoers/sssd.c 2013/10/14 07:56:35 1.1.1.3 +++ embedaddon/sudo/plugins/sudoers/sssd.c 2014/06/15 16:12:54 1.1.1.4 @@ -40,14 +40,9 @@ #ifdef HAVE_UNISTD_H # include #endif /* HAVE_UNISTD_H */ -#if TIME_WITH_SYS_TIME +#ifdef TIME_WITH_SYS_TIME # include #endif -#ifdef HAVE_DLOPEN -# include -#else -# include "compat/dlfcn.h" -#endif #include #include #include @@ -58,6 +53,7 @@ #include "sudoers.h" #include "parse.h" #include "lbuf.h" +#include "sudo_dso.h" #include "sudo_debug.h" /* SSSD <--> SUDO interface - do not change */ @@ -179,7 +175,7 @@ sudo_sss_filter_result(struct sudo_sss_handle *handle, debug_decl(sudo_sss_filter_result, SUDO_DEBUG_SSSD) sudo_debug_printf(SUDO_DEBUG_DEBUG, "in_res=%p, count=%u, act=%s", - in_res, in_res->num_rules, + in_res, in_res ? in_res->num_rules : 0, act == _SUDO_SSS_FILTER_EXCLUDE ? "EXCLUDE" : "INCLUDE"); if (in_res == NULL) @@ -226,8 +222,7 @@ sudo_sss_filter_result(struct sudo_sss_handle *handle, } struct sudo_nss sudo_nss_sss = { - &sudo_nss_sss, - NULL, + { NULL, NULL }, sudo_sss_open, sudo_sss_close, sudo_sss_parse, @@ -251,45 +246,49 @@ static int sudo_sss_open(struct sudo_nss *nss) handle = emalloc(sizeof(struct sudo_sss_handle)); /* Load symbols */ - handle->ssslib = dlopen(path, RTLD_LAZY); + handle->ssslib = sudo_dso_load(path, SUDO_DSO_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?")); + warningx(U_("unable to load %s: %s"), path, sudo_dso_strerror()); + warningx(U_("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"); + handle->fn_send_recv = + sudo_dso_findsym(handle->ssslib, "sss_sudo_send_recv"); if (handle->fn_send_recv == NULL) { - warningx(_("unable to find symbol \"%s\" in %s"), path, + warningx(U_("unable to find symbol \"%s\" in %s"), path, "sss_sudo_send_recv"); debug_return_int(EFAULT); } handle->fn_send_recv_defaults = - dlsym(handle->ssslib, "sss_sudo_send_recv_defaults"); + sudo_dso_findsym(handle->ssslib, "sss_sudo_send_recv_defaults"); if (handle->fn_send_recv_defaults == NULL) { - warningx(_("unable to find symbol \"%s\" in %s"), path, + warningx(U_("unable to find symbol \"%s\" in %s"), path, "sss_sudo_send_recv_defaults"); debug_return_int(EFAULT); } - handle->fn_free_result = dlsym(handle->ssslib, "sss_sudo_free_result"); + handle->fn_free_result = + sudo_dso_findsym(handle->ssslib, "sss_sudo_free_result"); if (handle->fn_free_result == NULL) { - warningx(_("unable to find symbol \"%s\" in %s"), path, + warningx(U_("unable to find symbol \"%s\" in %s"), path, "sss_sudo_free_result"); debug_return_int(EFAULT); } - handle->fn_get_values = dlsym(handle->ssslib, "sss_sudo_get_values"); + handle->fn_get_values = + sudo_dso_findsym(handle->ssslib, "sss_sudo_get_values"); if (handle->fn_get_values == NULL) { - warningx(_("unable to find symbol \"%s\" in %s"), path, + warningx(U_("unable to find symbol \"%s\" in %s"), path, "sss_sudo_get_values"); debug_return_int(EFAULT); } - handle->fn_free_values = dlsym(handle->ssslib, "sss_sudo_free_values"); + handle->fn_free_values = + sudo_dso_findsym(handle->ssslib, "sss_sudo_free_values"); if (handle->fn_free_values == NULL) { - warningx(_("unable to find symbol \"%s\" in %s"), path, + warningx(U_("unable to find symbol \"%s\" in %s"), path, "sss_sudo_free_values"); debug_return_int(EFAULT); } @@ -311,10 +310,9 @@ static int sudo_sss_close(struct sudo_nss *nss) if (nss && nss->handle) { handle = nss->handle; - dlclose(handle->ssslib); + sudo_dso_unload(handle->ssslib); + efree(nss->handle); } - - efree(nss->handle); debug_return_int(0); } @@ -534,30 +532,31 @@ sudo_sss_check_runas_group(struct sudo_sss_handle *han * Walk through search results and return true if we have a runas match, * else false. RunAs info is optional. */ -static int +static bool sudo_sss_check_runas(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule) { - int ret; + bool ret; debug_decl(sudo_sss_check_runas, SUDO_DEBUG_SSSD); if (rule == NULL) - debug_return_int(false); + debug_return_bool(false); ret = sudo_sss_check_runas_user(handle, rule) != false && sudo_sss_check_runas_group(handle, rule) != false; - debug_return_int(ret); + debug_return_bool(ret); } -static int +static bool sudo_sss_check_host(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule) { char **val_array, *val; - int ret = false, i; + bool ret = false; + int i; debug_decl(sudo_sss_check_host, SUDO_DEBUG_SSSD); if (rule == NULL) - debug_return_int(ret); + debug_return_bool(ret); /* get the values from the rule */ switch (handle->fn_get_values(rule, "sudoHost", &val_array)) @@ -566,10 +565,10 @@ sudo_sss_check_host(struct sudo_sss_handle *handle, st break; case ENOENT: sudo_debug_printf(SUDO_DEBUG_INFO, "No result."); - debug_return_int(false); + debug_return_bool(false); default: sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_get_values(sudoHost): != 0"); - debug_return_int(ret); + debug_return_bool(ret); } /* walk through values */ @@ -589,9 +588,58 @@ sudo_sss_check_host(struct sudo_sss_handle *handle, st handle->fn_free_values(val_array); - debug_return_int(ret); + debug_return_bool(ret); } +/* + * Look for netgroup specifcations in the sudoUser attribute and + * if found, filter according to netgroup membership. + * returns: + * true -> netgroup spec found && netgroup member + * false -> netgroup spec found && not a member of netgroup + * true -> netgroup spec not found (filtered by SSSD already, netgroups are an exception) + */ +static bool +sudo_sss_filter_user_netgroup(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule) +{ + bool ret = false, netgroup_spec_found = false; + char **val_array, *val; + int i; + debug_decl(sudo_sss_filter_user_netgroup, SUDO_DEBUG_SSSD); + + if (!handle || !rule) + debug_return_bool(ret); + + switch (handle->fn_get_values(rule, "sudoUser", &val_array)) { + case 0: + break; + case ENOENT: + sudo_debug_printf(SUDO_DEBUG_INFO, "No result."); + debug_return_bool(ret); + default: + sudo_debug_printf(SUDO_DEBUG_INFO, + "handle->fn_get_values(sudoUser): != 0"); + debug_return_bool(ret); + } + + 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, handle->pw->pw_name)) { + ret = true; + sudo_debug_printf(SUDO_DEBUG_DIAG, + "sssd/ldap sudoUser '%s' ... MATCH! (%s)", + val, handle->pw->pw_name); + break; + } + } + handle->fn_free_values(val_array); + debug_return_bool(netgroup_spec_found ? ret : true); +} + static int sudo_sss_result_filterp(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule, void *unused) @@ -599,7 +647,8 @@ sudo_sss_result_filterp(struct sudo_sss_handle *handle (void)unused; debug_decl(sudo_sss_result_filterp, SUDO_DEBUG_SSSD); - if (sudo_sss_check_host(handle, rule)) + if (sudo_sss_check_host(handle, rule) && + sudo_sss_filter_user_netgroup(handle, rule)) debug_return_int(1); else debug_return_int(0); @@ -617,7 +666,8 @@ sudo_sss_result_get(struct sudo_nss *nss, struct passw debug_return_ptr(NULL); sudo_debug_printf(SUDO_DEBUG_DIAG, " username=%s", handle->pw->pw_name); - sudo_debug_printf(SUDO_DEBUG_DIAG, "domainname=%s", handle->domainname); + sudo_debug_printf(SUDO_DEBUG_DIAG, "domainname=%s", + handle->domainname ? handle->domainname : "NULL"); u_sss_result = f_sss_result = NULL; @@ -664,11 +714,14 @@ sudo_sss_result_get(struct sudo_nss *nss, struct passw *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);