From: Alan T. DeKok Date: Thu, 29 Jun 2017 16:31:07 +0000 (-0400) Subject: remove checksimul from couchbase X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=05bf65e5a25d4996c67c1a58fb358de2f2d4fbbb;p=thirdparty%2Ffreeradius-server.git remove checksimul from couchbase --- diff --git a/raddb/mods-available/couchbase b/raddb/mods-available/couchbase index 5feca692197..6c2501c01b4 100644 --- a/raddb/mods-available/couchbase +++ b/raddb/mods-available/couchbase @@ -120,28 +120,6 @@ couchbase { } } - # Set to 'yes' to enable simultaneous use checking (multiple logins). - # NOTE: This will cause the execution of a view request on every check - # and may be a performance penalty. -# check_simul = no - - # Couchbase view that should return all account documents keyed by username. -# simul_view = "_design/acct/_view/by_user" - - # The key to the above view. - # NOTE: This will need to match EXACTLY what you emit from your view. -# simul_vkey = "%{tolower:%{%{Stripped-User-Name}:-%{User-Name}}}" - - # Set to 'yes' to enable verification of the results returned from the above view. - # NOTE: This may be an additional performance penalty to the actual check and - # should be avoided unless absolutely neccessary. -# verify_simul = no - - # Remove stale session if checkrad does not see a double login. - # NOTE: This will only be executed if both check_simul and verify_simul - # are set to 'yes' above. -# delete_stale_sessions = yes - # # The connection pool is new for 3.0, and will be used in many # modules, for all kinds of connection-related activity. diff --git a/src/modules/rlm_couchbase/mod.h b/src/modules/rlm_couchbase/mod.h index a74322132b8..d2aefe01ef5 100644 --- a/src/modules/rlm_couchbase/mod.h +++ b/src/modules/rlm_couchbase/mod.h @@ -59,13 +59,6 @@ typedef struct rlm_couchbase_t { bool read_clients; //!< Toggle for loading client records. const char *client_view; //!< Couchbase view that returns client documents. - bool check_simul; //!< Toggle to enable simultaneous use checking. - const char *simul_view; //!< Couchbase view that returns accounting documents. - - bool verify_simul; //!< Toggle to enable user login state verification. - vp_tmpl_t *simul_vkey; //!< The query key to be used with simul_view. - bool delete_stale_sessions; //!< Toggle to trigger zapping of stale sessions. - json_object *map; //!< Json object to hold user defined attribute map. fr_pool_t *pool; //!< Connection pool. } rlm_couchbase_t; diff --git a/src/modules/rlm_couchbase/rlm_couchbase.c b/src/modules/rlm_couchbase/rlm_couchbase.c index 284e0f36962..49db42b54bc 100644 --- a/src/modules/rlm_couchbase/rlm_couchbase.c +++ b/src/modules/rlm_couchbase/rlm_couchbase.c @@ -62,12 +62,6 @@ static const CONF_PARSER module_config[] = { { FR_CONF_OFFSET("user_key", FR_TYPE_TMPL, rlm_couchbase_t, user_key), .dflt = "raduser_%{md5:%{tolower:%{%{Stripped-User-Name}:-%{User-Name}}}}", .quote = T_DOUBLE_QUOTED_STRING }, { FR_CONF_OFFSET("read_clients", FR_TYPE_BOOL, rlm_couchbase_t, read_clients) }, /* NULL defaults to "no" */ { FR_CONF_POINTER("client", FR_TYPE_SUBSECTION, NULL), .subcs = (void const *) client_config }, -#ifdef WITH_SESSION_MGMT - { FR_CONF_OFFSET("check_simul", FR_TYPE_BOOL, rlm_couchbase_t, check_simul) }, /* NULL defaults to "no" */ - { FR_CONF_OFFSET("simul_view", FR_TYPE_STRING, rlm_couchbase_t, simul_view), .dflt = "_design/acct/_view/by_user" }, - { FR_CONF_OFFSET("simul_vkey", FR_TYPE_TMPL, rlm_couchbase_t, simul_vkey), .dflt = "%{tolower:%{%{Stripped-User-Name}:-%{User-Name}}}", .quote = T_DOUBLE_QUOTED_STRING }, - { FR_CONF_OFFSET("verify_simul", FR_TYPE_BOOL, rlm_couchbase_t, verify_simul) }, /* NULL defaults to "no" */ -#endif CONF_PARSER_TERMINATOR }; @@ -348,398 +342,6 @@ finish: } #endif -#ifdef WITH_SESSION_MGMT -/** Check if a given user is already logged in. - * - * Process accounting data to determine if a user is already logged in. Sets request->simul_count - * to the current session count for this user. - * - * Check twice. If on the first pass the user exceeds his maximum number of logins, do a second - * pass and validate all logins by querying the terminal server. - * - * @param instance The module instance. - * @param thread Thread specific data. - * @param request The checksimul request object. - * @return Operation status (#rlm_rcode_t). - */ -static rlm_rcode_t mod_checksimul(void *instance, UNUSED void *thread, REQUEST *request) { - rlm_couchbase_t const *inst = instance; /* our module instance */ - rlm_rcode_t rcode = RLM_MODULE_OK; /* return code */ - rlm_couchbase_handle_t *handle = NULL; /* connection pool handle */ - char vpath[256]; - - char buffer[MAX_KEY_SIZE]; - char const *vkey; /* view path and query key */ - char docid[MAX_KEY_SIZE]; /* document id returned from view */ - char error[512]; /* view error return */ - int idx = 0; /* row array index counter */ - char element[MAX_KEY_SIZE]; /* mapped radius attribute to element name */ - lcb_error_t cb_error = LCB_SUCCESS; /* couchbase error holder */ - json_object *json, *jval; /* json object holders */ - json_object *jrows = NULL; /* json object to hold view rows */ - VALUE_PAIR *vp; /* value pair */ - uint32_t client_ip_addr = 0; /* current client ip address */ - char const *client_cs_id = NULL; /* current client calling station id */ - char *user_name = NULL; /* user name from accounting document */ - char *session_id = NULL; /* session id from accounting document */ - char *cs_id = NULL; /* calling station id from accounting document */ - uint32_t nas_addr = 0; /* nas address from accounting document */ - uint32_t nas_port = 0; /* nas port from accounting document */ - uint32_t framed_ip_addr = 0; /* framed ip address from accounting document */ - char framed_proto = 0; /* framed proto from accounting document */ - int session_time = 0; /* session time from accounting document */ - ssize_t slen; - - /* do nothing if this is not enabled */ - if (inst->check_simul != true) { - RWDEBUG("Simultaneous-Use checking requires 'simul_count_query' to be configured"); - return RLM_MODULE_NOOP; - } - - /* ensure valid username in request */ - if ((!request->username) || (request->username->vp_length == 0)) { - REDEBUG("Zero Length username not permitted"); - return RLM_MODULE_INVALID; - } - - slen = tmpl_expand(&vkey, buffer, sizeof(buffer), request, inst->simul_vkey, NULL, NULL); - if (slen < 0) return RLM_MODULE_FAIL; - if ((vkey == buffer) && is_truncated((size_t)slen, sizeof(buffer))) { - REDEBUG("Key too long, expected < " STRINGIFY(sizeof(buffer)) " bytes, got %zi bytes", slen); - return RLM_MODULE_FAIL; - } - - /* get handle */ - handle = fr_pool_connection_get(inst->pool, request); - - /* check handle */ - if (!handle) return RLM_MODULE_FAIL; - - /* set couchbase instance */ - lcb_t cb_inst = handle->handle; - - /* set cookie */ - cookie_t *cookie = handle->cookie; - - /* build view path */ - snprintf(vpath, sizeof(vpath), "%s?key=\"%s\"&stale=update_after", - inst->simul_view, vkey); - - /* query view for document */ - cb_error = couchbase_query_view(cb_inst, cookie, vpath, NULL); - - /* check error and object */ - if (cb_error != LCB_SUCCESS || cookie->jerr != json_tokener_success || !cookie->jobj) { - /* log error */ - RERROR("failed to execute view request or parse return"); - /* set return */ - rcode = RLM_MODULE_FAIL; - /* return */ - goto finish; - } - - /* debugging */ - RDEBUG3("cookie->jobj == %s", json_object_to_json_string(cookie->jobj)); - - /* check for error in json object */ - if (json_object_object_get_ex(cookie->jobj, "error", &json)) { - /* build initial error buffer */ - strlcpy(error, json_object_get_string(json), sizeof(error)); - /* get error reason */ - if (json_object_object_get_ex(cookie->jobj, "reason", &json)) { - /* append divider */ - strlcat(error, " - ", sizeof(error)); - /* append reason */ - strlcat(error, json_object_get_string(json), sizeof(error)); - } - /* log error */ - RERROR("view request failed with error: %s", error); - /* set return */ - rcode = RLM_MODULE_FAIL; - /* return */ - goto finish; - } - - /* check for document id in return */ - if (!json_object_object_get_ex(cookie->jobj, "rows", &json)) { - /* log error */ - RERROR("failed to fetch rows from view payload"); - /* set return */ - rcode = RLM_MODULE_FAIL; - /* return */ - goto finish; - } - - /* get and hold rows */ - jrows = json_object_get(json); - - /* free cookie object */ - if (cookie->jobj) { - json_object_put(cookie->jobj); - cookie->jobj = NULL; - } - - /* check for valid row value */ - if (!jrows || !fr_json_object_is_type(jrows, json_type_array)) { - /* log error */ - RERROR("no valid rows returned from view: %s", vpath); - /* set return */ - rcode = RLM_MODULE_FAIL; - /* return */ - goto finish; - } - - /* debugging */ - RDEBUG3("jrows == %s", json_object_to_json_string(jrows)); - - /* set the count */ - request->simul_count = json_object_array_length(jrows); - - /* debugging */ - RDEBUG("found %d open sessions for %s", request->simul_count, request->username->vp_strvalue); - - /* check count */ - if (request->simul_count < request->simul_max) { - rcode = RLM_MODULE_OK; - goto finish; - } - - /* - * Current session count exceeds configured maximum. - * Continue on to verify the sessions if configured otherwise stop here. - */ - if (inst->verify_simul != true) { - rcode = RLM_MODULE_OK; - goto finish; - } - - /* debugging */ - RDEBUG("verifying session count"); - - /* reset the count */ - request->simul_count = 0; - - /* get client ip address for MPP detection below */ - if ((vp = fr_pair_find_by_num(request->packet->vps, 0, FR_FRAMED_IP_ADDRESS, TAG_ANY)) != NULL) { - client_ip_addr = vp->vp_ipv4addr; - } - - /* get calling station id for MPP detection below */ - if ((vp = fr_pair_find_by_num(request->packet->vps, 0, FR_CALLING_STATION_ID, TAG_ANY)) != NULL) { - client_cs_id = vp->vp_strvalue; - } - - /* loop across all row elements */ - for (idx = 0; idx < json_object_array_length(jrows); idx++) { - /* clear docid */ - memset(docid, 0, sizeof(docid)); - - /* fetch current index */ - json = json_object_array_get_idx(jrows, idx); - - /* get document id */ - if (json_object_object_get_ex(json, "id", &jval)) { - /* copy and check length */ - if (strlcpy(docid, json_object_get_string(jval), sizeof(docid)) >= sizeof(docid)) { - RERROR("document id from row longer than MAX_KEY_SIZE (%d)", MAX_KEY_SIZE); - continue; - } - } - - /* check for valid doc id */ - if (docid[0] == 0) { - RWARN("failed to fetch document id from row - skipping"); - continue; - } - - /* fetch document */ - cb_error = couchbase_get_key(cb_inst, cookie, docid); - - /* check error and object */ - if (cb_error != LCB_SUCCESS || cookie->jerr != json_tokener_success || !cookie->jobj) { - /* log error */ - RERROR("failed to execute get request or parse return"); - /* set return */ - rcode = RLM_MODULE_FAIL; - /* return */ - goto finish; - } - - /* debugging */ - RDEBUG3("cookie->jobj == %s", json_object_to_json_string(cookie->jobj)); - - /* get element name for User-Name attribute */ - if (mod_attribute_to_element("User-Name", inst->map, &element) == 0) { - /* get and check username element */ - if (!json_object_object_get_ex(cookie->jobj, element, &jval)){ - RDEBUG("cannot zap stale entry without username"); - rcode = RLM_MODULE_FAIL; - goto finish; - } - /* copy json string value to user_name */ - user_name = talloc_typed_strdup(request, json_object_get_string(jval)); - } else { - RDEBUG("failed to find map entry for User-Name attribute"); - rcode = RLM_MODULE_FAIL; - goto finish; - } - - /* get element name for Acct-Session-Id attribute */ - if (mod_attribute_to_element("Acct-Session-Id", inst->map, &element) == 0) { - /* get and check session id element */ - if (!json_object_object_get_ex(cookie->jobj, element, &jval)){ - RDEBUG("cannot zap stale entry without session id"); - rcode = RLM_MODULE_FAIL; - goto finish; - } - /* copy json string value to session_id */ - session_id = talloc_typed_strdup(request, json_object_get_string(jval)); - } else { - RDEBUG("failed to find map entry for Acct-Session-Id attribute"); - rcode = RLM_MODULE_FAIL; - goto finish; - } - - /* get element name for NAS-IP-Address attribute */ - if (mod_attribute_to_element("NAS-IP-Address", inst->map, &element) == 0) { - /* attempt to get and nas address element */ - if (json_object_object_get_ex(cookie->jobj, element, &jval)){ - nas_addr = inet_addr(json_object_get_string(jval)); - } - } - - /* get element name for NAS-Port attribute */ - if (mod_attribute_to_element("NAS-Port", inst->map, &element) == 0) { - /* attempt to get nas port element */ - if (json_object_object_get_ex(cookie->jobj, element, &jval)) { - nas_port = (uint32_t) json_object_get_int(jval); - } - } - - /* check terminal server */ - int check = rad_check_ts(nas_addr, nas_port, user_name, session_id); - - /* take action based on check return */ - if (check == 0) { - /* stale record - zap it if enabled */ - if (inst->delete_stale_sessions) { - /* get element name for Framed-IP-Address attribute */ - if (mod_attribute_to_element("Framed-IP-Address", inst->map, &element) == 0) { - /* attempt to get framed ip address element */ - if (json_object_object_get_ex(cookie->jobj, element, &jval)) { - framed_ip_addr = inet_addr(json_object_get_string(jval)); - } - } - - /* get element name for Framed-Port attribute */ - if (mod_attribute_to_element("Framed-Port", inst->map, &element) == 0) { - /* attempt to get framed port element */ - if (json_object_object_get_ex(cookie->jobj, element, &jval)) { - if (strcmp(json_object_get_string(jval), "PPP") == 0) { - framed_proto = 'P'; - } else if (strcmp(json_object_get_string(jval), "SLIP") == 0) { - framed_proto = 'S'; - } - } - } - - /* get element name for Acct-Session-Time attribute */ - if (mod_attribute_to_element("Acct-Session-Time", inst->map, &element) == 0) { - /* attempt to get session time element */ - if (json_object_object_get_ex(cookie->jobj, element, &jval)) { - session_time = json_object_get_int(jval); - } - } - - /* zap session */ - session_zap(request, nas_addr, nas_port, user_name, session_id, - framed_ip_addr, framed_proto, session_time); - } - } else if (check == 1) { - /* user is still logged in - increase count */ - ++request->simul_count; - - /* get element name for Framed-IP-Address attribute */ - if (mod_attribute_to_element("Framed-IP-Address", inst->map, &element) == 0) { - /* attempt to get framed ip address element */ - if (json_object_object_get_ex(cookie->jobj, element, &jval)) { - framed_ip_addr = inet_addr(json_object_get_string(jval)); - } else { - /* ensure 0 if not found */ - framed_ip_addr = 0; - } - } - - /* get element name for Calling-Station-Id attribute */ - if (mod_attribute_to_element("Calling-Station-Id", inst->map, &element) == 0) { - /* attempt to get framed ip address element */ - if (json_object_object_get_ex(cookie->jobj, element, &jval)) { - /* copy json string value to cs_id */ - cs_id = talloc_typed_strdup(request, json_object_get_string(jval)); - } else { - /* ensure null if not found */ - cs_id = NULL; - } - } - - /* Does it look like a MPP attempt? */ - if (client_ip_addr && framed_ip_addr && framed_ip_addr == client_ip_addr) { - request->simul_mpp = 2; - } else if (client_cs_id && cs_id && !strncmp(cs_id, client_cs_id, 16)) { - request->simul_mpp = 2; - } - - } else { - /* check failed - return error */ - REDEBUG("failed to check the terminal server for user '%s'", user_name); - rcode = RLM_MODULE_FAIL; - goto finish; - } - - /* free and reset document user name talloc */ - if (user_name) TALLOC_FREE(user_name); - - /* free and reset document calling station id talloc */ - if (cs_id) TALLOC_FREE(cs_id); - - /* free and reset document session id talloc */ - if (session_id) TALLOC_FREE(session_id); - - /* free and reset json object before fetching next row */ - if (cookie->jobj) { - json_object_put(cookie->jobj); - cookie->jobj = NULL; - } - } - - /* debugging */ - RDEBUG("Retained %d open sessions for %s after verification", - request->simul_count, request->username->vp_strvalue); - -finish: - if (user_name) talloc_free(user_name); - if (cs_id) talloc_free(cs_id); - if (session_id) talloc_free(session_id); - - /* free rows */ - if (jrows) json_object_put(jrows); - - /* free and reset json object */ - if (cookie->jobj) { - json_object_put(cookie->jobj); - cookie->jobj = NULL; - } - - if (handle) fr_pool_connection_release(inst->pool, request, handle); - - /* - * The Auth module apparently looks at request->simul_count, - * not the return value of this module when deciding to deny - * a call for too many sessions. - */ - return rcode; -} -#endif /** Detach the module * @@ -878,9 +480,6 @@ rad_module_t rlm_couchbase = { [MOD_AUTHORIZE] = mod_authorize, #ifdef WITH_ACCOUNTING [MOD_ACCOUNTING] = mod_accounting, -#endif -#ifdef WITH_SESSION_MGMT - [MOD_SESSION] = mod_checksimul #endif }, };