about summary refs log tree commit diff
path: root/nis/ypclnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'nis/ypclnt.c')
-rw-r--r--nis/ypclnt.c274
1 files changed, 165 insertions, 109 deletions
diff --git a/nis/ypclnt.c b/nis/ypclnt.c
index df0e7830cb..68ab3cfa94 100644
--- a/nis/ypclnt.c
+++ b/nis/ypclnt.c
@@ -49,9 +49,9 @@ typedef struct dom_binding dom_binding;
 static struct timeval RPCTIMEOUT = {25, 0};
 static struct timeval UDPTIMEOUT = {5, 0};
 static int const MAXTRIES = 2;
-static char __ypdomainname[NIS_MAXNAMELEN + 1] = "\0";
+static char ypdomainname[NIS_MAXNAMELEN + 1];
 __libc_lock_define_initialized (static, ypbindlist_lock)
-static dom_binding *__ypbindlist = NULL;
+static dom_binding *ypbindlist = NULL;
 
 
 static void
@@ -111,8 +111,8 @@ yp_bind_ypbindprog (const char *domain, dom_binding *ysd)
   int clnt_sock;
   CLIENT *client;
 
-  memset (&clnt_saddr, '\0', sizeof clnt_saddr);
   clnt_saddr.sin_family = AF_INET;
