int col_count;
} rlm_sql_conn_t;
+typedef struct rlm_sql_sqlite_config {
+ const char *filename;
+} rlm_sql_sqlite_config_t;
+
+static const CONF_PARSER driver_config[] = {
+ {"filename", PW_TYPE_STRING_PTR,
+ offsetof(rlm_sql_sqlite_config_t, filename), NULL, NULL},
+
+ {NULL, -1, 0, NULL, NULL}
+};
static int sql_check_error(sqlite3 *db)
{
*/
default:
radlog(L_ERR, "rlm_sql_sqlite: Handle is unusable, SQLite "
- "error (%d): %s", error, sqlite3_errmsg(db));
+ "error (%d): %s", error, sqlite3_errmsg(db));
return SQL_DOWN;
break;
}
}
+static int sql_instantiate(CONF_SECTION *conf, rlm_sql_config_t *config)
+{
+ rlm_sql_sqlite_config_t *driver;
+
+ MEM(driver = config->driver = talloc_zero(config, rlm_sql_sqlite_config_t));
+
+ if (cf_section_parse(conf, driver, driver_config) < 0) {
+ return -1;
+ }
+
+ if (!driver->filename) {
+ MEM(driver->filename = talloc_asprintf(driver, "%s/%s",
+ radius_dir,
+ config->sql_db));
+ }
+
+ return 0;
+}
+
/*************************************************************************
*
* Function: sql_create_socket
static int sql_init_socket(rlm_sql_handle_t *handle, rlm_sql_config_t *config)
{
rlm_sql_conn_t *conn;
+ rlm_sql_sqlite_config_t *driver = config->driver;
+
int status;
- const char *filename;
- char buffer[2048];
if (!conn) {
- MEM(handle->conn = talloc_zero(NULL, rlm_sql_conn));
+ MEM(handle->conn = talloc_zero(NULL, rlm_sql_conn_t));
}
conn = handle->conn;
+
+ DEBUG("rlm_sql_sqlite: Opening SQLite database %s", driver->filename);
- filename = config->sql_file;
- if (!filename) {
- snprintf(buffer, sizeof(buffer), "%s/sqlite_radius_client_database",
- radius_dir);
- filename = buffer;
- }
-
- DEBUG("rlm_sql_sqlite: Opening SQLite database %s", filename);
-
- status = sqlite3_open(filename, &(conn->db));
+ status = sqlite3_open(driver->filename, &(conn->db));
if (status != SQLITE_OK) {
return sql_check_error(conn->db);
}
static const CONF_PARSER module_config[] = {
{"driver", PW_TYPE_STRING_PTR,
- offsetof(rlm_sql_config_t,sql_driver), NULL, "mysql"},
+ offsetof(rlm_sql_config_t,sql_driver_name), NULL, "mysql"},
{"server", PW_TYPE_STRING_PTR,
offsetof(rlm_sql_config_t,sql_server), NULL, "localhost"},
{"port", PW_TYPE_STRING_PTR,
offsetof(rlm_sql_config_t,sql_password), NULL, ""},
{"radius_db", PW_TYPE_STRING_PTR,
offsetof(rlm_sql_config_t,sql_db), NULL, "radius"},
- {"filename", PW_TYPE_FILENAME, /* for sqlite */
- offsetof(rlm_sql_config_t,sql_file), NULL, NULL},
{"read_groups", PW_TYPE_BOOLEAN,
offsetof(rlm_sql_config_t,read_groups), NULL, "yes"},
{"readclients", PW_TYPE_BOOLEAN,
* more efficient about creating SQL-User-Name attributes.
*/
inst->sql_user = dict_attrbyname("SQL-User-Name");
- if (!inst->sql_user) return -1;
-
+ if (!inst->sql_user) {
+ return -1;
+ }
+
/*
* Export these methods, too. This avoids RTDL_GLOBAL.
*/
/*
* Sanity check for crazy people.
*/
- if (strncmp(inst->config->sql_driver, "rlm_sql_", 8) != 0) {
+ if (strncmp(inst->config->sql_driver_name, "rlm_sql_", 8) != 0) {
radlog(L_ERR, "rlm_sql (%s): \"%s\" is NOT an SQL driver!",
- inst->config->xlat_name, inst->config->sql_driver);
+ inst->config->xlat_name, inst->config->sql_driver_name);
return -1;
}
/*
* Load the appropriate driver for our database
*/
- inst->handle = lt_dlopenext(inst->config->sql_driver);
+ inst->handle = lt_dlopenext(inst->config->sql_driver_name);
if (inst->handle == NULL) {
radlog(L_ERR, "Could not link driver %s: %s",
- inst->config->sql_driver,
+ inst->config->sql_driver_name,
lt_dlerror());
radlog(L_ERR, "Make sure it (and all its dependent libraries!)"
"are in the search path of your system's ld.");
}
inst->module = (rlm_sql_module_t *) lt_dlsym(inst->handle,
- inst->config->sql_driver);
+ inst->config->sql_driver_name);
if (!inst->module) {
radlog(L_ERR, "Could not link symbol %s: %s",
- inst->config->sql_driver,
+ inst->config->sql_driver_name,
lt_dlerror());
return -1;
}
+
+ if (inst->module->sql_instantiate) {
+ /*
+ * It's up to the driver to register a destructor
+ */
+ if (inst->module->sql_instantiate(cf_section_sub_find(conf, inst->config->sql_driver_name), inst->config) < 0) {
+ return -1;
+ }
+ }
radlog(L_INFO, "rlm_sql (%s): Driver %s (module %s) loaded and linked",
- inst->config->xlat_name, inst->config->sql_driver,
+ inst->config->xlat_name, inst->config->sql_driver_name,
inst->module->name);
/*
typedef struct sql_config {
const char *xlat_name;
- const char *sql_driver;
+ const char *sql_driver_name;
const char *sql_server;
const char *sql_port;
const char *sql_login;
int const deletestalesessions;
const char *allowed_chars;
int const query_timeout;
- void *localcfg; /*individual driver config */
+
+ void *driver; //!< Where drivers should write a
+ //!< pointer to their configurations.
/*
- *TODO: The rest of the queries should also be moved into their own
- *sections.
+ * @todo The rest of the queries should also be moved into
+ * their own sections.
*/
- /*Section configurations */
+ /*
+ * Section configurations
+ */
sql_acct_section_t *postauth;
sql_acct_section_t *accounting;
} rlm_sql_config_t;
typedef struct rlm_sql_module_t {
const char *name;
-
+
+ int (*sql_instantiate)(CONF_SECTION *conf, rlm_sql_config_t *config);
int (*sql_init_socket)(rlm_sql_handle_t *handle, rlm_sql_config_t *config);
int (*sql_destroy_socket)(rlm_sql_handle_t *handle, rlm_sql_config_t *config);
int (*sql_query)(rlm_sql_handle_t *handle, rlm_sql_config_t *config, char *query);