示例#1
0
/*
 *	Free a module instance.
 */
static void module_instance_free(void *data)
{
	module_instance_t *this = data;

	module_instance_free_old(this->cs, this, time(NULL) + 100);

#ifdef HAVE_PTHREAD_H
	if (this->mutex) {
		/*
		 *	FIXME
		 *	The mutex MIGHT be locked...
		 *	we'll check for that later, I guess.
		 */
		pthread_mutex_destroy(this->mutex);
		talloc_free(this->mutex);
	}
#endif

	/*
	 *	Remove any registered paircompares.
	 */
	paircompare_unregister_instance(this->insthandle);

	xlat_unregister(this->name, NULL, this->insthandle);

#ifndef NDEBUG
	memset(this, 0, sizeof(*this));
#endif
	talloc_free(this);
}
示例#2
0
/*
 *	Free a module instance.
 */
static void module_instance_free(void *data)
{
	module_instance_t *node = talloc_get_type_abort(data, module_instance_t);

	module_instance_free_old(node->cs, node, time(NULL) + 100);

#ifdef HAVE_PTHREAD_H
	if (node->mutex) {
		/*
		 *	FIXME
		 *	The mutex MIGHT be locked...
		 *	we'll check for that later, I guess.
		 */
		pthread_mutex_destroy(node->mutex);
	}
#endif

	xlat_unregister(node->insthandle, node->name, NULL);

	/*
	 *	Remove all xlat's registered to module instance.
	 */
	if (node->insthandle) {
		/*
		 *	Remove any registered paircompares.
		 */
		paircompare_unregister_instance(node->insthandle);

		xlat_unregister_module(node->insthandle);
	}
	talloc_free(node);
}
示例#3
0
static int rlm_sql_detach(void *instance)
{
	rlm_sql_t *inst = instance;

	paircompare_unregister(PW_SQL_GROUP, sql_groupcmp);
	
	if (inst->config) {
		if (inst->pool) sql_poolfree(inst);

		if (inst->config->xlat_name) {
			xlat_unregister(inst->config->xlat_name, sql_xlat, instance);
		}
	}

	if (inst->handle) {
#if 0
		/*
		 *	FIXME: Call the modules 'destroy' function?
		 */
		lt_dlclose(inst->handle);	/* ignore any errors */
#endif
	}

	return 0;
}
示例#4
0
static int rlm_sql_detach(void *instance)
{
	SQL_INST *inst = instance;

	paircompare_unregister(PW_SQL_GROUP, sql_groupcmp);

	if (inst->config) {
		int i;

		if (inst->pool) sql_poolfree(inst);

		if (inst->config->xlat_name) {
			xlat_unregister(inst->config->xlat_name,(RAD_XLAT_FUNC)sql_xlat, instance);
			free(inst->config->xlat_name);
		}

		/*
		 *	Free up dynamically allocated string pointers.
		 */
		for (i = 0; module_config[i].name != NULL; i++) {
			char **p;
			if (module_config[i].type != PW_TYPE_STRING_PTR) {
				continue;
			}

			/*
			 *	Treat 'config' as an opaque array of bytes,
			 *	and take the offset into it.  There's a
			 *      (char*) pointer at that offset, and we want
			 *	to point to it.
			 */
			p = (char **) (((char *)inst->config) + module_config[i].offset);
			if (!*p) { /* nothing allocated */
				continue;
			}
			free(*p);
			*p = NULL;
		}
		/*
		 *	Catch multiple instances of the module.
		 */
		if (allowed_chars == inst->config->allowed_chars) {
			allowed_chars = NULL;
		}
		free(inst->config);
		inst->config = NULL;
	}

	if (inst->handle) {
#if 0
		/*
		 *	FIXME: Call the modules 'destroy' function?
		 */
		lt_dlclose(inst->handle);	/* ignore any errors */
#endif
	}
	free(inst);

	return 0;
}
示例#5
0
/*
 * Detach a instance free all ..
 */
