int rcode = 0;
bool attribute, required, secret, file_input, cant_be_empty, tmpl, file_exists;
- fr_ipaddr_t *ipaddr;
ssize_t slen;
int type = rule->type;
case FR_TYPE_IPV4_ADDR:
case FR_TYPE_IPV4_PREFIX:
- ipaddr = out;
+ {
+ fr_ipaddr_t *ipaddr = out;
if (fr_inet_pton4(ipaddr, cp->value, -1, true, false, true) < 0) {
cf_log_perr(cp, "Failed parsing config item");
rcode = -1;
goto error;
}
+ }
break;
case FR_TYPE_IPV6_ADDR:
case FR_TYPE_IPV6_PREFIX:
- ipaddr = out;
+ {
+ fr_ipaddr_t *ipaddr = out;
if (fr_inet_pton6(ipaddr, cp->value, -1, true, false, true) < 0) {
cf_log_perr(cp, "Failed parsing config item");
rcode = -1;
goto error;
}
+ }
break;
case FR_TYPE_COMBO_IP_ADDR:
- /*
- * Allow casting to <ipv4addr> or <ipv6addr>, so that we
- * don't need endless configuration options to do similar things.
- *
- * This also makes our new "radclient" easier to write. :)
- */
- if (cp->value && (*cp->value == '<')) {
- int af;
- size_t ip_outlen;
- char const *ip_out, *error;
- fr_dict_attr_t const *cast_da = NULL;
- fr_token_t token;
-
- slen = tmpl_preparse(&ip_out, &ip_outlen, cp->value, talloc_array_length(cp->value) - 1,
- &token, &error, &cast_da, false, false);
- if (slen <= 0) {
- cf_log_perr(cp, "Failed parsing config item");
- rcode = -1;
- goto error;
- }
-
- if (cast_da->type == FR_TYPE_IPV4_ADDR) {
- af = AF_INET;
- type = cast_da->type;
-
- } else if (cast_da->type == FR_TYPE_IPV6_ADDR) {
- af = AF_INET6;
- type = cast_da->type;
-
- } else {
- cf_log_perr(cp, "Invalid cast, expecting 'ipv4addr' or 'ipv6addr'");
- rcode = -1;
- goto error;
- }
+ case FR_TYPE_COMBO_IP_PREFIX:
+ {
+ fr_ipaddr_t *ipaddr = out;
+ int af = AF_UNSPEC;
+ fr_type_t our_type = FR_TYPE_INVALID;
+ fr_sbuff_t sbuff = FR_SBUFF_IN(cp->value, strlen(cp->value));
- ipaddr = out;
+ slen = tmpl_cast_from_substr(&our_type, &sbuff);
+ if (slen < 0) {
+ cf_log_perr(cp, "Failed parsing config item");
+ rcode = -1;
+ goto error;
+ }
- if (fr_inet_pton(ipaddr, ip_out, ip_outlen, af, true, true) < 0) {
- cf_log_perr(cp, "Failed parsing config item");
- rcode = -1;
- goto error;
- }
- /* Also prints the IP to the log */
- if (fr_item_validate_ipaddr(cs, cf_pair_attr(cp), type, ip_out, ipaddr) < 0) {
- rcode = -1;
- goto error;
+ if (slen > 0) {
+ if (type == FR_TYPE_COMBO_IP_ADDR) {
+ switch (our_type) {
+ case FR_TYPE_IPV4_ADDR:
+ af = AF_INET;
+ break;
+
+ case FR_TYPE_IPV6_ADDR:
+ af = AF_INET6;
+ break;
+
+ default:
+ cf_log_perr(cp, "Invalid cast, expecting 'ipv4addr' or 'ipv6addr'");
+ rcode = -1;
+ goto error;
+ }
+ } else if (type == FR_TYPE_COMBO_IP_PREFIX) {
+ switch (our_type) {
+ case FR_TYPE_IPV4_PREFIX:
+ af = AF_INET;
+ break;
+
+ case FR_TYPE_IPV6_PREFIX:
+ af = AF_INET6;
+ break;
+
+ default:
+ cf_log_perr(cp, "Invalid cast, expecting 'ipv4prefix' or 'ipv6prefix'");
+ rcode = -1;
+ goto error;
+ }
}
- break;
}
- FALL_THROUGH;
- case FR_TYPE_COMBO_IP_PREFIX:
- ipaddr = out;
-
- if (fr_inet_pton(ipaddr, cp->value, -1, AF_UNSPEC, true, true) < 0) {
+ if (fr_inet_pton(ipaddr, cp->value, -1, af, true, true) < 0) {
cf_log_perr(cp, "Failed parsing config item");
rcode = -1;
goto error;
rcode = -1;
goto error;
}
+ }
break;
case FR_TYPE_TIME_DELTA:
return 1;
}
-/*
- * Like tmpl_preparse(), but expands variables.
- */
-#if 0
-static ssize_t cond_preparse(TALLOC_CTX *ctx, char const **out, size_t *outlen, char const *in, size_t inlen,
- fr_token_t *type, char const **error,
- fr_dict_attr_t const **castda, bool require_regex,
- CONF_SECTION *cs)
-{
- ssize_t slen, my_slen;
- char *p, *expanded;
- char buffer[8192];
-
- /*
- * When 'request_regex == false', tmpl_preparse() treats
- * '/' as a bare word. This is so that the configuration
- * file parser can parse filenames, which may begin with
- * '/'. We therefore check for leading '/' here, as
- * conditions don't use filenames.
- */
- if (!require_regex && (*in == '/')) {
- fr_strerror_printf("Unexpected regular expression");
- return 0;
- }
-
- /*
- * Allow dynamic xlat expansion everywhere.
- */
- slen = tmpl_preparse(out, outlen, in, inlen, type, error, castda, require_regex, true);
- if (slen <= 0) return slen;
-
- p = strchr(in, '$');
- if (!p) return slen;
-
- if (!((p[1] == '{') ||
- ((p[1] == 'E') && (p[2] == 'N') && (p[3] == 'V') &&
- (p[4] == '{')))) {
- return slen;
- }
-
- if (!cf_expand_variables(cf_filename(cs), cf_lineno(cs), cf_item_to_section(cf_parent(cs)),
- buffer, sizeof(buffer), in, slen, NULL)) {
- fr_strerror_printf("Failed expanding configuration variable");
- return -1;
- }
-
- /*
- * We need to tell the caller how many *input* bytes to
- * skip. Which means that we need to keep treat this
- * length as different.
- */
- my_slen = tmpl_preparse(out, outlen, buffer, strlen(buffer), type, error, castda, require_regex, true);
- if (my_slen <= 0) return my_slen;
-
- if (!*out) return 0; /* for sanity checks, *outlen can be 0 for empty strings */
-
- /*
- * 'out' now points to 'buffer', which we don't want. So
- * we need to return a string which the caller can keep track of.
- */
- expanded = talloc_strndup(ctx, *out, *outlen);
- if (!expanded) {
- fr_strerror_printf("Failed allocating memory");
- return -1;
- }
-
- *out = expanded;
- return slen; /* NOT my_slen */
-}
-#endif
-
static int cond_normalise(TALLOC_CTX *ctx, fr_token_t lhs_type, fr_cond_t **c_out)
{
fr_cond_t *c = *c_out;