From: Arran Cudbard-Bell Date: Thu, 1 Jan 2015 18:13:27 +0000 (-0500) Subject: Rename radius_expand_tmpl to tmpl_expand and make it write the result to a char point... X-Git-Tag: release_3_0_7~377 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5d18a7a76e6402a51d8e09bab91d8658d1cefe09;p=thirdparty%2Ffreeradius-server.git Rename radius_expand_tmpl to tmpl_expand and make it write the result to a char pointer instead of value_data This means it can be used in more places --- diff --git a/src/include/radiusd.h b/src/include/radiusd.h index 6c212831e9b..8d3778dda5d 100644 --- a/src/include/radiusd.h +++ b/src/include/radiusd.h @@ -767,7 +767,6 @@ void mark_home_server_dead(home_server_t *home, struct timeval *when); /* evaluate.c */ typedef struct fr_cond_t fr_cond_t; -ssize_t radius_expand_tmpl(value_data_t *vd, REQUEST *request, value_pair_tmpl_t const *vpt); int radius_evaluate_tmpl(REQUEST *request, int modreturn, int depth, value_pair_tmpl_t const *vpt); int radius_evaluate_map(REQUEST *request, int modreturn, int depth, diff --git a/src/include/tmpl.h b/src/include/tmpl.h index b587852e6e0..1fd7c84520f 100644 --- a/src/include/tmpl.h +++ b/src/include/tmpl.h @@ -249,6 +249,9 @@ size_t tmpl_prints(char *buffer, size_t bufsize, value_pair_tmpl_t const *vpt, int tmpl_cast_to_vp(VALUE_PAIR **out, REQUEST *request, value_pair_tmpl_t const *vpt, DICT_ATTR const *cast); +ssize_t tmpl_expand(TALLOC_CTX *ctx, char **out, REQUEST *request, + value_pair_tmpl_t const *vpt); + VALUE_PAIR *tmpl_cursor_init(int *err, vp_cursor_t *cursor, REQUEST *request, value_pair_tmpl_t const *vpt); diff --git a/src/main/evaluate.c b/src/main/evaluate.c index f658933cd9d..0c1ffde6ee2 100644 --- a/src/main/evaluate.c +++ b/src/main/evaluate.c @@ -66,121 +66,6 @@ static bool all_digits(char const *string) return (*p == '\0'); } -/** Expand the RHS of a template - * - * @note Length of expanded string can be found with talloc_array_length(*out) - 1 - * - * @param vd the output string - * @param request Current request. - * @param vpt to evaluate. - * @return -1 on error, else 0. - */ -ssize_t radius_expand_tmpl(value_data_t *vd, REQUEST *request, value_pair_tmpl_t const *vpt) -{ - VALUE_PAIR *vp; - ssize_t slen = -1; /* quiet compiler */ - char *out = NULL; - - rad_assert(vpt->type != TMPL_TYPE_LIST); - - VERIFY_TMPL(vpt); - - switch (vpt->type) { - case TMPL_TYPE_LITERAL: - EVAL_DEBUG("EXPAND TMPL LITERAL"); - vd->strvalue = talloc_memdup(request, vpt->name, vpt->len); - return vpt->len; - - case TMPL_TYPE_EXEC: - EVAL_DEBUG("EXPAND TMPL EXEC"); - out = talloc_array(request, char, 1024); - if (radius_exec_program(out, 1024, NULL, request, vpt->name, NULL, true, false, EXEC_TIMEOUT) != 0) { - TALLOC_FREE(out); - return -1; - } - slen = strlen(out); - break; - - case TMPL_TYPE_XLAT: - EVAL_DEBUG("EXPAND TMPL XLAT"); - /* Error in expansion, this is distinct from zero length expansion */ - slen = radius_axlat(&out, request, vpt->name, NULL, NULL); - if (slen < 0) { - rad_assert(!out); - return slen; - } - slen = strlen(out); - break; - - case TMPL_TYPE_XLAT_STRUCT: - EVAL_DEBUG("EXPAND TMPL XLAT STRUCT"); - /* Error in expansion, this is distinct from zero length expansion */ - slen = radius_axlat_struct(&out, request, vpt->tmpl_xlat, NULL, NULL); - if (slen < 0) { - rad_assert(!out); - return slen; - } - slen = strlen(out); - break; - - case TMPL_TYPE_ATTR: - { - int ret; - - EVAL_DEBUG("EXPAND TMPL ATTR"); - ret = tmpl_find_vp(&vp, request, vpt); - if (ret < 0) return -2; - - out = vp_aprints_value(request, vp, '"'); - if (!out) return -1; - slen = talloc_array_length(out) - 1; - } - break; - - /* - * We should never be expanding these. - */ - case TMPL_TYPE_UNKNOWN: - case TMPL_TYPE_NULL: - case TMPL_TYPE_LIST: - case TMPL_TYPE_DATA: - case TMPL_TYPE_REGEX: - case TMPL_TYPE_ATTR_UNDEFINED: - case TMPL_TYPE_REGEX_STRUCT: - rad_assert(0 == 1); - slen = -1; - break; - } - - if (slen < 0) return slen; - - vd->strvalue = out; - - /* - * If we're doing correct escapes, we may have to re-parse the string. - * If the string is from another expansion, it needs re-parsing. - * Or, if it's from a "string" attribute, it needs re-parsing. - * Integers, IP addresses, etc. don't need re-parsing. - */ - if (cf_new_escape && - ((vpt->type != TMPL_TYPE_ATTR) || - (vpt->tmpl_da->type == PW_TYPE_STRING))) { - PW_TYPE type = PW_TYPE_STRING; - - slen = value_data_from_str(request, vd, &type, NULL, out, slen, '"'); - out = vd->ptr; - } - - if (vpt->type == TMPL_TYPE_XLAT_STRUCT) { - RDEBUG2("EXPAND %s", vpt->name); /* xlat_struct doesn't do this */ - RDEBUG2(" --> %s", out); - } else { - EVAL_DEBUG(" --> %s", out); - } - - return slen; -} - /** Evaluate a template * * Converts a value_pair_tmpl_t to a boolean value. @@ -229,19 +114,24 @@ int radius_evaluate_tmpl(REQUEST *request, int modreturn, UNUSED int depth, valu case TMPL_TYPE_XLAT_STRUCT: case TMPL_TYPE_XLAT: case TMPL_TYPE_EXEC: + { + char *p; + if (!*vpt->name) return false; - rcode = radius_expand_tmpl(&data, request, vpt); + rcode = tmpl_expand(request, &p, request, vpt); if (rcode < 0) { EVAL_DEBUG("FAIL %d", __LINE__); return -1; } + data.strvalue = p; rcode = (data.strvalue && (*data.strvalue != '\0')); talloc_free(data.ptr); + } break; - /* - * Can't have a bare ... (/foo/) ... - */ + /* + * Can't have a bare ... (/foo/) ... + */ case TMPL_TYPE_REGEX: case TMPL_TYPE_REGEX_STRUCT: rad_assert(0 == 1); @@ -626,18 +516,23 @@ do {\ value_data_t data; if (map->rhs->type != TMPL_TYPE_LITERAL) { - ret = radius_expand_tmpl(&data, request, map->rhs); + char *p; + + ret = tmpl_expand(request, &p, request, map->rhs); if (ret < 0) { EVAL_DEBUG("FAIL [%i]", __LINE__); rcode = -1; goto finish; } + data.strvalue = p; rhs_len = ret; } else { data.strvalue = map->rhs->name; rhs_len = map->rhs->len; } + rad_assert(data.strvalue); + rhs_type = PW_TYPE_STRING; rhs = &data; @@ -745,15 +640,19 @@ int radius_evaluate_map(REQUEST *request, UNUSED int modreturn, UNUSED int depth value_data_t data; if (map->lhs->type != TMPL_TYPE_LITERAL) { - ret = radius_expand_tmpl(&data, request, map->lhs); + char *p; + + ret = tmpl_expand(request, &p, request, map->lhs); if (ret < 0) { EVAL_DEBUG("FAIL [%i]", __LINE__); return ret; } + data.strvalue = p; } else { data.strvalue = map->lhs->name; ret = map->lhs->len; } + rad_assert(data.strvalue); rcode = cond_normalise_values(request, c, PW_TYPE_STRING, NULL, &data, ret); if (map->lhs->type != TMPL_TYPE_LITERAL) talloc_free(data.ptr); diff --git a/src/main/modcall.c b/src/main/modcall.c index f8aba74c01b..3bf428039f7 100644 --- a/src/main/modcall.c +++ b/src/main/modcall.c @@ -840,7 +840,10 @@ redo: if ((g->vpt->type == TMPL_TYPE_XLAT_STRUCT) || (g->vpt->type == TMPL_TYPE_XLAT) || (g->vpt->type == TMPL_TYPE_EXEC)) { - if (radius_expand_tmpl(&data, request, g->vpt) < 0) goto find_null_case; + char *p; + + if (tmpl_expand(request, &p, request, g->vpt) < 0) goto find_null_case; + data.strvalue = p; tmpl_init(&vpt, TMPL_TYPE_LITERAL, data.strvalue, talloc_array_length(data.strvalue) - 1); } diff --git a/src/main/tmpl.c b/src/main/tmpl.c index fcd702f7446..6a0c6f30093 100644 --- a/src/main/tmpl.c +++ b/src/main/tmpl.c @@ -1427,6 +1427,7 @@ int tmpl_cast_to_vp(VALUE_PAIR **out, REQUEST *request, int rcode; VALUE_PAIR *vp; value_data_t data; + char *p; VERIFY_TMPL(vpt); @@ -1444,11 +1445,12 @@ int tmpl_cast_to_vp(VALUE_PAIR **out, REQUEST *request, return 0; } - rcode = radius_expand_tmpl(&data, request, vpt); + rcode = tmpl_expand(vp, &p, request, vpt); if (rcode < 0) { pairfree(&vp); return rcode; } + data.strvalue = p; /* * New escapes: strings are in binary form. @@ -1458,15 +1460,135 @@ int tmpl_cast_to_vp(VALUE_PAIR **out, REQUEST *request, vp->vp_length = rcode; } else if (pairparsevalue(vp, data.strvalue, rcode) < 0) { - talloc_free(data.ptr); - pairfree(&vp); - return -1; + talloc_free(data.ptr); + pairfree(&vp); + return -1; } *out = vp; return 0; } + +/** Expand a template to a string, writing the result + * + * @param ctx to alloc output string in. + * @param out Result of expanding the tmpl. + * @param request Current request. + * @param vpt to evaluate. + * @return -1 on error, else 0. + */ +ssize_t tmpl_expand(TALLOC_CTX *ctx, char **out, REQUEST *request, value_pair_tmpl_t const *vpt) +{ + VALUE_PAIR *vp; + ssize_t slen = -1; /* quiet compiler */ + + rad_assert(vpt->type != TMPL_TYPE_LIST); + + VERIFY_TMPL(vpt); + + *out = NULL; + + switch (vpt->type) { + case TMPL_TYPE_LITERAL: + RDEBUG4("EXPAND TMPL LITERAL"); + *out = talloc_memdup(ctx, vpt->name, vpt->len); + return vpt->len; + + case TMPL_TYPE_EXEC: + { + char *buff = NULL; + + RDEBUG4("EXPAND TMPL EXEC"); + buff = talloc_array(ctx, char, 1024); + if (radius_exec_program(buff, 1024, NULL, request, vpt->name, NULL, true, false, EXEC_TIMEOUT) != 0) { + TALLOC_FREE(buff); + return -1; + } + slen = strlen(buff); + *out = buff; + } + break; + + case TMPL_TYPE_XLAT: + RDEBUG4("EXPAND TMPL XLAT"); + /* Error in expansion, this is distinct from zero length expansion */ + slen = radius_axlat(out, request, vpt->name, NULL, NULL); + if (slen < 0) { + rad_assert(!*out); + return slen; + } + slen = strlen(*out); + break; + + case TMPL_TYPE_XLAT_STRUCT: + RDEBUG4("EXPAND TMPL XLAT STRUCT"); + /* Error in expansion, this is distinct from zero length expansion */ + slen = radius_axlat_struct(out, request, vpt->tmpl_xlat, NULL, NULL); + if (slen < 0) { + rad_assert(!*out); + return slen; + } + slen = strlen(*out); + break; + + case TMPL_TYPE_ATTR: + { + int ret; + + RDEBUG4("EXPAND TMPL ATTR"); + ret = tmpl_find_vp(&vp, request, vpt); + if (ret < 0) return -2; + + *out = vp_aprints_value(ctx, vp, '"'); + if (!*out) return -1; + slen = talloc_array_length(*out) - 1; + } + break; + + /* + * We should never be expanding these. + */ + case TMPL_TYPE_UNKNOWN: + case TMPL_TYPE_NULL: + case TMPL_TYPE_LIST: + case TMPL_TYPE_DATA: + case TMPL_TYPE_REGEX: + case TMPL_TYPE_ATTR_UNDEFINED: + case TMPL_TYPE_REGEX_STRUCT: + rad_assert(0 == 1); + slen = -1; + break; + } + + if (slen < 0) return slen; + + /* + * If we're doing correct escapes, we may have to re-parse the string. + * If the string is from another expansion, it needs re-parsing. + * Or, if it's from a "string" attribute, it needs re-parsing. + * Integers, IP addresses, etc. don't need re-parsing. + */ + if (cf_new_escape && + ((vpt->type != TMPL_TYPE_ATTR) || + (vpt->tmpl_da->type == PW_TYPE_STRING))) { + value_data_t vd; + + PW_TYPE type = PW_TYPE_STRING; + + slen = value_data_from_str(ctx, &vd, &type, NULL, *out, slen, '"'); + talloc_free(*out); /* free the old value */ + *out = vd.ptr; + } + + if (vpt->type == TMPL_TYPE_XLAT_STRUCT) { + RDEBUG2("EXPAND %s", vpt->name); /* xlat_struct doesn't do this */ + RDEBUG2(" --> %s", *out); + } + + return slen; +} + /** Initialise a vp_cursor_t to the VALUE_PAIR specified by a value_pair_tmpl_t * * This makes iterating over the one or more VALUE_PAIRs specified by a value_pair_tmpl_t