⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modules.c

📁 radius server在linux下的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * modules.c	Radius module support. * * Version:	$Id: modules.c,v 1.86.2.1 2004/11/11 01:21:10 aland Exp $ * *   This program is free software; you can redistribute it and/or modify *   it under the terms of the GNU General Public License as published by *   the Free Software Foundation; either version 2 of the License, or *   (at your option) any later version. * *   This program is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with this program; if not, write to the Free Software *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * Copyright 2003  The FreeRADIUS server project * Copyright 2000  Alan DeKok <aland@ox.org> * Copyright 2000  Alan Curry <pacman@world.std.com> */static const char rcsid[] = "$Id: modules.c,v 1.86.2.1 2004/11/11 01:21:10 aland Exp $";#include "autoconf.h"#include "libradius.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include "radiusd.h"#include "modpriv.h"#include "modules.h"#include "modcall.h"#include "conffile.h"#include "ltdl.h"#include "rad_assert.h"/* *	Internal list of all of the modules we have loaded. */static module_list_t *module_list = NULL;/* *	Internal list of each module instance. */static module_instance_t *module_instance_list = NULL;typedef struct indexed_modcallable {	struct indexed_modcallable *next;	int idx;	modcallable *modulelist;} indexed_modcallable;/* *	For each component, keep an ordered list of ones to call. */static indexed_modcallable *components[RLM_COMPONENT_COUNT];/* *	The component names. * *	Hmm... we probably should be getting these from the configuration *	file, too. */const char *component_names[RLM_COMPONENT_COUNT] ={	"authenticate",	"authorize",	"preacct",	"accounting",	"session",	"pre-proxy",	"post-proxy",	"post-auth"};/* *	Delete ASAP. */static const char *old_subcomponent_names[RLM_COMPONENT_COUNT] ={	"authtype",	"autztype",	"preacctype",	"acctype",	"sesstype",	"pre-proxytype",	"post-proxytype",	"post-authtype"};static const char *subcomponent_names[RLM_COMPONENT_COUNT] ={	"Auth-Type",	"Autz-Type",	"Pre-Acct-Type",	"Acct-Type",	"Session-Type",	"Pre-Proxy-Type",	"Post-Proxy-Type",	"Post-Auth-Type"};static void indexed_modcallable_free(indexed_modcallable **cf){	indexed_modcallable	*c, *next;	c = *cf;	while (c) {		next = c->next;		modcallable_free(&c->modulelist);		free(c);		c = next;	}	*cf = NULL;}static void instance_list_free(module_instance_t **i){	module_instance_t	*c, *next;	c = *i;	while (c) {		next = c->next;		if(c->entry->module->detach)			(c->entry->module->detach)(c->insthandle);#ifdef HAVE_PTHREAD_H		if (c->mutex) {			/*			 *	FIXME			 *	The mutex MIGHT be locked...			 *	we'll check for that later, I guess.			 */			pthread_mutex_destroy(c->mutex);			free(c->mutex);		}#endif		free(c);		c = next;	}	*i = NULL;}/* *	Remove all of the modules. */int detach_modules(void){	module_list_t *ml, *next;	int i;	/*	 *	Delete the internal component pointers.	 */	for (i = 0; i < RLM_COMPONENT_COUNT; i++) {		indexed_modcallable_free(&components[i]);	}	instance_list_free(&module_instance_list);	ml = module_list;	while (ml) {		next = ml->next;		if (ml->module->destroy)			(ml->module->destroy)();		lt_dlclose(ml->handle);	/* ignore any errors */		free(ml);		ml = next;	}	module_list = NULL;	return 0;}/* *	Find a module on disk or in memory, and link to it. */static module_list_t *linkto_module(const char *module_name,		const char *cffilename, int cflineno){	module_list_t *node;	lt_dlhandle handle;	char module_struct[256];	char *p;	/*	 *	Look through the global module library list for the	 *	named module.	 */	for (node = module_list; node != NULL; node = node->next) {		/*		 *	Found the named module.  Return it.		 */		if (strcmp(node->name, module_name) == 0)			return node;	}	/*	 *	Keep the handle around so we can dlclose() it.	 */	handle = lt_dlopenext(module_name);	if (handle == NULL) {		radlog(L_ERR|L_CONS, "%s[%d] Failed to link to module '%s':"				" %s\n", cffilename, cflineno, module_name, lt_dlerror());		return NULL;	}	/* make room for the module type */	node = (module_list_t *) rad_malloc(sizeof(module_list_t));	/* fill in the module structure */	node->next = NULL;	node->handle = handle;	strNcpy(node->name, module_name, sizeof(node->name));	/*	 *	Link to the module's rlm_FOO{} module structure.	 */	/* module_name has the version embedded; strip it. */	strcpy(module_struct, module_name);	p = strrchr(module_struct, '-');	if (p)		*p = '\0';	node->module = (module_t *) lt_dlsym(node->handle, module_struct);	if (!node->module) {		radlog(L_ERR|L_CONS, "%s[%d] Failed linking to "				"%s structure in %s: %s\n",				cffilename, cflineno,				module_name, cffilename, lt_dlerror());		lt_dlclose(node->handle);	/* ignore any errors */		free(node);		return NULL;	}	/* call the modules initialization */	if (node->module->init && (node->module->init)() < 0) {		radlog(L_ERR|L_CONS, "%s[%d] Module initialization failed.\n",				cffilename, cflineno);		lt_dlclose(node->handle);	/* ignore any errors */		free(node);		return NULL;	}	DEBUG("Module: Loaded %s ", node->module->name);	node->next = module_list;	module_list = node;	return node;}/* *	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));#ifdef 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;}static indexed_modcallable *lookup_by_index(indexed_modcallable *head, int idx){	indexed_modcallable *p;	for (p = head; p != NULL; p = p->next) {		if( p->idx == idx)			return p;	}	return NULL;}static indexed_modcallable *new_sublist(int comp, int idx){	indexed_modcallable **head = &components[comp];	indexed_modcallable *node = *head;	indexed_modcallable **last = head;	while (node) {		/* It is an error to try to create a sublist that already		 * exists. It would almost certainly be caused by accidental		 * duplication in the config file.		 *		 * index 0 is the exception, because it is used when we want		 * to collect _all_ listed modules under a single index by		 * default, which is currently the case in all components		 * except authenticate. */		if (node->idx == idx) {			if (idx == 0)				return node;			else				return NULL;		}		last = &node->next;		node = node->next;	}	node = rad_malloc(sizeof *node);	node->next = NULL;	node->modulelist = NULL;	node->idx = idx;	*last = node;	return node;}static int indexed_modcall(int comp, int idx, REQUEST *request){	indexed_modcallable *this;	this = lookup_by_index(components[comp], idx);	if (!this) {		if (idx != 0) DEBUG2("  ERROR: Unknown value specified for %s.  Cannot perform requested action.",				     subcomponent_names[comp]);		/* Return a default value appropriate for the component */		switch(comp) {			case RLM_COMPONENT_AUTZ:    return RLM_MODULE_NOTFOUND;			case RLM_COMPONENT_AUTH:    return RLM_MODULE_REJECT;			case RLM_COMPONENT_PREACCT: return RLM_MODULE_NOOP;			case RLM_COMPONENT_ACCT:    return RLM_MODULE_NOOP;			case RLM_COMPONENT_SESS:    return RLM_MODULE_FAIL;			case RLM_COMPONENT_PRE_PROXY:  return RLM_MODULE_NOOP;			case RLM_COMPONENT_POST_PROXY: return RLM_MODULE_NOOP;			case RLM_COMPONENT_POST_AUTH:  return RLM_MODULE_NOOP;			default:                    return RLM_MODULE_FAIL;		}	}	DEBUG2("  Processing the %s section of radiusd.conf",	       component_names[comp]);	return modcall(comp, this->modulelist, request);}/* 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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -