]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
define, parse, and print tag ":V"
authorAlan T. DeKok <aland@freeradius.org>
Mon, 24 Feb 2025 19:57:24 +0000 (14:57 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 24 Feb 2025 20:45:37 +0000 (15:45 -0500)
which is intended to cause tags to be parsed from values

and hoist the "set tag" code to before the calls to
fr_pair_value_from_str(), so that it can parse the tag

src/include/libradius.h
src/main/tmpl.c
src/main/xlat.c
src/modules/rlm_rest/rest.c

index d3a47815847652873076bc7e25f1e0e0fcc2371d..56108ade3f2b749e9abdea2bdcd8e8ca8603553f 100644 (file)
@@ -150,8 +150,9 @@ typedef void (*sig_t)(int);
                                } while(0)
 
 #define TAG_VALID(x)           ((x) > 0 && (x) < 0x20)
-#define TAG_VALID_ZERO(x)      ((x) < 0x20)
+#define TAG_VALID_ZERO(x)      ((x) >= 0 && (x) < 0x20)
 #define TAG_ANY                        INT8_MIN
+#define TAG_VALUE              (INT8_MIN + 1)
 #define TAG_NONE               0
 /** Check if tags are equal
  *
index 6746bdec8d9f8f61bb0cc5b0e271994c150e6169..c64591a7525d188c093b0da7f40da2aa3f740ab1 100644 (file)
@@ -703,7 +703,6 @@ ssize_t tmpl_from_attr_substr(vp_tmpl_t *vpt, char const *name,
        da = dict_attrbyvalue(attr.da->attr, attr.da->vendor);
        if (da && (attr.da != da)) attr.da = da;
 
-
        /*
         *      The string MIGHT have a tag.
         */
@@ -713,6 +712,15 @@ ssize_t tmpl_from_attr_substr(vp_tmpl_t *vpt, char const *name,
                        return -(p - name);
                }
 
+               /*
+                *      Get the tag from the value.
+                */
+               if (*p == 'V') {
+                       attr.tag = TAG_VALUE;
+                       p++;
+                       goto do_num;
+               }
+
                num = strtol(p + 1, &q, 10);
                if ((num > 0x1f) || (num < 0)) {
                        fr_strerror_printf("Invalid tag value '%li' (should be between 0-31)", num);
@@ -1222,6 +1230,13 @@ int tmpl_cast_to_vp(VALUE_PAIR **out, REQUEST *request,
        }
        data.strvalue = p;
 
+       /*
+        *      Copy over any additional fields needed...
+        */
+       if ((vpt->type == TMPL_TYPE_ATTR) && vp->da->flags.has_tag) {
+               vp->tag = vpt->tmpl_tag;
+       }
+
        /*
         *      New escapes: strings are in binary form.
         */
@@ -1235,13 +1250,6 @@ int tmpl_cast_to_vp(VALUE_PAIR **out, REQUEST *request,
                return -1;
        }
 
-       /*
-        *      Copy over any additional fields needed...
-        */
-       if ((vpt->type == TMPL_TYPE_ATTR) && vp->da->flags.has_tag) {
-               vp->tag = vpt->tmpl_tag;
-       }
-
        *out = vp;
        return 0;
 }
@@ -1732,7 +1740,15 @@ size_t tmpl_prints(char *out, size_t outlen, vp_tmpl_t const *vpt, DICT_ATTR con
                q = out + len;
                outlen -= len;
 
-               if (vpt->tmpl_tag != TAG_ANY) {
+               if (vpt->tmpl_tag == TAG_ANY) {
+                       /* do nothing */
+
+               } else if (vpt->tmpl_tag == TAG_VALUE) {
+                       *q++ = ':';
+                       *q++ = 'V';
+                       outlen -= 2;
+
+               } else {
                        snprintf(q, outlen, ":%d", vpt->tmpl_tag);
                        len = strlen(q);
                        q += len;
@@ -1878,6 +1894,11 @@ VALUE_PAIR *tmpl_cursor_init(int *err, vp_cursor_t *cursor, REQUEST *request, vp
         *      May not may not be found, but it *is* a known name.
         */
        case TMPL_TYPE_ATTR:
+               if (vpt->tmpl_tag == TAG_ANY) {
+                       if (err) *err = -1;
+                       return NULL;
+               }
+
                switch (vpt->tmpl_num) {
                case NUM_ANY:
                        vp = fr_cursor_next_by_da(cursor, vpt->tmpl_da, vpt->tmpl_tag);
index d191f351aac06261fbbfdc16a75cef0570f14c65..7d3e3b92a2ad211fdcc5f452d5e2acd5fe09af1b 100644 (file)
@@ -1631,7 +1631,9 @@ static void xlat_tokenize_debug(xlat_exp_t const *node, int lvl)
                                DEBUG("%.*sref  %d", lvl + 1, xlat_tabs, node->attr.tmpl_request);
                                DEBUG("%.*slist %d", lvl + 1, xlat_tabs, node->attr.tmpl_list);
 
-                               if (node->attr.tmpl_tag != TAG_ANY) {
+                               if (node->attr.tmpl_tag == TAG_VALUE) {
+                                       DEBUG("%.*stag V", lvl + 1, xlat_tabs);
+                               } else if (node->attr.tmpl_tag != TAG_ANY) {
                                        DEBUG("%.*stag %d", lvl + 1, xlat_tabs, node->attr.tmpl_tag);
                                }
                                if (node->attr.tmpl_num != NUM_ANY) {
index d18c0084575951f3d27b8aa287c17cedc83527bf..34a2952129afbace2b01a4bac62666fa117d663f 100644 (file)
@@ -1294,6 +1294,9 @@ static VALUE_PAIR *json_pair_make_leaf(UNUSED rlm_rest_t *instance, UNUSED rlm_r
                return NULL;
        }
 
+       vp->op = flags->op;
+       vp->tag = flags->tag;
+
        ret = fr_pair_value_from_str(vp, to_parse, -1);
        talloc_free(expanded);
        if (ret < 0) {
@@ -1303,9 +1306,6 @@ static VALUE_PAIR *json_pair_make_leaf(UNUSED rlm_rest_t *instance, UNUSED rlm_r
                return NULL;
        }
 
-       vp->op = flags->op;
-       vp->tag = flags->tag;
-
        return vp;
 }