]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
copy protocol extensions for unknown / raw attributes
authorAlan T. DeKok <aland@freeradius.org>
Sun, 23 Feb 2025 20:29:31 +0000 (15:29 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Sun, 23 Feb 2025 20:30:38 +0000 (15:30 -0500)
which lets the der encoder create "raw" fields with the
correct DER tag.

src/lib/util/dict_ext_priv.h
src/lib/util/dict_unknown.c

index b02027d932ebfc505246f893afe5998ef3cd4cea..254fb4c5cadacd24d1be9cb97a86c7ae9628f39e 100644 (file)
@@ -76,11 +76,22 @@ static inline size_t dict_attr_ext_len(fr_dict_attr_t const *da, fr_dict_attr_ex
  */
 static inline void *dict_attr_ext_copy(fr_dict_attr_t **da_out_p, fr_dict_attr_t const *da_in, fr_dict_attr_ext_t ext)
 {
-       if (unlikely((*da_out_p)->dict && fr_dict_is_read_only((*da_out_p)->dict))) {
+       if (unlikely((*da_out_p)->dict && fr_dict_is_read_only((*da_out_p)->dict) && !(*da_out_p)->flags.is_unknown)) {
                fr_strerror_printf("%s dictionary has been marked as read only", fr_dict_root((*da_out_p)->dict)->name);
                return NULL;
        }
 
+       /*
+        *      We might be able to copy things for unknown
+        *      attributes.  But if the unknown is of type 'octets',
+        *      then we can only copy the protocol-specific things.
+        */
+#ifndef NDEBUG
+       if ((*da_out_p)->flags.is_unknown && ((*da_out_p)->type == FR_TYPE_OCTETS)) {
+               fr_assert(ext == FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC);
+       }
+#endif
+
        return fr_ext_copy(&fr_dict_attr_ext_def, (void **)da_out_p, (void const *)da_in, ext);
 }
 
index b4033caa25c18109481e5ad502bfa64a759ff52d..8d5e7a5616ce315d34d53b6692fb798a00ac8d13 100644 (file)
@@ -216,7 +216,13 @@ static fr_dict_attr_t *dict_unknown_alloc(TALLOC_CTX *ctx, fr_dict_attr_t const
        if (dict_attr_init(&n, parent, da->name, da->attr, type, &(dict_attr_args_t){ .flags = &flags }) < 0) {
                goto error;
        }
-       if (type != FR_TYPE_OCTETS) dict_attr_ext_copy_all(&n, da);
+       if (type != FR_TYPE_OCTETS) {
+               dict_attr_ext_copy_all(&n, da);
+
+       } else if (fr_dict_attr_ext(da, FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC) &&
+                  !dict_attr_ext_copy(&n, da, FR_DICT_ATTR_EXT_PROTOCOL_SPECIFIC)) {
+               goto error;
+       }
        DA_VERIFY(n);
 
        return n;