File pam-radius-auth-ip-conf.patch of Package pam_radius

diff -up pam_radius-release_2_0_0/src/pam_radius_auth.c.auth-ip-conf pam_radius-release_2_0_0/src/pam_radius_auth.c
--- pam_radius-release_2_0_0/src/pam_radius_auth.c.auth-ip-conf	2023-03-30 16:15:10.538286268 +0200
+++ pam_radius-release_2_0_0/src/pam_radius_auth.c	2023-03-30 16:16:58.163194003 +0200
@@ -60,6 +60,9 @@ static int _pam_parse(int argc, CONST ch
 	/* set the default prompt */
 	snprintf(conf->prompt, MAXPROMPT, "%s: ", DEFAULT_PROMPT);
 
+	conf->use_ipv4 = 1;
+	conf->use_ipv6 = 1;
+
 	/*
 	 *	If either is not there, then we can't parse anything.
 	 */
@@ -127,6 +130,14 @@ static int _pam_parse(int argc, CONST ch
 		} else if (!strncmp(*argv, "max_challenge=", 14)) {
 			conf->max_challenge = atoi(*argv+14);
 
+		} else if (!strncmp(*argv, "ipv4=", 5)) {
+			if (!strcmp(*argv + 5, "yes")) conf->use_ipv4 = 1;
+			if (!strcmp(*argv + 5, "no")) conf->use_ipv4 = 0;
+
+		} else if (!strncmp(*argv, "ipv6=", 5)) {
+			if (!strcmp(*argv + 5, "yes")) conf->use_ipv6 = 1;
+			if (!strcmp(*argv + 5, "no")) conf->use_ipv6 = 0;
+
 		} else if (!strcmp(*argv, "privilege_level")) {
 			conf->privilege_level = TRUE;
 
@@ -135,6 +146,12 @@ static int _pam_parse(int argc, CONST ch
 		}
 	}
 
+	if (!conf->use_ipv4 && !conf->use_ipv6) {
+		_pam_log(LOG_WARNING, "Cannot disable both IPv4 and IPv6'");
+
+		conf->use_ipv4 = 1;
+	}
+
 	return ctrl;
 }
 
@@ -527,8 +544,13 @@ static void cleanup(radius_server_t *ser
 	}
 }
 
-static int initialize_sockets(int *sockfd, int *sockfd6, struct sockaddr_storage *salocal4, struct sockaddr_storage *salocal6, char *vrf)
+static int initialize_sockets(radius_conf_t const *conf, int *sockfd, int *sockfd6, struct sockaddr_storage *salocal4, struct sockaddr_storage *salocal6, char *vrf)
 {
+	if (!conf->use_ipv4) {
+		*sockfd = -1;
+		goto use_ipv6;
+	}
+
 	/* open a socket.	Dies if it fails */
 	*sockfd = socket(AF_INET, SOCK_DGRAM, 0);
 	if (*sockfd < 0) {
@@ -566,10 +588,22 @@ static int initialize_sockets(int *sockf
 		return -1;
 	}
 
-	/* open a IPv6 socket.	Dies if it fails */
+	if (!conf->use_ipv6) {
+		*sockfd6 = -1;
+		return 0;
+	}
+
+use_ipv6:
+	/* open a IPv6 socket. */
 	*sockfd6 = socket(AF_INET6, SOCK_DGRAM, 0);
 	if (*sockfd6 < 0) {
 		char error_string[BUFFER_SIZE];
+
+		/*
+		 *	IPv6 can be disabled on localhost.
+		 */
+		if (errno == EAFNOSUPPORT) return 0;
+
 		get_error_string(errno, error_string, sizeof(error_string));
 		_pam_log(LOG_ERR, "Failed to open RADIUS IPv6 socket: %s\n", error_string);
 		return -1;
@@ -745,7 +779,8 @@ static int initialize(radius_conf_t *con
 		}
 
 		if (valid_src_ip == 0 || vrf[0]) {
-			if (initialize_sockets(&server->sockfd, &server->sockfd6, &salocal4, &salocal6, vrf) != 0) {
+			if (initialize_sockets(conf, &server->sockfd, &server->sockfd6, &salocal4, &salocal6, vrf) != 0) {
+
 				goto error;
 			}
 		}
@@ -766,7 +801,7 @@ static int initialize(radius_conf_t *con
 	((struct sockaddr *)&salocal4)->sa_family = AF_INET;
 	((struct sockaddr *)&salocal6)->sa_family = AF_INET6;
 
-	if (initialize_sockets(&conf->sockfd, &conf->sockfd6, &salocal4, &salocal6, NULL) != 0) {
+	if (initialize_sockets(conf, &conf->sockfd, &conf->sockfd6, &salocal4, &salocal6, NULL) != 0) {
 		goto error;
 	}
 
@@ -892,6 +927,14 @@ static int talk_radius(radius_conf_t *co
 			sockfd = server->sockfd6 != -1 ? server->sockfd6 : conf->sockfd6;
 		}
 
+		/*
+		 *	Is there a valid socket for this server + address family?  If not, skip it.
+		 */
+		if (sockfd < 0) {
+			ok = FALSE;
+			goto next;
+		}
+
 		total_length = ntohs(request->length);
 		server_tries = tries;
 	send:
diff -up pam_radius-release_2_0_0/src/pam_radius_auth.h.auth-ip-conf pam_radius-release_2_0_0/src/pam_radius_auth.h
--- pam_radius-release_2_0_0/src/pam_radius_auth.h.auth-ip-conf	2023-03-30 16:15:10.539286276 +0200
+++ pam_radius-release_2_0_0/src/pam_radius_auth.h	2023-03-30 16:17:06.352263072 +0200
@@ -150,6 +150,8 @@ typedef struct radius_server_t {
 typedef struct radius_conf_t {
 	radius_server_t *server;
 	int retries;
+	int use_ipv4;
+	int use_ipv6;
 	int localifdown;
 	char *client_id;
 	int accounting_bug;
openSUSE Build Service is sponsored by