Accepting request 213958 from network

Trying again, with some more changes added... (forwarded request 213905 from okir)

OBS-URL: https://build.opensuse.org/request/show/213958
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/rpcbind?expand=0&rev=34
This commit is contained in:
Stephan Kulow 2014-01-17 10:09:20 +00:00 committed by Git OBS Bridge
commit a98c6dfb5c
25 changed files with 2381 additions and 1399 deletions

View File

@ -0,0 +1,26 @@
From a45afd335e7e5965666ac5052a54b3981796b351 Mon Sep 17 00:00:00 2001
From: Olaf Kirch <okir@suse.de>
Date: Tue, 20 Aug 2013 11:43:13 +0200
Subject: [PATCH 01/13] Silence a warning about setgroups() being implicitly
defined
Signed-off-by: Olaf Kirch <okir@suse.de>
---
src/rpcbind.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/rpcbind.c b/src/rpcbind.c
index 83dbe93..7ed72bc 100644
--- a/src/rpcbind.c
+++ b/src/rpcbind.c
@@ -65,6 +65,7 @@
#include <syslog.h>
#include <err.h>
#include <pwd.h>
+#include <grp.h>
#include <string.h>
#include <errno.h>
#ifdef HAVE_NSS_H
--
1.7.12.4

View File

@ -1,731 +0,0 @@
Delivered-To: cr@cristianrodriguez.net
Received: by 10.180.126.41 with SMTP id mv9cs133382wib;
Thu, 22 Dec 2011 17:05:49 -0800 (PST)
Received: by 10.213.15.203 with SMTP id l11mr2621843eba.5.1324602347791;
Thu, 22 Dec 2011 17:05:47 -0800 (PST)
Return-Path: <teg@jklm.no>
Received: from mx2.suse.de (cantor2.suse.de. [195.135.220.15])
by mx.google.com with ESMTPS id q2si6918918eef.172.2011.12.22.17.05.47
(version=TLSv1/SSLv3 cipher=OTHER);
Thu, 22 Dec 2011 17:05:47 -0800 (PST)
Received-SPF: softfail (google.com: domain of transitioning teg@jklm.no does not designate 195.135.220.15 as permitted sender) client-ip=195.135.220.15;
Authentication-Results: mx.google.com; spf=softfail (google.com: domain of transitioning teg@jklm.no does not designate 195.135.220.15 as permitted sender) smtp.mail=teg@jklm.no
Received: from mail-lpp01m010-f48.google.com (mail-lpp01m010-f48.google.com [209.85.215.48])
(using TLSv1 with cipher RC4-SHA (128/128 bits))
(No client certificate requested)
by mx2.suse.de (Postfix) with ESMTP id 3ACC28738D
for <crrodriguez@opensuse.org>; Fri, 23 Dec 2011 02:05:46 +0100 (CET)
Received: by laam7 with SMTP id m7so4957545laa.35
for <crrodriguez@opensuse.org>; Thu, 22 Dec 2011 17:05:45 -0800 (PST)
Received: by 10.152.110.6 with SMTP id hw6mr10613571lab.37.1324602344510;
Thu, 22 Dec 2011 17:05:44 -0800 (PST)
Received: from localhost.localdomain (cm-84.212.224.43.getinternet.no. [84.212.224.43])
by mx.google.com with ESMTPS id 5sm9033897lah.0.2011.12.22.17.05.42
(version=TLSv1/SSLv3 cipher=OTHER);
Thu, 22 Dec 2011 17:05:43 -0800 (PST)
From: Tom Gundersen <teg@jklm.no>
To: linux-nfs@vger.kernel.org
Cc: Tom Gundersen <teg@jklm.no>, Steve Dickson <steved@redhat.com>,
systemd-devel@lists.freedesktop.org,
=?UTF-8?q?Cristian=20Rodr=C3=ADguez?= <crrodriguez@opensuse.org>
Subject: [PATCH] rpcbind: add support for systemd socket activation
Date: Fri, 23 Dec 2011 02:05:27 +0100
Message-Id: <1324602327-1789-1-git-send-email-teg@jklm.no>
X-Mailer: git-send-email 1.7.8
In-Reply-To: <4EEFCBF0.1070407@opensuse.org>
References: <4EEFCBF0.1070407@opensuse.org>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Making rpcbind sockect activated will greatly simplify
its integration in systemd systems. In essence, other services
may now assume that rpcbind is always available, even during very
early boot. This means that we no longer need to worry about any
ordering dependencies.
This is based on a patch originally posted by Lennart Poettering:
<http://permalink.gmane.org/gmane.linux.nfs/33774>.
That patch was not merged due to the lack of a shared library and
as systemd was seen to be too Fedora specific.
Systemd now provides a shared library, and it is shipped by defalt in
OpenSUSE in addition to Fedora, and it is available in Debain, Gentoo,
Arch, and others.
This version of the patch has three changes from the original:
* It uses the shared library.
* It comes with unit files.
* It is rebased on top of master.
Please review the patch with "git show -b" or otherwise ignoring the
whitespace changes, or it will be extremely difficult to read.
Comments welcome.
v2: correctly enable systemd code at compile time
handle the case where not all the required sockets were supplied
listen on udp/tcp port 111 in addition to /var/run/rpcbind.sock
do not daemonize
Original-patch-by: Lennart Poettering <lennart@poettering.net>
Cc: Steve Dickson <steved@redhat.com>
Cc: systemd-devel@lists.freedesktop.org
Cc: Cristian Rodríguez <crrodriguez@opensuse.org>
Signed-off-by: Tom Gundersen <teg@jklm.no>
---
Thanks to Cristian for testing. The testcase I had been using was entirely flawed,
the code did in fact not work at all. Sorry about that!
This time around it should work :-)
Makefile.am | 15 ++
configure.in | 11 +
src/rpcbind.c | 467 +++++++++++++++++++++++++-------------------
systemd/.gitignore | 1 +
systemd/rpcbind.service.in | 9 +
systemd/rpcbind.socket | 12 ++
6 files changed, 316 insertions(+), 199 deletions(-)
create mode 100644 systemd/.gitignore
create mode 100644 systemd/rpcbind.service.in
create mode 100644 systemd/rpcbind.socket
diff --git a/Makefile.am b/Makefile.am
index 9fa608e..194b467 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -38,6 +38,21 @@ rpcbind_SOURCES = \
src/warmstart.c
rpcbind_LDADD = $(TIRPC_LIBS)
+if SYSTEMD
+AM_CPPFLAGS += $(SYSTEMD_CFLAGS) -DSYSTEMD
+
+rpcbind_LDADD += $(SYSTEMD_LIBS)
+
+systemd/rpcbind.service: systemd/rpcbind.service.in Makefile
+ sed -e 's,@bindir\@,$(bindir),g' \
+ < $< > $@ || rm $@
+
+systemdsystemunit_DATA = \
+ systemd/rpcbind.service \
+ systemd/rpcbind.socket
+
+endif
+
rpcinfo_SOURCES = src/rpcinfo.c
rpcinfo_LDADD = $(TIRPC_LIBS)
diff --git a/configure.in b/configure.in
index 2b67720..397d52d 100644
--- a/configure.in
+++ b/configure.in
@@ -29,6 +29,17 @@ AC_SUBST([rpcuser], [$with_rpcuser])
PKG_CHECK_MODULES([TIRPC], [libtirpc])
+PKG_PROG_PKG_CONFIG
+AC_ARG_WITH([systemdsystemunitdir],
+ AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
+ [], [with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)])
+ if test "x$with_systemdsystemunitdir" != xno; then
+ AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
+ PKG_CHECK_MODULES([SYSTEMD], [libsystemd-daemon])
+ fi
+AM_CONDITIONAL(SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ])
+
+
AS_IF([test x$enable_libwrap = xyes], [
AC_CHECK_LIB([wrap], [hosts_access], ,
AC_MSG_ERROR([libwrap support requested but unable to find libwrap]))
diff --git a/src/rpcbind.c b/src/rpcbind.c
index 24e069b..a87ce05 100644
--- a/src/rpcbind.c
+++ b/src/rpcbind.c
@@ -56,6 +56,9 @@
#include <netinet/in.h>
#endif
#include <arpa/inet.h>
+#ifdef SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
#include <fcntl.h>
#include <netdb.h>
#include <stdio.h>
@@ -281,6 +284,7 @@ init_transport(struct netconfig *nconf)
u_int32_t host_addr[4]; /* IPv4 or IPv6 */
struct sockaddr_un sun;
mode_t oldmask;
+ int n = 0;
res = NULL;
if ((nconf->nc_semantics != NC_TPI_CLTS) &&
@@ -300,141 +304,285 @@ init_transport(struct netconfig *nconf)
}
#endif
- /*
- * XXX - using RPC library internal functions. For NC_TPI_CLTS
- * we call this later, for each socket we like to bind.
- */
- if (nconf->nc_semantics != NC_TPI_CLTS) {
- if ((fd = __rpc_nconf2fd(nconf)) < 0) {
- syslog(LOG_ERR, "cannot create socket for %s",
- nconf->nc_netid);
- return (1);
- }
- }
-
if (!__rpc_nconf2sockinfo(nconf, &si)) {
syslog(LOG_ERR, "cannot get information for %s",
nconf->nc_netid);
return (1);
}
- if ((strcmp(nconf->nc_netid, "local") == 0) ||
- (strcmp(nconf->nc_netid, "unix") == 0)) {
- memset(&sun, 0, sizeof sun);
- sun.sun_family = AF_LOCAL;
- unlink(_PATH_RPCBINDSOCK);
- strcpy(sun.sun_path, _PATH_RPCBINDSOCK);
- addrlen = SUN_LEN(&sun);
- sa = (struct sockaddr *)&sun;
- } else {
- /* Get rpcbind's address on this transport */
-
- memset(&hints, 0, sizeof hints);
- hints.ai_flags = AI_PASSIVE;
- hints.ai_family = si.si_af;
- hints.ai_socktype = si.si_socktype;
- hints.ai_protocol = si.si_proto;
+#ifdef SYSTEMD
+ n = sd_listen_fds(0);
+ if (n < 0) {
+ syslog(LOG_ERR, "failed to acquire systemd scokets: %s", strerror(-n));
+ return 1;
}
- if (nconf->nc_semantics == NC_TPI_CLTS) {
- /*
- * If no hosts were specified, just bind to INADDR_ANY. Otherwise
- * make sure 127.0.0.1 is added to the list.
- */
- nhostsbak = nhosts;
- nhostsbak++;
- hosts = realloc(hosts, nhostsbak * sizeof(char *));
- if (nhostsbak == 1)
- hosts[0] = "*";
- else {
- if (hints.ai_family == AF_INET) {
- hosts[nhostsbak - 1] = "127.0.0.1";
- } else if (hints.ai_family == AF_INET6) {
- hosts[nhostsbak - 1] = "::1";
- } else
- return 1;
+
+ /* Try to find if one of the systemd sockets we were given match
+ * our netconfig structure. */
+
+ for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) {
+ struct __rpc_sockinfo si_other;
+ union {
+ struct sockaddr sa;
+ struct sockaddr_un un;
+ struct sockaddr_in in4;
+ struct sockaddr_in6 in6;
+ struct sockaddr_storage storage;
+ } sa;
+ socklen_t addrlen = sizeof(sa);
+
+ if (!__rpc_fd2sockinfo(fd, &si_other)) {
+ syslog(LOG_ERR, "cannot get information for fd %i", fd);
+ return 1;
}
- /*
- * Bind to specific IPs if asked to
- */
- checkbind = 0;
- while (nhostsbak > 0) {
- --nhostsbak;
- /*
- * XXX - using RPC library internal functions.
- */
+ if (si.si_af != si_other.si_af ||
+ si.si_socktype != si_other.si_socktype ||
+ si.si_proto != si_other.si_proto)
+ continue;
+
+ if (getsockname(fd, &sa.sa, &addrlen) < 0) {
+ syslog(LOG_ERR, "failed to query socket name: %s",
+ strerror(errno));
+ goto error;
+ }
+
+ /* Copy the address */
+ taddr.addr.maxlen = taddr.addr.len = addrlen;
+ taddr.addr.buf = malloc(addrlen);
+ if (taddr.addr.buf == NULL) {
+ syslog(LOG_ERR,
+ "cannot allocate memory for %s address",
+ nconf->nc_netid);
+ goto error;
+ }
+ memcpy(taddr.addr.buf, &sa, addrlen);
+
+ my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr,
+ RPC_MAXDATASIZE, RPC_MAXDATASIZE);
+ if (my_xprt == (SVCXPRT *)NULL) {
+ syslog(LOG_ERR, "%s: could not create service",
+ nconf->nc_netid);
+ goto error;
+ }
+ }
+
+ /* if none of the systemd sockets matched, we set up the socket in
+ * the normal way:
+ */
+#endif
+
+ if(my_xprt == (SVCXPRT *)NULL) {
+
+ /*
+ * XXX - using RPC library internal functions. For NC_TPI_CLTS
+ * we call this later, for each socket we like to bind.
+ */
+ if (nconf->nc_semantics != NC_TPI_CLTS) {
if ((fd = __rpc_nconf2fd(nconf)) < 0) {
syslog(LOG_ERR, "cannot create socket for %s",
nconf->nc_netid);
return (1);
}
- switch (hints.ai_family) {
- case AF_INET:
- if (inet_pton(AF_INET, hosts[nhostsbak],
- host_addr) == 1) {
- hints.ai_flags &= AI_NUMERICHOST;
- } else {
- /*
- * Skip if we have an AF_INET6 adress.
- */
- if (inet_pton(AF_INET6,
- hosts[nhostsbak], host_addr) == 1)
- continue;
+ }
+
+ if ((strcmp(nconf->nc_netid, "local") == 0) ||
+ (strcmp(nconf->nc_netid, "unix") == 0)) {
+ memset(&sun, 0, sizeof sun);
+ sun.sun_family = AF_LOCAL;
+ unlink(_PATH_RPCBINDSOCK);
+ strcpy(sun.sun_path, _PATH_RPCBINDSOCK);
+ addrlen = SUN_LEN(&sun);
+ sa = (struct sockaddr *)&sun;
+ } else {
+ /* Get rpcbind's address on this transport */
+
+ memset(&hints, 0, sizeof hints);
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_family = si.si_af;
+ hints.ai_socktype = si.si_socktype;
+ hints.ai_protocol = si.si_proto;
+ }
+ if (nconf->nc_semantics == NC_TPI_CLTS) {
+ /*
+ * If no hosts were specified, just bind to INADDR_ANY. Otherwise
+ * make sure 127.0.0.1 is added to the list.
+ */
+ nhostsbak = nhosts;
+ nhostsbak++;
+ hosts = realloc(hosts, nhostsbak * sizeof(char *));
+ if (nhostsbak == 1)
+ hosts[0] = "*";
+ else {
+ if (hints.ai_family == AF_INET) {
+ hosts[nhostsbak - 1] = "127.0.0.1";
+ } else if (hints.ai_family == AF_INET6) {
+ hosts[nhostsbak - 1] = "::1";
+ } else
+ return 1;
+ }
+
+ /*
+ * Bind to specific IPs if asked to
+ */
+ checkbind = 0;
+ while (nhostsbak > 0) {
+ --nhostsbak;
+ /*
+ * XXX - using RPC library internal functions.
+ */
+ if ((fd = __rpc_nconf2fd(nconf)) < 0) {
+ syslog(LOG_ERR, "cannot create socket for %s",
+ nconf->nc_netid);
+ return (1);
+ }
+ switch (hints.ai_family) {
+ case AF_INET:
+ if (inet_pton(AF_INET, hosts[nhostsbak],
+ host_addr) == 1) {
+ hints.ai_flags &= AI_NUMERICHOST;
+ } else {
+ /*
+ * Skip if we have an AF_INET6 adress.
+ */
+ if (inet_pton(AF_INET6,
+ hosts[nhostsbak], host_addr) == 1)
+ continue;
+ }
+ break;
+ case AF_INET6:
+ if (inet_pton(AF_INET6, hosts[nhostsbak],
+ host_addr) == 1) {
+ hints.ai_flags &= AI_NUMERICHOST;
+ } else {
+ /*
+ * Skip if we have an AF_INET adress.
+ */
+ if (inet_pton(AF_INET, hosts[nhostsbak],
+ host_addr) == 1)
+ continue;
+ }
+ break;
+ default:
+ break;
}
- break;
- case AF_INET6:
- if (inet_pton(AF_INET6, hosts[nhostsbak],
- host_addr) == 1) {
- hints.ai_flags &= AI_NUMERICHOST;
- } else {
+
+ /*
+ * If no hosts were specified, just bind to INADDR_ANY
+ */
+ if (strcmp("*", hosts[nhostsbak]) == 0)
+ hosts[nhostsbak] = NULL;
+
+ if ((aicode = getaddrinfo(hosts[nhostsbak],
+ servname, &hints, &res)) != 0) {
+ if ((aicode = getaddrinfo(hosts[nhostsbak],
+ "portmapper", &hints, &res)) != 0) {
+ syslog(LOG_ERR,
+ "cannot get local address for %s: %s",
+ nconf->nc_netid, gai_strerror(aicode));
+ continue;
+ }
+ }
+ addrlen = res->ai_addrlen;
+ sa = (struct sockaddr *)res->ai_addr;
+ oldmask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
+ if (bind(fd, sa, addrlen) != 0) {
+ syslog(LOG_ERR, "cannot bind %s on %s: %m",
+ (hosts[nhostsbak] == NULL) ? "*" :
+ hosts[nhostsbak], nconf->nc_netid);
+ if (res != NULL)
+ freeaddrinfo(res);
+ continue;
+ } else
+ checkbind++;
+ (void) umask(oldmask);
+
+ /* Copy the address */
+ taddr.addr.maxlen = taddr.addr.len = addrlen;
+ taddr.addr.buf = malloc(addrlen);
+ if (taddr.addr.buf == NULL) {
+ syslog(LOG_ERR,
+ "cannot allocate memory for %s address",
+ nconf->nc_netid);
+ if (res != NULL)
+ freeaddrinfo(res);
+ return 1;
+ }
+ memcpy(taddr.addr.buf, sa, addrlen);
+#ifdef RPCBIND_DEBUG
+ if (debugging) {
/*
- * Skip if we have an AF_INET adress.
+ * for debugging print out our universal
+ * address
*/
- if (inet_pton(AF_INET, hosts[nhostsbak],
- host_addr) == 1)
- continue;
+ char *uaddr;
+ struct netbuf nb;
+ int sa_size = 0;
+
+ nb.buf = sa;
+ switch( sa->sa_family){
+ case AF_INET:
+ sa_size = sizeof (struct sockaddr_in);
+ break;
+ case AF_INET6:
+ sa_size = sizeof (struct sockaddr_in6);
+ break;
+ }
+ nb.len = nb.maxlen = sa_size;
+ uaddr = taddr2uaddr(nconf, &nb);
+ (void) fprintf(stderr,
+ "rpcbind : my address is %s\n", uaddr);
+ (void) free(uaddr);
+ }
+#endif
+ my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr,
+ RPC_MAXDATASIZE, RPC_MAXDATASIZE);
+ if (my_xprt == (SVCXPRT *)NULL) {
+ syslog(LOG_ERR, "%s: could not create service",
+ nconf->nc_netid);
+ goto error;
}
- break;
- default:
- break;
}
-
- /*
- * If no hosts were specified, just bind to INADDR_ANY
- */
- if (strcmp("*", hosts[nhostsbak]) == 0)
- hosts[nhostsbak] = NULL;
-
- if ((aicode = getaddrinfo(hosts[nhostsbak],
- servname, &hints, &res)) != 0) {
- if ((aicode = getaddrinfo(hosts[nhostsbak],
- "portmapper", &hints, &res)) != 0) {
- syslog(LOG_ERR,
- "cannot get local address for %s: %s",
- nconf->nc_netid, gai_strerror(aicode));
- continue;
- }
+ if (!checkbind)
+ return 1;
+ } else { /* NC_TPI_COTS */
+ if ((strcmp(nconf->nc_netid, "local") != 0) &&
+ (strcmp(nconf->nc_netid, "unix") != 0)) {
+ if ((aicode = getaddrinfo(NULL, servname, &hints, &res))!= 0) {
+ if ((aicode = getaddrinfo(NULL, "portmapper", &hints, &res))!= 0) {
+ printf("cannot get local address for %s: %s", nconf->nc_netid, gai_strerror(aicode));
+ syslog(LOG_ERR,
+ "cannot get local address for %s: %s",
+ nconf->nc_netid, gai_strerror(aicode));
+ return 1;
+ }
+ }
+ addrlen = res->ai_addrlen;
+ sa = (struct sockaddr *)res->ai_addr;
}
- addrlen = res->ai_addrlen;
- sa = (struct sockaddr *)res->ai_addr;
oldmask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
- if (bind(fd, sa, addrlen) != 0) {
- syslog(LOG_ERR, "cannot bind %s on %s: %m",
- (hosts[nhostsbak] == NULL) ? "*" :
- hosts[nhostsbak], nconf->nc_netid);
+ __rpc_fd2sockinfo(fd, &si);
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on,
+ sizeof(on)) != 0) {
+ syslog(LOG_ERR, "cannot set SO_REUSEADDR on %s",
+ nconf->nc_netid);
if (res != NULL)
freeaddrinfo(res);
- continue;
- } else
- checkbind++;
+ return 1;
+ }
+ if (bind(fd, sa, addrlen) < 0) {
+ syslog(LOG_ERR, "cannot bind %s: %m", nconf->nc_netid);
+ if (res != NULL)
+ freeaddrinfo(res);
+ return 1;
+ }
(void) umask(oldmask);
/* Copy the address */
- taddr.addr.maxlen = taddr.addr.len = addrlen;
+ taddr.addr.len = taddr.addr.maxlen = addrlen;
taddr.addr.buf = malloc(addrlen);
if (taddr.addr.buf == NULL) {
- syslog(LOG_ERR,
- "cannot allocate memory for %s address",
+ syslog(LOG_ERR, "cannot allocate memory for %s address",
nconf->nc_netid);
if (res != NULL)
freeaddrinfo(res);
@@ -443,116 +591,37 @@ init_transport(struct netconfig *nconf)
memcpy(taddr.addr.buf, sa, addrlen);
#ifdef RPCBIND_DEBUG
if (debugging) {
- /*
- * for debugging print out our universal
- * address
- */
+ /* for debugging print out our universal address */
char *uaddr;
struct netbuf nb;
- int sa_size = 0;
+ int sa_size2 = 0;
nb.buf = sa;
switch( sa->sa_family){
case AF_INET:
- sa_size = sizeof (struct sockaddr_in);
+ sa_size2 = sizeof (struct sockaddr_in);
break;
case AF_INET6:
- sa_size = sizeof (struct sockaddr_in6);
+ sa_size2 = sizeof (struct sockaddr_in6);
break;
}
- nb.len = nb.maxlen = sa_size;
+ nb.len = nb.maxlen = sa_size2;
uaddr = taddr2uaddr(nconf, &nb);
- (void) fprintf(stderr,
- "rpcbind : my address is %s\n", uaddr);
+ (void) fprintf(stderr, "rpcbind : my address is %s\n",
+ uaddr);
(void) free(uaddr);
}
#endif
- my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr,
- RPC_MAXDATASIZE, RPC_MAXDATASIZE);
+
+ listen(fd, SOMAXCONN);
+
+ my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr, RPC_MAXDATASIZE, RPC_MAXDATASIZE);
if (my_xprt == (SVCXPRT *)NULL) {
- syslog(LOG_ERR, "%s: could not create service",
- nconf->nc_netid);
+ syslog(LOG_ERR, "%s: could not create service",
+ nconf->nc_netid);
goto error;
}
}
- if (!checkbind)
- return 1;
- } else { /* NC_TPI_COTS */
- if ((strcmp(nconf->nc_netid, "local") != 0) &&
- (strcmp(nconf->nc_netid, "unix") != 0)) {
- if ((aicode = getaddrinfo(NULL, servname, &hints, &res))!= 0) {
- if ((aicode = getaddrinfo(NULL, "portmapper", &hints, &res))!= 0) {
- printf("cannot get local address for %s: %s", nconf->nc_netid, gai_strerror(aicode));
- syslog(LOG_ERR,
- "cannot get local address for %s: %s",
- nconf->nc_netid, gai_strerror(aicode));
- return 1;
- }
- }
- addrlen = res->ai_addrlen;
- sa = (struct sockaddr *)res->ai_addr;
- }
- oldmask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
- __rpc_fd2sockinfo(fd, &si);
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on,
- sizeof(on)) != 0) {
- syslog(LOG_ERR, "cannot set SO_REUSEADDR on %s",
- nconf->nc_netid);
- if (res != NULL)
- freeaddrinfo(res);
- return 1;
- }
- if (bind(fd, sa, addrlen) < 0) {
- syslog(LOG_ERR, "cannot bind %s: %m", nconf->nc_netid);
- if (res != NULL)
- freeaddrinfo(res);
- return 1;
- }
- (void) umask(oldmask);
-
- /* Copy the address */
- taddr.addr.len = taddr.addr.maxlen = addrlen;
- taddr.addr.buf = malloc(addrlen);
- if (taddr.addr.buf == NULL) {
- syslog(LOG_ERR, "cannot allocate memory for %s address",
- nconf->nc_netid);
- if (res != NULL)
- freeaddrinfo(res);
- return 1;
- }
- memcpy(taddr.addr.buf, sa, addrlen);
-#ifdef RPCBIND_DEBUG
- if (debugging) {
- /* for debugging print out our universal address */
- char *uaddr;
- struct netbuf nb;
- int sa_size2 = 0;
-
- nb.buf = sa;
- switch( sa->sa_family){
- case AF_INET:
- sa_size2 = sizeof (struct sockaddr_in);
- break;
- case AF_INET6:
- sa_size2 = sizeof (struct sockaddr_in6);
- break;
- }
- nb.len = nb.maxlen = sa_size2;
- uaddr = taddr2uaddr(nconf, &nb);
- (void) fprintf(stderr, "rpcbind : my address is %s\n",
- uaddr);
- (void) free(uaddr);
- }
-#endif
-
- listen(fd, SOMAXCONN);
-
- my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr, RPC_MAXDATASIZE, RPC_MAXDATASIZE);
- if (my_xprt == (SVCXPRT *)NULL) {
- syslog(LOG_ERR, "%s: could not create service",
- nconf->nc_netid);
- goto error;
- }
}
#ifdef PORTMAP
diff --git a/systemd/.gitignore b/systemd/.gitignore
new file mode 100644
index 0000000..b7b4561
--- /dev/null
+++ b/systemd/.gitignore
@@ -0,0 +1 @@
+rpcbind.service
diff --git a/systemd/rpcbind.service.in b/systemd/rpcbind.service.in
new file mode 100644
index 0000000..58ae5de
--- /dev/null
+++ b/systemd/rpcbind.service.in
@@ -0,0 +1,9 @@
+[Unit]
+Description=RPC Bind
+
+[Service]
+ExecStart=@bindir@/rpcbind -w -f
+
+[Install]
+WantedBy=multi-user.target
+Also=rpcbind.socket
diff --git a/systemd/rpcbind.socket b/systemd/rpcbind.socket
new file mode 100644
index 0000000..ad5fd62
--- /dev/null
+++ b/systemd/rpcbind.socket
@@ -0,0 +1,12 @@
+[Unit]
+Description=RPCbind Server Activation Socket
+Wants=rpcbind.target
+Before=rpcbind.target
+
+[Socket]
+ListenStream=/var/run/rpcbind.sock
+ListenStream=111
+ListenDatagram=111
+
+[Install]
+WantedBy=sockets.target
--
1.7.8

View File

@ -0,0 +1,69 @@
From 6ec7d84694e560c7e1968b1ba02cbf69802da290 Mon Sep 17 00:00:00 2001
From: Olaf Kirch <okir@suse.de>
Date: Tue, 20 Aug 2013 11:43:51 +0200
Subject: [PATCH 02/13] Remove obsolete function in6_fillscopeid
This seems to be an old remnant from the very early days of IPv6
when the kernel would include the ifindex in the link-local
addresses returned by getifaddrs(). This is no longer the case on
Linux, so the code is a no-op.
A no-op that makes gcc throw warnings about illegal type-punning.
Signed-off-by: Olaf Kirch <okir@suse.de>
---
src/util.c | 24 ------------------------
1 file changed, 24 deletions(-)
diff --git a/src/util.c b/src/util.c
index 9a5fb69..a6c835b 100644
--- a/src/util.c
+++ b/src/util.c
@@ -71,9 +71,6 @@ static struct sockaddr_in6 *local_in6;
#endif
static int bitmaskcmp __P((void *, void *, void *, int));
-#ifdef INET6
-static void in6_fillscopeid __P((struct sockaddr_in6 *));
-#endif
/*
* For all bits set in "mask", compare the corresponding bits in
@@ -93,26 +90,6 @@ bitmaskcmp(void *dst, void *src, void *mask, int bytelen)
}
/*
- * Similar to code in ifconfig.c. Fill in the scope ID for link-local
- * addresses returned by getifaddrs().
- */
-#ifdef INET6
-static void
-in6_fillscopeid(struct sockaddr_in6 *sin6)
-{
- u_int16_t ifindex;
-
- if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
- ifindex = ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]);
- if (sin6->sin6_scope_id == 0 && ifindex != 0) {
- sin6->sin6_scope_id = ifindex;
- *(u_int16_t *)&sin6->sin6_addr.s6_addr[2] = 0;
- }
- }
-}
-#endif
-
-/*
* Find a server address that can be used by `caller' to contact
* the local service specified by `serv_uaddr'. If `clnt_uaddr' is
* non-NULL, it is used instead of `caller' as a hint suggesting
@@ -209,7 +186,6 @@ addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr,
* a link-local address then use the scope id to see
* which one.
*/
- in6_fillscopeid(SA2SIN6(ifsa));
if (IN6_IS_ADDR_LINKLOCAL(&SA2SIN6ADDR(ifsa)) &&
IN6_IS_ADDR_LINKLOCAL(&SA2SIN6ADDR(caller_sa)) &&
IN6_IS_ADDR_LINKLOCAL(&SA2SIN6ADDR(hint_sa))) {
--
1.7.12.4

View File

@ -0,0 +1,30 @@
From 921c65c2f9fb023124bccd74a009a1faf1fbd476 Mon Sep 17 00:00:00 2001
From: Olaf Kirch <okir@suse.de>
Date: Tue, 20 Aug 2013 09:31:03 +0200
Subject: [PATCH 03/13] configure: fix the case when --with-rpcuser is not
given
If --with-rpcuser is not given, we would compile the code with
-DRPCBIND_USER='' which is clearly not intended
Signed-off-by: Olaf Kirch <okir@suse.de>
---
configure.ac | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index 2b67720..1cf42d3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -23,7 +23,7 @@ AC_ARG_WITH([statedir],
AC_SUBST([statedir], [$with_statedir])
AC_ARG_WITH([rpcuser],
- AS_HELP_STRING([--with-rpcuser=ARG], [use ARG for RPC @<:@default=root@:>@]),
+ AS_HELP_STRING([--with-rpcuser=ARG], [use ARG for RPC @<:@default=root@:>@])
,, [with_rpcuser=root])
AC_SUBST([rpcuser], [$with_rpcuser])
--
1.7.12.4

View File

@ -0,0 +1,50 @@
From 77ccf636447cce013f84ee7b7b09f0fe3adcec87 Mon Sep 17 00:00:00 2001
From: Olaf Kirch <okir@suse.de>
Date: Tue, 20 Aug 2013 09:11:45 +0200
Subject: [PATCH 04/13] In init_transport, move creation of COTS sockets
closer to where they are used
Signed-off-by: Olaf Kirch <okir@suse.de>
---
src/rpcbind.c | 18 ++++++------------
1 file changed, 6 insertions(+), 12 deletions(-)
diff --git a/src/rpcbind.c b/src/rpcbind.c
index 7ed72bc..f562f7a 100644
--- a/src/rpcbind.c
+++ b/src/rpcbind.c
@@ -309,18 +309,6 @@ init_transport(struct netconfig *nconf)
}
#endif
- /*
- * XXX - using RPC library internal functions. For NC_TPI_CLTS
- * we call this later, for each socket we like to bind.
- */
- if (nconf->nc_semantics != NC_TPI_CLTS) {
- if ((fd = __rpc_nconf2fd(nconf)) < 0) {
- syslog(LOG_ERR, "cannot create socket for %s",
- nconf->nc_netid);
- return (1);
- }
- }
-
if (!__rpc_nconf2sockinfo(nconf, &si)) {
syslog(LOG_ERR, "cannot get information for %s",
nconf->nc_netid);
@@ -487,6 +475,12 @@ init_transport(struct netconfig *nconf)
if (!checkbind)
return 1;
} else { /* NC_TPI_COTS */
+ if ((fd = __rpc_nconf2fd(nconf)) < 0) {
+ syslog(LOG_ERR, "cannot create socket for %s",
+ nconf->nc_netid);
+ return (1);
+ }
+
if ((strcmp(nconf->nc_netid, "local") != 0) &&
(strcmp(nconf->nc_netid, "unix") != 0)) {
if ((aicode = getaddrinfo(NULL, servname, &hints, &res))!= 0) {
--
1.7.12.4

View File

@ -0,0 +1,49 @@
From 369cc50768a9929ef0adf4b58987ce08cc3675b6 Mon Sep 17 00:00:00 2001
From: Olaf Kirch <okir@suse.de>
Date: Tue, 20 Aug 2013 09:12:49 +0200
Subject: [PATCH 05/13] The use of AI_NUMERICHOST in init_transport() is
broken.
In its current form, when seeing a dotted quad or a numeric IPv6 address,
it will clear all flags in hints.ai_flags (which has been set to AI_PASSIVE
a few lines above).
What this code should really be doing is to *set* AI_NUMERICHOST if and only
if it sees a numeric address.
Signed-off-by: Olaf Kirch <okir@suse.de>
---
src/rpcbind.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/rpcbind.c b/src/rpcbind.c
index f562f7a..896d509 100644
--- a/src/rpcbind.c
+++ b/src/rpcbind.c
@@ -365,11 +365,13 @@ init_transport(struct netconfig *nconf)
nconf->nc_netid);
return (1);
}
+
+ hints.ai_flags &= ~AI_NUMERICHOST;
switch (hints.ai_family) {
case AF_INET:
if (inet_pton(AF_INET, hosts[nhostsbak],
host_addr) == 1) {
- hints.ai_flags &= AI_NUMERICHOST;
+ hints.ai_flags |= AI_NUMERICHOST;
} else {
/*
* Skip if we have an AF_INET6 adress.
@@ -382,7 +384,7 @@ init_transport(struct netconfig *nconf)
case AF_INET6:
if (inet_pton(AF_INET6, hosts[nhostsbak],
host_addr) == 1) {
- hints.ai_flags &= AI_NUMERICHOST;
+ hints.ai_flags |= AI_NUMERICHOST;
} else {
/*
* Skip if we have an AF_INET adress.
--
1.7.12.4

View File

@ -0,0 +1,494 @@
From 9cea37f331fe76a9690e93677999cc47f3f70631 Mon Sep 17 00:00:00 2001
From: Olaf Kirch <okir@suse.de>
Date: Tue, 20 Aug 2013 09:26:37 +0200
Subject: [PATCH 06/13] First part of init_transport refactoring
This patch splits out the hostname resolution and socket creation/binding
code into individual functions, and calls those from init_transport instead.
Signed-off-by: Olaf Kirch <okir@suse.de>
---
src/rpcbind.c | 407 +++++++++++++++++++++++++++++-----------------------------
1 file changed, 201 insertions(+), 206 deletions(-)
diff --git a/src/rpcbind.c b/src/rpcbind.c
index 896d509..a7dcc0e 100644
--- a/src/rpcbind.c
+++ b/src/rpcbind.c
@@ -268,6 +268,186 @@ main(int argc, char *argv[])
}
/*
+ * Helper function - maybe this should go elsewhere
+ */
+static void
+sockaddr2netbuf(const struct sockaddr *sa, socklen_t alen, struct netbuf *abuf)
+{
+ abuf->len = abuf->maxlen = alen;
+ abuf->buf = malloc(alen);
+
+ if (abuf->buf == NULL) {
+ syslog(LOG_ERR, "not enough memory for address buffer (%u bytes)", alen);
+ exit(1);
+ }
+
+ memcpy(abuf->buf, sa, alen);
+}
+
+/*
+ * Perform hostname lookup
+ */
+static int
+do_hostname_lookup(struct netconfig *nconf, const char *hostname, struct netbuf *abuf)
+{
+ struct addrinfo hints, *res = NULL;
+ struct __rpc_sockinfo si;
+ int aicode;
+
+ if (!__rpc_nconf2sockinfo(nconf, &si)) {
+ syslog(LOG_ERR, "cannot get sockinfo for %s", nconf->nc_netid);
+ return -1;
+ }
+
+ memset(&hints, 0, sizeof hints);
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_family = si.si_af;
+ hints.ai_socktype = si.si_socktype;
+ hints.ai_protocol = si.si_proto;
+
+ if (hostname == NULL) {
+ /*
+ * If no hosts were specified, just bind to INADDR_ANY
+ */
+ } else {
+ u_int32_t host_addr[4]; /* IPv4 or IPv6 */
+
+ switch (hints.ai_family) {
+ case AF_INET:
+ if (inet_pton(AF_INET, hostname, host_addr) == 1)
+ hints.ai_flags |= AI_NUMERICHOST;
+ else if (inet_pton(AF_INET6, hostname, host_addr) == 1)
+ return 0;
+ break;
+
+ case AF_INET6:
+ if (inet_pton(AF_INET6, hostname, host_addr) == 1)
+ hints.ai_flags |= AI_NUMERICHOST;
+ else if (inet_pton(AF_INET, hostname, host_addr) == 1)
+ return 0;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if ((aicode = getaddrinfo(hostname, servname, &hints, &res)) != 0) {
+ if ((aicode = getaddrinfo(hostname, "portmapper", &hints, &res)) != 0) {
+ syslog(LOG_ERR,
+ "cannot get %s address for %s: %s",
+ nconf->nc_netid,
+ hostname? hostname : "*",
+ gai_strerror(aicode));
+ return 0;
+ }
+ }
+
+ /* XXX: should we loop over all addresses returned? */
+ sockaddr2netbuf(res->ai_addr, res->ai_addrlen, abuf);
+ freeaddrinfo(res);
+ return 1;
+}
+
+static void
+build_local_addr(const char *path, struct netbuf *abuf)
+{
+ struct sockaddr_un sun;
+
+ memset(&sun, 0, sizeof sun);
+ sun.sun_family = AF_LOCAL;
+ strcpy(sun.sun_path, path);
+
+ sockaddr2netbuf((struct sockaddr *) &sun, SUN_LEN(&sun), abuf);
+}
+
+/*
+ * Create a bound socket
+ *
+ * Return values:
+ * -1 means error or problem with this netconfig entry.
+ */
+static int
+create_transport_socket(struct netconfig *nconf, const char *hostname, struct netbuf *abuf, int *fdret)
+{
+ int fd = -1;
+ int r;
+ mode_t oldmask;
+
+ *fdret = -1;
+
+ if (strcmp(nconf->nc_netid, "local") == 0 || strcmp(nconf->nc_netid, "unix") == 0) {
+ unlink(_PATH_RPCBINDSOCK);
+ build_local_addr(_PATH_RPCBINDSOCK, abuf);
+ } else {
+ r = do_hostname_lookup(nconf, hostname, abuf);
+ if (r <= 0)
+ return r;
+ }
+
+ /*
+ * XXX - using RPC library internal functions.
+ */
+ if ((fd = __rpc_nconf2fd(nconf)) < 0) {
+ syslog(LOG_ERR, "cannot create socket for %s", nconf->nc_netid);
+ return -1;
+ }
+
+ if (nconf->nc_semantics != NC_TPI_CLTS) {
+ int on = 1;
+
+ /* For connection oriented sockets, always set REUSEADDR.
+ * This allows us to restart the server even if there are
+ * TCP sockets loitering around in TIME_WAIT */
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0) {
+ syslog(LOG_ERR, "cannot set SO_REUSEADDR on %s", nconf->nc_netid);
+ return -1;
+ }
+ }
+
+ oldmask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
+ if (bind(fd, (struct sockaddr *) abuf->buf, abuf->len) != 0) {
+ syslog(LOG_ERR, "cannot bind %s on %s: %m",
+ hostname? hostname : "*",
+ nconf->nc_netid);
+ (void) umask(oldmask);
+ goto skip;
+ }
+ (void) umask(oldmask);
+
+ if (nconf->nc_semantics != NC_TPI_CLTS) {
+ if (listen(fd, SOMAXCONN) < 0) {
+ syslog(LOG_ERR, "unable to listen on %s socket: %m",
+ nconf->nc_netid);
+ return -1;
+ }
+ }
+
+
+#ifdef RPCBIND_DEBUG
+ if (debugging) {
+ /*
+ * for debugging print out our universal
+ * address
+ */
+ char *uaddr;
+
+ uaddr = taddr2uaddr(nconf, abuf);
+ (void) fprintf(stderr, "rpcbind : my %s address is %s\n", nconf->nc_netid, uaddr);
+ (void) free(uaddr);
+ }
+#endif
+
+ *fdret = fd;
+ return 1;
+
+skip:
+ if (fd >= 0)
+ close(fd);
+ return 0;
+}
+
+/*
* Adds the entry into the rpcbind database.
* If PORTMAP, then for UDP and TCP, it adds the entries for version 2 also
* Returns 0 if succeeds, else fails
@@ -277,20 +457,9 @@ init_transport(struct netconfig *nconf)
{
int fd = -1;
struct t_bind taddr;
- struct addrinfo hints, *res;
struct __rpc_sockinfo si;
SVCXPRT *my_xprt = NULL;
int status; /* bound checking ? */
- int aicode;
- int addrlen = 0;
- int nhostsbak;
- int checkbind;
- int on = 1;
- struct sockaddr *sa = NULL;
- u_int32_t host_addr[4]; /* IPv4 or IPv6 */
- struct sockaddr_un sun;
- mode_t oldmask;
- res = NULL;
if ((nconf->nc_semantics != NC_TPI_CLTS) &&
(nconf->nc_semantics != NC_TPI_COTS) &&
@@ -315,24 +484,10 @@ init_transport(struct netconfig *nconf)
return (1);
}
- if ((strcmp(nconf->nc_netid, "local") == 0) ||
- (strcmp(nconf->nc_netid, "unix") == 0)) {
- memset(&sun, 0, sizeof sun);
- sun.sun_family = AF_LOCAL;
- unlink(_PATH_RPCBINDSOCK);
- strcpy(sun.sun_path, _PATH_RPCBINDSOCK);
- addrlen = SUN_LEN(&sun);
- sa = (struct sockaddr *)&sun;
- } else {
- /* Get rpcbind's address on this transport */
-
- memset(&hints, 0, sizeof hints);
- hints.ai_flags = AI_PASSIVE;
- hints.ai_family = si.si_af;
- hints.ai_socktype = si.si_socktype;
- hints.ai_protocol = si.si_proto;
- }
if (nconf->nc_semantics == NC_TPI_CLTS) {
+ int nhostsbak;
+ int checkbind;
+
/*
* If no hosts were specified, just bind to INADDR_ANY. Otherwise
* make sure 127.0.0.1 is added to the list.
@@ -343,9 +498,9 @@ init_transport(struct netconfig *nconf)
if (nhostsbak == 1)
hosts[0] = "*";
else {
- if (hints.ai_family == AF_INET) {
+ if (si.si_af == AF_INET) {
hosts[nhostsbak - 1] = "127.0.0.1";
- } else if (hints.ai_family == AF_INET6) {
+ } else if (si.si_af == AF_INET6) {
hosts[nhostsbak - 1] = "::1";
} else
return 1;
@@ -356,47 +511,9 @@ init_transport(struct netconfig *nconf)
*/
checkbind = 0;
while (nhostsbak > 0) {
- --nhostsbak;
- /*
- * XXX - using RPC library internal functions.
- */
- if ((fd = __rpc_nconf2fd(nconf)) < 0) {
- syslog(LOG_ERR, "cannot create socket for %s",
- nconf->nc_netid);
- return (1);
- }
+ int r;
- hints.ai_flags &= ~AI_NUMERICHOST;
- switch (hints.ai_family) {
- case AF_INET:
- if (inet_pton(AF_INET, hosts[nhostsbak],
- host_addr) == 1) {
- hints.ai_flags |= AI_NUMERICHOST;
- } else {
- /*
- * Skip if we have an AF_INET6 adress.
- */
- if (inet_pton(AF_INET6,
- hosts[nhostsbak], host_addr) == 1)
- continue;
- }
- break;
- case AF_INET6:
- if (inet_pton(AF_INET6, hosts[nhostsbak],
- host_addr) == 1) {
- hints.ai_flags |= AI_NUMERICHOST;
- } else {
- /*
- * Skip if we have an AF_INET adress.
- */
- if (inet_pton(AF_INET, hosts[nhostsbak],
- host_addr) == 1)
- continue;
- }
- break;
- default:
- break;
- }
+ --nhostsbak;
/*
* If no hosts were specified, just bind to INADDR_ANY
@@ -404,68 +521,14 @@ init_transport(struct netconfig *nconf)
if (strcmp("*", hosts[nhostsbak]) == 0)
hosts[nhostsbak] = NULL;
- if ((aicode = getaddrinfo(hosts[nhostsbak],
- servname, &hints, &res)) != 0) {
- if ((aicode = getaddrinfo(hosts[nhostsbak],
- "portmapper", &hints, &res)) != 0) {
- syslog(LOG_ERR,
- "cannot get local address for %s: %s",
- nconf->nc_netid, gai_strerror(aicode));
- continue;
- }
- }
- addrlen = res->ai_addrlen;
- sa = (struct sockaddr *)res->ai_addr;
- oldmask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
- if (bind(fd, sa, addrlen) != 0) {
- syslog(LOG_ERR, "cannot bind %s on %s: %m",
- (hosts[nhostsbak] == NULL) ? "*" :
- hosts[nhostsbak], nconf->nc_netid);
- if (res != NULL)
- freeaddrinfo(res);
+ memset(&taddr, 0, sizeof(taddr));
+
+ r = create_transport_socket(nconf, hosts[nhostsbak], &taddr.addr, &fd);
+ if (r < 0)
+ goto error;
+ if (r == 0)
continue;
- } else
- checkbind++;
- (void) umask(oldmask);
-
- /* Copy the address */
- taddr.addr.maxlen = taddr.addr.len = addrlen;
- taddr.addr.buf = malloc(addrlen);
- if (taddr.addr.buf == NULL) {
- syslog(LOG_ERR,
- "cannot allocate memory for %s address",
- nconf->nc_netid);
- if (res != NULL)
- freeaddrinfo(res);
- return 1;
- }
- memcpy(taddr.addr.buf, sa, addrlen);
-#ifdef RPCBIND_DEBUG
- if (debugging) {
- /*
- * for debugging print out our universal
- * address
- */
- char *uaddr;
- struct netbuf nb;
- int sa_size = 0;
-
- nb.buf = sa;
- switch( sa->sa_family){
- case AF_INET:
- sa_size = sizeof (struct sockaddr_in);
- break;
- case AF_INET6:
- sa_size = sizeof (struct sockaddr_in6);
- break;
- }
- nb.len = nb.maxlen = sa_size;
- uaddr = taddr2uaddr(nconf, &nb);
- (void) fprintf(stderr,
- "rpcbind : my address is %s\n", uaddr);
- (void) free(uaddr);
- }
-#endif
+
my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr,
RPC_MAXDATASIZE, RPC_MAXDATASIZE);
if (my_xprt == (SVCXPRT *)NULL) {
@@ -473,84 +536,15 @@ init_transport(struct netconfig *nconf)
nconf->nc_netid);
goto error;
}
+ checkbind = 1;
+ fd = -1;
}
if (!checkbind)
return 1;
} else { /* NC_TPI_COTS */
- if ((fd = __rpc_nconf2fd(nconf)) < 0) {
- syslog(LOG_ERR, "cannot create socket for %s",
- nconf->nc_netid);
- return (1);
- }
-
- if ((strcmp(nconf->nc_netid, "local") != 0) &&
- (strcmp(nconf->nc_netid, "unix") != 0)) {
- if ((aicode = getaddrinfo(NULL, servname, &hints, &res))!= 0) {
- if ((aicode = getaddrinfo(NULL, "portmapper", &hints, &res))!= 0) {
- printf("cannot get local address for %s: %s", nconf->nc_netid, gai_strerror(aicode));
- syslog(LOG_ERR,
- "cannot get local address for %s: %s",
- nconf->nc_netid, gai_strerror(aicode));
- return 1;
- }
- }
- addrlen = res->ai_addrlen;
- sa = (struct sockaddr *)res->ai_addr;
- }
- oldmask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
- __rpc_fd2sockinfo(fd, &si);
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on,
- sizeof(on)) != 0) {
- syslog(LOG_ERR, "cannot set SO_REUSEADDR on %s",
- nconf->nc_netid);
- if (res != NULL)
- freeaddrinfo(res);
- return 1;
- }
- if (bind(fd, sa, addrlen) < 0) {
- syslog(LOG_ERR, "cannot bind %s: %m", nconf->nc_netid);
- if (res != NULL)
- freeaddrinfo(res);
- return 1;
- }
- (void) umask(oldmask);
-
- /* Copy the address */
- taddr.addr.len = taddr.addr.maxlen = addrlen;
- taddr.addr.buf = malloc(addrlen);
- if (taddr.addr.buf == NULL) {
- syslog(LOG_ERR, "cannot allocate memory for %s address",
- nconf->nc_netid);
- if (res != NULL)
- freeaddrinfo(res);
- return 1;
- }
- memcpy(taddr.addr.buf, sa, addrlen);
-#ifdef RPCBIND_DEBUG
- if (debugging) {
- /* for debugging print out our universal address */
- char *uaddr;
- struct netbuf nb;
- int sa_size2 = 0;
-
- nb.buf = sa;
- switch( sa->sa_family){
- case AF_INET:
- sa_size2 = sizeof (struct sockaddr_in);
- break;
- case AF_INET6:
- sa_size2 = sizeof (struct sockaddr_in6);
- break;
- }
- nb.len = nb.maxlen = sa_size2;
- uaddr = taddr2uaddr(nconf, &nb);
- (void) fprintf(stderr, "rpcbind : my address is %s\n",
- uaddr);
- (void) free(uaddr);
- }
-#endif
-
- listen(fd, SOMAXCONN);
+ memset(&taddr, 0, sizeof(taddr));
+ if (create_transport_socket(nconf, NULL, &taddr.addr, &fd) <= 0)
+ goto error;
my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr, RPC_MAXDATASIZE, RPC_MAXDATASIZE);
if (my_xprt == (SVCXPRT *)NULL) {
@@ -682,7 +676,8 @@ init_transport(struct netconfig *nconf)
}
return (0);
error:
- close(fd);
+ if (fd >= 0)
+ close(fd);
return (1);
}
--
1.7.12.4

