static int do_regex(REQUEST *request, char const *lhs, char const *rhs, bool iflag) { int compare; int cflags = REG_EXTENDED; regex_t reg; regmatch_t rxmatch[REQUEST_MAX_REGEX + 1]; if (iflag) cflags |= REG_ICASE; /* * Include substring matches. */ compare = regcomp(®, rhs, cflags); if (compare != 0) { if (debug_flag) { char errbuf[128]; regerror(compare, ®, errbuf, sizeof(errbuf)); EDEBUG("Failed compiling regular expression: %s", errbuf); } EVAL_DEBUG("FAIL %d", __LINE__); return -1; } memset(&rxmatch, 0, sizeof(rxmatch)); /* regexec does not seem to initialise unused elements */ compare = regexec(®, lhs, REQUEST_MAX_REGEX + 1, rxmatch, 0); regfree(®); rad_regcapture(request, compare, lhs, rxmatch); return (compare == 0); }
static int do_regex(REQUEST *request, value_pair_map_t const *map, bool iflag) { int compare, rcode; int cflags = REG_EXTENDED; regex_t reg, *preg; char *lhs, *rhs; regmatch_t rxmatch[REQUEST_MAX_REGEX + 1]; if (iflag) cflags |= REG_ICASE; /* * Expand and then compile it. */ if (map->src->type == VPT_TYPE_REGEX) { rcode = radius_expand_tmpl(&rhs, request, map->src); if (rcode < 0) { EVAL_DEBUG("FAIL %d", __LINE__); return -1; } rad_assert(rhs != NULL); compare = regcomp(®, rhs, cflags); if (compare != 0) { if (debug_flag) { char errbuf[128]; regerror(compare, ®, errbuf, sizeof(errbuf)); EDEBUG("Failed compiling regular expression: %s", errbuf); } EVAL_DEBUG("FAIL %d", __LINE__); return -1; } preg = ® } else { preg = map->src->vpt_preg; } rcode = radius_expand_tmpl(&lhs, request, map->dst); if (rcode < 0) { EVAL_DEBUG("FAIL %d", __LINE__); return -1; } rad_assert(lhs != NULL); memset(&rxmatch, 0, sizeof(rxmatch)); /* regexec does not seem to initialise unused elements */ compare = regexec(preg, lhs, REQUEST_MAX_REGEX + 1, rxmatch, 0); rad_regcapture(request, compare, lhs, rxmatch); return (compare == 0); }
static int do_regex(REQUEST *request, value_pair_map_t const *map) { int compare, rcode, ret; regex_t reg, *preg; char *lhs, *rhs; regmatch_t rxmatch[REQUEST_MAX_REGEX + 1]; /* * Expand and then compile it. */ switch (map->src->type) { case TMPL_TYPE_REGEX: rcode = radius_expand_tmpl(&rhs, request, map->src); if (rcode < 0) { EVAL_DEBUG("FAIL %d", __LINE__); return -1; } rad_assert(rhs != NULL); compare = regcomp(®, rhs, REG_EXTENDED | (map->src->tmpl_iflag ? REG_ICASE : 0)); if (compare != 0) { if (debug_flag) { char errbuf[128]; regerror(compare, ®, errbuf, sizeof(errbuf)); ERROR("Failed compiling regular expression: %s", errbuf); } EVAL_DEBUG("FAIL %d", __LINE__); return -1; } preg = ® break; case TMPL_TYPE_REGEX_STRUCT: preg = map->src->tmpl_preg; break; default: rad_assert(0); return -1; } rcode = radius_expand_tmpl(&lhs, request, map->dst); if (rcode < 0) { EVAL_DEBUG("FAIL %d", __LINE__); ret = -1; goto finish; } rad_assert(lhs != NULL); /* * regexec doesn't initialise unused elements */ memset(&rxmatch, 0, sizeof(rxmatch)); compare = regexec(preg, lhs, REQUEST_MAX_REGEX + 1, rxmatch, 0); rad_regcapture(request, compare, lhs, rxmatch); ret = (compare == 0); finish: /* * regcomp allocs extra memory for the expression, so if the * result wasn't cached we need to free it here. */ if (preg == ®) regfree(®); return ret; }
/** Compares check and vp by value. * * Does not call any per-attribute comparison function, but does honour * check.operator. Basically does "vp.value check.op check.value". * * @param request Current request. * @param check rvalue, and operator. * @param vp lvalue. * @return 0 if check and vp are equal, -1 if vp value is less than check value, 1 is vp value is more than check * value, -2 on error. */ int radius_compare_vps(REQUEST *request, VALUE_PAIR *check, VALUE_PAIR *vp) { int ret = 0; /* * Check for =* and !* and return appropriately */ if (check->op == T_OP_CMP_TRUE) return 0; if (check->op == T_OP_CMP_FALSE) return 1; #ifdef HAVE_REGEX_H if (check->op == T_OP_REG_EQ) { int compare; regex_t reg; char value[1024]; regmatch_t rxmatch[REQUEST_MAX_REGEX + 1]; vp_prints_value(value, sizeof(value), vp, -1); /* * Include substring matches. */ compare = regcomp(®, check->vp_strvalue, REG_EXTENDED); if (compare != 0) { char buffer[256]; regerror(compare, ®, buffer, sizeof(buffer)); RDEBUG("Invalid regular expression %s: %s", check->vp_strvalue, buffer); return -2; } memset(&rxmatch, 0, sizeof(rxmatch)); /* regexec does not seem to initialise unused elements */ compare = regexec(®, value, REQUEST_MAX_REGEX + 1, rxmatch, 0); regfree(®); rad_regcapture(request, compare, value, rxmatch); ret = (compare == 0) ? 0 : -1; goto finish; } if (check->op == T_OP_REG_NE) { int compare; regex_t reg; char value[1024]; regmatch_t rxmatch[REQUEST_MAX_REGEX + 1]; vp_prints_value(value, sizeof(value), vp, -1); /* * Include substring matches. */ compare = regcomp(®, check->vp_strvalue, REG_EXTENDED); if (compare != 0) { char buffer[256]; regerror(compare, ®, buffer, sizeof(buffer)); RDEBUG("Invalid regular expression %s: %s", check->vp_strvalue, buffer); return -2; } compare = regexec(®, value, REQUEST_MAX_REGEX + 1, rxmatch, 0); regfree(®); ret = (compare != 0) ? 0 : -1; } #endif /* * Attributes must be of the same type. * * FIXME: deal with type mismatch properly if one side contain * ABINARY, OCTETS or STRING by converting the other side to * a string * */ if (vp->da->type != check->da->type) return -1; /* * Tagged attributes are equal if and only if both the * tag AND value match. */ if (check->da->flags.has_tag) { ret = ((int) vp->tag) - ((int) check->tag); goto finish; } /* * Not a regular expression, compare the types. */ switch(check->da->type) { #ifdef WITH_ASCEND_BINARY /* * Ascend binary attributes can be treated * as opaque objects, I guess... */ case PW_TYPE_ABINARY: #endif case PW_TYPE_OCTETS: if (vp->length != check->length) { ret = 1; /* NOT equal */ break; } ret = memcmp(vp->vp_strvalue, check->vp_strvalue, vp->length); break; case PW_TYPE_STRING: ret = strcmp(vp->vp_strvalue, check->vp_strvalue); break; case PW_TYPE_BYTE: case PW_TYPE_SHORT: case PW_TYPE_INTEGER: ret = vp->vp_integer - check->vp_integer; break; case PW_TYPE_INTEGER64: /* * Don't want integer overflow! */ if (vp->vp_integer64 < check->vp_integer64) { ret = -1; } else if (vp->vp_integer64 > check->vp_integer64) { ret = +1; } else { ret = 0; } break; case PW_TYPE_SIGNED: if (vp->vp_signed < check->vp_signed) { ret = -1; } else if (vp->vp_signed > check->vp_signed) { ret = +1; } else { ret = 0; } break; case PW_TYPE_DATE: ret = vp->vp_date - check->vp_date; break; case PW_TYPE_IPADDR: ret = ntohl(vp->vp_ipaddr) - ntohl(check->vp_ipaddr); break; case PW_TYPE_IPV6ADDR: ret = memcmp(&vp->vp_ipv6addr, &check->vp_ipv6addr, sizeof(vp->vp_ipv6addr)); break; case PW_TYPE_IPV6PREFIX: ret = memcmp(&vp->vp_ipv6prefix, &check->vp_ipv6prefix, sizeof(vp->vp_ipv6prefix)); break; case PW_TYPE_IFID: ret = memcmp(&vp->vp_ifid, &check->vp_ifid, sizeof(vp->vp_ifid)); break; default: break; } finish: if (ret > 0) { return 1; } if (ret < 0) { return -1; } return 0; }