/*
- * rlm_redis.c
- *
- * Version: $Id$
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * This program is is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2 if the
+ * License as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/**
+ * $Id$
+ * @file rlm_redis.c
+ * @brief Driver for the REDIS noSQL key value stores.
*
- * Copyright 2000,2006 The FreeRADIUS server project
- * Copyright 2011 TekSavvy Solutions <gabe@teksavvy.com>
+ * @copyright 2000,2006 The FreeRADIUS server project
+ * @copyright 2011 TekSavvy Solutions <gabe@teksavvy.com>
*/
-
#include <freeradius-devel/ident.h>
RCSID("$Id$")
char buffer[1024];
conn = redisConnect(inst->hostname, inst->port);
- if (dissocket->conn->err) return NULL;
+ if (conn->err) return NULL;
if (inst->password) {
redisReply *reply = NULL;
snprintf(buffer, sizeof(buffer), "AUTH %s", inst->password);
- reply = redisCommand(dissocket->conn, buffer);
+ reply = redisCommand(conn, buffer);
if (!reply) {
radlog(L_ERR, "rlm_redis (%s): Failed to run AUTH",
inst->xlat_name);
case REDIS_REPLY_STATUS:
if (strcmp(reply->str, "OK") != 0) {
radlog(L_ERR, "rlm_redis (%s): Failed authentication: reply %s",
- inst->xlat_name, dissocket->reply->str);
+ inst->xlat_name, reply->str);
goto do_close;
}
break; /* else it's OK */
snprintf(buffer, sizeof(buffer), "SELECT %d", inst->database);
- reply = redisCommand(dissocket->conn, buffer);
+ reply = redisCommand(conn, buffer);
if (!reply) {
radlog(L_ERR, "rlm_redis (%s): Failed to run SELECT",
inst->xlat_name);
if (strcmp(reply->str, "OK") != 0) {
radlog(L_ERR, "rlm_redis (%s): Failed SELECT %d: reply %s",
inst->xlat_name, inst->database,
- dissocket->reply->str);
+ reply->str);
goto do_close;
}
break; /* else it's OK */
size_t ret = 0;
char *buffer_ptr;
char buffer[21];
- char querystr[MAX_QUERY_LEN];
-
- if (!radius_xlat(querystr, sizeof(querystr), fmt, request,
- redis_escape_func, inst)) {
- radlog(L_ERR, "rlm_redis (%s): xlat failed.",
- inst->xlat_name);
-
- return 0;
- }
dissocket = fr_connection_get(inst->pool);
if (!dissocket) {
}
/* Query failed for some reason, release socket and return */
- if (rlm_redis_query(&dissocket, inst, querystr) < 0) {
+ if (rlm_redis_query(&dissocket, inst, fmt, request) < 0) {
goto release;
}
if (inst->xlat_name) {
xlat_unregister(inst->xlat_name, redis_xlat, instance);
- free(inst->xlat_name);
}
- free(inst->xlat_name);
- free(inst);
return 0;
}
/*
* Query the redis database
*/
-int rlm_redis_query(REDISSOCK **dissocket_p, REDIS_INST *inst, char *query)
+int rlm_redis_query(REDISSOCK **dissocket_p, REDIS_INST *inst,
+ const char *query, REQUEST *request)
{
REDISSOCK *dissocket;
+ int argc;
+ const char *argv[MAX_REDIS_ARGS];
+ char argv_buf[MAX_QUERY_LEN];
if (!query || !*query || !inst || !dissocket_p) {
return -1;
}
+ argc = rad_expand_xlat(request, query, MAX_REDIS_ARGS, argv, 0,
+ sizeof(argv_buf), argv_buf);
+ if (argc <= 0)
+ return -1;
+
dissocket = *dissocket_p;
- DEBUG2("executing query %s", query);
- dissocket->reply = redisCommand(dissocket->conn, query);
+ DEBUG2("executing %s ...", argv[0]);
+ dissocket->reply = redisCommandArgv(dissocket->conn, argc, argv, NULL);
if (!dissocket->reply) {
radlog(L_ERR, "rlm_redis: (%s) REDIS error: %s",
if (dissocket->reply->type == REDIS_REPLY_ERROR) {
radlog(L_ERR, "rlm_redis (%s): query failed, %s",
inst->xlat_name, query);
-
- /* Free the reply just in case */
- rlm_redis_finish_query(dissocket);
-
return -1;
}
/*
* Set up a storage area for instance data
*/
- inst = rad_malloc(sizeof (REDIS_INST));
- if (!inst) {
- return -1;
- }
- memset(inst, 0, sizeof (*inst));
+ *instance = inst = talloc_zero(conf, REDIS_INST);
+ if (!inst) return -1;
/*
* If the configuration parameters can't be parsed, then
* fail.
*/
if (cf_section_parse(conf, inst, module_config) < 0) {
- free(inst);
return -1;
}
if (!xlat_name)
xlat_name = cf_section_name1(conf);
- inst->xlat_name = strdup(xlat_name);
xlat_register(inst->xlat_name, redis_xlat, inst);
inst->pool = fr_connection_pool_init(conf, inst,
redis_create_conn, NULL,
redis_delete_conn);
if (!inst->pool) {
- redis_detach(inst);
return -1;
}
inst->redis_finish_query = rlm_redis_finish_query;
inst->redis_escape_func = redis_escape_func;
- *instance = inst;
-
return 0;
}