*
***********************************************************************/
static char const RCSID[] =
-"$Id: radius.c,v 1.2 2002/02/08 17:28:31 dfs Exp $";
+"$Id: radius.c,v 1.4 2002/03/01 15:16:51 dfs Exp $";
#include "pppd.h"
#include "chap.h"
static int get_client_port(char *ifname);
static int radius_allowed_address(u_int32_t addr);
-void (*radius_attributes_hook)(VALUE_PAIR *) = NULL;
-void (*radius_pre_auth_hook)(char const *user) = NULL;
-
#ifndef MAXSESSIONID
#define MAXSESSIONID 32
#endif
char config_file[MAXPATHLEN];
char session_id[MAXSESSIONID + 1];
time_t start_time;
+ SERVER *authserver; /* Authentication server to use */
+ SERVER *acctserver; /* Accounting server to use */
};
+void (*radius_attributes_hook)(VALUE_PAIR *) = NULL;
+
+/* The pre_auth_hook MAY set authserver and acctserver if it wants.
+ In that case, they override the values in the radiusclient.conf file */
+void (*radius_pre_auth_hook)(char const *user,
+ SERVER **authserver,
+ SERVER **acctserver) = NULL;
+
static struct radius_state rstate;
char pppd_version[] = VERSION;
make_username_realm(user);
if (radius_pre_auth_hook) {
- radius_pre_auth_hook(rstate.user);
+ radius_pre_auth_hook(rstate.user,
+ &rstate.authserver,
+ &rstate.acctserver);
}
send = NULL;
VENDOR_NONE);
}
- result = rc_auth(rstate.client_port, send, &received, radius_msg);
+ if (rstate.authserver) {
+ result = rc_auth_using_server(rstate.authserver,
+ rstate.client_port, send,
+ &received, radius_msg);
+ } else {
+ result = rc_auth(rstate.client_port, send, &received, radius_msg);
+ }
if (result == OK_RC) {
if (radius_setparams(received, radius_msg) < 0) {
make_username_realm(user);
rstate.client_port = get_client_port (ifname);
if (radius_pre_auth_hook) {
- radius_pre_auth_hook(rstate.user);
+ radius_pre_auth_hook(rstate.user,
+ &rstate.authserver,
+ &rstate.acctserver);
}
}
* make authentication with RADIUS server
*/
- result = rc_auth (rstate.client_port, send, &received, radius_msg);
+ if (rstate.authserver) {
+ result = rc_auth_using_server(rstate.authserver,
+ rstate.client_port, send,
+ &received, radius_msg);
+ } else {
+ result = rc_auth(rstate.client_port, send, &received, radius_msg);
+ }
if (result == OK_RC) {
if (!rstate.done_chap_once) {
*/
while (vp) {
- switch (vp->attribute) {
- case PW_SERVICE_TYPE:
- /* check for service type */
- /* if not FRAMED then exit */
- if (vp->lvalue != PW_FRAMED) {
- slprintf(msg, BUF_LEN, "RADIUS: wrong service type %ld for %s",
- vp->lvalue, rstate.user);
- return -1;
- }
- break;
- case PW_FRAMED_PROTOCOL:
- /* check for framed protocol type */
- /* if not PPP then also exit */
- if (vp->lvalue != PW_PPP) {
- slprintf(msg, BUF_LEN, "RADIUS: wrong framed protocol %ld for %s",
- vp->lvalue, rstate.user);
- return -1;
- }
- break;
-
- case PW_FRAMED_IP_ADDRESS:
- /* seting up remote IP addresses */
- remote = vp->lvalue;
- if (remote == 0xffffffff) {
- /* 0xffffffff means user should be allowed to select one */
- rstate.any_ip_addr_ok = 1;
- } else if (remote != 0xfffffffe) {
- /* 0xfffffffe means NAS should select an ip address */
- remote = htonl(vp->lvalue);
- if (bad_ip_adrs (remote)) {
- slprintf(msg, BUF_LEN, "RADIUS: bad remote IP address %I for %s",
- remote, rstate.user);
+ if (vp->vendorcode == VENDOR_NONE) {
+ switch (vp->attribute) {
+ case PW_SERVICE_TYPE:
+ /* check for service type */
+ /* if not FRAMED then exit */
+ if (vp->lvalue != PW_FRAMED) {
+ slprintf(msg, BUF_LEN, "RADIUS: wrong service type %ld for %s",
+ vp->lvalue, rstate.user);
return -1;
}
- rstate.choose_ip = 1;
- rstate.ip_addr = remote;
- }
+ break;
+ case PW_FRAMED_PROTOCOL:
+ /* check for framed protocol type */
+ /* if not PPP then also exit */
+ if (vp->lvalue != PW_PPP) {
+ slprintf(msg, BUF_LEN, "RADIUS: wrong framed protocol %ld for %s",
+ vp->lvalue, rstate.user);
+ return -1;
+ }
+ break;
+
+ case PW_FRAMED_IP_ADDRESS:
+ /* seting up remote IP addresses */
+ remote = vp->lvalue;
+ if (remote == 0xffffffff) {
+ /* 0xffffffff means user should be allowed to select one */
+ rstate.any_ip_addr_ok = 1;
+ } else if (remote != 0xfffffffe) {
+ /* 0xfffffffe means NAS should select an ip address */
+ remote = htonl(vp->lvalue);
+ if (bad_ip_adrs (remote)) {
+ slprintf(msg, BUF_LEN, "RADIUS: bad remote IP address %I for %s",
+ remote, rstate.user);
+ return -1;
+ }
+ rstate.choose_ip = 1;
+ rstate.ip_addr = remote;
+ }
break;
+ }
}
vp = vp->next;
}
av_type = htonl(hisaddr);
rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE);
- result = rc_acct(rstate.client_port, send);
+ if (rstate.acctserver) {
+ result = rc_acct_using_server(rstate.acctserver,
+ rstate.client_port, send);
+ } else {
+ result = rc_acct(rstate.client_port, send);
+ }
rc_avpair_free(send);
av_type = htonl(hisaddr);
rc_avpair_add(&send, PW_FRAMED_IP_ADDRESS , &av_type , 0, VENDOR_NONE);
- result = rc_acct(rstate.client_port, send);
+ if (rstate.acctserver) {
+ result = rc_acct_using_server(rstate.acctserver,
+ rstate.client_port, send);
+ } else {
+ result = rc_acct(rstate.client_port, send);
+ }
+
if (result != OK_RC) {
/* RADIUS server could be down so make this a warning */
syslog(LOG_WARNING,
{
return rstate.user;
}
-