diff options
author | wpaul <wpaul@FreeBSD.org> | 1996-11-08 01:42:02 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 1996-11-08 01:42:02 +0000 |
commit | 844872c49d9d0345297131bbe6554d7e0d84f90c (patch) | |
tree | ec79011f0f8857467195b8f339bb426a1503b453 /lib/libc/yp/yplib.c | |
parent | 80280d6037c15134f87b4f4d186014dd2c2b06ec (diff) | |
download | FreeBSD-src-844872c49d9d0345297131bbe6554d7e0d84f90c.zip FreeBSD-src-844872c49d9d0345297131bbe6554d7e0d84f90c.tar.gz |
- Avoid possible SEGVs: never call clnt_destroy() without checking
for NULL RPC client handles. This should hopefully fix the problems
Satoshi reported on -current.
- Add socket descriptor sanity checks to _yp_unbind().
- Fix yp_order() so that it handles the RPC_PROCUNAVAIL error gracefully.
NIS+ in YP compat mode doesn't support the YPPROC_ORDER procedure.
This is a 2.2 candidate with bells on.
Diffstat (limited to 'lib/libc/yp/yplib.c')
-rw-r--r-- | lib/libc/yp/yplib.c | 44 |
1 files changed, 36 insertions, 8 deletions
diff --git a/lib/libc/yp/yplib.c b/lib/libc/yp/yplib.c index e83f69a..92f8d8f 100644 --- a/lib/libc/yp/yplib.c +++ b/lib/libc/yp/yplib.c @@ -28,7 +28,7 @@ */ #ifndef LINT -static char *rcsid = "$Id: yplib.c,v 1.22 1996/06/04 17:35:15 jraynard Exp $"; +static char *rcsid = "$Id: yplib.c,v 1.7 1996/11/08 01:10:35 wpaul Exp $"; #endif #include <sys/param.h> @@ -229,7 +229,7 @@ _yp_dobind(dom, ypdb) if( !(pid==-1 || pid==gpid) ) { ysd = _ypbindlist; while(ysd) { - if(ysd->dom_client) + if(ysd->dom_client != NULL) clnt_destroy(ysd->dom_client); ysd2 = ysd->dom_pnext; free(ysd); @@ -266,7 +266,8 @@ _yp_dobind(dom, ypdb) sock = ysd->dom_socket; save = dup(ysd->dom_socket); - clnt_destroy(ysd->dom_client); + if (ysd->dom_client != NULL) + clnt_destroy(ysd->dom_client); ysd->dom_vers = 0; ysd->dom_client = NULL; sock = dup2(save, sock); @@ -287,7 +288,7 @@ again: * We're trying to make a new binding: zorch the * existing handle now (if any). */ - if(ysd->dom_client) { + if(ysd->dom_client != NULL) { clnt_destroy(ysd->dom_client); ysd->dom_client = NULL; ysd->dom_socket = -1; @@ -341,7 +342,7 @@ skipit: * We're trying to make a new binding: zorch the * existing handle now (if any). */ - if(ysd->dom_client) { + if(ysd->dom_client != NULL) { clnt_destroy(ysd->dom_client); ysd->dom_client = NULL; ysd->dom_socket = -1; @@ -375,7 +376,8 @@ skipit: * ypbind with the portmapper and is trying to trick us. */ if (ntohs(clnt_sin.sin_port) >= IPPORT_RESERVED) { - clnt_destroy(client); + if (client != NULL) + clnt_destroy(client); if (new) free(ysd); return(YPERR_YPBIND); @@ -472,8 +474,25 @@ static void _yp_unbind(ypb) struct dom_binding *ypb; { - if (ypb->dom_client) - clnt_destroy(ypb->dom_client); + struct sockaddr_in check; + int checklen = sizeof(struct sockaddr_in); + + if (ypb->dom_client != NULL) { + /* Check the socket -- may have been hosed by the caller. */ + if (getsockname(ypb->dom_socket, (struct sockaddr *)&check, + &checklen) == -1 || check.sin_family != AF_INET || + check.sin_port != ypb->dom_local_port) { + int save, sock; + + sock = ypb->dom_socket; + save = dup(ypb->dom_socket); + clnt_destroy(ypb->dom_client); + sock = dup2(save, sock); + close(save); + } else + clnt_destroy(ypb->dom_client); + } + ypb->dom_client = NULL; ypb->dom_socket = -1; ypb->dom_vers = -1; @@ -805,6 +824,15 @@ again: r = clnt_call(ysd->dom_client, YPPROC_ORDER, xdr_ypreq_nokey, &yprnk, xdr_ypresp_order, &ypro, tv); + + /* + * NIS+ in YP compat mode doesn't support the YPPROC_ORDER + * procedure. + */ + if (r == RPC_PROCUNAVAIL) { + return(YPERR_YPERR); + } + if(r != RPC_SUCCESS) { clnt_perror(ysd->dom_client, "yp_order: clnt_call"); _yp_unbind(ysd); |