~ubuntu-branches/ubuntu/dapper/freeradius/dapper-updates

« back to all changes in this revision

Viewing changes to src/modules/rlm_counter/rlm_counter.c

  • Committer: Bazaar Package Importer
  • Author(s): Paul Hampson
  • Date: 2004-12-29 20:19:42 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20041229201942-uj2e95la965uthc7
Tags: 1.0.1-2
* freeradius-dialupadmin Suggests php4-mysql | php4-pgsql
   Closes: #279419
* Added a two-second pause to restart in init.d script
   Closes: #262635
* FreeRADIUS module packages now depend on the same source
  version of the main FreeRADIUS package.
   Closes: #284353
* FreeRADIUS-dialupadmin's default paths in admin.conf are
  now correct.
   Closes: #280942
* FreeRADIUS-dialupadmin's help.php3 can now find README.
   Closes: #280941
* Fixes stolen from 1.0.2 CVS:
  - Bug fix to make udpfromto code work
  - radrelay shouldn't dump core if it can't read a VP from the
    detail file.
  - Only initialize the random pool once.
  - In rlm_sql, don't escape characters twice.
  - In rlm_ldap, only claim Auth-Type if a plain text password is present.
  - Locking fixes in threading code
  - Fix building on gcc-4.0 by not trying to access static auth_port from
    other files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * rlm_counter.c
3
3
 *
4
 
 * Version:  $Id: rlm_counter.c,v 1.32.2.5 2003/10/04 00:20:54 phampson Exp $
 
4
 * Version:  $Id: rlm_counter.c,v 1.43 2004/02/26 19:04:28 aland Exp $
5
5
 *
6
6
 *   This program is free software; you can redistribute it and/or modify
7
7
 *   it under the terms of the GNU General Public License as published by
19
19
 *
20
20
 * Copyright 2001  The FreeRADIUS server project
21
21
 * Copyright 2001  Alan DeKok <aland@ox.org>
22
 
 * Copyright 2001,2002  Kostas Kalevras <kkalev@noc.ntua.gr>
 
22
 * Copyright 2001-3  Kostas Kalevras <kkalev@noc.ntua.gr>
23
23
 */
24
24
 
25
25
#include "config.h"
56
56
 
57
57
#define UNIQUEID_MAX_LEN 32
58
58
 
59
 
static const char rcsid[] = "$Id: rlm_counter.c,v 1.32.2.5 2003/10/04 00:20:54 phampson Exp $";
 
59
static const char rcsid[] = "$Id: rlm_counter.c,v 1.43 2004/02/26 19:04:28 aland Exp $";
60
60
 
61
61
/*
62
62
 *      Define a structure for our module configuration.
130
130
/*
131
131
 *      See if the counter matches.
132
132
 */
133
 
static int counter_cmp(void *instance, REQUEST *req, VALUE_PAIR *request, VALUE_PAIR *check,
134
 
                VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
 
133
static int counter_cmp(void *instance,
 
134
                       REQUEST *req UNUSED,
 
135
                       VALUE_PAIR *request, VALUE_PAIR *check,
 
136
                       VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
135
137
{
136
138
        rlm_counter_t *data = (rlm_counter_t *) instance;
137
139
        datum key_datum;
141
143
 
142
144
        check_pairs = check_pairs; /* shut the compiler up */
143
145
        reply_pairs = reply_pairs;
 
146
        req = req;
144
147
 
145
148
        /*
146
149
         *      Find the key attribute.
171
174
        datum time_datum;
172
175
        const char *default1 = "DEFAULT1";
173
176
        const char *default2 = "DEFAULT2";
174
 
        
 
177
 
175
178
        DEBUG2("rlm_counter: add_defaults: Start");
176
179
 
177
 
        key_datum.dptr = (const char *) default1;
 
180
        key_datum.dptr = (char *) default1;
178
181
        key_datum.dsize = strlen(default1);
179
182
        time_datum.dptr = (char *) &data->reset_time;
180
183
        time_datum.dsize = sizeof(time_t);
186
189
        }
187
190
        DEBUG2("rlm_counter: DEFAULT1 set to %d",(int)data->reset_time);
188
191
 
189
 
        key_datum.dptr = (const char *) default2;
 
192
        key_datum.dptr = (char *) default2;
190
193
        key_datum.dsize = strlen(default2);
191
194
        time_datum.dptr = (char *) &data->last_reset;
192
195
        time_datum.dsize = sizeof(time_t);
229
232
         */
230
233
        ret = add_defaults(data);
231
234
        if (ret != RLM_MODULE_OK)
232
 
                return ret;     
 
235
                return ret;
233
236
 
234
237
        DEBUG2("rlm_counter: reset_db ended");
235
238
 
242
245
        unsigned int num=1;
243
246
        char last = 0;
244
247
        struct tm *tm, s_tm;
 
248
        char sCurrentTime[40], sNextTime[40];
245
249
 
246
250
        tm = localtime_r(&timeval, &s_tm);
 
251
        strftime(sCurrentTime, sizeof(sCurrentTime),"%Y-%m-%d %H:%M:%S",tm);
247
252
        tm->tm_sec = tm->tm_min = 0;
248
253
 
249
254
        if (data->reset == NULL)
292
297
                        data->reset);
293
298
                return -1;
294
299
        }
295
 
        DEBUG2("rlm_counter: Current Time: %d, Next reset %d", 
296
 
                (int)timeval,(int)data->reset_time);
 
300
        strftime(sNextTime, sizeof(sNextTime),"%Y-%m-%d %H:%M:%S",tm);
 
301
        DEBUG2("rlm_counter: Current Time: %d [%s], Next reset %d [%s]",
 
302
                (int)timeval,sCurrentTime,(int)data->reset_time,sNextTime);
297
303
 
298
304
        return ret;
299
305
}
322
328
        datum time_datum;
