SQLcounter patch - Addition of reply-attribute
I just made a patch against 1.1.3 for the SQLcounter module. This patch allows to set the reply-name variable in the sqlcounter.conf file per instance. In this way the default behaviour of Session-Timeout can be overridden by your own reply-attribute. The system will set the session-timeout attribute if you omit the reply-name var in your config for backwards compatibility. I'm planning the following additions: The ability to override the reject behaviour with an accept but adding attributes. For example: if the user has reached his volume limit, accept the user but add speed-limitation attributes. <BEGIN OF PATCH> --- rlm_sqlcounter.c.orig 2006-10-21 23:18:04.147404980 +0200 +++ rlm_sqlcounter.c 2006-10-21 23:01:30.190552948 +0200 @@ -65,17 +65,19 @@ * be used as the instance handle. */ typedef struct rlm_sqlcounter_t { - char *counter_name; /* Daily-Session-Time */ - char *check_name; /* Max-Daily-Session */ - char *key_name; /* User-Name */ + char *counter_name; /* Daily-Session-Time */ + char *check_name; /* Max-Daily-Session */ + char *key_name; /* User-Name */ + char *reply_name; /* Authorized Reply, defaults to Session-Timeout */ 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 *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; int key_attr; /* attribute number for key field */ int dict_attr; /* attribute number for the counter. */ + int reply_attr; /* attribute number for the authorized OK reply, defaults to Session-Timeout */ } rlm_sqlcounter_t; /* @@ -91,6 +93,7 @@ { "counter-name", PW_TYPE_STRING_PTR, offsetof(rlm_sqlcounter_t,counter_name), NULL, NULL }, { "check-name", PW_TYPE_STRING_PTR, offsetof(rlm_sqlcounter_t,check_name), NULL, NULL }, { "key", PW_TYPE_STRING_PTR, offsetof(rlm_sqlcounter_t,key_name), NULL, NULL }, + { "reply-name", PW_TYPE_STRING_PTR, offsetof(rlm_sqlcounter_t,reply_name), NULL, NULL }, { "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 }, @@ -480,6 +483,27 @@ data->key_attr = dattr->attr; /* + * Discover the attribute number of the reply. + * If not set, set it to Session-Timeout + * for backward compatibility + */ + if (data->reply_name == NULL) { + DEBUG2("rlm_sqlcounter: 'reply' set to Session-Timeout for counter name %s",data->counter_name); + data->reply_attr = PW_SESSION_TIMEOUT; + } + else { + dattr = dict_attrbyname(data->reply_name); + if (dattr == NULL) { + radlog(L_ERR, "rlm_sqlcounter: No such attribute %s", + data->reply_name); + return -1; + } + data->reply_attr = dattr->attr; + DEBUG2("rlm_sqlcounter: Reply attribute %s is number %d", + data->reply_name, dattr->attr); + } + + /* * Check the "sqlmod-inst" option. */ if (data->sqlmod_inst == NULL) { @@ -666,11 +690,12 @@ res += check_vp->lvalue; } - if ((reply_item = pairfind(request->reply->vps, PW_SESSION_TIMEOUT)) != NULL) { + /* if ((reply_item = pairfind(request->reply->vps, PW_SESSION_TIMEOUT)) != NULL) { */ + if ((reply_item = pairfind(request->reply->vps, data->reply_attr)) != NULL) { if (reply_item->lvalue > res) reply_item->lvalue = res; } else { - if ((reply_item = paircreate(PW_SESSION_TIMEOUT, PW_TYPE_INTEGER)) == NULL) { + if ((reply_item = paircreate(data->reply_attr, PW_TYPE_INTEGER)) == NULL) { radlog(L_ERR|L_CONS, "no memory"); return RLM_MODULE_NOOP; } @@ -682,8 +707,8 @@ DEBUG2("rlm_sqlcounter: Authorized user %s, check_item=%d, counter=%d", key_vp->strvalue,check_vp->lvalue,counter); - DEBUG2("rlm_sqlcounter: Sent Reply-Item for user %s, Type=Session-Timeout, value=%d", - key_vp->strvalue,reply_item->lvalue); + DEBUG2("rlm_sqlcounter: Sent Reply-Item for user %s, Type=%d, value=%d", + key_vp->strvalue,data->reply_attr,reply_item->lvalue); } else{ char module_fmsg[MAX_STRING_LEN]; @@ -722,6 +778,7 @@ free(data->sqlmod_inst); free(data->counter_name); free(data->allowed_chars); + free(data->reply_name); allowed_chars = NULL; free(instance); </END OF PATCH> Enjoy this patch, J. -- Jonathan De Graeve IMELDA vzw Informatica Dienst Network System Engineer jonathan.de.graeve@imelda.be +32(0)15/50.52.98
"Jonathan De Graeve" <Jonathan.De.Graeve@imelda.be> wrote:
I just made a patch against 1.1.3 for the SQLcounter module.
Please submit patches on bugs.freeradius.org. It's easier to manage them that way.
I'm planning the following additions:
The ability to override the reject behaviour with an accept but adding attributes.
For example: if the user has reached his volume limit, accept the user but add speed-limitation attributes.
That's really what multiple module are for. Have the sqlcounter module return a special return code when the user is over the limit, and use module failover to switch on that return code, and run another module.
- char *counter_name; /* Daily-Session-Time */ - char *check_name; /* Max-Daily-Session */ - char *key_name; /* User-Name */ + char *counter_name; /* Daily-Session-Time */
Why? Gratuitous whitespace changes don't belong in a patch.
- if ((reply_item = pairfind(request->reply->vps, PW_SESSION_TIMEOUT)) != NULL) { + /* if ((reply_item = pairfind(request->reply->vps, PW_SESSION_TIMEOUT)) != NULL) { */
If you're changing code PLEASE do not leave the old code in comments. It's confusing, and pointless. CVS will tell you what the old code was. This practice is just unnecessary. Alan DeKok. -- http://deployingradius.com - The web site of the book http://deployingradius.com/blog/ - The blog
participants (2)
-
Alan DeKok -
Jonathan De Graeve