View File

@ -0,0 +1,249 @@
From a43a3b1ab5545d835af2867c343ee195a6256665 Mon Sep 17 00:00:00 2001
From: Olaf Kirch <okir@suse.de>
Date: Tue, 20 Aug 2013 09:49:15 +0200
Subject: [PATCH 07/13] init_transport: move the registration code into a
separate function
Signed-off-by: Olaf Kirch <okir@suse.de>
---
src/rpcbind.c | 216 +++++++++++++++++++++++++++++++---------------------------
1 file changed, 116 insertions(+), 100 deletions(-)
diff --git a/src/rpcbind.c b/src/rpcbind.c
index a7dcc0e..25d12c9 100644
--- a/src/rpcbind.c
+++ b/src/rpcbind.c
@@ -447,6 +447,120 @@ skip:
return 0;
}
+static int
+rpcbind_register_transport(struct netconfig *nconf, SVCXPRT *xprt, struct netbuf *bind_addr)
+{
+ struct __rpc_sockinfo si;
+ int status;
+
+ (void) __rpc_nconf2sockinfo(nconf, &si);
+
+#ifdef PORTMAP
+ /*
+ * Register both the versions for tcp/ip, udp/ip.
+ */
+ if (si.si_af == AF_INET &&
+ (si.si_proto == IPPROTO_TCP || si.si_proto == IPPROTO_UDP)) {
+ struct pmaplist *pml;
+
+ pml = malloc(sizeof (struct pmaplist));
+ if (pml == NULL) {
+ syslog(LOG_ERR, "no memory!");
+ exit(1);
+ }
+ pml->pml_map.pm_prog = PMAPPROG;
+ pml->pml_map.pm_vers = PMAPVERS;
+ pml->pml_map.pm_port = PMAPPORT;
+ pml->pml_map.pm_prot = si.si_proto;
+
+ switch (si.si_proto) {
+ case IPPROTO_TCP:
+ tcptrans = strdup(nconf->nc_netid);
+ break;
+ case IPPROTO_UDP:
+ udptrans = strdup(nconf->nc_netid);
+ break;
+ }
+ pml->pml_next = list_pml;
+ list_pml = pml;
+
+ /* Add version 3 information */
+ pml = malloc(sizeof (struct pmaplist));
+ if (pml == NULL) {
+ syslog(LOG_ERR, "no memory!");
+ exit(1);
+ }
+ pml->pml_map = list_pml->pml_map;
+ pml->pml_map.pm_vers = RPCBVERS;
+ pml->pml_next = list_pml;
+ list_pml = pml;
+
+ /* Add version 4 information */
+ pml = malloc (sizeof (struct pmaplist));
+ if (pml == NULL) {
+ syslog(LOG_ERR, "no memory!");
+ exit(1);
+ }
+ pml->pml_map = list_pml->pml_map;
+ pml->pml_map.pm_vers = RPCBVERS4;
+ pml->pml_next = list_pml;
+ list_pml = pml;
+
+ /* Also add version 2 stuff to rpcbind list */
+ rbllist_add(PMAPPROG, PMAPVERS, nconf, bind_addr);
+ }
+
+ /* We need to support portmap over IPv4. It makes sense to
+ * support it over AF_LOCAL as well, because that allows
+ * rpcbind to identify the owner of a socket much better
+ * than by relying on privileged ports to tell root from
+ * non-root users. */
+ if (si.si_af == AF_INET || si.si_af == AF_LOCAL) {
+ if (!svc_register(xprt, PMAPPROG, PMAPVERS, pmap_service, 0)) {
+ syslog(LOG_ERR, "could not register on %s",
+ nconf->nc_netid);
+ return 0;
+ }
+ }
+#endif
+
+ /* version 3 registration */
+ if (!svc_reg(xprt, RPCBPROG, RPCBVERS, rpcb_service_3, NULL)) {
+ syslog(LOG_ERR, "could not register %s version 3",
+ nconf->nc_netid);
+ return 0;
+ }
+ rbllist_add(RPCBPROG, RPCBVERS, nconf, bind_addr);
+
+ /* version 4 registration */
+ if (!svc_reg(xprt, RPCBPROG, RPCBVERS4, rpcb_service_4, NULL)) {
+ syslog(LOG_ERR, "could not register %s version 4",
+ nconf->nc_netid);
+ return 0;
+ }
+ rbllist_add(RPCBPROG, RPCBVERS4, nconf, bind_addr);
+
+ /* decide if bound checking works for this transport */
+ status = add_bndlist(nconf, bind_addr);
+
+#ifdef RPCBIND_DEBUG
+ if (debugging) {
+ if (status < 0) {
+ fprintf(stderr, "Error in finding bind status for %s\n",
+ nconf->nc_netid);
+ } else if (status == 0) {
+ fprintf(stderr, "check binding for %s\n",
+ nconf->nc_netid);
+ } else if (status > 0) {
+ fprintf(stderr, "No check binding for %s\n",
+ nconf->nc_netid);
+ }
+ }
+#endif
+
+ return 1;
+}
+
/*
* Adds the entry into the rpcbind database.
* If PORTMAP, then for UDP and TCP, it adds the entries for version 2 also
@@ -554,107 +668,9 @@ init_transport(struct netconfig *nconf)
}
}
-#ifdef PORTMAP
- /*
- * Register both the versions for tcp/ip, udp/ip.
- */
- if (si.si_af == AF_INET &&
- (si.si_proto == IPPROTO_TCP || si.si_proto == IPPROTO_UDP)) {
- struct pmaplist *pml;
-
- pml = malloc(sizeof (struct pmaplist));
- if (pml == NULL) {
- syslog(LOG_ERR, "no memory!");
- exit(1);
- }
- pml->pml_map.pm_prog = PMAPPROG;
- pml->pml_map.pm_vers = PMAPVERS;
- pml->pml_map.pm_port = PMAPPORT;
- pml->pml_map.pm_prot = si.si_proto;
-
- switch (si.si_proto) {
- case IPPROTO_TCP:
- tcptrans = strdup(nconf->nc_netid);
- break;
- case IPPROTO_UDP:
- udptrans = strdup(nconf->nc_netid);
- break;
- }
- pml->pml_next = list_pml;
- list_pml = pml;
-
- /* Add version 3 information */
- pml = malloc(sizeof (struct pmaplist));
- if (pml == NULL) {
- syslog(LOG_ERR, "no memory!");
- exit(1);
- }
- pml->pml_map = list_pml->pml_map;
- pml->pml_map.pm_vers = RPCBVERS;
- pml->pml_next = list_pml;
- list_pml = pml;
-
- /* Add version 4 information */
- pml = malloc (sizeof (struct pmaplist));
- if (pml == NULL) {
- syslog(LOG_ERR, "no memory!");
- exit(1);
- }
- pml->pml_map = list_pml->pml_map;
- pml->pml_map.pm_vers = RPCBVERS4;
- pml->pml_next = list_pml;
- list_pml = pml;
-
- /* Also add version 2 stuff to rpcbind list */
- rbllist_add(PMAPPROG, PMAPVERS, nconf, &taddr.addr);
- }
-
- /* We need to support portmap over IPv4. It makes sense to
- * support it over AF_LOCAL as well, because that allows
- * rpcbind to identify the owner of a socket much better
- * than by relying on privileged ports to tell root from
- * non-root users. */
- if (si.si_af == AF_INET || si.si_af == AF_LOCAL) {
- if (!svc_register(my_xprt, PMAPPROG, PMAPVERS, pmap_service, 0)) {
- syslog(LOG_ERR, "could not register on %s",
- nconf->nc_netid);
- goto error;
- }
- }
-#endif
-
- /* version 3 registration */
- if (!svc_reg(my_xprt, RPCBPROG, RPCBVERS, rpcb_service_3, NULL)) {
- syslog(LOG_ERR, "could not register %s version 3",
- nconf->nc_netid);
- goto error;
- }
- rbllist_add(RPCBPROG, RPCBVERS, nconf, &taddr.addr);
-
- /* version 4 registration */
- if (!svc_reg(my_xprt, RPCBPROG, RPCBVERS4, rpcb_service_4, NULL)) {
- syslog(LOG_ERR, "could not register %s version 4",
- nconf->nc_netid);
- goto error;
- }
- rbllist_add(RPCBPROG, RPCBVERS4, nconf, &taddr.addr);
+ if (!rpcbind_register_transport(nconf, my_xprt, &taddr.addr))
+ return (1);
- /* decide if bound checking works for this transport */
- status = add_bndlist(nconf, &taddr.addr);
-#ifdef RPCBIND_DEBUG
- if (debugging) {
- if (status < 0) {
- fprintf(stderr, "Error in finding bind status for %s\n",
- nconf->nc_netid);
- } else if (status == 0) {
- fprintf(stderr, "check binding for %s\n",
- nconf->nc_netid);
- } else if (status > 0) {
- fprintf(stderr, "No check binding for %s\n",
- nconf->nc_netid);
- }
- }
-#endif
/*
* rmtcall only supported on CLTS transports for now.
*/
--
1.7.12.4

