[PATCH 2/2] Introduce new helper function getpmaphandle

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Olaf Kirch <okir@xxxxxxx>
Date: Mon, 23 Aug 2010 14:36:13 +0200
Subject: [PATCH] pmap_set/unset: allow compat functions to work with old-style 
portmap

This change fixes a bug when running applications compiled against
libtirpc on a host with old-style portmap. Without this change, the
pmap_set/pmap_unset compatibility functions will actually be mapped
to a RPCB_SET/UNSET call. If the server does not support anything more
recent than PMAP, the operations will fail completely.

One choice to fix this problem would have been to reimplement just
pmap_set/pmap_unset. The alternative approach, which this patch
takes, it to make rpcb_set/unset default to the PMAP protocol when
changing an IPv4 registration.

Signed-off-by: Olaf Kirch <okir@xxxxxxx>
---
 src/rpcb_clnt.c |   70 
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 70 insertions(+), 0 deletions(-)

diff --git a/src/rpcb_clnt.c b/src/rpcb_clnt.c
index 531c619..021525b 100644
--- a/src/rpcb_clnt.c
+++ b/src/rpcb_clnt.c
@@ -476,6 +476,65 @@ getpmaphandle(nconf, hostname, tgtaddr)
 #define IN4_LOCALHOST_STRING	"127.0.0.1"
 #define IN6_LOCALHOST_STRING	"::1"
 
+#ifdef PORTMAP
+/*
+ * Perform a PMAP_SET or PMAP_UNSET call to the
+ * local rpcbind/portmap service.
+ */
+static bool_t
+pmap_setunset(pmapproc, program, version, nconf, address)
+	rpcproc_t pmapproc;
+	rpcprog_t program;
+	rpcvers_t version;
+	const struct netconfig *nconf;	/* Network structure of transport */
+	const struct netbuf *address;		/* Services netconfig address */
+{
+	CLIENT *client;
+	struct pmap pmapparms;
+	bool_t rslt = FALSE;
+	enum clnt_stat clnt_st;
+
+	if (strcmp(nconf->nc_protofmly, NC_INET) != 0)
+		return (FALSE);
+
+	if (strcmp(nconf->nc_proto, NC_UDP) != 0
+	 && strcmp(nconf->nc_proto, NC_TCP) != 0)
+		return (FALSE);
+
+	pmapparms.pm_prog = program;
+	pmapparms.pm_vers = version;
+	pmapparms.pm_prot = strcmp(nconf->nc_proto, NC_TCP) ?  IPPROTO_UDP : 
IPPROTO_TCP;
+	if (pmapproc == PMAPPROC_UNSET) {
+		pmapparms.pm_port = 0;
+	} else {
+		if (address == NULL)
+			return (FALSE);
+		pmapparms.pm_port = ntohs(((struct sockaddr_in *) address->buf)-
>sin_port);
+	}
+
+	client = getpmaphandle(nconf, IN4_LOCALHOST_STRING, NULL);
+	if (client == NULL)
+		return (FALSE);
+
+	clnt_st = CLNT_CALL(client, pmapproc,
+	    (xdrproc_t) xdr_pmap, (caddr_t)(void *) &pmapparms,
+	    (xdrproc_t) xdr_bool, (caddr_t)(void *) &rslt,
+	    tottimeout);
+
+	if (clnt_st == RPC_SUCCESS)
+		return rslt;
+
+	if (clnt_st != RPC_PROGVERSMISMATCH &&
+	    clnt_st != RPC_PROGUNAVAIL) {
+		rpc_createerr.cf_stat = RPC_PMAPFAILURE;
+		clnt_geterr(client, &rpc_createerr.cf_error);
+		return (FALSE);
+	}
+
+	return (TRUE);
+}
+#endif
+
 /*
  * This routine will return a client handle that is connected to the local
  * rpcbind. Returns NULL on error and free's everything.
@@ -600,6 +659,12 @@ rpcb_set(program, version, nconf, address)
 		rpc_createerr.cf_stat = RPC_UNKNOWNADDR;
 		return (FALSE);
 	}
+
+#ifdef PORTMAP
+	if (pmap_setunset(PMAPPROC_SET, program, version, nconf, address))
+		return (TRUE);
+#endif
+
 	client = local_rpcb();
 	if (! client) {
 		return (FALSE);
@@ -651,6 +716,11 @@ rpcb_unset(program, version, nconf)
 	RPCB parms;
 	char uidbuf[32];
 
+#ifdef PORTMAP
+	if (pmap_setunset(PMAPPROC_UNSET, program, version, nconf, NULL))
+		return (TRUE);
+#endif
+
 	client = local_rpcb();
 	if (! client) {
 		return (FALSE);
-- 
1.6.0.2


-- 
Neo didn't bring down the Matrix. SOA did. (soafacts.com)
--------------------------------------------
Olaf Kirch - Director Server (okir@xxxxxxxxxx)
SUSE LINUX Products GmbH, Maxfeldstr. 5, D-90409 Nürnberg
GF: Markus Rex, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux