Add tag correction pass so update sections insert tagged attributes again
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 23 May 2014 16:18:31 +0000 (17:18 +0100)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 23 May 2014 16:19:15 +0000 (17:19 +0100)
src/main/valuepair.c
src/tests/keywords/xlat-attr-tag [new file with mode: 0644]

index 39d712b..efd99f6 100644 (file)
@@ -1060,11 +1060,10 @@ int radius_map2request(REQUEST *request, value_pair_map_t const *map,
 
        /*
         *      The destination is an attribute
-        *
-        *      It's a remove operation, or a filter, or an add or a set.
         */
        switch (map->op) {
-
+       default:
+               break;
        /*
         *      !* - Remove all attributes which match dst in the specified list.
         *      This doesn't use attributes returned by the func(), and immediately frees them.
@@ -1092,48 +1091,7 @@ int radius_map2request(REQUEST *request, value_pair_map_t const *map,
                 *      Check that the User-Name and User-Password
                 *      caches point to the correct attribute.
                 */
-               break;
-       /*
-        *      = - Set only if not already set
-        */
-       case T_OP_EQ:
-               if (dst) {
-                       RDEBUG3("Refusing to overwrite (use :=)");
-                       pairfree(&head);
-                       return 0;
-               }
-
-               /* Insert first instance (if multiple) */
-               fr_cursor_first(&src_list);
-               fr_cursor_insert(&dst_list, fr_cursor_remove(&src_list));
-               /* Free any we didn't insert */
-               pairfree(&head);
-               break;
-
-       /*
-        *      := - Overwrite existing attribute with last src_list attribute
-        */
-       case T_OP_SET:
-               /* Wind to last instance */
-               fr_cursor_last(&src_list);
-               if (dst) {
-                       dst = fr_cursor_remove(&dst_list);
-                       DEBUG_OVERWRITE(dst, fr_cursor_current(&src_list));
-                       pairfree(&dst);
-               }
-               fr_cursor_insert(&dst_list, fr_cursor_remove(&src_list));
-               /* Free any we didn't insert */
-               pairfree(&head);
-               break;
-
-       /*
-        *      += - Add all src_list attributes to the destination
-        */
-       case T_OP_ADD:
-               /* Insert all the instances! (if multiple) */
-               pairadd(list, head);
-               head = NULL;
-               break;
+               goto finish;
 
        /*
         *      -= - Delete attributes in the dst list which match any of the
@@ -1146,7 +1104,6 @@ int radius_map2request(REQUEST *request, value_pair_map_t const *map,
         *        against each of the src_list attributes.
         */
        case T_OP_SUB:
-       {
                /* We didn't find any attributes earlier */
                if (!dst) {
                        pairfree(&head);
@@ -1189,9 +1146,62 @@ int radius_map2request(REQUEST *request, value_pair_map_t const *map,
                }
                pairfree(&head);
                if (!found) return 0;
-               break;
+               goto finish;
        }
 
+       /*
+        *      Another fixup pass to set tags on attributes were about to insert
+        */
+       if (map->dst->vpt_tag != TAG_ANY) {
+               for (vp = fr_cursor_init(&src_list, &head);
+                    vp;
+                    vp = fr_cursor_next(&src_list)) {
+                       vp->tag = map->dst->vpt_tag;
+               }
+       }
+
+       switch (map->op) {
+       /*
+        *      = - Set only if not already set
+        */
+       case T_OP_EQ:
+               if (dst) {
+                       RDEBUG3("Refusing to overwrite (use :=)");
+                       pairfree(&head);
+                       return 0;
+               }
+
+               /* Insert first instance (if multiple) */
+               fr_cursor_first(&src_list);
+               fr_cursor_insert(&dst_list, fr_cursor_remove(&src_list));
+               /* Free any we didn't insert */
+               pairfree(&head);
+               break;
+
+       /*
+        *      := - Overwrite existing attribute with last src_list attribute
+        */
+       case T_OP_SET:
+               /* Wind to last instance */
+               fr_cursor_last(&src_list);
+               if (dst) {
+                       dst = fr_cursor_remove(&dst_list);
+                       DEBUG_OVERWRITE(dst, fr_cursor_current(&src_list));
+                       pairfree(&dst);
+               }
+               fr_cursor_insert(&dst_list, fr_cursor_remove(&src_list));
+               /* Free any we didn't insert */
+               pairfree(&head);
+               break;
+
+       /*
+        *      += - Add all src_list attributes to the destination
+        */
+       case T_OP_ADD:
+               /* Insert all the instances! (if multiple) */
+               pairadd(list, head);
+               head = NULL;
+               break;
 
        /*
         *      Filtering operators
diff --git a/src/tests/keywords/xlat-attr-tag b/src/tests/keywords/xlat-attr-tag
new file mode 100644 (file)
index 0000000..faebfc8
--- /dev/null
@@ -0,0 +1,41 @@
+#
+# PRE: update
+#
+#  Remove all attributes in a list
+#
+update {
+       control:Cleartext-Password := 'hello'
+       reply:Filter-Id := 'filter'
+}
+
+update request {
+       Tunnel-Server-Endpoint:0 := 192.0.1.1   # Should not be tagged
+       Tunnel-Server-Endpoint:0 += 192.0.1.1   # Should not be tagged
+       Tunnel-Server-Endpoint:1 := 192.0.2.1
+       Tunnel-Server-Endpoint:1 += 192.0.2.1
+       Tunnel-Server-Endpoint:2 := 192.0.3.2
+       Tunnel-Server-Endpoint:2 += 192.0.3.2
+}
+
+update request {
+       Tmp-Integer-0 := "%{debug_attr:request:}"
+}
+
+# Check that access attributes by tag works first
+if ("%{Tunnel-Server-Endpoint:2}" != 192.0.3.2) {
+       update {
+               reply:Filter-Id += 'fail 1'
+       }
+}
+
+if ("%{Tunnel-Server-Endpoint:2}" == 192.0.3.1) {
+       update {
+               reply:Filter-Id += 'fail 2'
+       }
+}
+
+if ("%{Tunnel-Server-Endpoint:1}" != 192.0.2.1) {
+       update {
+               reply:Filter-Id += 'fail 3'
+       }
+}