From f10b24cc46acd7df7eeebe72e291cd7399d2551c Mon Sep 17 00:00:00 2001 From: Arran Cudbard-Bell Date: Fri, 12 Oct 2012 15:34:50 +0100 Subject: [PATCH] If no check query is configured, skip it and run the reply queries Fix authorize function to be more sane --- src/modules/rlm_sql/rlm_sql.c | 234 +++++++++++++++++----------------- 1 file changed, 120 insertions(+), 114 deletions(-) diff --git a/src/modules/rlm_sql/rlm_sql.c b/src/modules/rlm_sql/rlm_sql.c index 2dee3ff657f..499932c9bf4 100644 --- a/src/modules/rlm_sql/rlm_sql.c +++ b/src/modules/rlm_sql/rlm_sql.c @@ -1010,16 +1010,21 @@ static int rlm_sql_instantiate(CONF_SECTION * conf, void **instance) static int rlm_sql_authorize(void *instance, REQUEST * request) { + int ret = RLM_MODULE_NOTFOUND; + + SQL_INST *inst = instance; + SQLSOCK *sqlsocket; + VALUE_PAIR *check_tmp = NULL; VALUE_PAIR *reply_tmp = NULL; VALUE_PAIR *user_profile = NULL; - int found = 0; + int dofallthrough = 1; int rows; - SQLSOCK *sqlsocket; - SQL_INST *inst = instance; - char querystr[MAX_QUERY_LEN]; + + char querystr[MAX_QUERY_LEN]; char sqlusername[MAX_STRING_LEN]; + /* * the profile username is used as the sqlusername during * profile checking so that we don't overwrite the orignal @@ -1033,158 +1038,159 @@ static int rlm_sql_authorize(void *instance, REQUEST * request) if (sql_set_user(inst, request, sqlusername, NULL) < 0) return RLM_MODULE_FAIL; - /* - * Reserve a socket + * Reserve a socket + * + * After this point use goto error or goto release to cleanup sockets + * temporary pairlists and temporary attributes. */ sqlsocket = sql_get_socket(inst); - if (sqlsocket == NULL) { - /* Remove the username we (maybe) added above */ - pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0); - return RLM_MODULE_FAIL; - } - - - /* - * After this point, ALL 'return's MUST release the SQL socket! - */ + if (sqlsocket == NULL) + goto error; /* - * Alright, start by getting the specific entry for the user + * Query the check table to find any conditions associated with + * this user/realm/whatever... */ - if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_check_query, request, sql_escape_func, inst)) { - radlog_request(L_ERR, 0, request, "Error generating query; rejecting user"); - sql_release_socket(inst, sqlsocket); - /* Remove the username we (maybe) added above */ - pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0); - return RLM_MODULE_FAIL; - } - rows = sql_getvpdata(inst, &sqlsocket, &check_tmp, querystr); - if (rows < 0) { - radlog_request(L_ERR, 0, request, "SQL query error; rejecting user"); - sql_release_socket(inst, sqlsocket); - /* Remove the username we (maybe) added above */ - pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0); - pairfree(&check_tmp); - return RLM_MODULE_FAIL; - } else if (rows > 0) { + if (inst->config->authorize_check_query && + *inst->config->authorize_check_query) { + if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_check_query, request, sql_escape_func)) { + radlog_request(L_ERR, 0, request, "Error generating query; rejecting user"); + + goto error; + } + + rows = sql_getvpdata(inst, &sqlsocket, &check_tmp, querystr); + if (rows < 0) { + radlog_request(L_ERR, 0, request, "SQL query error; rejecting user"); + + goto error; + } + /* - * Only do this if *some* check pairs were returned + * Only do this if *some* check pairs were returned */ - if (paircompare(request, request->packet->vps, check_tmp, &request->reply->vps) == 0) { - found = 1; + if ((rows > 0) && + (paircompare(request, request->packet->vps, check_tmp, &request->reply->vps) == 0)) { RDEBUG2("User found in radcheck table"); + + pairxlatmove(request, &request->config_items, &check_tmp); + + ret = RLM_MODULE_OK; + } + + /* + * We only process reply table items if check conditions + * were verified + */ + else + goto skipreply; + } + + if (inst->config->authorize_reply_query && + *inst->config->authorize_reply_query) { + /* + * Now get the reply pairs since the paircompare matched + */ + if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_reply_query, request, sql_escape_func)) { + radlog_request(L_ERR, 0, request, "Error generating query; rejecting user"); + + goto error; + } + + rows = sql_getvpdata(inst, &sqlsocket, &reply_tmp, querystr); + if (rows < 0) { + radlog_request(L_ERR, 0, request, "SQL query error; rejecting user"); - if (inst->config->authorize_reply_query && - *inst->config->authorize_reply_query) { - - /* - * Now get the reply pairs since the paircompare matched - */ - if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_reply_query, request, sql_escape_func, inst)) { - radlog_request(L_ERR, 0, request, "Error generating query; rejecting user"); - sql_release_socket(inst, sqlsocket); - /* Remove the username we (maybe) added above */ - pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0); - pairfree(&check_tmp); - return RLM_MODULE_FAIL; - } - if (sql_getvpdata(inst, &sqlsocket, &reply_tmp, querystr) < 0) { - radlog_request(L_ERR, 0, request, "SQL query error; rejecting user"); - sql_release_socket(inst, sqlsocket); - /* Remove the username we (maybe) added above */ - pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0); - pairfree(&check_tmp); - pairfree(&reply_tmp); - - return RLM_MODULE_FAIL; - } - + goto error; + } + + if (rows > 0) { if (!inst->config->read_groups) dofallthrough = fallthrough(reply_tmp); + pairxlatmove(request, &request->reply->vps, &reply_tmp); - } - pairxlatmove(request, &request->config_items, &check_tmp); + + ret = RLM_MODULE_OK; } } + + skipreply: /* - * Clear out the pairlists + * Clear out the pairlists */ pairfree(&check_tmp); pairfree(&reply_tmp); /* - * dofallthrough is set to 1 by default so that if the user information - * is not found, we will still process groups. If the user information, - * however, *is* found, Fall-Through must be set in order to process - * the groups as well + * dofallthrough is set to 1 by default so that if the user information + * is not found, we will still process groups. If the user information, + * however, *is* found, Fall-Through must be set in order to process + * the groups as well. */ if (dofallthrough) { rows = rlm_sql_process_groups(inst, request, sqlsocket, &dofallthrough); if (rows < 0) { radlog_request(L_ERR, 0, request, "Error processing groups; rejecting user"); - sql_release_socket(inst, sqlsocket); - /* Remove the username we (maybe) added above */ - pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0); - return RLM_MODULE_FAIL; - } else if (rows > 0) { - found = 1; + + goto error; } + + if (rows > 0) + ret = RLM_MODULE_OK; } /* - * repeat the above process with the default profile or User-Profile + * Repeat the above process with the default profile or User-Profile */ if (dofallthrough) { - int profile_found = 0; /* - * Check for a default_profile or for a User-Profile. - */ + * Check for a default_profile or for a User-Profile. + */ user_profile = pairfind(request->config_items, PW_USER_PROFILE, 0); - if (inst->config->default_profile[0] != 0 || user_profile != NULL){ - char *profile = inst->config->default_profile; - - if (user_profile != NULL) - profile = user_profile->vp_strvalue; - if (profile && strlen(profile)){ - RDEBUG("Checking profile %s", profile); - if (sql_set_user(inst, request, profileusername, profile) < 0) { - radlog_request(L_ERR, 0, request, "Error setting profile; rejecting user"); - sql_release_socket(inst, sqlsocket); - /* Remove the username we (maybe) added above */ - pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0); - return RLM_MODULE_FAIL; - } else { - profile_found = 1; - } - } + + char *profile = user_profile ? + user_profile->vp_strvalue : + inst->config->default_profile; + + if (!profile || !*profile) + goto release; + + RDEBUG("Checking profile %s", profile); + + if (sql_set_user(inst, request, profileusername, profile) < 0) { + radlog_request(L_ERR, 0, request, "Error setting profile; rejecting user"); + + goto error; } + + rows = rlm_sql_process_groups(inst, request, sqlsocket, &dofallthrough); + if (rows < 0) { + radlog_request(L_ERR, 0, request, "Error processing profile groups; rejecting user"); - if (profile_found) { - rows = rlm_sql_process_groups(inst, request, sqlsocket, &dofallthrough); - if (rows < 0) { - radlog_request(L_ERR, 0, request, "Error processing profile groups; rejecting user"); - sql_release_socket(inst, sqlsocket); - /* Remove the username we (maybe) added above */ - pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0); - return RLM_MODULE_FAIL; - } else if (rows > 0) { - found = 1; - } + goto error; } + + if (rows > 0) + ret = RLM_MODULE_OK; } + + goto release; + + error: + ret = RLM_MODULE_FAIL; + + release: + sql_release_socket(inst, sqlsocket); /* Remove the username we (maybe) added above */ pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0); - sql_release_socket(inst, sqlsocket); - - if (!found) { - RDEBUG("User %s not found", sqlusername); - return RLM_MODULE_NOTFOUND; - } else { - return RLM_MODULE_OK; - } + + pairfree(&check_tmp); + pairfree(&reply_tmp); + + return ret; } /* -- 2.47.3