diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2022-07-15 16:59:50 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2022-07-15 16:59:50 +0000 |
commit | 9774a250fc60ea2f9375fb0c5d43cfe9378cbf63 (patch) | |
tree | 838cc5a1b146ad462b71877d1542b6a43b27ea45 /usr.sbin/ypbind/ypbind.c | |
parent | e168bc1eb42a4cea906b6cac43e520ac641c1836 (diff) |
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
Diffstat (limited to 'usr.sbin/ypbind/ypbind.c')
-rw-r--r-- | usr.sbin/ypbind/ypbind.c | 24 |
1 files 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 <deraadt@openbsd.org> @@ -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); |