--- Makefile.orig Sat May 15 10:38:13 1999 +++ Makefile Sat May 15 09:44:05 1999 @@ -4,18 +4,26 @@ # +CC = gcc +CFLAGS = -Wall -g +LDFLAGS = # -s # tatic +LIBS = + # # Autoselect -lshadow and -lcrypt # ifneq ($(wildcard /usr/lib/libshadow.a),) -LSHADOW = -lshadow +LIBS += -lshadow +else +CFLAGS += -DNOSHADOW endif + ifneq ($(wildcard /usr/lib/libcrypt.a),) -LCRYPT = -lcrypt +LIBS += -lcrypt endif -CC = gcc -CFLAGS = -Wall -g # -DNOSHADOW -LDFLAGS = # -s # tatic -LIBS = $(LSHADOW) +ifneq ($(wildcard /usr/lib/libpthread.so),) +LIBS += -lpthread +CFLAGS += -DHAVE_THREADS +endif DBM = -DNDBM --- acct.c.orig Sat May 15 10:38:13 1999 +++ acct.c Sat May 15 09:57:24 1999 @@ -687,5 +687,5 @@ * rad_accounting: call both the old and new style accounting functions. */ -int rad_accounting(AUTH_REQ *authreq, int activefd) +int rad_accounting(AUTH_REQ *authreq) { int reply = 0; @@ -700,5 +700,5 @@ if (auth < 0) { - authfree(authreq); + authreq->finished = TRUE; return -1; } @@ -730,8 +730,8 @@ */ rad_send_reply(PW_ACCOUNTING_RESPONSE, - authreq, NULL, NULL, activefd); + authreq, NULL, NULL); } - authfree(authreq); + authreq->finished = TRUE; return reply ? 0 : -1; --- auth.c.orig Sat May 15 10:38:13 1999 +++ auth.c Sat May 15 10:26:55 1999 @@ -222,5 +222,5 @@ * 1 End check & return. */ -static int rad_check_password(AUTH_REQ *authreq, int activefd, +static int rad_check_password(AUTH_REQ *authreq, VALUE_PAIR *check_item, VALUE_PAIR *namepair, @@ -460,5 +460,5 @@ * process the hints and huntgroups file. */ -int rad_auth_init(AUTH_REQ *authreq, int activefd) +int rad_auth_init(AUTH_REQ *authreq) { VALUE_PAIR *namepair; @@ -474,7 +474,5 @@ log(L_ERR, "No username: [] (from nas %s)", nas_name2(authreq)); - pairfree(authreq->request); - memset(authreq, 0, sizeof(AUTH_REQ)); - free(authreq); + authfree(authreq); return -1; } @@ -512,5 +510,5 @@ namepair->strvalue, auth_name(authreq, 1)); rad_send_reply(PW_AUTHENTICATION_REJECT, authreq, - authreq->request, NULL, activefd); + authreq->request, NULL); authfree(authreq); return -1; @@ -523,5 +521,5 @@ * Process and reply to an authentication request */ -int rad_authenticate(AUTH_REQ *authreq, int activefd) +int rad_authenticate(AUTH_REQ *authreq) { VALUE_PAIR *namepair; @@ -598,8 +596,8 @@ namepair->strvalue, auth_name(authreq, 1)); rad_send_reply(PW_AUTHENTICATION_REJECT, authreq, - proxy_pairs, NULL, activefd); + proxy_pairs, NULL); pairfree(proxy_pairs); pairfree(user_reply); - authfree(authreq); + authreq->finished = TRUE; return -1; } @@ -613,5 +611,5 @@ if ((result = check_expiration(user_check, umsg, &user_msg))<0) break; - result = rad_check_password(authreq, activefd, user_check, + result = rad_check_password(authreq, user_check, namepair, pw_digest, &user_msg, userpass); if (result > 0) { @@ -621,7 +619,7 @@ * doesn't work anyway, so .. */ - authfree(authreq); pairfree(proxy_pairs); pairfree(user_reply); + authreq->finished = TRUE; return -1; } @@ -640,5 +638,5 @@ */ rad_send_reply(PW_AUTHENTICATION_REJECT, authreq, - user_reply, user_msg, activefd); + user_reply, user_msg); if (log_auth) { log(L_AUTH, @@ -672,5 +670,5 @@ } rad_send_reply(PW_AUTHENTICATION_REJECT, authreq, - user_reply, user_msg, activefd); + user_reply, user_msg); log(L_ERR, "Multiple logins: [%s] (from nas %s) max. %d%s", namepair->strvalue, @@ -704,5 +702,5 @@ "You are calling outside your allowed timespan\r\n"; rad_send_reply(PW_AUTHENTICATION_REJECT, authreq, - user_reply, user_msg, activefd); + user_reply, user_msg); log(L_ERR, "Outside allowed timespan: [%s]" " (from nas %s) time allowed: %s", @@ -738,7 +736,7 @@ */ if (result < 0) { - authfree(authreq); pairfree(user_check); pairfree(user_reply); + authreq->finished = TRUE; return 0; } @@ -792,5 +790,5 @@ user_msg = "\r\nAccess denied (external check failed)."; rad_send_reply(PW_AUTHENTICATION_REJECT, authreq, - user_reply, user_msg, activefd); + user_reply, user_msg); if (log_auth) { log(L_AUTH, @@ -800,7 +798,7 @@ auth_name(authreq, 1)); } - authfree(authreq); pairfree(user_check); pairfree(user_reply); + authreq->finished = TRUE; return 0; } @@ -844,5 +842,5 @@ rad_send_reply(PW_AUTHENTICATION_ACK, authreq, - user_reply, user_msg, activefd); + user_reply, user_msg); if (log_auth) { #if 1 /* Hide the password for `miquels' :) */ @@ -866,7 +864,7 @@ if (exec_program) free(exec_program); - authfree(authreq); pairfree(user_check); pairfree(user_reply); + authreq->finished = TRUE; return 0; --- radius.c.orig Sat May 15 10:38:14 1999 +++ radius.c Sat May 15 10:26:09 1999 @@ -23,9 +23,23 @@ #include "radiusd.h" -/* - * Make sure our buffer is aligned. - */ -static int i_send_buffer[1024]; -static char *send_buffer = (char *)i_send_buffer; +int send_packet(AUTH_REQ *authreq) +{ + struct sockaddr saremote; + struct sockaddr_in *sin; + + sin = (struct sockaddr_in *) &saremote; + memset ((char *) sin, '\0', sizeof (saremote)); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = htonl(authreq->ipaddr); + sin->sin_port = htons(authreq->udp_port); + + /* + * Send it to the user + */ + return sendto(authreq->activefd, (char *)authreq->reply, + (int) ntohs(authreq->reply->length), + (int)0, &saremote, sizeof(struct sockaddr_in)); + +} /* @@ -34,5 +48,5 @@ */ int rad_send_reply(int code, AUTH_REQ *authreq, VALUE_PAIR *oreply, - char *msg, int activefd) + char *msg) { AUTH_HDR *auth; @@ -48,6 +62,13 @@ VALUE_PAIR *reply; int vendorcode, vendorpec; + char *send_buffer; + + send_buffer = malloc(4096); + if (!send_buffer) { + exit(1); + } auth = (AUTH_HDR *)send_buffer; + authreq->reply = auth; reply = oreply; @@ -212,5 +233,5 @@ * Send it to the user */ - sendto(activefd, (char *)auth, (int)total_length, (int)0, + sendto(authreq->activefd, (char *)auth, (int)total_length, (int)0, &saremote, sizeof(struct sockaddr_in)); @@ -362,4 +383,6 @@ authreq->data = buffer; authreq->data_len = length; + authreq->reply = NULL; + authreq->finished = FALSE; /* @@ -499,5 +522,5 @@ */ static void send_challenge(AUTH_REQ *authreq, char *msg, - char *state, int activefd) + char *state) { AUTH_HDR *auth; @@ -574,5 +597,5 @@ * Send it to the user */ - sendto(activefd, (char *)auth, (int)total_length, (int)0, + sendto(authreq->activefd, (char *)auth, (int)total_length, (int)0, &saremote, sizeof(struct sockaddr_in)); } --- radiusd.c.orig Sat May 15 10:38:14 1999 +++ radiusd.c Sat May 15 10:31:28 1999 @@ -74,10 +74,4 @@ int acct_port; -/* - * Make sure recv_buffer is aligned properly. - */ -static int i_recv_buffer[1024]; -static char *recv_buffer = (char *)i_recv_buffer; - static int got_chld = 0; static int request_list_busy = 0; @@ -85,5 +79,5 @@ static int acctfd; static int spawn_flag; -static int acct_pid; +static int acct_pid = 0; static int radius_pid; static int need_reload = 0; @@ -95,5 +89,5 @@ #endif -typedef int (*FUNP)(AUTH_REQ *, int); +typedef int (*FUNP)(AUTH_REQ *); static int config_init(void); @@ -104,5 +98,5 @@ static int radrespond (AUTH_REQ *, int); -static void rad_spawn_child (AUTH_REQ *, int, FUNP); +static void rad_spawn_child (AUTH_REQ *, FUNP); /* @@ -384,8 +378,12 @@ } #endif + +#ifndef HAVE_THREADS /* * If we are in forking mode, we will start a child * to listen for Accounting requests. If not, we will * listen for them ourself. + * + * Threads: listen to all requests ourselves. */ if (spawn_flag) { @@ -405,4 +403,5 @@ } } else +#endif log(L_INFO, "Ready to process requests."); @@ -437,7 +436,10 @@ } if (sockfd >= 0 && FD_ISSET(sockfd, &readfds)) { + char *recv_buffer = malloc(4096); + if (!recv_buffer) exit(1); + salen = sizeof (saremote); result = recvfrom (sockfd, (char *) recv_buffer, - (int) sizeof(i_recv_buffer), + (int) 4096, (int) 0, &saremote, &salen); @@ -450,11 +452,15 @@ } else if (result < 0 && errno == EINTR) { + free(recv_buffer); result = 0; } } if (acctfd >=0 && FD_ISSET(acctfd, &readfds)) { + char *recv_buffer = malloc(4096); + if (!recv_buffer) exit(1); + salen = sizeof (saremote); result = recvfrom (acctfd, (char *) recv_buffer, - (int) sizeof(i_recv_buffer), + (int) 4096, (int) 0, &saremote, &salen); @@ -467,4 +473,5 @@ } else if (result < 0 && errno == EINTR) { + free(recv_buffer); result = 0; } @@ -498,4 +505,5 @@ dospawn = 0; fun = NULL; + authreq->activefd = activefd; /* @@ -508,5 +516,5 @@ * Check request against hints and huntgroups. */ - if ((e = rad_auth_init(authreq, activefd)) < 0) + if ((e = rad_auth_init(authreq)) < 0) return e; /*FALLTHRU*/ @@ -543,4 +551,7 @@ case PW_ACCOUNTING_REQUEST: +#ifdef HAVE_THREADS + dospawn = spawn_flag; +#endif fun = rad_accounting; break; @@ -565,7 +576,9 @@ if (fun) { if (dospawn) - rad_spawn_child(authreq, activefd, fun); - else - (*fun)(authreq, activefd); + rad_spawn_child(authreq, fun); + else { + (*fun)(authreq); + authfree(authreq); + } } @@ -581,5 +594,5 @@ * requests are filtered out). */ -static void rad_spawn_child(AUTH_REQ *authreq, int activefd, FUNP fun) +static void rad_spawn_child(AUTH_REQ *authreq, FUNP fun) { AUTH_REQ *curreq; @@ -587,5 +600,9 @@ UINT4 curtime; int request_count; +#ifndef HAVE_THREADS int child_pid; +#else + pthread_t child_pid; +#endif curtime = (UINT4)time(NULL); @@ -602,5 +619,15 @@ while(curreq != (AUTH_REQ *)NULL) { - if (curreq->child_pid == -1 && +#ifdef HAVE_THREADS + /* + * Child thread has told us it's finished: clean it up + */ + if (curreq->finished) { + pthread_join(curreq->child_pid, NULL); + curreq->child_pid = 0; + } +#endif + + if (curreq->child_pid == 0 && curreq->timestamp + CLEANUP_DELAY <= curtime) { /* @@ -609,11 +636,9 @@ if (prevreq == (AUTH_REQ *)NULL) { first_request = curreq->next; - pairfree(curreq->request); - free(curreq); + authfree(curreq); curreq = first_request; } else { prevreq->next = curreq->next; - pairfree(curreq->request); - free(curreq); + authfree(curreq); curreq = prevreq->next; } @@ -625,4 +650,19 @@ */ if (memcmp(curreq->vector, authreq->vector, 16) == 0) { +#ifdef HAVE_THREADS + if (curreq->reply) { + curreq->udp_port = authreq->udp_port; + send_packet(curreq); + log(L_ERR, + "Sending duplicate authentication response" + " to client %s - ID: %d", + client_name(authreq->ipaddr), authreq->id); + + authfree(authreq); + request_list_busy = 0; + sig_cleanup(SIGCHLD); + return; + } +#endif /* * This is a duplicate request - just drop it @@ -632,6 +672,5 @@ " from client %s - ID: %d", client_name(authreq->ipaddr), authreq->id); - pairfree(authreq->request); - free(authreq); + authfree(authreq); request_list_busy = 0; sig_cleanup(SIGCHLD); @@ -643,5 +682,5 @@ * delete it right now. */ - if (curreq->child_pid == -1) { + if (curreq->child_pid == 0) { curreq->timestamp = curtime - CLEANUP_DELAY; continue; @@ -656,5 +695,5 @@ } else { if (curreq->timestamp + MAX_REQUEST_TIME <= curtime && - curreq->child_pid != -1) { + curreq->child_pid != 0) { /* * This request seems to have hung - @@ -665,5 +704,5 @@ "Killing unresponsive child pid %d", child_pid); - curreq->child_pid = -1; + curreq->child_pid = 0; kill(child_pid, SIGTERM); } @@ -680,6 +719,5 @@ log(L_ERR, "Dropping request (too many): from client %s - ID: %d", client_name(authreq->ipaddr), authreq->id); - pairfree(authreq->request); - free(authreq); + authfree(authreq); request_list_busy = 0; @@ -693,5 +731,5 @@ */ authreq->next = (AUTH_REQ *)NULL; - authreq->child_pid = -1; + authreq->child_pid = 0; authreq->timestamp = curtime; @@ -701,4 +739,5 @@ prevreq->next = authreq; +#ifndef HAVE_THREADS /* * fork our child @@ -714,5 +753,5 @@ request_list_busy = 0; signal(SIGCHLD, SIG_DFL); - (*fun)(authreq, activefd); + (*fun)(authreq); exit(0); } @@ -722,5 +761,13 @@ */ authreq->child_pid = child_pid; - +#else + /* + * fork our child thread + */ + if (pthread_create(&authreq->child_pid, NULL, fun, authreq) < 0) { + log(L_ERR, "Thread create failed for request from nas %s - ID: %d", + nas_name2(authreq), authreq->id); + } +#endif request_list_busy = 0; sig_cleanup(SIGCHLD); @@ -767,5 +814,5 @@ while (curreq != (AUTH_REQ *)NULL) { if (curreq->child_pid == pid) { - curreq->child_pid = -1; + curreq->child_pid = 0; /* * FIXME: UINT4 ? --- radiusd.h.orig Sat May 15 10:38:14 1999 +++ radiusd.h Sat May 15 10:18:00 1999 @@ -71,4 +71,5 @@ typedef struct auth_req { + int activefd; UINT4 ipaddr; u_short udp_port; @@ -79,6 +80,12 @@ u_char username[AUTH_STRING_LEN]; VALUE_PAIR *request; +#ifndef HAVE_THREADS int child_pid; /* Process ID of child */ +#else + pthread_t child_pid; /* thread ID of child */ +#endif + AUTH_HDR *reply; /* reply to the client */ UINT4 timestamp; + int finished; u_char *data; /* Raw received data */ int data_len; @@ -149,4 +156,12 @@ #define VENDOR(x) (x >> 16) +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + /* * Global variables. @@ -177,5 +192,5 @@ /* acct.c */ -int rad_accounting(AUTH_REQ *, int); +int rad_accounting(AUTH_REQ *); int rad_accounting_orig(AUTH_REQ *, int, char *); int radzap(UINT4 nas, int port, char *user, time_t t); @@ -224,5 +239,6 @@ /* radius.c */ -int rad_send_reply(int, AUTH_REQ *, VALUE_PAIR *, char *, int); +int send_packet(AUTH_REQ *authreq); +int rad_send_reply(int, AUTH_REQ *, VALUE_PAIR *, char *); AUTH_REQ *radrecv (UINT4, u_short, u_char *, int); int calc_digest (u_char *, AUTH_REQ *); @@ -268,6 +284,6 @@ /* auth.c */ -int rad_auth_init(AUTH_REQ *authreq, int activefd); -int rad_authenticate (AUTH_REQ *, int); +int rad_auth_init(AUTH_REQ *authreq); +int rad_authenticate (AUTH_REQ *); /* exec.c */ --- radtest.c.orig Sat May 15 10:38:14 1999 +++ radtest.c Sat May 15 10:31:59 1999 @@ -99,5 +99,5 @@ printf("radrecv: Reply from host %lx code=%d, id=%d, length=%d\n", - (u_long)host, auth->code, auth->id, totallen); + (u_long)ntohl(host), auth->code, auth->id, totallen); /* --- sysdep.h.orig Sat May 15 10:38:14 1999 +++ sysdep.h Sat May 15 10:00:19 1999 @@ -54,3 +54,8 @@ #endif +#ifdef HAVE_THREADS +#include +#define kill pthread_kill +#endif + #endif /* SYSDEP_H_INCLUDED */ --- util.c.orig Sat May 15 10:38:14 1999 +++ util.c Sat May 15 10:15:38 1999 @@ -279,4 +279,6 @@ { pairfree(authreq->request); + free(authreq->data); + if (authreq->reply) free(authreq->reply); memset(authreq, 0, sizeof(AUTH_REQ)); free(authreq);