Please look at my nas_ident passthough patch.
Developers, In my freeradius installation I make some decisions based on what the NAS identifies itself as in the nas-identifier attribute. One of these decisions is which accounting database to use. This has been causing problems for me since the session_zap function is called when we get two start messages in a row. The purpose of the function makes perfect sense: to end the old session so that multiple login detection works, but the problem is that the nas-identifier attribute isn't translated though to the stop message like the username or the nas-ip-Address so it gets logged to the wrong accounting database because there isn't a nas-identifier to match on. The solution is to pass the NAS-Identifier attribute though to the session_zap function and have it output to the accounting modules instead of simply leaving it null. I the attached patch to do this and it works, except my radius server has become less than stable. It crashes here and there, but I can't figure out why. I'm not much of a C programmer so I'm hoping that someone on the list can look at my patch and point out what I did wrong. I suspect it's a typing issue or something. Also, it would be great if the developers would consider this for a production version since passing though the NAS-Identifier won't break or affect anything currently running, but offers the flexibility of changing the Session-Type based on matching something in the NAS-Identifier. Thanks to any that can help, schu diff -ruN freeradius-1.1.7.orig/src/include/radiusd.h freeradius-1.1.7/src/include/radiusd.h --- freeradius-1.1.7.orig/src/include/radiusd.h 2007-06-12 01:31:45.000000000 -0800 +++ freeradius-1.1.7/src/include/radiusd.h 2007-09-20 16:06:57.000000000 -0800 @@ -295,7 +295,7 @@ int session_zap(REQUEST *request, uint32_t nasaddr, unsigned int port, const char *user, const char *sessionid, uint32_t cliaddr, - char proto); + char proto, const char *nas_ident); /* radiusd.c */ #ifndef _LIBRADIUS diff -ruN freeradius-1.1.7.orig/src/main/session.c freeradius-1.1.7/src/main/session.c --- freeradius-1.1.7.orig/src/main/session.c 2007-05-15 01:50:51.000000000 -0800 +++ freeradius-1.1.7/src/main/session.c 2007-09-20 16:08:45.000000000 -0800 @@ -46,7 +46,7 @@ /* End a session by faking a Stop packet to all accounting modules */ int session_zap(REQUEST *request, uint32_t nasaddr, unsigned int port, const char *user, - const char *sessionid, uint32_t cliaddr, char proto) + const char *sessionid, uint32_t cliaddr, char proto, const char *nas_ident) { REQUEST *stopreq; VALUE_PAIR *vp, *userpair; @@ -85,6 +85,7 @@ IPPAIR(PW_NAS_IP_ADDRESS, nasaddr); INTPAIR(PW_ACCT_DELAY_TIME, 0); STRINGPAIR(PW_USER_NAME, user); + STRINGPAIR(PW_NAS_IDENTIFIER, nas_ident); userpair = vp; INTPAIR(PW_NAS_PORT, port); STRINGPAIR(PW_ACCT_SESSION_ID, sessionid); diff -ruN freeradius-1.1.7.orig/src/modules/rlm_radutmp/rlm_radutmp.c freeradius-1.1.7/src/modules/rlm_radutmp/rlm_radutmp.c --- freeradius-1.1.7.orig/src/modules/rlm_radutmp/rlm_radutmp.c 2007-04-07 14:40:00.000000000 -0800 +++ freeradius-1.1.7/src/modules/rlm_radutmp/rlm_radutmp.c 2007-09-20 16:15:18.000000000 -0800 @@ -589,6 +589,7 @@ rlm_radutmp_t *inst = instance; char login[256]; char filename[1024]; + char *nas_ident = NULL; ssize_t read_size; /* @@ -664,6 +665,8 @@ ipno = vp->lvalue; if ((vp = pairfind(request->packet->vps, PW_CALLING_STATION_ID)) != NULL) call_num = vp->strvalue; + if ((vp = pairfind(request->packet->vps, PW_NAS_IDENTIFIER)) != NULL) + nas_ident = vp->strvalue; /* * lock the file while reading/writing. @@ -744,7 +747,7 @@ session_zap(request, u.nas_address, u.nas_port, login, session_id, u.framed_address, - u.proto); + u.proto, nas_ident); } } } diff -ruN freeradius-1.1.7.orig/src/modules/rlm_sql/rlm_sql.c freeradius-1.1.7/src/modules/rlm_sql/rlm_sql.c --- freeradius-1.1.7.orig/src/modules/rlm_sql/rlm_sql.c 2007-07-17 04:59:08.000000000 -0800 +++ freeradius-1.1.7/src/modules/rlm_sql/rlm_sql.c 2007-09-20 16:14:24.000000000 -0800 @@ -1131,6 +1131,7 @@ int ret; uint32_t nas_addr = 0; int nas_port = 0; + char *nas_ident = NULL; /* If simul_count_query is not defined, we don't do any checking */ if (inst->config->simul_count_query[0] == 0) { @@ -1206,6 +1207,8 @@ ipno = vp->lvalue; if ((vp = pairfind(request->packet->vps, PW_CALLING_STATION_ID)) != NULL) call_num = vp->strvalue; + if ((vp = pairfind(request->packet->vps, PW_NAS_IDENTIFIER)) != NULL) + nas_ident = vp->strvalue; while (rlm_sql_fetch_row(sqlsocket, inst) == 0) { @@ -1270,7 +1273,7 @@ session_zap(request, nas_addr,nas_port,row[2],row[1], - framed_addr, proto); + framed_addr, proto, nas_ident); } }
Matthew Schumacher wrote:
The solution is to pass the NAS-Identifier attribute though to the session_zap function and have it output to the accounting modules instead of simply leaving it null.
A longer term solution is to permit the modules to update a "zap" packet, just like "request", "reply", etc. But that's somewhat difficult to do.
I the attached patch to do this and it works, except my radius server has become less than stable. It crashes here and there, but I can't figure out why. I'm not much of a C programmer so I'm hoping that someone on the list can look at my patch and point out what I did wrong. I suspect it's a typing issue or something.
I don't see anything obviously wrong... Alan DeKok.
participants (2)
-
Alan DeKok -
Matthew Schumacher