int DBUtil::Init(const char* conffile, const char* dbsection, const char* logsection) { SQL_INST* sqlinst = NULL; // free previous instance first Free(); // init sql module rlm_sql_init(); // read conf file CONF_SECTION *conf; conf = conf_read(__FILE__, __LINE__, conffile, NULL); if(!conf) { radlog(L_CONS|L_ERROR, "[DBUtil::DBUtil] can not read '%s'", conffile); rlm_sql_destroy(); return -1; } // get db section CONF_SECTION* sqlconf = cf_section_sub_find(conf, dbsection); if(!sqlconf) { radlog(L_CONS|L_ERROR, "[DBUtil::DBUtil] can not find sub section '%s'", dbsection); cf_section_free(&conf); rlm_sql_destroy(); return -1; } // get log section if present CONF_SECTION* logconf = NULL; if(logsection) { logconf = cf_section_sub_find(conf, logsection); if(!logconf) { radlog(L_CONS|L_WARN, "[DBUtil::DBUtil] can not find sub section '%s', " "no logging parameters would be applied to rlm_sql. This may be " "a problem when using rlm_sql with dynamic loading sql_drivers", logsection); } } // get sql instance if(rlm_sql_instantiate(sqlconf, &sqlinst, logconf) != 0) { radlog(L_CONS|L_ERROR, "[DBUtil::DBUtil] can not instantiate sql instance"); cf_section_free(&conf); rlm_sql_destroy(); return -1; } // free conf section cf_section_free(&conf); dbHandle_ = sqlinst; return 0; }
/* * Free the configuration. Called only when the server is exiting. */ int free_mainconfig(void) { cached_config_t *cc, *next; virtual_servers_free(0); /* * Free all of the cached configurations. */ for (cc = cs_cache; cc != NULL; cc = next) { next = cc->next; cf_section_free(&cc->cs); free(cc); } /* * Clean up the configuration data * structures. */ realms_free(); listen_free(&mainconfig.listen); dict_free(); return 0; }
static int filter_detach(void *instance) { rlm_protocol_filter_t *inst = instance; if (inst->cs) cf_section_free(&(inst->cs)); free(instance); return 0; }
/* * Read config files. * * This function can ONLY be called from the main server process. */ int read_mainconfig(int reload) { const char *p = NULL; CONF_PAIR *cp; CONF_SECTION *cs; struct stat statbuf; cached_config_t *cc; char buffer[1024]; if (reload != 0) { radlog(L_ERR, "Reload is not implemented"); return -1; } if (stat(radius_dir, &statbuf) < 0) { radlog(L_ERR, "Errors reading %s: %s", radius_dir, strerror(errno)); return -1; } #ifdef S_IWOTH if ((statbuf.st_mode & S_IWOTH) != 0) { radlog(L_ERR, "Configuration directory %s is globally writable. Refusing to start due to insecure configuration.", radius_dir); return -1; } #endif #ifdef S_IROTH if (0 && (statbuf.st_mode & S_IROTH) != 0) { radlog(L_ERR, "Configuration directory %s is globally readable. Refusing to start due to insecure configuration.", radius_dir); return -1; } #endif radlog(L_INFO, "Starting - reading configuration files ..."); /* Read the configuration file */ snprintf(buffer, sizeof(buffer), "%.200s/%.50s.conf", radius_dir, mainconfig.name); if ((cs = cf_file_read(buffer)) == NULL) { radlog(L_ERR, "Errors reading or parsing %s", buffer); return -1; } /* * If there was no log destination set on the command line, * set it now. */ if (mainconfig.radlog_dest == RADLOG_NULL) { if (cf_section_parse(cs, NULL, serverdest_config) < 0) { fprintf(stderr, "radiusd: Error: Failed to parse log{} section.\n"); cf_section_free(&cs); return -1; } if (!radlog_dest) { fprintf(stderr, "radiusd: Error: No log destination specified.\n"); cf_section_free(&cs); return -1; } mainconfig.radlog_dest = fr_str2int(str2dest, radlog_dest, RADLOG_NUM_DEST); if (mainconfig.radlog_dest == RADLOG_NUM_DEST) { fprintf(stderr, "radiusd: Error: Unknown log_destination %s\n", radlog_dest); cf_section_free(&cs); return -1; } if (mainconfig.radlog_dest == RADLOG_SYSLOG) { /* * Make sure syslog_facility isn't NULL * before using it */ if (!syslog_facility) { fprintf(stderr, "radiusd: Error: Syslog chosen but no facility was specified\n"); cf_section_free(&cs); return -1; } mainconfig.syslog_facility = fr_str2int(syslog_str2fac, syslog_facility, -1); if (mainconfig.syslog_facility < 0) { fprintf(stderr, "radiusd: Error: Unknown syslog_facility %s\n", syslog_facility); cf_section_free(&cs); return -1; } #ifdef HAVE_SYSLOG_H /* * Call openlog only once, when the * program starts. */ openlog(progname, LOG_PID, mainconfig.syslog_facility); #endif } else if (mainconfig.radlog_dest == RADLOG_FILES) { if (!mainconfig.log_file) { fprintf(stderr, "radiusd: Error: Specified \"files\" as a log destination, but no log filename was given!\n"); cf_section_free(&cs); return -1; } } } #ifdef HAVE_SETUID /* * Switch users as early as possible. */ if (!switch_users(cs)) exit(1); #endif /* * Open the log file AFTER switching uid / gid. If we * did switch uid/gid, then the code in switch_users() * took care of setting the file permissions correctly. */ if ((mainconfig.radlog_dest == RADLOG_FILES) && (mainconfig.radlog_fd < 0)) { mainconfig.radlog_fd = open(mainconfig.log_file, O_WRONLY | O_APPEND | O_CREAT, 0640); if (mainconfig.radlog_fd < 0) { fprintf(stderr, "radiusd: Failed to open log file %s: %s\n", mainconfig.log_file, strerror(errno)); cf_section_free(&cs); return -1; } } /* Initialize the dictionary */ cp = cf_pair_find(cs, "dictionary"); if (cp) p = cf_pair_value(cp); if (!p) p = radius_dir; DEBUG2("including dictionary file %s/%s", p, RADIUS_DICTIONARY); if (dict_init(p, RADIUS_DICTIONARY) != 0) { radlog(L_ERR, "Errors reading dictionary: %s", fr_strerror()); return -1; } /* * This allows us to figure out where, relative to * radiusd.conf, the other configuration files exist. */ if (cf_section_parse(cs, NULL, server_config) < 0) { return -1; } if (mainconfig.max_request_time == 0) mainconfig.max_request_time = 100; if (mainconfig.reject_delay > 5) mainconfig.reject_delay = 5; if (mainconfig.cleanup_delay > 5) mainconfig.cleanup_delay =5; /* * Free the old configuration items, and replace them * with the new ones. * * Note that where possible, we do atomic switch-overs, * to ensure that the pointers are always valid. */ cf_section_free(&mainconfig.config); mainconfig.config = cs; DEBUG2("%s: #### Loading Realms and Home Servers ####", mainconfig.name); if (!realms_init(cs)) { return -1; } DEBUG2("%s: #### Loading Clients ####", mainconfig.name); if (!clients_parse_section(cs)) { return -1; } /* * Register the %{config:section.subsection} xlat function. */ xlat_register("config", xlat_config, NULL); xlat_register("client", xlat_client, NULL); /* * Starting the server, WITHOUT "-x" on the * command-line: use whatever is in the config * file. */ if (debug_flag == 0) { debug_flag = mainconfig.debug_level; } fr_debug_flag = debug_flag; /* * Go update our behaviour, based on the configuration * changes. */ /* * Sanity check the configuration for internal * consistency. */ if (mainconfig.reject_delay > mainconfig.cleanup_delay) { mainconfig.reject_delay = mainconfig.cleanup_delay; } if (mainconfig.reject_delay < 0) mainconfig.reject_delay = 0; /* Reload the modules. */ if (setup_modules(reload, mainconfig.config) < 0) { return -1; } if (chroot_dir) { if (chdir(radlog_dir) < 0) { radlog(L_ERR, "Failed to 'chdir %s' after chroot: %s", radlog_dir, strerror(errno)); return -1; } } cc = rad_malloc(sizeof(*cc)); memset(cc, 0, sizeof(*cc)); cc->cs = cs; rad_assert(cs_cache == NULL); cs_cache = cc; return 0; }
/* * Parse a module statement. */ static int parse_module(policy_lex_file_t *lexer, policy_item_t **tail) { int component; policy_lex_t token; policy_module_t *this; char *p; const char *section_name; char filename[1024]; char buffer[2048]; CONF_SECTION *cs, *subcs; modcallable *mc; /* * And the filename */ token = policy_lex_file(lexer, 0, filename, sizeof(filename)); if (token != POLICY_LEX_DOUBLE_QUOTED_STRING) { fprintf(stderr, "%s[%d]: Expected filename, got \"%s\"\n", lexer->filename, lexer->lineno, fr_int2str(rlm_policy_tokens, token, "?")); return 0; } /* * See if we're including all of the files in a subdirectory. */ strlcpy(buffer, lexer->filename, sizeof(buffer)); p = strrchr(buffer, '/'); if (p) { strlcpy(p + 1, filename, sizeof(buffer) - 1 - (p - buffer)); } else { snprintf(buffer, sizeof(buffer), "%s/%s", radius_dir, filename); } /* * Include section calling a module. */ debug_tokens("including module section from file %s\n", buffer); cs = cf_file_read(buffer); if (!cs) { return 0; /* it prints out error messages */ } /* * The outer section is called "main", and can be ignored. * It should be a section, so there should be a subsection. */ subcs = cf_subsection_find_next(cs, NULL, NULL); if (!subcs) { fprintf(stderr, "%s[%d]: Expected section containing modules\n", lexer->filename, lexer->lineno); cf_section_free(&cs); return 0; } section_name = cf_section_name1(subcs); rad_assert(section_name != NULL); component = fr_str2int(policy_component_names, section_name, RLM_COMPONENT_COUNT); if (component == RLM_COMPONENT_COUNT) { fprintf(stderr, "%s[%d]: Invalid section name \"%s\"\n", lexer->filename, lexer->lineno, section_name); cf_section_free(&cs); return 0; } /* * Compile the module entry. */ mc = compile_modgroup(NULL, component, subcs); if (!mc) { cf_section_free(&cs); return 0; /* more often results in calling exit... */ } this = rad_malloc(sizeof(*this)); memset(this, 0, sizeof(*this)); this->item.type = POLICY_TYPE_MODULE; this->item.lineno = lexer->lineno; this->component = component; this->cs = cs; this->mc = mc; *tail = (policy_item_t *) this; return 1; }
/* * The "free" functions are here, for no particular reason. */ void rlm_policy_free_item(policy_item_t *item) { while (item) { policy_item_t *next = item->next; switch (item->type) { default: case POLICY_TYPE_BAD: break; case POLICY_TYPE_ASSIGNMENT: { policy_assignment_t *this; this = (policy_assignment_t *) item; if (this->lhs) free(this->lhs); if (this->rhs) free(this->rhs); } break; case POLICY_TYPE_CONDITIONAL: { policy_condition_t *this; this = (policy_condition_t *) item; if (this->lhs) free(this->lhs); if (this->rhs) free(this->rhs); if (this->child) { rlm_policy_free_item(this->child); this->child = NULL; } } break; case POLICY_TYPE_IF: { policy_if_t *this; this = (policy_if_t *) item; if (this->condition) { rlm_policy_free_item(this->condition); this->condition = NULL; } if (this->if_true) { rlm_policy_free_item(this->if_true); this->if_true = NULL; } if (this->if_false) { rlm_policy_free_item(this->if_false); this->if_false = NULL; } } break; case POLICY_TYPE_ATTRIBUTE_LIST: { policy_attributes_t *this; this = (policy_attributes_t *) item; rlm_policy_free_item(this->attributes); } break; case POLICY_TYPE_NAMED_POLICY: { policy_named_t *this; this = (policy_named_t *) item; rad_assert(this->name != NULL); free(this->name); rlm_policy_free_item(this->policy); } break; case POLICY_TYPE_CALL: { policy_call_t *this; this = (policy_call_t *) item; if (this->name) free(this->name); } break; case POLICY_TYPE_RETURN: break; /* do nothing */ case POLICY_TYPE_MODULE: { policy_module_t *this; this = (policy_module_t *) item; if (this->cs) cf_section_free(&this->cs); if (this->mc) modcallable_free(&this->mc); } break; } /* switch over type */ item->next = NULL; /* for debugging & sanity checks */ item->type = POLICY_TYPE_BAD; free(item); item = next; } }