The getdefs() function now get called multiple times so use the

cached data if present.
This commit is contained in:
Todd C. Miller
2018-05-29 10:53:47 -06:00
parent 899aedfd10
commit 919b567229
2 changed files with 33 additions and 25 deletions

View File

@@ -154,6 +154,7 @@ struct sudo_ldap_handle {
struct passwd *pw; struct passwd *pw;
struct userspec_list userspecs; struct userspec_list userspecs;
struct defaults_list defaults; struct defaults_list defaults;
bool cached_defaults;
}; };
#ifdef HAVE_LDAP_INITIALIZE #ifdef HAVE_LDAP_INITIALIZE
@@ -1669,12 +1670,12 @@ done:
static struct defaults_list * static struct defaults_list *
sudo_ldap_getdefs(struct sudo_nss *nss) sudo_ldap_getdefs(struct sudo_nss *nss)
{ {
struct ldap_config_str *base;
struct sudo_ldap_handle *handle = nss->handle; struct sudo_ldap_handle *handle = nss->handle;
struct defaults_list *ret = &handle->defaults;
struct timeval tv, *tvp = NULL; struct timeval tv, *tvp = NULL;
struct defaults_list *ret = NULL; struct ldap_config_str *base;
LDAPMessage *entry, *result = NULL; LDAPMessage *entry, *result = NULL;
char *filt; char *filt = NULL;
int rc; int rc;
debug_decl(sudo_ldap_getdefs, SUDOERS_DEBUG_LDAP) debug_decl(sudo_ldap_getdefs, SUDOERS_DEBUG_LDAP)
@@ -1684,8 +1685,9 @@ sudo_ldap_getdefs(struct sudo_nss *nss)
debug_return_ptr(NULL); debug_return_ptr(NULL);
} }
/* Free old defaults, if any. */ /* Use cached result if present. */
free_defaults(&handle->defaults); if (handle->cached_defaults)
goto done;
filt = sudo_ldap_build_default_filter(); filt = sudo_ldap_build_default_filter();
if (filt == NULL) { if (filt == NULL) {
@@ -1708,13 +1710,15 @@ sudo_ldap_getdefs(struct sudo_nss *nss)
filt, NULL, 0, NULL, NULL, tvp, 0, &result); filt, NULL, 0, NULL, NULL, tvp, 0, &result);
if (rc == LDAP_SUCCESS && (entry = ldap_first_entry(ld, result))) { if (rc == LDAP_SUCCESS && (entry = ldap_first_entry(ld, result))) {
DPRINTF1("found:%s", ldap_get_dn(ld, entry)); DPRINTF1("found:%s", ldap_get_dn(ld, entry));
if (!sudo_ldap_parse_options(ld, entry, &handle->defaults)) if (!sudo_ldap_parse_options(ld, entry, &handle->defaults)) {
ret = NULL;
goto done; goto done;
}
} else { } else {
DPRINTF1("no default options found in %s", base->val); DPRINTF1("no default options found in %s", base->val);
} }
} }
ret = &handle->defaults; handle->cached_defaults = true;
done: done:
ldap_msgfree(result); ldap_msgfree(result);

View File

@@ -85,6 +85,7 @@ struct sudo_sss_handle {
void *ssslib; void *ssslib;
struct userspec_list userspecs; struct userspec_list userspecs;
struct defaults_list defaults; struct defaults_list defaults;
bool cached_defaults;
sss_sudo_send_recv_t fn_send_recv; sss_sudo_send_recv_t fn_send_recv;
sss_sudo_send_recv_defaults_t fn_send_recv_defaults; sss_sudo_send_recv_defaults_t fn_send_recv_defaults;
sss_sudo_free_result_t fn_free_result; sss_sudo_free_result_t fn_free_result;
@@ -695,7 +696,6 @@ sudo_sss_getdefs(struct sudo_nss *nss)
{ {
struct sudo_sss_handle *handle = nss->handle; struct sudo_sss_handle *handle = nss->handle;
struct sss_sudo_result *sss_result = NULL; struct sss_sudo_result *sss_result = NULL;
struct sss_sudo_rule *sss_rule;
uint32_t sss_error; uint32_t sss_error;
unsigned int i; unsigned int i;
int rc; int rc;
@@ -707,8 +707,9 @@ sudo_sss_getdefs(struct sudo_nss *nss)
debug_return_ptr(NULL); debug_return_ptr(NULL);
} }
/* Free old defaults, if any. */ /* Use cached result if present. */
free_defaults(&handle->defaults); if (handle->cached_defaults)
debug_return_ptr(&handle->defaults);
sudo_debug_printf(SUDO_DEBUG_DIAG, "Looking for cn=defaults"); sudo_debug_printf(SUDO_DEBUG_DIAG, "Looking for cn=defaults");
@@ -726,27 +727,30 @@ sudo_sss_getdefs(struct sudo_nss *nss)
"handle->fn_send_recv_defaults: rc=%d, sss_error=%u", rc, sss_error); "handle->fn_send_recv_defaults: rc=%d, sss_error=%u", rc, sss_error);
debug_return_ptr(NULL); debug_return_ptr(NULL);
} }
if (sss_error != 0) {
if (sss_error == ENOENT) { switch (sss_error) {
sudo_debug_printf(SUDO_DEBUG_INFO, case 0:
"No global defaults entry found in SSSD."); /* Success */
goto done; for (i = 0; i < sss_result->num_rules; ++i) {
struct sss_sudo_rule *sss_rule = sss_result->rules + i;
sudo_debug_printf(SUDO_DEBUG_DIAG,
"Parsing cn=defaults, %d/%d", i, sss_result->num_rules);
if (!sudo_sss_parse_options(handle, sss_rule, &handle->defaults))
goto bad;
} }
break;
case ENOENT:
sudo_debug_printf(SUDO_DEBUG_INFO,
"No global defaults entry found in SSSD.");
break;
default:
sudo_debug_printf(SUDO_DEBUG_ERROR, "sss_error=%u\n", sss_error); sudo_debug_printf(SUDO_DEBUG_ERROR, "sss_error=%u\n", sss_error);
goto bad; goto bad;
} }
handle->cached_defaults = true;
for (i = 0; i < sss_result->num_rules; ++i) {
sudo_debug_printf(SUDO_DEBUG_DIAG,
"Parsing cn=defaults, %d/%d", i, sss_result->num_rules);
sss_rule = sss_result->rules + i;
if (!sudo_sss_parse_options(handle, sss_rule, &handle->defaults))
goto bad;
}
done:
handle->fn_free_result(sss_result); handle->fn_free_result(sss_result);
debug_return_ptr(&handle->defaults); debug_return_ptr(&handle->defaults);
bad: bad:
handle->fn_free_result(sss_result); handle->fn_free_result(sss_result);
debug_return_ptr(NULL); debug_return_ptr(NULL);