diff -urN pam_radius-1.3.17/USAGE pam_radius-1.3.17-retry/USAGE --- pam_radius-1.3.17/USAGE 2007-03-26 07:35:31.000000000 +0200 +++ pam_radius-1.3.17-retry/USAGE 2007-09-19 01:36:34.613667651 +0200 @@ -62,8 +62,10 @@ This feature may be disabled by using 'client_id='. i.e. A blank client ID. -retry = # - allow a number of retries before continuing to the next - authentication module +retry = # - allow a number of authentication retries before continuing + to the next configured server. This parameter acts as + the default when no (or invalid) server-specific retry is + configured. use_authtok - force the use of a previously entered password. This is needed for pluggable password strength checking diff -urN pam_radius-1.3.17/pam_radius_auth.c pam_radius-1.3.17-retry/pam_radius_auth.c --- pam_radius-1.3.17/pam_radius_auth.c 2007-03-26 11:36:13.000000000 +0200 +++ pam_radius-1.3.17-retry/pam_radius_auth.c 2007-09-19 01:19:27.001035047 +0200 @@ -592,6 +592,7 @@ struct sockaddr_in * s_in; int timeout; int line = 0; + int retries; /* the first time around, read the configuration file */ if ((fserver = fopen (conf_file, "r")) == (FILE*)NULL) { @@ -621,7 +622,8 @@ } timeout = 3; - if (sscanf(p, "%s %s %d", hostname, secret, &timeout) < 2) { + retries = -1; + if (sscanf(p, "%s %s %d %d", hostname, secret, &timeout, &retries) < 2) { _pam_log(LOG_ERR, "ERROR reading %s, line %d: Could not read hostname or secret\n", conf_file, line); continue; /* invalid line */ @@ -648,6 +650,12 @@ } else { server->timeout = timeout; } + + if ((retries < 0) || (retries > 10)) { + retries = conf->retries; + } + server->retries = retries; + server->next = NULL; } } @@ -764,7 +772,7 @@ */ static int talk_radius(radius_conf_t *conf, AUTH_HDR *request, AUTH_HDR *response, - char *password, char *old_password, int tries) + char *password, char *old_password, int do_retry) { int salen, total_length; fd_set set; @@ -814,7 +822,10 @@ get_accounting_vector(request, server); } - server_tries = tries; + server_tries = 1; + if (do_retry) { + server_tries += server->retries; + } send: /* send the packet */ if (sendto(conf->sockfd, (char *) request, total_length, 0, @@ -1175,7 +1186,7 @@ DPRINT(LOG_DEBUG, "Sending RADIUS request code %d", request->code); retval = talk_radius(&config, request, response, password, - NULL, config.retries + 1); + NULL, 1); PAM_FAIL_CHECK; DPRINT(LOG_DEBUG, "Got RADIUS response code %d", response->code); @@ -1223,7 +1234,7 @@ /* copy the state over from the servers response */ add_attribute(request, PW_STATE, a_state->data, a_state->length - 2); - retval = talk_radius(&config, request, response, resp2challenge, NULL, 1); + retval = talk_radius(&config, request, response, resp2challenge, NULL, 0); PAM_FAIL_CHECK; DPRINT(LOG_DEBUG, "Got response to challenge code %d", response->code); @@ -1347,7 +1358,7 @@ add_int_attribute(request, PW_ACCT_SESSION_TIME, time(NULL) - session_time); } - retval = talk_radius(&config, request, response, NULL, NULL, 1); + retval = talk_radius(&config, request, response, NULL, NULL, 0); PAM_FAIL_CHECK; /* oops! They don't have the right password. Complain and die. */ @@ -1466,7 +1477,7 @@ build_radius_packet(request, user, password, &config); add_int_attribute(request, PW_USER_SERVICE_TYPE, PW_AUTHENTICATE_ONLY); - retval = talk_radius(&config, request, response, password, NULL, 1); + retval = talk_radius(&config, request, response, password, NULL, 0); PAM_FAIL_CHECK; /* oops! They don't have the right password. Complain and die. */ @@ -1569,7 +1580,7 @@ build_radius_packet(request, user, new_password, &config); add_password(request, PW_OLD_PASSWORD, password, password); - retval = talk_radius(&config, request, response, new_password, password, 1); + retval = talk_radius(&config, request, response, new_password, password, 0); PAM_FAIL_CHECK; /* Whew! Done password changing, check for password acknowledge */ diff -urN pam_radius-1.3.17/pam_radius_auth.conf pam_radius-1.3.17-retry/pam_radius_auth.conf --- pam_radius-1.3.17/pam_radius_auth.conf 2000-07-10 21:18:42.000000000 +0200 +++ pam_radius-1.3.17-retry/pam_radius_auth.conf 2007-09-19 01:19:27.011673047 +0200 @@ -8,7 +8,7 @@ # lines. Blank lines or lines beginning with '#' are treated as # comments, and are ignored. The fields are: # -# server[:port] secret [timeout] +# server[:port] secret [timeout] [retries] # # the port name or number is optional. The default port name is # "radius", and is looked up from /etc/services The timeout field is @@ -22,9 +22,13 @@ # The timeout field controls how many seconds the module waits before # deciding that the server has failed to respond. # -# server[:port] shared_secret timeout (s) -127.0.0.1 secret 1 -other-server other-secret 3 +# The retries field indicates how many time the server should be retried +# before continuing to other servers. Valid values range from 0 to 10, +# other values are overridden by the retry= parameter. +# +# server[:port] shared_secret timeout (s) retries +127.0.0.1 secret 1 0 +other-server other-secret 3 3 # # having localhost in your radius configuration is a Good Thing. diff -urN pam_radius-1.3.17/pam_radius_auth.h pam_radius-1.3.17-retry/pam_radius_auth.h --- pam_radius-1.3.17/pam_radius_auth.h 2007-03-26 07:35:31.000000000 +0200 +++ pam_radius-1.3.17-retry/pam_radius_auth.h 2007-09-19 01:19:27.023667997 +0200 @@ -42,6 +42,7 @@ char *secret; int timeout; int accounting; + int retries; } radius_server_t; typedef struct radius_conf_t {