Remove fr_connection_delete
[freeradius.git] / src / modules / rlm_couchbase / rlm_couchbase.c
index 37bc16b..ffab0ed 100644 (file)
@@ -31,7 +31,7 @@ RCSID("$Id$");
 #include <freeradius-devel/rad_assert.h>
 
 #include <libcouchbase/couchbase.h>
-#include <json/json.h>
+#include <json.h>
 
 #include "mod.h"
 #include "couchbase.h"
@@ -41,50 +41,56 @@ RCSID("$Id$");
  * Module Configuration
  */
 static const CONF_PARSER module_config[] = {
-       {"acctkey", PW_TYPE_STRING_PTR, offsetof(rlm_couchbase_t, acctkey), NULL,
-               "radacct_%{%{Acct-Unique-Session-Id}:-%{Acct-Session-Id}}"},
-       {"doctype", PW_TYPE_STRING_PTR, offsetof(rlm_couchbase_t, doctype), NULL, "radacct"},
-       {"server", PW_TYPE_STRING_PTR | PW_TYPE_REQUIRED, offsetof(rlm_couchbase_t, server), NULL, NULL},
-       {"bucket", PW_TYPE_STRING_PTR | PW_TYPE_REQUIRED, offsetof(rlm_couchbase_t, bucket), NULL, NULL},
-       {"pass", PW_TYPE_STRING_PTR, offsetof(rlm_couchbase_t, pass), NULL, NULL},
-       {"expire", PW_TYPE_INTEGER, offsetof(rlm_couchbase_t, expire), NULL, 0},
-       {"userkey", PW_TYPE_STRING_PTR | PW_TYPE_REQUIRED, offsetof(rlm_couchbase_t, userkey), NULL,
-               "raduser_%{md5:%{tolower:%{%{Stripped-User-Name}:-%{User-Name}}}}"},
+       { "acct_key", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_couchbase_t, acct_key), "radacct_%{%{Acct-Unique-Session-Id}:-%{Acct-Session-Id}}" },
+       { "doctype", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_couchbase_t, doctype), "radacct" },
+       { "server", FR_CONF_OFFSET(PW_TYPE_STRING | PW_TYPE_REQUIRED, rlm_couchbase_t, server_raw), NULL },
+       { "bucket", FR_CONF_OFFSET(PW_TYPE_STRING | PW_TYPE_REQUIRED, rlm_couchbase_t, bucket), NULL },
+       { "password", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_couchbase_t, password), NULL },
+       { "expire", FR_CONF_OFFSET(PW_TYPE_INTEGER, rlm_couchbase_t, expire), 0 },
+       { "user_key", FR_CONF_OFFSET(PW_TYPE_STRING | PW_TYPE_REQUIRED, rlm_couchbase_t, user_key), "raduser_%{md5:%{tolower:%{%{Stripped-User-Name}:-%{User-Name}}}}" },
        {NULL, -1, 0, NULL, NULL}     /* end the list */
 };
 
 /* initialize couchbase connection */
 static int mod_instantiate(CONF_SECTION *conf, void *instance) {
+       static bool version_done;
+
        rlm_couchbase_t *inst = instance;   /* our module instance */
 
-       /* fail on bad config */
-       if (cf_section_parse(conf, inst, module_config) < 0) {
-               ERROR("rlm_couchbase: failed to parse config");
-               /* fail */
-               return -1;
+       if (!version_done) {
+               version_done = true;
+               INFO("rlm_couchbase: json-c version: %s", json_c_version());
+               INFO("rlm_couchbase: libcouchbase version: %s", lcb_get_version(NULL));
        }
 
-       /* rebuild server list if needed - libcouchbase only takes a semi-colon separated list */
-       if (strchr(inst->server, '\t') || strchr(inst->server, ' ') || strchr(inst->server, ',')) {
-               char *tok;  /* temporary token pointer */
-               /* make a temporary copy of the server string */
-               char *temps1 = talloc_typed_strdup(inst, inst->server);
-               /* temporary buffer for the new server string */
-               char *temps2 = talloc_zero_size(inst, strlen(inst->server) + 1);
-               /* loop through server list and break into pieces */
-               while ((tok = strsep(&temps1, "\t ,")) != NULL) {
-                       /* build server string */
-                       if (strlen(tok)) {
-                               temps2 = talloc_asprintf_append(temps2, "%s;", tok);
+       {
+               char *server, *p;
+               size_t len, i;
+               bool sep = false;
+
+               len = talloc_array_length(inst->server_raw);
+               server = p = talloc_array(inst, char, len);
+               for (i = 0; i < len; i++) {
+                       switch (inst->server_raw[i]) {
+                       case '\t':
+                       case ' ':
+                       case ',':
+                               /* Consume multiple separators occurring in sequence */
+                               if (sep == true) continue;
+
+                               sep = true;
+                               *p++ = ';';
+                               break;
+
+                       default:
+                               sep = false;
+                               *p++ = inst->server_raw[i];
+                               break;
                        }
                }
-               /* replace old server string with new */
-               strlcpy(inst->server, temps2, strlen(temps2));
-               /* free temporary buffers */
-               talloc_free(temps1);
-               talloc_free(temps2);
-               /* debugging */
-               DEBUG("rlm_couchbase: built server string '%s' from config", inst->server);
+
+               *p = '\0';
+               inst->server = server;
        }
 
        /* setup item map */
@@ -94,7 +100,7 @@ static int mod_instantiate(CONF_SECTION *conf, void *instance) {
        }
 
        /* initiate connection pool */
-       inst->pool = fr_connection_pool_init(conf, inst, mod_conn_create, mod_conn_alive, mod_conn_delete, NULL);
+       inst->pool = fr_connection_pool_init(conf, inst, mod_conn_create, mod_conn_alive, NULL);
 
        /* check connection pool */
        if (!inst->pool) {
@@ -118,9 +124,9 @@ static rlm_rcode_t CC_HINT(nonnull) mod_authorize(void *instance, REQUEST *reque
        rad_assert(request->packet != NULL);
 
        /* attempt to build document key */
-       if (radius_xlat(dockey, sizeof(dockey), request, inst->userkey, NULL, NULL) < 0) {
+       if (radius_xlat(dockey, sizeof(dockey), request, inst->user_key, NULL, NULL) < 0) {
                /* log error */
-               RERROR("could not find user key attribute (%s) in packet", inst->userkey);
+               RERROR("could not find user key attribute (%s) in packet", inst->user_key);
                /* return */
                return RLM_MODULE_FAIL;
        }
@@ -265,9 +271,9 @@ static rlm_rcode_t CC_HINT(nonnull) mod_accounting(void *instance, REQUEST *requ
        }
 
        /* attempt to build document key */
-       if (radius_xlat(dockey, sizeof(dockey), request, inst->acctkey, NULL, NULL) < 0) {
+       if (radius_xlat(dockey, sizeof(dockey), request, inst->acct_key, NULL, NULL) < 0) {
                /* log error */
-               RERROR("could not find accounting key attribute (%s) in packet", inst->acctkey);
+               RERROR("could not find accounting key attribute (%s) in packet", inst->acct_key);
                /* release handle */
                if (handle) {
                        fr_connection_release(inst->pool, handle);
@@ -330,6 +336,7 @@ static rlm_rcode_t CC_HINT(nonnull) mod_accounting(void *instance, REQUEST *requ
                        }
                        /* check start timestamp and adjust if needed */
                        mod_ensure_start_timestamp(cookie->jobj, request->packet->vps);
+               break;
                case PW_STATUS_ALIVE:
                        /* check start timestamp and adjust if needed */
                        mod_ensure_start_timestamp(cookie->jobj, request->packet->vps);
@@ -345,7 +352,6 @@ static rlm_rcode_t CC_HINT(nonnull) mod_accounting(void *instance, REQUEST *requ
                        }
                        /* return without doing anything */
                        return RLM_MODULE_NOOP;
-               break;
        }
 
        /* loop through pairs and add to json document */