From e10053ca4ddefd8713134c6f81d302947ab573c3 Mon Sep 17 00:00:00 2001 From: Steve Dickson Date: Sep 16 2008 15:48:09 +0000 Subject: - Added usptream patches 01 thru 03 that do: Introduce helpers for ipprot/netid mapping Change how we decide on the netids to use for portmap Simplify port live check in pmap_svc.c --- diff --git a/rpcbind-0.1.6-ipprot2netid.patch b/rpcbind-0.1.6-ipprot2netid.patch new file mode 100644 index 0000000..e006adb --- /dev/null +++ b/rpcbind-0.1.6-ipprot2netid.patch @@ -0,0 +1,146 @@ +commit 3e4c74ab527375f37b6633f528e7eab0c363967b +Author: Olaf Kirch +Date: Tue Sep 16 10:08:35 2008 -0400 + + Introduce helpers for ipprot/netid mapping + + There's a couple of places in the portmap emulation code + where we translate between ip protocol numbers and netids. + Encapsulate these in two helper functions: + + extern char *pmap_ipprot2netid(int); + extern int pmap_netid2ipprot(const char *); + + Signed-off-by: okir@suse.de + Signed-off-by: Steve Dickson + +diff --git a/src/pmap_svc.c b/src/pmap_svc.c +index 99ce508..02a57d2 100644 +--- a/src/pmap_svc.c ++++ b/src/pmap_svc.c +@@ -211,11 +211,8 @@ pmapproc_change(struct svc_req *rqstp /*__unused*/, SVCXPRT *xprt, unsigned long + if (op == PMAPPROC_SET) { + char buf[32]; + +- if (reg.pm_prot == IPPROTO_UDP) { +- rpcbreg.r_netid = udptrans; +- } else if (reg.pm_prot == IPPROTO_TCP) { +- rpcbreg.r_netid = tcptrans; +- } else { ++ rpcbreg.r_netid = pmap_ipprot2netid(reg.pm_prot); ++ if (rpcbreg.r_netid == NULL) { + ans = FALSE; + goto done_change; + } +@@ -289,7 +286,8 @@ pmapproc_getport(struct svc_req *rqstp /*__unused*/, SVCXPRT *xprt) + svc_getrpccaller(xprt)); + fprintf(stderr, "PMAP_GETPORT req for (%lu, %lu, %s) from %s :", + reg.pm_prog, reg.pm_vers, +- reg.pm_prot == IPPROTO_UDP ? "udp" : "tcp", uaddr); ++ pmap_ipprot2netid(reg.pm_prot)?: "", ++ uaddr); + free(uaddr); + } + #endif +@@ -299,12 +297,13 @@ pmapproc_getport(struct svc_req *rqstp /*__unused*/, SVCXPRT *xprt) + char *pt1, *pt2; + char *netid; + ++ netid = pmap_ipprot2netid(reg.pm_prot); ++ if (netid == NULL) ++ goto sendreply; + if (reg.pm_prot == IPPROTO_UDP) { + ua = udp_uaddr; +- netid = udptrans; + } else { + ua = tcp_uaddr; /* To get the len */ +- netid = tcptrans; + } + if (ua == NULL) { + goto sendreply; +@@ -341,7 +340,7 @@ sendreply: + fprintf(stderr, "port = %d\n", port); + #endif + rpcbs_getaddr(RPCBVERS_2_STAT, reg.pm_prog, reg.pm_vers, +- reg.pm_prot == IPPROTO_UDP ? udptrans : tcptrans, ++ pmap_ipprot2netid(reg.pm_prot) ?: "", + port ? udptrans : ""); + + return (TRUE); +@@ -372,4 +371,24 @@ pmapproc_dump(struct svc_req *rqstp /*__unused*/, SVCXPRT *xprt) + return (TRUE); + } + ++int pmap_netid2ipprot(const char *netid) ++{ ++ if (!netid) ++ return 0; ++ if (strcmp(netid, tcptrans) == 0) ++ return IPPROTO_TCP; ++ if (strcmp(netid, udptrans) == 0) ++ return IPPROTO_UDP; ++ return 0; ++} ++ ++char *pmap_ipprot2netid(unsigned long proto) ++{ ++ if (proto == IPPROTO_UDP) ++ return udptrans; ++ if (proto == IPPROTO_TCP) ++ return tcptrans; ++ return NULL; ++} ++ + #endif /* PORTMAP */ +diff --git a/src/rpcb_svc_com.c b/src/rpcb_svc_com.c +index 8f6b4c7..08aa194 100644 +--- a/src/rpcb_svc_com.c ++++ b/src/rpcb_svc_com.c +@@ -1416,13 +1416,8 @@ add_pmaplist(RPCB *arg) + struct pmap pmap; + struct pmaplist *pml; + +- if (strcmp(arg->r_netid, udptrans) == 0) { +- /* It is UDP! */ +- pmap.pm_prot = IPPROTO_UDP; +- } else if (strcmp(arg->r_netid, tcptrans) == 0) { +- /* It is TCP */ +- pmap.pm_prot = IPPROTO_TCP; +- } else ++ pmap.pm_prot = pmap_netid2ipprot(arg->r_netid); ++ if (!pmap.pm_prot) + /* Not an IP protocol */ + return (0); + +@@ -1464,15 +1459,10 @@ del_pmaplist(RPCB *arg) + struct pmaplist *prevpml, *fnd; + unsigned long prot; + +- if (strcmp(arg->r_netid, udptrans) == 0) { +- /* It is UDP! */ +- prot = IPPROTO_UDP; +- } else if (strcmp(arg->r_netid, tcptrans) == 0) { +- /* It is TCP */ +- prot = IPPROTO_TCP; +- } else if (arg->r_netid[0] == 0) { ++ if (arg->r_netid[0] == 0) { + prot = 0; /* Remove all occurrences */ +- } else { ++ } else ++ if ((prot = pmap_netid2ipprot(arg->r_netid)) == 0) { + /* Not an IP protocol */ + return (0); + } +diff --git a/src/rpcbind.h b/src/rpcbind.h +index 84deba0..58ab3ef 100644 +--- a/src/rpcbind.h ++++ b/src/rpcbind.h +@@ -78,6 +78,8 @@ extern char *udptrans; /* Name of UDP transport */ + extern char *tcptrans; /* Name of TCP transport */ + extern char *udp_uaddr; /* Universal UDP address */ + extern char *tcp_uaddr; /* Universal TCP address */ ++extern char *pmap_ipprot2netid(unsigned long); ++extern int pmap_netid2ipprot(const char *); + #endif + + int add_bndlist(struct netconfig *, struct netbuf *); diff --git a/rpcbind-0.1.6-pmap-ipv4-only.patch b/rpcbind-0.1.6-pmap-ipv4-only.patch new file mode 100644 index 0000000..23a9ab2 --- /dev/null +++ b/rpcbind-0.1.6-pmap-ipv4-only.patch @@ -0,0 +1,107 @@ +commit 1a94b830a6b5a248faa6fa0e4b7818d9394f6369 +Author: Olaf Kirch +Date: Tue Sep 16 10:15:39 2008 -0400 + + Change how we decide on the netids to use for portmap + + The current code will try to use either udp or udp6, and either tcp or + tcp6 for its portmap emulation code. Enabling eg both tcp6 and tcp in + the netconfig file will cause error messages, and cause rpcbind to not + register itself on the second transport (tcp). + + This is not what we want. + + I believe portmap emulation should only be enabled over IPv4. + There's no point in enabling it over IPv6. + + Signed-off-by: okir@suse.de + Signed-off-by: Steve Dickson + +diff --git a/src/rpcbind.c b/src/rpcbind.c +index 5e7e744..dc6f66b 100644 +--- a/src/rpcbind.c ++++ b/src/rpcbind.c +@@ -167,10 +167,6 @@ main(int argc, char *argv[]) + syslog(LOG_ERR, "could not read /etc/netconfig"); + exit(1); + } +-#ifdef PORTMAP +- udptrans = ""; +- tcptrans = ""; +-#endif + + nconf = getnetconfigent("local"); + if (nconf == NULL) +@@ -190,6 +186,13 @@ main(int argc, char *argv[]) + } + endnetconfig(nc_handle); + ++#ifdef PORTMAP ++ if (!udptrans) ++ udptrans = ""; ++ if (!tcptrans) ++ tcptrans = ""; ++#endif ++ + /* catch the usual termination signals for graceful exit */ + (void) signal(SIGCHLD, reap); + (void) signal(SIGINT, terminate); +@@ -545,15 +548,12 @@ init_transport(struct netconfig *nconf) + + #ifdef PORTMAP + /* +- * Register both the versions for tcp/ip, udp/ip and local. ++ * Register both the versions for tcp/ip, udp/ip. + */ +- if (((strcmp(nconf->nc_protofmly, NC_INET) == 0 || +- strcmp(nconf->nc_protofmly, NC_INET6) == 0) && +- (strcmp(nconf->nc_proto, NC_TCP) == 0 || +- strcmp(nconf->nc_proto, NC_UDP) == 0)) || +- (strcmp(nconf->nc_netid, "unix") == 0) || +- (strcmp(nconf->nc_netid, "local") == 0)) { ++ if (si.si_af == AF_INET && ++ (si.si_proto == IPPROTO_TCP || si.si_proto == IPPROTO_UDP)) { + struct pmaplist *pml; ++ + if (!svc_register(my_xprt, PMAPPROG, PMAPVERS, + pmap_service, 0)) { + syslog(LOG_ERR, "could not register on %s", +@@ -568,30 +568,18 @@ init_transport(struct netconfig *nconf) + pml->pml_map.pm_prog = PMAPPROG; + pml->pml_map.pm_vers = PMAPVERS; + pml->pml_map.pm_port = PMAPPORT; +- if (strcmp(nconf->nc_proto, NC_TCP) == 0) { +- if (tcptrans[0]) { +- syslog(LOG_ERR, +- "cannot have more than one TCP transport"); +- goto error; +- } +- tcptrans = strdup(nconf->nc_netid); +- pml->pml_map.pm_prot = IPPROTO_TCP; ++ pml->pml_map.pm_prot = si.si_proto; + +- /* Let's snarf the universal address */ +- /* "h1.h2.h3.h4.p1.p2" */ ++ /* Stash away the universal address */ ++ switch (si.si_proto) { ++ case IPPROTO_TCP: ++ tcptrans = strdup(nconf->nc_netid); + tcp_uaddr = taddr2uaddr(nconf, &taddr.addr); +- } else if (strcmp(nconf->nc_proto, NC_UDP) == 0) { +- if (udptrans[0]) { +- syslog(LOG_ERR, +- "cannot have more than one UDP transport"); +- goto error; +- } ++ break; ++ case IPPROTO_UDP: + udptrans = strdup(nconf->nc_netid); +- pml->pml_map.pm_prot = IPPROTO_UDP; +- +- /* Let's snarf the universal address */ +- /* "h1.h2.h3.h4.p1.p2" */ + udp_uaddr = taddr2uaddr(nconf, &taddr.addr); ++ break; + } + pml->pml_next = list_pml; + list_pml = pml; diff --git a/rpcbind-0.1.6-pmap-no-uaddrs.patch b/rpcbind-0.1.6-pmap-no-uaddrs.patch new file mode 100644 index 0000000..b8b6fce --- /dev/null +++ b/rpcbind-0.1.6-pmap-no-uaddrs.patch @@ -0,0 +1,113 @@ +commit 566f261ff6bae2842e2e64aaf70d2e31acc1efe7 +Author: Olaf Kirch +Date: Tue Sep 16 10:23:48 2008 -0400 + + Simplify port live check in pmap_svc.c + + There's some hack in pmap_getport that will cause a service + to be unregistered from the portmap list if we find the port + is no longer in use. Apart from being a gross hack, it is + also a rather inefficient hack. Since we now restrict pmap + emulation to IPv4, we know the address is always 0.0.0.0, + so no need to mess with uaddr strings. + + (The bind_check code is a huge messy no-op anyway, since + all ports are added with bind_check = FALSE). + + Signed-off-by: okir@suse.de + Signed-off-by: Steve Dickson + +diff --git a/src/pmap_svc.c b/src/pmap_svc.c +index 02a57d2..7a4f059 100644 +--- a/src/pmap_svc.c ++++ b/src/pmap_svc.c +@@ -293,40 +293,24 @@ pmapproc_getport(struct svc_req *rqstp /*__unused*/, SVCXPRT *xprt) + #endif + fnd = find_service_pmap(reg.pm_prog, reg.pm_vers, reg.pm_prot); + if (fnd) { +- char serveuaddr[32], *ua; +- char *pt1, *pt2; ++ char serveuaddr[32]; + char *netid; + + netid = pmap_ipprot2netid(reg.pm_prot); +- if (netid == NULL) +- goto sendreply; +- if (reg.pm_prot == IPPROTO_UDP) { +- ua = udp_uaddr; +- } else { +- ua = tcp_uaddr; /* To get the len */ +- } +- if (ua == NULL) { +- goto sendreply; +- } +- if ((pt1 = strrchr(ua, '.')) != NULL) { +- *pt1 = 0; +- if ((pt2 = strrchr(ua, '.')) != NULL) { +- *pt2 = 0; +- snprintf(serveuaddr, sizeof serveuaddr, +- "%s.%ld.%ld", ua, +- (fnd->pml_map.pm_port >> 8) & 0xff, +- (fnd->pml_map.pm_port) & 0xff); +- *pt2 = '.'; +- if (is_bound(netid, serveuaddr)) { +- port = fnd->pml_map.pm_port; +- } else { /* this service is dead; delete it */ +- delete_prog(reg.pm_prog); +- } ++ if (netid != NULL) { ++ snprintf(serveuaddr, sizeof serveuaddr, ++ "0.0.0.0.%ld.%ld", ++ (fnd->pml_map.pm_port >> 8) & 0xff, ++ (fnd->pml_map.pm_port) & 0xff); ++ ++ if (is_bound(netid, serveuaddr)) { ++ port = fnd->pml_map.pm_port; ++ } else { /* this service is dead; delete it */ ++ delete_prog(reg.pm_prog); + } +- *pt1 = '.'; + } + } +-sendreply: ++ + lport = port; + if ((!svc_sendreply(xprt, (xdrproc_t) xdr_long, (caddr_t)&lport)) && + debugging) { +diff --git a/src/rpcbind.c b/src/rpcbind.c +index dc6f66b..e0e7ddf 100644 +--- a/src/rpcbind.c ++++ b/src/rpcbind.c +@@ -570,18 +570,15 @@ init_transport(struct netconfig *nconf) + pml->pml_map.pm_port = PMAPPORT; + pml->pml_map.pm_prot = si.si_proto; + +- /* Stash away the universal address */ + switch (si.si_proto) { + case IPPROTO_TCP: + tcptrans = strdup(nconf->nc_netid); +- tcp_uaddr = taddr2uaddr(nconf, &taddr.addr); + break; + case IPPROTO_UDP: + udptrans = strdup(nconf->nc_netid); +- udp_uaddr = taddr2uaddr(nconf, &taddr.addr); + break; + } +- pml->pml_next = list_pml; ++ pml->pml_next = list_pml; + list_pml = pml; + + /* Add version 3 information */ +diff --git a/src/rpcbind.h b/src/rpcbind.h +index 58ab3ef..295711a 100644 +--- a/src/rpcbind.h ++++ b/src/rpcbind.h +@@ -76,8 +76,6 @@ extern rpcblist_ptr list_rbl; /* A list of version 3 & 4 rpcbind services */ + extern struct pmaplist *list_pml; /* A list of version 2 rpcbind services */ + extern char *udptrans; /* Name of UDP transport */ + extern char *tcptrans; /* Name of TCP transport */ +-extern char *udp_uaddr; /* Universal UDP address */ +-extern char *tcp_uaddr; /* Universal TCP address */ + extern char *pmap_ipprot2netid(unsigned long); + extern int pmap_netid2ipprot(const char *); + #endif diff --git a/rpcbind.spec b/rpcbind.spec index 5c818f4..6cfbf4e 100644 --- a/rpcbind.spec +++ b/rpcbind.spec @@ -2,7 +2,7 @@ Name: rpcbind Version: 0.1.6 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Universal Addresses to RPC Program Number Mapper Group: System Environment/Daemons License: GPL @@ -25,6 +25,10 @@ Requires(post): /sbin/chkconfig Provides: portmap = %{version}-%{release} Obsoletes: portmap <= 4.0-65.3 +Patch01: rpcbind-0.1.6-ipprot2netid.patch +Patch02: rpcbind-0.1.6-pmap-ipv4-only.patch +Patch03: rpcbind-0.1.6-pmap-no-uaddrs.patch + %description The rpcbind utility is a server that converts RPC program numbers into universal addresses. It must be running on the host to be able to make @@ -32,6 +36,9 @@ RPC calls on a server on that machine. %prep %setup -q +%patch01 -p1 +%patch02 -p1 +%patch03 -p1 %build %ifarch s390 s390x @@ -111,6 +118,12 @@ fi %dir %attr(700,rpc,rpc) /var/lib/rpcbind %changelog +* Tue Sep 16 2008 Steve Dickson 0.1.6-2 +- Added usptream patches 01 thru 03 that do: + * Introduce helpers for ipprot/netid mapping + * Change how we decide on the netids to use for portmap + * Simplify port live check in pmap_svc.c + * Wed Jul 9 2008 Steve Dickson 0.1.6-1 - Updated to latest upstream release 0.1.6