/* * 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); }
/* * 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); }
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; }
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; }
/* * 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; }
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; }
/* * 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; }
/* * 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 }
/* * 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; }
/* * 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; }
/* * 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; }
/* * 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; }
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; }
/* * 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; }
/* * 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; }
/* * 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; }