Patches from "Alan Curry" <pacman-radius@cqc.com>
authoraland <aland>
Thu, 27 Jul 2000 18:46:32 +0000 (18:46 +0000)
committeraland <aland>
Thu, 27 Jul 2000 18:46:32 +0000 (18:46 +0000)
8. Small fixes that are *not* just repeats of things I've sent before:
     Reactivate the proxy retransmission code, which is dead code in CVS
     since it operates on the the old proxy_requests list which no longer has
     any requests added to it ever!

     Make distclean a little more clean (I had to clean and diff this tree 8
     times and it was getting annoying).

     Various cosmetic changes

Makefile
src/include/radiusd.h
src/main/auth.c
src/main/checkrad.pl.in
src/main/proxy.c
src/main/radclient.c
src/main/radiusd.c

index 1c896dc..e2e6dc2 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -51,7 +51,10 @@ common:
        done
 
 distclean: clean
-       rm -f config.cache config.log config.status
+       rm -f config.cache config.log config.status libtool \
+               src/include/radpaths.h src/include/stamp-h \
+               src/libltdl/config.log src/libltdl/config.status \
+               src/libltdl/libtool
        -find . ! -name configure.in -name \*.in -print | \
                sed 's/\.in$$//' | \
                while read file; do rm -f $$file; done
index 570d967..0aa85a1 100644 (file)
@@ -150,6 +150,8 @@ extern int          auth_port;
 extern int             acct_port;
 extern int             proxy_port;
 extern int             proxyfd;
+extern int             proxy_retry_count;
+extern int             proxy_retry_delay;
 
 /*
  *     Function prototypes.
@@ -206,8 +208,6 @@ int         pam_pass(char *name, char *passwd, const char *pamauth);
 /* proxy.c */
 int proxy_receive(REQUEST *request);
 int proxy_send(REQUEST *request);
-struct timeval *proxy_setuptimeout(struct timeval *);
-void proxy_retry(void);
 
 /* auth.c */
 char           *auth_name(char *buf, size_t buflen, REQUEST *request, int do_cli);
index dbac582..6bd214c 100644 (file)
@@ -62,7 +62,7 @@ char *auth_name(char *buf, size_t buflen, REQUEST *request, int do_cli)
        if ((pair = pairfind(request->packet->vps, PW_NAS_PORT_ID)) != NULL)
                port = pair->lvalue;
 
