]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Allow dictionaries to depend on each other
authorAlan T. DeKok <aland@freeradius.org>
Fri, 25 Nov 2022 18:29:14 +0000 (13:29 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Fri, 25 Nov 2022 19:59:43 +0000 (14:59 -0500)
and add API to see if the dictionaries are compatible.
Because we can no longer depend on comparing pointers

src/lib/server/tmpl_tokenize.c
src/lib/unlang/compile.c
src/lib/util/dict.h
src/lib/util/dict_priv.h
src/lib/util/dict_util.c

index 8a3ad9626726262f660ae6c6aa327f04677925f3..e93ca00cde67e7198385aca6cfc14a323f7ea337 100644 (file)
@@ -1824,7 +1824,7 @@ check_attr:
                 *      |_ RADIUS attribute
                 */
                if (found_in != fr_dict_internal() &&
-                   !at_rules->allow_foreign && (found_in != fr_dict_by_da(our_parent))) {
+                   !at_rules->allow_foreign && !fr_dict_compatible(found_in, fr_dict_by_da(our_parent))) {
                        fr_strerror_printf("Foreign %s attribute found.  Only %s attributes are allowed here",
                                           fr_dict_root(found_in)->name,
                                           fr_dict_root(dict_def)->name);
index 9e67346f8e8834cb7b71338fde7092f9b94ce17c..fc6f9e5081335211d996da9cdea85b93e8d4438e 100644 (file)
@@ -4731,8 +4731,8 @@ static unlang_t *compile_module(unlang_t *parent, unlang_compile_t *unlang_ctx,
         */
        if (mrlm->dict && *mrlm->dict && unlang_ctx->rules && unlang_ctx->rules->attr.dict_def &&
            (unlang_ctx->rules->attr.dict_def != fr_dict_internal()) &&
-           (*(mrlm->dict) != unlang_ctx->rules->attr.dict_def)) {
-               cf_log_err(ci, "The \"%s\" module can only used with 'namespace = %s'.  It cannot be used with 'namespace = %s'.",
+           !fr_dict_compatible(*(mrlm->dict), unlang_ctx->rules->attr.dict_def)) {
+               cf_log_err(ci, "The \"%s\" module can only be used with 'namespace = %s'.  It cannot be used with 'namespace = %s'.",
                           inst->module->name,
                           fr_dict_root(*mrlm->dict)->name,
                           fr_dict_root(unlang_ctx->rules->attr.dict_def)->name);
index d30255498926a7c05505392f58d3d80d46d00586..122e6f52875beec0b271f74628a2936224b86dcc 100644 (file)
@@ -500,6 +500,8 @@ fr_dict_t const             *fr_dict_by_da(fr_dict_attr_t const *da) CC_HINT(nonnull);
 
 fr_dict_t const                *fr_dict_by_attr_name(fr_dict_attr_t const **found, char const *name);
 
+bool                   fr_dict_compatible(fr_dict_t const *dict1, fr_dict_t const *dict2) CC_HINT(nonnull);
+
 /** Return true if this attribute is parented directly off the dictionary root
  *
  * @param[in] da               to check.
index edb543ea78b4f86178c1adfbb33aeffb1fd2579f..2af25cb9c9a64d5f271189c8992f4da25a212a2a 100644 (file)
@@ -91,6 +91,8 @@ struct fr_dict {
 
        fr_hash_table_t         *autoref;               //!< other dictionaries that we loaded via references
 
+       fr_dict_t const         *next;                  //!< for attribute overloading
+
        fr_table_num_ordered_t const *subtype_table;    //!< table of subtypes for this protocol
        size_t                  subtype_table_len;      //!< length of table of subtypes for this protocol
 
index f72f9397d0719875069226a6bd2e1d362817538b..5117acb4a95997e5b1e5bee2c48e54a5fe907add 100644 (file)
@@ -2182,6 +2182,23 @@ fr_dict_t const *fr_dict_by_da(fr_dict_attr_t const *da)
        return dict_by_da(da);
 }
 
+/** See if two dictionaries have the same end parent
+ *
+ * @param[in] dict1 one dictionary
+ * @param[in] dict2 two dictionary
+ * @return
+ *     - true the dictionaries have the same end parent
+ *     - false the dictionaries do not have the same end parent.
+ */
+bool fr_dict_compatible(fr_dict_t const *dict1, fr_dict_t const *dict2)
+{
+       while (dict1->next) dict1 = dict1->next;
+
+       while (dict2->next) dict2 = dict2->next;
+
+       return (dict1 == dict2);
+}
+
 /** Look up a vendor by one of its child attributes
  *
  * @param[in] da       The vendor attribute.