From: Todd C. Miller Date: Tue, 29 May 2018 15:39:40 +0000 (-0600) Subject: Move cached userspecs and defaults into the handle object. X-Git-Tag: SUDO_1_8_24^2~56 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0b31f186cdf7723eb782dd7722401534c113e867;p=sudo Move cached userspecs and defaults into the handle object. --- diff --git a/plugins/sudoers/file.c b/plugins/sudoers/file.c index 71e498392..c83e91605 100644 --- a/plugins/sudoers/file.c +++ b/plugins/sudoers/file.c @@ -38,35 +38,61 @@ #include "sudo_lbuf.h" #include -static int -sudo_file_open(struct sudo_nss *nss) -{ - debug_decl(sudo_file_open, SUDOERS_DEBUG_NSS) - - if (def_ignore_local_sudoers) - debug_return_int(-1); - nss->handle = open_sudoers(sudoers_file, false, NULL); - debug_return_int(nss->handle ? 0 : -1); -} +struct sudo_file_handle { + FILE *fp; + struct defaults_list defaults; + struct userspec_list userspecs; +}; static int sudo_file_close(struct sudo_nss *nss) { debug_decl(sudo_file_close, SUDOERS_DEBUG_NSS) + struct sudo_file_handle *handle = nss->handle; - if (nss->handle != NULL) { - fclose(nss->handle); - nss->handle = NULL; + if (handle != NULL) { + fclose(handle->fp); sudoersin = NULL; - /* XXX - do in main module? */ - free_userspecs(&nss->userspecs); - free_defaults(&nss->defaults); + free_userspecs(&handle->userspecs); + free_defaults(&handle->defaults); + + nss->handle = NULL; } debug_return_int(0); } +static int +sudo_file_open(struct sudo_nss *nss) +{ + debug_decl(sudo_file_open, SUDOERS_DEBUG_NSS) + struct sudo_file_handle *handle; + + if (def_ignore_local_sudoers) + debug_return_int(-1); + + if (nss->handle != NULL) { + sudo_debug_printf(SUDO_DEBUG_ERROR, + "%s: called with non-NULL handle %p", __func__, nss->handle); + sudo_file_close(nss); + } + + handle = malloc(sizeof(*handle)); + if (handle != NULL) { + handle->fp = open_sudoers(sudoers_file, false, NULL); + if (handle->fp != NULL) { + TAILQ_INIT(&handle->userspecs); + TAILQ_INIT(&handle->defaults); + } else { + free(handle); + handle = NULL; + } + } + nss->handle = handle; + debug_return_int(nss->handle ? 0 : -1); +} + /* * Parse the specified sudoers file. */ @@ -74,11 +100,15 @@ static int sudo_file_parse(struct sudo_nss *nss) { debug_decl(sudo_file_close, SUDOERS_DEBUG_NSS) + struct sudo_file_handle *handle = nss->handle; - if (nss->handle == NULL) + if (handle == NULL || handle->fp == NULL) { + sudo_debug_printf(SUDO_DEBUG_ERROR, "%s: called with NULL %s", + __func__, handle ? "file pointer" : "handle"); debug_return_int(-1); + } - sudoersin = nss->handle; + sudoersin = handle->fp; if (sudoersparse() != 0 || parse_error) { if (errorlineno != -1) { log_warningx(SLOG_SEND_MAIL, N_("parse error in %s near line %d"), @@ -90,30 +120,45 @@ sudo_file_parse(struct sudo_nss *nss) } /* Move parsed userspecs and defaults to nss structure. */ - TAILQ_CONCAT(&nss->userspecs, &userspecs, entries); - TAILQ_CONCAT(&nss->defaults, &defaults, entries); + TAILQ_CONCAT(&handle->userspecs, &userspecs, entries); + TAILQ_CONCAT(&handle->defaults, &defaults, entries); debug_return_int(0); } /* - * No need for explicit queries for sudoers file, we have it all in memory. + * We return all cached userspecs, the parse functions will + * perform matching against pw for us. */ -static int +static struct userspec_list * sudo_file_query(struct sudo_nss *nss, struct passwd *pw) { + struct sudo_file_handle *handle = nss->handle; debug_decl(sudo_file_query, SUDOERS_DEBUG_NSS) - debug_return_int(0); + + if (handle == NULL) { + sudo_debug_printf(SUDO_DEBUG_ERROR, + "%s: called with NULL handle", __func__); + debug_return_ptr(NULL); + } + debug_return_ptr(&handle->userspecs); } /* - * No need to get defaults for sudoers file, the parse function handled it. + * Return cached defaults entries. */ -static int +static struct defaults_list * sudo_file_getdefs(struct sudo_nss *nss) { debug_decl(sudo_file_getdefs, SUDOERS_DEBUG_NSS) - debug_return_int(0); + struct sudo_file_handle *handle = nss->handle; + + if (handle == NULL) { + sudo_debug_printf(SUDO_DEBUG_ERROR, + "%s: called with NULL handle", __func__); + debug_return_ptr(NULL); + } + debug_return_ptr(&handle->defaults); } /* sudo_nss implementation */ diff --git a/plugins/sudoers/ldap.c b/plugins/sudoers/ldap.c index c3f34f401..da15a1e3a 100644 --- a/plugins/sudoers/ldap.c +++ b/plugins/sudoers/ldap.c @@ -152,6 +152,8 @@ STAILQ_HEAD(ldap_netgroup_list, ldap_netgroup); struct sudo_ldap_handle { LDAP *ld; struct passwd *pw; + struct userspec_list userspecs; + struct defaults_list defaults; }; #ifdef HAVE_LDAP_INITIALIZE @@ -1540,6 +1542,33 @@ done: debug_return_int(ret); } +/* + * Shut down the LDAP connection. + */ +static int +sudo_ldap_close(struct sudo_nss *nss) +{ + struct sudo_ldap_handle *handle = nss->handle; + debug_decl(sudo_ldap_close, SUDOERS_DEBUG_LDAP) + + if (handle != NULL) { + /* Unbind and close the LDAP connection. */ + if (handle->ld != NULL) { + ldap_unbind_ext_s(handle->ld, NULL, NULL); + handle->ld = NULL; + } + + /* Free the handle container. */ + if (handle->pw != NULL) + sudo_pw_delref(handle->pw); + free_userspecs(&handle->userspecs); + free_defaults(&handle->defaults); + free(handle); + nss->handle = NULL; + } + debug_return_int(0); +} + /* * Open a connection to the LDAP server. * Returns 0 on success and non-zero on failure. @@ -1553,6 +1582,12 @@ sudo_ldap_open(struct sudo_nss *nss) struct sudo_ldap_handle *handle; debug_decl(sudo_ldap_open, SUDOERS_DEBUG_LDAP) + if (nss->handle != NULL) { + sudo_debug_printf(SUDO_DEBUG_ERROR, + "%s: called with non-NULL handle %p", __func__, nss->handle); + sudo_ldap_close(nss); + } + if (!sudo_ldap_read_config()) goto done; @@ -1632,42 +1667,46 @@ sudo_ldap_open(struct sudo_nss *nss) goto done; } handle->ld = ld; - /* handle->result = NULL; */ - /* handle->username = NULL; */ - /* handle->gidlist = NULL; */ + /* handle->pw = NULL; */ + TAILQ_INIT(&handle->userspecs); + TAILQ_INIT(&handle->defaults); nss->handle = handle; done: debug_return_int(rc == LDAP_SUCCESS ? 0 : -1); } -static int +static struct defaults_list * sudo_ldap_getdefs(struct sudo_nss *nss) { struct ldap_config_str *base; struct sudo_ldap_handle *handle = nss->handle; struct timeval tv, *tvp = NULL; - LDAP *ld; + struct defaults_list *ret = NULL; LDAPMessage *entry, *result = NULL; char *filt; - int rc, ret = -1; + int rc; debug_decl(sudo_ldap_getdefs, SUDOERS_DEBUG_LDAP) - if (handle == NULL || handle->ld == NULL) - debug_return_int(-1); - ld = handle->ld; + if (handle == NULL) { + sudo_debug_printf(SUDO_DEBUG_ERROR, + "%s: called with NULL handle", __func__); + debug_return_ptr(NULL); + } /* Free old defaults, if any. */ - free_defaults(&nss->defaults); + free_defaults(&handle->defaults); filt = sudo_ldap_build_default_filter(); if (filt == NULL) { sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); - debug_return_int(-1); + debug_return_ptr(NULL); } DPRINTF1("Looking for cn=defaults: %s", filt); STAILQ_FOREACH(base, &ldap_conf.base, entries) { + LDAP *ld = handle->ld; + if (ldap_conf.timeout > 0) { tv.tv_sec = ldap_conf.timeout; tv.tv_usec = 0; @@ -1679,19 +1718,19 @@ sudo_ldap_getdefs(struct sudo_nss *nss) filt, NULL, 0, NULL, NULL, tvp, 0, &result); if (rc == LDAP_SUCCESS && (entry = ldap_first_entry(ld, result))) { DPRINTF1("found:%s", ldap_get_dn(ld, entry)); - if (!sudo_ldap_parse_options(ld, entry, &nss->defaults)) + if (!sudo_ldap_parse_options(ld, entry, &handle->defaults)) goto done; } else { DPRINTF1("no default options found in %s", base->val); } } - ret = 0; + ret = &handle->defaults; done: ldap_msgfree(result); free(filt); - debug_return_int(ret); + debug_return_ptr(ret); } /* @@ -1777,25 +1816,6 @@ sudo_ldap_result_add_entry(struct ldap_result *lres, LDAPMessage *entry) debug_return_ptr(&lres->entries[lres->nentries - 1]); } -/* - * Free the cached results in the sudo_nss handle, if present. - */ -static void -sudo_ldap_result_free_nss(struct sudo_nss *nss) -{ - struct sudo_ldap_handle *handle = nss->handle; - debug_decl(sudo_ldap_result_free_nss, SUDOERS_DEBUG_LDAP) - - if (handle->pw != NULL) - sudo_pw_delref(handle->pw); - - /* XXX - do in main module? */ - free_userspecs(&nss->userspecs); - free_defaults(&nss->defaults); - - debug_return; -} - /* * Perform the LDAP query for the user. The caller is responsible for * freeing the result with sudo_ldap_result_free(). @@ -1899,48 +1919,23 @@ oom: debug_return_ptr(NULL); } -/* - * Shut down the LDAP connection. - */ -static int -sudo_ldap_close(struct sudo_nss *nss) -{ - struct sudo_ldap_handle *handle = nss->handle; - debug_decl(sudo_ldap_close, SUDOERS_DEBUG_LDAP) - - if (handle != NULL) { - /* Free the cached result. */ - sudo_ldap_result_free_nss(nss); - - /* Unbind and close the LDAP connection. */ - if (handle->ld != NULL) { - ldap_unbind_ext_s(handle->ld, NULL, NULL); - handle->ld = NULL; - } - - /* Free the handle container. */ - free(nss->handle); - nss->handle = NULL; - } - debug_return_int(0); -} - /* * Perform LDAP query for user and host and convert to sudoers * parse tree. */ -static int +static struct userspec_list * sudo_ldap_query(struct sudo_nss *nss, struct passwd *pw) { struct sudo_ldap_handle *handle = nss->handle; struct ldap_result *lres = NULL; - int ret = 0; - LDAP *ld; + struct userspec_list *ret = &handle->userspecs; debug_decl(sudo_ldap_query, SUDOERS_DEBUG_LDAP) - if (handle == NULL || handle->ld == NULL) - goto done; - ld = handle->ld; + if (handle == NULL) { + sudo_debug_printf(SUDO_DEBUG_ERROR, + "%s: called with NULL handle", __func__); + debug_return_ptr(NULL); + } /* Use cached result if it matches pw. */ if (handle->pw != NULL) { @@ -1951,18 +1946,18 @@ sudo_ldap_query(struct sudo_nss *nss, struct passwd *pw) } /* Free old userspecs, if any. */ - free_userspecs(&nss->userspecs); + free_userspecs(&handle->userspecs); DPRINTF1("%s: ldap search user %s, host %s", __func__, pw->pw_name, user_runhost); if ((lres = sudo_ldap_result_get(nss, pw)) == NULL) { - ret = -1; + ret = NULL; goto done; } /* Convert to sudoers parse tree. */ - if (!ldap_to_sudoers(ld, lres, &nss->userspecs)) { - ret = -1; + if (!ldap_to_sudoers(handle->ld, lres, &handle->userspecs)) { + ret = NULL; goto done; } @@ -1970,12 +1965,16 @@ sudo_ldap_query(struct sudo_nss *nss, struct passwd *pw) sudo_pw_addref(pw); handle->pw = pw; + ret = &handle->userspecs; + done: /* Cleanup. */ sudo_ldap_result_free(lres); - if (ret == -1) - free_userspecs(&nss->userspecs); - debug_return_int(ret); + if (ret == NULL) { + free_userspecs(&handle->userspecs); + debug_return_ptr(NULL); + } + debug_return_ptr(ret); } /* diff --git a/plugins/sudoers/parse.c b/plugins/sudoers/parse.c index 4f669a306..d7f3e7e21 100644 --- a/plugins/sudoers/parse.c +++ b/plugins/sudoers/parse.c @@ -65,12 +65,13 @@ sudoers_lookup_pseudo(struct sudo_nss_list *snl, struct passwd *pw, CLR(validated, FLAG_NO_HOST); match = DENY; TAILQ_FOREACH(nss, snl, entries) { - if (nss->query(nss, pw) == -1) { + struct userspec_list *usl = nss->query(nss, pw); + if (usl == NULL) { /* The query function should have printed an error message. */ SET(validated, VALIDATE_ERROR); break; } - TAILQ_FOREACH(us, &nss->userspecs, entries) { + TAILQ_FOREACH(us, usl, entries) { if (userlist_matches(pw, &us->users) != ALLOW) continue; TAILQ_FOREACH(priv, &us->privileges, entries) { @@ -114,8 +115,9 @@ sudoers_lookup_pseudo(struct sudo_nss_list *snl, struct passwd *pw, } static int -sudoers_lookup_check(struct sudo_nss *nss, struct passwd *pw, int *validated, - struct cmndspec **matching_cs, struct defaults_list **defs, time_t now) +sudoers_lookup_check(struct userspec_list *usl, struct passwd *pw, + int *validated, struct cmndspec **matching_cs, + struct defaults_list **defs, time_t now) { int host_match, runas_match, cmnd_match; struct cmndspec *cs; @@ -124,7 +126,7 @@ sudoers_lookup_check(struct sudo_nss *nss, struct passwd *pw, int *validated, struct member *matching_user; debug_decl(sudoers_lookup_check, SUDOERS_DEBUG_PARSER) - TAILQ_FOREACH_REVERSE(us, &nss->userspecs, userspec_list, entries) { + TAILQ_FOREACH_REVERSE(us, usl, userspec_list, entries) { if (userlist_matches(pw, &us->users) != ALLOW) continue; CLR(*validated, FLAG_NO_USER); @@ -290,13 +292,14 @@ sudoers_lookup(struct sudo_nss_list *snl, struct passwd *pw, int validated, /* Query each sudoers source and check the user. */ time(&now); TAILQ_FOREACH(nss, snl, entries) { - if (nss->query(nss, pw) == -1) { + struct userspec_list *usl = nss->query(nss, pw); + if (usl == NULL) { /* The query function should have printed an error message. */ SET(validated, VALIDATE_ERROR); break; } - m = sudoers_lookup_check(nss, pw, &validated, &cs, &defs, now); + m = sudoers_lookup_check(usl, pw, &validated, &cs, &defs, now); if (m != UNSPEC) match = m; @@ -690,14 +693,6 @@ display_privs(struct sudo_nss_list *snl, struct passwd *pw) int cols, count, olen, n; debug_decl(display_privs, SUDOERS_DEBUG_PARSER) - /* Query all sudoers sources first. */ - TAILQ_FOREACH(nss, snl, entries) { - if (nss->query(nss, pw) == -1) { - /* The query function should have printed an error message. */ - debug_return_int(-1); - } - } - cols = sudo_user.cols; if (fstat(STDOUT_FILENO, &sb) == 0 && S_ISFIFO(sb.st_mode)) cols = 0; @@ -708,10 +703,13 @@ display_privs(struct sudo_nss_list *snl, struct passwd *pw) pw->pw_name, user_srunhost); count = 0; TAILQ_FOREACH(nss, snl, entries) { - n = display_defaults(&nss->defaults, pw, &def_buf); - if (n == -1) - goto bad; - count += n; + struct defaults_list *defs = nss->getdefs(nss); + if (defs != NULL) { + n = display_defaults(defs, pw, &def_buf); + if (n == -1) + goto bad; + count += n; + } } if (count != 0) { sudo_lbuf_append(&def_buf, "\n\n"); @@ -726,10 +724,13 @@ display_privs(struct sudo_nss_list *snl, struct passwd *pw) pw->pw_name); count = 0; TAILQ_FOREACH(nss, snl, entries) { - n = display_bound_defaults(&nss->defaults, pw, &def_buf); - if (n == -1) - goto bad; - count += n; + struct defaults_list *defs = nss->getdefs(nss); + if (defs != NULL) { + n = display_bound_defaults(defs, pw, &def_buf); + if (n == -1) + goto bad; + count += n; + } } if (count != 0) { sudo_lbuf_append(&def_buf, "\n\n"); @@ -744,10 +745,13 @@ display_privs(struct sudo_nss_list *snl, struct passwd *pw) pw->pw_name, user_srunhost); count = 0; TAILQ_FOREACH(nss, snl, entries) { - n = sudo_display_userspecs(&nss->userspecs, pw, &priv_buf); - if (n == -1) - goto bad; - count += n; + struct userspec_list *usl = nss->query(nss, pw); + if (usl != NULL) { + n = sudo_display_userspecs(usl, pw, &priv_buf); + if (n == -1) + goto bad; + count += n; + } } if (count == 0) { def_buf.len = 0; @@ -774,7 +778,7 @@ bad: } static int -display_cmnd_check(struct sudo_nss *nss, struct passwd *pw, time_t now) +display_cmnd_check(struct userspec_list *usl, struct passwd *pw, time_t now) { int host_match, runas_match, cmnd_match; struct cmndspec *cs; @@ -782,7 +786,7 @@ display_cmnd_check(struct sudo_nss *nss, struct passwd *pw, time_t now) struct userspec *us; debug_decl(display_cmnd_check, SUDOERS_DEBUG_PARSER) - TAILQ_FOREACH_REVERSE(us, &nss->userspecs, userspec_list, entries) { + TAILQ_FOREACH_REVERSE(us, usl, userspec_list, entries) { if (userlist_matches(pw, &us->users) != ALLOW) continue; TAILQ_FOREACH_REVERSE(priv, &us->privileges, privilege_list, entries) { @@ -828,12 +832,13 @@ display_cmnd(struct sudo_nss_list *snl, struct passwd *pw) /* Iterate over each source, checking for the command. */ time(&now); TAILQ_FOREACH(nss, snl, entries) { - if (nss->query(nss, pw) == -1) { + struct userspec_list *usl = nss->query(nss, pw); + if (usl == NULL) { /* The query function should have printed an error message. */ debug_return_int(-1); } - m = display_cmnd_check(nss, pw, now); + m = display_cmnd_check(usl, pw, now); if (m != UNSPEC) match = m; diff --git a/plugins/sudoers/sssd.c b/plugins/sudoers/sssd.c index da69f32ec..017462269 100644 --- a/plugins/sudoers/sssd.c +++ b/plugins/sudoers/sssd.c @@ -83,6 +83,8 @@ struct sudo_sss_handle { char *ipa_shost; struct passwd *pw; void *ssslib; + struct userspec_list userspecs; + struct defaults_list defaults; 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; @@ -508,7 +510,27 @@ sudo_sss_result_get(struct sudo_nss *nss, struct passwd *pw) } /* sudo_nss implementation */ -// ok +static int +sudo_sss_close(struct sudo_nss *nss) +{ + struct sudo_sss_handle *handle = nss->handle; + debug_decl(sudo_sss_close, SUDOERS_DEBUG_SSSD); + + if (handle != NULL) { + sudo_dso_unload(handle->ssslib); + if (handle->pw != NULL) + sudo_pw_delref(handle->pw); + free(handle->ipa_host); + if (handle->ipa_host != handle->ipa_shost) + free(handle->ipa_shost); + free_userspecs(&handle->userspecs); + free_defaults(&handle->defaults); + free(handle); + nss->handle = NULL; + } + debug_return_int(0); +} + static int sudo_sss_open(struct sudo_nss *nss) { @@ -516,6 +538,12 @@ sudo_sss_open(struct sudo_nss *nss) static const char path[] = _PATH_SSSD_LIB"/libsss_sudo.so"; debug_decl(sudo_sss_open, SUDOERS_DEBUG_SSSD); + if (nss->handle != NULL) { + sudo_debug_printf(SUDO_DEBUG_ERROR, + "%s: called with non-NULL handle %p", __func__, nss->handle); + sudo_sss_close(nss); + } + /* Create a handle container. */ handle = calloc(1, sizeof(struct sudo_sss_handle)); if (handle == NULL) { @@ -523,6 +551,9 @@ sudo_sss_open(struct sudo_nss *nss) debug_return_int(ENOMEM); } + TAILQ_INIT(&handle->userspecs); + TAILQ_INIT(&handle->defaults); + /* Load symbols */ handle->ssslib = sudo_dso_load(path, SUDO_DSO_LAZY); if (handle->ssslib == NULL) { @@ -597,42 +628,23 @@ sudo_sss_open(struct sudo_nss *nss) debug_return_int(0); } -// ok -static int -sudo_sss_close(struct sudo_nss *nss) -{ - struct sudo_sss_handle *handle; - debug_decl(sudo_sss_close, SUDOERS_DEBUG_SSSD); - - if (nss && nss->handle) { - handle = nss->handle; - sudo_dso_unload(handle->ssslib); - if (handle->pw != NULL) - sudo_pw_delref(handle->pw); - free(handle->ipa_host); - if (handle->ipa_host != handle->ipa_shost) - free(handle->ipa_shost); - free(handle); - nss->handle = NULL; - - /* XXX - do in main module? */ - free_userspecs(&nss->userspecs); - free_defaults(&nss->defaults); - } - debug_return_int(0); -} - /* * Perform query for user and host and convert to sudoers parse tree. */ -static int +static struct userspec_list * sudo_sss_query(struct sudo_nss *nss, struct passwd *pw) { struct sudo_sss_handle *handle = nss->handle; struct sss_sudo_result *sss_result = NULL; - int ret = 0; + struct userspec_list *ret = &handle->userspecs; debug_decl(sudo_sss_query, SUDOERS_DEBUG_SSSD); + if (handle == NULL) { + sudo_debug_printf(SUDO_DEBUG_ERROR, + "%s: called with NULL handle", __func__); + debug_return_ptr(NULL); + } + /* Use cached result if it matches pw. */ if (handle->pw != NULL) { if (pw == handle->pw) @@ -642,7 +654,7 @@ sudo_sss_query(struct sudo_nss *nss, struct passwd *pw) } /* Free old userspecs, if any. */ - free_userspecs(&nss->userspecs); + free_userspecs(&handle->userspecs); /* Fetch list of sudoRole entries that match user and host. */ sss_result = sudo_sss_result_get(nss, pw); @@ -659,26 +671,25 @@ sudo_sss_query(struct sudo_nss *nss, struct passwd *pw) handle->pw = pw; /* Convert to sudoers parse tree. */ - if (!sss_to_sudoers(handle, sss_result, &nss->userspecs)) { - ret = -1; + if (!sss_to_sudoers(handle, sss_result, &handle->userspecs)) { + ret = NULL; goto done; } done: /* Cleanup */ handle->fn_free_result(sss_result); - if (ret == -1) { - free_userspecs(&nss->userspecs); + if (ret == NULL) { + free_userspecs(&handle->userspecs); sudo_pw_delref(handle->pw); handle->pw = NULL; } sudo_debug_printf(SUDO_DEBUG_DIAG, "Done with LDAP searches"); - debug_return_int(ret); + debug_return_ptr(ret); } -// ok static int sudo_sss_parse(struct sudo_nss *nss) { @@ -686,10 +697,11 @@ sudo_sss_parse(struct sudo_nss *nss) debug_return_int(0); } -static int +static struct defaults_list * sudo_sss_getdefs(struct sudo_nss *nss) { struct sudo_sss_handle *handle = nss->handle; + struct defaults_list *ret = NULL; struct sss_sudo_result *sss_result = NULL; struct sss_sudo_rule *sss_rule; uint32_t sss_error; @@ -697,11 +709,14 @@ sudo_sss_getdefs(struct sudo_nss *nss) int rc; debug_decl(sudo_sss_getdefs, SUDOERS_DEBUG_SSSD); - if (handle == NULL) - debug_return_int(-1); + if (handle == NULL) { + sudo_debug_printf(SUDO_DEBUG_ERROR, + "%s: called with NULL handle", __func__); + debug_return_ptr(NULL); + } /* Free old defaults, if any. */ - free_defaults(&nss->defaults); + free_defaults(&handle->defaults); sudo_debug_printf(SUDO_DEBUG_DIAG, "Looking for cn=defaults"); @@ -717,7 +732,7 @@ sudo_sss_getdefs(struct sudo_nss *nss) default: sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_send_recv_defaults: rc=%d, sss_error=%u", rc, sss_error); - debug_return_int(-1); + debug_return_ptr(NULL); } if (sss_error != 0) { if (sss_error == ENOENT) { @@ -726,23 +741,21 @@ sudo_sss_getdefs(struct sudo_nss *nss) goto done; } sudo_debug_printf(SUDO_DEBUG_INFO, "sss_error=%u\n", sss_error); - goto bad; + goto done; } 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, &nss->defaults)) - goto bad; + if (!sudo_sss_parse_options(handle, sss_rule, &handle->defaults)) + goto done; } + ret = &handle->defaults; done: handle->fn_free_result(sss_result); - debug_return_int(0); -bad: - handle->fn_free_result(sss_result); - debug_return_int(-1); + debug_return_ptr(ret); } /* sudo_nss implementation */ diff --git a/plugins/sudoers/sudo_nss.c b/plugins/sudoers/sudo_nss.c index 426434cb8..bdd9a502a 100644 --- a/plugins/sudoers/sudo_nss.c +++ b/plugins/sudoers/sudo_nss.c @@ -43,18 +43,6 @@ extern struct sudo_nss sudo_nss_ldap; extern struct sudo_nss sudo_nss_sss; #endif -static void -sudo_nss_insert(struct sudo_nss_list *snl, struct sudo_nss *nss) -{ - debug_decl(sudo_nss_insert, SUDOERS_DEBUG_NSS) - - TAILQ_INIT(&nss->userspecs); - TAILQ_INIT(&nss->defaults); - TAILQ_INSERT_TAIL(snl, nss, entries); - - debug_return; -} - /* Make sure we have not already inserted the nss entry. */ #define SUDO_NSS_CHECK_UNUSED(nss, tag) \ if (nss.entries.tqe_next != NULL || nss.entries.tqe_prev != NULL) { \ @@ -103,18 +91,18 @@ sudo_read_nss(void) for ((cp = strtok_r(line + 8, " \t", &last)); cp != NULL; (cp = strtok_r(NULL, " \t", &last))) { if (strcasecmp(cp, "files") == 0 && !saw_files) { SUDO_NSS_CHECK_UNUSED(sudo_nss_file, "files"); - sudo_nss_insert(&snl, &sudo_nss_file); + TAILQ_INSERT_TAIL(&snl, &sudo_nss_file, entries); got_match = saw_files = true; #ifdef HAVE_LDAP } else if (strcasecmp(cp, "ldap") == 0 && !saw_ldap) { SUDO_NSS_CHECK_UNUSED(sudo_nss_ldap, "ldap"); - sudo_nss_insert(&snl, &sudo_nss_ldap); + TAILQ_INSERT_TAIL(&snl, &sudo_nss_ldap, entries); got_match = saw_ldap = true; #endif #ifdef HAVE_SSSD } else if (strcasecmp(cp, "sss") == 0 && !saw_sss) { SUDO_NSS_CHECK_UNUSED(sudo_nss_sss, "sss"); - sudo_nss_insert(&snl, &sudo_nss_sss); + TAILQ_INSERT_TAIL(&snl, &sudo_nss_sss, entries); got_match = saw_sss = true; #endif } else if (strcasecmp(cp, "[NOTFOUND=return]") == 0 && got_match) { @@ -137,7 +125,7 @@ sudo_read_nss(void) nomatch: /* Default to files only if no matches */ if (TAILQ_EMPTY(&snl)) - sudo_nss_insert(&snl, &sudo_nss_file); + TAILQ_INSERT_TAIL(&snl, &sudo_nss_file, entries); debug_return_ptr(&snl); } @@ -190,20 +178,20 @@ sudo_read_nss(void) if (!saw_files && strncasecmp(cp, "files", 5) == 0 && (isspace((unsigned char)cp[5]) || cp[5] == '\0')) { - sudo_nss_insert(&snl, &sudo_nss_file); + TAILQ_INSERT_TAIL(&snl, &sudo_nss_file, entries); 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')) { - sudo_nss_insert(&snl, &sudo_nss_ldap); + TAILQ_INSERT_TAIL(&snl, &sudo_nss_ldap, entries); 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')) { - sudo_nss_insert(&snl, &sudo_nss_sss); + TAILQ_INSERT_TAIL(&snl, &sudo_nss_sss, entries); got_match = saw_sss = true; ep = &cp[3]; #endif @@ -230,7 +218,7 @@ sudo_read_nss(void) nomatch: /* Default to files only if no matches */ if (TAILQ_EMPTY(&snl)) - sudo_nss_insert(&snl, &sudo_nss_file); + TAILQ_INSERT_TAIL(&snl, &sudo_nss_file, entries); debug_return_ptr(&snl); } @@ -247,12 +235,12 @@ sudo_read_nss(void) debug_decl(sudo_read_nss, SUDOERS_DEBUG_NSS) # ifdef HAVE_SSSD - sudo_nss_insert(&snl, &sudo_nss_sss); + TAILQ_INSERT_TAIL(&snl, &sudo_nss_sss, entries); # endif # ifdef HAVE_LDAP - sudo_nss_insert(&snl, &sudo_nss_ldap); + TAILQ_INSERT_TAIL(&snl, &sudo_nss_ldap, entries); # endif - sudo_nss_insert(&snl, &sudo_nss_file); + TAILQ_INSERT_TAIL(&snl, &sudo_nss_file, entries); debug_return_ptr(&snl); } diff --git a/plugins/sudoers/sudo_nss.h b/plugins/sudoers/sudo_nss.h index 20909f577..d6d3aa3c0 100644 --- a/plugins/sudoers/sudo_nss.h +++ b/plugins/sudoers/sudo_nss.h @@ -17,21 +17,20 @@ #ifndef SUDOERS_NSS_H #define SUDOERS_NSS_H -struct sudo_lbuf; struct passwd; +struct userspec_list; +struct defaults_list; struct sudo_nss { TAILQ_ENTRY(sudo_nss) entries; int (*open)(struct sudo_nss *nss); int (*close)(struct sudo_nss *nss); int (*parse)(struct sudo_nss *nss); - int (*query)(struct sudo_nss *nss, struct passwd *pw); - int (*getdefs)(struct sudo_nss *nss); + struct userspec_list *(*query)(struct sudo_nss *nss, struct passwd *pw); + struct defaults_list *(*getdefs)(struct sudo_nss *nss); void *handle; bool ret_if_found; bool ret_if_notfound; - struct defaults_list defaults; - struct userspec_list userspecs; }; TAILQ_HEAD(sudo_nss_list, sudo_nss); diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c index 29ce411f5..6bbe165fe 100644 --- a/plugins/sudoers/sudoers.c +++ b/plugins/sudoers/sudoers.c @@ -193,8 +193,9 @@ sudoers_policy_init(void *info, char * const envp[]) init_parser(sudoers_file, false); TAILQ_FOREACH_SAFE(nss, snl, entries, nss_next) { if (nss->open(nss) == 0 && nss->parse(nss) == 0) { + struct defaults_list *defs = nss->getdefs(nss); sources++; - if (nss->getdefs(nss) != 0 || !update_defaults(&nss->defaults, + if (defs == NULL || !update_defaults(defs, SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER|SETDEF_RUNAS, false)) { log_warningx(SLOG_SEND_MAIL|SLOG_NO_STDERR, N_("problem with defaults entries")); @@ -853,7 +854,8 @@ set_cmnd(void) user_base = user_cmnd; TAILQ_FOREACH(nss, snl, entries) { - if (!update_defaults(&nss->defaults, SETDEF_CMND, false)) { + struct defaults_list *defs = nss->getdefs(nss); + if (!update_defaults(defs, SETDEF_CMND, false)) { log_warningx(SLOG_SEND_MAIL|SLOG_NO_STDERR, N_("problem with defaults entries")); }