static int mod_detach(void *instance)
{
	rlm_expr_t	*inst = instance;

	xlat_unregister(inst->xlat_name, expr_xlat, instance);
	pair_builtincompare_del();
	return 0;
}
示例#6
0
static int mod_detach(void *instance)
{
	rlm_soh_t	*inst = instance;

	if (inst->xlat_name) {
		xlat_unregister(inst->xlat_name, soh_xlat, instance);
	}
	return 0;
}
示例#7
0
/*
 * Detach a instance free all ..
 */
static int expr_detach(void *instance)
{
	rlm_expr_t	*inst = instance;

	xlat_unregister(inst->xlat_name, expr_xlat);
	free(inst->xlat_name);

	free(inst);
	return 0;
}
示例#8
0
/*
 *	deinstantiate module, free all memory allocated during
 *	mschap_instantiate()
 */
static int mschap_detach(void *instance){
#define inst ((rlm_mschap_t *)instance)
	if (inst->xlat_name) {
		xlat_unregister(inst->xlat_name, mschap_xlat);
		free(inst->xlat_name);
	}
	free(instance);
	return 0;
#undef inst
}
示例#9
0
/*
 *	Only free memory we allocated.  The strings allocated via
 *	cf_section_parse() do not need to be freed.
 */
static int redis_detach(void *instance)
{
	REDIS_INST *inst = instance;

	fr_connection_pool_delete(inst->pool);

	if (inst->xlat_name) {
		xlat_unregister(inst->xlat_name, redis_xlat, instance);
	}

	return 0;
}
示例#10
0
/*
 *	Detach an instance and free it's data.
 */
static int exec_detach(void *instance)
{
	rlm_exec_t	*inst = instance;

	if (inst->xlat_name) {
		xlat_unregister(inst->xlat_name, exec_xlat, instance);
		free(inst->xlat_name);
	}

	free(inst);
	return 0;
}
示例#11
0
/*
 *	Only free memory we allocated.  The strings allocated via
 *	cf_section_parse() do not need to be freed.
 */
static int mod_detach(void *instance)
{
	rlm_rest_t *inst = instance;

	fr_connection_pool_delete(inst->conn_pool);

	xlat_unregister(inst->xlat_name, rest_xlat, instance);

	/* Free any memory used by libcurl */
	rest_cleanup();

	return 0;
}
示例#12
0
/*
 *	Only free memory we allocated.  The strings allocated via
 *	cf_section_parse() do not need to be freed.
 */
static int redis_detach(void *instance)
{
	REDIS_INST *inst = instance;

	redis_poolfree(inst);

	if (inst->xlat_name) {
		xlat_unregister(inst->xlat_name, (RAD_XLAT_FUNC)redis_xlat);
		free(inst->xlat_name);
	}
	free(inst->xlat_name);
	free(inst);

	return 0;
}
示例#13
0
static int rlm_redisn_detach(void *instance)
{
	REDIS_INST *inst = instance;
	paircompare_unregister(PW_REDIS_GROUP, redisn_groupcmp);

	int i;
	
	if (inst->redisnpool) {
	  redisn_poolfree(inst);
	}

	if (inst->xlat_name) {
	  xlat_unregister(inst->xlat_name,(RAD_XLAT_FUNC)redisn_xlat, instance);
	  free(inst->xlat_name);
	}

	/*
	 *	Free up dynamically allocated string pointers.
	 */
	for (i = 0; module_config[i].name != NULL; i++) {
	  char **p;
	  if (module_config[i].type != PW_TYPE_STRING_PTR) {
	    continue;
	  }
	  
	  /*
	   *	Treat 'config' as an opaque array of bytes,
	   *	and take the offset into it.  There's a
	   *      (char*) pointer at that offset, and we want
	   *	to point to it.
	   */
	  p = (char **) (((char *)inst) + module_config[i].offset);
	  if (!*p) { /* nothing allocated */
	    continue;
	  }
	  free(*p);
	  *p = NULL;
	}
	/*
	 *	Catch multiple instances of the module.
	 */
	if (allowed_chars == inst->allowed_chars) {
	  allowed_chars = NULL;
	}

	if (inst->servers_count>0) {
	  if (inst->server_names) {
	    for(i=0;i<inst->servers_count;i++) {
	      if (inst->server_names[i])
		free(inst->server_names[i]);
	      if (inst->server_passwords[i])
		free(inst->server_passwords[i]);
	    }
	    free(inst->server_names);
	  }
	  if (inst->server_ports)
	    free(inst->server_ports);
	  if (inst->server_dbs)
	    free(inst->server_dbs);
	  if (inst->server_passwords)
	    free(inst->server_passwords);
	  if (inst->server_connect_afters)
	    free(inst->server_connect_afters);
	}	  
	
	free(inst);

	return 0;
}
示例#14
0
/*
 *	Only free memory we allocated.  The strings allocated via
 *	cf_section_parse() do not need to be freed.
 */
