mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-31 22:35:10 +00:00
Move cached userspecs and defaults into the handle object.
This commit is contained in:
@@ -38,35 +38,61 @@
|
|||||||
#include "sudo_lbuf.h"
|
#include "sudo_lbuf.h"
|
||||||
#include <gram.h>
|
#include <gram.h>
|
||||||
|
|
||||||
static int
|
struct sudo_file_handle {
|
||||||
sudo_file_open(struct sudo_nss *nss)
|
FILE *fp;
|
||||||
{
|
struct defaults_list defaults;
|
||||||
debug_decl(sudo_file_open, SUDOERS_DEBUG_NSS)
|
struct userspec_list userspecs;
|
||||||
|
};
|
||||||
if (def_ignore_local_sudoers)
|
|
||||||
debug_return_int(-1);
|
|
||||||
nss->handle = open_sudoers(sudoers_file, false, NULL);
|
|
||||||
debug_return_int(nss->handle ? 0 : -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sudo_file_close(struct sudo_nss *nss)
|
sudo_file_close(struct sudo_nss *nss)
|
||||||
{
|
{
|
||||||
debug_decl(sudo_file_close, SUDOERS_DEBUG_NSS)
|
debug_decl(sudo_file_close, SUDOERS_DEBUG_NSS)
|
||||||
|
struct sudo_file_handle *handle = nss->handle;
|
||||||
|
|
||||||
if (nss->handle != NULL) {
|
if (handle != NULL) {
|
||||||
fclose(nss->handle);
|
fclose(handle->fp);
|
||||||
nss->handle = NULL;
|
|
||||||
sudoersin = NULL;
|
sudoersin = NULL;
|
||||||
|
|
||||||
/* XXX - do in main module? */
|
free_userspecs(&handle->userspecs);
|
||||||
free_userspecs(&nss->userspecs);
|
free_defaults(&handle->defaults);
|
||||||
free_defaults(&nss->defaults);
|
|
||||||
|
nss->handle = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_return_int(0);
|
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.
|
* Parse the specified sudoers file.
|
||||||
*/
|
*/
|
||||||
@@ -74,11 +100,15 @@ static int
|
|||||||
sudo_file_parse(struct sudo_nss *nss)
|
sudo_file_parse(struct sudo_nss *nss)
|
||||||
{
|
{
|
||||||
debug_decl(sudo_file_close, SUDOERS_DEBUG_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);
|
debug_return_int(-1);
|
||||||
|
}
|
||||||
|
|
||||||
sudoersin = nss->handle;
|
sudoersin = handle->fp;
|
||||||
if (sudoersparse() != 0 || parse_error) {
|
if (sudoersparse() != 0 || parse_error) {
|
||||||
if (errorlineno != -1) {
|
if (errorlineno != -1) {
|
||||||
log_warningx(SLOG_SEND_MAIL, N_("parse error in %s near line %d"),
|
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. */
|
/* Move parsed userspecs and defaults to nss structure. */
|
||||||
TAILQ_CONCAT(&nss->userspecs, &userspecs, entries);
|
TAILQ_CONCAT(&handle->userspecs, &userspecs, entries);
|
||||||
TAILQ_CONCAT(&nss->defaults, &defaults, entries);
|
TAILQ_CONCAT(&handle->defaults, &defaults, entries);
|
||||||
|
|
||||||
debug_return_int(0);
|
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)
|
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_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)
|
sudo_file_getdefs(struct sudo_nss *nss)
|
||||||
{
|
{
|
||||||
debug_decl(sudo_file_getdefs, SUDOERS_DEBUG_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 */
|
/* sudo_nss implementation */
|
||||||
|
@@ -152,6 +152,8 @@ STAILQ_HEAD(ldap_netgroup_list, ldap_netgroup);
|
|||||||
struct sudo_ldap_handle {
|
struct sudo_ldap_handle {
|
||||||
LDAP *ld;
|
LDAP *ld;
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
|
struct userspec_list userspecs;
|
||||||
|
struct defaults_list defaults;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef HAVE_LDAP_INITIALIZE
|
#ifdef HAVE_LDAP_INITIALIZE
|
||||||
@@ -1540,6 +1542,33 @@ done:
|
|||||||
debug_return_int(ret);
|
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.
|
* Open a connection to the LDAP server.
|
||||||
* Returns 0 on success and non-zero on failure.
|
* 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;
|
struct sudo_ldap_handle *handle;
|
||||||
debug_decl(sudo_ldap_open, SUDOERS_DEBUG_LDAP)
|
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())
|
if (!sudo_ldap_read_config())
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
@@ -1632,42 +1667,46 @@ sudo_ldap_open(struct sudo_nss *nss)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
handle->ld = ld;
|
handle->ld = ld;
|
||||||
/* handle->result = NULL; */
|
/* handle->pw = NULL; */
|
||||||
/* handle->username = NULL; */
|
TAILQ_INIT(&handle->userspecs);
|
||||||
/* handle->gidlist = NULL; */
|
TAILQ_INIT(&handle->defaults);
|
||||||
nss->handle = handle;
|
nss->handle = handle;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
debug_return_int(rc == LDAP_SUCCESS ? 0 : -1);
|
debug_return_int(rc == LDAP_SUCCESS ? 0 : -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static struct defaults_list *
|
||||||
sudo_ldap_getdefs(struct sudo_nss *nss)
|
sudo_ldap_getdefs(struct sudo_nss *nss)
|
||||||
{
|
{
|
||||||
struct ldap_config_str *base;
|
struct ldap_config_str *base;
|
||||||
struct sudo_ldap_handle *handle = nss->handle;
|
struct sudo_ldap_handle *handle = nss->handle;
|
||||||
struct timeval tv, *tvp = NULL;
|
struct timeval tv, *tvp = NULL;
|
||||||
LDAP *ld;
|
struct defaults_list *ret = NULL;
|
||||||
LDAPMessage *entry, *result = NULL;
|
LDAPMessage *entry, *result = NULL;
|
||||||
char *filt;
|
char *filt;
|
||||||
int rc, ret = -1;
|
int rc;
|
||||||
debug_decl(sudo_ldap_getdefs, SUDOERS_DEBUG_LDAP)
|
debug_decl(sudo_ldap_getdefs, SUDOERS_DEBUG_LDAP)
|
||||||
|
|
||||||
if (handle == NULL || handle->ld == NULL)
|
if (handle == NULL) {
|
||||||
debug_return_int(-1);
|
sudo_debug_printf(SUDO_DEBUG_ERROR,
|
||||||
ld = handle->ld;
|
"%s: called with NULL handle", __func__);
|
||||||
|
debug_return_ptr(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Free old defaults, if any. */
|
/* Free old defaults, if any. */
|
||||||
free_defaults(&nss->defaults);
|
free_defaults(&handle->defaults);
|
||||||
|
|
||||||
filt = sudo_ldap_build_default_filter();
|
filt = sudo_ldap_build_default_filter();
|
||||||
if (filt == NULL) {
|
if (filt == NULL) {
|
||||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
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);
|
DPRINTF1("Looking for cn=defaults: %s", filt);
|
||||||
|
|
||||||
STAILQ_FOREACH(base, &ldap_conf.base, entries) {
|
STAILQ_FOREACH(base, &ldap_conf.base, entries) {
|
||||||
|
LDAP *ld = handle->ld;
|
||||||
|
|
||||||
if (ldap_conf.timeout > 0) {
|
if (ldap_conf.timeout > 0) {
|
||||||
tv.tv_sec = ldap_conf.timeout;
|
tv.tv_sec = ldap_conf.timeout;
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
@@ -1679,19 +1718,19 @@ 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, &nss->defaults))
|
if (!sudo_ldap_parse_options(ld, entry, &handle->defaults))
|
||||||
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 = 0;
|
ret = &handle->defaults;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
ldap_msgfree(result);
|
ldap_msgfree(result);
|
||||||
free(filt);
|
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]);
|
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
|
* Perform the LDAP query for the user. The caller is responsible for
|
||||||
* freeing the result with sudo_ldap_result_free().
|
* freeing the result with sudo_ldap_result_free().
|
||||||
@@ -1899,48 +1919,23 @@ oom:
|
|||||||
debug_return_ptr(NULL);
|
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
|
* Perform LDAP query for user and host and convert to sudoers
|
||||||
* parse tree.
|
* parse tree.
|
||||||
*/
|
*/
|
||||||
static int
|
static struct userspec_list *
|
||||||
sudo_ldap_query(struct sudo_nss *nss, struct passwd *pw)
|
sudo_ldap_query(struct sudo_nss *nss, struct passwd *pw)
|
||||||
{
|
{
|
||||||
struct sudo_ldap_handle *handle = nss->handle;
|
struct sudo_ldap_handle *handle = nss->handle;
|
||||||
struct ldap_result *lres = NULL;
|
struct ldap_result *lres = NULL;
|
||||||
int ret = 0;
|
struct userspec_list *ret = &handle->userspecs;
|
||||||
LDAP *ld;
|
|
||||||
debug_decl(sudo_ldap_query, SUDOERS_DEBUG_LDAP)
|
debug_decl(sudo_ldap_query, SUDOERS_DEBUG_LDAP)
|
||||||
|
|
||||||
if (handle == NULL || handle->ld == NULL)
|
if (handle == NULL) {
|
||||||
goto done;
|
sudo_debug_printf(SUDO_DEBUG_ERROR,
|
||||||
ld = handle->ld;
|
"%s: called with NULL handle", __func__);
|
||||||
|
debug_return_ptr(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Use cached result if it matches pw. */
|
/* Use cached result if it matches pw. */
|
||||||
if (handle->pw != NULL) {
|
if (handle->pw != NULL) {
|
||||||
@@ -1951,18 +1946,18 @@ sudo_ldap_query(struct sudo_nss *nss, struct passwd *pw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Free old userspecs, if any. */
|
/* 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,
|
DPRINTF1("%s: ldap search user %s, host %s", __func__, pw->pw_name,
|
||||||
user_runhost);
|
user_runhost);
|
||||||
if ((lres = sudo_ldap_result_get(nss, pw)) == NULL) {
|
if ((lres = sudo_ldap_result_get(nss, pw)) == NULL) {
|
||||||
ret = -1;
|
ret = NULL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert to sudoers parse tree. */
|
/* Convert to sudoers parse tree. */
|
||||||
if (!ldap_to_sudoers(ld, lres, &nss->userspecs)) {
|
if (!ldap_to_sudoers(handle->ld, lres, &handle->userspecs)) {
|
||||||
ret = -1;
|
ret = NULL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1970,12 +1965,16 @@ sudo_ldap_query(struct sudo_nss *nss, struct passwd *pw)
|
|||||||
sudo_pw_addref(pw);
|
sudo_pw_addref(pw);
|
||||||
handle->pw = pw;
|
handle->pw = pw;
|
||||||
|
|
||||||
|
ret = &handle->userspecs;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
/* Cleanup. */
|
/* Cleanup. */
|
||||||
sudo_ldap_result_free(lres);
|
sudo_ldap_result_free(lres);
|
||||||
if (ret == -1)
|
if (ret == NULL) {
|
||||||
free_userspecs(&nss->userspecs);
|
free_userspecs(&handle->userspecs);
|
||||||
debug_return_int(ret);
|
debug_return_ptr(NULL);
|
||||||
|
}
|
||||||
|
debug_return_ptr(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -65,12 +65,13 @@ sudoers_lookup_pseudo(struct sudo_nss_list *snl, struct passwd *pw,
|
|||||||
CLR(validated, FLAG_NO_HOST);
|
CLR(validated, FLAG_NO_HOST);
|
||||||
match = DENY;
|
match = DENY;
|
||||||
TAILQ_FOREACH(nss, snl, entries) {
|
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. */
|
/* The query function should have printed an error message. */
|
||||||
SET(validated, VALIDATE_ERROR);
|
SET(validated, VALIDATE_ERROR);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
TAILQ_FOREACH(us, &nss->userspecs, entries) {
|
TAILQ_FOREACH(us, usl, entries) {
|
||||||
if (userlist_matches(pw, &us->users) != ALLOW)
|
if (userlist_matches(pw, &us->users) != ALLOW)
|
||||||
continue;
|
continue;
|
||||||
TAILQ_FOREACH(priv, &us->privileges, entries) {
|
TAILQ_FOREACH(priv, &us->privileges, entries) {
|
||||||
@@ -114,8 +115,9 @@ sudoers_lookup_pseudo(struct sudo_nss_list *snl, struct passwd *pw,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sudoers_lookup_check(struct sudo_nss *nss, struct passwd *pw, int *validated,
|
sudoers_lookup_check(struct userspec_list *usl, struct passwd *pw,
|
||||||
struct cmndspec **matching_cs, struct defaults_list **defs, time_t now)
|
int *validated, struct cmndspec **matching_cs,
|
||||||
|
struct defaults_list **defs, time_t now)
|
||||||
{
|
{
|
||||||
int host_match, runas_match, cmnd_match;
|
int host_match, runas_match, cmnd_match;
|
||||||
struct cmndspec *cs;
|
struct cmndspec *cs;
|
||||||
@@ -124,7 +126,7 @@ sudoers_lookup_check(struct sudo_nss *nss, struct passwd *pw, int *validated,
|
|||||||
struct member *matching_user;
|
struct member *matching_user;
|
||||||
debug_decl(sudoers_lookup_check, SUDOERS_DEBUG_PARSER)
|
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)
|
if (userlist_matches(pw, &us->users) != ALLOW)
|
||||||
continue;
|
continue;
|
||||||
CLR(*validated, FLAG_NO_USER);
|
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. */
|
/* Query each sudoers source and check the user. */
|
||||||
time(&now);
|
time(&now);
|
||||||
TAILQ_FOREACH(nss, snl, entries) {
|
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. */
|
/* The query function should have printed an error message. */
|
||||||
SET(validated, VALIDATE_ERROR);
|
SET(validated, VALIDATE_ERROR);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m = sudoers_lookup_check(nss, pw, &validated, &cs, &defs, now);
|
m = sudoers_lookup_check(usl, pw, &validated, &cs, &defs, now);
|
||||||
if (m != UNSPEC)
|
if (m != UNSPEC)
|
||||||
match = m;
|
match = m;
|
||||||
|
|
||||||
@@ -690,14 +693,6 @@ display_privs(struct sudo_nss_list *snl, struct passwd *pw)
|
|||||||
int cols, count, olen, n;
|
int cols, count, olen, n;
|
||||||
debug_decl(display_privs, SUDOERS_DEBUG_PARSER)
|
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;
|
cols = sudo_user.cols;
|
||||||
if (fstat(STDOUT_FILENO, &sb) == 0 && S_ISFIFO(sb.st_mode))
|
if (fstat(STDOUT_FILENO, &sb) == 0 && S_ISFIFO(sb.st_mode))
|
||||||
cols = 0;
|
cols = 0;
|
||||||
@@ -708,10 +703,13 @@ display_privs(struct sudo_nss_list *snl, struct passwd *pw)
|
|||||||
pw->pw_name, user_srunhost);
|
pw->pw_name, user_srunhost);
|
||||||
count = 0;
|
count = 0;
|
||||||
TAILQ_FOREACH(nss, snl, entries) {
|
TAILQ_FOREACH(nss, snl, entries) {
|
||||||
n = display_defaults(&nss->defaults, pw, &def_buf);
|
struct defaults_list *defs = nss->getdefs(nss);
|
||||||
if (n == -1)
|
if (defs != NULL) {
|
||||||
goto bad;
|
n = display_defaults(defs, pw, &def_buf);
|
||||||
count += n;
|
if (n == -1)
|
||||||
|
goto bad;
|
||||||
|
count += n;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (count != 0) {
|
if (count != 0) {
|
||||||
sudo_lbuf_append(&def_buf, "\n\n");
|
sudo_lbuf_append(&def_buf, "\n\n");
|
||||||
@@ -726,10 +724,13 @@ display_privs(struct sudo_nss_list *snl, struct passwd *pw)
|
|||||||
pw->pw_name);
|
pw->pw_name);
|
||||||
count = 0;
|
count = 0;
|
||||||
TAILQ_FOREACH(nss, snl, entries) {
|
TAILQ_FOREACH(nss, snl, entries) {
|
||||||
n = display_bound_defaults(&nss->defaults, pw, &def_buf);
|
struct defaults_list *defs = nss->getdefs(nss);
|
||||||
if (n == -1)
|
if (defs != NULL) {
|
||||||
goto bad;
|
n = display_bound_defaults(defs, pw, &def_buf);
|
||||||
count += n;
|
if (n == -1)
|
||||||
|
goto bad;
|
||||||
|
count += n;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (count != 0) {
|
if (count != 0) {
|
||||||
sudo_lbuf_append(&def_buf, "\n\n");
|
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);
|
pw->pw_name, user_srunhost);
|
||||||
count = 0;
|
count = 0;
|
||||||
TAILQ_FOREACH(nss, snl, entries) {
|
TAILQ_FOREACH(nss, snl, entries) {
|
||||||
n = sudo_display_userspecs(&nss->userspecs, pw, &priv_buf);
|
struct userspec_list *usl = nss->query(nss, pw);
|
||||||
if (n == -1)
|
if (usl != NULL) {
|
||||||
goto bad;
|
n = sudo_display_userspecs(usl, pw, &priv_buf);
|
||||||
count += n;
|
if (n == -1)
|
||||||
|
goto bad;
|
||||||
|
count += n;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
def_buf.len = 0;
|
def_buf.len = 0;
|
||||||
@@ -774,7 +778,7 @@ bad:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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;
|
int host_match, runas_match, cmnd_match;
|
||||||
struct cmndspec *cs;
|
struct cmndspec *cs;
|
||||||
@@ -782,7 +786,7 @@ display_cmnd_check(struct sudo_nss *nss, struct passwd *pw, time_t now)
|
|||||||
struct userspec *us;
|
struct userspec *us;
|
||||||
debug_decl(display_cmnd_check, SUDOERS_DEBUG_PARSER)
|
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)
|
if (userlist_matches(pw, &us->users) != ALLOW)
|
||||||
continue;
|
continue;
|
||||||
TAILQ_FOREACH_REVERSE(priv, &us->privileges, privilege_list, entries) {
|
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. */
|
/* Iterate over each source, checking for the command. */
|
||||||
time(&now);
|
time(&now);
|
||||||
TAILQ_FOREACH(nss, snl, entries) {
|
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. */
|
/* The query function should have printed an error message. */
|
||||||
debug_return_int(-1);
|
debug_return_int(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
m = display_cmnd_check(nss, pw, now);
|
m = display_cmnd_check(usl, pw, now);
|
||||||
if (m != UNSPEC)
|
if (m != UNSPEC)
|
||||||
match = m;
|
match = m;
|
||||||
|
|
||||||
|
@@ -83,6 +83,8 @@ struct sudo_sss_handle {
|
|||||||
char *ipa_shost;
|
char *ipa_shost;
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
void *ssslib;
|
void *ssslib;
|
||||||
|
struct userspec_list userspecs;
|
||||||
|
struct defaults_list 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;
|
||||||
@@ -508,7 +510,27 @@ sudo_sss_result_get(struct sudo_nss *nss, struct passwd *pw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* sudo_nss implementation */
|
/* 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
|
static int
|
||||||
sudo_sss_open(struct sudo_nss *nss)
|
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";
|
static const char path[] = _PATH_SSSD_LIB"/libsss_sudo.so";
|
||||||
debug_decl(sudo_sss_open, SUDOERS_DEBUG_SSSD);
|
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. */
|
/* Create a handle container. */
|
||||||
handle = calloc(1, sizeof(struct sudo_sss_handle));
|
handle = calloc(1, sizeof(struct sudo_sss_handle));
|
||||||
if (handle == NULL) {
|
if (handle == NULL) {
|
||||||
@@ -523,6 +551,9 @@ sudo_sss_open(struct sudo_nss *nss)
|
|||||||
debug_return_int(ENOMEM);
|
debug_return_int(ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TAILQ_INIT(&handle->userspecs);
|
||||||
|
TAILQ_INIT(&handle->defaults);
|
||||||
|
|
||||||
/* Load symbols */
|
/* Load symbols */
|
||||||
handle->ssslib = sudo_dso_load(path, SUDO_DSO_LAZY);
|
handle->ssslib = sudo_dso_load(path, SUDO_DSO_LAZY);
|
||||||
if (handle->ssslib == NULL) {
|
if (handle->ssslib == NULL) {
|
||||||
@@ -597,42 +628,23 @@ sudo_sss_open(struct sudo_nss *nss)
|
|||||||
debug_return_int(0);
|
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.
|
* 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)
|
sudo_sss_query(struct sudo_nss *nss, struct passwd *pw)
|
||||||
{
|
{
|
||||||
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;
|
||||||
int ret = 0;
|
struct userspec_list *ret = &handle->userspecs;
|
||||||
debug_decl(sudo_sss_query, SUDOERS_DEBUG_SSSD);
|
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. */
|
/* Use cached result if it matches pw. */
|
||||||
if (handle->pw != NULL) {
|
if (handle->pw != NULL) {
|
||||||
if (pw == handle->pw)
|
if (pw == handle->pw)
|
||||||
@@ -642,7 +654,7 @@ sudo_sss_query(struct sudo_nss *nss, struct passwd *pw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Free old userspecs, if any. */
|
/* Free old userspecs, if any. */
|
||||||
free_userspecs(&nss->userspecs);
|
free_userspecs(&handle->userspecs);
|
||||||
|
|
||||||
/* Fetch list of sudoRole entries that match user and host. */
|
/* Fetch list of sudoRole entries that match user and host. */
|
||||||
sss_result = sudo_sss_result_get(nss, pw);
|
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;
|
handle->pw = pw;
|
||||||
|
|
||||||
/* Convert to sudoers parse tree. */
|
/* Convert to sudoers parse tree. */
|
||||||
if (!sss_to_sudoers(handle, sss_result, &nss->userspecs)) {
|
if (!sss_to_sudoers(handle, sss_result, &handle->userspecs)) {
|
||||||
ret = -1;
|
ret = NULL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
/* Cleanup */
|
/* Cleanup */
|
||||||
handle->fn_free_result(sss_result);
|
handle->fn_free_result(sss_result);
|
||||||
if (ret == -1) {
|
if (ret == NULL) {
|
||||||
free_userspecs(&nss->userspecs);
|
free_userspecs(&handle->userspecs);
|
||||||
sudo_pw_delref(handle->pw);
|
sudo_pw_delref(handle->pw);
|
||||||
handle->pw = NULL;
|
handle->pw = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_DIAG, "Done with LDAP searches");
|
sudo_debug_printf(SUDO_DEBUG_DIAG, "Done with LDAP searches");
|
||||||
|
|
||||||
debug_return_int(ret);
|
debug_return_ptr(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ok
|
|
||||||
static int
|
static int
|
||||||
sudo_sss_parse(struct sudo_nss *nss)
|
sudo_sss_parse(struct sudo_nss *nss)
|
||||||
{
|
{
|
||||||
@@ -686,10 +697,11 @@ sudo_sss_parse(struct sudo_nss *nss)
|
|||||||
debug_return_int(0);
|
debug_return_int(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static struct defaults_list *
|
||||||
sudo_sss_getdefs(struct sudo_nss *nss)
|
sudo_sss_getdefs(struct sudo_nss *nss)
|
||||||
{
|
{
|
||||||
struct sudo_sss_handle *handle = nss->handle;
|
struct sudo_sss_handle *handle = nss->handle;
|
||||||
|
struct defaults_list *ret = NULL;
|
||||||
struct sss_sudo_result *sss_result = NULL;
|
struct sss_sudo_result *sss_result = NULL;
|
||||||
struct sss_sudo_rule *sss_rule;
|
struct sss_sudo_rule *sss_rule;
|
||||||
uint32_t sss_error;
|
uint32_t sss_error;
|
||||||
@@ -697,11 +709,14 @@ sudo_sss_getdefs(struct sudo_nss *nss)
|
|||||||
int rc;
|
int rc;
|
||||||
debug_decl(sudo_sss_getdefs, SUDOERS_DEBUG_SSSD);
|
debug_decl(sudo_sss_getdefs, SUDOERS_DEBUG_SSSD);
|
||||||
|
|
||||||
if (handle == NULL)
|
if (handle == NULL) {
|
||||||
debug_return_int(-1);
|
sudo_debug_printf(SUDO_DEBUG_ERROR,
|
||||||
|
"%s: called with NULL handle", __func__);
|
||||||
|
debug_return_ptr(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Free old defaults, if any. */
|
/* Free old defaults, if any. */
|
||||||
free_defaults(&nss->defaults);
|
free_defaults(&handle->defaults);
|
||||||
|
|
||||||
sudo_debug_printf(SUDO_DEBUG_DIAG, "Looking for cn=defaults");
|
sudo_debug_printf(SUDO_DEBUG_DIAG, "Looking for cn=defaults");
|
||||||
|
|
||||||
@@ -717,7 +732,7 @@ sudo_sss_getdefs(struct sudo_nss *nss)
|
|||||||
default:
|
default:
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO,
|
sudo_debug_printf(SUDO_DEBUG_INFO,
|
||||||
"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_int(-1);
|
debug_return_ptr(NULL);
|
||||||
}
|
}
|
||||||
if (sss_error != 0) {
|
if (sss_error != 0) {
|
||||||
if (sss_error == ENOENT) {
|
if (sss_error == ENOENT) {
|
||||||
@@ -726,23 +741,21 @@ sudo_sss_getdefs(struct sudo_nss *nss)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO, "sss_error=%u\n", sss_error);
|
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) {
|
for (i = 0; i < sss_result->num_rules; ++i) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_DIAG,
|
sudo_debug_printf(SUDO_DEBUG_DIAG,
|
||||||
"Parsing cn=defaults, %d/%d", i, sss_result->num_rules);
|
"Parsing cn=defaults, %d/%d", i, sss_result->num_rules);
|
||||||
sss_rule = sss_result->rules + i;
|
sss_rule = sss_result->rules + i;
|
||||||
if (!sudo_sss_parse_options(handle, sss_rule, &nss->defaults))
|
if (!sudo_sss_parse_options(handle, sss_rule, &handle->defaults))
|
||||||
goto bad;
|
goto done;
|
||||||
}
|
}
|
||||||
|
ret = &handle->defaults;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
handle->fn_free_result(sss_result);
|
handle->fn_free_result(sss_result);
|
||||||
debug_return_int(0);
|
debug_return_ptr(ret);
|
||||||
bad:
|
|
||||||
handle->fn_free_result(sss_result);
|
|
||||||
debug_return_int(-1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sudo_nss implementation */
|
/* sudo_nss implementation */
|
||||||
|
@@ -43,18 +43,6 @@ extern struct sudo_nss sudo_nss_ldap;
|
|||||||
extern struct sudo_nss sudo_nss_sss;
|
extern struct sudo_nss sudo_nss_sss;
|
||||||
#endif
|
#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. */
|
/* Make sure we have not already inserted the nss entry. */
|
||||||
#define SUDO_NSS_CHECK_UNUSED(nss, tag) \
|
#define SUDO_NSS_CHECK_UNUSED(nss, tag) \
|
||||||
if (nss.entries.tqe_next != NULL || nss.entries.tqe_prev != NULL) { \
|
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))) {
|
for ((cp = strtok_r(line + 8, " \t", &last)); cp != NULL; (cp = strtok_r(NULL, " \t", &last))) {
|
||||||
if (strcasecmp(cp, "files") == 0 && !saw_files) {
|
if (strcasecmp(cp, "files") == 0 && !saw_files) {
|
||||||
SUDO_NSS_CHECK_UNUSED(sudo_nss_file, "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;
|
got_match = saw_files = true;
|
||||||
#ifdef HAVE_LDAP
|
#ifdef HAVE_LDAP
|
||||||
} else if (strcasecmp(cp, "ldap") == 0 && !saw_ldap) {
|
} else if (strcasecmp(cp, "ldap") == 0 && !saw_ldap) {
|
||||||
SUDO_NSS_CHECK_UNUSED(sudo_nss_ldap, "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;
|
got_match = saw_ldap = true;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SSSD
|
#ifdef HAVE_SSSD
|
||||||
} else if (strcasecmp(cp, "sss") == 0 && !saw_sss) {
|
} else if (strcasecmp(cp, "sss") == 0 && !saw_sss) {
|
||||||
SUDO_NSS_CHECK_UNUSED(sudo_nss_sss, "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;
|
got_match = saw_sss = true;
|
||||||
#endif
|
#endif
|
||||||
} else if (strcasecmp(cp, "[NOTFOUND=return]") == 0 && got_match) {
|
} else if (strcasecmp(cp, "[NOTFOUND=return]") == 0 && got_match) {
|
||||||
@@ -137,7 +125,7 @@ sudo_read_nss(void)
|
|||||||
nomatch:
|
nomatch:
|
||||||
/* Default to files only if no matches */
|
/* Default to files only if no matches */
|
||||||
if (TAILQ_EMPTY(&snl))
|
if (TAILQ_EMPTY(&snl))
|
||||||
sudo_nss_insert(&snl, &sudo_nss_file);
|
TAILQ_INSERT_TAIL(&snl, &sudo_nss_file, entries);
|
||||||
|
|
||||||
debug_return_ptr(&snl);
|
debug_return_ptr(&snl);
|
||||||
}
|
}
|
||||||
@@ -190,20 +178,20 @@ sudo_read_nss(void)
|
|||||||
|
|
||||||
if (!saw_files && strncasecmp(cp, "files", 5) == 0 &&
|
if (!saw_files && strncasecmp(cp, "files", 5) == 0 &&
|
||||||
(isspace((unsigned char)cp[5]) || cp[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;
|
got_match = saw_files = true;
|
||||||
ep = &cp[5];
|
ep = &cp[5];
|
||||||
#ifdef HAVE_LDAP
|
#ifdef HAVE_LDAP
|
||||||
} else if (!saw_ldap && strncasecmp(cp, "ldap", 4) == 0 &&
|
} else if (!saw_ldap && strncasecmp(cp, "ldap", 4) == 0 &&
|
||||||
(isspace((unsigned char)cp[4]) || cp[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;
|
got_match = saw_ldap = true;
|
||||||
ep = &cp[4];
|
ep = &cp[4];
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SSSD
|
#ifdef HAVE_SSSD
|
||||||
} else if (!saw_sss && strncasecmp(cp, "sss", 3) == 0 &&
|
} else if (!saw_sss && strncasecmp(cp, "sss", 3) == 0 &&
|
||||||
(isspace((unsigned char)cp[3]) || cp[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;
|
got_match = saw_sss = true;
|
||||||
ep = &cp[3];
|
ep = &cp[3];
|
||||||
#endif
|
#endif
|
||||||
@@ -230,7 +218,7 @@ sudo_read_nss(void)
|
|||||||
nomatch:
|
nomatch:
|
||||||
/* Default to files only if no matches */
|
/* Default to files only if no matches */
|
||||||
if (TAILQ_EMPTY(&snl))
|
if (TAILQ_EMPTY(&snl))
|
||||||
sudo_nss_insert(&snl, &sudo_nss_file);
|
TAILQ_INSERT_TAIL(&snl, &sudo_nss_file, entries);
|
||||||
|
|
||||||
debug_return_ptr(&snl);
|
debug_return_ptr(&snl);
|
||||||
}
|
}
|
||||||
@@ -247,12 +235,12 @@ sudo_read_nss(void)
|
|||||||
debug_decl(sudo_read_nss, SUDOERS_DEBUG_NSS)
|
debug_decl(sudo_read_nss, SUDOERS_DEBUG_NSS)
|
||||||
|
|
||||||
# ifdef HAVE_SSSD
|
# ifdef HAVE_SSSD
|
||||||
sudo_nss_insert(&snl, &sudo_nss_sss);
|
TAILQ_INSERT_TAIL(&snl, &sudo_nss_sss, entries);
|
||||||
# endif
|
# endif
|
||||||
# ifdef HAVE_LDAP
|
# ifdef HAVE_LDAP
|
||||||
sudo_nss_insert(&snl, &sudo_nss_ldap);
|
TAILQ_INSERT_TAIL(&snl, &sudo_nss_ldap, entries);
|
||||||
# endif
|
# endif
|
||||||
sudo_nss_insert(&snl, &sudo_nss_file);
|
TAILQ_INSERT_TAIL(&snl, &sudo_nss_file, entries);
|
||||||
|
|
||||||
debug_return_ptr(&snl);
|
debug_return_ptr(&snl);
|
||||||
}
|
}
|
||||||
|
@@ -17,21 +17,20 @@
|
|||||||
#ifndef SUDOERS_NSS_H
|
#ifndef SUDOERS_NSS_H
|
||||||
#define SUDOERS_NSS_H
|
#define SUDOERS_NSS_H
|
||||||
|
|
||||||
struct sudo_lbuf;
|
|
||||||
struct passwd;
|
struct passwd;
|
||||||
|
struct userspec_list;
|
||||||
|
struct defaults_list;
|
||||||
|
|
||||||
struct sudo_nss {
|
struct sudo_nss {
|
||||||
TAILQ_ENTRY(sudo_nss) entries;
|
TAILQ_ENTRY(sudo_nss) entries;
|
||||||
int (*open)(struct sudo_nss *nss);
|
int (*open)(struct sudo_nss *nss);
|
||||||
int (*close)(struct sudo_nss *nss);
|
int (*close)(struct sudo_nss *nss);
|
||||||
int (*parse)(struct sudo_nss *nss);
|
int (*parse)(struct sudo_nss *nss);
|
||||||
int (*query)(struct sudo_nss *nss, struct passwd *pw);
|
struct userspec_list *(*query)(struct sudo_nss *nss, struct passwd *pw);
|
||||||
int (*getdefs)(struct sudo_nss *nss);
|
struct defaults_list *(*getdefs)(struct sudo_nss *nss);
|
||||||
void *handle;
|
void *handle;
|
||||||
bool ret_if_found;
|
bool ret_if_found;
|
||||||
bool ret_if_notfound;
|
bool ret_if_notfound;
|
||||||
struct defaults_list defaults;
|
|
||||||
struct userspec_list userspecs;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TAILQ_HEAD(sudo_nss_list, sudo_nss);
|
TAILQ_HEAD(sudo_nss_list, sudo_nss);
|
||||||
|
@@ -193,8 +193,9 @@ sudoers_policy_init(void *info, char * const envp[])
|
|||||||
init_parser(sudoers_file, false);
|
init_parser(sudoers_file, false);
|
||||||
TAILQ_FOREACH_SAFE(nss, snl, entries, nss_next) {
|
TAILQ_FOREACH_SAFE(nss, snl, entries, nss_next) {
|
||||||
if (nss->open(nss) == 0 && nss->parse(nss) == 0) {
|
if (nss->open(nss) == 0 && nss->parse(nss) == 0) {
|
||||||
|
struct defaults_list *defs = nss->getdefs(nss);
|
||||||
sources++;
|
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)) {
|
SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER|SETDEF_RUNAS, false)) {
|
||||||
log_warningx(SLOG_SEND_MAIL|SLOG_NO_STDERR,
|
log_warningx(SLOG_SEND_MAIL|SLOG_NO_STDERR,
|
||||||
N_("problem with defaults entries"));
|
N_("problem with defaults entries"));
|
||||||
@@ -853,7 +854,8 @@ set_cmnd(void)
|
|||||||
user_base = user_cmnd;
|
user_base = user_cmnd;
|
||||||
|
|
||||||
TAILQ_FOREACH(nss, snl, entries) {
|
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,
|
log_warningx(SLOG_SEND_MAIL|SLOG_NO_STDERR,
|
||||||
N_("problem with defaults entries"));
|
N_("problem with defaults entries"));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user