From: Todd C. Miller Date: Sat, 10 Feb 2018 05:06:56 +0000 (-0700) Subject: Use an iterator instead of fragile pointer arithmetic to iterate X-Git-Tag: SUDO_1_8_23^2~141 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4459ee42ed8beb0fad9d8aa407bfceb48d834ea4;p=sudo Use an iterator instead of fragile pointer arithmetic to iterate over value arrays in sudo_ldap_role_to_priv(). --- diff --git a/plugins/sudoers/ldap.c b/plugins/sudoers/ldap.c index a781635aa..9498454f2 100644 --- a/plugins/sudoers/ldap.c +++ b/plugins/sudoers/ldap.c @@ -2311,6 +2311,16 @@ sudo_ldap_display_bound_defaults(struct sudo_nss *nss, struct passwd *pw, debug_return_int(0); } +static char * +berval_iter(void *base, void **save) +{ + struct berval **bv; + + bv = *save ? *save : base; + *save = bv + 1; + return *bv ? (*bv)->bv_val : NULL; +} + static struct userspec_list * ldap_to_sudoers(LDAP *ld, struct ldap_result *lres) { @@ -2368,8 +2378,7 @@ ldap_to_sudoers(LDAP *ld, struct ldap_result *lres) priv = sudo_ldap_role_to_priv(cn, runasusers, runasgroups, cmnds, opts, notbefore ? notbefore[0]->bv_val : NULL, - notafter ? notafter[0]->bv_val : NULL, - sizeof(struct berval *), offsetof(struct berval, bv_val)); + notafter ? notafter[0]->bv_val : NULL, berval_iter); /* Cleanup */ if (cn != NULL) diff --git a/plugins/sudoers/ldap_common.c b/plugins/sudoers/ldap_common.c index fa14308c8..144d24e91 100644 --- a/plugins/sudoers/ldap_common.c +++ b/plugins/sudoers/ldap_common.c @@ -117,19 +117,19 @@ sudo_ldap_parse_option(char *optstr, char **varp, char **valp) * The caller is responsible for freeing the returned struct member_list. */ static struct member_list * -array_to_member_list(void *a, size_t ele_size, size_t str_off) +array_to_member_list(void *a, sudo_ldap_iter_t iter) { struct member_list *members; struct member *m; + void *save = NULL; + char *val; debug_decl(bv_to_member_list, SUDOERS_DEBUG_LDAP) if ((members = calloc(1, sizeof(*members))) == NULL) return NULL; TAILQ_INIT(members); - for (;*((char **)a) != NULL; a = (char *)a + ele_size) { - char *val = *(char **)(*((char **)a) + str_off); - + while ((val = iter(a, &save)) != NULL) { if ((m = calloc(1, sizeof(*m))) == NULL) goto bad; @@ -173,13 +173,15 @@ bad: struct privilege * sudo_ldap_role_to_priv(const char *cn, void *runasusers, void *runasgroups, void *cmnds, void *opts, const char *notbefore, - const char *notafter, size_t ele_size, size_t str_off) + const char *notafter, sudo_ldap_iter_t iter) { struct cmndspec *cmndspec = NULL; struct cmndspec *prev_cmndspec = NULL; struct sudo_command *c; struct privilege *priv; struct member *m; + void *cmnds_save = NULL; + char *cmnd; debug_decl(sudo_ldap_role_to_priv, SUDOERS_DEBUG_LDAP) if ((priv = calloc(1, sizeof(*priv))) == NULL) @@ -200,12 +202,8 @@ sudo_ldap_role_to_priv(const char *cn, void *runasusers, void *runasgroups, /* * Parse sudoCommands and add to cmndlist. - * The convoluted pointer arithmetic is to support passing in - * either a struct berval ** or a char ***. - * An interator would probably be better. */ - for (;*((char **)cmnds) != NULL; cmnds = (char *)cmnds + ele_size) { - char *cmnd = *(char **)(*((char **)cmnds) + str_off); + while ((cmnd = iter(cmnds, &cmnds_save)) != NULL) { char *args; /* Allocate storage upfront. */ @@ -256,7 +254,7 @@ sudo_ldap_role_to_priv(const char *cn, void *runasusers, void *runasgroups, /* Parse sudoRunAsUser / sudoRunAs */ if (runasusers != NULL) { cmndspec->runasuserlist = - array_to_member_list(runasusers, ele_size, str_off); + array_to_member_list(runasusers, iter); if (cmndspec->runasuserlist == NULL) goto oom; } @@ -264,7 +262,7 @@ sudo_ldap_role_to_priv(const char *cn, void *runasusers, void *runasgroups, /* Parse sudoRunAsGroup */ if (runasgroups != NULL) { cmndspec->runasgrouplist = - array_to_member_list(runasgroups, ele_size, str_off); + array_to_member_list(runasgroups, iter); if (cmndspec->runasgrouplist == NULL) goto oom; } @@ -277,8 +275,10 @@ sudo_ldap_role_to_priv(const char *cn, void *runasusers, void *runasgroups, /* Parse sudoOptions. */ if (opts != NULL) { - for (; *((char **)opts) != NULL; opts = (char *)opts + ele_size) { - char *opt = *(char **)(*((char **)opts) + str_off); + void *opts_save = NULL; + char *opt; + + while ((opt = iter(opts, &opts_save)) != NULL) { char *var, *val; int op; diff --git a/plugins/sudoers/sssd.c b/plugins/sudoers/sssd.c index c1fd1ec97..d932858b3 100644 --- a/plugins/sudoers/sssd.c +++ b/plugins/sudoers/sssd.c @@ -1408,6 +1408,17 @@ sudo_sss_display_bound_defaults(struct sudo_nss *nss, debug_return_int(0); } +static char * +val_array_iter(void *base, void **save) +{ + char **val_array; + + val_array = *save ? *save : base; + *save = val_array + 1; + + return *val_array; +} + static struct userspec_list * sss_to_sudoers(struct sudo_sss_handle *handle, struct sss_sudo_result *sss_result) { @@ -1466,10 +1477,9 @@ sss_to_sudoers(struct sudo_sss_handle *handle, struct sss_sudo_result *sss_resul /* Parse sudoOptions. */ handle->fn_get_values(rule, "sudoOption", &opts); - priv = sudo_ldap_role_to_priv(cn, runasusers ? &runasusers : NULL, - runasgroups ? &runasgroups: NULL, &cmnds, opts ? &opts : NULL, + priv = sudo_ldap_role_to_priv(cn, runasusers, runasgroups, cmnds, opts, notbefore ? notbefore[0] : NULL, notafter ? notafter[0] : NULL, - sizeof(char **), 0); + val_array_iter); /* Cleanup */ if (cn_array != NULL) diff --git a/plugins/sudoers/sudo_ldap.h b/plugins/sudoers/sudo_ldap.h index 8904433f0..1eb567943 100644 --- a/plugins/sudoers/sudo_ldap.h +++ b/plugins/sudoers/sudo_ldap.h @@ -17,9 +17,11 @@ #ifndef SUDOERS_LDAP_H #define SUDOERS_LDAP_H +typedef char * (*sudo_ldap_iter_t)(void *, void **); + bool sudo_ldap_is_negated(char **valp); int sudo_ldap_parse_option(char *optstr, char **varp, char **valp); -struct privilege *sudo_ldap_role_to_priv(const char *cn, void *runasusers, void *runasgroups, void *cmnds, void *opts, const char *notbefore, const char *notafter, size_t ele_size, size_t str_off); +struct privilege *sudo_ldap_role_to_priv(const char *cn, void *runasusers, void *runasgroups, void *cmnds, void *opts, const char *notbefore, const char *notafter, sudo_ldap_iter_t iter); struct sudo_digest *sudo_ldap_extract_digest(char **cmnd, struct sudo_digest *digest); #endif /* SUDOERS_LDAP_H */