Allow sqlite filename to be specified in the configuration file.
[freeradius.git] / src / modules / rlm_sql / rlm_sql.c
index 5940700..15da1c6 100644 (file)
@@ -49,6 +49,8 @@ static const CONF_PARSER module_config[] = {
         offsetof(SQL_CONFIG,sql_password), NULL, ""},
        {"radius_db", PW_TYPE_STRING_PTR,
         offsetof(SQL_CONFIG,sql_db), NULL, "radius"},
+       {"filename", PW_TYPE_FILENAME, /* for sqlite */
+        offsetof(SQL_CONFIG,sql_file), NULL, NULL},
        {"read_groups", PW_TYPE_BOOLEAN,
         offsetof(SQL_CONFIG,read_groups), NULL, "yes"},
        {"sqltrace", PW_TYPE_BOOLEAN,
@@ -122,7 +124,7 @@ static const CONF_PARSER module_config[] = {
 static int fallthrough(VALUE_PAIR *vp)
 {
        VALUE_PAIR *tmp;
-       tmp = pairfind(vp, PW_FALL_THROUGH);
+       tmp = pairfind(vp, PW_FALL_THROUGH, 0);
 
        return tmp ? tmp->vp_integer : 0;
 }
@@ -398,12 +400,13 @@ static int generate_sql_clients(SQL_INST *inst)
                        c->nastype = strdup(row[3]);
 
                numf = (inst->module->sql_num_fields)(sqlsocket, inst->config);
-               if ((numf > 5) && (row[5] != NULL)) c->server = strdup(row[5]);
+               if ((numf > 5) && (row[5] != NULL) && *row[5]) c->server = strdup(row[5]);
 
                DEBUG("rlm_sql (%s): Adding client %s (%s, server=%s) to clients list",
                      inst->config->xlat_name,
                      c->longname,c->shortname, c->server ? c->server : "<none>");
                if (!client_add(NULL, c)) {
+                       sql_release_socket(inst, sqlsocket);
                        DEBUG("rlm_sql (%s): Failed to add client %s (%s) to clients list.  Maybe there's a duplicate?",
                              inst->config->xlat_name,
                              c->longname,c->shortname);
@@ -484,7 +487,7 @@ int sql_set_user(SQL_INST *inst, REQUEST *request, char *sqlusername, const char
        sqlusername[0]= '\0';
 
        /* Remove any user attr we added previously */
-       pairdelete(&request->packet->vps, PW_SQL_USER_NAME);
+       pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0);
 
        if (username != NULL) {
                strlcpy(tmpuser, username, sizeof(tmpuser));
@@ -619,7 +622,7 @@ static int sql_groupcmp(void *instance, REQUEST *request, VALUE_PAIR *request_vp
        sqlsocket = sql_get_socket(inst);
        if (sqlsocket == NULL) {
                /* Remove the username we (maybe) added above */
-               pairdelete(&request->packet->vps, PW_SQL_USER_NAME);
+               pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0);
                return 1;
        }
 
@@ -630,7 +633,7 @@ static int sql_groupcmp(void *instance, REQUEST *request, VALUE_PAIR *request_vp
                radlog_request(L_ERR, 0, request,
                               "Error getting group membership");
                /* Remove the username we (maybe) added above */
-               pairdelete(&request->packet->vps, PW_SQL_USER_NAME);
+               pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0);
                sql_release_socket(inst, sqlsocket);
                return 1;
        }
@@ -642,7 +645,7 @@ static int sql_groupcmp(void *instance, REQUEST *request, VALUE_PAIR *request_vp
                        /* Free the grouplist */
                        sql_grouplist_free(&group_list);
                        /* Remove the username we (maybe) added above */
-                       pairdelete(&request->packet->vps, PW_SQL_USER_NAME);
+                       pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0);
                        sql_release_socket(inst, sqlsocket);
                        return 0;
                }
@@ -651,7 +654,7 @@ static int sql_groupcmp(void *instance, REQUEST *request, VALUE_PAIR *request_vp
        /* Free the grouplist */
        sql_grouplist_free(&group_list);
        /* Remove the username we (maybe) added above */
-       pairdelete(&request->packet->vps, PW_SQL_USER_NAME);
+       pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0);
        sql_release_socket(inst,sqlsocket);
 
        RDEBUG("sql_groupcmp finished: User is NOT a member of group %s",
@@ -696,7 +699,7 @@ static int rlm_sql_process_groups(SQL_INST *inst, REQUEST *request, SQLSOCK *sql
                        radlog_request(L_ERR, 0, request,
                                       "Error generating query; rejecting user");
                        /* Remove the grouup we added above */
-                       pairdelete(&request->packet->vps, PW_SQL_GROUP);
+                       pairdelete(&request->packet->vps, PW_SQL_GROUP, 0);
                        return -1;
                }
                rows = sql_getvpdata(inst, sqlsocket, &check_tmp, querystr);
@@ -704,7 +707,7 @@ static int rlm_sql_process_groups(SQL_INST *inst, REQUEST *request, SQLSOCK *sql
                        radlog_request(L_ERR, 0, request, "Error retrieving check pairs for group %s",
                               group_list_tmp->groupname);
                        /* Remove the grouup we added above */
-                       pairdelete(&request->packet->vps, PW_SQL_GROUP);
+                       pairdelete(&request->packet->vps, PW_SQL_GROUP, 0);
                        pairfree(&check_tmp);
                        return -1;
                } else if (rows > 0) {
@@ -721,7 +724,7 @@ static int rlm_sql_process_groups(SQL_INST *inst, REQUEST *request, SQLSOCK *sql
                                if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_reply_query, request, sql_escape_func)) {
                                        radlog_request(L_ERR, 0, request, "Error generating query; rejecting user");
                                        /* Remove the grouup we added above */
-                                       pairdelete(&request->packet->vps, PW_SQL_GROUP);
+                                       pairdelete(&request->packet->vps, PW_SQL_GROUP, 0);
                                        pairfree(&check_tmp);
                                        return -1;
                                }
@@ -729,7 +732,7 @@ static int rlm_sql_process_groups(SQL_INST *inst, REQUEST *request, SQLSOCK *sql
                                        radlog_request(L_ERR, 0, request, "Error retrieving reply pairs for group %s",
                                               group_list_tmp->groupname);
                                        /* Remove the grouup we added above */
-                                       pairdelete(&request->packet->vps, PW_SQL_GROUP);
+                                       pairdelete(&request->packet->vps, PW_SQL_GROUP, 0);
                                        pairfree(&check_tmp);
                                        pairfree(&reply_tmp);
                                        return -1;
@@ -754,7 +757,7 @@ static int rlm_sql_process_groups(SQL_INST *inst, REQUEST *request, SQLSOCK *sql
                        if (!radius_xlat(querystr, sizeof(querystr), inst->config->authorize_group_reply_query, request, sql_escape_func)) {
                                radlog_request(L_ERR, 0, request, "Error generating query; rejecting user");
                                /* Remove the grouup we added above */
-                               pairdelete(&request->packet->vps, PW_SQL_GROUP);
+                               pairdelete(&request->packet->vps, PW_SQL_GROUP, 0);
                                pairfree(&check_tmp);
                                return -1;
                        }
@@ -762,7 +765,7 @@ static int rlm_sql_process_groups(SQL_INST *inst, REQUEST *request, SQLSOCK *sql
                                radlog_request(L_ERR, 0, request, "Error retrieving reply pairs for group %s",
                                       group_list_tmp->groupname);
                                /* Remove the grouup we added above */
-                               pairdelete(&request->packet->vps, PW_SQL_GROUP);
+                               pairdelete(&request->packet->vps, PW_SQL_GROUP, 0);
                                pairfree(&check_tmp);
                                pairfree(&reply_tmp);
                                return -1;
@@ -776,7 +779,7 @@ static int rlm_sql_process_groups(SQL_INST *inst, REQUEST *request, SQLSOCK *sql
                 * Delete the Sql-Group we added above
                 * And clear out the pairlists
                 */
-               pairdelete(&request->packet->vps, PW_SQL_GROUP);
+               pairdelete(&request->packet->vps, PW_SQL_GROUP, 0);
                pairfree(&check_tmp);
                pairfree(&reply_tmp);
        }
@@ -880,8 +883,38 @@ static int rlm_sql_instantiate(CONF_SECTION * conf, void **instance)
        }
 
        xlat_name = cf_section_name2(conf);
-       if (xlat_name == NULL)
+       if (xlat_name == NULL) {
                xlat_name = cf_section_name1(conf);
+       } else {
+               char *group_name;
+               DICT_ATTR *dattr;
+               ATTR_FLAGS flags;
+
+               /*
+                * Allocate room for <instance>-SQL-Group
+                */
+               group_name = rad_malloc((strlen(xlat_name) + 1 + 11) * sizeof(char));
+               sprintf(group_name,"%s-SQL-Group",xlat_name);
+               DEBUG("rlm_sql Creating new attribute %s",group_name);
+
+               memset(&flags, 0, sizeof(flags));
+               dict_addattr(group_name, 0, PW_TYPE_STRING, -1, flags);
+               dattr = dict_attrbyname(group_name);
+               if (dattr == NULL){
+                       radlog(L_ERR, "rlm_ldap: Failed to create attribute %s",group_name);
+                       free(group_name);
+                       free(inst);     /* FIXME: detach */
+                       return -1;
+               }
+
+               if (inst->config->groupmemb_query && 
+                   inst->config->groupmemb_query[0]) {
+                       DEBUG("rlm_sql: Registering sql_groupcmp for %s",group_name);
+                       paircompare_register(dattr->attr, PW_USER_NAME, sql_groupcmp, inst);
+               }
+
+               free(group_name);
+       }
        if (xlat_name){
                inst->config->xlat_name = strdup(xlat_name);
                xlat_register(xlat_name, (RAD_XLAT_FUNC)sql_xlat, inst);
@@ -936,7 +969,10 @@ static int rlm_sql_instantiate(CONF_SECTION * conf, void **instance)
                return -1;
        }
 
-       paircompare_register(PW_SQL_GROUP, PW_USER_NAME, sql_groupcmp, inst);
+       if (inst->config->groupmemb_query && 
+           inst->config->groupmemb_query[0]) {
+               paircompare_register(PW_SQL_GROUP, PW_USER_NAME, sql_groupcmp, inst);
+       }
 
        if (inst->config->do_clients){
                if (generate_sql_clients(inst) == -1){
@@ -985,7 +1021,7 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
        sqlsocket = sql_get_socket(inst);
        if (sqlsocket == NULL) {
                /* Remove the username we (maybe) added above */
-               pairdelete(&request->packet->vps, PW_SQL_USER_NAME);
+               pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0);
                return RLM_MODULE_FAIL;
        }
 
@@ -1001,7 +1037,7 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
                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);
+               pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0);
                return RLM_MODULE_FAIL;
        }
        rows = sql_getvpdata(inst, sqlsocket, &check_tmp, querystr);
@@ -1009,7 +1045,7 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
                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);
+               pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0);
                pairfree(&check_tmp);
                return RLM_MODULE_FAIL;
        } else if (rows > 0) {
@@ -1030,7 +1066,7 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
                                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);
