Beispiel #1
0
/* 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;
}
Beispiel #2
0
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);
	}
}
Beispiel #3
0
/*
 *	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;
}