]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
allow Simultaneous-Use to use IPv6 addresses, too
authorAlan T. DeKok <aland@freeradius.org>
Mon, 6 Sep 2021 12:39:03 +0000 (08:39 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 6 Sep 2021 12:41:16 +0000 (08:41 -0400)
src/include/radiusd.h
src/main/session.c
src/modules/rlm_couchbase/rlm_couchbase.c
src/modules/rlm_radutmp/rlm_radutmp.c
src/modules/rlm_sql/rlm_sql.c

index 0e485f8b661d69336a28099f171a05a824db64e7..69aa74b19be2506dca78b112e7c04cc030574438 100644 (file)
@@ -378,8 +378,8 @@ int         rad_accounting(REQUEST *);
 int            rad_coa_recv(REQUEST *request);
 
 /* session.c */
-int            rad_check_ts(uint32_t nasaddr, uint32_t nas_port, char const *user, char const *sessionid);
-int            session_zap(REQUEST *request, uint32_t nasaddr,
+int            rad_check_ts(fr_ipaddr_t const *nas_addr, uint32_t nas_port, char const *user, char const *sessionid);
+int            session_zap(REQUEST *request, fr_ipaddr_t const *nas_addr,
                            uint32_t nas_port, char const *user,
                            char const *sessionid, uint32_t cliaddr,
                            char proto, int session_time);
index e359010a1b90ad4d3d5cae2f4bae67e1051f5a4b..8dbf5a6f14b0bc86871bc251c81dfcf89e07ca5a 100644 (file)
@@ -34,7 +34,7 @@ RCSID("$Id$")
 /*
  *     End a session by faking a Stop packet to all accounting modules.
  */
-int session_zap(REQUEST *request, uint32_t nasaddr, uint32_t nas_port,
+int session_zap(REQUEST *request, fr_ipaddr_t const *nasaddr, uint32_t nas_port,
                char const *user,
                char const *sessionid, uint32_t cliaddr, char proto,
                int session_time)
@@ -64,6 +64,8 @@ int session_zap(REQUEST *request, uint32_t nasaddr, uint32_t nas_port,
 
 #define IPPAIR(n,v) PAIR(n,v,vp_ipaddr)
 
+#define IPV6PAIR(n,v) PAIR(n,v,vp_ipv6addr)
+
 #define STRINGPAIR(n,v) do { \
          if(!(vp = fr_pair_afrom_num(stopreq->packet,n, 0))) { \
                talloc_free(stopreq); \
@@ -75,7 +77,12 @@ int session_zap(REQUEST *request, uint32_t nasaddr, uint32_t nas_port,
        } while(0)
 
        INTPAIR(PW_ACCT_STATUS_TYPE, PW_STATUS_STOP);
-       IPPAIR(PW_NAS_IP_ADDRESS, nasaddr);
+
+       if (nasaddr->af == AF_INET) {
+               IPPAIR(PW_NAS_IP_ADDRESS, nasaddr->ipaddr.ip4addr.s_addr);
+       } else {
+               IPV6PAIR(PW_NAS_IPV6_ADDRESS, nasaddr->ipaddr.ip6addr);
+       }
 
        INTPAIR(PW_EVENT_TIMESTAMP, 0);
        vp->vp_date = time(NULL);
@@ -127,29 +134,25 @@ int session_zap(REQUEST *request, uint32_t nasaddr, uint32_t nas_port,
  *             1 The user is logged in.
  *             2 Some error occured.
  */
-int rad_check_ts(uint32_t nasaddr, uint32_t nas_port, char const *user,
+int rad_check_ts(fr_ipaddr_t const *nasaddr, uint32_t nas_port, char const *user,
                 char const *session_id)
 {
        pid_t   pid, child_pid;
        int     status;
-       char    address[16];
+       char    address[64];
        char    port[11];
        RADCLIENT *cl;
-       fr_ipaddr_t ipaddr;
-
-       ipaddr.af = AF_INET;
-       ipaddr.ipaddr.ip4addr.s_addr = nasaddr;
 
        /*
         *      Find NAS type.
         */
-       cl = client_find_old(&ipaddr);
+       cl = client_find_old(nasaddr);
        if (!cl) {
                /*
                 *  Unknown NAS, so trusting radutmp.
                 */
                DEBUG2("checkrad: Unknown NAS %s, not checking",
-                      ip_ntoa(address, nasaddr));
+                      inet_ntop(nasaddr->af, &(nasaddr->ipaddr), address, sizeof(address)));
                return 1;
        }
 
@@ -202,8 +205,8 @@ int rad_check_ts(uint32_t nasaddr, uint32_t nas_port, char const *user,
         */
        closefrom(3);
 
-       ip_ntoa(address, nasaddr);
-       snprintf(port, 11, "%u", nas_port);
+       inet_ntop(nasaddr->af, &(nasaddr->ipaddr), address, sizeof(address));
+       snprintf(port, sizeof(port), "%u", nas_port);
 
 #ifdef __EMX__
        /* OS/2 can't directly execute scripts then we call the command
@@ -223,7 +226,7 @@ int rad_check_ts(uint32_t nasaddr, uint32_t nas_port, char const *user,
        exit(2);
 }
 #else
-int rad_check_ts(UNUSED uint32_t nasaddr, UNUSED unsigned int nas_port,
+int rad_check_ts(fr_ipaddr_t const *nasaddr, UNUSED unsigned int nas_port,
                 UNUSED char const *user, UNUSED char const *session_id)
 {
        ERROR("Simultaneous-Use is not supported");
@@ -234,7 +237,7 @@ int rad_check_ts(UNUSED uint32_t nasaddr, UNUSED unsigned int nas_port,
 #else
 /* WITH_SESSION_MGMT */
 
-int session_zap(UNUSED REQUEST *request, UNUSED uint32_t nasaddr, UNUSED uint32_t nas_port,
+int session_zap(UNUSED REQUEST *request, fr_ipaddr_t const *nasaddr, UNUSED uint32_t nas_port,
                UNUSED char const *user,
                UNUSED char const *sessionid, UNUSED uint32_t cliaddr, UNUSED char proto,
                UNUSED int session_time)
@@ -242,7 +245,7 @@ int session_zap(UNUSED REQUEST *request, UNUSED uint32_t nasaddr, UNUSED uint32_
        return RLM_MODULE_FAIL;
 }
 
-int rad_check_ts(UNUSED uint32_t nasaddr, UNUSED unsigned int nas_port,
+int rad_check_ts(fr_ipaddr_t const *nasaddr, UNUSED unsigned int nas_port,
                 UNUSED char const *user, UNUSED char const *session_id)
 {
        ERROR("Simultaneous-Use is not supported");
index 7b3707668fc42161dc0ba63d73b35d8f46909951..4f5efb8db2b92fcfc2aab82be6137bc9838c39e1 100644 (file)
@@ -468,7 +468,7 @@ static rlm_rcode_t mod_checksimul(void *instance, REQUEST *request) {
        char *user_name = NULL;                /* user name from accounting document */
        char *session_id = NULL;               /* session id from accounting document */
        char *cs_id = NULL;                    /* calling station id from accounting document */
-       uint32_t nas_addr = 0;                 /* nas address from accounting document */
+       fr_ipaddr_t nas_addr;                 /* nas address from accounting document */
        uint32_t nas_port = 0;                 /* nas port from accounting document */
        uint32_t framed_ip_addr = 0;           /* framed ip address from accounting document */
        char framed_proto = 0;                 /* framed proto from accounting document */
@@ -689,7 +689,8 @@ static rlm_rcode_t mod_checksimul(void *instance, REQUEST *request) {
                if (mod_attribute_to_element("NAS-IP-Address", inst->map, &element) == 0) {
                        /* attempt to get and nas address element */
                        if (json_object_object_get_ex(cookie->jobj, element, &jval)){
-                               nas_addr = inet_addr(json_object_get_string(jval));
+                               nas_addr.af = AF_INET;
+                               nas_addr.ipaddr.ip4addr.s_addr = inet_addr(json_object_get_string(jval));
                        }
                }
 
@@ -702,7 +703,7 @@ static rlm_rcode_t mod_checksimul(void *instance, REQUEST *request) {
                }
 
                /* check terminal server */
-               int check = rad_check_ts(nas_addr, nas_port, user_name, session_id);
+               int check = rad_check_ts(&nas_addr, nas_port, user_name, session_id);
 
                /* take action based on check return */
                if (check == 0) {
@@ -737,7 +738,7 @@ static rlm_rcode_t mod_checksimul(void *instance, REQUEST *request) {
                                }
 
                                /* zap session */
-                               session_zap(request, nas_addr, nas_port, user_name, session_id,
+                               session_zap(request, &nas_addr, nas_port, user_name, session_id,
                                            framed_ip_addr, framed_proto, session_time);
                        }
                } else if (check == 1) {
index b542618153854a72d8e2a7432a5523c5e1c3b6cb..e58f34da2a6693cdb17b8e6adc93d67ca92c261f 100644 (file)
@@ -660,6 +660,8 @@ static rlm_rcode_t CC_HINT(nonnull) mod_checksimul(void *instance, REQUEST *requ
         */
        request->simul_count = 0;
        while (read(fd, &u, sizeof(u)) == sizeof(u)) {
+               fr_ipaddr_t nasaddr;
+
                if (((strncmp(expanded, u.login, RUT_NAMESIZE) == 0) || (!inst->case_sensitive &&
                    (strncasecmp(expanded, u.login, RUT_NAMESIZE) == 0))) && (u.type == P_LOGIN)) {
                        char session_id[sizeof(u.session_id) + 1];
@@ -688,20 +690,23 @@ static rlm_rcode_t CC_HINT(nonnull) mod_checksimul(void *instance, REQUEST *requ
                        memset(utmp_login, 0, sizeof(utmp_login));
                        memcpy(utmp_login, u.login, sizeof(u.login));
 
+                       nasaddr.af = AF_INET;
+                       nasaddr.ipaddr.ip4addr.s_addr = u.nas_address;
+
                        /*
                         *      rad_check_ts may take seconds
                         *      to return, and we don't want
                         *      to block everyone else while
                         *      that's happening.  */
                        rad_unlockfd(fd, LOCK_LEN);
-                       rcode = rad_check_ts(u.nas_address, u.nas_port, utmp_login, session_id);
+                       rcode = rad_check_ts(&nasaddr, u.nas_port, utmp_login, session_id);
                        rad_lockfd(fd, LOCK_LEN);
 
                        if (rcode == 0) {
                                /*
                                 *      Stale record - zap it.
                                 */
-                               session_zap(request, u.nas_address, u.nas_port, expanded, session_id,
+                               session_zap(request, &nasaddr, u.nas_port, expanded, session_id,
                                            u.framed_address, u.proto, 0);
                        }
                        else if (rcode == 1) {
index 90fe371b0757d4aa364f70f6eb743e68073487e8..7edd9cec361b0d5191d88dd8434440f71cd9ecd9 100644 (file)
@@ -1604,7 +1604,7 @@ static rlm_rcode_t mod_checksimul(void *instance, REQUEST * request)
        char const              *call_num = NULL;
        VALUE_PAIR              *vp;
        int                     ret;
-       uint32_t                nas_addr = 0;
+       fr_ipaddr_t             nas_addr;
        uint32_t                nas_port = 0;
 
        char                    *expanded = NULL;
@@ -1727,14 +1727,18 @@ static rlm_rcode_t mod_checksimul(void *instance, REQUEST * request)
                }
 
                if (row[3]) {
-                       nas_addr = inet_addr(row[3]);
+                       if (fr_pton(&nas_addr, row[3], -1, AF_INET, false) < 0) {
+                               RDEBUG("Cannot parse '%s' as an IPv4 or an IPv6 address", row[3]);
+                               rcode = RLM_MODULE_FAIL;
+                               goto finish;
+                       }
                }
 
                if (row[4]) {
                        nas_port = atoi(row[4]);
                }
 
-               check = rad_check_ts(nas_addr, nas_port, row[2], row[1]);
+               check = rad_check_ts(&nas_addr, nas_port, row[2], row[1]);
                if (check == 0) {
                        /*
                         *      Stale record - zap it.
@@ -1754,7 +1758,7 @@ static rlm_rcode_t mod_checksimul(void *instance, REQUEST * request)
                                }
                                if ((num_rows > 8) && row[8])
                                        sess_time = atoi(row[8]);
-                               session_zap(request, nas_addr, nas_port,
+                               session_zap(request, &nas_addr, nas_port,
                                            row[2], row[1], framed_addr,
                                            proto, sess_time);
                        }