Add option 'avpair' to send arbitrary RADIUS attributes to the server.
authorFrank Cusack <fcusack@fcusack.com>
Tue, 1 Oct 2002 08:36:49 +0000 (08:36 +0000)
committerFrank Cusack <fcusack@fcusack.com>
Tue, 1 Oct 2002 08:36:49 +0000 (08:36 +0000)
pppd/plugins/radius/radius.c

index 27243b15b7c155f55973c5968d44a237004e105d..53757abcbb1701f0b9952fbe64853b08c4e4b7fe 100644 (file)
@@ -24,7 +24,7 @@
 *
 ***********************************************************************/
 static char const RCSID[] =
-"$Id: radius.c,v 1.15 2002/09/12 05:41:49 fcusack Exp $";
+"$Id: radius.c,v 1.16 2002/10/01 08:36:49 fcusack Exp $";
 
 #include "pppd.h"
 #include "chap.h"
@@ -45,9 +45,15 @@ static char const RCSID[] =
 #define BUF_LEN 1024
 
 static char *config_file = NULL;
+static int add_avp(char **);
+static struct avpopt {
+    char *vpstr;
+    struct avpopt *next;
+} *avpopt = NULL;
 
 static option_t Options[] = {
     { "radius-config-file", o_string, &config_file },
+    { "avpair", o_special, add_avp },
     { NULL }
 };
 
@@ -103,6 +109,7 @@ struct radius_state {
     SERVER *acctserver;                /* Accounting server to use */
     int class_len;
     char class[MAXCLASSLEN];
+    VALUE_PAIR *avp;   /* Additional (user supplied) vp's to send to server */
 };
 
 void (*radius_attributes_hook)(VALUE_PAIR *) = NULL;
@@ -151,6 +158,28 @@ plugin_init(void)
     info("RADIUS plugin initialized.");
 }
 
+/**********************************************************************
+* %FUNCTION: add_avp
+* %ARGUMENTS:
+*  argv -- the <attribute=value> pair to add
+* %RETURNS:
+*  1
+* %DESCRIPTION:
+*  Adds an av pair to be passed on to the RADIUS server on each request.
+***********************************************************************/
+static int
+add_avp(char **argv)
+{
+    struct avpopt *p = malloc(sizeof(struct avpopt));
+
+    /* Append to a list of vp's for later parsing */
+    p->vpstr = strdup(*argv);
+    p->next = avpopt;
+    avpopt = p;
+
+    return 1;
+}
+
 /**********************************************************************
 * %FUNCTION: radius_secret_check
 * %ARGUMENTS:
@@ -245,6 +274,10 @@ radius_pap_auth(char *user,
                       VENDOR_NONE);
     }
 
+    /* Add user specified vp's */
+    if (rstate.avp)
+       rc_avpair_insert(&send, NULL, rstate.avp);
+
     if (rstate.authserver) {
        result = rc_auth_using_server(rstate.authserver,
                                      rstate.client_port, send,
@@ -398,6 +431,10 @@ radius_chap_auth(char *user,
 
     }
 
+    /* Add user specified vp's */
+    if (rstate.avp)
+       rc_avpair_insert(&send, NULL, rstate.avp);
+
     /*
      * make authentication with RADIUS server
      */
@@ -801,6 +838,10 @@ radius_acct_start(void)
     av_type = htonl(hisaddr);
     rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE);
 
+    /* Add user specified vp's */
+    if (rstate.avp)
+       rc_avpair_insert(&send, NULL, rstate.avp);
+
     if (rstate.acctserver) {
        result = rc_acct_using_server(rstate.acctserver,
                                      rstate.client_port, send);
@@ -897,6 +938,10 @@ radius_acct_stop(void)
     av_type = htonl(hisaddr);
     rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE);
 
+    /* Add user specified vp's */
+    if (rstate.avp)
+       rc_avpair_insert(&send, NULL, rstate.avp);
+
     if (rstate.acctserver) {
        result = rc_acct_using_server(rstate.acctserver,
                                      rstate.client_port, send);
@@ -989,6 +1034,10 @@ radius_acct_interim(void *ignored)
     av_type = htonl(hisaddr);
     rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE);
 
+    /* Add user specified vp's */
+    if (rstate.avp)
+       rc_avpair_insert(&send, NULL, rstate.avp);
+
     if (rstate.acctserver) {
        result = rc_acct_using_server(rstate.acctserver,
                                      rstate.client_port, send);
@@ -1078,6 +1127,16 @@ radius_init(char *msg)
                 rc_conf_str("mapfile"));
        return -1;
     }
+
+    /* Add av pairs saved during option parsing */
+    while (avpopt) {
+       struct avpopt *n = avpopt->next;
+
+       rc_avpair_parse(avpopt->vpstr, &rstate.avp);
+       free(avpopt->vpstr);
+       free(avpopt);
+       avpopt = n;
+    }
     return 0;
 }