View File

@ -0,0 +1,141 @@
From 2a825515a2b6304e27f0e28fd5da562d44d6cbfe Mon Sep 17 00:00:00 2001
From: Olaf Kirch <okir@suse.de>
Date: Tue, 20 Aug 2013 09:58:51 +0200
Subject: [PATCH 08/13] Fix the behavior when specifying the -h option
Currently, when specifying the "-h" option, rpcbind will try to create
sockets for all specified addresses, plus the loopback address. However,
it will only register its programs on the last SVCXPRT created, which
will usually be the first address specified via -h.
This patch fixes this problem by introducing a new function that creates
the socket *and* registers all programs, and use that from the while
loop.
Signed-off-by: Olaf Kirch <okir@suse.de>
---
src/rpcbind.c | 79 ++++++++++++++++++++++++++++++++---------------------------
1 file changed, 43 insertions(+), 36 deletions(-)
diff --git a/src/rpcbind.c b/src/rpcbind.c
index 25d12c9..c3679e2 100644
--- a/src/rpcbind.c
+++ b/src/rpcbind.c
@@ -562,6 +562,43 @@ rpcbind_register_transport(struct netconfig *nconf, SVCXPRT *xprt, struct netbuf
}
/*
+ * This will create a server socket for the given netid, bound to the
+ * address specified by @hostname
+ *
+ * Return value:
+ * 1: success
+ * 0: error - ignore this hostname
+ * <0: error - ignore this netid
+ */
+static int
+rpcbind_init_endpoint(struct netconfig *nconf, const char *hostname)
+{
+ struct t_bind taddr;
+ SVCXPRT *my_xprt = NULL;
+ int r, fd = -1;
+
+ memset(&taddr, 0, sizeof(taddr));
+
+ r = create_transport_socket(nconf, hostname, &taddr.addr, &fd);
+ if (r <= 0)
+ return r;
+
+ my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr, RPC_MAXDATASIZE, RPC_MAXDATASIZE);
+ if (my_xprt == (SVCXPRT *)NULL) {
+ syslog(LOG_ERR, "%s: could not create service", nconf->nc_netid);
+ close(fd);
+ return 0;
+ }
+
+ if (!rpcbind_register_transport(nconf, my_xprt, &taddr.addr)) {
+ svc_destroy(my_xprt);
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
* Adds the entry into the rpcbind database.
* If PORTMAP, then for UDP and TCP, it adds the entries for version 2 also
* Returns 0 if succeeds, else fails
@@ -569,10 +606,7 @@ rpcbind_register_transport(struct netconfig *nconf, SVCXPRT *xprt, struct netbuf
static int
init_transport(struct netconfig *nconf)
{
- int fd = -1;
- struct t_bind taddr;
struct __rpc_sockinfo si;
- SVCXPRT *my_xprt = NULL;
int status; /* bound checking ? */
if ((nconf->nc_semantics != NC_TPI_CLTS) &&
@@ -635,42 +669,19 @@ init_transport(struct netconfig *nconf)
if (strcmp("*", hosts[nhostsbak]) == 0)
hosts[nhostsbak] = NULL;
- memset(&taddr, 0, sizeof(taddr));
-
- r = create_transport_socket(nconf, hosts[nhostsbak], &taddr.addr, &fd);
+ r = rpcbind_init_endpoint(nconf, hosts[nhostsbak]);
if (r < 0)
- goto error;
- if (r == 0)
- continue;
-
- my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr,
- RPC_MAXDATASIZE, RPC_MAXDATASIZE);
- if (my_xprt == (SVCXPRT *)NULL) {
- syslog(LOG_ERR, "%s: could not create service",
- nconf->nc_netid);
- goto error;
- }
- checkbind = 1;
- fd = -1;
+ return 1;
+ if (r > 0)
+ checkbind = 1;
}
if (!checkbind)
return 1;
} else { /* NC_TPI_COTS */
- memset(&taddr, 0, sizeof(taddr));
- if (create_transport_socket(nconf, NULL, &taddr.addr, &fd) <= 0)
- goto error;
-
- my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr, RPC_MAXDATASIZE, RPC_MAXDATASIZE);
- if (my_xprt == (SVCXPRT *)NULL) {
- syslog(LOG_ERR, "%s: could not create service",
- nconf->nc_netid);
- goto error;
- }
+ if (rpcbind_init_endpoint(nconf, NULL) <= 0)
+ return 1;
}
- if (!rpcbind_register_transport(nconf, my_xprt, &taddr.addr))
- return (1);
-
/*
* rmtcall only supported on CLTS transports for now.
*/
@@ -691,10 +702,6 @@ init_transport(struct netconfig *nconf)
#endif
}
return (0);
-error:
- if (fd >= 0)
- close(fd);
- return (1);
}
static void
--
1.7.12.4