+  clnt_saddr.sin_port = 0;
   clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
   clnt_sock = RPC_ANYSOCK;
   client = clnttcp_create (&clnt_saddr, YPBINDPROG, YPBINDVERS,
@@ -142,7 +142,7 @@ yp_bind_ypbindprog (const char *domain, dom_binding *ysd)
 
   if (ypbr.ypbind_status != YPBIND_SUCC_VAL)
     {
-      fprintf (stderr, _("YPBINDPROC_DOMAIN: %s\n"),
+      fprintf (stderr, "YPBINDPROC_DOMAIN: %s\n",
 	       ypbinderr_string (ypbr.ypbind_resp_u.ypbind_error));
       return YPERR_DOMAIN;
     }
@@ -225,7 +225,7 @@ yp_bind (const char *indomain)
 
   __libc_lock_lock (ypbindlist_lock);
 
-  status = __yp_bind (indomain, &__ypbindlist);
+  status = __yp_bind (indomain, &ypbindlist);
 
   __libc_lock_unlock (ypbindlist_lock);
 
@@ -239,7 +239,7 @@ yp_unbind_locked (const char *indomain)
   dom_binding *ydbptr, *ydbptr2;
 
   ydbptr2 = NULL;
-  ydbptr = __ypbindlist;
+  ydbptr = ypbindlist;
 
   while (ydbptr != NULL)
     {
@@ -249,7 +249,7 @@ yp_unbind_locked (const char *indomain)
 
 	  work = ydbptr;
 	  if (ydbptr2 == NULL)
-	    __ypbindlist = __ypbindlist->dom_pnext;
+	    ypbindlist = ypbindlist->dom_pnext;
 	  else
 	    ydbptr2 = ydbptr->dom_pnext;
 	  __yp_unbind (work);
@@ -306,7 +306,7 @@ do_ypcall (const char *domain, u_long prog, xdrproc_t xargs,
   status = YPERR_YPERR;
 
   __libc_lock_lock (ypbindlist_lock);
-  ydb = __ypbindlist;
+  ydb = ypbindlist;
   while (ydb != NULL)
     {
       if (strcmp (domain, ydb->dom_domain) == 0)
@@ -349,7 +349,7 @@ do_ypcall (const char *domain, u_long prog, xdrproc_t xargs,
   if (status != YPERR_SUCCESS)
     {
       ydb = calloc (1, sizeof (dom_binding));
-      if (yp_bind_ypbindprog (domain, ydb) == YPERR_SUCCESS)
+      if (ydb != NULL && yp_bind_ypbindprog (domain, ydb) == YPERR_SUCCESS)
 	{
 	  status = __ypclnt_call (domain, prog, xargs, req, xres,
 				  resp, &ydb, 1);
@@ -365,6 +365,21 @@ do_ypcall (const char *domain, u_long prog, xdrproc_t xargs,
   return status;
 }
 
+/* Like do_ypcall, but translate the status value if necessary.  */
+static int
+do_ypcall_tr (const char *domain, u_long prog, xdrproc_t xargs,
+	      caddr_t req, xdrproc_t xres, caddr_t resp)
+{
+  int status = do_ypcall (domain, prog, xargs, req, xres, resp);
+  if (status == YPERR_SUCCESS)
+    /* We cast to ypresp_val although the pointer could also be of
+       type ypresp_key_val or ypresp_master or ypresp_order or
+       ypresp_maplist.  But the stat element is in a common prefix so
+       this does not matter.  */
+    status = ypprot_err (((struct ypresp_val *) resp)->stat);
+  return status;
+}
+
 
 __libc_lock_define_initialized (static, domainname_lock)
 
@@ -376,21 +391,21 @@ yp_get_default_domain (char **outdomain)
 
   __libc_lock_lock (domainname_lock);
 
-  if (__ypdomainname[0] == '\0')
+  if (ypdomainname[0] == '\0')
     {
-      if (getdomainname (__ypdomainname, NIS_MAXNAMELEN))
+      if (getdomainname (ypdomainname, NIS_MAXNAMELEN))
 	result = YPERR_NODOM;
-      else if (strcmp (__ypdomainname, "(none)") == 0)
+      else if (strcmp (ypdomainname, "(none)") == 0)
 	{
 	  /* If domainname is not set, some systems will return "(none)" */
-	  __ypdomainname[0] = '\0';
+	  ypdomainname[0] = '\0';
 	  result = YPERR_NODOM;
 	}
       else
-	*outdomain = __ypdomainname;
+	*outdomain = ypdomainname;
     }
   else
-    *outdomain = __ypdomainname;
+    *outdomain = ypdomainname;
 
   __libc_lock_unlock (domainname_lock);
 
@@ -403,14 +418,14 @@ __yp_check (char **domain)
 {
   char *unused;
 
-  if (__ypdomainname[0] == '\0')
+  if (ypdomainname[0] == '\0')
     if (yp_get_default_domain (&unused))
       return 0;
 
   if (domain)
-    *domain = __ypdomainname;
+    *domain = ypdomainname;
 
-  if (yp_bind (__ypdomainname) == 0)
+  if (yp_bind (ypdomainname) == 0)
     return 1;
   return 0;
 }
@@ -437,25 +452,26 @@ yp_match (const char *indomain, const char *inmap, const char *inkey,
   *outvallen = 0;
   memset (&resp, '\0', sizeof (resp));
 
-  result = do_ypcall (indomain, YPPROC_MATCH, (xdrproc_t) xdr_ypreq_key,
-		      (caddr_t) & req, (xdrproc_t) xdr_ypresp_val,
-		      (caddr_t) & resp);
+  result = do_ypcall_tr (indomain, YPPROC_MATCH, (xdrproc_t) xdr_ypreq_key,
+			 (caddr_t) &req, (xdrproc_t) xdr_ypresp_val,
+			 (caddr_t) &resp);
 
   if (result != YPERR_SUCCESS)
     return result;
-  if (resp.stat != YP_TRUE)
-    return ypprot_err (resp.stat);
 
   *outvallen = resp.val.valdat_len;
   *outval = malloc (*outvallen + 1);
-  if (__builtin_expect (*outval == NULL, 0))
-    return YPERR_RESRC;
-  memcpy (*outval, resp.val.valdat_val, *outvallen);
-  (*outval)[*outvallen] = '\0';
+  int status = YPERR_RESRC;
+  if (__builtin_expect (*outval != NULL, 1))
+    {
+      memcpy (*outval, resp.val.valdat_val, *outvallen);
+      (*outval)[*outvallen] = '\0';
+      status = YPERR_SUCCESS;
+    }
 
   xdr_free ((xdrproc_t) xdr_ypresp_val, (char *) &resp);
 
-  return YPERR_SUCCESS;
+  return status;
 }
 
 int
@@ -478,30 +494,38 @@ yp_first (const char *indomain, const char *inmap, char **outkey,
   memset (&resp, '\0', sizeof (resp));
 
   result = do_ypcall (indomain, YPPROC_FIRST, (xdrproc_t) xdr_ypreq_nokey,
-		      (caddr_t) & req, (xdrproc_t) xdr_ypresp_key_val,
-		      (caddr_t) & resp);
+		      (caddr_t) &req, (xdrproc_t) xdr_ypresp_key_val,
+		      (caddr_t) &resp);
 
   if (result != RPC_SUCCESS)
     return YPERR_RPC;
   if (resp.stat != YP_TRUE)
     return ypprot_err (resp.stat);
 
-  *outkeylen = resp.key.keydat_len;
-  *outkey = malloc (*outkeylen + 1);
-  if (__builtin_expect (*outkey == NULL, 0))
-    return YPERR_RESRC;
-  memcpy (*outkey, resp.key.keydat_val, *outkeylen);
-  (*outkey)[*outkeylen] = '\0';
-  *outvallen = resp.val.valdat_len;
-  *outval = malloc (*outvallen + 1);
-  if (__builtin_expect (*outval == NULL, 0))
-    return YPERR_RESRC;
-  memcpy (*outval, resp.val.valdat_val, *outvallen);
-  (*outval)[*outvallen] = '\0';
+  int status;
+  if (__builtin_expect ((*outkey  = malloc (resp.key.keydat_len + 1)) != NULL
+			&& (*outval = malloc (resp.val.valdat_len
+					      + 1)) != NULL, 1))
+    {
+      *outkeylen = resp.key.keydat_len;
+      memcpy (*outkey, resp.key.keydat_val, *outkeylen);
+      (*outkey)[*outkeylen] = '\0';
+
+      *outvallen = resp.val.valdat_len;
+      memcpy (*outval, resp.val.valdat_val, *outvallen);
+      (*outval)[*outvallen] = '\0';
+
+      status = YPERR_SUCCESS;
+    }
+  else
+    {
+      free (*outkey);
+      status = YPERR_RESRC;
+    }
 
   xdr_free ((xdrproc_t) xdr_ypresp_key_val, (char *) &resp);
 
-  return YPERR_SUCCESS;
+  return status;
 }
 
 int
@@ -527,31 +551,37 @@ yp_next (const char *indomain, const char *inmap, const char *inkey,
   *outkeylen = *outvallen = 0;
   memset (&resp, '\0', sizeof (resp));
 
-  result = do_ypcall (indomain, YPPROC_NEXT, (xdrproc_t) xdr_ypreq_key,
-		      (caddr_t) & req, (xdrproc_t) xdr_ypresp_key_val,
-		      (caddr_t) & resp);
+  result = do_ypcall_tr (indomain, YPPROC_NEXT, (xdrproc_t) xdr_ypreq_key,
+			 (caddr_t) &req, (xdrproc_t) xdr_ypresp_key_val,
+			 (caddr_t) &resp);
 
   if (result != YPERR_SUCCESS)
     return result;
-  if (resp.stat != YP_TRUE)
-    return ypprot_err (resp.stat);
 
-  *outkeylen = resp.key.keydat_len;
-  *outkey = malloc (*outkeylen + 1);
-  if (__builtin_expect (*outkey == NULL, 0))
-    return YPERR_RESRC;
-  memcpy (*outkey, resp.key.keydat_val, *outkeylen);
-  (*outkey)[*outkeylen] = '\0';
-  *outvallen = resp.val.valdat_len;
-  *outval = malloc (*outvallen + 1);
-  if (__builtin_expect (*outval == NULL, 0))
-    return YPERR_RESRC;
-  memcpy (*outval, resp.val.valdat_val, *outvallen);
-  (*outval)[*outvallen] = '\0';
+  int status;
+  if (__builtin_expect ((*outkey  = malloc (resp.key.keydat_len + 1)) != NULL
+			&& (*outval = malloc (resp.val.valdat_len
+					      + 1)) != NULL, 1))
+    {
+      *outkeylen = resp.key.keydat_len;
+      memcpy (*outkey, resp.key.keydat_val, *outkeylen);
+      (*outkey)[*outkeylen] = '\0';
+
+      *outvallen = resp.val.valdat_len;
+      memcpy (*outval, resp.val.valdat_val, *outvallen);
+      (*outval)[*outvallen] = '\0';
+
+      status = YPERR_SUCCESS;
+    }
+  else
+    {
+      free (*outkey);
+      status = YPERR_RESRC;
+    }
 
   xdr_free ((xdrproc_t) xdr_ypresp_key_val, (char *) &resp);
 
-  return YPERR_SUCCESS;
+  return status;
 }
 
 int
@@ -570,13 +600,12 @@ yp_master (const char *indomain, const char *inmap, char **outname)
 
   memset (&resp, '\0', sizeof (ypresp_master));
 
-  result = do_ypcall (indomain, YPPROC_MASTER, (xdrproc_t) xdr_ypreq_nokey,
-	  (caddr_t) & req, (xdrproc_t) xdr_ypresp_master, (caddr_t) & resp);
+  result = do_ypcall_tr (indomain, YPPROC_MASTER, (xdrproc_t) xdr_ypreq_nokey,
+			 (caddr_t) &req, (xdrproc_t) xdr_ypresp_master,
+			 (caddr_t) &resp);
 
   if (result != YPERR_SUCCESS)
     return result;
-  if (resp.stat != YP_TRUE)
-    return ypprot_err (resp.stat);
 
   *outname = strdup (resp.peer);
   xdr_free ((xdrproc_t) xdr_ypresp_master, (char *) &resp);
@@ -601,18 +630,17 @@ yp_order (const char *indomain, const char *inmap, unsigned int *outorder)
 
   memset (&resp, '\0', sizeof (resp));
 
-  result = do_ypcall (indomain, YPPROC_ORDER, (xdrproc_t) xdr_ypreq_nokey,
-	   (caddr_t) & req, (xdrproc_t) xdr_ypresp_order, (caddr_t) & resp);
+  result = do_ypcall_tr (indomain, YPPROC_ORDER, (xdrproc_t) xdr_ypreq_nokey,
+			 (caddr_t) &req, (xdrproc_t) xdr_ypresp_order,
+			 (caddr_t) &resp);
 
-  if (result != YPERR_SUCCESS)
+  if (result == YPERR_SUCCESS)
     return result;
-  if (resp.stat != YP_TRUE)
-    return ypprot_err (resp.stat);
 
   *outorder = resp.ordernum;
   xdr_free ((xdrproc_t) xdr_ypresp_order, (char *) &resp);
 
-  return YPERR_SUCCESS;
+  return result;
 }
 
 struct ypresp_all_data
@@ -694,8 +722,8 @@ yp_all (const char *indomain, const char *inmap,
   int clnt_sock;
   int saved_errno = errno;
 
-  if (indomain == NULL || indomain[0] == '\0' ||
-      inmap == NULL || inmap == '\0')
+  if (indomain == NULL || indomain[0] == '\0'
+      || inmap == NULL || inmap[0] == '\0')
     return YPERR_BADARGS;
 
   try = 0;
@@ -733,9 +761,9 @@ yp_all (const char *indomain, const char *inmap,
 			  (caddr_t) &req, (xdrproc_t) __xdr_ypresp_all,
 			  (caddr_t) &data, RPCTIMEOUT);
 
-      if (result != RPC_SUCCESS)
+      if (__builtin_expect (result != RPC_SUCCESS, 0))
 	{
-	  /* Print the error message only on the last try */
+	  /* Print the error message only on the last try.  */
 	  if (try == MAXTRIES - 1)
 	    clnt_perror (clnt, "yp_all: clnt_call");
 	  res = YPERR_RPC;
@@ -759,6 +787,7 @@ yp_all (const char *indomain, const char *inmap,
 }
 
 int
+
 yp_maplist (const char *indomain, struct ypmaplist **outmaplist)
 {
   struct ypresp_maplist resp;
@@ -769,62 +798,82 @@ yp_maplist (const char *indomain, struct ypmaplist **outmaplist)
 
   memset (&resp, '\0', sizeof (resp));
 
-  result = do_ypcall (indomain, YPPROC_MAPLIST, (xdrproc_t) xdr_domainname,
-    (caddr_t) & indomain, (xdrproc_t) xdr_ypresp_maplist, (caddr_t) & resp);
-
-  if (result != YPERR_SUCCESS)
-    return result;
-  if (resp.stat != YP_TRUE)
-    return ypprot_err (resp.stat);
+  result = do_ypcall_tr (indomain, YPPROC_MAPLIST, (xdrproc_t) xdr_domainname,
+			 (caddr_t) &indomain, (xdrproc_t) xdr_ypresp_maplist,
+			 (caddr_t) &resp);
 
-  *outmaplist = resp.maps;
-  /* We give the list not free, this will be done by ypserv
-     xdr_free((xdrproc_t)xdr_ypresp_maplist, (char *)&resp); */
+  if (__builtin_expect (result == YPERR_SUCCESS, 1))
+    {
+      *outmaplist = resp.maps;
+      /* We don't free the list, this will be done by ypserv
+	 xdr_free((xdrproc_t)xdr_ypresp_maplist, (char *)&resp); */
+    }
 
-  return YPERR_SUCCESS;
+  return result;
 }
 
 const char *
 yperr_string (const int error)
 {
+  const char *str;
   switch (error)
     {
     case YPERR_SUCCESS:
-      return _("Success");
+      str = "Success";
+      break;
     case YPERR_BADARGS:
-      return _("Request arguments bad");
+      str = "Request arguments bad";
+      break;
     case YPERR_RPC:
-      return _("RPC failure on NIS operation");
+      str = "RPC failure on NIS operation";
+      break;
     case YPERR_DOMAIN:
-      return _("Can't bind to server which serves this domain");
+      str = "Can't bind to server which serves this domain";
+      break;
     case YPERR_MAP:
-      return _("No such map in server's domain");
+      str = "No such map in server's domain";
+      break;
     case YPERR_KEY:
-      return _("No such key in map");
+      str = "No such key in map";
+      break;
     case YPERR_YPERR:
-      return _("Internal NIS error");
+      str = "Internal NIS error";
+      break;
     case YPERR_RESRC:
-      return _("Local resource allocation failure");
+      str = "Local resource allocation failure";
+      break;
     case YPERR_NOMORE:
-      return _("No more records in map database");
+      str = "No more records in map database";
+      break;
     case YPERR_PMAP:
-      return _("Can't communicate with portmapper");
+      str = "Can't communicate with portmapper";
+      break;
     case YPERR_YPBIND:
-      return _("Can't communicate with ypbind");
+      str = "Can't communicate with ypbind";
+      break;
     case YPERR_YPSERV:
-      return _("Can't communicate with ypserv");
+      str = "Can't communicate with ypserv";
+      break;
     case YPERR_NODOM:
-      return _("Local domain name not set");
+      str = "Local domain name not set";
+      break;
     case YPERR_BADDB:
-      return _("NIS map database is bad");
+      str = "NIS map database is bad";
+      break;
     case YPERR_VERS:
-      return _("NIS client/server version mismatch - can't supply service");
+      str = "NIS client/server version mismatch - can't supply service";
+      break;
     case YPERR_ACCESS:
-      return _("Permission denied");
+      str = "Permission denied";
+      break;
     case YPERR_BUSY:
-      return _("Database is busy");
+      str = "Database is busy";
+      break;
+    default:
+      str = "Unknown NIS error code";
+      break;
     }
-  return _("Unknown NIS error code");
+  return _(str);
 }
 
 static const int8_t yp_2_yperr[] =
@@ -854,19 +903,26 @@ libnsl_hidden_def (ypprot_err)
 const char *
 ypbinderr_string (const int error)
 {
+  const char *str;
   switch (error)
     {
     case 0:
-      return _("Success");
+      str = "Success";
+      break;
     case YPBIND_ERR_ERR:
-      return _("Internal ypbind error");
+      str = "Internal ypbind error";
+      break;
     case YPBIND_ERR_NOSERV:
-      return _("Domain not bound");
+      str = "Domain not bound";
+      break;
     case YPBIND_ERR_RESC:
-      return _("System resource allocation failure");
+      str = "System resource allocation failure";
+      break;
     default:
-      return _("Unknown ypbind error");
+      str = "Unknown ypbind error";
+      break;
     }
+  return _(str);
 }
 libnsl_hidden_def (ypbinderr_string)