323
329
        const char *default1 = "DEFAULT1";
324
330
        const char *default2 = "DEFAULT2";
325
 
        
 
331
 
326
332
        /*
327
333
         *      Set up a storage area for instance data
328
334
         */
344
350
        cache_size = data->cache_size;
345
351
 
346
352
        /*
347
 
         *      Discover the attribute number of the key. 
 
353
         *      Discover the attribute number of the key.
348
354
         */
349
355
        if (data->key_name == NULL) {
350
356
                radlog(L_ERR, "rlm_counter: 'key' must be set.");
359
365
                return -1;
360
366
        }
361
367
        data->key_attr = dattr->attr;
362
 
        
 
368
 
363
369
        /*
364
 
         *      Discover the attribute number of the counter. 
 
370
         *      Discover the attribute number of the counter.
365
371
         */
366
372
        if (data->count_attribute == NULL) {
367
373
                radlog(L_ERR, "rlm_counter: 'count-attribute' must be set.");
428
434
                        return -1;
429
435
                }
430
436
                data->service_val = dval->value;
431
 
        }       
 
437
        }
432
438
 
433
439
        /*
434
440
         * Find when to reset the database.
477
483
         * If DEFAULT1 and DEFAULT2 do not exist (new database) we add them to the database
478
484
         */
479
485
 
480
 
        key_datum.dptr = (const char *)default1;
 
486
        key_datum.dptr = (char *)default1;
481
487
        key_datum.dsize = strlen(default1);
482
488
 
483
489
        time_datum = gdbm_fetch(data->gdbm, key_datum);
498
504
                }
499
505
                else
500
506
                        data->reset_time = next_reset;
501
 
                key_datum.dptr = (const char *)default2;
 
507
                key_datum.dptr = (char *)default2;
502
508
                key_datum.dsize = strlen(default2);
503
509
 
504
 
                time_datum = gdbm_fetch(data->gdbm, key_datum); 
 
510
                time_datum = gdbm_fetch(data->gdbm, key_datum);
505
511
                if (time_datum.dptr != NULL){
506
512
                        memcpy(&data->last_reset, time_datum.dptr, sizeof(time_t));
507
513
                        free(time_datum.dptr);
528
534
        pthread_mutex_init(&data->mutex, NULL);
529
535
 
530
536
        *instance = data;
531
 
        
 
537
 
532
538
        return 0;
533
539
}
534
540
 
567
573
        if (data->reset_time && (data->reset_time <= request->timestamp)) {
568
574
                int ret;
569
575
 
 
576
                DEBUG("rlm_counter: Time to reset the database.");
570
577
                data->last_reset = data->reset_time;
571
578
                find_next_reset(data,request->timestamp);
572
579
                pthread_mutex_lock(&data->mutex);
583
590
                        DEBUG("rlm_counter: Could not find Service-Type attribute in the request. Returning NOOP.");
584
591
                        return RLM_MODULE_NOOP;
585
592
                }
