char *sqlmod_inst; /* instance of SQL module to use, usually just 'sql' */
char *query; /* SQL query to retrieve current session time */
char *reset; /* daily, weekly, monthly, never or user defined */
- char *allowed_chars; /* safe characters list for SQL queries */
time_t reset_time;
time_t last_reset;
DICT_ATTR *key_attr; /* attribute number for key field */
{ "sqlmod-inst", PW_TYPE_STRING_PTR, offsetof(rlm_sqlcounter_t,sqlmod_inst), NULL, NULL },
{ "query", PW_TYPE_STRING_PTR, offsetof(rlm_sqlcounter_t,query), NULL, NULL },
{ "reset", PW_TYPE_STRING_PTR, offsetof(rlm_sqlcounter_t,reset), NULL, NULL },
- { "safe-characters", PW_TYPE_STRING_PTR, offsetof(rlm_sqlcounter_t,allowed_chars), NULL, "@abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_: /"},
{ NULL, -1, 0, NULL, NULL }
};
-static char *allowed_chars = NULL;
-
-/*
- * Translate the SQL queries.
- */
-static size_t sql_escape_func(UNUSED REQUEST *request, char *out, size_t outlen, const char *in, UNUSED void *arg)
-{
- int len = 0;
-
- while (in[0]) {
- /*
- * Non-printable characters get replaced with their
- * mime-encoded equivalents.
- */
- if ((in[0] < 32) ||
- strchr(allowed_chars, *in) == NULL) {
- /*
- * Only 3 or less bytes available.
- */
- if (outlen <= 3) {
- break;
- }
-
- snprintf(out, outlen, "=%02X", (unsigned char) in[0]);
- in++;
- out += 3;
- outlen -= 3;
- len += 3;
- continue;
- }
-
- /*
- * Only one byte left.
- */
- if (outlen <= 1) {
- break;
- }
-
- /*
- * Allowed character.
- */
- *out = *in;
- out++;
- in++;
- outlen--;
- len++;
- }
- *out = '\0';
- return len;
-}
-
static int find_next_reset(rlm_sqlcounter_t *data, time_t timeval)
{
int ret = 0;
strlcpy(q, data->key_name, freespace);
q += strlen(q);
break;
- case 'S': /* SQL module instance */
- DEBUG2("WARNING: Please replace '%%S' with '${sqlmod-inst}'");
- strlcpy(q, data->sqlmod_inst, freespace);
- q += strlen(q);
- break;
default:
*q++ = '%';
*q++ = *p;
rlm_sqlcounter_t *data = (rlm_sqlcounter_t *) instance;
int counter;
char querystr[MAX_QUERY_LEN];
- char responsestr[MAX_QUERY_LEN];
+ char sqlxlat[MAX_QUERY_LEN];
check_pairs = check_pairs; /* shut the compiler up */
reply_pairs = reply_pairs;
/* first, expand %k, %b and %e in query */
sqlcounter_expand(querystr, MAX_QUERY_LEN, data->query, instance);
- /* second, xlat any request attribs in query */
- radius_xlat(responsestr, MAX_QUERY_LEN, querystr, req, sql_escape_func, NULL);
-
/* third, wrap query with sql module call & expand */
- snprintf(querystr, sizeof(querystr), "%%{%%S:%s}", responsestr);
- sqlcounter_expand(responsestr, MAX_QUERY_LEN, querystr, instance);
+ snprintf(sqlxlat, sizeof(sqlxlat), "%%{%s:%s}", data->sqlmod_inst, querystr);
/* Finally, xlat resulting SQL query */
- radius_xlat(querystr, MAX_QUERY_LEN, responsestr, req, sql_escape_func, NULL);
+ radius_xlat(querystr, MAX_QUERY_LEN, sqlxlat, req, NULL, NULL);
counter = atoi(querystr);
DICT_ATTR *dattr;
ATTR_FLAGS flags;
time_t now;
- char buffer[MAX_STRING_LEN];
/*
* Set up a storage area for instance data
return -1;
}
- /*
- * Safe characters list for sql queries. Everything else is
- * replaced with their mime-encoded equivalents.
- */
- allowed_chars = data->allowed_chars;
-
/*
* Discover the attribute number of the key.
*/
sqlcounter_detach(data);
return -1;
}
- sql_escape_func(NULL, buffer, sizeof(buffer), data->key_name, NULL);
- if (strcmp(buffer, data->key_name) != 0) {
- radlog(L_ERR, "rlm_sqlcounter: The value for option 'key' is too long or contains unsafe characters.");
- sqlcounter_detach(data);
- return -1;
- }
dattr = dict_attrbyname(data->key_name);
if (dattr == NULL) {
radlog(L_ERR, "rlm_sqlcounter: No such attribute %s",
sqlcounter_detach(data);
return -1;
}
- sql_escape_func(NULL, buffer, sizeof(buffer), data->sqlmod_inst, NULL);
- if (strcmp(buffer, data->sqlmod_inst) != 0) {
- radlog(L_ERR, "rlm_sqlcounter: The value for option 'sqlmod-inst' is too long or contains unsafe characters.");
- sqlcounter_detach(data);
- return -1;
- }
/*
* Create a new attribute for the counter.
VALUE_PAIR *reply_item;
char msg[128];
char querystr[MAX_QUERY_LEN];
- char responsestr[MAX_QUERY_LEN];
+ char sqlxlat[MAX_QUERY_LEN];
/* quiet the compiler */
instance = instance;
/* first, expand %k, %b and %e in query */
sqlcounter_expand(querystr, MAX_QUERY_LEN, data->query, instance);
- /* second, xlat any request attribs in query */
- radius_xlat(responsestr, MAX_QUERY_LEN, querystr, request, sql_escape_func, NULL);
-
- /* third, wrap query with sql module & expand */
- snprintf(querystr, sizeof(querystr), "%%{%%S:%s}", responsestr);
- sqlcounter_expand(responsestr, MAX_QUERY_LEN, querystr, instance);
+ /* next, wrap query with sql module & expand */
+ snprintf(sqlxlat, sizeof(sqlxlat), "%%{%s:%s}", data->sqlmod_inst, querystr);
/* Finally, xlat resulting SQL query */
- radius_xlat(querystr, MAX_QUERY_LEN, responsestr, request, sql_escape_func, NULL);
+ radius_xlat(querystr, MAX_QUERY_LEN, sqlxlat, request, NULL, NULL);
if (sscanf(querystr, "%u", &counter) != 1) {
DEBUG2("rlm_sqlcounter: No integer found in string \"%s\"",
char **p;
rlm_sqlcounter_t *inst = (rlm_sqlcounter_t *)instance;
- allowed_chars = NULL;
paircompare_unregister(inst->dict_attr->attr, sqlcounter_cmp);
/*