rlm_redis argument splitting
authorBrian Candler <b.candler@pobox.com>
Sat, 9 Feb 2013 10:20:10 +0000 (10:20 +0000)
committerBrian Candler <b.candler@pobox.com>
Tue, 26 Feb 2013 17:42:28 +0000 (17:42 +0000)
rlm_redis_query now splits the query into separate arguments and expands
each one individually.

This allows for both string literals and expansions to contain spaces, e.g.

    %{redis:LPUSH 'my key' %{User-Name}}

src/modules/rlm_redis/rlm_redis.c
src/modules/rlm_redis/rlm_redis.h
src/modules/rlm_rediswho/rlm_rediswho.c

index 9909a45..3776c52 100644 (file)
@@ -193,15 +193,6 @@ static size_t redis_xlat(void *instance, REQUEST *request,
        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) {
@@ -212,7 +203,7 @@ static size_t redis_xlat(void *instance, REQUEST *request,
        }
 
        /* 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;
        }
 
@@ -272,18 +263,27 @@ static int redis_detach(void *instance)
 /*
  *     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",
index 855a201..9c9869a 100644 (file)
@@ -50,15 +50,17 @@ typedef struct rlm_redis_t {
        char            *password;
        fr_connection_pool_t *pool;
 
-        int (*redis_query)(REDISSOCK **dissocket_p, REDIS_INST *inst, char *query);
+        int (*redis_query)(REDISSOCK **dissocket_p, REDIS_INST *inst, const char *query, REQUEST *request);
         int (*redis_finish_query)(REDISSOCK *dissocket);
         size_t (*redis_escape_func)(REQUEST *request, char *out, size_t outlen, const char *in, void *);
 
 } rlm_redis_t;
 
 #define MAX_QUERY_LEN                  4096
+#define MAX_REDIS_ARGS                 16
 
-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);
 int rlm_redis_finish_query(REDISSOCK *dissocket);
 
 #endif /* RLM_REDIS_H */
index 8741e9f..0225bc4 100644 (file)
@@ -64,31 +64,16 @@ static int rediswho_command(const char *fmt, REDISSOCK **dissocket_p,
                            rlm_rediswho_t *inst, REQUEST *request)
 {
        REDISSOCK *dissocket;
-       char query[MAX_STRING_LEN * 4];
        int result = 0;
 
        if (!fmt) {
                return 0;
        }
 
-       /*
-        *      Do an xlat on the provided string
-        */
-       if (request) {
-               if (!radius_xlat(query, sizeof (query), fmt, request,
-                                inst->redis_inst->redis_escape_func,
-                                inst->redis_inst)) {
-                       radlog(L_ERR, "rediswho_command: xlat failed on: '%s'", query);
-                       return 0;
-               }
-
-       } else {
-               strcpy(query, fmt);
-       }
-
-       if (inst->redis_inst->redis_query(dissocket_p, inst->redis_inst, query) < 0) {
+       if (inst->redis_inst->redis_query(dissocket_p, inst->redis_inst,
+                                         fmt, request) < 0) {
 
-               radlog(L_ERR, "rediswho_command: database query error in: '%s'", query);
+               radlog(L_ERR, "rediswho_command: database query error in: '%s'", fmt);
                return -1;
 
        }