static int mod_detach(void *instance)
{
    xlat_unregister("dhcp_options", dhcp_options_xlat, instance);
    return 0;
}
示例#15
0
/*
 * Detach a instance give a chance to a module to make some internal setup ...
 */
static int perl_detach(void *instance)
{
	PERL_INST	*inst = (PERL_INST *) instance;
	int 		exitstatus=0,count=0;

#ifdef USE_ITHREADS
	POOL_HANDLE	*handle, *tmp, *tmp2;

	MUTEX_LOCK(&inst->perl_pool->mutex);
	inst->perl_pool->detach = yes;
	MUTEX_UNLOCK(&inst->perl_pool->mutex);

	for (handle = inst->perl_pool->head; handle != NULL; handle = handle->next) {

		radlog(L_DBG,"Detach perl 0x%lx", (unsigned long) handle->clone);
		/*
		 * Wait until clone becomes idle
		 */
		MUTEX_LOCK(&handle->lock);

		/*
		 * Give a clones chance to run detach function
		 */
		{
		dTHXa(handle->clone);
		PERL_SET_CONTEXT(handle->clone);
		{
		dSP; ENTER; SAVETMPS; PUSHMARK(SP);
		count = call_pv(inst->func_detach, G_SCALAR | G_EVAL );
		SPAGAIN;

		if (count == 1) {
			exitstatus = POPi;
			/*
			 * FIXME: bug in perl
			 *
			 */
			if (exitstatus >= 100 || exitstatus < 0) {
				exitstatus = RLM_MODULE_FAIL;
			}
		}
		PUTBACK;
		FREETMPS;
		LEAVE;
		radlog(L_DBG,"detach at 0x%lx returned status %d",
				(unsigned long) handle->clone, exitstatus);
		}
		}
		MUTEX_UNLOCK(&handle->lock);
	}
	/*
	 * Free handles
	 */

	for (tmp = inst->perl_pool->head; tmp !=NULL  ; tmp = tmp2) {
		tmp2 = tmp->next;
		radlog(L_DBG,"rlm_perl:: Destroy perl");
		rlm_perl_destruct(tmp->clone);
		delete_pool_handle(tmp,inst);
	}

	{
	dTHXa(inst->perl);
#endif /* USE_ITHREADS */
	PERL_SET_CONTEXT(inst->perl);
	{
	dSP; ENTER; SAVETMPS;
	PUSHMARK(SP);

	count = call_pv(inst->func_detach, G_SCALAR | G_EVAL );
	SPAGAIN;

	if (count == 1) {
		exitstatus = POPi;
		if (exitstatus >= 100 || exitstatus < 0) {
			exitstatus = RLM_MODULE_FAIL;
		}
	}
	PUTBACK;
	FREETMPS;
	LEAVE;
	}
#ifdef USE_ITHREADS
	}
#endif

	xlat_unregister(inst->xlat_name, perl_xlat);
	free(inst->xlat_name);

	if (inst->func_authorize) free(inst->func_authorize);
	if (inst->func_authenticate) free(inst->func_authenticate);
	if (inst->func_accounting) free(inst->func_accounting);
	if (inst->func_preacct) free(inst->func_preacct);
	if (inst->func_checksimul) free(inst->func_checksimul);
	if (inst->func_pre_proxy) free(inst->func_pre_proxy);
	if (inst->func_post_proxy) free(inst->func_post_proxy);
	if (inst->func_post_auth) free(inst->func_post_auth);
	if (inst->func_detach) free(inst->func_detach);

#ifdef USE_ITHREADS
	free(inst->perl_pool->head);
	free(inst->perl_pool->tail);
	MUTEX_DESTROY(&inst->perl_pool->mutex);
	free(inst->perl_pool);
	rlm_perl_destruct(inst->perl);
#else
	perl_destruct(inst->perl);
	perl_free(inst->perl);
#endif

	free(inst);
	return exitstatus;
}
示例#16
0
/*
 *	The main guy.
 */
