When converting LDAP to sudoers, ignore entries with no sudoHost attribute.
Otherwise, sudo_ldap_role_to_priv() will treat a NULL host list as as the "ALL" wildcard. This regression was introduced in sudo 1.8.23, which was the first version to convert LDAP sudoRole objects to sudoers internal data structures. Thanks to Andreas Mueller for reporting and debugging this problem.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: ISC
|
||||
*
|
||||
* Copyright (c) 2003-2018 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
* Copyright (c) 2003-2020 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
* Copyright (c) 2011 Daniel Kopecek <dkopecek@redhat.com>
|
||||
*
|
||||
* This code is derived from software contributed by Aaron Spangler.
|
||||
@@ -232,6 +232,126 @@ val_array_iter(void **vp)
|
||||
return *val_array;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper for sudo_ldap_role_to_priv() that takes an sss rule..
|
||||
* Returns a struct privilege on success or NULL on failure.
|
||||
*/
|
||||
static struct privilege *
|
||||
sss_rule_to_priv(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule,
|
||||
int *rc_out)
|
||||
{
|
||||
char **cmnds, **runasusers = NULL, **runasgroups = NULL;
|
||||
char **opts = NULL, **notbefore = NULL, **notafter = NULL;
|
||||
char **hosts = NULL, **cn_array = NULL, *cn = NULL;
|
||||
struct privilege *priv = NULL;
|
||||
int rc;
|
||||
debug_decl(sss_rule_to_priv, SUDOERS_DEBUG_SSSD);
|
||||
|
||||
/* Ignore sudoRole without sudoCommand or sudoHost. */
|
||||
rc = handle->fn_get_values(rule, "sudoCommand", &cmnds);
|
||||
if (rc != 0)
|
||||
goto cleanup;
|
||||
rc = handle->fn_get_values(rule, "sudoHost", &hosts);
|
||||
if (rc != 0)
|
||||
goto cleanup;
|
||||
|
||||
/* Get the entry's dn for long format printing. */
|
||||
rc = handle->fn_get_values(rule, "cn", &cn_array);
|
||||
if (rc != 0)
|
||||
goto cleanup;
|
||||
cn = cn_array[0];
|
||||
|
||||
/* Get sudoRunAsUser / sudoRunAs */
|
||||
rc = handle->fn_get_values(rule, "sudoRunAsUser", &runasusers);
|
||||
switch (rc) {
|
||||
case 0:
|
||||
break;
|
||||
case ENOENT:
|
||||
rc = handle->fn_get_values(rule, "sudoRunAs", &runasusers);
|
||||
switch (rc) {
|
||||
case 0:
|
||||
case ENOENT:
|
||||
break;
|
||||
default:
|
||||
goto cleanup;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Get sudoRunAsGroup */
|
||||
rc = handle->fn_get_values(rule, "sudoRunAsGroup", &runasgroups);
|
||||
switch (rc) {
|
||||
case 0:
|
||||
case ENOENT:
|
||||
break;
|
||||
default:
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Get sudoNotBefore */
|
||||
rc = handle->fn_get_values(rule, "sudoNotBefore", ¬before);
|
||||
switch (rc) {
|
||||
case 0:
|
||||
case ENOENT:
|
||||
break;
|
||||
default:
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Get sudoNotAfter */
|
||||
rc = handle->fn_get_values(rule, "sudoNotAfter", ¬after);
|
||||
switch (rc) {
|
||||
case 0:
|
||||
case ENOENT:
|
||||
break;
|
||||
default:
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Parse sudoOptions. */
|
||||
rc = handle->fn_get_values(rule, "sudoOption", &opts);
|
||||
switch (rc) {
|
||||
case 0:
|
||||
case ENOENT:
|
||||
break;
|
||||
default:
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
priv = sudo_ldap_role_to_priv(cn, hosts, runasusers, runasgroups,
|
||||
cmnds, opts, notbefore ? notbefore[0] : NULL,
|
||||
notafter ? notafter[0] : NULL, false, true, val_array_iter);
|
||||
if (priv == NULL) {
|
||||
rc = ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
rc = 0;
|
||||
|
||||
cleanup:
|
||||
if (cn_array != NULL)
|
||||
handle->fn_free_values(cn_array);
|
||||
if (cmnds != NULL)
|
||||
handle->fn_free_values(cmnds);
|
||||
if (hosts != NULL)
|
||||
handle->fn_free_values(hosts);
|
||||
if (runasusers != NULL)
|
||||
handle->fn_free_values(runasusers);
|
||||
if (runasgroups != NULL)
|
||||
handle->fn_free_values(runasgroups);
|
||||
if (opts != NULL)
|
||||
handle->fn_free_values(opts);
|
||||
if (notbefore != NULL)
|
||||
handle->fn_free_values(notbefore);
|
||||
if (notafter != NULL)
|
||||
handle->fn_free_values(notafter);
|
||||
|
||||
*rc_out = rc;
|
||||
|
||||
debug_return_ptr(priv);
|
||||
}
|
||||
|
||||
static bool
|
||||
sss_to_sudoers(struct sudo_sss_handle *handle,
|
||||
struct sss_sudo_result *sss_result)
|
||||
@@ -256,7 +376,7 @@ sss_to_sudoers(struct sudo_sss_handle *handle,
|
||||
TAILQ_INSERT_TAIL(&us->users, m, entries);
|
||||
|
||||
/*
|
||||
* Treat each sudoRole as a separate privilege.
|
||||
* Treat each rule as a separate privilege.
|
||||
*
|
||||
* Sssd has already sorted the rules in descending order.
|
||||
* The conversion to a sudoers parse tree requires that entries be
|
||||
@@ -264,10 +384,8 @@ sss_to_sudoers(struct sudo_sss_handle *handle,
|
||||
*/
|
||||
for (i = sss_result->num_rules; i-- > 0; ) {
|
||||
struct sss_sudo_rule *rule = sss_result->rules + i;
|
||||
char **cmnds, **runasusers = NULL, **runasgroups = NULL;
|
||||
char **opts = NULL, **notbefore = NULL, **notafter = NULL;
|
||||
char **hosts = NULL, **cn_array = NULL, *cn = NULL;
|
||||
struct privilege *priv = NULL;
|
||||
struct privilege *priv;
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* We don't know whether a rule was included due to a user/group
|
||||
@@ -276,113 +394,11 @@ sss_to_sudoers(struct sudo_sss_handle *handle,
|
||||
if (!sudo_sss_check_user(handle, rule))
|
||||
continue;
|
||||
|
||||
switch (handle->fn_get_values(rule, "sudoCommand", &cmnds)) {
|
||||
case 0:
|
||||
break;
|
||||
case ENOENT:
|
||||
/* Ignore sudoRole without sudoCommand. */
|
||||
if ((priv = sss_rule_to_priv(handle, rule, &rc)) == NULL) {
|
||||
if (rc == ENOMEM)
|
||||
goto oom;
|
||||
continue;
|
||||
default:
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Get the entry's dn for long format printing. */
|
||||
switch (handle->fn_get_values(rule, "cn", &cn_array)) {
|
||||
case 0:
|
||||
cn = cn_array[0];
|
||||
break;
|
||||
case ENOENT:
|
||||
break;
|
||||
default:
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Get sudoHost */
|
||||
switch (handle->fn_get_values(rule, "sudoHost", &hosts)) {
|
||||
case 0:
|
||||
case ENOENT:
|
||||
break;
|
||||
default:
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Get sudoRunAsUser / sudoRunAs */
|
||||
switch (handle->fn_get_values(rule, "sudoRunAsUser", &runasusers)) {
|
||||
case 0:
|
||||
break;
|
||||
case ENOENT:
|
||||
switch (handle->fn_get_values(rule, "sudoRunAs", &runasusers)) {
|
||||
case 0:
|
||||
case ENOENT:
|
||||
break;
|
||||
default:
|
||||
goto cleanup;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Get sudoRunAsGroup */
|
||||
switch (handle->fn_get_values(rule, "sudoRunAsGroup", &runasgroups)) {
|
||||
case 0:
|
||||
case ENOENT:
|
||||
break;
|
||||
default:
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Get sudoNotBefore */
|
||||
switch (handle->fn_get_values(rule, "sudoNotBefore", ¬before)) {
|
||||
case 0:
|
||||
case ENOENT:
|
||||
break;
|
||||
default:
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Get sudoNotAfter */
|
||||
switch (handle->fn_get_values(rule, "sudoNotAfter", ¬after)) {
|
||||
case 0:
|
||||
case ENOENT:
|
||||
break;
|
||||
default:
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Parse sudoOptions. */
|
||||
switch (handle->fn_get_values(rule, "sudoOption", &opts)) {
|
||||
case 0:
|
||||
case ENOENT:
|
||||
break;
|
||||
default:
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
priv = sudo_ldap_role_to_priv(cn, hosts, runasusers, runasgroups,
|
||||
cmnds, opts, notbefore ? notbefore[0] : NULL,
|
||||
notafter ? notafter[0] : NULL, false, true, val_array_iter);
|
||||
|
||||
cleanup:
|
||||
if (cn_array != NULL)
|
||||
handle->fn_free_values(cn_array);
|
||||
if (cmnds != NULL)
|
||||
handle->fn_free_values(cmnds);
|
||||
if (hosts != NULL)
|
||||
handle->fn_free_values(hosts);
|
||||
if (runasusers != NULL)
|
||||
handle->fn_free_values(runasusers);
|
||||
if (runasgroups != NULL)
|
||||
handle->fn_free_values(runasgroups);
|
||||
if (opts != NULL)
|
||||
handle->fn_free_values(opts);
|
||||
if (notbefore != NULL)
|
||||
handle->fn_free_values(notbefore);
|
||||
if (notafter != NULL)
|
||||
handle->fn_free_values(notafter);
|
||||
|
||||
if (priv == NULL)
|
||||
goto oom;
|
||||
TAILQ_INSERT_TAIL(&us->privileges, priv, entries);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user