/* * Instantiate the module. */ static int mod_instantiate(CONF_SECTION *conf, void *instance) { rlm_linelog_t *inst = instance; int num; if (!inst->filename) { cf_log_err_cs(conf, "No value provided for 'filename'"); return -1; } /* * Escape filenames only if asked. */ if (inst->escape) { inst->escape_func = rad_filename_escape; } else { inst->escape_func = rad_filename_make_safe; } #ifndef HAVE_SYSLOG_H if (strcmp(inst->filename, "syslog") == 0) { cf_log_err_cs(conf, "Syslog output is not supported on this system"); return -1; } #else if (inst->syslog_facility) { num = fr_str2int(syslog_facility_table, inst->syslog_facility, -1); if (num < 0) { cf_log_err_cs(conf, "Invalid syslog facility \"%s\"", inst->syslog_facility); return -1; } inst->syslog_priority |= num; } num = fr_str2int(syslog_severity_table, inst->syslog_severity, -1); if (num < 0) { cf_log_err_cs(conf, "Invalid syslog severity \"%s\"", inst->syslog_severity); return -1; } inst->syslog_priority |= num; #endif if (!inst->line && !inst->reference) { cf_log_err_cs(conf, "Must specify a log format, or reference"); return -1; } inst->ef = exfile_init(inst, 256, 30, true); if (!inst->ef) { cf_log_err_cs(conf, "Failed creating log file context"); return -1; } inst->cs = conf; return 0; }
/** Initialise a module specific exfile handle * * @see exfile_init * * @param[in] ctx to bind the lifetime of the exfile handle to. * @param[in] module section. * @param[in] max_entries Max file descriptors to cache, and manage locks for. * @param[in] max_idle Maximum time a file descriptor can be idle before it's closed. * @param[in] locking Whether or not to lock the files. * @param[in] trigger_prefix if NULL will be set automatically from the module CONF_SECTION. * @param[in] trigger_args to make available in any triggers executed by the connection pool. * @return * - New connection pool. * - NULL on error. */ exfile_t *module_exfile_init(TALLOC_CTX *ctx, CONF_SECTION *module, uint32_t max_entries, uint32_t max_idle, bool locking, char const *trigger_prefix, VALUE_PAIR *trigger_args) { char trigger_prefix_buff[128]; exfile_t *handle; if (!trigger_prefix) { snprintf(trigger_prefix_buff, sizeof(trigger_prefix_buff), "modules.%s.file", cf_section_name1(module)); trigger_prefix = trigger_prefix_buff; } handle = exfile_init(ctx, max_entries, max_idle, locking); if (!handle) return NULL; exfile_enable_triggers(handle, cf_section_find(module, "file", NULL), trigger_prefix, trigger_args); return handle; }
/* * Instantiate the module. */ static int mod_instantiate(CONF_SECTION *conf, void *instance) { linelog_instance_t *inst = instance; char prefix[100]; /* * Escape filenames only if asked. */ if (inst->file.escape) { inst->file.escape_func = rad_filename_escape; } else { inst->file.escape_func = rad_filename_make_safe; } inst->log_dst = fr_str2int(linelog_dst_table, inst->log_dst_str, LINELOG_DST_INVALID); if (inst->log_dst == LINELOG_DST_INVALID) { cf_log_err_cs(conf, "Invalid log destination \"%s\"", inst->log_dst_str); return -1; } if (!inst->log_src && !inst->log_ref) { cf_log_err_cs(conf, "Must specify a log format, or reference"); return -1; } inst->name = cf_section_name2(conf); if (!inst->name) inst->name = cf_section_name1(conf); snprintf(prefix, sizeof(prefix), "rlm_linelog (%s)", inst->name); /* * Setup the logging destination */ switch (inst->log_dst) { case LINELOG_DST_FILE: { if (!inst->file.name) { cf_log_err_cs(conf, "No value provided for 'filename'"); return -1; } inst->file.ef = exfile_init(inst, 64, 30, true); if (!inst->file.ef) { cf_log_err_cs(conf, "Failed creating log file context"); return -1; } if (inst->file.group_str) { char *endptr; inst->file.group = strtol(inst->file.group_str, &endptr, 10); if (*endptr != '\0') { if (rad_getgid(inst, &(inst->file.group), inst->file.group_str) < 0) { cf_log_err_cs(conf, "Unable to find system group \"%s\"", inst->file.group_str); return -1; } } } } break; case LINELOG_DST_SYSLOG: { int num; #ifndef HAVE_SYSLOG_H cf_log_err_cs(conf, "Syslog output is not supported on this system"); return -1; #else if (inst->syslog.facility) { num = fr_str2int(syslog_facility_table, inst->syslog.facility, -1); if (num < 0) { cf_log_err_cs(conf, "Invalid syslog facility \"%s\"", inst->syslog.facility); return -1; } inst->syslog.priority |= num; } num = fr_str2int(syslog_severity_table, inst->syslog.severity, -1); if (num < 0) { cf_log_err_cs(conf, "Invalid syslog severity \"%s\"", inst->syslog.severity); return -1; } inst->syslog.priority |= num; #endif } break; case LINELOG_DST_UNIX: #ifndef HAVE_SYS_UN_H cf_log_err_cs(conf, "Unix sockets are not supported on this sytem"); return -1; #else inst->pool = fr_connection_pool_module_init(cf_section_sub_find(conf, "unix"), inst, mod_conn_create, NULL, prefix); if (!inst->pool) return -1; #endif break; case LINELOG_DST_UDP: inst->pool = fr_connection_pool_module_init(cf_section_sub_find(conf, "udp"), inst, mod_conn_create, NULL, prefix); if (!inst->pool) return -1; break; case LINELOG_DST_TCP: inst->pool = fr_connection_pool_module_init(cf_section_sub_find(conf, "tcp"), inst, mod_conn_create, NULL, prefix); if (!inst->pool) return -1; break; case LINELOG_DST_INVALID: rad_assert(0); break; } inst->delimiter_len = talloc_array_length(inst->delimiter) - 1; inst->cs = conf; return 0; }
static int mod_instantiate(CONF_SECTION *conf, void *instance) { rlm_sql_t *inst = instance; /* * Hack... */ inst->config = &inst->myconfig; inst->cs = conf; inst->config->xlat_name = cf_section_name2(conf); if (!inst->config->xlat_name) { inst->config->xlat_name = cf_section_name1(conf); } else { char *group_name; DICT_ATTR const *da; ATTR_FLAGS flags; /* * Allocate room for <instance>-SQL-Group */ group_name = talloc_typed_asprintf(inst, "%s-SQL-Group", inst->config->xlat_name); DEBUG("rlm_sql (%s): Creating new attribute %s", inst->config->xlat_name, group_name); memset(&flags, 0, sizeof(flags)); if (dict_addattr(group_name, -1, 0, PW_TYPE_STRING, flags) < 0) { ERROR("rlm_sql (%s): Failed to create " "attribute %s: %s", inst->config->xlat_name, group_name, fr_strerror()); return -1; } da = dict_attrbyname(group_name); if (!da) { ERROR("rlm_sql (%s): Failed to create " "attribute %s", inst->config->xlat_name, group_name); return -1; } if (inst->config->groupmemb_query) { DEBUG("rlm_sql (%s): Registering sql_groupcmp for %s", inst->config->xlat_name, group_name); paircompare_register(da, dict_attrbyvalue(PW_USER_NAME, 0), false, sql_groupcmp, inst); } } rad_assert(inst->config->xlat_name); /* * Sanity check for crazy people. */ if (strncmp(inst->config->sql_driver_name, "rlm_sql_", 8) != 0) { ERROR("rlm_sql (%s): \"%s\" is NOT an SQL driver!", inst->config->xlat_name, inst->config->sql_driver_name); return -1; } /* * We need authorize_group_check_query or authorize_group_reply_query * if group_membership_query is set. * * Or we need group_membership_query if authorize_group_check_query or * authorize_group_reply_query is set. */ if (!inst->config->groupmemb_query) { if (inst->config->authorize_group_check_query) { WARN("rlm_sql (%s): Ignoring authorize_group_reply_query as group_membership_query " "is not configured", inst->config->xlat_name); } if (inst->config->authorize_group_reply_query) { WARN("rlm_sql (%s): Ignoring authorize_group_check_query as group_membership_query " "is not configured", inst->config->xlat_name); } } else { if (!inst->config->authorize_group_check_query) { ERROR("rlm_sql (%s): authorize_group_check_query must be configured as group_membership_query " "is configured", inst->config->xlat_name); return -1; } if (!inst->config->authorize_group_reply_query) { ERROR("rlm_sql (%s): authorize_group_reply_query must be configured as group_membership_query " "is configured", inst->config->xlat_name); return -1; } } /* * This will always exist, as cf_section_parse_init() * will create it if it doesn't exist. However, the * "reference" config item won't exist in an auto-created * configuration. So if that doesn't exist, we ignore * the whole subsection. */ inst->config->accounting.cs = cf_section_sub_find(conf, "accounting"); inst->config->accounting.reference_cp = (cf_pair_find(inst->config->accounting.cs, "reference") != NULL); inst->config->postauth.cs = cf_section_sub_find(conf, "post-auth"); inst->config->postauth.reference_cp = (cf_pair_find(inst->config->postauth.cs, "reference") != NULL); /* * Cache the SQL-User-Name DICT_ATTR, so we can be slightly * more efficient about creating SQL-User-Name attributes. */ inst->sql_user = dict_attrbyname("SQL-User-Name"); if (!inst->sql_user) { return -1; } /* * Export these methods, too. This avoids RTDL_GLOBAL. */ inst->sql_set_user = sql_set_user; inst->sql_escape_func = sql_escape_func; inst->sql_query = rlm_sql_query; inst->sql_select_query = rlm_sql_select_query; inst->sql_fetch_row = rlm_sql_fetch_row; /* * Register the SQL xlat function */ xlat_register(inst->config->xlat_name, sql_xlat, sql_escape_func, inst); /* * Load the appropriate driver for our database */ inst->handle = lt_dlopenext(inst->config->sql_driver_name); if (!inst->handle) { ERROR("Could not link driver %s: %s", inst->config->sql_driver_name, dlerror()); ERROR("Make sure it (and all its dependent libraries!) are in the search path of your system's ld"); return -1; } inst->module = (rlm_sql_module_t *) dlsym(inst->handle, inst->config->sql_driver_name); if (!inst->module) { ERROR("Could not link symbol %s: %s", inst->config->sql_driver_name, dlerror()); return -1; } if (inst->module->mod_instantiate) { CONF_SECTION *cs; char const *name; name = strrchr(inst->config->sql_driver_name, '_'); if (!name) { name = inst->config->sql_driver_name; } else { name++; } cs = cf_section_sub_find(conf, name); if (!cs) { cs = cf_section_alloc(conf, name, NULL); if (!cs) { return -1; } } /* * It's up to the driver to register a destructor */ if (inst->module->mod_instantiate(cs, inst->config) < 0) { return -1; } } inst->ef = exfile_init(inst, 64, 30); if (!inst->ef) { cf_log_err_cs(conf, "Failed creating log file context"); return -1; } INFO("rlm_sql (%s): Driver %s (module %s) loaded and linked", inst->config->xlat_name, inst->config->sql_driver_name, inst->module->name); /* * Initialise the connection pool for this instance */ INFO("rlm_sql (%s): Attempting to connect to database \"%s\"", inst->config->xlat_name, inst->config->sql_db); inst->pool = fr_connection_pool_module_init(inst->cs, inst, mod_conn_create, NULL, NULL); if (!inst->pool) return -1; if (inst->config->groupmemb_query) { paircompare_register(dict_attrbyvalue(PW_SQL_GROUP, 0), dict_attrbyvalue(PW_USER_NAME, 0), false, sql_groupcmp, inst); } if (inst->config->do_clients) { if (generate_sql_clients(inst) == -1){ ERROR("Failed to load clients from SQL"); return -1; } } return RLM_MODULE_OK; }
static int mod_instantiate(CONF_SECTION *conf, void *instance) { rlm_sql_t *inst = instance; /* * Sanity check for crazy people. */ if (strncmp(inst->config->sql_driver_name, "rlm_sql_", 8) != 0) { ERROR("rlm_sql (%s): \"%s\" is NOT an SQL driver!", inst->name, inst->config->sql_driver_name); return -1; } /* * We need authorize_group_check_query or authorize_group_reply_query * if group_membership_query is set. * * Or we need group_membership_query if authorize_group_check_query or * authorize_group_reply_query is set. */ if (!inst->config->groupmemb_query) { if (inst->config->authorize_group_check_query) { WARN("rlm_sql (%s): Ignoring authorize_group_reply_query as group_membership_query " "is not configured", inst->name); } if (inst->config->authorize_group_reply_query) { WARN("rlm_sql (%s): Ignoring authorize_group_check_query as group_membership_query " "is not configured", inst->name); } if (!inst->config->read_groups) { WARN("rlm_sql (%s): Ignoring read_groups as group_membership_query " "is not configured", inst->name); inst->config->read_groups = false; } } /* allow the group check / reply queries to be NULL */ /* * This will always exist, as cf_section_parse_init() * will create it if it doesn't exist. However, the * "reference" config item won't exist in an auto-created * configuration. So if that doesn't exist, we ignore * the whole subsection. */ inst->config->accounting.cs = cf_section_sub_find(conf, "accounting"); inst->config->accounting.reference_cp = (cf_pair_find(inst->config->accounting.cs, "reference") != NULL); inst->config->postauth.cs = cf_section_sub_find(conf, "post-auth"); inst->config->postauth.reference_cp = (cf_pair_find(inst->config->postauth.cs, "reference") != NULL); /* * Cache the SQL-User-Name fr_dict_attr_t, so we can be slightly * more efficient about creating SQL-User-Name attributes. */ inst->sql_user = fr_dict_attr_by_name(NULL, "SQL-User-Name"); if (!inst->sql_user) { return -1; } /* * Export these methods, too. This avoids RTDL_GLOBAL. */ inst->sql_set_user = sql_set_user; inst->sql_query = rlm_sql_query; inst->sql_select_query = rlm_sql_select_query; inst->sql_fetch_row = rlm_sql_fetch_row; if (inst->module->mod_instantiate) { CONF_SECTION *cs; char const *name; name = strrchr(inst->config->sql_driver_name, '_'); if (!name) { name = inst->config->sql_driver_name; } else { name++; } cs = cf_section_sub_find(conf, name); if (!cs) { cs = cf_section_alloc(conf, name, NULL); if (!cs) { return -1; } } /* * It's up to the driver to register a destructor */ if (inst->module->mod_instantiate(cs, inst->config) < 0) { return -1; } } /* * Either use the module specific escape function * or our default one. */ inst->sql_escape_func = inst->module->sql_escape_func ? inst->module->sql_escape_func : sql_escape_func; inst->ef = exfile_init(inst, 64, 30, true); if (!inst->ef) { cf_log_err_cs(conf, "Failed creating log file context"); return -1; } /* * Initialise the connection pool for this instance */ INFO("rlm_sql (%s): Attempting to connect to database \"%s\"", inst->name, inst->config->sql_db); inst->pool = module_connection_pool_init(inst->cs, inst, mod_conn_create, NULL, NULL); if (!inst->pool) return -1; if (inst->config->do_clients) { if (generate_sql_clients(inst) == -1){ ERROR("Failed to load clients from SQL"); return -1; } } return RLM_MODULE_OK; }
/* * (Re-)read radiusd.conf into memory. */ static int mod_instantiate(CONF_SECTION *conf, void *instance) { detail_instance_t *inst = instance; CONF_SECTION *cs; inst->name = cf_section_name2(conf); if (!inst->name) { inst->name = cf_section_name1(conf); } /* * Escape filenames only if asked. */ if (inst->escape) { inst->escape_func = rad_filename_escape; } else { inst->escape_func = fix_directories; } inst->ef = exfile_init(inst, 64, 30); if (!inst->ef) { cf_log_err_cs(conf, "Failed creating log file context"); return -1; } /* * Suppress certain attributes. */ cs = cf_section_sub_find(conf, "suppress"); if (cs) { CONF_ITEM *ci; inst->ht = fr_hash_table_create(detail_hash, detail_cmp, NULL); for (ci = cf_item_find_next(cs, NULL); ci != NULL; ci = cf_item_find_next(cs, ci)) { char const *attr; DICT_ATTR const *da; if (!cf_item_is_pair(ci)) continue; attr = cf_pair_attr(cf_item_to_pair(ci)); if (!attr) continue; /* pair-anoia */ da = dict_attrbyname(attr); if (!da) { cf_log_err_cs(conf, "No such attribute '%s'", attr); return -1; } /* * Be kind to minor mistakes. */ if (fr_hash_table_finddata(inst->ht, da)) { WARN("rlm_detail (%s): Ignoring duplicate entry '%s'", inst->name, attr); continue; } if (!fr_hash_table_insert(inst->ht, da)) { ERROR("rlm_detail (%s): Failed inserting '%s' into suppression table", inst->name, attr); return -1; } DEBUG("rlm_detail (%s): '%s' suppressed, will not appear in detail output", inst->name, attr); } /* * If we didn't suppress anything, delete the hash table. */ if (fr_hash_table_num_elements(inst->ht) == 0) { fr_hash_table_free(inst->ht); inst->ht = NULL; } } return 0; }