int main(int argc, char *argv[])
{
	int rcode = EXIT_SUCCESS;
	int argval;
	const char *input_file = NULL;
	const char *output_file = NULL;
	const char *filter_file = NULL;
	FILE *fp;
	REQUEST *request = NULL;
	VALUE_PAIR *vp;
	VALUE_PAIR *filter_vps = NULL;
	bool xlat_only = false;
	fr_state_tree_t *state = NULL;

	fr_talloc_fault_setup();

	/*
	 *	If the server was built with debugging enabled always install
	 *	the basic fatal signal handlers.
	 */
#ifndef NDEBUG
	if (fr_fault_setup(getenv("PANIC_ACTION"), argv[0]) < 0) {
		fr_perror("unittest");
		exit(EXIT_FAILURE);
	}
#endif

	rad_debug_lvl = 0;
	set_radius_dir(NULL, RADIUS_DIR);

	/*
	 *	Ensure that the configuration is initialized.
	 */
	memset(&main_config, 0, sizeof(main_config));
	main_config.name = "unittest";

	/*
	 *	The tests should have only IPs, not host names.
	 */
	fr_hostname_lookups = false;

	/*
	 *	We always log to stdout.
	 */
	fr_log_fp = stdout;
	default_log.dst = L_DST_STDOUT;
	default_log.fd = STDOUT_FILENO;

	/*  Process the options.  */
	while ((argval = getopt(argc, argv, "d:D:f:hi:mMn:o:O:xX")) != EOF) {

		switch (argval) {
			case 'd':
				set_radius_dir(NULL, optarg);
				break;

			case 'D':
				main_config.dictionary_dir = talloc_typed_strdup(NULL, optarg);
				break;

			case 'f':
				filter_file = optarg;
				break;

			case 'h':
				usage(0);
				break;

			case 'i':
				input_file = optarg;
				break;

			case 'm':
				main_config.debug_memory = true;
				break;

			case 'M':
				memory_report = true;
				main_config.debug_memory = true;
				break;

			case 'n':
				main_config.name = optarg;
				break;

			case 'o':
				output_file = optarg;
				break;

			case 'O':
				if (strcmp(optarg, "xlat_only") == 0) {
					xlat_only = true;
					break;
				}

				fprintf(stderr, "Unknown option '%s'\n", optarg);
				exit(EXIT_FAILURE);

			case 'X':
				rad_debug_lvl += 2;
				main_config.log_auth = true;
				main_config.log_auth_badpass = true;
				main_config.log_auth_goodpass = true;
				break;

			case 'x':
				rad_debug_lvl++;
				break;

			default:
				usage(1);
				break;
		}
	}

	if (rad_debug_lvl) version_print();
	fr_debug_lvl = rad_debug_lvl;

	/*
	 *	Mismatch between the binary and the libraries it depends on
	 */
	if (fr_check_lib_magic(RADIUSD_MAGIC_NUMBER) < 0) {
		fr_perror("%s", main_config.name);
		exit(EXIT_FAILURE);
	}

	/*
	 *  Initialising OpenSSL once, here, is safer than having individual modules do it.
	 */
#ifdef HAVE_OPENSSL_CRYPTO_H
	if (tls_global_init() < 0) {
		rcode = EXIT_FAILURE;
		goto finish;
	}
#endif

	if (xlat_register(NULL, "poke", xlat_poke, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN) < 0) {
		rcode = EXIT_FAILURE;
		goto finish;
	}

	if (map_proc_register(NULL, "test-fail", mod_map_proc, NULL,  NULL, 0) < 0) {
		rcode = EXIT_FAILURE;
		goto finish;
	}


	/*  Read the configuration files, BEFORE doing anything else.  */
	if (main_config_init() < 0) {
	exit_failure:
		rcode = EXIT_FAILURE;
		goto finish;
	}

	/*
	 *	Setup dummy virtual server
	 */
	cf_section_add(main_config.config, cf_section_alloc(main_config.config, "server", "unit_test"));

	/*
	 *	Initialize Auth-Type, etc. in the virtual servers
	 *	before loading the modules.  Some modules need those
	 *	to be defined.
	 */
	if (virtual_servers_bootstrap(main_config.config) < 0) goto exit_failure;

	/*
	 *	Bootstrap the modules.  This links to them, and runs
	 *	their "bootstrap" routines.
	 *
	 *	After this step, all dynamic attributes, xlats, etc. are defined.
	 */
	if (modules_bootstrap(main_config.config) < 0) exit(EXIT_FAILURE);

	/*
	 *	Load the modules
	 */
	if (modules_init(main_config.config) < 0) goto exit_failure;

	/*
	 *	And then load the virtual servers.
	 */
	if (virtual_servers_init(main_config.config) < 0) goto exit_failure;

	state = fr_state_tree_init(NULL, main_config.max_requests * 2, 10);

	/*
	 *  Set the panic action (if required)
	 */
	{
		char const *panic_action = NULL;

		panic_action = getenv("PANIC_ACTION");
		if (!panic_action) panic_action = main_config.panic_action;

		if (panic_action && (fr_fault_setup(panic_action, argv[0]) < 0)) {
			fr_perror("%s", main_config.name);
			exit(EXIT_FAILURE);
		}
	}

	setlinebuf(stdout); /* unbuffered output */

	if (!input_file || (strcmp(input_file, "-") == 0)) {
		fp = stdin;
	} else {
		fp = fopen(input_file, "r");
		if (!fp) {
			fprintf(stderr, "Failed reading %s: %s\n",
				input_file, strerror(errno));
			rcode = EXIT_FAILURE;
			goto finish;
		}
	}

	/*
	 *	For simplicity, read xlat's.
	 */
	if (xlat_only) {
		if (!do_xlats(input_file, fp)) rcode = EXIT_FAILURE;
		if (input_file) fclose(fp);
		goto finish;
	}

	/*
	 *	Grab the VPs from stdin, or from the file.
	 */
	request = request_setup(fp);
	if (!request) {
		fprintf(stderr, "Failed reading input: %s\n", fr_strerror());
		rcode = EXIT_FAILURE;
		goto finish;
	}

	/*
	 *	No filter file, OR there's no more input, OR we're
	 *	reading from a file, and it's different from the
	 *	filter file.
	 */
	if (!filter_file || filedone ||
	    ((input_file != NULL) && (strcmp(filter_file, input_file) != 0))) {
		if (output_file) {
			fclose(fp);
			fp = NULL;
		}
		filedone = false;
	}

	/*
	 *	There is a filter file.  If necessary, open it.  If we
	 *	already are reading it via "input_file", then we don't
	 *	need to re-open it.
	 */
	if (filter_file) {
		if (!fp) {
			fp = fopen(filter_file, "r");
			if (!fp) {
				fprintf(stderr, "Failed reading %s: %s\n", filter_file, strerror(errno));
				rcode = EXIT_FAILURE;
				goto finish;
			}
		}


		if (fr_pair_list_afrom_file(request, &filter_vps, fp, &filedone) < 0) {
			fprintf(stderr, "Failed reading attributes from %s: %s\n",
				filter_file, fr_strerror());
			rcode = EXIT_FAILURE;
			goto finish;
		}

		/*
		 *	FIXME: loop over input packets.
		 */
		fclose(fp);
	}

	rad_virtual_server(request);

	if (!output_file || (strcmp(output_file, "-") == 0)) {
		fp = stdout;
	} else {
		fp = fopen(output_file, "w");
		if (!fp) {
			fprintf(stderr, "Failed writing %s: %s\n",
				output_file, strerror(errno));
			exit(EXIT_FAILURE);
		}
	}

	print_packet(fp, request->reply);

	if (output_file) fclose(fp);

	/*
	 *	Update the list with the response type.
	 */
	vp = radius_pair_create(request->reply, &request->reply->vps,
			       PW_RESPONSE_PACKET_TYPE, 0);
	vp->vp_integer = request->reply->code;

	{
		VALUE_PAIR const *failed[2];

		if (filter_vps && !fr_pair_validate(failed, filter_vps, request->reply->vps)) {
			fr_pair_validate_debug(request, failed);
			fr_perror("Output file %s does not match attributes in filter %s (%s)",
				  output_file ? output_file : input_file, filter_file, fr_strerror());
			rcode = EXIT_FAILURE;
			goto finish;
		}
	}

	INFO("Exiting normally");

finish:
	talloc_free(request);
	talloc_free(state);

	/*
	 *	Free the configuration items.
	 */
	main_config_free();

	/*
	 *	Detach any modules.
	 */
	modules_free();

	xlat_unregister(NULL, "poke", xlat_poke);

	xlat_free();		/* modules may have xlat's */

	if (memory_report) {
		INFO("Allocated memory at time of report:");
		fr_log_talloc_report(NULL);
	}

	return rcode;
}
/*
 * Detach a instance give a chance to a module to make some internal setup ...
 */
