From: Olaf Kirch <okir@suse.de>
Subject: make libtirpc honor /etc/bindresvport.blacklist

Signed-off-by: Olaf Kirch <okir@suse.de>

--- src/bindresvport.c	2015-04-23 21:22:56.986448281 +0200
+++ src/bindresvport.c	2015-04-23 21:48:06.501561665 +0200
@@ -39,7 +39,10 @@
 #include <netdb.h>
 #include <netinet/in.h>
 
+#include <stdio.h>
+#include <ctype.h>
 #include <errno.h>
+#include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
@@ -68,6 +71,80 @@
 #define ENDPORT (IPPORT_RESERVED - 1)
 #define NPORTS  (ENDPORT - STARTPORT + 1)
 
+/*
+ * Read the file /etc/bindresvport.blacklist, so that we don't bind
+ * to these ports.
+ */
+
+static int blacklist_read;
+static int *list;
+static int list_size = 0;
+
+static void
+load_blacklist (void)
+{
+  FILE *fp;
+  char *buf = NULL;
+  size_t buflen = 0;
+  int size = 0, ptr = 0;
+
+  blacklist_read = 1;
+
+  fp = fopen ("/etc/bindresvport.blacklist", "r");
+  if (NULL == fp)
+    return;
+
+  while (!feof (fp))
+    {
+      unsigned long port;
+      char *tmp, *cp;
+      ssize_t n = getline (&buf, &buflen, fp);
+      if (n < 1)
+        break;
+
+      cp = buf;
+      tmp = strchr (cp, '#');  /* remove comments */
+      if (tmp)
+        *tmp = '\0';
+      while (isspace ((int)*cp))    /* remove spaces and tabs */
+        ++cp;
+      if (*cp == '\0')        /* ignore empty lines */
+        continue;
+      if (cp[strlen (cp) - 1] == '\n')
+        cp[strlen (cp) - 1] = '\0';
+
+      port = strtoul (cp, &tmp, 0);
+      while (isspace(*tmp))
+        ++tmp;
+      if (*tmp != '\0' || (port == ULONG_MAX && errno == ERANGE))
+	continue;
+
+      /* Don't bother with out-of-range ports */
+      if (port < LOWPORT || port > ENDPORT)
+        continue;
+
+      if (ptr >= size)
+	{
+	  size += 10;
+	  list = realloc (list, size * sizeof (int));
+	  if (list == NULL)
+	    {
+	      free (buf);
+	      return;
+	    }
+	}
+
+      list[ptr++] = port;
+    }
+
+  fclose (fp);
+
+  if (buf)
+    free (buf);
+
+  list_size = ptr;
+}
+
 int
 bindresvport_sa(sd, sa)
         int sd;
@@ -87,6 +164,9 @@
 	int endport = ENDPORT;
 	int i;
 
+	if (!blacklist_read)
+		load_blacklist();
+
 	mutex_lock(&port_lock);
 	nports = ENDPORT - startport + 1;
 
@@ -132,12 +212,21 @@
         errno = EADDRINUSE;
 		again:
         for (i = 0; i < nports; ++i) {
-                *portp = htons(port++);
-                 if (port > endport) 
-                        port = startport;
-                res = bind(sd, sa, salen);
+		int j;
+
+		/* Check if this port is not blacklisted. */
+		for (j = 0; j < list_size; j++)
+			if (port == list[j])
+				goto try_next_port;
+
+		*portp = htons(port);
+		res = bind(sd, sa, salen);
 		if (res >= 0 || errno != EADDRINUSE)
 	                break;
+
+try_next_port:
+		if (++port > endport)
+			port = startport;
         }
 	if (i == nports && startport != LOWPORT) {
 	    startport = LOWPORT;