-       snprintf(buf, buflen, "from nas %.128s/S%d%s%.128s",
+       snprintf(buf, buflen, "from nas %.128s port %d%s%.128s",
                 nas_name2(request->packet), port,
                 (do_cli ? " cli " : ""), (do_cli ? (char *)cli->strvalue : ""));
 
index 0f1d9df..6892bf4 100644 (file)
@@ -317,16 +317,16 @@ sub multitech_snmp {
 #
 # The finger response format is version-dependent. To do this *right*, you
 # need to know exactly where the port number and username are. I know that
-# for 1.7.2, but for others I just guess.
+# for 1.7.2, and 3.0.4 but for others I just guess.
 # Oh yeah and on top of it all, the thing truncates usernames. --Pac.
 #
-# 1.7.2 looks like this:
+# 1.7.2 and 3.0.4 both look like this:
 #
 # 0    0 000 00:56 luser         pppfsm  Incoming PPP, ppp00, 10.0.0.1
 #
 # and the truncated ones look like this:
 #
-# 25   0 000 00:15 longnameluse..pppfsm  Incoming PPP, ppp25, 209.43.25.164
+# 25   0 000 00:15 longnameluse..pppfsm  Incoming PPP, ppp25, 10.0.0.26
 #
 # Yes, the fields run together. Long Usernames Considered Harmful.
 #
@@ -342,8 +342,8 @@ sub computone_finger {
                        $ver = $1;
                        next;
                }
-               # Check for 1.7.2
-               if ($ver eq '1.7.2') {
+               # Check for known versions
+               if ($ver eq '1.7.2' || $ver eq '3.0.4') {
                        if (/^\Q$ARGV[2]\E\s+\S+\s+\S+\s+\S+\s+\Q$trunc\E(\s+|\.\.)/) {
                                close FD;
                                return 1;
index 224fe99..f38499c 100644 (file)
@@ -29,8 +29,6 @@ static const char rcsid[] = "$Id$";
 
 static uint32_t        proxy_id = 1;
 
-static REQUEST *proxy_requests = NULL;
-
 static const int allowed[] = {
        PW_SERVICE_TYPE,
        PW_FRAMED_PROTOCOL,
@@ -171,6 +169,11 @@ int proxy_send(REQUEST *request)
        char                    *realmname;
        int                     replicating;
 
+#if 0  /* This looks bad to me... the timestamp is used below to figure the
+        * next_try. The request needs to "hang around" until either the
+        * other server sends a reply or the retry count has been exceeded.
+        * Until then, it should not be eligible for the time-based cleanup.
+        * --Pac. */
        /*
         *      Ensure that the request hangs around for a little
         *      while longer.
@@ -178,6 +181,7 @@ int proxy_send(REQUEST *request)
         *      FIXME: This is a hack... it should be more intelligent.
         */
        request->timestamp += 5;
+#endif
 
        /* Look for proxy/replicate signs */
        /* FIXME - What to do if multiple Proxy-To/Replicate-To attrs are
@@ -189,7 +193,7 @@ int proxy_send(REQUEST *request)
        if (proxypair) {
                realmpair = proxypair;
                replicating = 0;
-       } else ifreplicatepair) {
+       } else if (replicatepair) {
                realmpair = replicatepair;
                replicating = 1;
        } else {
@@ -325,94 +329,18 @@ int proxy_send(REQUEST *request)
        rad_send(request->proxy, (char *)realm->secret);
        memcpy(request->proxysecret, realm->secret, sizeof(request->proxysecret));
        request->proxy_is_replicate = replicating;
-       request->proxy_try_count = RETRY_COUNT - 1;
-       request->proxy_next_try = request->timestamp + RETRY_DELAY;
+       request->proxy_try_count = proxy_retry_count - 1;
+       request->proxy_next_try = request->timestamp + proxy_retry_delay;
        delaypair = pairfind(vps, PW_ACCT_DELAY_TIME);
        request->proxy->timestamp = request->timestamp - (delaypair ? delaypair->lvalue : 0);
 
+#if 0  /* You can't do this - the pairs are needed for the retries! --Pac. */
        /*
         *      We can free proxy->vps now, not needed anymore.
         */
        pairfree(request->proxy->vps);
        request->proxy->vps = NULL;
+#endif
 
        return replicating?2:1;
 }
-
-/*
- *  FIXME: Maybe keeping the proxy_requests list sorted by
- *  proxy_next_try would be cheaper than all this searching.
- */
-struct timeval *proxy_setuptimeout(struct timeval *tv)
-{
-       time_t now = time(NULL);
-       time_t difference, smallest;
-       int foundone = 0;
-       REQUEST *p;
-
-       smallest = 0;
-       for (p = proxy_requests; p; p = p->next) {
-               if (!p->proxy_is_replicate)
-                       continue;
-               difference = p->proxy_next_try - now;
-               if (!foundone) {
-                       foundone = 1;
-                       smallest = difference;
-               } else {
-                       if (difference < smallest)
-                               smallest = difference;
-               }
-       }
-
-       /*
-        *      Not found one, tell the server to wake up a second
-        *      later anyways, so that it can service the lists.
-        */
-       if ((!foundone) ||
-           (smallest == 0)) {
-               tv->tv_sec = 1;
-               tv->tv_usec = 0;
-               return tv;
-       }
-
-       tv->tv_sec = smallest;
-       tv->tv_usec = 0;
-       return tv;
-}
-
-void proxy_retry(void)
-{
-       time_t now = time(NULL);
-       REQUEST *p;
-
-       for (p = proxy_requests; p; p = p->next) {
-         if (p->proxy_next_try <= now) {
-           if (p->proxy_try_count) {
-             --p->proxy_try_count;
-             p->proxy_next_try = now + RETRY_DELAY;
-             
-             /* Fix up Acct-Delay-Time */
-             if (p->proxy->code == PW_ACCOUNTING_REQUEST) {
-               VALUE_PAIR *delaypair;
-               delaypair = pairfind(p->proxy->vps, PW_ACCT_DELAY_TIME);
-
-               if (!delaypair) {
-                 delaypair = paircreate(PW_ACCT_DELAY_TIME, PW_TYPE_INTEGER);
-                 if (!delaypair) {
-                   log(L_ERR|L_CONS, "no memory");
-                   exit(1);
-                 }
-                 pairadd(&p->proxy->vps, delaypair);
-               }
-               delaypair->lvalue = now - p->proxy->timestamp;
-               
-               /* Must recompile the valuepairs to wire format */
-               free(p->proxy->data);
-               p->proxy->data = NULL;
-             }
-             
-             rad_send(p->proxy, p->proxysecret);
-           }
-         }
-       }
-}
index 2281873..ea8a686 100644 (file)
@@ -71,7 +71,7 @@ static VALUE_PAIR *readvp(FILE *fp)
 
 static void usage(void)
 {
-       fprintf(stderr, "Usage: radclient [ -c count] [-d raddb ] [-f file] [-r retries] [-t timeout] [-i id] [-qvx]\n          server acct|auth <secret>\n");
+       fprintf(stderr, "Usage: radclient [-c count] [-d raddb] [-f file] [-r retries] [-t timeout]\n           [-i id] [-qvx] server acct|auth <secret>\n");
        
        fprintf(stderr, " -c count    Send 'count' packets.\n");
        fprintf(stderr, " -d raddb    Set dictionary directory.\n");
index d17ed97..d5862dd 100644 (file)
@@ -129,6 +129,8 @@ static int  rad_process (REQUEST *, int);
 static int     rad_clean_list(void);
 static REQUEST *rad_check_list(REQUEST *);
 static REQUEST *proxy_check_list(REQUEST *request);
+struct timeval *proxy_setuptimeout(struct timeval *);
+void           proxy_retry(void);
 #ifndef WITH_THREAD_POOL
 static int     rad_spawn_child(REQUEST *, RAD_REQUEST_FUNP);
 #else
@@ -1135,8 +1137,8 @@ int rad_respond(REQUEST *request, RAD_REQUEST_FUNP fun)
 {
        RADIUS_PACKET   *packet, *original;
        const char      *secret;
-       int             replicating;
        int             finished = FALSE;
+       int             proxy_sent = 0;
        
        /*
         *      Put the decoded packet into it's proper place.
@@ -1172,6 +1174,7 @@ int rad_respond(REQUEST *request, RAD_REQUEST_FUNP fun)
         *      attributes from the list of VP's.
         */
        if (request->proxy) {
+               int replicating;
                replicating = proxy_receive(request);
                if (replicating != 0) {
                        goto next_request;
@@ -1200,16 +1203,15 @@ int rad_respond(REQUEST *request, RAD_REQUEST_FUNP fun)
         */
        if (proxy_requests) {
                if (request->proxy == NULL) {
-                       int sent;
-                       sent = proxy_send(request);
+                       proxy_sent = proxy_send(request);
                        
                        /*
                         *      sent==1 means it's been proxied.  The child
                         *      is done handling the request, but the request
                         *      is NOT finished!
                         */
-                       if (sent == 1) {
-                               goto next_request;
+                       if (proxy_sent == 1) {
+                               goto postpone_request;
                        }
                }
        } else if ((request->packet->code == PW_AUTHENTICATION_REQUEST) &&
@@ -1251,6 +1253,13 @@ int rad_respond(REQUEST *request, RAD_REQUEST_FUNP fun)
         *      Hmm... cleaning them up in the child thread also seems
         *      to make the server run more efficiently!
         */
+
+       /*      If we proxied this request, it's not safe to delete it until
+        *      after the proxy reply
+        */
+       if (proxy_sent)
+               goto postpone_request;
+
        if (request->packet && request->packet->vps) {
                pairfree(request->packet->vps);
                request->packet->vps = NULL;
@@ -1290,6 +1299,8 @@ int rad_respond(REQUEST *request, RAD_REQUEST_FUNP fun)
        request->child_pid = NO_SUCH_CHILD_PID;
 #endif
        request->finished = finished; /* do as the LAST thing before exiting */
+
+ postpone_request:
        return 0;
 }
 
@@ -1989,8 +2000,8 @@ static void sig_hup(int sig)
 /*
  *     Do a proxy check of the REQUEST_LIST when using the new proxy code.
  *
- *     This function is here because it has to access the REQUEST_LIST
- *     structure, which is 'static' to this C file.
+ *     This function and the next two are here because they have to access
+ *     the REQUEST_LIST structure, which is 'static' to this C file.
  */
 static REQUEST *proxy_check_list(REQUEST *request)
 {
@@ -2044,10 +2055,10 @@ static REQUEST *proxy_check_list(REQUEST *request)
         *      If we haven't found the old request, complain.
         */
        if (oldreq == NULL) {
-               request_free(request);
                log(L_PROXY, "Unrecognized proxy reply from server %s - ID %d",
                    client_name(request->packet->src_ipaddr),
                    request->packet->id);
+               request_free(request);
                return NULL;
        }
 
@@ -2060,3 +2071,95 @@ static REQUEST *proxy_check_list(REQUEST *request)
        request_free(request);
        return oldreq;
 }
+
+struct timeval *proxy_setuptimeout(struct timeval *tv)
+{
+       time_t now = time(NULL);
+       time_t difference, smallest = 0;
+       int foundone = 0;
+       int id;
+       REQUEST *p;
+
+       if (proxy_requests) {
+               for (id = 0; id < 256; id++) {
+                       for (p = request_list[id].first_request; p; p = p->next)
+                       {
+                               if (!p->proxy)
+                                       continue;
+                               if (!p->proxy_is_replicate)
+                                       continue;
+                               difference = p->proxy_next_try - now;
+                               if (!foundone) {
+                                       foundone = 1;
+                                       smallest = difference;
+                               } else {
+                                       if (difference < smallest)
+                                               smallest = difference;
+                               }
+                       }
+               }
+       }
+
+       /*
+        *      Not found one, tell the server to wake up a second
+        *      later anyways, so that it can service the lists.
+        *
+        *      FIXME: It would be better if the select() would
+        *      actually wake up when there's something to do, and
+        *      no sooner. Waking up _every_ second is kludgy
+        */
+       if ((!foundone) ||
+           (smallest == 0)) {
+               tv->tv_sec = 1;
+               tv->tv_usec = 0;
+               return tv;
+       }
+
+       tv->tv_sec = smallest;
+       tv->tv_usec = 0;
+       return tv;
+}
+
+void proxy_retry(void)
+{
+       time_t now = time(NULL);
+       REQUEST *p;
+       int id;
+
+       for (id = 0; id < 256; id++) {
+         for (p = request_list[id].first_request; p; p = p->next) {
+           if (!p->proxy)
+             continue;
+           if (p->proxy_next_try <= now) {
+             if (p->proxy_try_count) {
+               --p->proxy_try_count;
+               p->proxy_next_try = now + proxy_retry_delay;
+               
+               /* Fix up Acct-Delay-Time */
+               if (p->proxy->code == PW_ACCOUNTING_REQUEST) {
+                 VALUE_PAIR *delaypair;
+                 delaypair = pairfind(p->proxy->vps, PW_ACCT_DELAY_TIME);
+
+                 if (!delaypair) {
+                   delaypair = paircreate(PW_ACCT_DELAY_TIME, PW_TYPE_INTEGER);
+                   if (!delaypair) {
+                     log(L_ERR|L_CONS, "no memory");
+                     exit(1);
+                   }
+                   pairadd(&p->proxy->vps, delaypair);
+                 }
+                 delaypair->lvalue = now - p->proxy->timestamp;
+                 
+                 /* Must recompile the valuepairs to wire format */
+                 free(p->proxy->data);
+                 p->proxy->data = NULL;
+               }
+               
+               rad_send(p->proxy, p->proxysecret);
+             } else {
+               p->finished = TRUE;
+             }
+           }
+         }
+       }
+}