+                               pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0);
                                pairfree(&check_tmp);
                                return RLM_MODULE_FAIL;
                        }
@@ -1038,7 +1074,7 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
                                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);
+                               pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0);
                                pairfree(&check_tmp);
                                pairfree(&reply_tmp);
                                return RLM_MODULE_FAIL;
@@ -1070,7 +1106,7 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
                        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);
+                       pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0);
                        return RLM_MODULE_FAIL;
                } else if (rows > 0) {
                        found = 1;
@@ -1085,7 +1121,7 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
                /*
                * Check for a default_profile or for a User-Profile.
                */
-               user_profile = pairfind(request->config_items, PW_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;
 
@@ -1097,7 +1133,7 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
                                        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);
+                                       pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0);
                                        return RLM_MODULE_FAIL;
                                } else {
                                        profile_found = 1;
@@ -1111,7 +1147,7 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
                                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);
+                               pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0);
                                return RLM_MODULE_FAIL;
                        } else if (rows > 0) {
                                found = 1;
@@ -1120,7 +1156,7 @@ static int rlm_sql_authorize(void *instance, REQUEST * request)
        }
 
        /* Remove the username we (maybe) added above */
-       pairdelete(&request->packet->vps, PW_SQL_USER_NAME);
+       pairdelete(&request->packet->vps, PW_SQL_USER_NAME, 0);
        sql_release_socket(inst, sqlsocket);
 
        if (!found) {
@@ -1155,7 +1191,7 @@ static int rlm_sql_accounting(void *instance, REQUEST * request) {
        /*
         * Find the Acct Status Type
         */
-       if ((pair = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE)) != NULL) {
+       if ((pair = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE, 0)) != NULL) {
                acctstatustype = pair->vp_integer;
        } else {
                radius_xlat(logstr, sizeof(logstr), "packet has no accounting status type. [user '%{User-Name}', nas '%{NAS-IP-Address}']", request, NULL);
@@ -1316,7 +1352,7 @@ static int rlm_sql_accounting(void *instance, REQUEST * request) {
                                                 * This is to fix CISCO's aaa from filling our
                                                 * table with bogus crap
                                                 */
-                                               if ((pair = pairfind(request->packet->vps, PW_ACCT_SESSION_TIME)) != NULL)
+                                               if ((pair = pairfind(request->packet->vps, PW_ACCT_SESSION_TIME, 0)) != NULL)
                                                        acctsessiontime = pair->vp_integer;
 
                                                if (acctsessiontime <= 0) {
@@ -1458,9 +1494,9 @@ static int rlm_sql_checksimul(void *instance, REQUEST * request) {
          */
        request->simul_count = 0;
 
-        if ((vp = pairfind(request->packet->vps, PW_FRAMED_IP_ADDRESS)) != NULL)
+        if ((vp = pairfind(request->packet->vps, PW_FRAMED_IP_ADDRESS, 0)) != NULL)
                 ipno = vp->vp_ipaddr;
-        if ((vp = pairfind(request->packet->vps, PW_CALLING_STATION_ID)) != NULL)
+        if ((vp = pairfind(request->packet->vps, PW_CALLING_STATION_ID, 0)) != NULL)
                 call_num = vp->vp_strvalue;