summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormweissen13 <mw@dermichi.com>2016-11-28 16:10:12 +0100
committermweissen13 <mw@dermichi.com>2016-11-28 16:10:12 +0100
commitd7a0fdf2c93ee136dadc658d1472af0f57db8025 (patch)
treed7ef0a438f430dc2aa698a288fd9e2a2bfb4bde2
parent1bff76afb3b893bb941762419daa2a14657c3b71 (diff)
downloadlibpam-radius-auth-d7a0fdf2c93ee136dadc658d1472af0f57db8025.tar.gz
libpam-radius-auth-d7a0fdf2c93ee136dadc658d1472af0f57db8025.zip
Replaced select with poll to allow file descriptors >FD_SETSIZE
-rw-r--r--src/pam_radius_auth.c42
-rw-r--r--src/pam_radius_auth.h1
2 files changed, 22 insertions, 21 deletions
diff --git a/src/pam_radius_auth.c b/src/pam_radius_auth.c
index e9b3034..41fc1d2 100644
--- a/src/pam_radius_auth.c
+++ b/src/pam_radius_auth.c
@@ -28,6 +28,7 @@
* 1.3.16 - Miscellaneous fixes (see CVS for history)
* 1.3.17 - Security fixes
* 1.4.0 - bind to any open port, add add force_prompt, max_challenge, prompt options
+ * 1.4.1 - replace select with poll to allow file descriptors >=1024
*
*
* This program is free software; you can redistribute it and/or modify
@@ -779,8 +780,8 @@ static int talk_radius(radius_conf_t *conf, AUTH_HDR *request, AUTH_HDR *respons
{
socklen_t salen;
int total_length;
- fd_set set;
- struct timeval tv;
+ struct pollfd pollfds[1];
+ int timeout_sec;
time_t now, end;
int rcode;
struct sockaddr saremote;
@@ -842,30 +843,29 @@ static int talk_radius(radius_conf_t *conf, AUTH_HDR *request, AUTH_HDR *respons
/* ************************************************************ */
/* Wait for the response, and verify it. */
salen = sizeof(struct sockaddr);
- tv.tv_sec = server->timeout; /* wait for the specified time */
- tv.tv_usec = 0;
- FD_ZERO(&set); /* clear out the set */
- FD_SET(conf->sockfd, &set); /* wait only for the RADIUS UDP socket */
+ timeout_sec = server->timeout; /* wait for the specified time */
+ pollfds[0].fd = conf->sockfd; /* wait only for the RADIUS UDP socket */
+ pollfds[0].events = POLLIN; /* wait for data to read */
time(&now);
- end = now + tv.tv_sec;
+ end = now + timeout_sec;
- /* loop, waiting for the select to return data */
+ /* loop, waiting for the poll to return data */
ok = TRUE;
while (ok) {
- rcode = select(conf->sockfd + 1, &set, NULL, NULL, &tv);
+ rcode = poll((struct pollfd*)&pollfds, 1, timeout_sec*1000);
- /* select timed out */
+ /* poll timed out */
if (rcode == 0) {
_pam_log(LOG_ERR, "RADIUS server %s failed to respond", server->hostname);
if (--server_tries) {
goto send;
}
ok = FALSE;
- break; /* exit from the select loop */
+ break; /* exit from the poll loop */
} else if (rcode < 0) {
- /* select had an error */
+ /* poll returned an error */
if (errno == EINTR) { /* we were interrupted */
time(&now);
@@ -874,12 +874,12 @@ static int talk_radius(radius_conf_t *conf, AUTH_HDR *request, AUTH_HDR *respons
server->hostname);
if (--server_tries) goto send;
ok = FALSE;
- break; /* exit from the select loop */
+ break; /* exit from the poll loop */
}
- tv.tv_sec = end - now;
- if (tv.tv_sec == 0) { /* keep waiting */
- tv.tv_sec = 1;
+ timeout_sec = end - now;
+ if (timeout_sec <= 0) { /* keep waiting */
+ timeout_sec = 1;
}
} else { /* not an interrupt, it was a real error */
@@ -889,8 +889,8 @@ static int talk_radius(radius_conf_t *conf, AUTH_HDR *request, AUTH_HDR *respons
break;
}
- /* the select returned OK */
- } else if (FD_ISSET(conf->sockfd, &set)) {
+ /* the poll call returned OK */
+ } else if (pollfds[0].revents & POLLIN) {
/* try to receive some data */
if ((total_length = recvfrom(conf->sockfd, (void *) response, BUFFER_SIZE,
@@ -951,14 +951,14 @@ static int talk_radius(radius_conf_t *conf, AUTH_HDR *request, AUTH_HDR *respons
}
/*
- * Whew! The select is done. It hasn't timed out, or errored out.
+ * Whew! The poll is done. It hasn't timed out, or errored out.
* It's our descriptor. We've got some data. It's the right size.
* The packet is valid.
- * NOW, we can skip out of the select loop, and process the packet
+ * NOW, we can skip out of the loop, and process the packet
*/
break;
}
- /* otherwise, we've got data on another descriptor, keep select'ing */
+ /* otherwise, we've got data on another descriptor, keep poll'ing */
}
/* go to the next server if this one didn't respond */
diff --git a/src/pam_radius_auth.h b/src/pam_radius_auth.h
index 95f262c..698a4e9 100644
--- a/src/pam_radius_auth.h
+++ b/src/pam_radius_auth.h
@@ -21,6 +21,7 @@
#include <netdb.h>
#include <fcntl.h>
#include <arpa/inet.h>
+#include <poll.h>
#if defined(HAVE_SECURITY_PAM_APPL_H)
# include <security/pam_appl.h>