From f1eb3c946baa233d3e41e591472f14ff6bfd5928 Mon Sep 17 00:00:00 2001 From: deraadt Date: Fri, 15 Jul 2022 16:59:49 +0000 Subject: [PATCH] Once a ypserv is discovered we know the remote UDP port number, but not the TCP port number. Immediately reach out (syncronously via pmap_getport, to ask the portmap on the ypserv machine) to learn the TCP port number. Append this as 2 bytes (network byte order) to the binding file, because an upcoming change will require this information also. with jmatthew, also ok claudio miod --- usr.sbin/ypbind/ypbind.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/usr.sbin/ypbind/ypbind.c b/usr.sbin/ypbind/ypbind.c index 0f1e77126f6..fae94ff9570 100644 --- a/usr.sbin/ypbind/ypbind.c +++ b/usr.sbin/ypbind/ypbind.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ypbind.c,v 1.74 2020/12/29 19:48:49 benno Exp $ */ +/* $OpenBSD: ypbind.c,v 1.75 2022/07/15 16:59:49 deraadt Exp $ */ /* * Copyright (c) 1992, 1993, 1996, 1997, 1998 Theo de Raadt @@ -955,9 +955,10 @@ void rpc_received(char *dom, struct sockaddr_in *raddrp, int force) { struct _dom_binding *ypdb; - struct iovec iov[2]; + struct iovec iov[3]; struct ypbind_resp ybr; char path[PATH_MAX]; + u_short ypserv_tcp, ypserv_udp; int fd; if (strchr(dom, '/')) @@ -1012,6 +1013,18 @@ rpc_received(char *dom, struct sockaddr_in *raddrp, int force) return; } + /* syncronously ask for the matching ypserv TCP port number */ + ypserv_udp = raddrp->sin_port; + ypserv_tcp = pmap_getport(raddrp, YPPROG, + YPVERS, IPPROTO_TCP); + if (ypserv_tcp == 0) { + clnt_pcreateerror("pmap_getport"); + return; + } + if (ypserv_tcp >= IPPORT_RESERVED || ypserv_tcp == 20) + return; + ypserv_tcp = htons(ypserv_tcp); + memcpy(&ypdb->dom_server_addr, raddrp, sizeof ypdb->dom_server_addr); /* recheck binding in 60 seconds */ ypdb->dom_check_t = time(NULL) + 60; @@ -1052,6 +1065,8 @@ rpc_received(char *dom, struct sockaddr_in *raddrp, int force) iov[0].iov_len = sizeof udptransp->xp_port; iov[1].iov_base = (caddr_t)&ybr; iov[1].iov_len = sizeof ybr; + iov[2].iov_base = (caddr_t)&ypserv_tcp; + iov[2].iov_len = sizeof ypserv_tcp; memset(&ybr, 0, sizeof ybr); ybr.ypbind_status = YPBIND_SUCC_VAL; @@ -1059,10 +1074,11 @@ rpc_received(char *dom, struct sockaddr_in *raddrp, int force) &raddrp->sin_addr, sizeof(ybr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr)); memmove(&ybr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port, - &raddrp->sin_port, + &ypserv_udp, sizeof(ybr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port)); - if (writev(ypdb->dom_lockfd, iov, 2) != iov[0].iov_len + iov[1].iov_len) { + if (writev(ypdb->dom_lockfd, iov, sizeof(iov)/sizeof(iov[0])) != + iov[0].iov_len + iov[1].iov_len + iov[2].iov_len) { perror("write"); close(ypdb->dom_lockfd); unlink(path); -- 2.20.1