Backport radius_vpt_get_vp changes from master
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 27 May 2014 09:24:52 +0000 (10:24 +0100)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Tue, 27 May 2014 09:25:45 +0000 (10:25 +0100)
src/include/radiusd.h
src/main/evaluate.c
src/main/modcall.c
src/main/valuepair.c

index 7a0028f..530520d 100644 (file)
@@ -732,9 +732,10 @@ int radius_map2request(REQUEST *request, value_pair_map_t const *map,
 int radius_strpair2map(value_pair_map_t **out, REQUEST *request, char const *raw,
                       request_refs_t dst_request_def, pair_lists_t dst_list_def,
                       request_refs_t src_request_def, pair_lists_t src_list_def);
-VALUE_PAIR *radius_vpt_get_vp(REQUEST *request, value_pair_tmpl_t const *vpt);
+int radius_vpt_get_vp(VALUE_PAIR **out, REQUEST *request, value_pair_tmpl_t const *vpt);
 int radius_get_vp(VALUE_PAIR **out, REQUEST *request, char const *name);
 int radius_vpt_copy_vp(VALUE_PAIR **out, REQUEST *request, value_pair_tmpl_t const *vpt);
+int radius_copy_vp(VALUE_PAIR **out, REQUEST *request, char const *name);
 
 #ifdef WITH_TLS
 /*
index dfb9598..234690c 100644 (file)
@@ -90,6 +90,7 @@ static int all_digits(char const *string)
 static int radius_expand_tmpl(char **out, REQUEST *request, value_pair_tmpl_t const *vpt)
 {
        VALUE_PAIR *vp;
+       int ret;
        *out = NULL;
 
        rad_assert(vpt->type != VPT_TYPE_LIST);
@@ -140,10 +141,9 @@ static int radius_expand_tmpl(char **out, REQUEST *request, value_pair_tmpl_t co
 
        case VPT_TYPE_ATTR:
                EVAL_DEBUG("TMPL ATTR");
-               vp = radius_vpt_get_vp(request, vpt);
-               if (!vp) {
-                       return -1;
-               }
+               ret = radius_vpt_get_vp(&vp, request, vpt);
+               if (ret < 0) return ret;
+
                *out = vp_aprint_value(request, vp);
                if (!*out) {
                        return -1;
@@ -200,10 +200,10 @@ int radius_evaluate_tmpl(REQUEST *request, int modreturn, UNUSED int depth,
 
        case VPT_TYPE_ATTR:
        case VPT_TYPE_LIST:
-               if (radius_vpt_get_vp(request, vpt) != NULL) {
-                       rcode = true;
-               } else {
+               if (radius_vpt_get_vp(NULL, request, vpt) < 0) {
                        rcode = false;
+               } else {
+                       rcode = true;
                }
                break;
 
@@ -504,10 +504,8 @@ int radius_evaluate_map(REQUEST *request, UNUSED int modreturn, UNUSED int depth
                VALUE_PAIR *lhs_vp, *rhs_vp;
 
                EVAL_DEBUG("ATTR to ATTR");
-               lhs_vp = radius_vpt_get_vp(request, map->dst);
-               rhs_vp = radius_vpt_get_vp(request, map->src);
-
-               if (!lhs_vp || !rhs_vp) return false;
+               if ((radius_vpt_get_vp(&lhs_vp, request, map->dst) < 0) ||
+                   (radius_vpt_get_vp(&rhs_vp, request, map->src) < 0)) return false;
 
                return paircmp_op(lhs_vp, map->op, rhs_vp);
        }
@@ -527,8 +525,7 @@ int radius_evaluate_map(REQUEST *request, UNUSED int modreturn, UNUSED int depth
                if (map->dst->type == VPT_TYPE_ATTR) {
                        VALUE_PAIR *cast_vp;
 
-                       cast_vp = radius_vpt_get_vp(request, map->dst);
-                       if (!cast_vp) return false;
+                       if (radius_vpt_get_vp(&cast_vp, request, map->dst) < 0) return false;
 
                        lhs_vp = pairalloc(request, c->cast);
                        if (!lhs_vp) return false;
@@ -551,7 +548,7 @@ int radius_evaluate_map(REQUEST *request, UNUSED int modreturn, UNUSED int depth
                 *      VP, and return that.
                 */
                if (map->src->type == VPT_TYPE_ATTR) {
-                       rhs_vp = radius_vpt_get_vp(request, map->src);
+                       radius_vpt_get_vp(&rhs_vp, request, map->src);
                } else {
                        rhs_vp = get_cast_vp(request, map->src, c->cast);
                }
@@ -609,8 +606,7 @@ int radius_evaluate_map(REQUEST *request, UNUSED int modreturn, UNUSED int depth
 
                EVAL_DEBUG("ATTR to DATA");
 
-               lhs_vp = radius_vpt_get_vp(request, map->dst);
-               if (!lhs_vp) return false;
+               if (radius_vpt_get_vp(&lhs_vp, request, map->dst) < 0) return false;
 
                rhs_vp = get_cast_vp(request, map->src, map->dst->vpt_da);
                if (!rhs_vp) return false;
@@ -665,8 +661,7 @@ int radius_evaluate_map(REQUEST *request, UNUSED int modreturn, UNUSED int depth
                /*
                 *      No LHS means no match
                 */
-               lhs_vp = radius_vpt_get_vp(request, map->dst);
-               if (!lhs_vp) {
+               if (radius_vpt_get_vp(&lhs_vp, request, map->dst) < 0) {
                        /*
                         *      Not a real attr: might be a dynamic comparison.
                         */
index bd87a59..e143b70 100644 (file)
@@ -639,8 +639,7 @@ redo:
                        goto calculate_result;
                }
 
-               vp = radius_vpt_get_vp(request, g->vpt);
-               if (!vp) {      /* nothing to loop over */
+               if (radius_vpt_get_vp(&vp, request, g->vpt) < 0) {      /* nothing to loop over */
                        MOD_LOG_OPEN_BRACE("foreach");
                        result = RLM_MODULE_NOOP;
                        MOD_LOG_CLOSE_BRACE();
@@ -816,8 +815,7 @@ redo:
                 *      The attribute doesn't exist.  We can skip
                 *      directly to the default 'case' statement.
                 */
-               if ((g->vpt->type == VPT_TYPE_ATTR) &&
-                   !radius_vpt_get_vp(request, g->vpt)) {
+               if ((g->vpt->type == VPT_TYPE_ATTR) && (radius_vpt_get_vp(NULL, request, g->vpt) < 0)) {
                        for (this = g->children; this; this = this->next) {
                                rad_assert(this->type == MOD_CASE);
 
index e88b32d..46edf12 100644 (file)
@@ -1555,8 +1555,7 @@ int radius_map2vp(VALUE_PAIR **out, REQUEST *request, value_pair_map_t const *ma
                        return 0;
                }
 
-               found = radius_vpt_get_vp(request, map->src);
-               if (!found) {
+               if (radius_vpt_get_vp(&found, request, map->src) < 0) {
                        REDEBUG("Attribute \"%s\" not found in request", map->src->name);
                        rcode = 0;
                        goto error;
@@ -1643,80 +1642,91 @@ int radius_strpair2map(value_pair_map_t **out, REQUEST *request, char const *raw
        return 0;
 }
 
-
 /** Return a VP from a value_pair_tmpl_t
  *
+ * @param out where to write the retrieved vp.
  * @param request current request.
  * @param vpt the value pair template
- * @return NULL if not found, or the VPs.
+ * @return -1 if VP could not be found, -2 if list could not be found, -3 if context could not be found.
  */
-VALUE_PAIR *radius_vpt_get_vp(REQUEST *request, value_pair_tmpl_t const *vpt)
+int radius_vpt_get_vp(VALUE_PAIR **out, REQUEST *request, value_pair_tmpl_t const *vpt)
 {
        VALUE_PAIR **vps, *vp;
 
+       if (out) *out = NULL;
+
        if (radius_request(&request, vpt->vpt_request) < 0) {
-               return NULL;
+               return -3;
        }
 
        vps = radius_list(request, vpt->vpt_list);
        if (!vps) {
-               return NULL;
+               return -2;
        }
 
        switch (vpt->type) {
-       /*
-        *      May not may not be found, but it *is* a known
-        *      name.
-        */
+               /*
+                *      May not may not be found, but it *is* a known
+                *      name.
+                */
        case VPT_TYPE_ATTR:
        {
                int num;
                vp_cursor_t cursor;
 
                if (vpt->vpt_num == NUM_ANY) {
-                       return pairfind(*vps, vpt->vpt_da->attr, vpt->vpt_da->vendor, vpt->vpt_tag);
+                       vp = pairfind(*vps, vpt->vpt_da->attr, vpt->vpt_da->vendor, vpt->vpt_tag);
+                       if (!vp) return -1;
+                       break;
                }
 
                (void) fr_cursor_init(&cursor, vps);
                num = vpt->vpt_num;
-               while ((vp = fr_cursor_next_by_da(&cursor, vpt->vpt_da, vpt->vpt_tag))) {
+               while((vp = fr_cursor_next_by_da(&cursor, vpt->vpt_da, vpt->vpt_tag))) {
                        VERIFY_VP(vp);
-                       if (num-- == 0) return vp;
+                       if (num-- == 0) goto finish;
                }
-               return NULL;
+               return -1;
        }
 
        case VPT_TYPE_LIST:
-               return *vps;
+               vp = *vps;
+               break;
 
        default:
-               break;
+               /*
+                *      literal, xlat, regex, exec, data.
+                *      no attribute.
+                */
+               return -1;
        }
 
-       return NULL;
+finish:
+       if (out) *out = vp;
+
+       return 0;
 }
 
 /** Return a VP from the specified request.
  *
- * @param vp_p where to write the pointer to the resolved VP.
+ * @param out where to write the pointer to the resolved VP.
  *     Will be NULL if the attribute couldn't be resolved.
  * @param request current request.
  * @param name attribute name including qualifiers.
- * @return -1 if either the attribute or qualifier were invalid, else 0
+ * @return -4 if either the attribute or qualifier were invalid, and the same error codes as radius_vpt_get_vp for other
+ *     error conditions.
  */
-int radius_get_vp(VALUE_PAIR **vp_p, REQUEST *request, char const *name)
+int radius_get_vp(VALUE_PAIR **out, REQUEST *request, char const *name)
 {
        value_pair_tmpl_t vpt;
 
-       *vp_p = NULL;
+       *out = NULL;
 
        if (radius_parse_attr(&vpt, name, REQUEST_CURRENT, PAIR_LIST_REQUEST) < 0) {
-               RDEBUG("%s", fr_strerror());
-               return -1;
+               return -4;
        }
 
-       *vp_p = radius_vpt_get_vp(request, &vpt);
-       return 0;
+       return radius_vpt_get_vp(out, request, &vpt);
 }
 
 /** Copy pairs matching a VPT in the current request
@@ -1773,6 +1783,28 @@ int radius_vpt_copy_vp(VALUE_PAIR **out, REQUEST *request, value_pair_tmpl_t con
        return 0;
 }
 
+/** Copy a VP from the specified request.
+ *
+ * @param out where to write the pointer to the copied VP.
+ *     Will be NULL if the attribute couldn't be resolved.
+ * @param request current request.
+ * @param name attribute name including qualifiers.
+ * @return -4 if either the attribute or qualifier were invalid, and the same error codes as radius_vpt_get_vp for other
+ *     error conditions.
+ */
+int radius_copy_vp(VALUE_PAIR **out, REQUEST *request, char const *name)
+{
+       value_pair_tmpl_t vpt;
+
+       *out = NULL;
+
+       if (radius_parse_attr(&vpt, name, REQUEST_CURRENT, PAIR_LIST_REQUEST) < 0) {
+               return -4;
+       }
+
+       return radius_vpt_copy_vp(out, request, &vpt);
+}
+
 void module_failure_msg(REQUEST *request, char const *fmt, ...)
 {
        va_list ap;