]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
If no check query is configured, skip it and run the reply queries 105/head
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 12 Oct 2012 14:34:50 +0000 (15:34 +0100)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Fri, 12 Oct 2012 14:52:45 +0000 (15:52 +0100)
Fix authorize function to be more sane

src/modules/rlm_sql/rlm_sql.c

index 2dee3ff657f43104bb7ee886dfb5284f2bca32d0..499932c9bf4136ecf6c13b4b3907750750b35f01 100644 (file)
@@ -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;
 }
 
 /*