From: Arran Cudbard-Bell Date: Tue, 5 Nov 2019 20:17:25 +0000 (-0600) Subject: Add new top level dict_gctx, fix a bunch of const issues, make dictionaries read... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c7eb8027c9868746d1b118d883dd0c0d6f5a971b;p=thirdparty%2Ffreeradius-server.git Add new top level dict_gctx, fix a bunch of const issues, make dictionaries read only at runtime --- diff --git a/src/bin/radiusd.c b/src/bin/radiusd.c index 4969d97ecd8..525951125ad 100644 --- a/src/bin/radiusd.c +++ b/src/bin/radiusd.c @@ -874,6 +874,12 @@ int main(int argc, char *argv[]) */ if (sync_time) fr_time_sync_event(main_loop_event_list(), fr_time(), NULL); + /* + * Prevent anything from modifying the dictionaries + * they're now immutable. + */ + fr_dict_global_read_only(); + /* * Process requests until HUP or exit. */ diff --git a/src/bin/unit_test_attribute.c b/src/bin/unit_test_attribute.c index 903d5e488b5..338a04b6a6f 100644 --- a/src/bin/unit_test_attribute.c +++ b/src/bin/unit_test_attribute.c @@ -788,7 +788,7 @@ static ssize_t load_test_point_by_command(void **symbol, char *command, char con /** Common dictionary load function * - * Callers call fr_dict_dir_set to set the dictionary root to + * Callers call fr_dict_global_dir_set to set the dictionary root to * load dictionaries from, then provide a relative path to * navigate through test subdirectories or protocols */ @@ -1586,7 +1586,7 @@ static size_t command_proto(command_result_t *result, UNUSED command_ctx_t *cc, RETURN_PARSE_ERROR(0); } - fr_dict_dir_set(dict_dir); + fr_dict_global_dir_set(dict_dir); slen = load_proto_library(in); if (slen <= 0) RETURN_PARSE_ERROR(-(slen)); @@ -1596,7 +1596,7 @@ static size_t command_proto(command_result_t *result, UNUSED command_ctx_t *cc, static size_t command_proto_dictionary(command_result_t *result, command_ctx_t *cc, UNUSED char *data, UNUSED size_t data_used, char *in, UNUSED size_t inlen) { - fr_dict_dir_set(dict_dir); + fr_dict_global_dir_set(dict_dir); return dictionary_load_common(result, cc, in, NULL); } @@ -1616,7 +1616,7 @@ static size_t command_touch(command_result_t *result, UNUSED command_ctx_t *cc, static size_t command_test_dictionary(command_result_t *result, command_ctx_t *cc, UNUSED char *data, UNUSED size_t data_used, char *in, UNUSED size_t inlen) { - fr_dict_dir_set(cc->path); + fr_dict_global_dir_set(cc->path); return dictionary_load_common(result, cc, in, "."); } diff --git a/src/lib/server/cf_file.c b/src/lib/server/cf_file.c index 6fc859f6500..899382e3613 100644 --- a/src/lib/server/cf_file.c +++ b/src/lib/server/cf_file.c @@ -1049,7 +1049,7 @@ static CONF_SECTION *process_if(CONF_SECTION *parent, char const **ptr_p, char * cd = cf_data_find_in_parent(parent, fr_dict_t **, "dictionary"); if (!cd) { - dict = fr_dict_internal; /* HACK - To fix policy sections */ + dict = fr_dict_internal(); /* HACK - To fix policy sections */ } else { dict = *((fr_dict_t **)cf_data_value(cd)); } diff --git a/src/lib/server/cond_tokenize.c b/src/lib/server/cond_tokenize.c index b0ea64d2b61..4ca7ae2ea3e 100644 --- a/src/lib/server/cond_tokenize.c +++ b/src/lib/server/cond_tokenize.c @@ -448,14 +448,14 @@ static ssize_t cond_check_attrs(fr_cond_t *c, char const *start, case FR_TYPE_IPV4_ADDR: if (strchr(c->data.map->rhs->name, '/') != NULL) { type = FR_TYPE_IPV4_PREFIX; - c->cast = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal), FR_CAST_BASE + type); + c->cast = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal()), FR_CAST_BASE + type); } break; case FR_TYPE_IPV6_ADDR: if (strchr(c->data.map->rhs->name, '/') != NULL) { type = FR_TYPE_IPV6_PREFIX; - c->cast = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal), FR_CAST_BASE + type); + c->cast = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal()), FR_CAST_BASE + type); } break; @@ -516,12 +516,12 @@ static ssize_t cond_check_attrs(fr_cond_t *c, char const *start, tmpl_is_xlat_struct(c->data.map->rhs) || tmpl_is_exec(c->data.map->rhs))) { if (c->data.map->lhs->tmpl_da->type == FR_TYPE_IPV4_ADDR) { - c->cast = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal), + c->cast = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal()), FR_CAST_BASE + FR_TYPE_IPV4_PREFIX); } if (c->data.map->lhs->tmpl_da->type == FR_TYPE_IPV6_ADDR) { - c->cast = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal), + c->cast = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal()), FR_CAST_BASE + FR_TYPE_IPV6_PREFIX); } } @@ -760,7 +760,7 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, CONF_SECTION *cs, return_P("Empty octet string is invalid"); } - c->cast = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal), + c->cast = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal()), FR_CAST_BASE + FR_TYPE_OCTETS); } @@ -967,7 +967,7 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, CONF_SECTION *cs, (map->lhs->tmpl_da->type == FR_TYPE_UINT16) || (map->lhs->tmpl_da->type == FR_TYPE_UINT32) || (map->lhs->tmpl_da->type == FR_TYPE_UINT64))) { - c->cast = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal), + c->cast = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal()), FR_CAST_BASE + FR_TYPE_OCTETS); } } diff --git a/src/lib/server/exec.c b/src/lib/server/exec.c index cdf60f970af..e028a8eb419 100644 --- a/src/lib/server/exec.c +++ b/src/lib/server/exec.c @@ -227,7 +227,7 @@ pid_t radius_start_program(char const *cmd, REQUEST *request, bool exec_wait, } if (request) { - da = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal), FR_EXEC_EXPORT); + da = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal()), FR_EXEC_EXPORT); if (da) { for (vp = fr_cursor_iter_by_da_init(&cursor, &request->control, da); vp && (envlen < ((NUM_ELEMENTS(envp)) - 1)); diff --git a/src/lib/server/exfile.c b/src/lib/server/exfile.c index 4e0c1bc2565..7819b2d1551 100644 --- a/src/lib/server/exfile.c +++ b/src/lib/server/exfile.c @@ -76,7 +76,7 @@ static inline void exfile_trigger_exec(exfile_t *ef, REQUEST *request, exfile_en if (!ef->trigger_prefix) return; - da = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal), FR_EXFILE_NAME); + da = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal()), FR_EXFILE_NAME); if (!da) { ROPTIONAL(RERROR, ERROR, "Incomplete internal dictionary: Missing definition for \"Exfile-Name\""); return; diff --git a/src/lib/server/paircmp.c b/src/lib/server/paircmp.c index 5457edec8d0..c59966fa55b 100644 --- a/src/lib/server/paircmp.c +++ b/src/lib/server/paircmp.c @@ -754,7 +754,7 @@ int paircmp_register_by_name(char const *name, fr_dict_attr_t const *from, memset(&flags, 0, sizeof(flags)); - da = fr_dict_attr_by_name(fr_dict_internal, name); + da = fr_dict_attr_by_name(fr_dict_internal(), name); if (da) { if (paircmp_find(da)) { fr_strerror_printf_push("Cannot register two comparions for attribute %s", @@ -762,13 +762,13 @@ int paircmp_register_by_name(char const *name, fr_dict_attr_t const *from, return -1; } } else if (from) { - if (fr_dict_attr_add(fr_dict_internal, fr_dict_root(fr_dict_internal), + if (fr_dict_attr_add(fr_dict_unconst(fr_dict_internal()), fr_dict_root(fr_dict_internal()), name, -1, from->type, &flags) < 0) { fr_strerror_printf_push("Failed creating attribute '%s'", name); return -1; } - da = fr_dict_attr_by_name(fr_dict_internal, name); + da = fr_dict_attr_by_name(fr_dict_internal(), name); if (!da) { fr_strerror_printf("Failed finding attribute '%s'", name); return -1; diff --git a/src/lib/server/tmpl.c b/src/lib/server/tmpl.c index 50502d53bb3..7f2132ca40f 100644 --- a/src/lib/server/tmpl.c +++ b/src/lib/server/tmpl.c @@ -835,13 +835,13 @@ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, attr_ref_error_t *err, * Attribute location checks */ { - fr_dict_t *found_in = fr_dict_by_da(vpt->tmpl_da); + fr_dict_t const *found_in = fr_dict_by_da(vpt->tmpl_da); /* * Even if allow_foreign is false, if disallow_internal is not * true, we still allow foreign */ - if (found_in == fr_dict_internal) { + if (found_in == fr_dict_internal()) { if (rules->disallow_internal) { fr_strerror_printf("Internal attributes not allowed here"); if (err) *err = ATTR_REF_ERROR_INTERNAL_ATTRIBUTE_NOT_ALLOWED; @@ -1448,7 +1448,7 @@ int tmpl_define_unknown_attr(vp_tmpl_t *vpt) if (!vpt->tmpl_da->flags.is_unknown) return 1; - da = fr_dict_unknown_add(fr_dict_internal, vpt->tmpl_da); + da = fr_dict_unknown_add(fr_dict_unconst(fr_dict_internal()), vpt->tmpl_da); if (!da) return -1; vpt->tmpl_da = da; @@ -1487,7 +1487,7 @@ int tmpl_define_undefined_attr(fr_dict_t *dict_def, vp_tmpl_t *vpt, if (!tmpl_is_attr_undefined(vpt)) return 1; - if (fr_dict_attr_add(dict_def, fr_dict_root(fr_dict_internal), vpt->tmpl_unknown_name, -1, type, flags) < 0) { + if (fr_dict_attr_add(dict_def, fr_dict_root(fr_dict_internal()), vpt->tmpl_unknown_name, -1, type, flags) < 0) { return -1; } da = fr_dict_attr_by_name(dict_def, vpt->tmpl_unknown_name); @@ -2964,7 +2964,7 @@ ssize_t tmpl_preparse(char const **out, size_t *outlen, char const *start, return_P("Forbidden data type in cast"); } - *castda = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal), FR_CAST_BASE + cast); + *castda = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal()), FR_CAST_BASE + cast); if (!*castda) { return_P("Cannot cast to this data type"); } diff --git a/src/lib/server/trigger.c b/src/lib/server/trigger.c index 5b62b31472b..343640c23b7 100644 --- a/src/lib/server/trigger.c +++ b/src/lib/server/trigger.c @@ -361,13 +361,13 @@ VALUE_PAIR *trigger_args_afrom_server(TALLOC_CTX *ctx, char const *server, uint1 VALUE_PAIR *out = NULL, *vp; fr_cursor_t cursor; - server_da = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal), FR_CONNECTION_POOL_SERVER); + server_da = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal()), FR_CONNECTION_POOL_SERVER); if (!server_da) { ERROR("Incomplete dictionary: Missing definition for \"Connection-Pool-Server\""); return NULL; } - port_da = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal), FR_CONNECTION_POOL_PORT); + port_da = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal()), FR_CONNECTION_POOL_PORT); if (!port_da) { ERROR("Incomplete dictionary: Missing definition for \"Connection-Pool-Port\""); return NULL; diff --git a/src/lib/server/virtual_servers.c b/src/lib/server/virtual_servers.c index 31e2d488e47..7a7b5a726c8 100644 --- a/src/lib/server/virtual_servers.c +++ b/src/lib/server/virtual_servers.c @@ -398,7 +398,7 @@ int virtual_server_section_attribute_define(CONF_SECTION *server_cs, char const * this code, so it doesn't matter. The only * requirement is that it's unique. */ - if (fr_dict_enum_add_name_next(da, name2) < 0) { + if (fr_dict_enum_add_name_next(fr_dict_attr_unconst(da), name2) < 0) { PERROR("Failed adding section value"); return -1; } @@ -1066,7 +1066,7 @@ rlm_rcode_t process_authenticate(int auth_type, REQUEST *request) return RLM_MODULE_REJECT; } - da = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal), FR_AUTH_TYPE); + da = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal()), FR_AUTH_TYPE); if (!da) return RLM_MODULE_FAIL; dv = fr_dict_enum_by_value(da, fr_box_uint32((uint32_t) auth_type)); diff --git a/src/lib/unlang/compile.c b/src/lib/unlang/compile.c index de749bf551d..39cecccedaa 100644 --- a/src/lib/unlang/compile.c +++ b/src/lib/unlang/compile.c @@ -502,14 +502,14 @@ static bool pass2_fixup_map(fr_cond_t *c, vp_tmpl_rules_t const *rules) switch (cast->type) { case FR_TYPE_IPV4_ADDR: if (strchr(c->data.map->lhs->name, '/') != NULL) { - c->cast = cast = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal), + c->cast = cast = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal()), FR_CAST_BASE + FR_TYPE_IPV4_PREFIX); } break; case FR_TYPE_IPV6_ADDR: if (strchr(c->data.map->lhs->name, '/') != NULL) { - c->cast = cast = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal), + c->cast = cast = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal()), FR_CAST_BASE + FR_TYPE_IPV6_PREFIX); } break; @@ -529,14 +529,14 @@ static bool pass2_fixup_map(fr_cond_t *c, vp_tmpl_rules_t const *rules) switch (cast->type) { case FR_TYPE_IPV4_ADDR: if (strchr(c->data.map->rhs->name, '/') != NULL) { - c->cast = cast = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal), + c->cast = cast = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal()), FR_CAST_BASE + FR_TYPE_IPV4_PREFIX); } break; case FR_TYPE_IPV6_ADDR: if (strchr(c->data.map->rhs->name, '/') != NULL) { - c->cast = cast = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal), + c->cast = cast = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal()), FR_CAST_BASE + FR_TYPE_IPV6_PREFIX); } break; @@ -3056,7 +3056,7 @@ static unlang_t *compile_call(unlang_t *parent, unlang_compile_t *unlang_ctx, CO * The dictionaries are not compatible, forbid it. */ dict = virtual_server_namespace(server); - if (dict && (dict != fr_dict_internal) && fr_dict_internal && + if (dict && (dict != fr_dict_internal()) && fr_dict_internal() && unlang_ctx->rules->dict_def && (unlang_ctx->rules->dict_def != dict)) { cf_log_err(cs, "Cannot call namespace '%s' from namespaces '%s'", fr_dict_root(dict)->name, fr_dict_root(unlang_ctx->rules->dict_def)->name); @@ -3185,7 +3185,7 @@ static unlang_t *compile_module(unlang_t *parent, unlang_compile_t *unlang_ctx, * Can't use "chap" in "dhcp". */ if (inst->module->dict && *inst->module->dict && unlang_ctx->rules && unlang_ctx->rules->dict_def && - (unlang_ctx->rules->dict_def != fr_dict_internal) && + (unlang_ctx->rules->dict_def != fr_dict_internal()) && (*inst->module->dict != unlang_ctx->rules->dict_def)) { cf_log_err(ci, "The \"%s\" module can only used with 'namespace = %s'. It cannot be used with 'namespace = %s'.", inst->module->name, diff --git a/src/lib/util/dict.h b/src/lib/util/dict.h index bbb775b1e93..a271722cc24 100644 --- a/src/lib/util/dict.h +++ b/src/lib/util/dict.h @@ -106,7 +106,6 @@ enum { #define da_is_length_field(_da) ((_da)->flags.extra && ((_da)->flags.subtype == FLAG_LENGTH_UINT16)) extern const size_t dict_attr_sizes[FR_TYPE_MAX + 1][2]; -extern fr_dict_t *fr_dict_internal; /** Dictionary attribute */ @@ -248,10 +247,10 @@ extern bool const fr_dict_non_data_types[FR_TYPE_MAX + 1]; int fr_dict_attr_add(fr_dict_t *dict, fr_dict_attr_t const *parent, char const *name, int attr, fr_type_t type, fr_dict_attr_flags_t const *flags) CC_HINT(nonnull(1,2,3)); -int fr_dict_enum_add_name(fr_dict_attr_t const *da, char const *name, - fr_value_box_t const *value, bool coerce, bool replace); +int fr_dict_enum_add_name(fr_dict_attr_t *da, char const *name, + fr_value_box_t const *value, bool coerce, bool replace); -int fr_dict_enum_add_name_next(fr_dict_attr_t const *da, char const *name) CC_HINT(nonnull); +int fr_dict_enum_add_name_next(fr_dict_attr_t *da, char const *name) CC_HINT(nonnull); int fr_dict_str_to_argv(char *str, char **argv, int max_argc); /** @} */ @@ -296,7 +295,7 @@ int fr_dict_oid_component(unsigned int *out, char const **oid); size_t fr_dict_print_attr_oid(size_t *need, char *buffer, size_t outlen, fr_dict_attr_t const *ancestor, fr_dict_attr_t const *da); -ssize_t fr_dict_attr_by_oid(fr_dict_t *dict, fr_dict_attr_t const **parent, +ssize_t fr_dict_attr_by_oid(fr_dict_t const *dict, fr_dict_attr_t const **parent, unsigned int *attr, char const *oid) CC_HINT(nonnull); /** @} */ @@ -308,13 +307,13 @@ fr_dict_attr_t const *fr_dict_root(fr_dict_t const *dict); ssize_t fr_dict_by_protocol_substr(fr_dict_t const **out, char const *name, fr_dict_t const *dict_def); -fr_dict_t *fr_dict_by_protocol_name(char const *name); +fr_dict_t const *fr_dict_by_protocol_name(char const *name); -fr_dict_t *fr_dict_by_protocol_num(unsigned int num); +fr_dict_t const *fr_dict_by_protocol_num(unsigned int num); -fr_dict_t *fr_dict_by_da(fr_dict_attr_t const *da); +fr_dict_t const *fr_dict_by_da(fr_dict_attr_t const *da); -fr_dict_t *fr_dict_by_attr_name(fr_dict_attr_t const **found, char const *name); +fr_dict_t const *fr_dict_by_attr_name(fr_dict_attr_t const **found, char const *name); /** Return true if this attribute is parented directly off the dictionary root * @@ -422,15 +421,24 @@ void fr_dict_free(fr_dict_t **dict); /** @} */ -/** @name Initialisation +/** @name Global dictionary management * * @{ */ - int fr_dict_global_init(TALLOC_CTX *ctx, char const *dict_dir); +int fr_dict_global_init(TALLOC_CTX *ctx, char const *dict_dir); - int fr_dict_dir_set(char const *dict_dir); +int fr_dict_global_dir_set(char const *dict_dir); + +void fr_dict_global_read_only(void); + +char const *fr_dict_global_dir(void); fr_dict_t *fr_dict_unconst(fr_dict_t const *dict); + +fr_dict_attr_t *fr_dict_attr_unconst(fr_dict_attr_t const *da); + +fr_dict_t const *fr_dict_internal(void); + /** @} */ /** @name Dictionary testing and validation diff --git a/src/lib/util/dict_priv.h b/src/lib/util/dict_priv.h index 1659bff8c5f..c14c92e7b38 100644 --- a/src/lib/util/dict_priv.h +++ b/src/lib/util/dict_priv.h @@ -41,7 +41,7 @@ extern "C" { #define INTERNAL_IF_NULL(_dict, _ret) \ do { \ if (!(_dict)) { \ - _dict = fr_dict_internal; \ + _dict = dict_gctx ? dict_gctx->internal : NULL; \ if (unlikely(!(_dict))) { \ fr_strerror_printf("No dictionaries available for attribute resolution"); \ return (_ret); \ @@ -58,6 +58,8 @@ extern "C" { * There would also be conflicts for DHCP(v6)/RADIUS attributes etc... */ struct fr_dict { + bool read_only; //!< If true, disallow modifications. + bool in_protocol_by_name; //!< Whether the dictionary has been inserted into the ///< protocol_by_name hash. bool in_protocol_by_num; //!< Whether the dictionary has been inserted into the @@ -93,9 +95,30 @@ struct fr_dict { fr_dict_protocol_t const *proto; //!< protocol-specific validation functions }; -extern bool dict_initialised; -extern char *dict_dir_default; -extern TALLOC_CTX *dict_ctx; +typedef struct { + bool read_only; + char *dict_dir_default; //!< The default location for loading dictionaries if one + ///< wasn't provided. + + dl_loader_t *dict_loader; //!< for protocol validation + + fr_hash_table_t *protocol_by_name; //!< Hash containing names of all the + ///< registered protocols. + fr_hash_table_t *protocol_by_num; //!< Hash containing numbers of all the + ///< registered protocols. + + /** Magic internal dictionary + * + * Internal dictionary is checked in addition to the protocol dictionary + * when resolving attribute names. + * + * This is because internal attributes are valid for every + * protocol. + */ + fr_dict_t *internal; +} dict_gctx_t; + +extern dict_gctx_t *dict_gctx; extern fr_table_num_ordered_t const date_precision_table[]; extern size_t date_precision_table_len; @@ -147,6 +170,17 @@ bool dict_attr_fields_valid(fr_dict_t *dict, fr_dict_attr_t const *parent, char const *name, int *attr, fr_type_t type, fr_dict_attr_flags_t *flags); +fr_dict_attr_t *dict_attr_by_name(fr_dict_t const *dict, char const *name); + +fr_dict_attr_t *dict_attr_child_by_num(fr_dict_attr_t const *parent, unsigned int attr); + +fr_dict_t *dict_by_protocol_name(char const *name); + +fr_dict_t *dict_by_protocol_num(unsigned int num); + +fr_dict_t *dict_by_da(fr_dict_attr_t const *da); + +fr_dict_t *dict_by_attr_name(fr_dict_attr_t const **found, char const *name); #ifdef __cplusplus } diff --git a/src/lib/util/dict_tokenize.c b/src/lib/util/dict_tokenize.c index 4481407acdf..6a36b63b204 100644 --- a/src/lib/util/dict_tokenize.c +++ b/src/lib/util/dict_tokenize.c @@ -82,9 +82,9 @@ typedef struct { dict_tokenize_frame_t stack[MAX_STACK]; //!< stack of attributes to track int stack_depth; //!< points to the last used stack frame - fr_dict_attr_t const *value_attr; //!< Cache of last attribute to speed up + fr_dict_attr_t *value_attr; //!< Cache of last attribute to speed up ///< value processing. - fr_dict_attr_t const *relative_attr; //!< for ".82" instead of "1.2.3.82". + fr_dict_attr_t *relative_attr; //!< for ".82" instead of "1.2.3.82". ///< only for parents of type "tlv" TALLOC_CTX *fixup_pool; //!< Temporary pool for fixups, reduces holes @@ -447,7 +447,7 @@ static int dict_process_flag_field(dict_tokenize_ctx_t *ctx, char *name, fr_type } -static int dict_ctx_push(dict_tokenize_ctx_t *ctx, fr_dict_attr_t const *da) +static int dict_gctx_push(dict_tokenize_ctx_t *ctx, fr_dict_attr_t const *da) { if ((ctx->stack_depth + 1) >= MAX_STACK) { fr_strerror_printf_push("Attribute definitions are nested too deep."); @@ -465,7 +465,7 @@ static int dict_ctx_push(dict_tokenize_ctx_t *ctx, fr_dict_attr_t const *da) return 0; } -static fr_dict_attr_t const *dict_ctx_unwind(dict_tokenize_ctx_t *ctx) +static fr_dict_attr_t const *dict_gctx_unwind(dict_tokenize_ctx_t *ctx) { while ((ctx->stack_depth > 0) && (ctx->stack[ctx->stack_depth].nest == FR_TYPE_INVALID)) { @@ -519,7 +519,7 @@ static int dict_read_process_attribute(dict_tokenize_ctx_t *ctx, char **argv, in * unwind the stack to match. */ if (argv[1][0] != '.') { - parent = dict_ctx_unwind(ctx); + parent = dict_gctx_unwind(ctx); /* * Allow '0xff00' as attribute numbers, but only @@ -603,7 +603,7 @@ static int dict_read_process_attribute(dict_tokenize_ctx_t *ctx, char **argv, in fr_dict_t const *dict; char *p; - da = fr_dict_attr_child_by_num(parent, attr); + da = dict_attr_child_by_num(parent, attr); if (!da) { fr_strerror_printf("Failed to find attribute '%s' we just added.", argv[0]); return -1; @@ -620,7 +620,7 @@ static int dict_read_process_attribute(dict_tokenize_ctx_t *ctx, char **argv, in goto check; } - da = fr_dict_attr_by_name(ctx->dict, ref); + da = dict_attr_by_name(ctx->dict, ref); if (da) { dict = ctx->dict; goto check; @@ -681,7 +681,7 @@ static int dict_read_process_attribute(dict_tokenize_ctx_t *ctx, char **argv, in /* * Look up the attribute. */ - da = fr_dict_attr_by_name(dict, ref + slen); + da = dict_attr_by_name(dict, ref + slen); if (!da) { fr_strerror_printf("protocol loaded, but no attribute '%s'", ref + slen); talloc_free(ref); @@ -707,21 +707,21 @@ static int dict_read_process_attribute(dict_tokenize_ctx_t *ctx, char **argv, in * *canonical* previous attribute, and not any potential * duplicate which was just added. */ - if (set_relative_attr) ctx->relative_attr = fr_dict_attr_child_by_num(parent, attr); + if (set_relative_attr) ctx->relative_attr = dict_attr_child_by_num(parent, attr); /* * Adding an attribute of type 'struct' is an implicit * BEGIN-STRUCT. */ if (type == FR_TYPE_STRUCT) { - fr_dict_attr_t const *da = fr_dict_attr_child_by_num(parent, attr); + fr_dict_attr_t const *da = dict_attr_child_by_num(parent, attr); if (!da) { fr_strerror_printf("Failed adding attribute %s", argv[0]); return -1; } - if (dict_ctx_push(ctx, da) < 0) return -1; + if (dict_gctx_push(ctx, da) < 0) return -1; } return 0; @@ -771,7 +771,11 @@ static int dict_read_process_member(dict_tokenize_ctx_t *ctx, char **argv, int a /* * Add the MEMBER to the parent. */ - if (fr_dict_attr_add(ctx->dict, ctx->stack[ctx->stack_depth].da, argv[0], ++ctx->stack[ctx->stack_depth].member_num, type, &flags) < 0) return -1; + if (fr_dict_attr_add(ctx->dict, + ctx->stack[ctx->stack_depth].da, + argv[0], + ++ctx->stack[ctx->stack_depth].member_num, + type, &flags) < 0) return -1; /* * A 'struct' can have a MEMBER of type 'tlv', but ONLY @@ -782,8 +786,9 @@ static int dict_read_process_member(dict_tokenize_ctx_t *ctx, char **argv, int a * to them. */ if (type == FR_TYPE_TLV) { - ctx->relative_attr = fr_dict_attr_child_by_num(ctx->stack[ctx->stack_depth].da, ctx->stack[ctx->stack_depth].member_num); - if (dict_ctx_push(ctx, ctx->relative_attr) < 0) return -1; + ctx->relative_attr = dict_attr_child_by_num(ctx->stack[ctx->stack_depth].da, + ctx->stack[ctx->stack_depth].member_num); + if (dict_gctx_push(ctx, ctx->relative_attr) < 0) return -1; } else { fr_dict_attr_t *mutable; @@ -812,8 +817,8 @@ static int dict_read_process_member(dict_tokenize_ctx_t *ctx, char **argv, int a */ static int dict_read_process_value(dict_tokenize_ctx_t *ctx, char **argv, int argc) { - fr_dict_attr_t const *da; - fr_value_box_t value; + fr_dict_attr_t *da; + fr_value_box_t value; if (argc != 3) { fr_strerror_printf("Invalid VALUE syntax"); @@ -826,7 +831,7 @@ static int dict_read_process_value(dict_tokenize_ctx_t *ctx, char **argv, int ar * caching the last attribute for a VALUE. */ if (!ctx->value_attr || (strcasecmp(argv[0], ctx->value_attr->name) != 0)) { - ctx->value_attr = fr_dict_attr_by_name(ctx->dict, argv[0]); + ctx->value_attr = dict_attr_by_name(ctx->dict, argv[0]); } da = ctx->value_attr; @@ -956,7 +961,7 @@ static int dict_read_process_struct(dict_tokenize_ctx_t *ctx, char **argv, int a /* * This SHOULD be the "key" field. */ - parent = fr_dict_attr_by_name(ctx->dict, key_attr); + parent = dict_attr_by_name(ctx->dict, key_attr); if (!parent) { fr_strerror_printf("Unknown attribute '%s'", key_attr); return -1; @@ -1066,14 +1071,14 @@ get_value: */ if (fr_dict_attr_add(ctx->dict, parent, argv[1], attr, FR_TYPE_STRUCT, &flags) < 0) return -1; - da = fr_dict_attr_by_name(ctx->dict, argv[1]); + da = dict_attr_by_name(ctx->dict, argv[1]); if (!da) return -1; /* * A STRUCT definition is an implicit BEGIN-STRUCT. */ ctx->relative_attr = NULL; - if (dict_ctx_push(ctx, da) < 0) return -1; + if (dict_gctx_push(ctx, da) < 0) return -1; return 0; } @@ -1200,7 +1205,7 @@ static int dict_read_process_protocol(char **argv, int argc) /* * Cross check name / number. */ - dict = fr_dict_by_protocol_name(argv[0]); + dict = dict_by_protocol_name(argv[0]); if (dict) { #ifdef __clang_analyzer__ if (!dict->root) return -1; @@ -1212,7 +1217,7 @@ static int dict_read_process_protocol(char **argv, int argc) return -1; } - } else if ((dict = fr_dict_by_protocol_num(value)) != NULL) { + } else if ((dict = dict_by_protocol_num(value)) != NULL) { #ifdef __clang_analyzer__ if (!dict->root || !dict->root->name || !argv[0]) return -1; #endif @@ -1335,7 +1340,7 @@ static int fr_dict_finalise(dict_tokenize_ctx_t *ctx) * before the attributes they reference. */ if (ctx->enum_fixup) { - fr_dict_attr_t const *da; + fr_dict_attr_t *da; dict_enum_fixup_t *this, *next; for (this = ctx->enum_fixup; this != NULL; this = next) { @@ -1344,7 +1349,7 @@ static int fr_dict_finalise(dict_tokenize_ctx_t *ctx) int ret; next = this->next; - da = fr_dict_attr_by_name(ctx->dict, this->attribute); + da = dict_attr_by_name(ctx->dict, this->attribute); if (!da) { fr_strerror_printf("No ATTRIBUTE '%s' defined for VALUE '%s' at %s[%d]", this->attribute, this->name, this->filename, this->line); @@ -1411,7 +1416,7 @@ static int fr_dict_finalise(dict_tokenize_ctx_t *ctx) char *p; ssize_t slen; - da = fr_dict_attr_by_name(ctx->dict, this->ref); + da = dict_attr_by_name(ctx->dict, this->ref); if (da) { dict = ctx->dict; goto check; @@ -1474,7 +1479,7 @@ static int fr_dict_finalise(dict_tokenize_ctx_t *ctx) /* * Look up the attribute. */ - da = fr_dict_attr_by_name(dict, this->ref + slen + 1); + da = dict_attr_by_name(dict, this->ref + slen + 1); if (!da) { fr_strerror_printf("No such attribute '%s' in reference at %s[%d]", this->ref + slen + 1, this->filename, this->line); @@ -1825,12 +1830,12 @@ static int _dict_from_file(dict_tokenize_ctx_t *ctx, * dictionary, then we don't allow BEGIN-PROTOCOL * statements. */ - if (ctx->dict != fr_dict_internal) { + if (ctx->dict != dict_gctx->internal) { fr_strerror_printf_push("Nested BEGIN-PROTOCOL statements are not allowed"); goto error; } - found = fr_dict_by_protocol_name(argv[1]); + found = dict_by_protocol_name(argv[1]); if (!found) { fr_strerror_printf("Unknown protocol '%s'", argv[1]); goto error; @@ -1852,7 +1857,7 @@ static int _dict_from_file(dict_tokenize_ctx_t *ctx, ctx->dict = found; - if (dict_ctx_push(ctx, ctx->dict->root) < 0) goto error; + if (dict_gctx_push(ctx, ctx->dict->root) < 0) goto error; ctx->stack[ctx->stack_depth].nest = FR_TYPE_MAX; continue; } @@ -1868,7 +1873,7 @@ static int _dict_from_file(dict_tokenize_ctx_t *ctx, goto error; } - found = fr_dict_by_protocol_name(argv[1]); + found = dict_by_protocol_name(argv[1]); if (!found) { fr_strerror_printf("END-PROTOCOL %s does not refer to a valid protocol", argv[1]); goto error; @@ -1933,7 +1938,7 @@ static int _dict_from_file(dict_tokenize_ctx_t *ctx, goto error; } - da = fr_dict_attr_by_name(ctx->dict, argv[1]); + da = dict_attr_by_name(ctx->dict, argv[1]); if (!da) { fr_strerror_printf_push("Unknown attribute '%s'", argv[1]); goto error; @@ -1954,7 +1959,7 @@ static int _dict_from_file(dict_tokenize_ctx_t *ctx, goto error; } - if (dict_ctx_push(ctx, da) < 0) goto error; + if (dict_gctx_push(ctx, da) < 0) goto error; ctx->stack[ctx->stack_depth].nest = FR_TYPE_TLV; continue; } /* BEGIN-TLV */ @@ -1968,7 +1973,7 @@ static int _dict_from_file(dict_tokenize_ctx_t *ctx, goto error; } - da = fr_dict_attr_by_name(ctx->dict, argv[1]); + da = dict_attr_by_name(ctx->dict, argv[1]); if (!da) { fr_strerror_printf_push("Unknown attribute '%s'", argv[1]); goto error; @@ -2034,7 +2039,7 @@ static int _dict_from_file(dict_tokenize_ctx_t *ctx, } p = argv[2] + 7; - da = fr_dict_attr_by_name(ctx->dict, p); + da = dict_attr_by_name(ctx->dict, p); if (!da) { fr_strerror_printf_push("Invalid format for BEGIN-VENDOR: Unknown " "parent attribute '%s'", p); @@ -2066,7 +2071,7 @@ static int _dict_from_file(dict_tokenize_ctx_t *ctx, /* * Check that the protocol-specific VSA parent exists. */ - vsa_da = fr_dict_attr_child_by_num(ctx->stack[ctx->stack_depth].da, ctx->dict->vsa_parent); + vsa_da = dict_attr_child_by_num(ctx->stack[ctx->stack_depth].da, ctx->dict->vsa_parent); if (!vsa_da) { fr_strerror_printf_push("Failed finding VSA parent for Vendor %s", vendor->name); @@ -2078,7 +2083,7 @@ static int _dict_from_file(dict_tokenize_ctx_t *ctx, * Create a VENDOR attribute on the fly, either in the context * of the VSA (26) attribute. */ - vendor_da = fr_dict_attr_child_by_num(vsa_da, vendor->pen); + vendor_da = dict_attr_child_by_num(vsa_da, vendor->pen); if (!vendor_da) { memset(&flags, 0, sizeof(flags)); @@ -2114,7 +2119,7 @@ static int _dict_from_file(dict_tokenize_ctx_t *ctx, vendor_da = new; } - if (dict_ctx_push(ctx, vendor_da) < 0) goto error; + if (dict_gctx_push(ctx, vendor_da) < 0) goto error; ctx->stack[ctx->stack_depth].nest = FR_TYPE_VENDOR; continue; } /* BEGIN-VENDOR */ @@ -2228,12 +2233,11 @@ int fr_dict_internal_afrom_file(fr_dict_t **out, char const *dict_subdir) { fr_dict_t *dict; char *dict_path = NULL; - char *tmp; size_t i; fr_dict_attr_flags_t flags = { .internal = true }; char *type_name; - if (unlikely(!dict_initialised)) { + if (unlikely(!dict_gctx)) { fr_strerror_printf("fr_dict_global_init() must be called before loading dictionary files"); return -1; } @@ -2241,19 +2245,20 @@ int fr_dict_internal_afrom_file(fr_dict_t **out, char const *dict_subdir) /* * Increase the reference count of the internal dictionary. */ - if (fr_dict_internal) { - talloc_increase_ref_count(fr_dict_internal); - *out = fr_dict_internal; + if (dict_gctx->internal) { + talloc_increase_ref_count(dict_gctx->internal); + *out = dict_gctx->internal; return 0; } - memcpy(&tmp, &dict_dir_default, sizeof(tmp)); - dict_path = dict_subdir ? talloc_asprintf(NULL, "%s%c%s", dict_dir_default, FR_DIR_SEP, dict_subdir) : tmp; + dict_path = dict_subdir ? + talloc_asprintf(NULL, "%s%c%s", fr_dict_global_dir(), FR_DIR_SEP, dict_subdir) : + talloc_strdup(NULL, fr_dict_global_dir()); - dict = dict_alloc(dict_ctx); + dict = dict_alloc(dict_gctx); if (!dict) { error: - if (!fr_dict_internal) talloc_free(dict); + if (!dict_gctx->internal) talloc_free(dict); talloc_free(dict_path); return -1; } @@ -2303,7 +2308,7 @@ int fr_dict_internal_afrom_file(fr_dict_t **out, char const *dict_subdir) talloc_free(dict_path); *out = dict; - if (!fr_dict_internal) fr_dict_internal = dict; + if (!dict_gctx->internal) dict_gctx->internal = dict; return 0; } @@ -2325,12 +2330,12 @@ int fr_dict_protocol_afrom_file(fr_dict_t **out, char const *proto_name, char co char *dict_dir = NULL; fr_dict_t *dict; - if (unlikely(!dict_initialised)) { + if (unlikely(!dict_gctx)) { fr_strerror_printf("fr_dict_global_init() must be called before loading dictionary files"); return -1; } - if (unlikely(!fr_dict_internal)) { + if (unlikely(!dict_gctx->internal)) { fr_strerror_printf("Internal dictionary must be initialised before loading protocol dictionaries"); return -1; } @@ -2339,7 +2344,7 @@ int fr_dict_protocol_afrom_file(fr_dict_t **out, char const *proto_name, char co * Increment the reference count if the dictionary * has already been loaded and return that. */ - dict = fr_dict_by_protocol_name(proto_name); + dict = dict_by_protocol_name(proto_name); if (dict && dict->autoloaded) { talloc_increase_ref_count(dict); *out = dict; @@ -2347,9 +2352,9 @@ int fr_dict_protocol_afrom_file(fr_dict_t **out, char const *proto_name, char co } if (!proto_dir) { - dict_dir = talloc_asprintf(NULL, "%s%c%s", dict_dir_default, FR_DIR_SEP, proto_name); + dict_dir = talloc_asprintf(NULL, "%s%c%s", fr_dict_global_dir(), FR_DIR_SEP, proto_name); } else { - dict_dir = talloc_asprintf(NULL, "%s%c%s", dict_dir_default, FR_DIR_SEP, proto_dir); + dict_dir = talloc_asprintf(NULL, "%s%c%s", fr_dict_global_dir(), FR_DIR_SEP, proto_dir); } /* @@ -2361,7 +2366,7 @@ int fr_dict_protocol_afrom_file(fr_dict_t **out, char const *proto_name, char co * for multiple protocols, which'll probably be useful * at some point. */ - if (dict_from_file(fr_dict_internal, dict_dir, FR_DICTIONARY_FILE, NULL, 0) < 0) { + if (dict_from_file(dict_gctx->internal, dict_dir, FR_DICTIONARY_FILE, NULL, 0) < 0) { error: talloc_free(dict_dir); return -1; @@ -2370,7 +2375,7 @@ int fr_dict_protocol_afrom_file(fr_dict_t **out, char const *proto_name, char co /* * Check the dictionary actually defined the protocol */ - dict = fr_dict_by_protocol_name(proto_name); + dict = dict_by_protocol_name(proto_name); if (!dict) { fr_strerror_printf("Dictionary \"%s\" missing \"BEGIN-PROTOCOL %s\" declaration", dict_dir, proto_name); goto error; @@ -2405,6 +2410,11 @@ int fr_dict_read(fr_dict_t *dict, char const *dir, char const *filename) { INTERNAL_IF_NULL(dict, -1); + if (unlikely(dict->read_only)) { + fr_strerror_printf("%s dictionary has been marked as read only", fr_dict_root(dict)->name); + return -1; + } + if (!dict->attributes_by_name) { fr_strerror_printf("%s: Must initialise dictionary before calling fr_dict_read()", __FUNCTION__); return -1; @@ -2447,7 +2457,7 @@ int fr_dict_parse_str(fr_dict_t *dict, char *buf, fr_dict_attr_t const *parent) return -1; } - if (!fr_dict_attr_by_name(dict, argv[1])) { + if (!dict_attr_by_name(dict, argv[1])) { fr_strerror_printf("Attribute \"%s\" does not exist in dictionary \"%s\"", argv[1], dict->root->name); goto error; diff --git a/src/lib/util/dict_unknown.c b/src/lib/util/dict_unknown.c index b83a8bc72ec..00f56b3b192 100644 --- a/src/lib/util/dict_unknown.c +++ b/src/lib/util/dict_unknown.c @@ -83,6 +83,11 @@ fr_dict_attr_t const *fr_dict_unknown_add(fr_dict_t *dict, fr_dict_attr_t const fr_dict_attr_t const *parent; fr_dict_attr_flags_t flags; + if (unlikely(dict->read_only)) { + fr_strerror_printf("%s dictionary has been marked as read only", fr_dict_root(dict)->name); + return -1; + } + da = fr_dict_attr_by_name(dict, old->name); if (da) return da; @@ -316,7 +321,7 @@ fr_dict_attr_t const *fr_dict_unknown_afrom_fields(TALLOC_CTX *ctx, fr_dict_attr * If so, use the pre-defined name instead of an unknown * one.! */ - da = fr_dict_attr_by_name(fr_dict_by_da(parent), n->name); + da = fr_dict_attr_by_name(dict_by_da(parent), n->name); if (da) { fr_dict_unknown_free(&parent); parent = n; diff --git a/src/lib/util/dict_util.c b/src/lib/util/dict_util.c index ef51dd38101..12fff6b1b4b 100644 --- a/src/lib/util/dict_util.c +++ b/src/lib/util/dict_util.c @@ -36,15 +36,7 @@ RCSID("$Id$") # include #endif -bool dict_initialised = false; -char *dict_dir_default; //!< The default location for loading dictionaries if one - ///< wasn't provided. -TALLOC_CTX *dict_ctx; - -static dl_loader_t *dict_loader; //!< for protocol validation - -static fr_hash_table_t *protocol_by_name = NULL; //!< Hash containing names of all the registered protocols. -static fr_hash_table_t *protocol_by_num = NULL; //!< Hash containing numbers of all the registered protocols. +dict_gctx_t *dict_gctx; //!< Top level structure containing global dictionary state. fr_table_num_ordered_t const date_precision_table[] = { { "microseconds", FR_TIME_RES_USEC }, @@ -73,16 +65,6 @@ static fr_table_num_ordered_t const eap_aka_sim_subtype_table[] = { }; static size_t eap_aka_sim_subtype_table_len = NUM_ELEMENTS(eap_aka_sim_subtype_table); -/** Magic internal dictionary - * - * Internal dictionary is checked in addition to the protocol dictionary - * when resolving attribute names. - * - * This is because internal attributes are valid for every - * protocol. - */ -fr_dict_t *fr_dict_internal = NULL; //!< Internal server dictionary. - /** Map data types to min / max data sizes */ size_t const dict_attr_sizes[FR_TYPE_MAX + 1][2] = { @@ -490,7 +472,6 @@ static fr_dict_attr_t *dict_attr_acopy(TALLOC_CTX *ctx, fr_dict_attr_t const *in return n; } - /** Add a protocol to the global protocol table * * Inserts a protocol into the global protocol table. Uses the root attributes @@ -505,10 +486,10 @@ int dict_protocol_add(fr_dict_t *dict) { if (!dict->root) return -1; /* Should always have root */ - if (!fr_hash_table_insert(protocol_by_name, dict)) { + if (!fr_hash_table_insert(dict_gctx->protocol_by_name, dict)) { fr_dict_t *old_proto; - old_proto = fr_hash_table_finddata(protocol_by_name, dict); + old_proto = fr_hash_table_finddata(dict_gctx->protocol_by_name, dict); if (!old_proto) { fr_strerror_printf("%s: Failed inserting protocol name %s", __FUNCTION__, dict->root->name); return -1; @@ -524,7 +505,7 @@ int dict_protocol_add(fr_dict_t *dict) } dict->in_protocol_by_name = true; - if (!fr_hash_table_insert(protocol_by_num, dict)) { + if (!fr_hash_table_insert(dict_gctx->protocol_by_num, dict)) { fr_strerror_printf("%s: Duplicate protocol number %i", __FUNCTION__, dict->root->attr); return -1; } @@ -848,7 +829,6 @@ int dict_attr_add_by_name(fr_dict_t *dict, fr_dict_attr_t *da) return 0; } - /** Add an attribute to the dictionary * * @param[in] dict of protocol context we're operating in. @@ -870,6 +850,11 @@ int fr_dict_attr_add(fr_dict_t *dict, fr_dict_attr_t const *parent, fr_dict_attr_t *mutable; fr_dict_attr_flags_t our_flags = *flags; + if (unlikely(dict->read_only)) { + fr_strerror_printf("%s dictionary has been marked as read only", fr_dict_root(dict)->name); + return -1; + } + /* * Check that the definition is valid. */ @@ -957,9 +942,9 @@ int fr_dict_attr_add(fr_dict_t *dict, fr_dict_attr_t const *parent, * - 0 on success. * - -1 on failure. */ -int fr_dict_enum_add_name(fr_dict_attr_t const *da, char const *name, - fr_value_box_t const *value, - bool coerce, bool takes_precedence) +int fr_dict_enum_add_name(fr_dict_attr_t *da, char const *name, + fr_value_box_t const *value, + bool coerce, bool takes_precedence) { size_t len; fr_dict_t *dict; @@ -982,7 +967,7 @@ int fr_dict_enum_add_name(fr_dict_attr_t const *da, char const *name, return -1; } - dict = fr_dict_by_da(da); + dict = dict_by_da(da); enumv = talloc_zero(dict->pool, fr_dict_enum_t); if (!enumv) { @@ -1083,7 +1068,7 @@ int fr_dict_enum_add_name(fr_dict_attr_t const *da, char const *name, /** Add an name to an integer attribute hashing the name for the integer value * */ -int fr_dict_enum_add_name_next(fr_dict_attr_t const *da, char const *name) +int fr_dict_enum_add_name_next(fr_dict_attr_t *da, char const *name) { fr_value_box_t v = { .type = da->type @@ -1253,7 +1238,7 @@ int fr_dict_oid_component(unsigned int *out, char const **oid) * - > 0 on success (number of bytes parsed). * - <= 0 on parse error (negative offset of parse error). */ -ssize_t fr_dict_attr_by_oid(fr_dict_t *dict, fr_dict_attr_t const **parent, unsigned int *attr, char const *oid) +ssize_t fr_dict_attr_by_oid(fr_dict_t const *dict, fr_dict_attr_t const **parent, unsigned int *attr, char const *oid) { char const *p = oid; unsigned int num = 0; @@ -1310,7 +1295,7 @@ ssize_t fr_dict_attr_by_oid(fr_dict_t *dict, fr_dict_attr_t const **parent, unsi fr_dict_attr_t const *child; p++; - child = fr_dict_attr_child_by_num(*parent, num); + child = dict_attr_child_by_num(*parent, num); if (!child) { fr_strerror_printf("Unknown attribute '%i' in OID string \"%s\" for parent %s", num, oid, (*parent)->name); @@ -1349,7 +1334,7 @@ ssize_t fr_dict_attr_by_oid(fr_dict_t *dict, fr_dict_attr_t const **parent, unsi */ fr_dict_attr_t const *fr_dict_root(fr_dict_t const *dict) { - if (!dict) return fr_dict_internal->root; /* Remove me when dictionaries are done */ + if (!dict) return dict_gctx->internal->root; /* Remove me when dictionaries are done */ return dict->root; } @@ -1372,7 +1357,7 @@ ssize_t fr_dict_by_protocol_substr(fr_dict_t const **out, char const *name, fr_d char const *p; size_t len; - if (!protocol_by_name || !name || !*name || !out) return 0; + if (!dict_gctx || !name || !*name || !out) return 0; memset(&root, 0, sizeof(root)); @@ -1403,7 +1388,7 @@ ssize_t fr_dict_by_protocol_substr(fr_dict_t const **out, char const *name, fr_d *out = NULL; return 0; } - dict = fr_hash_table_finddata(protocol_by_name, &(fr_dict_t){ .root = &root }); + dict = fr_hash_table_finddata(dict_gctx->protocol_by_name, &(fr_dict_t){ .root = &root }); talloc_const_free(root.name); if (!dict) { @@ -1416,47 +1401,41 @@ ssize_t fr_dict_by_protocol_substr(fr_dict_t const **out, char const *name, fr_d return p - name; } -/** Lookup a protocol by its name +/**Internal version of #fr_dict_by_protocol_name * - * @param[in] name of the protocol to locate. - * @return - * - Attribute matching name. - * - NULL if no matching protocolibute could be found. + * @note For internal use by the dictionary API only. + * + * @copybrief fr_dict_by_protocol_name. */ -fr_dict_t *fr_dict_by_protocol_name(char const *name) +fr_dict_t *dict_by_protocol_name(char const *name) { - if (!protocol_by_name || !name) return NULL; + if (!dict_gctx || !name) return NULL; - return fr_hash_table_finddata(protocol_by_name, &(fr_dict_t){ .root = &(fr_dict_attr_t){ .name = name } }); + return fr_hash_table_finddata(dict_gctx->protocol_by_name, + &(fr_dict_t){ .root = &(fr_dict_attr_t){ .name = name } }); } -/** Lookup a protocol by its number. +/** Internal version of #fr_dict_by_protocol_num * - * Returns the #fr_dict_t belonging to the protocol with the specified number - * if any have been registered. + * @note For internal use by the dictionary API only. * - * @param[in] num to search for. - * @return dictionary representing the protocol (if it exists). + * @copybrief fr_dict_by_protocol_num. */ -fr_dict_t *fr_dict_by_protocol_num(unsigned int num) +fr_dict_t *dict_by_protocol_num(unsigned int num) { - if (!protocol_by_num) return NULL; + if (!dict_gctx) return NULL; - return fr_hash_table_finddata(protocol_by_num, &(fr_dict_t) { .root = &(fr_dict_attr_t){ .attr = num } }); + return fr_hash_table_finddata(dict_gctx->protocol_by_num, + &(fr_dict_t) { .root = &(fr_dict_attr_t){ .attr = num } }); } -/** Attempt to locate the protocol dictionary containing an attribute +/** Internal version of #fr_dict_by_da * - * @note Unlike fr_dict_by_attr_name, doesn't search through all the dictionaries, - * just uses the fr_dict_attr_t hierarchy and the talloc hierarchy to locate - * the dictionary (much much faster and more scalable). + * @note For internal use by the dictionary API only. * - * @param[in] da To get the containing dictionary for. - * @return - * - The dictionary containing da. - * - NULL. + * @copybrief fr_dict_by_da */ -fr_dict_t *fr_dict_by_da(fr_dict_attr_t const *da) +fr_dict_t *dict_by_da(fr_dict_attr_t const *da) { fr_dict_attr_t const *da_p = da; @@ -1511,17 +1490,13 @@ static int _dict_attr_find_in_dicts(void *ctx, void *data) return 1; } -/** Attempt to locate the protocol dictionary containing an attribute +/** Internal version of #fr_dict_by_attr_name * - * @note This is O(n) and will only return the first instance of the dictionary. + * @note For internal use by the dictionary API only. * - * @param[out] found the attribute that was resolved from the name. May be NULL. - * @param[in] name the name of the attribute. - * @return - * - the dictionary the attribute was found in. - * - NULL if an attribute with the specified name wasn't found in any dictionary. + * @copybrief fr_dict_by_attr_name */ -fr_dict_t *fr_dict_by_attr_name(fr_dict_attr_t const **found, char const *name) +fr_dict_t *dict_by_attr_name(fr_dict_attr_t const **found, char const *name) { fr_dict_attr_t find = { .name = name @@ -1535,7 +1510,7 @@ fr_dict_t *fr_dict_by_attr_name(fr_dict_attr_t const **found, char const *name) if (!name || !*name) return NULL; - ret = fr_hash_table_walk(protocol_by_name, _dict_attr_find_in_dicts, &search); + ret = fr_hash_table_walk(dict_gctx->protocol_by_name, _dict_attr_find_in_dicts, &search); if (ret == 0) return NULL; if (found) *found = search.found_da; @@ -1543,6 +1518,64 @@ fr_dict_t *fr_dict_by_attr_name(fr_dict_attr_t const **found, char const *name) return search.found_dict; } +/** Lookup a protocol by its name + * + * @note For internal use by the dictionary API only. + * + * @param[in] name of the protocol to locate. + * @return + * - Attribute matching name. + * - NULL if no matching protocol could be found. + */ +fr_dict_t const *fr_dict_by_protocol_name(char const *name) +{ + return dict_by_protocol_name(name); +} + +/** Lookup a protocol by its number + * + * Returns the #fr_dict_t belonging to the protocol with the specified number + * if any have been registered. + * + * @param[in] num to search for. + * @return dictionary representing the protocol (if it exists). + */ +fr_dict_t const *fr_dict_by_protocol_num(unsigned int num) +{ + return dict_by_protocol_num(num); +} + +/** Attempt to locate the protocol dictionary containing an attribute + * + * @note Unlike fr_dict_by_attr_name, doesn't search through all the dictionaries, + * just uses the fr_dict_attr_t hierarchy and the talloc hierarchy to locate + * the dictionary (much much faster and more scalable). + * + * @param[in] da To get the containing dictionary for. + * @return + * - The dictionary containing da. + * - NULL. + */ +fr_dict_t const *fr_dict_by_da(fr_dict_attr_t const *da) +{ + return dict_by_da(da); +} + +/** Attempt to locate the protocol dictionary containing an attribute + * + * @note This is O(n) and will only return the first instance of the dictionary. + * + * @param[out] found the attribute that was resolved from the name. May be NULL. + * @param[in] name the name of the attribute. + * @return + * - the dictionary the attribute was found in. + * - NULL if an attribute with the specified name wasn't found in any dictionary. + */ +fr_dict_t const *fr_dict_by_attr_name(fr_dict_attr_t const **found, char const *name) +{ + return dict_by_attr_name(found, name); +} + /** Look up a vendor by one of its child attributes * * @param[in] da The vendor attribute. @@ -1558,7 +1591,7 @@ fr_dict_vendor_t const *fr_dict_vendor_by_da(fr_dict_attr_t const *da) dv.pen = fr_dict_vendor_num_by_da(da); if (!dv.pen) return NULL; - dict = fr_dict_by_da(da); + dict = dict_by_da(da); return fr_hash_table_finddata(dict->vendors_by_num, &dv); } @@ -1651,7 +1684,7 @@ fr_dict_attr_t const *fr_dict_vendor_attr_by_num(fr_dict_attr_t const *vendor_ro return NULL; } - vendor = fr_dict_attr_child_by_num(vendor_root, vendor_pen); + vendor = dict_attr_child_by_num(vendor_root, vendor_pen); if (!vendor) { fr_strerror_printf("Vendor %i not defined", vendor_pen); return NULL; @@ -1739,6 +1772,19 @@ ssize_t fr_dict_attr_by_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t cons return p - name; } +/* Internal version of fr_dict_attr_by_name + * + */ +fr_dict_attr_t *dict_attr_by_name(fr_dict_t const *dict, char const *name) +{ + INTERNAL_IF_NULL(dict, NULL); + + if (!name) return NULL; + + return fr_hash_table_finddata(dict->attributes_by_name, &(fr_dict_attr_t) { .name = name }); +} + + /** Locate a #fr_dict_attr_t by its name * * @note Unlike attribute numbers, attribute names are unique to the dictionary. @@ -1752,11 +1798,7 @@ ssize_t fr_dict_attr_by_name_substr(fr_dict_attr_err_t *err, fr_dict_attr_t cons */ fr_dict_attr_t const *fr_dict_attr_by_name(fr_dict_t const *dict, char const *name) { - INTERNAL_IF_NULL(dict, NULL); - - if (!name) return NULL; - - return fr_hash_table_finddata(dict->attributes_by_name, &(fr_dict_attr_t) { .name = name }); + return dict_attr_by_name(dict, name); } /** Locate a qualified #fr_dict_attr_t by its name and a dictionary qualifier @@ -1844,8 +1886,8 @@ again: */ if (!internal) { internal = true; - if (dict_def != fr_dict_internal) { - dict = fr_dict_internal; + if (dict_def != dict_gctx->internal) { + dict = dict_gctx->internal; goto again; } } @@ -1853,10 +1895,10 @@ again: /* * Start the iteration over all dictionaries. */ - dict_iter = fr_hash_table_iter_init(protocol_by_num, &iter); + dict_iter = fr_hash_table_iter_init(dict_gctx->protocol_by_num, &iter); } else { redo: - dict_iter = fr_hash_table_iter_next(protocol_by_num, &iter); + dict_iter = fr_hash_table_iter_next(dict_gctx->protocol_by_num, &iter); } if (!dict_iter) goto fail; @@ -1931,7 +1973,7 @@ fr_dict_attr_err_t fr_dict_attr_by_qualified_name(fr_dict_attr_t const **out, fr */ fr_dict_attr_t const *fr_dict_attr_by_type(fr_dict_attr_t const *da, fr_type_t type) { - return fr_hash_table_finddata(fr_dict_by_da(da)->attributes_combo, + return fr_hash_table_finddata(dict_by_da(da)->attributes_combo, &(fr_dict_attr_t){ .parent = da->parent, .attr = da->attr, @@ -1982,15 +2024,10 @@ fr_dict_attr_t const *fr_dict_attr_child_by_da(fr_dict_attr_t const *parent, fr_ return NULL; } -/** Check if a child attribute exists in a parent using an attribute number +/** Internal version of fr_dict_attr_child_by_num * - * @param[in] parent to check for child in. - * @param[in] attr number to look for. - * @return - * - The child attribute on success. - * - NULL if the child attribute does not exist. */ -inline fr_dict_attr_t const *fr_dict_attr_child_by_num(fr_dict_attr_t const *parent, unsigned int attr) +inline fr_dict_attr_t *dict_attr_child_by_num(fr_dict_attr_t const *parent, unsigned int attr) { fr_dict_attr_t const *bin; @@ -2002,9 +2039,7 @@ inline fr_dict_attr_t const *fr_dict_attr_child_by_num(fr_dict_attr_t const *par * We return the child of the referenced attribute, and * not of the "group" attribute. */ - if (parent->type == FR_TYPE_GROUP) { - parent = parent->ref; - } + if (parent->type == FR_TYPE_GROUP) parent = parent->ref; /* * Child arrays may be trimmed back to save memory. @@ -2015,13 +2050,32 @@ inline fr_dict_attr_t const *fr_dict_attr_child_by_num(fr_dict_attr_t const *par bin = parent->children[attr & 0xff]; for (;;) { if (!bin) return NULL; - if (bin->attr == attr) return bin; + if (bin->attr == attr) { + fr_dict_attr_t *out; + + memcpy(&out, &bin, sizeof(bin)); + + return out; + } bin = bin->next; } return NULL; } +/** Check if a child attribute exists in a parent using an attribute number + * + * @param[in] parent to check for child in. + * @param[in] attr number to look for. + * @return + * - The child attribute on success. + * - NULL if the child attribute does not exist. + */ +fr_dict_attr_t const *fr_dict_attr_child_by_num(fr_dict_attr_t const *parent, unsigned int attr) +{ + return dict_attr_child_by_num(parent, attr); +} + /** Lookup the structure representing an enum value in a #fr_dict_attr_t * * @param[in] da to search in. @@ -2037,7 +2091,7 @@ fr_dict_enum_t *fr_dict_enum_by_value(fr_dict_attr_t const *da, fr_value_box_t c if (!da) return NULL; - dict = fr_dict_by_da(da); + dict = dict_by_da(da); if (!dict) { fr_strerror_printf("Attributes \"%s\" not present in any dictionaries", da->name); return NULL; @@ -2083,7 +2137,7 @@ char const *fr_dict_enum_name_by_value(fr_dict_attr_t const *da, fr_value_box_t if (!da) return NULL; - dict = fr_dict_by_da(da); + dict = dict_by_da(da); if (!dict) { fr_strerror_printf("Attributes \"%s\" not present in any dictionaries", da->name); return NULL; @@ -2109,7 +2163,7 @@ fr_dict_enum_t *fr_dict_enum_by_name(fr_dict_attr_t const *da, char const *name, if (!name) return NULL; - dict = fr_dict_by_da(da); + dict = dict_by_da(da); if (!dict) { fr_strerror_printf("Attributes \"%s\" not present in any dictionaries", da->name); return NULL; @@ -2145,7 +2199,7 @@ int dict_dlopen(fr_dict_t *dict, char const *name) * Not all dictionaries have validation functions. It's * a soft error if they don't exist. */ - dict->dl = dl_by_name(dict_loader, module_name, dict, false); + dict->dl = dl_by_name(dict_gctx->dict_loader, module_name, dict, false); talloc_free(module_name); return 0; @@ -2161,13 +2215,13 @@ static int _dict_free_autoref(UNUSED void *ctx, void *data) static int _dict_free(fr_dict_t *dict) { - if (dict == fr_dict_internal) fr_dict_internal = NULL; + if (dict == dict_gctx->internal) dict_gctx->internal = NULL; - if (!fr_cond_assert(!dict->in_protocol_by_name || fr_hash_table_delete(protocol_by_name, dict))) { + if (!fr_cond_assert(!dict->in_protocol_by_name || fr_hash_table_delete(dict_gctx->protocol_by_name, dict))) { fr_strerror_printf("Failed removing dictionary from protocol hash \"%s\"", dict->root->name); return -1; } - if (!fr_cond_assert(!dict->in_protocol_by_num || fr_hash_table_delete(protocol_by_num, dict))) { + if (!fr_cond_assert(!dict->in_protocol_by_num || fr_hash_table_delete(dict_gctx->protocol_by_num, dict))) { fr_strerror_printf("Failed removing dictionary from protocol number_hash \"%s\"", dict->root->name); return -1; } @@ -2480,36 +2534,39 @@ static int dict_onload_func(dl_t const *dl, void *symbol, UNUSED void *user_ctx) */ int fr_dict_global_init(TALLOC_CTX *ctx, char const *dict_dir) { - TALLOC_FREE(dict_ctx); - dict_ctx = ctx; + dict_gctx_t *new_ctx = talloc_zero(ctx, dict_gctx_t); - if (!protocol_by_name) { - protocol_by_name = fr_hash_table_create(dict_ctx, dict_protocol_name_hash, dict_protocol_name_cmp, NULL); - if (!protocol_by_name) { - fr_strerror_printf("Failed initializing protocol_by_name hash"); - return -1; - } + if (!dict_dir) { + fr_strerror_printf("No dictionary location provided"); + return -1; } - if (!protocol_by_num) { - protocol_by_num = fr_hash_table_create(dict_ctx, dict_protocol_num_hash, dict_protocol_num_cmp, NULL); - if (!protocol_by_num) { - fr_strerror_printf("Failed initializing protocol_by_num hash"); - return -1; - } + new_ctx->protocol_by_name = fr_hash_table_create(new_ctx, dict_protocol_name_hash, dict_protocol_name_cmp, NULL); + if (!new_ctx->protocol_by_name) { + fr_strerror_printf("Failed initializing protocol_by_name hash"); + error: + talloc_free(new_ctx); + return -1; } - talloc_free(dict_dir_default); /* Free previous value */ - dict_dir_default = talloc_strdup(dict_ctx, dict_dir); - - dict_loader = dl_loader_init(ctx, NULL, NULL, false, false); - if (!dict_loader) return -1; + new_ctx->protocol_by_num = fr_hash_table_create(new_ctx, dict_protocol_num_hash, dict_protocol_num_cmp, NULL); + if (!new_ctx->protocol_by_num) { + fr_strerror_printf("Failed initializing protocol_by_num hash"); + goto error; + } - if (dl_symbol_init_cb_register(dict_loader, 0, "dict_protocol", dict_onload_func, NULL) < 0) { - return -1; + new_ctx->dict_dir_default = talloc_strdup(new_ctx, dict_dir); + if (!new_ctx->dict_dir_default) { + fr_strerror_printf("Out of Memory"); + goto error; } - dict_initialised = true; + new_ctx->dict_loader = dl_loader_init(new_ctx, NULL, NULL, false, false); + if (!new_ctx->dict_loader) goto error; + + if (dl_symbol_init_cb_register(new_ctx->dict_loader, 0, "dict_protocol", dict_onload_func, NULL) < 0) goto error; + + dict_gctx = new_ctx; return 0; } @@ -2521,15 +2578,84 @@ int fr_dict_global_init(TALLOC_CTX *ctx, char const *dict_dir) * - 0 on success. * - -1 on failure. */ -int fr_dict_dir_set(char const *dict_dir) +int fr_dict_global_dir_set(char const *dict_dir) { - talloc_free(dict_dir_default); /* Free previous value */ - dict_dir_default = talloc_strdup(dict_ctx, dict_dir); - if (!dict_dir_default) return -1; + talloc_free(dict_gctx->dict_dir_default); /* Free previous value */ + dict_gctx->dict_dir_default = talloc_strdup(dict_gctx, dict_dir); + if (!dict_gctx->dict_dir_default) return -1; return 0; } +char const *fr_dict_global_dir(void) +{ + return dict_gctx->dict_dir_default; +} + +/** Mark all dictionaries and the global dictionary ctx as read only + * + * Any attempts to add new attributes will now fail. + */ +void fr_dict_global_read_only(void) +{ + fr_hash_iter_t iter; + fr_dict_t *dict; + + /* + * Set everything to read only + */ + for (dict = fr_hash_table_iter_init(dict_gctx->protocol_by_num, &iter); + dict; + dict = fr_hash_table_iter_next(dict_gctx->protocol_by_num, &iter)) { + talloc_set_memlimit(dict, talloc_get_size(dict)); + dict->read_only = true; + } + + talloc_set_memlimit(dict_gctx, talloc_get_size(dict_gctx)); + dict_gctx->read_only = true; +} + +/** Coerce to non-const + * + */ +fr_dict_t *fr_dict_unconst(fr_dict_t const *dict) +{ + fr_dict_t *mutable; + + if (unlikely(dict->read_only)) { + fr_strerror_printf("%s dictionary has been marked as read only", fr_dict_root(dict)->name); + return -1; + } + + memcpy(&mutable, &dict, sizeof(dict)); + return mutable; +} + +/** Coerce to non-const + * + */ +fr_dict_attr_t *fr_dict_attr_unconst(fr_dict_attr_t const *da) +{ + fr_dict_attr_t *mutable; + fr_dict_t *dict; + + dict = dict_by_da(da); + if (unlikely(dict->read_only)) { + fr_strerror_printf("%s dictionary has been marked as read only", fr_dict_root(dict)->name); + return -1; + } + + memcpy(&mutable, &da, sizeof(da)); + return mutable; +} + +fr_dict_t const *fr_dict_internal(void) +{ + if (!dict_gctx) return NULL; + + return dict_gctx->internal; +} + /* * [a-zA-Z0-9_-:.]+ */ @@ -2683,14 +2809,3 @@ fr_dict_attr_t const *fr_dict_attr_iterate_children(fr_dict_attr_t const *parent return NULL; } - -/** Coerce to non-const - * - */ -fr_dict_t *fr_dict_unconst(fr_dict_t const *dict) -{ - fr_dict_t *mutable; - - memcpy(&mutable, &dict, sizeof(dict)); - return mutable; -} diff --git a/src/lib/util/pair.c b/src/lib/util/pair.c index cfb775a3e93..6d9a67e813b 100644 --- a/src/lib/util/pair.c +++ b/src/lib/util/pair.c @@ -154,11 +154,11 @@ VALUE_PAIR *fr_pair_afrom_num(TALLOC_CTX *ctx, unsigned int vendor, unsigned int fr_dict_attr_t const *parent; if (vendor == 0) { - da = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal), attr); + da = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal()), attr); goto alloc; } - parent = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal), FR_VENDOR_SPECIFIC); + parent = fr_dict_attr_child_by_num(fr_dict_root(fr_dict_internal()), FR_VENDOR_SPECIFIC); if (!parent) return NULL; parent = fr_dict_attr_child_by_num(parent, vendor); @@ -176,7 +176,7 @@ alloc: /* * Ensure that the DA is parented by the VP. */ - da = fr_dict_unknown_afrom_fields(vp, fr_dict_root(fr_dict_internal), vendor, attr); + da = fr_dict_unknown_afrom_fields(vp, fr_dict_root(fr_dict_internal()), vendor, attr); if (!da) { talloc_free(vp); return NULL; diff --git a/src/modules/proto_detail/proto_detail.c b/src/modules/proto_detail/proto_detail.c index 53ff84daf3e..447ed4f2402 100644 --- a/src/modules/proto_detail/proto_detail.c +++ b/src/modules/proto_detail/proto_detail.c @@ -118,7 +118,7 @@ fr_dict_attr_autoload_t proto_detail_dict_attr[] = { static int dictionary_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *parent, CONF_ITEM *ci, UNUSED CONF_PARSER const *rule) { char const *dict_str = cf_pair_value(cf_item_to_pair(ci)); - fr_dict_t *dict; + fr_dict_t const *dict; dict = fr_dict_by_protocol_name(dict_str); if (!dict) { @@ -126,7 +126,7 @@ static int dictionary_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *pare return -1; } - *(fr_dict_t **) out = dict; + *(fr_dict_t **) out = fr_dict_unconst(dict); return 0; } diff --git a/src/modules/proto_ldap_sync/proto_ldap_sync.c b/src/modules/proto_ldap_sync/proto_ldap_sync.c index fe497d47ed1..c0fe5f8eb91 100644 --- a/src/modules/proto_ldap_sync/proto_ldap_sync.c +++ b/src/modules/proto_ldap_sync/proto_ldap_sync.c @@ -250,7 +250,7 @@ static int fr_dict_enum_from_name_number(fr_dict_attr_t const *da, fr_table_num_ for (p = table; p->name; p++) { value.vb_int32 = p->value; - if (fr_dict_enum_add_name(da, p->name, &value, true, false) < 0) return -1; + if (fr_dict_enum_add_name(fr_dict_attr_unconst(da), p->name, &value, true, false) < 0) return -1; } return 0; diff --git a/src/modules/rlm_chap/rlm_chap.c b/src/modules/rlm_chap/rlm_chap.c index 89ae47b95e4..1d4c0295b1a 100644 --- a/src/modules/rlm_chap/rlm_chap.c +++ b/src/modules/rlm_chap/rlm_chap.c @@ -201,7 +201,7 @@ static int mod_bootstrap(void *instance, CONF_SECTION *conf) inst->name = cf_section_name2(conf); if (!inst->name) inst->name = cf_section_name1(conf); - if (fr_dict_enum_add_name_next(attr_auth_type, inst->name) < 0) { + if (fr_dict_enum_add_name_next(fr_dict_attr_unconst(attr_auth_type), inst->name) < 0) { PERROR("Failed adding %s alias", attr_auth_type->name); return -1; } diff --git a/src/modules/rlm_dict/rlm_dict.c b/src/modules/rlm_dict/rlm_dict.c index 722e3c494a7..e68c5f0a5f4 100644 --- a/src/modules/rlm_dict/rlm_dict.c +++ b/src/modules/rlm_dict/rlm_dict.c @@ -69,7 +69,7 @@ static ssize_t xlat_dict_attr_by_oid(TALLOC_CTX *ctx, char **out, UNUSED size_t fr_dict_attr_t const *da; ssize_t ret; - ret = fr_dict_attr_by_oid(fr_dict_internal, &parent, &attr, fmt); + ret = fr_dict_attr_by_oid(fr_dict_internal(), &parent, &attr, fmt); if (ret <= 0) { REMARKER(fmt, -(ret), "%s", fr_strerror()); return ret; diff --git a/src/modules/rlm_digest/rlm_digest.c b/src/modules/rlm_digest/rlm_digest.c index f6db40f84e6..2eedae643c0 100644 --- a/src/modules/rlm_digest/rlm_digest.c +++ b/src/modules/rlm_digest/rlm_digest.c @@ -585,7 +585,7 @@ static int mod_bootstrap(void *instance, CONF_SECTION *conf) if (!name) name = cf_section_name1(conf); inst->name = name; - if (fr_dict_enum_add_name_next(attr_auth_type, inst->name) < 0) { + if (fr_dict_enum_add_name_next(fr_dict_attr_unconst(attr_auth_type), inst->name) < 0) { PERROR("Failed adding %s alias", attr_auth_type->name); return -1; } diff --git a/src/modules/rlm_eap/rlm_eap.c b/src/modules/rlm_eap/rlm_eap.c index 7fe9602f1f5..1753b8362dd 100644 --- a/src/modules/rlm_eap/rlm_eap.c +++ b/src/modules/rlm_eap/rlm_eap.c @@ -996,7 +996,7 @@ static int mod_bootstrap(void *instance, CONF_SECTION *cs) inst->name = cf_section_name2(cs); if (!inst->name) inst->name = "eap"; - if (fr_dict_enum_add_name_next(attr_auth_type, inst->name) < 0) { + if (fr_dict_enum_add_name_next(fr_dict_attr_unconst(attr_auth_type), inst->name) < 0) { PERROR("Failed adding %s alias", inst->name); return -1; } diff --git a/src/modules/rlm_eap/types/rlm_eap_gtc/rlm_eap_gtc.c b/src/modules/rlm_eap/types/rlm_eap_gtc/rlm_eap_gtc.c index ba49bfd60f5..ba7a3dfeb97 100644 --- a/src/modules/rlm_eap/types/rlm_eap_gtc/rlm_eap_gtc.c +++ b/src/modules/rlm_eap/types/rlm_eap_gtc/rlm_eap_gtc.c @@ -86,7 +86,7 @@ static int auth_type_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *paren { char const *auth_type = cf_pair_value(cf_item_to_pair(ci)); - if (fr_dict_enum_add_name_next(attr_auth_type, auth_type) < 0) { + if (fr_dict_enum_add_name_next(fr_dict_attr_unconst(attr_auth_type), auth_type) < 0) { cf_log_err(ci, "Failed adding %s alias", attr_auth_type->name); return -1; } diff --git a/src/modules/rlm_eap/types/rlm_eap_mschapv2/rlm_eap_mschapv2.c b/src/modules/rlm_eap/types/rlm_eap_mschapv2/rlm_eap_mschapv2.c index a76ab5bc453..32cae852801 100644 --- a/src/modules/rlm_eap/types/rlm_eap_mschapv2/rlm_eap_mschapv2.c +++ b/src/modules/rlm_eap/types/rlm_eap_mschapv2/rlm_eap_mschapv2.c @@ -134,7 +134,7 @@ static int auth_type_parse(UNUSED TALLOC_CTX *ctx, void *out, UNUSED void *paren { char const *auth_type = cf_pair_value(cf_item_to_pair(ci)); - if (fr_dict_enum_add_name_next(attr_auth_type, auth_type) < 0) { + if (fr_dict_enum_add_name_next(fr_dict_attr_unconst(attr_auth_type), auth_type) < 0) { cf_log_err(ci, "Failed adding %s alias", attr_auth_type->name); return -1; } diff --git a/src/modules/rlm_eap/types/rlm_eap_ttls/ttls.c b/src/modules/rlm_eap/types/rlm_eap_ttls/ttls.c index 45cb3a4afdd..67bb9427c46 100644 --- a/src/modules/rlm_eap/types/rlm_eap_ttls/ttls.c +++ b/src/modules/rlm_eap/types/rlm_eap_ttls/ttls.c @@ -622,7 +622,7 @@ FR_CODE eap_ttls_process(REQUEST *request, eap_session_t *eap_session, tls_sessi * Add the tunneled attributes to the request request. */ fr_cursor_init(&cursor, &request->packet->vps); - if (eap_ttls_decode_pair(request->packet, &cursor, fr_dict_root(fr_dict_internal), + if (eap_ttls_decode_pair(request->packet, &cursor, fr_dict_root(fr_dict_internal()), data, data_len, tls_session->ssl) < 0) { RPEDEBUG("Decoding TTLS TLVs failed"); code = FR_CODE_ACCESS_REJECT; diff --git a/src/modules/rlm_mschap/rlm_mschap.c b/src/modules/rlm_mschap/rlm_mschap.c index 2456f5a30ee..504ee80c301 100644 --- a/src/modules/rlm_mschap/rlm_mschap.c +++ b/src/modules/rlm_mschap/rlm_mschap.c @@ -2188,7 +2188,7 @@ static int mod_bootstrap(void *instance, CONF_SECTION *conf) if (!name) name = cf_section_name1(conf); inst->name = name; - if (fr_dict_enum_add_name_next(attr_auth_type, inst->name) < 0) { + if (fr_dict_enum_add_name_next(fr_dict_attr_unconst(attr_auth_type), inst->name) < 0) { PERROR("Failed adding %s alias", attr_auth_type->name); return -1; } diff --git a/src/modules/rlm_opendirectory/rlm_opendirectory.c b/src/modules/rlm_opendirectory/rlm_opendirectory.c index f8e727d5aaa..330f9914cd3 100644 --- a/src/modules/rlm_opendirectory/rlm_opendirectory.c +++ b/src/modules/rlm_opendirectory/rlm_opendirectory.c @@ -517,7 +517,7 @@ static int mod_bootstrap(void *instance, CONF_SECTION *conf) inst->name = cf_section_name2(conf); if (!inst->name) inst->name = cf_section_name1(conf); - if (fr_dict_enum_add_name_next(attr_auth_type, inst->name) < 0) { + if (fr_dict_enum_add_name_next(fr_dict_attr_unconst(attr_auth_type), inst->name) < 0) { PERROR("Failed adding %s alias", attr_auth_type->name); return -1; } diff --git a/src/modules/rlm_pap/rlm_pap.c b/src/modules/rlm_pap/rlm_pap.c index 1a785769238..3686dd55d8c 100644 --- a/src/modules/rlm_pap/rlm_pap.c +++ b/src/modules/rlm_pap/rlm_pap.c @@ -922,7 +922,7 @@ static int mod_bootstrap(void *instance, CONF_SECTION *conf) if (!name) name = cf_section_name1(conf); inst->name = name; - if (fr_dict_enum_add_name_next(attr_auth_type, inst->name) < 0) { + if (fr_dict_enum_add_name_next(fr_dict_attr_unconst(attr_auth_type), inst->name) < 0) { PERROR("Failed adding %s alias", attr_auth_type->name); return -1; } diff --git a/src/modules/rlm_winbind/rlm_winbind.c b/src/modules/rlm_winbind/rlm_winbind.c index 117c449503c..4492a6800a3 100644 --- a/src/modules/rlm_winbind/rlm_winbind.c +++ b/src/modules/rlm_winbind/rlm_winbind.c @@ -335,7 +335,7 @@ static int mod_bootstrap(void *instance, CONF_SECTION *conf) inst->name = cf_section_name2(conf); if (!inst->name) inst->name = cf_section_name1(conf); - if (fr_dict_enum_add_name_next(attr_auth_type, inst->name) < 0) { + if (fr_dict_enum_add_name_next(fr_dict_attr_unconst(attr_auth_type), inst->name) < 0) { PERROR("Failed adding %s alias", inst->name); return -1; } diff --git a/src/modules/rlm_yubikey/rlm_yubikey.c b/src/modules/rlm_yubikey/rlm_yubikey.c index 9c78ee989d9..7b04541c9a5 100644 --- a/src/modules/rlm_yubikey/rlm_yubikey.c +++ b/src/modules/rlm_yubikey/rlm_yubikey.c @@ -165,7 +165,7 @@ static int mod_bootstrap(void *instance, CONF_SECTION *conf) } #endif - if (fr_dict_enum_add_name_next(attr_auth_type, inst->name) < 0) { + if (fr_dict_enum_add_name_next(fr_dict_attr_unconst(attr_auth_type), inst->name) < 0) { PERROR("Failed adding %s alias", inst->name); return -1; } diff --git a/src/protocols/dhcpv4/base.c b/src/protocols/dhcpv4/base.c index 170f7e0b5af..1af8914c1e8 100644 --- a/src/protocols/dhcpv4/base.c +++ b/src/protocols/dhcpv4/base.c @@ -556,7 +556,8 @@ int fr_dhcpv4_global_init(void) } value.vb_uint8 = i; - if (fr_dict_enum_add_name(attr_dhcp_parameter_request_list, attr->name, &value, true, false) < 0) { + if (fr_dict_enum_add_name(fr_dict_attr_unconst(attr_dhcp_parameter_request_list), + attr->name, &value, true, false) < 0) { return -1; } } diff --git a/src/protocols/dhcpv6/base.c b/src/protocols/dhcpv6/base.c index 6a86875444a..feec96c4eaf 100644 --- a/src/protocols/dhcpv6/base.c +++ b/src/protocols/dhcpv6/base.c @@ -466,7 +466,8 @@ int fr_dhcpv6_global_init(void) value.vb_uint16 = child->attr; - if (fr_dict_enum_add_name(attr_option_request, child->name, &value, true, false) < 0) { + if (fr_dict_enum_add_name(fr_dict_attr_unconst(attr_option_request), + child->name, &value, true, false) < 0) { fr_dict_autofree(libfreeradius_dhcpv6_dict); return -1; }