Add a return-attribute directive. That way we can send back configurable
[freeradius.git] / src / modules / rlm_counter / rlm_counter.c
index 7480475..f48ab92 100644 (file)
@@ -70,6 +70,7 @@ typedef struct rlm_counter_t {
        char *reset;            /* daily, weekly, monthly, never or user defined */
        char *key_name;         /* User-Name */
        char *count_attribute;  /* Acct-Session-Time */
+       char *return_attribute; /* Session-Timeout */
        char *counter_name;     /* Daily-Session-Time */
        char *check_name;       /* Daily-Max-Session */
        char *service_type;     /* Service-Type to search for */
@@ -77,6 +78,7 @@ typedef struct rlm_counter_t {
        int service_val;
        int key_attr;
        int count_attr;
+       int return_attr;
        int check_attr;
        time_t reset_time;      /* The time of the next reset. */
        time_t last_reset;      /* The time of the last reset. */
@@ -117,6 +119,7 @@ static CONF_PARSER module_config[] = {
   { "key", PW_TYPE_STRING_PTR, offsetof(rlm_counter_t,key_name), NULL, NULL },
   { "reset", PW_TYPE_STRING_PTR, offsetof(rlm_counter_t,reset), NULL,  NULL },
   { "count-attribute", PW_TYPE_STRING_PTR, offsetof(rlm_counter_t,count_attribute), NULL, NULL },
+  { "return-attribute", PW_TYPE_STRING_PTR, offsetof(rlm_counter_t,return_attribute), NULL, NULL },
   { "counter-name", PW_TYPE_STRING_PTR, offsetof(rlm_counter_t,counter_name), NULL,  NULL },
   { "check-name", PW_TYPE_STRING_PTR, offsetof(rlm_counter_t,check_name), NULL, NULL },
   { "allowed-servicetype", PW_TYPE_STRING_PTR, offsetof(rlm_counter_t,service_type),NULL, NULL },
@@ -384,6 +387,27 @@ static int counter_instantiate(CONF_SECTION *conf, void **instance)
        data->count_attr = dattr->attr;
 
        /*
+        * Discover the attribute number of the return attribute.
+        */
+       if (data->return_attribute != NULL) {
+               dattr = dict_attrbyname(data->return_attribute);
+               if (dattr == NULL) {
+                       radlog(L_ERR, "rlm_counter: No such attribute %s",
+                                       data->return_attribute);
+                       counter_detach(data);
+                       return -1;
+               }
+               if (dattr->type != PW_TYPE_INTEGER) {
+                       radlog(L_ERR, "rlm_counter: Return attribute %s is not of type integer",
+                               data->return_attribute);
+                       counter_detach(data);
+                       return -1;
+               }
+               data->return_attr = dattr->attr;
+       }
+       
+
+       /*
         *  Create a new attribute for the counter.
         */
        if (data->counter_name == NULL) {
@@ -835,6 +859,20 @@ static int counter_authorize(void *instance, REQUEST *request)
                                pairadd(&request->reply->vps, reply_item);
                        }
                }
+               else if (data->return_attr) {
+                       if ((reply_item = pairfind(request->reply->vps, data->return_attr)) != NULL) {
+                               if (reply_item->lvalue > res)
+                                       reply_item->lvalue = res;
+                       }
+                       else {
+                               if ((reply_item = paircreate(data->return_attr, PW_TYPE_INTEGER)) == NULL) {
+                                       radlog(L_ERR|L_CONS, "no memory");
+                                       return RLM_MODULE_NOOP;
+                               }
+                               reply_item->lvalue = res;
+                               pairadd(&request->reply->vps, reply_item);
+                       }
+               }
 
                ret=RLM_MODULE_OK;