/* Load a flat module list, as found inside an authtype{} block */ static void load_subcomponent_section(CONF_SECTION *cs, int comp, const char *filename) { int idx; indexed_modcallable *subcomp; modcallable *ml; DICT_VALUE *dval; static int meaningless_counter = 1; ml = compile_modgroup(comp, cs, filename); /* We must assign a numeric index to this subcomponent. For * auth, it is generated and placed in the dictionary by * new_sectiontype_value(). The others are just numbers that are pulled * out of thin air, and the names are neither put into the dictionary * nor checked for uniqueness, but all that could be fixed in a few * minutes, if anyone finds a real use for indexed config of * components other than auth. */ dval = NULL; if (comp==RLM_COMPONENT_AUTH) { dval = dict_valbyname(PW_AUTH_TYPE, cf_section_name2(cs)); } else if (comp == RLM_COMPONENT_AUTZ) { dval = dict_valbyname(PW_AUTZ_TYPE, cf_section_name2(cs)); } else if (comp == RLM_COMPONENT_ACCT) { dval = dict_valbyname(PW_ACCT_TYPE, cf_section_name2(cs)); } else if (comp == RLM_COMPONENT_SESS) { dval = dict_valbyname(PW_SESSION_TYPE, cf_section_name2(cs)); } else if (comp == RLM_COMPONENT_POST_AUTH) { dval = dict_valbyname(PW_POST_AUTH_TYPE, cf_section_name2(cs)); } if (dval) { idx = dval->value; } else { idx = meaningless_counter++; } subcomp = new_sublist(comp, idx); if (!subcomp) { radlog(L_ERR|L_CONS, "%s[%d] %s %s already configured - skipping", filename, cf_section_lineno(cs), subcomponent_names[comp], cf_section_name2(cs)); modcallable_free(&ml); return; } subcomp->modulelist = ml; }
static void load_component_section(CONF_SECTION *cs, int comp, const char *filename) { modcallable *this; CONF_ITEM *modref; int modreflineno; int idx; indexed_modcallable *subcomp; const char *modname; char *visiblename; for (modref=cf_item_find_next(cs, NULL); modref != NULL; modref=cf_item_find_next(cs, modref)) { if (cf_item_is_section(modref)) { CONF_SECTION *scs; scs = cf_itemtosection(modref); if (strcmp(cf_section_name1(scs), subcomponent_names[comp]) == 0) { load_subcomponent_section(scs, comp, filename); continue; } /* * Allow old names, too. */ if (strcmp(cf_section_name1(scs), old_subcomponent_names[comp]) == 0) { load_subcomponent_section(scs, comp, filename); continue; } modreflineno = cf_section_lineno(scs); } else { CONF_PAIR *cp; cp = cf_itemtopair(modref); modreflineno = cf_pair_lineno(cp); } this = compile_modsingle(comp, modref, filename, &modname); if (comp == RLM_COMPONENT_AUTH) { DICT_VALUE *dval; dval = dict_valbyname(PW_AUTH_TYPE, modname); rad_assert(dval != NULL); idx = dval->value; } else { /* See the comment in new_sublist() for explanation * of the special index 0 */ idx = 0; } subcomp = new_sublist(comp, idx); if (subcomp == NULL) { radlog(L_ERR|L_CONS, "%s %s %s already configured - skipping", filename, subcomponent_names[comp], modname); modcallable_free(&this); continue; } /* If subcomp->modulelist is NULL, add_to_modcallable will * create it */ visiblename = cf_section_name2(cs); if (visiblename == NULL) visiblename = cf_section_name1(cs); add_to_modcallable(&subcomp->modulelist, this, comp, visiblename); } }
/* * Find a module instance. */ module_instance_t *find_module_instance(const char *instname) { CONF_SECTION *cs, *inst_cs; const char *name1, *name2; module_instance_t *node, **last; char module_name[256]; /* * Look through the global module instance list for the * named module. */ last = &module_instance_list; for (node = module_instance_list; node != NULL; node = node->next) { /* * Found the named instance. Return it. */ if (strcmp(node->name, instname) == 0) return node; /* * Keep a pointer to the last entry to update... */ last = &node->next; } /* * Instance doesn't exist yet. Try to find the * corresponding configuration section and create it. */ /* * Look for the 'modules' configuration section. */ cs = cf_section_find("modules"); if (cs == NULL) { radlog(L_ERR|L_CONS, "ERROR: Cannot find a 'modules' section in the configuration file.\n"); return NULL; } /* * Module instances are declared in the modules{} block * and referenced later by their name, which is the * name2 from the config section, or name1 if there was * no name2. */ name1 = name2 = NULL; for(inst_cs=cf_subsection_find_next(cs, NULL, NULL); inst_cs != NULL; inst_cs=cf_subsection_find_next(cs, inst_cs, NULL)) { name1 = cf_section_name1(inst_cs); name2 = cf_section_name2(inst_cs); if ( (name2 && !strcmp(name2, instname)) || (!name2 && !strcmp(name1, instname)) ) break; } if (inst_cs == NULL) { radlog(L_ERR|L_CONS, "ERROR: Cannot find a configuration entry for module \"%s\".\n", instname); return NULL; } /* * Found the configuration entry. */ node = rad_malloc(sizeof(*node)); node->next = NULL; node->insthandle = NULL; /* * Link to the module by name: rlm_FOO-major.minor */ if (strncmp(name1, "rlm_", 4)) { #if 0 snprintf(module_name, sizeof(module_name), "rlm_%s-%d.%d", name1, RADIUSD_MAJOR_VERSION, RADIUSD_MINOR_VERSION); #else snprintf(module_name, sizeof(module_name), "rlm_%s", name1); #endif } else { strNcpy(module_name, name1, sizeof(module_name)); } /* * FIXME: "radiusd.conf" is wrong here; must find cf filename */ node->entry = linkto_module(module_name, "radiusd.conf", cf_section_lineno(inst_cs)); if (!node->entry) { free(node); /* linkto_module logs any errors */ return NULL; } /* * Call the module's instantiation routine. */ if ((node->entry->module->instantiate) && ((node->entry->module->instantiate)(inst_cs, &node->insthandle) < 0)) { radlog(L_ERR|L_CONS, "radiusd.conf[%d]: %s: Module instantiation failed.\n", cf_section_lineno(inst_cs), instname); free(node); return NULL; } /* * We're done. Fill in the rest of the data structure, * and link it to the module instance list. */ strNcpy(node->name, instname, sizeof(node->name)); #if HAVE_PTHREAD_H /* * If we're threaded, check if the module is thread-safe. * * If it isn't, we create a mutex. */ if ((node->entry->module->type & RLM_TYPE_THREAD_UNSAFE) != 0) { node->mutex = (pthread_mutex_t *) rad_malloc(sizeof(pthread_mutex_t)); /* * Initialize the mutex. */ pthread_mutex_init(node->mutex, NULL); } else { /* * The module is thread-safe. Don't give it a mutex. */ node->mutex = NULL; } #endif *last = node; DEBUG("Module: Instantiated %s (%s) ", name1, node->name); return node; }
/* * Apply a subsection to a request. * Returns permit/deny/error. */ static int apply_subsection(rlm_protocol_filter_t *inst, REQUEST *request, CONF_SECTION *cs, const char *name) { int sense; CONF_PAIR *cp; const char *value; char keybuf[256]; DEBUG2(" rlm_protocol_filter: Found subsection %s", name); cp = cf_pair_find(cs, "key"); if (!cp) { radlog(L_ERR, "rlm_protocol_filter: %s[%d]: No key defined in subsection %s", inst->filename, cf_section_lineno(cs), name); return RLM_MODULE_FAIL; } radius_xlat(keybuf, sizeof(keybuf), cf_pair_value(cp), request, NULL); if (!*keybuf) { DEBUG2(" rlm_protocol_filter: %s[%d]: subsection %s, key is empty, doing nothing.", inst->filename, cf_section_lineno(cs), name); return RLM_MODULE_NOOP; } DEBUG2(" rlm_protocol_filter: %s[%d]: subsection %s, using key %s", inst->filename, cf_section_lineno(cs), name, keybuf); /* * And repeat some of the above code. */ cp = cf_pair_find(cs, keybuf); if (!cp) { CONF_SECTION *subcs; /* * Maybe it has a subsection, too. */ subcs = cf_section_sub_find(cs, keybuf); if (subcs) { return apply_subsection(inst, request, subcs, keybuf); } /* it was a subsection */ DEBUG2(" rlm_protocol_filter: %s[%d]: subsection %s, rule not found, doing nothing.", inst->filename, cf_section_lineno(cs), name); return RLM_MODULE_NOOP; } value = cf_pair_value(cp); sense = str2sense(value); if (sense < 0) { radlog(L_ERR, "rlm_protocol_filter: %s[%d]: Unknwn directive %s", inst->filename, cf_pair_lineno(cp), value); return RLM_MODULE_FAIL; } if (!sense) return RLM_MODULE_REJECT; return RLM_MODULE_OK; }