static int perl_detach(void *instance)
{
	PERL_INST	*inst = (PERL_INST *) instance;
	int 		exitstatus = 0, count = 0;

#if 0
	/*
	 *	FIXME: Call this in the destruct function?
	 */
		{
		dTHXa(handle->clone);
		PERL_SET_CONTEXT(handle->clone);
		{
		dSP; ENTER; SAVETMPS; PUSHMARK(SP);
		count = call_pv(inst->func_detach, G_SCALAR | G_EVAL );
		SPAGAIN;

		if (count == 1) {
			exitstatus = POPi;
			/*
			 * FIXME: bug in perl
			 *
			 */
			if (exitstatus >= 100 || exitstatus < 0) {
				exitstatus = RLM_MODULE_FAIL;
			}
		}
		PUTBACK;
		FREETMPS;
		LEAVE;
		}
		}
#endif

		if (inst->func_detach) {
	dTHXa(inst->perl);
	PERL_SET_CONTEXT(inst->perl);
	{
	dSP; ENTER; SAVETMPS;
	PUSHMARK(SP);

	count = call_pv(inst->func_detach, G_SCALAR | G_EVAL );
	SPAGAIN;

	if (count == 1) {
		exitstatus = POPi;
		if (exitstatus >= 100 || exitstatus < 0) {
			exitstatus = RLM_MODULE_FAIL;
		}
	}
	PUTBACK;
	FREETMPS;
	LEAVE;
	}
	}

	xlat_unregister(inst->xlat_name, perl_xlat, instance);
	free(inst->xlat_name);

#ifdef USE_ITHREADS
	rlm_perl_destruct(inst->perl);
	pthread_mutex_destroy(&inst->clone_mutex);
#else
	perl_destruct(inst->perl);
	perl_free(inst->perl);
#endif

        PERL_SYS_TERM();
	free(inst);
	return exitstatus;
}