about summary refs log tree commit diff
path: root/nis
diff options
context:
space:
mode:
Diffstat (limited to 'nis')
-rw-r--r--nis/ypclnt.c52
1 files changed, 48 insertions, 4 deletions
diff --git a/nis/ypclnt.c b/nis/ypclnt.c
index c661ee3262..a20d4926aa 100644
--- a/nis/ypclnt.c
+++ b/nis/ypclnt.c
@@ -25,8 +25,14 @@
 #include <rpcsvc/yp.h>
 #include <rpcsvc/ypclnt.h>
 #include <rpcsvc/ypupd.h>
+#include <sys/uio.h>
 #include <bits/libc-lock.h>
 
+/* This should only be defined on systems with a BSD compatible ypbind */
+#ifndef BINDINGDIR
+# define BINDINGDIR "/var/yp/binding"
+#endif
+
 struct dom_binding
   {
     struct dom_binding *dom_pnext;
@@ -91,6 +97,44 @@ __yp_bind (const char *domain, dom_binding **ypdb)
           return YPERR_YPBIND;
         }
 
+#if USE_BINDINGDIR
+      if (ysd->dom_vers < 1)
+	{
+	  char path[sizeof (BINDINGDIR) - 1 + strlen (domain) + 10];
+	  struct iovec vec[2];
+	  u_short port;
+	  int fd;
+
+	  sprintf (path, "%s/%s.%ld", BINDINGDIR, domain, YPBINDVERS);
+	  fd = open (path, O_RDONLY);
+	  if (fd >= 0)
+	    {
+	      /* We have a binding file and could save a RPC call */
+	      vec[0].iov_base = &port;
+	      vec[0].iov_len = sizeof (port);
+	      vec[1].iov_base = &ypbr;
+	      vec[1].iov_len = sizeof (ypbr);
+
+	      if (readv (fd, vec, 2) == vec[0].iov_len + vec[1].iov_len)
+		{
+		  memset (&ysd->dom_server_addr, '\0',
+			  sizeof ysd->dom_server_addr);
+		  ysd->dom_server_addr.sin_family = AF_INET;
+		  memcpy (&ysd->dom_server_addr.sin_port,
+			  ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port,
+			  sizeof (ysd->dom_server_addr.sin_port));
+		  memcpy (&ysd->dom_server_addr.sin_addr.s_addr,
+			  ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr,
+			  sizeof (ysd->dom_server_addr.sin_addr.s_addr));
+		  ysd->dom_vers = YPVERS;
+		  strncpy (ysd->dom_domain, domain, YPMAXDOMAIN);
+		  ysd->dom_domain[YPMAXDOMAIN] = '\0';
+		}
+	      close (fd);
+	    }
+	}
+#endif /* USE_BINDINGDIR */
+
       if (ysd->dom_vers == -1)
         {
           if(ysd->dom_client)
@@ -116,12 +160,12 @@ __yp_bind (const char *domain, dom_binding **ypdb)
           ** If not, it's possible someone has registered a bogus
           ** ypbind with the portmapper and is trying to trick us.
           */
-          if (ntohs(clnt_saddr.sin_port) >= IPPORT_RESERVED)
+          if (ntohs (clnt_saddr.sin_port) >= IPPORT_RESERVED)
             {
-              clnt_destroy(client);
+              clnt_destroy (client);
               if (is_new)
-                free(ysd);
-              return(YPERR_YPBIND);
+                free (ysd);
+              return YPERR_YPBIND;
             }
 
           if (clnt_call (client, YPBINDPROC_DOMAIN,