586
 
                if (proto_vp->lvalue != data->service_val){
 
593
                if ((unsigned)proto_vp->lvalue != data->service_val){
587
594
                        DEBUG("rlm_counter: This Service-Type is not allowed. Returning NOOP.");
588
595
                        return RLM_MODULE_NOOP;
589
596
                }
594
601
         */
595
602
        key_vp = pairfind(request->packet->vps, PW_ACCT_DELAY_TIME);
596
603
        if (key_vp != NULL){
597
 
                if (key_vp->lvalue != 0 && (request->timestamp - key_vp->lvalue) < data->last_reset){
 
604
                if (key_vp->lvalue != 0 &&
 
605
                    (request->timestamp - key_vp->lvalue) < data->last_reset){
598
606
                        DEBUG("rlm_counter: This packet is too old. Returning NOOP.");
599
607
                        return RLM_MODULE_NOOP;
600
608
                }
601
609
        }
602
610
 
603
 
        
 
611
 
604
612
 
605
613
        /*
606
614
         *      Look for the key.  User-Name is special.  It means
624
632
        key_datum.dptr = key_vp->strvalue;
625
633
        key_datum.dsize = key_vp->length;
626
634
 
 
635
        DEBUG("rlm_counter: Searching the database for key '%s'",key_vp->strvalue);
627
636
        pthread_mutex_lock(&data->mutex);
628
637
        count_datum = gdbm_fetch(data->gdbm, key_datum);
629
638
        pthread_mutex_unlock(&data->mutex);
630
639
        if (count_datum.dptr == NULL){
 
640
                DEBUG("rlm_counter: Could not find the requested key in the database.");
631
641
                counter.user_counter = 0;
632
642
                if (uniqueid_vp != NULL)
633
 
                        strncpy(uniqueid_vp->strvalue,counter.uniqueid,UNIQUEID_MAX_LEN - 1);
 
643
                        strncpy(counter.uniqueid,uniqueid_vp->strvalue,UNIQUEID_MAX_LEN - 1);
634
644
                else
635
645
                        memset((char *)counter.uniqueid,0,UNIQUEID_MAX_LEN);
636
646
        }
637
647
        else{
 
648
                DEBUG("rlm_counter: Key found.");
638
649
                memcpy(&counter, count_datum.dptr, sizeof(rad_counter));
639
650
                free(count_datum.dptr);
640
651
                if (counter.uniqueid)
641
652
                        DEBUG("rlm_counter: Counter Unique ID = '%s'",counter.uniqueid);
642
 
                if (uniqueid_vp != NULL){ 
643
 
                        if (counter.uniqueid != NULL && 
 
653
                if (uniqueid_vp != NULL){
 
654
                        if (counter.uniqueid != NULL &&
644
655
                                strncmp(uniqueid_vp->strvalue,counter.uniqueid, UNIQUEID_MAX_LEN - 1) == 0){
645
656
                                DEBUG("rlm_counter: Unique IDs for user match. Droping the request.");
646
657
                                return RLM_MODULE_NOOP;
680
691
        }
681
692
 
682
693
        DEBUG("rlm_counter: User=%s, New Counter=%d.",request->username->strvalue,counter.user_counter);
683
 
        count_datum.dptr = (rad_counter *) &counter;
 
694
        count_datum.dptr = (char *) &counter;
684
695
        count_datum.dsize = sizeof(rad_counter);
685
696
 
 
697
        DEBUG("rlm_counter: Storing new value in database.");
686
698
        pthread_mutex_lock(&data->mutex);
687
699
        rcode = gdbm_store(data->gdbm, key_datum, count_datum, GDBM_REPLACE);
688
700
        pthread_mutex_unlock(&data->mutex);
691
703
                                data->filename, gdbm_strerror(gdbm_errno));
692
704
                return RLM_MODULE_FAIL;
693
705
        }
 
706
        DEBUG("rlm_counter: New value stored successfully.");
694
707
 
695
708
        return RLM_MODULE_OK;
696
709
}
762
775
         */
763
776
 
764
777
        counter.user_counter = 0;
765
 
        
 
778
 
 
779
        DEBUG("rlm_counter: Searching the database for key '%s'",key_vp->strvalue);
766
780
        pthread_mutex_lock(&data->mutex);
767
781
        count_datum = gdbm_fetch(data->gdbm, key_datum);
768
782
        pthread_mutex_unlock(&data->mutex);
769
783
        if (count_datum.dptr != NULL){
 
784
                DEBUG("rlm_counter: Key Found.");
770
785
                memcpy(&counter, count_datum.dptr, sizeof(rad_counter));
771
786
                free(count_datum.dptr);
772
787
        }
 
788
        else
 
789
                DEBUG("rlm_counter: Could not find the requested key in the database.");
773
790
 
774
791
        /*
775
792
         * Check if check item > counter
776
793
         */
 
794
        DEBUG("rlm_counter: Check item = %d, Count = %d",check_vp->lvalue,counter.user_counter);
777
795
        res=check_vp->lvalue - counter.user_counter;
778
796
        if (res > 0) {
 
797
                DEBUG("rlm_counter: res is greater than zero");
779
798
                if (data->count_attr == PW_ACCT_SESSION_TIME) {
780
799
                        /*
781
 
                         * Do the following only if the count attribute is 
 
800
                         * Do the following only if the count attribute is
782
801
                         * AcctSessionTime
783
802
                         */
784
803
 
838
857
 
839
858
                snprintf(module_fmsg,sizeof(module_fmsg), "rlm_counter: Maximum %s usage time reached", data->reset);
840
859
                module_fmsg_vp = pairmake("Module-Failure-Message", module_fmsg, T_OP_EQ);
841
 
                pairadd(&request->packet->vps, module_fmsg_vp); 
 
860
                pairadd(&request->packet->vps, module_fmsg_vp);
842
861
 
843
862
                ret=RLM_MODULE_REJECT;
844
863
 
879
898
 *      is single-threaded.
880
899
 */
881
900
module_t rlm_counter = {
882
 
        "Counter",      
 
901
        "Counter",
883
902
        RLM_TYPE_THREAD_SAFE,           /* type */
884
903
        NULL,                           /* initialization */
885
904
        counter_instantiate,            /* instantiation */