From: Arran Cudbard-Bell Date: Sun, 5 Jun 2022 09:01:37 +0000 (-0400) Subject: Break out parse functions more X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0a48b23dfdcb18a363546b47ff901f9f0a1ba227;p=thirdparty%2Ffreeradius-server.git Break out parse functions more --- diff --git a/src/lib/server/cf_parse.c b/src/lib/server/cf_parse.c index 4fe2ecd374b..3191ef84f41 100644 --- a/src/lib/server/cf_parse.c +++ b/src/lib/server/cf_parse.c @@ -46,7 +46,7 @@ static char const parse_spaces[] = " #define PAIR_SPACE(_cs) ((_cs->depth + 1) * 2) #define SECTION_SPACE(_cs) (_cs->depth * 2) -static void cf_pair_debug(CONF_SECTION const *cs, CONF_PAIR const *cp, CONF_PARSER const *rule) +void cf_pair_debug(CONF_SECTION const *cs, CONF_PAIR const *cp, CONF_PARSER const *rule) { char const *value; char *tmp = NULL; @@ -105,6 +105,55 @@ static void cf_pair_debug(CONF_SECTION const *cs, CONF_PAIR const *cp, CONF_PARS talloc_free(tmp); } +/** Parses a #CONF_PAIR into a boxed value + * + * @copybrief cf_pair_value + * @see cf_pair_value + * + * @param[in] ctx to allocate any dynamic buffers in. + * @param[out] out Where to write the parsed value. + * @param[in] cp to parse. + * @param[in] rule to parse to. May contain flags. + * @return + * - 0 on success. + * - -1 on failure. + */ +int cf_pair_to_value_box(TALLOC_CTX *ctx, fr_value_box_t *out, CONF_PAIR *cp, CONF_PARSER const *rule) +{ + CONF_SECTION *cs = cf_item_to_section(cf_parent(cp)); + fr_type_t type = FR_BASE_TYPE(rule->type); + + if (fr_value_box_from_str(ctx, out, type, NULL, + cf_pair_value(cp), strlen(cf_pair_value(cp)), NULL, false) < 0) { + cf_log_perr(cs, "Invalid value \"%s\" for config item %s", + cp->value, cp->attr); + + return -1; + } + + if (!cp->printed) cf_pair_debug(cs, cp, rule); + + /* + * Strings can be file paths... + */ + if (fr_type_is_string(type)) { + /* + * If there's out AND it's an input file, check + * that we can read it. This check allows errors + * to be caught as early as possible, during + * server startup. + */ + if (fr_rule_file_input(rule) && !cf_file_check(cs, cp->value, true)) { + error: + fr_value_box_clear(out); + return -1; + } + if (fr_rule_file_exists(rule) && !cf_file_check(cs, cp->value, false)) goto error; + } + + return 0; +} + /** Parses a #CONF_PAIR into a C data type * * @copybrief cf_pair_value @@ -123,7 +172,7 @@ static void cf_pair_debug(CONF_SECTION const *cs, CONF_PAIR const *cp, CONF_PARS int cf_pair_parse_value(TALLOC_CTX *ctx, void *out, UNUSED void *base, CONF_ITEM *ci, CONF_PARSER const *rule) { int ret = 0; - bool attribute, required, file_input, cant_be_empty, tmpl, file_exists, nonblock; + bool cant_be_empty, tmpl, nonblock; ssize_t slen; @@ -131,18 +180,14 @@ int cf_pair_parse_value(TALLOC_CTX *ctx, void *out, UNUSED void *base, CONF_ITEM CONF_PAIR *cp = cf_item_to_pair(ci); CONF_SECTION *cs = cf_item_to_section(cf_parent(ci)); - attribute = (type & FR_TYPE_ATTRIBUTE); - required = (type & FR_TYPE_REQUIRED); - file_input = (type == FR_TYPE_FILE_INPUT); /* check, not and */ - file_exists = (type == FR_TYPE_FILE_EXISTS); /* check, not and */ - cant_be_empty = (type & FR_TYPE_NOT_EMPTY); - tmpl = (type & FR_TYPE_TMPL); - nonblock = (type & FR_TYPE_NON_BLOCKING); + cant_be_empty = fr_rule_not_empty(rule); + tmpl = fr_rule_tmpl(rule); + nonblock = fr_rule_non_blocking(rule); fr_assert(cp); - fr_assert(!(type & FR_TYPE_ATTRIBUTE) || tmpl); /* Attribute flag only valid for templates */ + fr_assert(!fr_rule_attribute(rule) || tmpl); /* Attribute flag only valid for templates */ - if (required) cant_be_empty = true; /* May want to review this in the future... */ + if (fr_rule_required(rule)) cant_be_empty = true; /* May want to review this in the future... */ type = FR_BASE_TYPE(type); /* normal types are small */ @@ -167,7 +212,7 @@ int cf_pair_parse_value(TALLOC_CTX *ctx, void *out, UNUSED void *base, CONF_ITEM */ if ((cp->value[0] == '\0') && cant_be_empty) { cf_log_err(cp, "Configuration pair \"%s\" must not be empty (zero length)", cp->attr); - if (!required) cf_log_err(cp, "Comment item to silence this message"); + if (!fr_rule_required(rule)) cf_log_err(cp, "Comment item to silence this message"); error: ret = -1; return ret; @@ -205,7 +250,7 @@ int cf_pair_parse_value(TALLOC_CTX *ctx, void *out, UNUSED void *base, CONF_ITEM goto error; } fr_sbuff_adv_past_whitespace(&sbuff, SIZE_MAX, NULL); - } else if (attribute) { + } else if (fr_rule_attribute(rule)) { cf_log_err(cp, "Invalid quoting. Unquoted attribute reference is required"); goto error; } @@ -215,7 +260,7 @@ int cf_pair_parse_value(TALLOC_CTX *ctx, void *out, UNUSED void *base, CONF_ITEM &rules); if (!vpt) goto tmpl_error; - if (attribute && (!tmpl_is_attr(vpt) && !tmpl_is_attr_unresolved(vpt))) { + if (fr_rule_attribute(rule) && (!tmpl_is_attr(vpt) && !tmpl_is_attr_unresolved(vpt))) { cf_log_err(cp, "Expected attr got %s", tmpl_type_to_str(vpt->type)); return -1; @@ -251,35 +296,12 @@ int cf_pair_parse_value(TALLOC_CTX *ctx, void *out, UNUSED void *base, CONF_ITEM { fr_value_box_t vb; - if (fr_value_box_from_str(ctx, &vb, type, NULL, - cf_pair_value(cp), strlen(cf_pair_value(cp)), NULL, false) < 0) { - cf_log_perr(cs, "Invalid value \"%s\" for config item %s", - cp->value, cp->attr); - - return -1; - } + if (cf_pair_to_value_box(ctx, &vb, cf_item_to_pair(ci), rule) < 0) goto error; - if (!cp->printed) cf_pair_debug(cs, cp, rule); - - /* - * Strings can be file paths... - */ - if (fr_type_is_string(type)) { - /* - * If there's out AND it's an input file, check - * that we can read it. This check allows errors - * to be caught as early as possible, during - * server startup. - */ - if (file_input && !cf_file_check(cs, cp->value, true)) { - value_error: - fr_value_box_clear_value(&vb); - goto error; - } - if (file_exists && !cf_file_check(cs, cp->value, false)) goto value_error; + if (fr_value_box_memcpy_out(out, &vb) < 0) { + fr_value_box_clear_value(&vb); + goto error; } - - if (fr_value_box_memcpy_out(out, &vb) < 0) goto value_error; } finish: diff --git a/src/lib/server/cf_parse.h b/src/lib/server/cf_parse.h index 75b0f3469ff..1204ddfa751 100644 --- a/src/lib/server/cf_parse.h +++ b/src/lib/server/cf_parse.h @@ -30,8 +30,9 @@ RCSIDH(cf_parse_h, "$Id$") #include #include #include -#include #include +#include +#include #include #ifdef __cplusplus @@ -312,6 +313,39 @@ _Generic((_ct), \ #define FR_BASE_TYPE(_t) (0xff & (_t)) /** @} */ +/** @name #CONF_PARSER flags checks + * + * @{ + */ +#define fr_rule_deprecated(_rule) ((_rule)->type & FR_TYPE_DEPRECATED) + +#define fr_rule_required(_rule) ((_rule)->type & FR_TYPE_REQUIRED) + +#define fr_rule_attribute(_rule) ((_rule)->type & FR_TYPE_ATTRIBUTE) + +#define fr_rule_secret(_rule) ((_rule)->type & FR_TYPE_SECRET) + +#define fr_rule_file_input(_rule) ((_rule)->type & FR_TYPE_FILE_INPUT) + +#define fr_rule_file_output(_rule) ((_rule)->type & FR_TYPE_FILE_OUTPUT) + +#define fr_rule_xlat(_rule) ((_rule)->type & FR_TYPE_XLAT) + +#define fr_rule_tmpl(_rule) ((_rule)->type & FR_TYPE_TMPL) + +#define fr_rule_multi(_rule) ((_rule)->type & FR_TYPE_MULTI) + +#define fr_rule_not_empty(_rule) ((_rule)->type & FR_TYPE_NOT_EMPTY) + +#define fr_rule_is_set(_rule) ((_rule)->type & FR_TYPE_IS_SET) + +#define fr_rule_ok_missing(_rule) ((_rule)->type & FR_TYPE_OK_MISSING) + +#define fr_rule_non_blocking(_rule) ((_rule)->type & FR_TYPE_NON_BLOCKING) + +#define fr_rule_file_exists(_rule) ((_rule)->type & FR_TYPE_FILE_EXISTS) +/** @} */ + #define FR_SIZE_COND_CHECK(_name, _var, _cond, _new)\ do {\ if (!(_cond)) {\ @@ -481,11 +515,17 @@ typedef struct { #define CF_FILE_CONFIG (1 << 2) #define CF_FILE_MODULE (1 << 3) +void cf_pair_debug(CONF_SECTION const *cs, CONF_PAIR const *cp, CONF_PARSER const *rule); + /* * Type validation and conversion */ +int cf_pair_to_value_box(TALLOC_CTX *ctx, fr_value_box_t *out, CONF_PAIR *cp, CONF_PARSER const *rule) + CC_HINT(nonnull(2, 3, 4)); + int cf_pair_parse_value(TALLOC_CTX *ctx, void *out, void *base, CONF_ITEM *ci, CONF_PARSER const *rule) CC_HINT(nonnull(2, 4, 5)); + int cf_pair_parse(TALLOC_CTX *ctx, CONF_SECTION *cs, char const *name, unsigned int type, void *data, char const *dflt, fr_token_t dflt_quote) CC_HINT(nonnull(2,3)); int cf_section_parse(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs);