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
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;
}
/*