View File

@ -0,0 +1,104 @@
From 734101ba29f0b169d72e8ec6de6d924922f1583c Mon Sep 17 00:00:00 2001
From: Olaf Kirch <okir@suse.de>
Date: Tue, 20 Aug 2013 10:10:41 +0200
Subject: [PATCH 09/13] Clean up the way we handle the -h option in
init_transport
There's some odd realloc()ing going on, which is plain ugly.
Make the code a little more readable.
Signed-off-by: Olaf Kirch <okir@suse.de>
---
src/rpcbind.c | 66 +++++++++++++++++++++++++++--------------------------------
1 file changed, 30 insertions(+), 36 deletions(-)
diff --git a/src/rpcbind.c b/src/rpcbind.c
index c3679e2..1d59362 100644
--- a/src/rpcbind.c
+++ b/src/rpcbind.c
@@ -632,52 +632,46 @@ init_transport(struct netconfig *nconf)
return (1);
}
- if (nconf->nc_semantics == NC_TPI_CLTS) {
- int nhostsbak;
- int checkbind;
+ /* Check if the -h option was used to specify addresses to bind to.
+ * The original purpose was to allow multihomed hosts to function
+ * properly, making the reply originate from the same IP address
+ * that it was sent to. We're solving this differently in the meantime
+ * (using PKTINFO magic in libtirpc), but there may be other uses for
+ * this option, like restricting rpcbind to certain "public" interfaces
+ */
+ if (nhosts != 0 && nconf->nc_semantics == NC_TPI_CLTS) {
+ int numbound = 0, n, r;
- /*
- * If no hosts were specified, just bind to INADDR_ANY. Otherwise
- * make sure 127.0.0.1 is added to the list.
- */
- nhostsbak = nhosts;
- nhostsbak++;
- hosts = realloc(hosts, nhostsbak * sizeof(char *));
- if (nhostsbak == 1)
- hosts[0] = "*";
- else {
- if (si.si_af == AF_INET) {
- hosts[nhostsbak - 1] = "127.0.0.1";
- } else if (si.si_af == AF_INET6) {
- hosts[nhostsbak - 1] = "::1";
- } else
- return 1;
- }
+ /* Ensure that we always bind to loopback */
+ switch (si.si_af) {
+ case AF_INET:
+ if (rpcbind_init_endpoint(nconf, "127.0.0.1") > 0)
+ numbound++;
+ break;
- /*
- * Bind to specific IPs if asked to
- */
- checkbind = 0;
- while (nhostsbak > 0) {
- int r;
+ case AF_INET6:
+ if (rpcbind_init_endpoint(nconf, "::1") > 0)
+ numbound++;
+ break;
+ }
- --nhostsbak;
+ for (n = 0; n < nhosts; ++n) {
+ const char *hostname = hosts[n];
- /*
- * If no hosts were specified, just bind to INADDR_ANY
- */
- if (strcmp("*", hosts[nhostsbak]) == 0)
- hosts[nhostsbak] = NULL;
+ /* In case someone gets the idea to specify "-h '*'" */
+ if (strcmp("*", hostname) == 0)
+ hostname = NULL;
- r = rpcbind_init_endpoint(nconf, hosts[nhostsbak]);
+ r = rpcbind_init_endpoint(nconf, hostname);
if (r < 0)
return 1;
if (r > 0)
- checkbind = 1;
+ numbound++;
}
- if (!checkbind)
+
+ if (numbound == 0)
return 1;
- } else { /* NC_TPI_COTS */
+ } else {
if (rpcbind_init_endpoint(nconf, NULL) <= 0)
return 1;
}
--
1.7.12.4

View File

@ -0,0 +1,372 @@
From c3ec796dd8f177a3c6ab9b76de490dbfe2c86476 Mon Sep 17 00:00:00 2001
From: Olaf Kirch <okir@suse.de>
Date: Tue, 20 Aug 2013 11:26:42 +0200
Subject: [PATCH 10/13] Support systemd activation.
This code is loosely based on previous work by Tom Gundersen <teg@jklm.no>.
Signed-off-by: Olaf Kirch <okir@suse.de>
---
Makefile.am | 15 ++++
configure.ac | 11 +++
src/rpcbind.c | 172 ++++++++++++++++++++++++++++++++++++---------
systemd/.gitignore | 1 +
systemd/rpcbind.service.in | 9 +++
systemd/rpcbind.socket | 12 ++++
6 files changed, 188 insertions(+), 32 deletions(-)
create mode 100644 systemd/.gitignore
create mode 100644 systemd/rpcbind.service.in
create mode 100644 systemd/rpcbind.socket
diff --git a/Makefile.am b/Makefile.am
index d10c906..df755dd 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -38,6 +38,21 @@ rpcbind_SOURCES = \
src/warmstart.c
rpcbind_LDADD = $(TIRPC_LIBS)
+if SYSTEMD
+AM_CPPFLAGS += $(SYSTEMD_CFLAGS) -DSYSTEMD
+
+rpcbind_LDADD += $(SYSTEMD_LIBS)
+
+systemd/rpcbind.service: systemd/rpcbind.service.in Makefile
+ sed -e 's,@bindir\@,$(bindir),g' \
+ < $< > $@ || rm $@
+
+systemdsystemunit_DATA = \
+ systemd/rpcbind.service \
+ systemd/rpcbind.socket
+
+endif
+
rpcinfo_SOURCES = src/rpcinfo.c
rpcinfo_LDADD = $(TIRPC_LIBS)
diff --git a/configure.ac b/configure.ac
index 1cf42d3..a94933b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -29,6 +29,17 @@ AC_SUBST([rpcuser], [$with_rpcuser])
PKG_CHECK_MODULES([TIRPC], [libtirpc])
+PKG_PROG_PKG_CONFIG
+AC_ARG_WITH([systemdsystemunitdir],
+ AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]),
+ [], [with_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)])
+ if test "x$with_systemdsystemunitdir" != xno -a "x$with_systemdsystemunitdir" != "x"; then
+ AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
+ PKG_CHECK_MODULES([SYSTEMD], [libsystemd-daemon])
+ fi
+AM_CONDITIONAL(SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ])
+
+
AS_IF([test x$enable_libwrap = xyes], [
AC_CHECK_LIB([wrap], [hosts_access], ,
AC_MSG_ERROR([libwrap support requested but unable to find libwrap]))
diff --git a/src/rpcbind.c b/src/rpcbind.c
index 1d59362..32e6deb 100644
--- a/src/rpcbind.c
+++ b/src/rpcbind.c
@@ -56,6 +56,9 @@
#include <netinet/in.h>
#endif
#include <arpa/inet.h>
+#ifdef SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
#include <fcntl.h>
#include <netdb.h>
#include <stdio.h>
@@ -100,6 +103,9 @@ int runasdaemon = 0;
int insecure = 0;
int oldstyle_local = 0;
int verboselog = 0;
+#ifdef SYSTEMD
+int systemd_activation = 0;
+#endif
char **hosts = NULL;
int nhosts = 0;
@@ -123,6 +129,10 @@ static char superuser[] = "superuser";
int main __P((int, char *[]));
+static void init_transports_daemon __P((void));
+#ifdef SYSTEMD
+static void init_transports_systemd __P((void));
+#endif
static int init_transport __P((struct netconfig *));
static void rbllist_add __P((rpcprog_t, rpcvers_t, struct netconfig *,
struct netbuf *));
@@ -132,11 +142,15 @@ static void parseargs __P((int, char *[]));
int
main(int argc, char *argv[])
{
- struct netconfig *nconf;
- void *nc_handle; /* Net config handle */
struct rlimit rl;
int maxrec = RPC_MAXDATASIZE;
+#ifdef SYSTEMD
+ /* See whether we've been activated by systemd */
+ if (sd_listen_fds(0) > 0)
+ systemd_activation = 1;
+#endif
+
parseargs(argc, argv);
/* Check that another rpcbind isn't already running. */
@@ -167,29 +181,14 @@ main(int argc, char *argv[])
*/
__nss_configure_lookup("services", "files");
- nc_handle = setnetconfig(); /* open netconfig file */
- if (nc_handle == NULL) {
- syslog(LOG_ERR, "could not read /etc/netconfig");
- exit(1);
- }
-
- nconf = getnetconfigent("local");
- if (nconf == NULL)
- nconf = getnetconfigent("unix");
- if (nconf == NULL) {
- syslog(LOG_ERR, "%s: can't find local transport\n", argv[0]);
- exit(1);
- }
-
rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec);
- init_transport(nconf);
-
- while ((nconf = getnetconfig(nc_handle))) {
- if (nconf->nc_flag & NC_VISIBLE)
- init_transport(nconf);
- }
- endnetconfig(nc_handle);
+#ifdef SYSTEMD
+ if (systemd_activation)
+ init_transports_systemd();
+ else
+#endif
+ init_transports_daemon();
#ifdef PORTMAP
if (!udptrans)
@@ -571,17 +570,29 @@ rpcbind_register_transport(struct netconfig *nconf, SVCXPRT *xprt, struct netbuf
* <0: error - ignore this netid
*/
static int
-rpcbind_init_endpoint(struct netconfig *nconf, const char *hostname)
+rpcbind_init_endpoint(struct netconfig *nconf, const char *hostname, int fd)
{
struct t_bind taddr;
SVCXPRT *my_xprt = NULL;
- int r, fd = -1;
+ int r;
memset(&taddr, 0, sizeof(taddr));
- r = create_transport_socket(nconf, hostname, &taddr.addr, &fd);
- if (r <= 0)
- return r;
+ if (fd < 0) {
+ r = create_transport_socket(nconf, hostname, &taddr.addr, &fd);
+ if (r <= 0)
+ return r;
+ } else {
+ struct sockaddr_storage addr;
+ socklen_t alen = sizeof(addr);
+
+ if (getsockname(fd, (struct sockaddr *) &addr, &alen) < 0) {
+ syslog(LOG_ERR, "cannot get address for socket fd %d", fd);
+ exit(1);
+ }
+
+ sockaddr2netbuf((struct sockaddr *) &addr, alen, &taddr.addr);
+ }
my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr, RPC_MAXDATASIZE, RPC_MAXDATASIZE);
if (my_xprt == (SVCXPRT *)NULL) {
@@ -645,12 +656,12 @@ init_transport(struct netconfig *nconf)
/* Ensure that we always bind to loopback */
switch (si.si_af) {
case AF_INET:
- if (rpcbind_init_endpoint(nconf, "127.0.0.1") > 0)
+ if (rpcbind_init_endpoint(nconf, "127.0.0.1", -1) > 0)
numbound++;
break;
case AF_INET6:
- if (rpcbind_init_endpoint(nconf, "::1") > 0)
+ if (rpcbind_init_endpoint(nconf, "::1", -1) > 0)
numbound++;
break;
}
@@ -662,7 +673,7 @@ init_transport(struct netconfig *nconf)
if (strcmp("*", hostname) == 0)
hostname = NULL;
- r = rpcbind_init_endpoint(nconf, hostname);
+ r = rpcbind_init_endpoint(nconf, hostname, -1);
if (r < 0)
return 1;
if (r > 0)
@@ -672,7 +683,7 @@ init_transport(struct netconfig *nconf)
if (numbound == 0)
return 1;
} else {
- if (rpcbind_init_endpoint(nconf, NULL) <= 0)
+ if (rpcbind_init_endpoint(nconf, NULL, -1) <= 0)
return 1;
}
@@ -699,6 +710,103 @@ init_transport(struct netconfig *nconf)
}
static void
+init_transports_daemon(void)
+{
+ void *nc_handle;
+ struct netconfig *nconf;
+
+ nc_handle = setnetconfig(); /* open netconfig file */
+ if (nc_handle == NULL) {
+ syslog(LOG_ERR, "could not read /etc/netconfig");
+ exit(1);
+ }
+
+ nconf = getnetconfigent("local");
+ if (nconf == NULL)
+ nconf = getnetconfigent("unix");
+ if (nconf == NULL) {
+ syslog(LOG_ERR, "rpcbind: can't find local transport\n");
+ exit(1);
+ }
+
+ init_transport(nconf);
+
+ while ((nconf = getnetconfig(nc_handle))) {
+ if (nconf->nc_flag & NC_VISIBLE)
+ init_transport(nconf);
+ }
+ endnetconfig(nc_handle);
+}
+
+#ifdef SYSTEMD
+static struct netconfig *
+sockinfo2nconf(void **handlep, const struct __rpc_sockinfo *match)
+{
+ struct netconfig *nconf;
+
+ if (*handlep)
+ endnetconfig(*handlep);
+ *handlep = setnetconfig();
+
+ while ((nconf = getnetconfig(*handlep))) {
+ struct __rpc_sockinfo si;
+
+ if (!__rpc_nconf2sockinfo(nconf, &si))
+ continue;
+
+ if (si.si_af == match->si_af
+ && si.si_socktype == match->si_socktype
+ && si.si_proto == match->si_proto)
+ return nconf;
+ }
+ return NULL;
+}
+
+static void
+init_transports_systemd()
+{
+ void *nc_handle = NULL;
+ int nfds, n;
+
+ if ((nfds = sd_listen_fds(0)) < 0) {
+ syslog(LOG_ERR, "failed to acquire systemd sockets: %s", strerror(-nfds));
+ exit(1);
+ }
+ if (nfds >= 16) {
+ syslog(LOG_ERR, "too many sockets passed by systemd (%u)", nfds);
+ exit(1);
+ }
+
+ for (n = 0; n < nfds; ++n) {
+ struct netconfig *nconf;
+ struct __rpc_sockinfo si;
+ int fd;
+
+ fd = SD_LISTEN_FDS_START + n;
+
+ if (!__rpc_fd2sockinfo(fd, &si)) {
+ syslog(LOG_ERR, "cannot get socket information for fd %d", fd);
+ exit(1);
+ }
+
+ /* Now find the netconfig entry matching this transport */
+ if ((nconf = sockinfo2nconf(&nc_handle, &si)) == NULL) {
+ syslog(LOG_ERR, "not netconfig for socket fd %d", fd);
+ exit(1);
+ }
+
+ if (rpcbind_init_endpoint(nconf, NULL, fd) <= 0) {
+ syslog(LOG_ERR, "unable to create transport for socket fd %d", fd);
+ exit(1);
+ }
+ }
+
+ if (nc_handle)
+ endnetconfig(nc_handle);
+}
+#endif
+
+static void
rbllist_add(rpcprog_t prog, rpcvers_t vers, struct netconfig *nconf,
struct netbuf *addr)
{
diff --git a/systemd/.gitignore b/systemd/.gitignore
new file mode 100644
index 0000000..b7b4561
--- /dev/null
+++ b/systemd/.gitignore
@@ -0,0 +1 @@
+rpcbind.service
diff --git a/systemd/rpcbind.service.in b/systemd/rpcbind.service.in
new file mode 100644
index 0000000..58ae5de
--- /dev/null
+++ b/systemd/rpcbind.service.in
@@ -0,0 +1,9 @@
+[Unit]
+Description=RPC Bind
+
+[Service]
+ExecStart=@bindir@/rpcbind -w -f
+
+[Install]
+WantedBy=multi-user.target
+Also=rpcbind.socket
diff --git a/systemd/rpcbind.socket b/systemd/rpcbind.socket
new file mode 100644
index 0000000..ad5fd62
--- /dev/null
+++ b/systemd/rpcbind.socket
@@ -0,0 +1,12 @@
+[Unit]
+Description=RPCbind Server Activation Socket
+Wants=rpcbind.target
+Before=rpcbind.target
+
+[Socket]
+ListenStream=/var/run/rpcbind.sock
+ListenStream=111
+ListenDatagram=111
+
+[Install]
+WantedBy=sockets.target
--
1.7.12.4

View File

@ -1,6 +1,8 @@
From 994e57f91c58e9e88c9f793e948e8d3af6ff4528 Mon Sep 17 00:00:00 2001
From: Jeff Mahoney <jeffm@suse.com>
Subject: socket-activation: Fix rpcbind.service to use separate sockets
References: bnc#757909
Date: Tue, 20 Aug 2013 15:20:13 +0200
Subject: [PATCH 11/13] socket-activation: Fix rpcbind.service to use separate
sockets
systemd will, by default, pass a socket that provides both IPv4 and
IPv6 services. RPC netconfig requires that sockets be either IPv4
@ -11,15 +13,14 @@ References: bnc#757909
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
---
src/rpcbind.c | 29 +++++++++++++++++++++++++++++
systemd/rpcbind.socket | 11 ++++++++---
2 files changed, 37 insertions(+), 3 deletions(-)
src/rpcbind.c | 32 +++++++++++++++++++++++++++++++-
systemd/rpcbind.socket | 9 +++++++--
2 files changed, 38 insertions(+), 3 deletions(-)
Index: rpcbind-0.2.0_git201103171419/src/rpcbind.c
===================================================================
--- rpcbind-0.2.0_git201103171419.orig/src/rpcbind.c
+++ rpcbind-0.2.0_git201103171419/src/rpcbind.c
diff --git a/src/rpcbind.c b/src/rpcbind.c
index 32e6deb..d2b25fa 100644
--- a/src/rpcbind.c
+++ b/src/rpcbind.c
@@ -50,6 +50,7 @@
#include <sys/file.h>
#include <sys/socket.h>
@ -28,7 +29,7 @@ Index: rpcbind-0.2.0_git201103171419/src/rpcbind.c
#include <rpc/rpc.h>
#include <rpc/rpc_com.h>
#ifdef PORTMAP
@@ -263,6 +264,32 @@ main(int argc, char *argv[])
@@ -561,6 +562,31 @@ rpcbind_register_transport(struct netconfig *nconf, SVCXPRT *xprt, struct netbuf
}
/*
@ -44,9 +45,8 @@ Index: rpcbind-0.2.0_git201103171419/src/rpcbind.c
+ socklen_t len = sizeof(opt);
+
+ if (getsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, &len)) {
+ syslog(LOG_ERR, "failed to get ipv6 socket opts: %s",
+ strerror(errno));
+ return 1;
+ syslog(LOG_ERR, "failed to get ipv6 socket opts: %m");
+ return -1;
+ }
+
+ if (opt) /* socket is already in V6ONLY mode */
@ -54,36 +54,27 @@ Index: rpcbind-0.2.0_git201103171419/src/rpcbind.c
+
+ syslog(LOG_ERR, "systemd has passed an IPv4/IPv6 dual-mode socket.");
+ syslog(LOG_ERR, "Please fix your systemd config by specifying IPv4 and IPv6 sockets separately and using BindIPv6Only=ipv6-only.");
+ return 1;
+ return -1;
+}
+
+/*
* Adds the entry into the rpcbind database.
* If PORTMAP, then for UDP and TCP, it adds the entries for version 2 also
* Returns 0 if succeeds, else fails
@@ -314,7 +341,7 @@ init_transport(struct netconfig *nconf)
#ifdef SYSTEMD
n = sd_listen_fds(0);
if (n < 0) {
- syslog(LOG_ERR, "failed to acquire systemd scokets: %s", strerror(-n));
+ syslog(LOG_ERR, "failed to acquire systemd sockets: %s", strerror(-n));
return 1;
}
@@ -348,6 +375,9 @@ init_transport(struct netconfig *nconf)
goto error;
* This will create a server socket for the given netid, bound to the
* address specified by @hostname
*
@@ -591,6 +617,9 @@ rpcbind_init_endpoint(struct netconfig *nconf, const char *hostname, int fd)
exit(1);
}
+ if (sa.sa.sa_family == AF_INET6 && handle_ipv6_socket(fd))
+ goto error;
+ if (addr.ss_family == AF_INET6 && handle_ipv6_socket(fd))
+ return -1;
+
/* Copy the address */
taddr.addr.maxlen = taddr.addr.len = addrlen;
taddr.addr.buf = malloc(addrlen);
Index: rpcbind-0.2.0_git201103171419/systemd/rpcbind.socket
===================================================================
--- rpcbind-0.2.0_git201103171419.orig/systemd/rpcbind.socket
+++ rpcbind-0.2.0_git201103171419/systemd/rpcbind.socket
sockaddr2netbuf((struct sockaddr *) &addr, alen, &taddr.addr);
}
diff --git a/systemd/rpcbind.socket b/systemd/rpcbind.socket
index ad5fd62..0b0c1d3 100644
--- a/systemd/rpcbind.socket
+++ b/systemd/rpcbind.socket
@@ -4,9 +4,14 @@ Wants=rpcbind.target
Before=rpcbind.target
@ -102,3 +93,6 @@ Index: rpcbind-0.2.0_git201103171419/systemd/rpcbind.socket
[Install]
WantedBy=sockets.target
--
1.7.12.4

View File

@ -0,0 +1,540 @@
From 2eae383ebb716b27a6ac0aa2c0c2288f92b56b4e Mon Sep 17 00:00:00 2001
From: Olaf Kirch <okir@suse.de>
Date: Tue, 20 Aug 2013 15:59:17 +0200
Subject: [PATCH 12/13] When using systemd, redirect syslog() calls to the
systemd journal
Signed-off-by: Olaf Kirch <okir@suse.de>
---
Makefile.am | 4 +--
configure.ac | 1 +
src/check_bound.c | 4 +--
src/rpcb_svc.c | 1 -
src/rpcb_svc_4.c | 1 -
src/rpcb_svc_com.c | 5 ++-
src/rpcbind.c | 100 +++++++++++++++++++++++++++++++++++------------------
src/rpcbind.h | 3 ++
src/security.c | 2 +-
src/warmstart.c | 13 ++++---
10 files changed, 83 insertions(+), 51 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index df755dd..6f7474f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -39,9 +39,9 @@ rpcbind_SOURCES = \
rpcbind_LDADD = $(TIRPC_LIBS)
if SYSTEMD
-AM_CPPFLAGS += $(SYSTEMD_CFLAGS) -DSYSTEMD
+AM_CPPFLAGS += $(SYSTEMD_CFLAGS) $(SYSTEMD_JOURNAL_CFLAGS) -DSYSTEMD
-rpcbind_LDADD += $(SYSTEMD_LIBS)
+rpcbind_LDADD += $(SYSTEMD_LIBS) $(SYSTEMD_JOURNAL_LIBS)
systemd/rpcbind.service: systemd/rpcbind.service.in Makefile
sed -e 's,@bindir\@,$(bindir),g' \
diff --git a/configure.ac b/configure.ac
index a94933b..6d91dcd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -36,6 +36,7 @@ AC_ARG_WITH([systemdsystemunitdir],
if test "x$with_systemdsystemunitdir" != xno -a "x$with_systemdsystemunitdir" != "x"; then
AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
PKG_CHECK_MODULES([SYSTEMD], [libsystemd-daemon])
+ PKG_CHECK_MODULES([SYSTEMD_JOURNAL], [libsystemd-journal])
fi
AM_CONDITIONAL(SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ])
diff --git a/src/check_bound.c b/src/check_bound.c
index c70b845..82d84b9 100644
--- a/src/check_bound.c
+++ b/src/check_bound.c
@@ -119,7 +119,7 @@ add_bndlist(struct netconfig *nconf, struct netbuf *baddr /*__unused*/)
fdl = malloc(sizeof (struct fdlist));
if (fdl == NULL) {
freenetconfigent(newnconf);
- syslog(LOG_ERR, "no memory!");
+ rpcbind_log_error("no memory!");
return (-1);
}
fdl->nconf = newnconf;
@@ -179,7 +179,7 @@ mergeaddr(SVCXPRT *xprt, char *netid, char *uaddr, char *saddr)
} else {
c_uaddr = taddr2uaddr(fdl->nconf, svc_getrpccaller(xprt));
if (c_uaddr == NULL) {
- syslog(LOG_ERR, "taddr2uaddr failed for %s",
+ rpcbind_log_error("taddr2uaddr failed for %s",
fdl->nconf->nc_netid);
return (NULL);
}
diff --git a/src/rpcb_svc.c b/src/rpcb_svc.c
index e350f85..c26b5be 100644
--- a/src/rpcb_svc.c
+++ b/src/rpcb_svc.c
@@ -45,7 +45,6 @@
#include <rpc/rpc.h>
#include <rpc/rpcb_prot.h>
#include <netconfig.h>
-#include <syslog.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
diff --git a/src/rpcb_svc_4.c b/src/rpcb_svc_4.c
index 313e6d1..6858095 100644
--- a/src/rpcb_svc_4.c
+++ b/src/rpcb_svc_4.c
@@ -48,7 +48,6 @@
#include <stdio.h>
#include <unistd.h>
#include <netconfig.h>
-#include <syslog.h>
#include <string.h>
#include <stdlib.h>
#include "rpcbind.h"
diff --git a/src/rpcb_svc_com.c b/src/rpcb_svc_com.c
index f6bd6bd..1a4ad84 100644
--- a/src/rpcb_svc_com.c
+++ b/src/rpcb_svc_com.c
@@ -50,7 +50,6 @@
#include <rpc/svc_dg.h>
#include <netconfig.h>
#include <errno.h>
-#include <syslog.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
@@ -520,7 +519,7 @@ create_rmtcall_fd(struct netconfig *nconf)
}
rmt = malloc(sizeof (struct rmtcallfd_list));
if (rmt == NULL) {
- syslog(LOG_ERR, "create_rmtcall_fd: no memory!");
+ rpcbind_log_error("create_rmtcall_fd: no memory!");
return (-1);
}
rmt->xprt = xprt;
@@ -1438,7 +1437,7 @@ add_pmaplist(RPCB *arg)
*/
pml = malloc(sizeof (struct pmaplist));
if (pml == NULL) {
- (void) syslog(LOG_ERR, "rpcbind: no memory!\n");
+ (void) rpcbind_log_error("rpcbind: no memory!\n");
return (1);
}
pml->pml_map = pmap;
diff --git a/src/rpcbind.c b/src/rpcbind.c
index d2b25fa..964c2d3 100644
--- a/src/rpcbind.c
+++ b/src/rpcbind.c
@@ -59,18 +59,20 @@
#include <arpa/inet.h>
#ifdef SYSTEMD
#include <systemd/sd-daemon.h>
+#include <systemd/sd-journal.h>
#endif
+#include <syslog.h>
#include <fcntl.h>
#include <netdb.h>
#include <stdio.h>
#include <netconfig.h>
#include <stdlib.h>
#include <unistd.h>
-#include <syslog.h>
#include <err.h>
#include <pwd.h>
#include <grp.h>
#include <string.h>
+#include <stdarg.h>
#include <errno.h>
#ifdef HAVE_NSS_H
#include <nss.h>
@@ -234,19 +236,19 @@ main(int argc, char *argv[])
__nss_configure_lookup("passwd", "files");
if((p = getpwnam(id)) == NULL) {
- syslog(LOG_ERR, "cannot get uid of '%s': %m", id);
+ rpcbind_log_error("cannot get uid of '%s': %m", id);
exit(1);
}
if (setgid(p->pw_gid) == -1) {
- syslog(LOG_ERR, "setgid to '%s' (%d) failed: %m", id, p->pw_gid);
+ rpcbind_log_error("setgid to '%s' (%d) failed: %m", id, p->pw_gid);
exit(1);
}
if (setgroups(0, NULL) == -1) {
- syslog(LOG_ERR, "dropping supplemental groups failed: %m");
+ rpcbind_log_error("dropping supplemental groups failed: %m");
exit(1);
}
if (setuid(p->pw_uid) == -1) {
- syslog(LOG_ERR, "setuid to '%s' (%d) failed: %m", id, p->pw_uid);
+ rpcbind_log_error("setuid to '%s' (%d) failed: %m", id, p->pw_uid);
exit(1);
}
}
@@ -260,7 +262,7 @@ main(int argc, char *argv[])
network_init();
my_svc_run();
- syslog(LOG_ERR, "svc_run returned unexpectedly");
+ rpcbind_log_error("svc_run returned unexpectedly");
rpcbind_abort();
/* NOTREACHED */
@@ -277,7 +279,7 @@ sockaddr2netbuf(const struct sockaddr *sa, socklen_t alen, struct netbuf *abuf)
abuf->buf = malloc(alen);
if (abuf->buf == NULL) {
- syslog(LOG_ERR, "not enough memory for address buffer (%u bytes)", alen);
+ rpcbind_log_error("not enough memory for address buffer (%u bytes)", alen);
exit(1);
}
@@ -295,7 +297,7 @@ do_hostname_lookup(struct netconfig *nconf, const char *hostname, struct netbuf
int aicode;
if (!__rpc_nconf2sockinfo(nconf, &si)) {
- syslog(LOG_ERR, "cannot get sockinfo for %s", nconf->nc_netid);
+ rpcbind_log_error("cannot get sockinfo for %s", nconf->nc_netid);
return -1;
}
@@ -334,7 +336,7 @@ do_hostname_lookup(struct netconfig *nconf, const char *hostname, struct netbuf
if ((aicode = getaddrinfo(hostname, servname, &hints, &res)) != 0) {
if ((aicode = getaddrinfo(hostname, "portmapper", &hints, &res)) != 0) {
- syslog(LOG_ERR,
+ rpcbind_log_error(
"cannot get %s address for %s: %s",
nconf->nc_netid,
hostname? hostname : "*",
@@ -389,7 +391,7 @@ create_transport_socket(struct netconfig *nconf, const char *hostname, struct ne
* XXX - using RPC library internal functions.
*/
if ((fd = __rpc_nconf2fd(nconf)) < 0) {
- syslog(LOG_ERR, "cannot create socket for %s", nconf->nc_netid);
+ rpcbind_log_error("cannot create socket for %s", nconf->nc_netid);
return -1;
}
@@ -400,14 +402,14 @@ create_transport_socket(struct netconfig *nconf, const char *hostname, struct ne
* This allows us to restart the server even if there are
* TCP sockets loitering around in TIME_WAIT */
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) != 0) {
- syslog(LOG_ERR, "cannot set SO_REUSEADDR on %s", nconf->nc_netid);
+ rpcbind_log_error("cannot set SO_REUSEADDR on %s", nconf->nc_netid);
return -1;
}
}
oldmask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
if (bind(fd, (struct sockaddr *) abuf->buf, abuf->len) != 0) {
- syslog(LOG_ERR, "cannot bind %s on %s: %m",
+ rpcbind_log_error("cannot bind %s on %s: %m",
hostname? hostname : "*",
nconf->nc_netid);
(void) umask(oldmask);
@@ -417,7 +419,7 @@ create_transport_socket(struct netconfig *nconf, const char *hostname, struct ne
if (nconf->nc_semantics != NC_TPI_CLTS) {
if (listen(fd, SOMAXCONN) < 0) {
- syslog(LOG_ERR, "unable to listen on %s socket: %m",
+ rpcbind_log_error("unable to listen on %s socket: %m",
nconf->nc_netid);
return -1;
}
@@ -465,7 +467,7 @@ rpcbind_register_transport(struct netconfig *nconf, SVCXPRT *xprt, struct netbuf
pml = malloc(sizeof (struct pmaplist));
if (pml == NULL) {
- syslog(LOG_ERR, "no memory!");
+ rpcbind_log_error("no memory!");
exit(1);
}
pml->pml_map.pm_prog = PMAPPROG;
@@ -487,7 +489,7 @@ rpcbind_register_transport(struct netconfig *nconf, SVCXPRT *xprt, struct netbuf
/* Add version 3 information */
pml = malloc(sizeof (struct pmaplist));
if (pml == NULL) {
- syslog(LOG_ERR, "no memory!");
+ rpcbind_log_error("no memory!");
exit(1);
}
pml->pml_map = list_pml->pml_map;
@@ -498,7 +500,7 @@ rpcbind_register_transport(struct netconfig *nconf, SVCXPRT *xprt, struct netbuf
/* Add version 4 information */
pml = malloc (sizeof (struct pmaplist));
if (pml == NULL) {
- syslog(LOG_ERR, "no memory!");
+ rpcbind_log_error("no memory!");
exit(1);
}
pml->pml_map = list_pml->pml_map;
@@ -517,7 +519,7 @@ rpcbind_register_transport(struct netconfig *nconf, SVCXPRT *xprt, struct netbuf
* non-root users. */
if (si.si_af == AF_INET || si.si_af == AF_LOCAL) {
if (!svc_register(xprt, PMAPPROG, PMAPVERS, pmap_service, 0)) {
- syslog(LOG_ERR, "could not register on %s",
+ rpcbind_log_error("could not register on %s",
nconf->nc_netid);
return 0;
}
@@ -526,7 +528,7 @@ rpcbind_register_transport(struct netconfig *nconf, SVCXPRT *xprt, struct netbuf
/* version 3 registration */
if (!svc_reg(xprt, RPCBPROG, RPCBVERS, rpcb_service_3, NULL)) {
- syslog(LOG_ERR, "could not register %s version 3",
+ rpcbind_log_error("could not register %s version 3",
nconf->nc_netid);
return 0;
}
@@ -534,7 +536,7 @@ rpcbind_register_transport(struct netconfig *nconf, SVCXPRT *xprt, struct netbuf
/* version 4 registration */
if (!svc_reg(xprt, RPCBPROG, RPCBVERS4, rpcb_service_4, NULL)) {
- syslog(LOG_ERR, "could not register %s version 4",
+ rpcbind_log_error("could not register %s version 4",
nconf->nc_netid);
return 0;
}
@@ -574,15 +576,15 @@ handle_ipv6_socket(int fd)
socklen_t len = sizeof(opt);
if (getsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, &len)) {
- syslog(LOG_ERR, "failed to get ipv6 socket opts: %m");
+ rpcbind_log_error("failed to get ipv6 socket opts: %m");
return -1;
}
if (opt) /* socket is already in V6ONLY mode */
return 0;
- syslog(LOG_ERR, "systemd has passed an IPv4/IPv6 dual-mode socket.");
- syslog(LOG_ERR, "Please fix your systemd config by specifying IPv4 and IPv6 sockets separately and using BindIPv6Only=ipv6-only.");
+ rpcbind_log_error("systemd has passed an IPv4/IPv6 dual-mode socket.");
+ rpcbind_log_error("Please fix your systemd config by specifying IPv4 and IPv6 sockets separately and using BindIPv6Only=ipv6-only.");
return -1;
}
@@ -613,7 +615,7 @@ rpcbind_init_endpoint(struct netconfig *nconf, const char *hostname, int fd)
socklen_t alen = sizeof(addr);
if (getsockname(fd, (struct sockaddr *) &addr, &alen) < 0) {
- syslog(LOG_ERR, "cannot get address for socket fd %d", fd);
+ rpcbind_log_error("cannot get address for socket fd %d", fd);
exit(1);
}
@@ -625,7 +627,7 @@ rpcbind_init_endpoint(struct netconfig *nconf, const char *hostname, int fd)
my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr, RPC_MAXDATASIZE, RPC_MAXDATASIZE);
if (my_xprt == (SVCXPRT *)NULL) {
- syslog(LOG_ERR, "%s: could not create service", nconf->nc_netid);
+ rpcbind_log_error("%s: could not create service", nconf->nc_netid);
close(fd);
return 0;
}
@@ -667,7 +669,7 @@ init_transport(struct netconfig *nconf)
#endif
if (!__rpc_nconf2sockinfo(nconf, &si)) {
- syslog(LOG_ERR, "cannot get information for %s",
+ rpcbind_log_error("cannot get information for %s",
nconf->nc_netid);
return (1);
}
@@ -746,7 +748,7 @@ init_transports_daemon(void)
nc_handle = setnetconfig(); /* open netconfig file */
if (nc_handle == NULL) {
- syslog(LOG_ERR, "could not read /etc/netconfig");
+ rpcbind_log_error("could not read /etc/netconfig");
exit(1);
}
@@ -754,7 +756,7 @@ init_transports_daemon(void)
if (nconf == NULL)
nconf = getnetconfigent("unix");
if (nconf == NULL) {
- syslog(LOG_ERR, "rpcbind: can't find local transport\n");
+ rpcbind_log_error("rpcbind: can't find local transport\n");
exit(1);
}
@@ -798,11 +800,11 @@ init_transports_systemd()
int nfds, n;
if ((nfds = sd_listen_fds(0)) < 0) {
- syslog(LOG_ERR, "failed to acquire systemd sockets: %s", strerror(-nfds));
+ rpcbind_log_error("failed to acquire systemd sockets: %s", strerror(-nfds));
exit(1);
}
if (nfds >= 16) {
- syslog(LOG_ERR, "too many sockets passed by systemd (%u)", nfds);
+ rpcbind_log_error("too many sockets passed by systemd (%u)", nfds);
exit(1);
}
@@ -814,18 +816,18 @@ init_transports_systemd()
fd = SD_LISTEN_FDS_START + n;
if (!__rpc_fd2sockinfo(fd, &si)) {
- syslog(LOG_ERR, "cannot get socket information for fd %d", fd);
+ rpcbind_log_error("cannot get socket information for fd %d", fd);
exit(1);
}
/* Now find the netconfig entry matching this transport */
if ((nconf = sockinfo2nconf(&nc_handle, &si)) == NULL) {
- syslog(LOG_ERR, "not netconfig for socket fd %d", fd);
+ rpcbind_log_error("not netconfig for socket fd %d", fd);
exit(1);
}
if (rpcbind_init_endpoint(nconf, NULL, fd) <= 0) {
- syslog(LOG_ERR, "unable to create transport for socket fd %d", fd);
+ rpcbind_log_error("unable to create transport for socket fd %d", fd);
exit(1);
}
}
@@ -843,7 +845,7 @@ rbllist_add(rpcprog_t prog, rpcvers_t vers, struct netconfig *nconf,
rbl = malloc(sizeof (rpcblist));
if (rbl == NULL) {
- syslog(LOG_ERR, "no memory!");
+ rpcbind_log_error("no memory!");
exit(1);
}
#ifdef RPCBIND_DEBUG
@@ -872,7 +874,7 @@ terminate(int dummy /*__unused*/)
unlink(_PATH_RPCBINDSOCK);
unlink(RPCBINDDLOCK);
#ifdef WARMSTART
- syslog(LOG_ERR,
+ rpcbind_log_error(
"rpcbind terminating on signal. Restart with \"rpcbind -w\"");
write_warmstart(); /* Dump yourself */
#endif
@@ -956,3 +958,33 @@ toggle_verboselog(int dummy /*__unused*/)
{
verboselog = !verboselog;
}
+
+void
+rpcbind_log_error(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+#ifdef SYSTEMD
+ if (systemd_activation)
+ sd_journal_printv(LOG_ERR, fmt, ap);
+ else
+#endif
+ vsyslog(LOG_ERR, fmt, ap);
+ va_end(ap);
+}
+
+void
+rpcbind_log(int severity, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+#ifdef SYSTEMD
+ if (systemd_activation)
+ sd_journal_printv(severity, fmt, ap);
+ else
+#endif
+ vsyslog(severity, fmt, ap);
+ va_end(ap);
+}
diff --git a/src/rpcbind.h b/src/rpcbind.h
index 74f9591..bbdbd35 100644
--- a/src/rpcbind.h
+++ b/src/rpcbind.h
@@ -136,6 +136,9 @@ char *addrmerge(struct netbuf *caller, char *serv_uaddr, char *clnt_uaddr, char
void network_init(void);
struct sockaddr *local_sa(int);
+void rpcbind_log_error(const char *, ...);
+void rpcbind_log(int, const char *, ...);
+
/* For different getaddr semantics */
#define RPCB_ALLVERS 0
#define RPCB_ONEVERS 1
diff --git a/src/security.c b/src/security.c
index d272f74..3b768c0 100644
--- a/src/security.c
+++ b/src/security.c
@@ -274,7 +274,7 @@ logit(int severity, struct sockaddr *addr, rpcproc_t procnum, rpcprog_t prognum,
}
getnameinfo(addr,size , fromname, sizeof fromname, NULL, 0, NI_NUMERICHOST);
}
- syslog(severity, "connect from %s to %s(%s)%s",
+ rpcbind_log(severity, "connect from %s to %s(%s)%s",
fromname, procname, progname, text);
_exit(0);
}
diff --git a/src/warmstart.c b/src/warmstart.c
index d1bb971..16eed3e 100644
--- a/src/warmstart.c
+++ b/src/warmstart.c
@@ -42,7 +42,6 @@
#include <netinet/in.h>
#include <rpc/pmap_prot.h>
#endif
-#include <syslog.h>
#include <unistd.h>
#include <errno.h>
@@ -77,9 +76,9 @@ write_struct(char *filename, xdrproc_t structproc, void *list)
close(i);
fp = fopen(filename, "w");
if (fp == NULL) {
- syslog(LOG_ERR,
+ rpcbind_log_error(
"cannot open file = %s for writing", filename);
- syslog(LOG_ERR, "cannot save any registration");
+ rpcbind_log_error("cannot save any registration");
return (FALSE);
}
}
@@ -87,7 +86,7 @@ write_struct(char *filename, xdrproc_t structproc, void *list)
xdrstdio_create(&xdrs, fp, XDR_ENCODE);
if (structproc(&xdrs, list) == FALSE) {
- syslog(LOG_ERR, "xdr_%s: failed", filename);
+ rpcbind_log_error("xdr_%s: failed", filename);
fclose(fp);
return (FALSE);
}
@@ -106,7 +105,7 @@ read_struct(char *filename, xdrproc_t structproc, void *list)
fprintf(stderr, "rpcbind: using '%s' startup file\n", filename);
if ((fp = fopen(filename, "r")) == NULL) {
- syslog(LOG_ERR,
+ rpcbind_log_error(
"Cannot open '%s' file for reading, errno %d (%s)",
filename, errno, strerror(errno));
goto error;
@@ -122,14 +121,14 @@ read_struct(char *filename, xdrproc_t structproc, void *list)
fclose(fp);
if (unlink(filename) < 0) {
- syslog(LOG_ERR, "Cannot unlink '%s', errno %d (%s)",
+ rpcbind_log_error("Cannot unlink '%s', errno %d (%s)",
filename, errno, strerror(errno));
}
return (TRUE);
error:
if (errno != ENOENT && unlink(filename) < 0) {
- syslog(LOG_ERR, "Cannot unlink '%s', errno %d (%s)",
+ rpcbind_log_error("Cannot unlink '%s', errno %d (%s)",
filename, errno, strerror(errno));
}
if (debugging)
--
1.7.12.4

View File

@ -0,0 +1,43 @@
From 417e4dc9a33711843a36c700fbc3ce1d7a823a0d Mon Sep 17 00:00:00 2001
From: Olaf Kirch <okir@suse.de>
Date: Tue, 20 Aug 2013 16:01:59 +0200
Subject: [PATCH 13/13] When using systemd activation, make rpcbind notify
system when ready to service requests
Signed-off-by: Olaf Kirch <okir@suse.de>
---
src/rpcbind.c | 5 ++++-
systemd/rpcbind.service.in | 1 +
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/rpcbind.c b/src/rpcbind.c
index 964c2d3..7fa6baf 100644
--- a/src/rpcbind.c
+++ b/src/rpcbind.c
@@ -260,7 +260,10 @@ main(int argc, char *argv[])
#endif
network_init();
-
+#ifdef SYSTEMD
+ if (systemd_activation)
+ sd_notify(0, "READY=1");
+#endif
my_svc_run();
rpcbind_log_error("svc_run returned unexpectedly");
rpcbind_abort();
diff --git a/systemd/rpcbind.service.in b/systemd/rpcbind.service.in
index 58ae5de..527d07b 100644
--- a/systemd/rpcbind.service.in
+++ b/systemd/rpcbind.service.in
@@ -2,6 +2,7 @@
Description=RPC Bind
[Service]
+Type=notify
ExecStart=@bindir@/rpcbind -w -f
[Install]
--
1.7.12.4

View File

@ -0,0 +1,40 @@
From 95d8dc18699638313a2b9bd3dcd3b84eaed432d8 Mon Sep 17 00:00:00 2001
From: Olaf Kirch <okir@suse.de>
Date: Fri, 10 Jan 2014 11:29:40 +0100
Subject: [PATCH 14/14] Notify systemd unconditionally
rpcbind may be started from systemd with or without socket activation.
However, in both cases systemd would expect to be notified of successful
startup.
If we're started from the command line, calling sd_notify doesn't do
any harm either; it will just silently fail.
Signed-off-by: Olaf Kirch <okir@suse.de>
---
src/rpcbind.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/rpcbind.c b/src/rpcbind.c
index 7fa6baf..8df2950 100644
--- a/src/rpcbind.c
+++ b/src/rpcbind.c
@@ -260,9 +260,13 @@ main(int argc, char *argv[])
#endif
network_init();
+
#ifdef SYSTEMD
- if (systemd_activation)
- sd_notify(0, "READY=1");
+ /* Try to notify system of successful startup, regardless of whether we
+ * used systemd socket activation or not. When started from the command
+ * line, this should not hurt either.
+ */
+ rpcbind_log_error("sd_notify returns %d\n", sd_notify(0, "READY=1"));
#endif
my_svc_run();
rpcbind_log_error("svc_run returned unexpectedly");
--
1.7.12.4

View File

@ -0,0 +1,27 @@
From 565692c3c88c6e94f31fb511c374d5a9f3c31075 Mon Sep 17 00:00:00 2001
From: Olaf Kirch <okir@suse.de>
Date: Tue, 14 Jan 2014 16:19:04 +0100
Subject: [PATCH 15/15] Pull the sysconfig file into rpcbind.service and use
Signed-off-by: Olaf Kirch <okir@suse.de>
---
systemd/rpcbind.service.in | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/systemd/rpcbind.service.in b/systemd/rpcbind.service.in
index 527d07b..1f5b596 100644
--- a/systemd/rpcbind.service.in
+++ b/systemd/rpcbind.service.in
@@ -3,7 +3,8 @@ Description=RPC Bind
[Service]
Type=notify
-ExecStart=@bindir@/rpcbind -w -f
+EnvironmentFile=-/etc/sysconfig/rpcbind
+ExecStart=@bindir@/rpcbind $RPCBIND_OPTIONS -w -f
[Install]
WantedBy=multi-user.target
--
1.7.12.4

View File

@ -0,0 +1,30 @@
From 0be5e1d603226b3226e4204f67471788eacf475c Mon Sep 17 00:00:00 2001
From: Olaf Kirch <okir@suse.de>
Date: Tue, 14 Jan 2014 16:40:55 +0100
Subject: [PATCH 17/17] configure: check for <nss.h>
There's code in rpcbind that tries to configure nss lookups so that it
avoids NIS when resolving user names or service names. Unfortunately, this
code is turned into a no-op unless HAVE_NSS_H is defined. Which it is not
unless the configure script actually checks for it.
Signed-off-by: Olaf Kirch <okir@suse.de>
---
configure.ac | 1 +
1 file changed, 1 insertion(+)
diff --git a/configure.ac b/configure.ac
index 6d91dcd..8cdd08f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -40,6 +40,7 @@ AC_ARG_WITH([systemdsystemunitdir],
fi
AM_CONDITIONAL(SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ])
+AC_CHECK_HEADERS(nss.h)
AS_IF([test x$enable_libwrap = xyes], [
AC_CHECK_LIB([wrap], [hosts_access], ,
--
1.7.12.4

View File

@ -1,13 +0,0 @@
Index: rpcbind-0.2.0_git201103171419/src/rpcbind.c
===================================================================
--- rpcbind-0.2.0_git201103171419.orig/src/rpcbind.c
+++ rpcbind-0.2.0_git201103171419/src/rpcbind.c
@@ -93,7 +93,7 @@ char *rpcbinduser = NULL;
/* who to suid to if -s is given */
#define RUN_AS "daemon"
-#define RPCBINDDLOCK "/var/run/rpcbind.lock"
+#define RPCBINDDLOCK "/run/rpcbind.lock"
int runasdaemon = 0;
int insecure = 0;

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dd1363a8537a5839814d9a013a1b014353752e2d63dcb94c33d662dfae4e94f7
size 49419

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9fde689ddaf775c092a10012281fa4b8fcbbcee77ccf1b0784feed45c523b604
size 49282

View File

@ -1,520 +0,0 @@
--- src/check_bound.c.orig
+++ src/check_bound.c
@@ -52,7 +52,6 @@ static char sccsid[] = "@(#)check_bound.
#include <rpc/rpc.h>
#include <stdio.h>
#include <netconfig.h>
-#include <syslog.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
@@ -119,7 +118,7 @@ add_bndlist(struct netconfig *nconf, str
fdl = malloc(sizeof (struct fdlist));
if (fdl == NULL) {
freenetconfigent(newnconf);
- syslog(LOG_ERR, "no memory!");
+ rpcbind_syslog(LOG_ERR, "no memory!");
return (-1);
}
fdl->nconf = newnconf;
@@ -179,7 +178,7 @@ mergeaddr(SVCXPRT *xprt, char *netid, ch
} else {
c_uaddr = taddr2uaddr(fdl->nconf, svc_getrpccaller(xprt));
if (c_uaddr == NULL) {
- syslog(LOG_ERR, "taddr2uaddr failed for %s",
+ rpcbind_syslog(LOG_ERR, "taddr2uaddr failed for %s",
fdl->nconf->nc_netid);
return (NULL);
}
--- src/rpcb_svc.c.orig
+++ src/rpcb_svc.c
@@ -45,7 +45,6 @@
#include <rpc/rpc.h>
#include <rpc/rpcb_prot.h>
#include <netconfig.h>
-#include <syslog.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
--- src/rpcb_svc_4.c.orig
+++ src/rpcb_svc_4.c
@@ -48,7 +48,6 @@
#include <stdio.h>
#include <unistd.h>
#include <netconfig.h>
-#include <syslog.h>
#include <string.h>
#include <stdlib.h>
#include "rpcbind.h"
--- src/rpcb_svc_com.c.orig
+++ src/rpcb_svc_com.c
@@ -50,7 +50,6 @@
#include <rpc/svc_dg.h>
#include <netconfig.h>
#include <errno.h>
-#include <syslog.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
@@ -520,7 +519,7 @@ create_rmtcall_fd(struct netconfig *ncon
}
rmt = malloc(sizeof (struct rmtcallfd_list));
if (rmt == NULL) {
- syslog(LOG_ERR, "create_rmtcall_fd: no memory!");
+ rpcbind_syslog(LOG_ERR, "create_rmtcall_fd: no memory!");
return (-1);
}
rmt->xprt = xprt;
@@ -1433,7 +1432,7 @@ add_pmaplist(RPCB *arg)
*/
pml = malloc(sizeof (struct pmaplist));
if (pml == NULL) {
- (void) syslog(LOG_ERR, "rpcbind: no memory!\n");
+ (void) rpcbind_syslog(LOG_ERR, "rpcbind: no memory!\n");
return (1);
}
pml->pml_map = pmap;
--- src/rpcbind.c.orig
+++ src/rpcbind.c
@@ -66,7 +66,6 @@
#include <netconfig.h>
#include <stdlib.h>
#include <unistd.h>
-#include <syslog.h>
#include <err.h>
#include <pwd.h>
#include <string.h>
@@ -169,7 +168,7 @@ main(int argc, char *argv[])
nc_handle = setnetconfig(); /* open netconfig file */
if (nc_handle == NULL) {
- syslog(LOG_ERR, "could not read /etc/netconfig");
+ rpcbind_syslog(LOG_ERR, "could not read /etc/netconfig");
exit(1);
}
@@ -177,7 +176,7 @@ main(int argc, char *argv[])
if (nconf == NULL)
nconf = getnetconfigent("unix");
if (nconf == NULL) {
- syslog(LOG_ERR, "%s: can't find local transport\n", argv[0]);
+ rpcbind_syslog(LOG_ERR, "%s: can't find local transport\n", argv[0]);
exit(1);
}
@@ -234,15 +233,15 @@ main(int argc, char *argv[])
__nss_configure_lookup("passwd", "files");
if((p = getpwnam(id)) == NULL) {
- syslog(LOG_ERR, "cannot get uid of '%s': %m", id);
+ rpcbind_syslog(LOG_ERR, "cannot get uid of '%s': %m", id);
exit(1);
}
if (setgid(p->pw_gid) == -1) {
- syslog(LOG_ERR, "setgid to '%s' (%d) failed: %m", id, p->pw_gid);
+ rpcbind_syslog(LOG_ERR, "setgid to '%s' (%d) failed: %m", id, p->pw_gid);
exit(1);
}
if (setuid(p->pw_uid) == -1) {
- syslog(LOG_ERR, "setuid to '%s' (%d) failed: %m", id, p->pw_uid);
+ rpcbind_syslog(LOG_ERR, "setuid to '%s' (%d) failed: %m", id, p->pw_uid);
exit(1);
}
}
@@ -256,7 +255,7 @@ main(int argc, char *argv[])
network_init();
my_svc_run();
- syslog(LOG_ERR, "svc_run returned unexpectedly");
+ rpcbind_syslog(LOG_ERR, "svc_run returned unexpectedly");
rpcbind_abort();
/* NOTREACHED */
@@ -276,7 +275,7 @@ handle_ipv6_socket(int fd)
socklen_t len = sizeof(opt);
if (getsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, &len)) {
- syslog(LOG_ERR, "failed to get ipv6 socket opts: %s",
+ rpcbind_syslog(LOG_ERR, "failed to get ipv6 socket opts: %s",
strerror(errno));
return 1;
}
@@ -284,8 +283,8 @@ handle_ipv6_socket(int fd)
if (opt) /* socket is already in V6ONLY mode */
return 0;
- syslog(LOG_ERR, "systemd has passed an IPv4/IPv6 dual-mode socket.");
- syslog(LOG_ERR, "Please fix your systemd config by specifying IPv4 and IPv6 sockets separately and using BindIPv6Only=ipv6-only.");
+ rpcbind_syslog(LOG_ERR, "systemd has passed an IPv4/IPv6 dual-mode socket.");
+ rpcbind_syslog(LOG_ERR, "Please fix your systemd config by specifying IPv4 and IPv6 sockets separately and using BindIPv6Only=ipv6-only.");
return 1;
}
@@ -333,7 +332,7 @@ init_transport(struct netconfig *nconf)
#endif
if (!__rpc_nconf2sockinfo(nconf, &si)) {
- syslog(LOG_ERR, "cannot get information for %s",
+ rpcbind_syslog(LOG_ERR, "cannot get information for %s",
nconf->nc_netid);
return (1);
}
@@ -341,7 +340,7 @@ init_transport(struct netconfig *nconf)
#ifdef SYSTEMD
n = sd_listen_fds(0);
if (n < 0) {
- syslog(LOG_ERR, "failed to acquire systemd sockets: %s", strerror(-n));
+ rpcbind_syslog(LOG_ERR, "failed to acquire systemd sockets: %s", strerror(-n));
return 1;
}
@@ -360,7 +359,7 @@ init_transport(struct netconfig *nconf)
socklen_t addrlen = sizeof(sa);
if (!__rpc_fd2sockinfo(fd, &si_other)) {
- syslog(LOG_ERR, "cannot get information for fd %i", fd);
+ rpcbind_syslog(LOG_ERR, "cannot get information for fd %i", fd);
return 1;
}
@@ -370,7 +369,7 @@ init_transport(struct netconfig *nconf)
continue;
if (getsockname(fd, &sa.sa, &addrlen) < 0) {
- syslog(LOG_ERR, "failed to query socket name: %s",
+ rpcbind_syslog(LOG_ERR, "failed to query socket name: %s",
strerror(errno));
goto error;
}
@@ -382,7 +381,7 @@ init_transport(struct netconfig *nconf)
taddr.addr.maxlen = taddr.addr.len = addrlen;
taddr.addr.buf = malloc(addrlen);
if (taddr.addr.buf == NULL) {
- syslog(LOG_ERR,
+ rpcbind_syslog(LOG_ERR,
"cannot allocate memory for %s address",
nconf->nc_netid);
goto error;
@@ -392,7 +391,7 @@ init_transport(struct netconfig *nconf)
my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr,
RPC_MAXDATASIZE, RPC_MAXDATASIZE);
if (my_xprt == (SVCXPRT *)NULL) {
- syslog(LOG_ERR, "%s: could not create service",
+ rpcbind_syslog(LOG_ERR, "%s: could not create service",
nconf->nc_netid);
goto error;
}
@@ -419,7 +418,7 @@ init_transport(struct netconfig *nconf)
*/
if (nconf->nc_semantics != NC_TPI_CLTS) {
if ((fd = __rpc_nconf2fd(nconf)) < 0) {
- syslog(LOG_ERR, "cannot create socket for %s",
+ rpcbind_syslog(LOG_ERR, "cannot create socket for %s",
nconf->nc_netid);
return (1);
}
@@ -471,7 +470,7 @@ init_transport(struct netconfig *nconf)
* XXX - using RPC library internal functions.
*/
if ((fd = __rpc_nconf2fd(nconf)) < 0) {
- syslog(LOG_ERR, "cannot create socket for %s",
+ rpcbind_syslog(LOG_ERR, "cannot create socket for %s",
nconf->nc_netid);
return (1);
}
@@ -516,7 +515,7 @@ init_transport(struct netconfig *nconf)
servname, &hints, &res)) != 0) {
if ((aicode = getaddrinfo(hosts[nhostsbak],
"portmapper", &hints, &res)) != 0) {
- syslog(LOG_ERR,
+ rpcbind_syslog(LOG_ERR,
"cannot get local address for %s: %s",
nconf->nc_netid, gai_strerror(aicode));
continue;
@@ -526,7 +525,7 @@ init_transport(struct netconfig *nconf)
sa = (struct sockaddr *)res->ai_addr;
oldmask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
if (bind(fd, sa, addrlen) != 0) {
- syslog(LOG_ERR, "cannot bind %s on %s: %m",
+ rpcbind_syslog(LOG_ERR, "cannot bind %s on %s: %m",
(hosts[nhostsbak] == NULL) ? "*" :
hosts[nhostsbak], nconf->nc_netid);
if (res != NULL)
@@ -540,7 +539,7 @@ init_transport(struct netconfig *nconf)
taddr.addr.maxlen = taddr.addr.len = addrlen;
taddr.addr.buf = malloc(addrlen);
if (taddr.addr.buf == NULL) {
- syslog(LOG_ERR,
+ rpcbind_syslog(LOG_ERR,
"cannot allocate memory for %s address",
nconf->nc_netid);
if (res != NULL)
@@ -577,7 +576,7 @@ init_transport(struct netconfig *nconf)
my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr,
RPC_MAXDATASIZE, RPC_MAXDATASIZE);
if (my_xprt == (SVCXPRT *)NULL) {
- syslog(LOG_ERR, "%s: could not create service",
+ rpcbind_syslog(LOG_ERR, "%s: could not create service",
nconf->nc_netid);
goto error;
}
@@ -590,7 +589,7 @@ init_transport(struct netconfig *nconf)
if ((aicode = getaddrinfo(NULL, servname, &hints, &res))!= 0) {
if ((aicode = getaddrinfo(NULL, "portmapper", &hints, &res))!= 0) {
printf("cannot get local address for %s: %s", nconf->nc_netid, gai_strerror(aicode));
- syslog(LOG_ERR,
+ rpcbind_syslog(LOG_ERR,
"cannot get local address for %s: %s",
nconf->nc_netid, gai_strerror(aicode));
return 1;
@@ -603,14 +602,14 @@ init_transport(struct netconfig *nconf)
__rpc_fd2sockinfo(fd, &si);
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on,
sizeof(on)) != 0) {
- syslog(LOG_ERR, "cannot set SO_REUSEADDR on %s",
+ rpcbind_syslog(LOG_ERR, "cannot set SO_REUSEADDR on %s",
nconf->nc_netid);
if (res != NULL)
freeaddrinfo(res);
return 1;
}
if (bind(fd, sa, addrlen) < 0) {
- syslog(LOG_ERR, "cannot bind %s: %m", nconf->nc_netid);
+ rpcbind_syslog(LOG_ERR, "cannot bind %s: %m", nconf->nc_netid);
if (res != NULL)
freeaddrinfo(res);
return 1;
@@ -621,7 +620,7 @@ init_transport(struct netconfig *nconf)
taddr.addr.len = taddr.addr.maxlen = addrlen;
taddr.addr.buf = malloc(addrlen);
if (taddr.addr.buf == NULL) {
- syslog(LOG_ERR, "cannot allocate memory for %s address",
+ rpcbind_syslog(LOG_ERR, "cannot allocate memory for %s address",
nconf->nc_netid);
if (res != NULL)
freeaddrinfo(res);
@@ -656,7 +655,7 @@ init_transport(struct netconfig *nconf)
my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr, RPC_MAXDATASIZE, RPC_MAXDATASIZE);
if (my_xprt == (SVCXPRT *)NULL) {
- syslog(LOG_ERR, "%s: could not create service",
+ rpcbind_syslog(LOG_ERR, "%s: could not create service",
nconf->nc_netid);
goto error;
}
@@ -673,7 +672,7 @@ init_transport(struct netconfig *nconf)
pml = malloc(sizeof (struct pmaplist));
if (pml == NULL) {
- syslog(LOG_ERR, "no memory!");
+ rpcbind_syslog(LOG_ERR, "no memory!");
exit(1);
}
pml->pml_map.pm_prog = PMAPPROG;
@@ -695,7 +694,7 @@ init_transport(struct netconfig *nconf)
/* Add version 3 information */
pml = malloc(sizeof (struct pmaplist));
if (pml == NULL) {
- syslog(LOG_ERR, "no memory!");
+ rpcbind_syslog(LOG_ERR, "no memory!");
exit(1);
}
pml->pml_map = list_pml->pml_map;
@@ -706,7 +705,7 @@ init_transport(struct netconfig *nconf)
/* Add version 4 information */
pml = malloc (sizeof (struct pmaplist));
if (pml == NULL) {
- syslog(LOG_ERR, "no memory!");
+ rpcbind_syslog(LOG_ERR, "no memory!");
exit(1);
}
pml->pml_map = list_pml->pml_map;
@@ -725,7 +724,7 @@ init_transport(struct netconfig *nconf)
* non-root users. */
if (si.si_af == AF_INET || si.si_af == AF_LOCAL) {
if (!svc_register(my_xprt, PMAPPROG, PMAPVERS, pmap_service, 0)) {
- syslog(LOG_ERR, "could not register on %s",
+ rpcbind_syslog(LOG_ERR, "could not register on %s",
nconf->nc_netid);
goto error;
}
@@ -734,7 +733,7 @@ init_transport(struct netconfig *nconf)
/* version 3 registration */
if (!svc_reg(my_xprt, RPCBPROG, RPCBVERS, rpcb_service_3, NULL)) {
- syslog(LOG_ERR, "could not register %s version 3",
+ rpcbind_syslog(LOG_ERR, "could not register %s version 3",
nconf->nc_netid);
goto error;
}
@@ -742,7 +741,7 @@ init_transport(struct netconfig *nconf)
/* version 4 registration */
if (!svc_reg(my_xprt, RPCBPROG, RPCBVERS4, rpcb_service_4, NULL)) {
- syslog(LOG_ERR, "could not register %s version 4",
+ rpcbind_syslog(LOG_ERR, "could not register %s version 4",
nconf->nc_netid);
goto error;
}
@@ -797,7 +796,7 @@ rbllist_add(rpcprog_t prog, rpcvers_t ve
rbl = malloc(sizeof (rpcblist));
if (rbl == NULL) {
- syslog(LOG_ERR, "no memory!");
+ rpcbind_syslog(LOG_ERR, "no memory!");
exit(1);
}
#ifdef RPCBIND_DEBUG
@@ -827,7 +826,7 @@ terminate(int dummy /*__unused*/)
unlink(_PATH_RPCBINDSOCK);
unlink(RPCBINDDLOCK);
#ifdef WARMSTART
- syslog(LOG_ERR,
+ rpcbind_syslog(LOG_ERR,
"rpcbind terminating on signal. Restart with \"rpcbind -w\"");
write_warmstart(); /* Dump yourself */
#endif
--- src/rpcbind.h.orig
+++ src/rpcbind.h
@@ -47,6 +47,14 @@
#endif
#include <rpc/rpcb_prot.h>
+#include <syslog.h>
+#ifdef SYSTEMD
+#include <systemd/sd-journal.h>
+#define rpcbind_syslog sd_journal_print
+#else
+#define rpcbind_syslog syslog
+#endif
+
/*
* Stuff for the rmtcall service
*/
--- src/security.c.orig
+++ src/security.c
@@ -14,7 +14,6 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#include <syslog.h>
#include <netdb.h>
/*
@@ -201,7 +200,7 @@ is_localroot(struct netbuf *nbuf)
}
-/* logit - report events of interest via the syslog daemon */
+/* logit - report events of interest via the rpcbind_syslog daemon */
void
logit(int severity, struct sockaddr *addr, rpcproc_t procnum, rpcprog_t prognum,
const char *text){
@@ -231,7 +230,7 @@ logit(int severity, struct sockaddr *add
/*
* Fork off a process or the portmap daemon might hang while
- * getrpcbynumber() or syslog() does its thing.
+ * getrpcbynumber() or rpcbind_syslog() does its thing.
*/
if (fork() == 0) {
@@ -256,7 +255,7 @@ logit(int severity, struct sockaddr *add
} else
procname = procmap[procnum];
- /* Write syslog record. */
+ /* Write rpcbind_syslog record. */
if (addr->sa_family == AF_LOCAL)
strcpy(fromname, "local");
@@ -274,7 +273,7 @@ logit(int severity, struct sockaddr *add
}
getnameinfo(addr,size , fromname, sizeof fromname, NULL, 0, NI_NUMERICHOST);
}
- syslog(severity, "connect from %s to %s(%s)%s",
+ rpcbind_syslog(severity, "connect from %s to %s(%s)%s",
fromname, procname, progname, text);
_exit(0);
}
--- src/warmstart.c.orig
+++ src/warmstart.c
@@ -42,7 +42,6 @@
#include <netinet/in.h>
#include <rpc/pmap_prot.h>
#endif
-#include <syslog.h>
#include <unistd.h>
#include <errno.h>
@@ -77,9 +76,9 @@ write_struct(char *filename, xdrproc_t s
close(i);
fp = fopen(filename, "w");
if (fp == NULL) {
- syslog(LOG_ERR,
+ rpcbind_syslog(LOG_ERR,
"cannot open file = %s for writing", filename);
- syslog(LOG_ERR, "cannot save any registration");
+ rpcbind_syslog(LOG_ERR, "cannot save any registration");
return (FALSE);
}
}
@@ -87,7 +86,7 @@ write_struct(char *filename, xdrproc_t s
xdrstdio_create(&xdrs, fp, XDR_ENCODE);
if (structproc(&xdrs, list) == FALSE) {
- syslog(LOG_ERR, "xdr_%s: failed", filename);
+ rpcbind_syslog(LOG_ERR, "xdr_%s: failed", filename);
fclose(fp);
return (FALSE);
}
@@ -106,7 +105,7 @@ read_struct(char *filename, xdrproc_t st
fprintf(stderr, "rpcbind: using '%s' startup file\n", filename);
if ((fp = fopen(filename, "r")) == NULL) {
- syslog(LOG_ERR,
+ rpcbind_syslog(LOG_ERR,
"Cannot open '%s' file for reading, errno %d (%s)",
filename, errno, strerror(errno));
goto error;
@@ -122,14 +121,14 @@ read_struct(char *filename, xdrproc_t st
fclose(fp);
if (unlink(filename) < 0) {
- syslog(LOG_ERR, "Cannot unlink '%s', errno %d (%s)",
+ rpcbind_syslog(LOG_ERR, "Cannot unlink '%s', errno %d (%s)",
filename, errno, strerror(errno));
}
return (TRUE);
error:
if (errno != ENOENT && unlink(filename) < 0) {
- syslog(LOG_ERR, "Cannot unlink '%s', errno %d (%s)",
+ rpcbind_syslog(LOG_ERR, "Cannot unlink '%s', errno %d (%s)",
filename, errno, strerror(errno));
}
if (debugging)
--- configure.in.orig
+++ configure.in
@@ -36,6 +36,7 @@ AC_ARG_WITH([systemdsystemunitdir],
if test "x$with_systemdsystemunitdir" != xno; then
AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])
PKG_CHECK_MODULES([SYSTEMD], [libsystemd-daemon])
+ PKG_CHECK_MODULES([SYSTEMD_JOURNAL], [libsystemd-journal])
fi
AM_CONDITIONAL(SYSTEMD, [test -n "$with_systemdsystemunitdir" -a "x$with_systemdsystemunitdir" != xno ])
--- Makefile.am.orig
+++ Makefile.am
@@ -39,9 +39,9 @@ rpcbind_SOURCES = \
rpcbind_LDADD = $(TIRPC_LIBS)
if SYSTEMD
-AM_CPPFLAGS += $(SYSTEMD_CFLAGS) -DSYSTEMD
+AM_CPPFLAGS += $(SYSTEMD_CFLAGS) $(SYSTEMD_JOURNAL_CFLAGS) -DSYSTEMD
-rpcbind_LDADD += $(SYSTEMD_LIBS)
+rpcbind_LDADD += $(SYSTEMD_LIBS) $(SYSTEMD_JOURNAL_LIBS)
systemd/rpcbind.service: systemd/rpcbind.service.in Makefile
sed -e 's,@bindir\@,$(bindir),g' \

View File

@ -1,23 +0,0 @@
--- rpcbind-0.2.0_git201103171419.orig/src/rpcbind.c
+++ rpcbind-0.2.0_git201103171419/src/rpcbind.c
@@ -253,7 +253,9 @@ main(int argc, char *argv[])
#endif
network_init();
-
+#ifdef SYSTEMD
+ sd_notify(0, "READY=1");
+#endif
my_svc_run();
rpcbind_syslog(LOG_ERR, "svc_run returned unexpectedly");
rpcbind_abort();
--- rpcbind-0.2.0_git201103171419.orig/systemd/rpcbind.service.in
+++ rpcbind-0.2.0_git201103171419/systemd/rpcbind.service.in
@@ -2,6 +2,7 @@
Description=RPC Bind
[Service]
+Type=notify
ExecStart=@bindir@/rpcbind -w -f
[Install]

View File

@ -1,3 +1,49 @@
-------------------------------------------------------------------
Tue Jan 14 16:18:49 UTC 2014 - okir@suse.com
- Recognize RPCBIND_OPTIONS from /etc/sysconfig/rpcbind (bnc#824621)
Added:
0015-Pull-the-sysconfig-file-into-rpcbind.service-and-use.patch
- Make rpcbind run as user "rpc" by default (bnc#714735)
- Avoid NIS lookups of host names and service names (bnc#858700)
Added:
0016-configure-check-for-nss.h.patch
-------------------------------------------------------------------
Fri Jan 10 10:58:47 UTC 2014 - okir@suse.com
- Notify systemd unconditionally. This prevented
"systemctl start rpcbind.service" from succeeding
Added:
0014-Notify-systemd-unconditionally.patch
-------------------------------------------------------------------
Tue Aug 20 18:34:19 UTC 2013 - okir@suse.com
- Update rpcbind to latest upstream, and rewrote patches for systemd
integration.
Removed:
0001-systemd-add-support-for-system-bus-activation.patch
socket-activation-don-t-unlink-socket-we-didn-t-create
socket-activation-fix-rpcbind-service-to-use-separate-sockets
rpcbind-journal.patch
move-lock-file-to-run-fs.patch
rpcbind-systemd-notify.patch
Added:
0001-Silence-a-warning-about-setgroups-being-implicitly-d.patch
0002-Remove-obsolete-function-in6_fillscopeid.patch
0003-configure-fix-the-case-when-with-rpcuser-is-not-give.patch
0004-In-init_transport-move-creation-of-COTS-sockets-clos.patch
0005-The-use-of-AI_NUMERICHOST-in-init_transport-is-broke.patch
0006-First-part-of-init_transport-refactoring.patch
0007-init_transport-move-the-registration-code-into-a-sep.patch
0008-Fix-the-behavior-when-specifying-the-h-option.patch
0009-Clean-up-the-way-we-handle-the-h-option-in-init_tran.patch
0010-Support-systemd-activation.patch
0011-socket-activation-Fix-rpcbind.service-to-use-separat.patch
0012-When-using-systemd-redirect-syslog-calls-to-the-syst.patch
0013-When-using-systemd-activation-make-rpcbind-notify-sy.patch
-------------------------------------------------------------------
Thu Jun 27 21:36:52 UTC 2013 - crrodriguez@opensuse.org

View File

@ -1,7 +1,7 @@
#
# spec file for package rpcbind
#
# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@ -17,7 +17,7 @@
Name: rpcbind
Version: 0.2.0_git201103171419
Version: 0.2.1_git1b0fdf5
Release: 0
Summary: Transport independent RPC portmapper
License: BSD-4-Clause
@ -33,12 +33,22 @@ BuildRequires: libtool
BuildRequires: pkgconfig
BuildRequires: tcpd-devel
PreReq: %fillup_prereq
Patch0: 0001-systemd-add-support-for-system-bus-activation.patch
Patch1: socket-activation-don-t-unlink-socket-we-didn-t-create
Patch2: socket-activation-fix-rpcbind-service-to-use-separate-sockets
Patch3: rpcbind-journal.patch
Patch4: move-lock-file-to-run-fs.patch
Patch5: rpcbind-systemd-notify.patch
Patch0: 0001-Silence-a-warning-about-setgroups-being-implicitly-d.patch
Patch1: 0002-Remove-obsolete-function-in6_fillscopeid.patch
Patch2: 0003-configure-fix-the-case-when-with-rpcuser-is-not-give.patch
Patch3: 0004-In-init_transport-move-creation-of-COTS-sockets-clos.patch
Patch4: 0005-The-use-of-AI_NUMERICHOST-in-init_transport-is-broke.patch
Patch5: 0006-First-part-of-init_transport-refactoring.patch
Patch6: 0007-init_transport-move-the-registration-code-into-a-sep.patch
Patch7: 0008-Fix-the-behavior-when-specifying-the-h-option.patch
Patch8: 0009-Clean-up-the-way-we-handle-the-h-option-in-init_tran.patch
Patch9: 0010-Support-systemd-activation.patch
Patch10: 0011-socket-activation-Fix-rpcbind.service-to-use-separat.patch
Patch11: 0012-When-using-systemd-redirect-syslog-calls-to-the-syst.patch
Patch12: 0013-When-using-systemd-activation-make-rpcbind-notify-sy.patch
Patch13: 0014-Notify-systemd-unconditionally.patch
Patch14: 0015-Pull-the-sysconfig-file-into-rpcbind.service-and-use.patch
Patch15: 0016-configure-check-for-nss.h.patch
%define statefile /var/lib/portmap.state
BuildRequires: pkgconfig(systemd)
%{?systemd_requires}
@ -64,9 +74,19 @@ cp %{SOURCE4} .
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p1
%patch13 -p1
%patch14 -p1
%patch15 -p1
%build
autoreconf -fiv
@ -76,7 +96,9 @@ export LDFLAGS="-pie -Wl,-z,relro,-z,now"
--bindir=/sbin \
--enable-libwrap \
--enable-warmstarts \
--with-statedir=%{_localstatedir}/lib/rpcbind
--enable-debug \
--with-statedir=%{_localstatedir}/lib/rpcbind \
--with-rpcuser=rpc
%{__make} %{?jobs:-j%jobs}
%{__cc} -pie -fpie -fwhole-program -Wl,-z,relro,-z,now %{optflags} pmap_set.c -o pmap_set
@ -98,6 +120,10 @@ rm -rf $RPM_BUILD_ROOT
%pre
%service_add_pre %{name}.service %{name}.socket
# Add "rpc" user
getent passwd rpc >/dev/null || useradd -r -g nogroup -d /var/lib/emptry -s /sbin/nologin -c "user for rpcbind" rpc
exit 0
%preun
%service_del_preun %{name}.service %{name}.socket

View File

@ -1,61 +0,0 @@
From: Jeff Mahoney <jeffm@suse.com>
Subject: socket-activation: don't unlink socket we didn't create
References: bnc#757667
On an unpatched system, try this:
rpcinfo <works>
rcrpcbind restart
rpcinfo <fails>
This is due to rpcbind unlinking the socket file when it exits. It
doesn't own the socket file when socket activation is used - systemd
does. Systemd still has an open reference to it and when rpcbind is
restarted, it passes the open reference back to it and rpcbind is
perfectly happy to accept it. Unfortunately, everything that needs to
talk to rpcbind no longer can because the socket file each of those
users needs to open is no longer on the file system.
This patch adds a new global that's used to avoid unlinking the
rpcbind.sock socket file during shutdown.
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
---
src/rpcbind.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
--- a/src/rpcbind.c
+++ b/src/rpcbind.c
@@ -80,6 +81,7 @@
int debugging = 0; /* Tell me what's going on */
int doabort = 0; /* When debugging, do an abort on errors */
int dofork = 1; /* fork? */
+int sock_needs_unlink = 1; /* we created rpcbind.sock */
rpcblist_ptr list_rbl; /* A list of version 3/4 rpcbind services */
@@ -365,6 +396,14 @@ init_transport(struct netconfig *nconf)
nconf->nc_netid);
goto error;
}
+
+ /*
+ * We were passed the open UNIX socket
+ * and shouldn't remove it.
+ */
+ if (sa.sa.sa_family == AF_UNIX &&
+ strcmp(sa.un.sun_path, _PATH_RPCBINDSOCK))
+ sock_needs_unlink = 0;
}
/* if none of the systemd sockets matched, we set up the socket in
@@ -784,7 +823,8 @@ static void
terminate(int dummy /*__unused*/)
{
close(rpcbindlockfd);
- unlink(_PATH_RPCBINDSOCK);
+ if (sock_needs_unlink)
+ unlink(_PATH_RPCBINDSOCK);
unlink(RPCBINDDLOCK);
#ifdef WARMSTART
syslog(LOG_ERR,