Blame nis/ypclnt.c

Packit Service 82fcde
/* Copyright (C) 1996-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
   Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#include <errno.h>
Packit Service 82fcde
#include <fcntl.h>
Packit Service 82fcde
#include <string.h>
Packit Service 82fcde
#include <unistd.h>
Packit Service 82fcde
#include <libintl.h>
Packit Service 82fcde
#include <rpc/rpc.h>
Packit Service 82fcde
#include <rpcsvc/nis.h>
Packit Service 82fcde
#include <rpcsvc/yp.h>
Packit Service 82fcde
#include <rpcsvc/ypclnt.h>
Packit Service 82fcde
#include <rpcsvc/ypupd.h>
Packit Service 82fcde
#include <sys/socket.h>
Packit Service 82fcde
#include <sys/uio.h>
Packit Service 82fcde
#include <libc-lock.h>
Packit Service 82fcde
#include <shlib-compat.h>
Packit Service 82fcde
Packit Service 82fcde
/* This should only be defined on systems with a BSD compatible ypbind */
Packit Service 82fcde
#ifndef BINDINGDIR
Packit Service 82fcde
# define BINDINGDIR "/var/yp/binding"
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
struct dom_binding
Packit Service 82fcde
  {
Packit Service 82fcde
    struct dom_binding *dom_pnext;
Packit Service 82fcde
    char dom_domain[YPMAXDOMAIN + 1];
Packit Service 82fcde
    struct sockaddr_in dom_server_addr;
Packit Service 82fcde
    int dom_socket;
Packit Service 82fcde
    CLIENT *dom_client;
Packit Service 82fcde
  };
Packit Service 82fcde
typedef struct dom_binding dom_binding;
Packit Service 82fcde
Packit Service 82fcde
static const struct timeval RPCTIMEOUT = {25, 0};
Packit Service 82fcde
static const struct timeval UDPTIMEOUT = {5, 0};
Packit Service 82fcde
static int const MAXTRIES = 2;
Packit Service 82fcde
static char ypdomainname[NIS_MAXNAMELEN + 1];
Packit Service 82fcde
__libc_lock_define_initialized (static, ypbindlist_lock)
Packit Service 82fcde
static dom_binding *ypbindlist = NULL;
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
yp_bind_client_create (const char *domain, dom_binding *ysd,
Packit Service 82fcde
		       struct ypbind_resp *ypbr)
Packit Service 82fcde
{
Packit Service 82fcde
  ysd->dom_server_addr.sin_family = AF_INET;
Packit Service 82fcde
  memcpy (&ysd->dom_server_addr.sin_port,
Packit Service 82fcde
	  ypbr->ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port,
Packit Service 82fcde
	  sizeof (ysd->dom_server_addr.sin_port));
Packit Service 82fcde
  memcpy (&ysd->dom_server_addr.sin_addr.s_addr,
Packit Service 82fcde
	  ypbr->ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr,
Packit Service 82fcde
	  sizeof (ysd->dom_server_addr.sin_addr.s_addr));
Packit Service 82fcde
  strncpy (ysd->dom_domain, domain, YPMAXDOMAIN);
Packit Service 82fcde
  ysd->dom_domain[YPMAXDOMAIN] = '\0';
Packit Service 82fcde
Packit Service 82fcde
  ysd->dom_socket = RPC_ANYSOCK;
Packit Service 82fcde
  ysd->dom_client = __libc_clntudp_bufcreate (&ysd->dom_server_addr, YPPROG,
Packit Service 82fcde
					      YPVERS, UDPTIMEOUT,
Packit Service 82fcde
					      &ysd->dom_socket,
Packit Service 82fcde
					      UDPMSGSIZE, UDPMSGSIZE,
Packit Service 82fcde
					      SOCK_CLOEXEC);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#if USE_BINDINGDIR
Packit Service 82fcde
static void
Packit Service 82fcde
yp_bind_file (const char *domain, dom_binding *ysd)
Packit Service 82fcde
{
Packit Service 82fcde
  char path[sizeof (BINDINGDIR) + strlen (domain) + 3 * sizeof (unsigned) + 3];
Packit Service 82fcde
Packit Service 82fcde
  snprintf (path, sizeof (path), "%s/%s.%u", BINDINGDIR, domain, YPBINDVERS);
Packit Service 82fcde
  int fd = open (path, O_RDONLY);
Packit Service 82fcde
  if (fd >= 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      /* We have a binding file and could save a RPC call.  The file
Packit Service 82fcde
	 contains a port number and the YPBIND_RESP record.  The port
Packit Service 82fcde
	 number (16 bits) can be ignored.  */
Packit Service 82fcde
      struct ypbind_resp ypbr;
Packit Service 82fcde
Packit Service 82fcde
      if (pread (fd, &ypbr, sizeof (ypbr), 2) == sizeof (ypbr))
Packit Service 82fcde
	yp_bind_client_create (domain, ysd, &ypbr);
Packit Service 82fcde
Packit Service 82fcde
      close (fd);
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
yp_bind_ypbindprog (const char *domain, dom_binding *ysd)
Packit Service 82fcde
{
Packit Service 82fcde
  struct sockaddr_in clnt_saddr;
Packit Service 82fcde
  struct ypbind_resp ypbr;
Packit Service 82fcde
  int clnt_sock;
Packit Service 82fcde
  CLIENT *client;
Packit Service 82fcde
Packit Service 82fcde
  clnt_saddr.sin_family = AF_INET;
Packit Service 82fcde
  clnt_saddr.sin_port = 0;
Packit Service 82fcde
  clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
Packit Service 82fcde
  clnt_sock = RPC_ANYSOCK;
Packit Service 82fcde
  client = clnttcp_create (&clnt_saddr, YPBINDPROG, YPBINDVERS,
Packit Service 82fcde
			   &clnt_sock, 0, 0);
Packit Service 82fcde
  if (client == NULL)
Packit Service 82fcde
    return YPERR_YPBIND;
Packit Service 82fcde
Packit Service 82fcde
  /* Check the port number -- should be < IPPORT_RESERVED.
Packit Service 82fcde
     If not, it's possible someone has registered a bogus
Packit Service 82fcde
     ypbind with the portmapper and is trying to trick us. */
Packit Service 82fcde
  if (ntohs (clnt_saddr.sin_port) >= IPPORT_RESERVED)
Packit Service 82fcde
    {
Packit Service 82fcde
      clnt_destroy (client);
Packit Service 82fcde
      return YPERR_YPBIND;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (clnt_call (client, YPBINDPROC_DOMAIN,
Packit Service 82fcde
		 (xdrproc_t) xdr_domainname, (caddr_t) &domain,
Packit Service 82fcde
		 (xdrproc_t) xdr_ypbind_resp,
Packit Service 82fcde
		 (caddr_t) &ypbr, RPCTIMEOUT) != RPC_SUCCESS)
Packit Service 82fcde
    {
Packit Service 82fcde
      clnt_destroy (client);
Packit Service 82fcde
      return YPERR_YPBIND;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  clnt_destroy (client);
Packit Service 82fcde
Packit Service 82fcde
  if (ypbr.ypbind_status != YPBIND_SUCC_VAL)
Packit Service 82fcde
    {
Packit Service 82fcde
      fprintf (stderr, "YPBINDPROC_DOMAIN: %s\n",
Packit Service 82fcde
	       ypbinderr_string (ypbr.ypbind_resp_u.ypbind_error));
Packit Service 82fcde
      return YPERR_DOMAIN;
Packit Service 82fcde
    }
Packit Service 82fcde
  memset (&ysd->dom_server_addr, '\0', sizeof ysd->dom_server_addr);
Packit Service 82fcde
Packit Service 82fcde
  yp_bind_client_create (domain, ysd, &ypbr);
Packit Service 82fcde
Packit Service 82fcde
  return YPERR_SUCCESS;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
__yp_bind (const char *domain, dom_binding **ypdb)
Packit Service 82fcde
{
Packit Service 82fcde
  dom_binding *ysd = NULL;
Packit Service 82fcde
  int is_new = 0;
Packit Service 82fcde
Packit Service 82fcde
  if (domain == NULL || domain[0] == '\0')
Packit Service 82fcde
    return YPERR_BADARGS;
Packit Service 82fcde
Packit Service 82fcde
  ysd = *ypdb;
Packit Service 82fcde
  while (ysd != NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (strcmp (domain, ysd->dom_domain) == 0)
Packit Service 82fcde
	break;
Packit Service 82fcde
      ysd = ysd->dom_pnext;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (ysd == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      is_new = 1;
Packit Service 82fcde
      ysd = (dom_binding *) calloc (1, sizeof *ysd);
Packit Service 82fcde
      if (__glibc_unlikely (ysd == NULL))
Packit Service 82fcde
	return YPERR_RESRC;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
#if USE_BINDINGDIR
Packit Service 82fcde
  /* Try binding dir at first if we have no binding */
Packit Service 82fcde
  if (ysd->dom_client == NULL)
Packit Service 82fcde
    yp_bind_file (domain, ysd);
Packit Service 82fcde
#endif /* USE_BINDINGDIR */
Packit Service 82fcde
Packit Service 82fcde
  if (ysd->dom_client == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      int retval = yp_bind_ypbindprog (domain, ysd);
Packit Service 82fcde
      if (retval != YPERR_SUCCESS)
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (is_new)
Packit Service 82fcde
	    free (ysd);
Packit Service 82fcde
	  return retval;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (ysd->dom_client == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (is_new)
Packit Service 82fcde
	free (ysd);
Packit Service 82fcde
      return YPERR_YPSERV;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (is_new)
Packit Service 82fcde
    {
Packit Service 82fcde
      ysd->dom_pnext = *ypdb;
Packit Service 82fcde
      *ypdb = ysd;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return YPERR_SUCCESS;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
__yp_unbind (dom_binding *ydb)
Packit Service 82fcde
{
Packit Service 82fcde
  clnt_destroy (ydb->dom_client);
Packit Service 82fcde
  free (ydb);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
yp_bind (const char *indomain)
Packit Service 82fcde
{
Packit Service 82fcde
  int status;
Packit Service 82fcde
Packit Service 82fcde
  __libc_lock_lock (ypbindlist_lock);
Packit Service 82fcde
Packit Service 82fcde
  status = __yp_bind (indomain, &ypbindlist);
Packit Service 82fcde
Packit Service 82fcde
  __libc_lock_unlock (ypbindlist_lock);
Packit Service 82fcde
Packit Service 82fcde
  return status;
Packit Service 82fcde
}
Packit Service 82fcde
libnsl_hidden_nolink_def (yp_bind, GLIBC_2_0)
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
yp_unbind_locked (const char *indomain)
Packit Service 82fcde
{
Packit Service 82fcde
  dom_binding *ydbptr, *ydbptr2;
Packit Service 82fcde
Packit Service 82fcde
  ydbptr2 = NULL;
Packit Service 82fcde
  ydbptr = ypbindlist;
Packit Service 82fcde
Packit Service 82fcde
  while (ydbptr != NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (strcmp (ydbptr->dom_domain, indomain) == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  dom_binding *work;
Packit Service 82fcde
Packit Service 82fcde
	  work = ydbptr;
Packit Service 82fcde
	  if (ydbptr2 == NULL)
Packit Service 82fcde
	    ypbindlist = ypbindlist->dom_pnext;
Packit Service 82fcde
	  else
Packit Service 82fcde
	    ydbptr2 = ydbptr->dom_pnext;
Packit Service 82fcde
	  __yp_unbind (work);
Packit Service 82fcde
	  break;
Packit Service 82fcde
	}
Packit Service 82fcde
      ydbptr2 = ydbptr;
Packit Service 82fcde
      ydbptr = ydbptr->dom_pnext;
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
void
Packit Service 82fcde
yp_unbind (const char *indomain)
Packit Service 82fcde
{
Packit Service 82fcde
  __libc_lock_lock (ypbindlist_lock);
Packit Service 82fcde
Packit Service 82fcde
  yp_unbind_locked (indomain);
Packit Service 82fcde
Packit Service 82fcde
  __libc_lock_unlock (ypbindlist_lock);
Packit Service 82fcde
Packit Service 82fcde
  return;
Packit Service 82fcde
}
Packit Service 82fcde
libnsl_hidden_nolink_def(yp_unbind, GLIBC_2_0)
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
__ypclnt_call (const char *domain, u_long prog, xdrproc_t xargs,
Packit Service 82fcde
	       caddr_t req, xdrproc_t xres, caddr_t resp, dom_binding **ydb,
Packit Service 82fcde
	       int print_error)
Packit Service 82fcde
{
Packit Service 82fcde
  enum clnt_stat result;
Packit Service 82fcde
Packit Service 82fcde
  result = clnt_call ((*ydb)->dom_client, prog,
Packit Service 82fcde
		      xargs, req, xres, resp, RPCTIMEOUT);
Packit Service 82fcde
Packit Service 82fcde
  if (result != RPC_SUCCESS)
Packit Service 82fcde
    {
Packit Service 82fcde
      /* We don't print an error message, if we try our old,
Packit Service 82fcde
	 cached data. Only print this for data, which should work.  */
Packit Service 82fcde
      if (print_error)
Packit Service 82fcde
	clnt_perror ((*ydb)->dom_client, "do_ypcall: clnt_call");
Packit Service 82fcde
Packit Service 82fcde
      return YPERR_RPC;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return YPERR_SUCCESS;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
do_ypcall (const char *domain, u_long prog, xdrproc_t xargs,
Packit Service 82fcde
	   caddr_t req, xdrproc_t xres, caddr_t resp)
Packit Service 82fcde
{
Packit Service 82fcde
  dom_binding *ydb;
Packit Service 82fcde
  int status;
Packit Service 82fcde
  int saved_errno = errno;
Packit Service 82fcde
Packit Service 82fcde
  status = YPERR_YPERR;
Packit Service 82fcde
Packit Service 82fcde
  __libc_lock_lock (ypbindlist_lock);
Packit Service 82fcde
  ydb = ypbindlist;
Packit Service 82fcde
  while (ydb != NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (strcmp (domain, ydb->dom_domain) == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
          if (__yp_bind (domain, &ydb) == 0)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      /* Call server, print no error message, do not unbind.  */
Packit Service 82fcde
	      status = __ypclnt_call (domain, prog, xargs, req, xres,
Packit Service 82fcde
				      resp, &ydb, 0);
Packit Service 82fcde
	      if (status == YPERR_SUCCESS)
Packit Service 82fcde
	        {
Packit Service 82fcde
		  __libc_lock_unlock (ypbindlist_lock);
Packit Service 82fcde
	          __set_errno (saved_errno);
Packit Service 82fcde
	          return status;
Packit Service 82fcde
	        }
Packit Service 82fcde
	    }
Packit Service 82fcde
	  /* We use ypbindlist, and the old cached data is
Packit Service 82fcde
	     invalid. unbind now and create a new binding */
Packit Service 82fcde
	  yp_unbind_locked (domain);
Packit Service 82fcde
Packit Service 82fcde
	  break;
Packit Service 82fcde
	}
Packit Service 82fcde
      ydb = ydb->dom_pnext;
Packit Service 82fcde
    }
Packit Service 82fcde
  __libc_lock_unlock (ypbindlist_lock);
Packit Service 82fcde
Packit Service 82fcde
  /* First try with cached data failed. Now try to get
Packit Service 82fcde
     current data from the system.  */
Packit Service 82fcde
  ydb = NULL;
Packit Service 82fcde
  if (__yp_bind (domain, &ydb) == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      status = __ypclnt_call (domain, prog, xargs, req, xres,
Packit Service 82fcde
			      resp, &ydb, 1);
Packit Service 82fcde
      __yp_unbind (ydb);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
#if USE_BINDINGDIR
Packit Service 82fcde
  /* If we support binding dir data, we have a third chance:
Packit Service 82fcde
     Ask ypbind.  */
Packit Service 82fcde
  if (status != YPERR_SUCCESS)
Packit Service 82fcde
    {
Packit Service 82fcde
      ydb = calloc (1, sizeof (dom_binding));
Packit Service 82fcde
      if (ydb != NULL && yp_bind_ypbindprog (domain, ydb) == YPERR_SUCCESS)
Packit Service 82fcde
	{
Packit Service 82fcde
	  status = __ypclnt_call (domain, prog, xargs, req, xres,
Packit Service 82fcde
				  resp, &ydb, 1);
Packit Service 82fcde
	  __yp_unbind (ydb);
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	free (ydb);
Packit Service 82fcde
    }
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
  __set_errno (saved_errno);
Packit Service 82fcde
Packit Service 82fcde
  return status;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* Like do_ypcall, but translate the status value if necessary.  */
Packit Service 82fcde
static int
Packit Service 82fcde
do_ypcall_tr (const char *domain, u_long prog, xdrproc_t xargs,
Packit Service 82fcde
	      caddr_t req, xdrproc_t xres, caddr_t resp)
Packit Service 82fcde
{
Packit Service 82fcde
  int status = do_ypcall (domain, prog, xargs, req, xres, resp);
Packit Service 82fcde
  if (status == YPERR_SUCCESS)
Packit Service 82fcde
    /* We cast to ypresp_val although the pointer could also be of
Packit Service 82fcde
       type ypresp_key_val or ypresp_master or ypresp_order or
Packit Service 82fcde
       ypresp_maplist.  But the stat element is in a common prefix so
Packit Service 82fcde
       this does not matter.  */
Packit Service 82fcde
    status = ypprot_err (((struct ypresp_val *) resp)->stat);
Packit Service 82fcde
  return status;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
__libc_lock_define_initialized (static, domainname_lock)
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
yp_get_default_domain (char **outdomain)
Packit Service 82fcde
{
Packit Service 82fcde
  int result = YPERR_SUCCESS;;
Packit Service 82fcde
  *outdomain = NULL;
Packit Service 82fcde
Packit Service 82fcde
  __libc_lock_lock (domainname_lock);
Packit Service 82fcde
Packit Service 82fcde
  if (ypdomainname[0] == '\0')
Packit Service 82fcde
    {
Packit Service 82fcde
      if (getdomainname (ypdomainname, NIS_MAXNAMELEN))
Packit Service 82fcde
	result = YPERR_NODOM;
Packit Service 82fcde
      else if (strcmp (ypdomainname, "(none)") == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* If domainname is not set, some systems will return "(none)" */
Packit Service 82fcde
	  ypdomainname[0] = '\0';
Packit Service 82fcde
	  result = YPERR_NODOM;
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	*outdomain = ypdomainname;
Packit Service 82fcde
    }
Packit Service 82fcde
  else
Packit Service 82fcde
    *outdomain = ypdomainname;
Packit Service 82fcde
Packit Service 82fcde
  __libc_lock_unlock (domainname_lock);
Packit Service 82fcde
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
libnsl_hidden_nolink_def (yp_get_default_domain, GLIBC_2_0)
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
__yp_check (char **domain)
Packit Service 82fcde
{
Packit Service 82fcde
  char *unused;
Packit Service 82fcde
Packit Service 82fcde
  if (ypdomainname[0] == '\0')
Packit Service 82fcde
    if (yp_get_default_domain (&unused))
Packit Service 82fcde
      return 0;
Packit Service 82fcde
Packit Service 82fcde
  if (domain)
Packit Service 82fcde
    *domain = ypdomainname;
Packit Service 82fcde
Packit Service 82fcde
  if (yp_bind (ypdomainname) == 0)
Packit Service 82fcde
    return 1;
Packit Service 82fcde
  return 0;
Packit Service 82fcde
}
Packit Service 82fcde
libnsl_hidden_nolink_def(__yp_check, GLIBC_2_0)
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
yp_match (const char *indomain, const char *inmap, const char *inkey,
Packit Service 82fcde
	  const int inkeylen, char **outval, int *outvallen)
Packit Service 82fcde
{
Packit Service 82fcde
  ypreq_key req;
Packit Service 82fcde
  ypresp_val resp;
Packit Service 82fcde
  enum clnt_stat result;
Packit Service 82fcde
Packit Service 82fcde
  if (indomain == NULL || indomain[0] == '\0' ||
Packit Service 82fcde
      inmap == NULL || inmap[0] == '\0' ||
Packit Service 82fcde
      inkey == NULL || inkey[0] == '\0' || inkeylen <= 0)
Packit Service 82fcde
    return YPERR_BADARGS;
Packit Service 82fcde
Packit Service 82fcde
  req.domain = (char *) indomain;
Packit Service 82fcde
  req.map = (char *) inmap;
Packit Service 82fcde
  req.key.keydat_val = (char *) inkey;
Packit Service 82fcde
  req.key.keydat_len = inkeylen;
Packit Service 82fcde
Packit Service 82fcde
  *outval = NULL;
Packit Service 82fcde
  *outvallen = 0;
Packit Service 82fcde
  memset (&resp, '\0', sizeof (resp));
Packit Service 82fcde
Packit Service 82fcde
  result = do_ypcall_tr (indomain, YPPROC_MATCH, (xdrproc_t) xdr_ypreq_key,
Packit Service 82fcde
			 (caddr_t) &req, (xdrproc_t) xdr_ypresp_val,
Packit Service 82fcde
			 (caddr_t) &resp);
Packit Service 82fcde
Packit Service 82fcde
  if (result != YPERR_SUCCESS)
Packit Service 82fcde
    return result;
Packit Service 82fcde
Packit Service 82fcde
  *outvallen = resp.val.valdat_len;
Packit Service 82fcde
  *outval = malloc (*outvallen + 1);
Packit Service 82fcde
  int status = YPERR_RESRC;
Packit Service 82fcde
  if (__glibc_likely (*outval != NULL))
Packit Service 82fcde
    {
Packit Service 82fcde
      memcpy (*outval, resp.val.valdat_val, *outvallen);
Packit Service 82fcde
      (*outval)[*outvallen] = '\0';
Packit Service 82fcde
      status = YPERR_SUCCESS;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  xdr_free ((xdrproc_t) xdr_ypresp_val, (char *) &resp);
Packit Service 82fcde
Packit Service 82fcde
  return status;
Packit Service 82fcde
}
Packit Service 82fcde
libnsl_hidden_nolink_def(yp_match, GLIBC_2_0)
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
yp_first (const char *indomain, const char *inmap, char **outkey,
Packit Service 82fcde
	  int *outkeylen, char **outval, int *outvallen)
Packit Service 82fcde
{
Packit Service 82fcde
  ypreq_nokey req;
Packit Service 82fcde
  ypresp_key_val resp;
Packit Service 82fcde
  enum clnt_stat result;
Packit Service 82fcde
Packit Service 82fcde
  if (indomain == NULL || indomain[0] == '\0' ||
Packit Service 82fcde
      inmap == NULL || inmap[0] == '\0')
Packit Service 82fcde
    return YPERR_BADARGS;
Packit Service 82fcde
Packit Service 82fcde
  req.domain = (char *) indomain;
Packit Service 82fcde
  req.map = (char *) inmap;
Packit Service 82fcde
Packit Service 82fcde
  *outkey = *outval = NULL;
Packit Service 82fcde
  *outkeylen = *outvallen = 0;
Packit Service 82fcde
  memset (&resp, '\0', sizeof (resp));
Packit Service 82fcde
Packit Service 82fcde
  result = do_ypcall (indomain, YPPROC_FIRST, (xdrproc_t) xdr_ypreq_nokey,
Packit Service 82fcde
		      (caddr_t) &req, (xdrproc_t) xdr_ypresp_key_val,
Packit Service 82fcde
		      (caddr_t) &resp);
Packit Service 82fcde
Packit Service 82fcde
  if (result != RPC_SUCCESS)
Packit Service 82fcde
    return YPERR_RPC;
Packit Service 82fcde
  if (resp.stat != YP_TRUE)
Packit Service 82fcde
    return ypprot_err (resp.stat);
Packit Service 82fcde
Packit Service 82fcde
  int status;
Packit Service 82fcde
  if (__builtin_expect ((*outkey  = malloc (resp.key.keydat_len + 1)) != NULL
Packit Service 82fcde
			&& (*outval = malloc (resp.val.valdat_len
Packit Service 82fcde
					      + 1)) != NULL, 1))
Packit Service 82fcde
    {
Packit Service 82fcde
      *outkeylen = resp.key.keydat_len;
Packit Service 82fcde
      memcpy (*outkey, resp.key.keydat_val, *outkeylen);
Packit Service 82fcde
      (*outkey)[*outkeylen] = '\0';
Packit Service 82fcde
Packit Service 82fcde
      *outvallen = resp.val.valdat_len;
Packit Service 82fcde
      memcpy (*outval, resp.val.valdat_val, *outvallen);
Packit Service 82fcde
      (*outval)[*outvallen] = '\0';
Packit Service 82fcde
Packit Service 82fcde
      status = YPERR_SUCCESS;
Packit Service 82fcde
    }
Packit Service 82fcde
  else
Packit Service 82fcde
    {
Packit Service 82fcde
      free (*outkey);
Packit Service 82fcde
      status = YPERR_RESRC;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  xdr_free ((xdrproc_t) xdr_ypresp_key_val, (char *) &resp);
Packit Service 82fcde
Packit Service 82fcde
  return status;
Packit Service 82fcde
}
Packit Service 82fcde
libnsl_hidden_nolink_def(yp_first, GLIBC_2_0)
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
yp_next (const char *indomain, const char *inmap, const char *inkey,
Packit Service 82fcde
	 const int inkeylen, char **outkey, int *outkeylen, char **outval,
Packit Service 82fcde
	 int *outvallen)
Packit Service 82fcde
{
Packit Service 82fcde
  ypreq_key req;
Packit Service 82fcde
  ypresp_key_val resp;
Packit Service 82fcde
  enum clnt_stat result;
Packit Service 82fcde
Packit Service 82fcde
  if (indomain == NULL || indomain[0] == '\0' ||
Packit Service 82fcde
      inmap == NULL || inmap[0] == '\0' ||
Packit Service 82fcde
      inkeylen <= 0 || inkey == NULL || inkey[0] == '\0')
Packit Service 82fcde
    return YPERR_BADARGS;
Packit Service 82fcde
Packit Service 82fcde
  req.domain = (char *) indomain;
Packit Service 82fcde
  req.map = (char *) inmap;
Packit Service 82fcde
  req.key.keydat_val = (char *) inkey;
Packit Service 82fcde
  req.key.keydat_len = inkeylen;
Packit Service 82fcde
Packit Service 82fcde
  *outkey = *outval = NULL;
Packit Service 82fcde
  *outkeylen = *outvallen = 0;
Packit Service 82fcde
  memset (&resp, '\0', sizeof (resp));
Packit Service 82fcde
Packit Service 82fcde
  result = do_ypcall_tr (indomain, YPPROC_NEXT, (xdrproc_t) xdr_ypreq_key,
Packit Service 82fcde
			 (caddr_t) &req, (xdrproc_t) xdr_ypresp_key_val,
Packit Service 82fcde
			 (caddr_t) &resp);
Packit Service 82fcde
Packit Service 82fcde
  if (result != YPERR_SUCCESS)
Packit Service 82fcde
    return result;
Packit Service 82fcde
Packit Service 82fcde
  int status;
Packit Service 82fcde
  if (__builtin_expect ((*outkey  = malloc (resp.key.keydat_len + 1)) != NULL
Packit Service 82fcde
			&& (*outval = malloc (resp.val.valdat_len
Packit Service 82fcde
					      + 1)) != NULL, 1))
Packit Service 82fcde
    {
Packit Service 82fcde
      *outkeylen = resp.key.keydat_len;
Packit Service 82fcde
      memcpy (*outkey, resp.key.keydat_val, *outkeylen);
Packit Service 82fcde
      (*outkey)[*outkeylen] = '\0';
Packit Service 82fcde
Packit Service 82fcde
      *outvallen = resp.val.valdat_len;
Packit Service 82fcde
      memcpy (*outval, resp.val.valdat_val, *outvallen);
Packit Service 82fcde
      (*outval)[*outvallen] = '\0';
Packit Service 82fcde
Packit Service 82fcde
      status = YPERR_SUCCESS;
Packit Service 82fcde
    }
Packit Service 82fcde
  else
Packit Service 82fcde
    {
Packit Service 82fcde
      free (*outkey);
Packit Service 82fcde
      status = YPERR_RESRC;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  xdr_free ((xdrproc_t) xdr_ypresp_key_val, (char *) &resp);
Packit Service 82fcde
Packit Service 82fcde
  return status;
Packit Service 82fcde
}
Packit Service 82fcde
libnsl_hidden_nolink_def(yp_next, GLIBC_2_0)
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
yp_master (const char *indomain, const char *inmap, char **outname)
Packit Service 82fcde
{
Packit Service 82fcde
  ypreq_nokey req;
Packit Service 82fcde
  ypresp_master resp;
Packit Service 82fcde
  enum clnt_stat result;
Packit Service 82fcde
Packit Service 82fcde
  if (indomain == NULL || indomain[0] == '\0' ||
Packit Service 82fcde
      inmap == NULL || inmap[0] == '\0')
Packit Service 82fcde
    return YPERR_BADARGS;
Packit Service 82fcde
Packit Service 82fcde
  req.domain = (char *) indomain;
Packit Service 82fcde
  req.map = (char *) inmap;
Packit Service 82fcde
Packit Service 82fcde
  memset (&resp, '\0', sizeof (ypresp_master));
Packit Service 82fcde
Packit Service 82fcde
  result = do_ypcall_tr (indomain, YPPROC_MASTER, (xdrproc_t) xdr_ypreq_nokey,
Packit Service 82fcde
			 (caddr_t) &req, (xdrproc_t) xdr_ypresp_master,
Packit Service 82fcde
			 (caddr_t) &resp);
Packit Service 82fcde
Packit Service 82fcde
  if (result != YPERR_SUCCESS)
Packit Service 82fcde
    return result;
Packit Service 82fcde
Packit Service 82fcde
  *outname = strdup (resp.peer);
Packit Service 82fcde
  xdr_free ((xdrproc_t) xdr_ypresp_master, (char *) &resp);
Packit Service 82fcde
Packit Service 82fcde
  return *outname == NULL ? YPERR_YPERR : YPERR_SUCCESS;
Packit Service 82fcde
}
Packit Service 82fcde
libnsl_hidden_nolink_def (yp_master, GLIBC_2_0)
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
yp_order (const char *indomain, const char *inmap, unsigned int *outorder)
Packit Service 82fcde
{
Packit Service 82fcde
  struct ypreq_nokey req;
Packit Service 82fcde
  struct ypresp_order resp;
Packit Service 82fcde
  enum clnt_stat result;
Packit Service 82fcde
Packit Service 82fcde
  if (indomain == NULL || indomain[0] == '\0' ||
Packit Service 82fcde
      inmap == NULL || inmap[0] == '\0')
Packit Service 82fcde
    return YPERR_BADARGS;
Packit Service 82fcde
Packit Service 82fcde
  req.domain = (char *) indomain;
Packit Service 82fcde
  req.map = (char *) inmap;
Packit Service 82fcde
Packit Service 82fcde
  memset (&resp, '\0', sizeof (resp));
Packit Service 82fcde
Packit Service 82fcde
  result = do_ypcall_tr (indomain, YPPROC_ORDER, (xdrproc_t) xdr_ypreq_nokey,
Packit Service 82fcde
			 (caddr_t) &req, (xdrproc_t) xdr_ypresp_order,
Packit Service 82fcde
			 (caddr_t) &resp);
Packit Service 82fcde
Packit Service 82fcde
  if (result != YPERR_SUCCESS)
Packit Service 82fcde
    return result;
Packit Service 82fcde
Packit Service 82fcde
  *outorder = resp.ordernum;
Packit Service 82fcde
  xdr_free ((xdrproc_t) xdr_ypresp_order, (char *) &resp);
Packit Service 82fcde
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
libnsl_hidden_nolink_def(yp_order, GLIBC_2_0)
Packit Service 82fcde
Packit Service 82fcde
struct ypresp_all_data
Packit Service 82fcde
{
Packit Service 82fcde
  unsigned long status;
Packit Service 82fcde
  void *data;
Packit Service 82fcde
  int (*foreach) (int status, char *key, int keylen,
Packit Service 82fcde
		  char *val, int vallen, char *data);
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
static bool_t
Packit Service 82fcde
__xdr_ypresp_all (XDR *xdrs, struct ypresp_all_data *objp)
Packit Service 82fcde
{
Packit Service 82fcde
  while (1)
Packit Service 82fcde
    {
Packit Service 82fcde
      struct ypresp_all resp;
Packit Service 82fcde
Packit Service 82fcde
      memset (&resp, '\0', sizeof (struct ypresp_all));
Packit Service 82fcde
      if (!xdr_ypresp_all (xdrs, &resp))
Packit Service 82fcde
	{
Packit Service 82fcde
	  xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
Packit Service 82fcde
	  objp->status = YP_YPERR;
Packit Service 82fcde
	  return FALSE;
Packit Service 82fcde
	}
Packit Service 82fcde
      if (resp.more == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
Packit Service 82fcde
	  objp->status = YP_NOMORE;
Packit Service 82fcde
	  return TRUE;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      switch (resp.ypresp_all_u.val.stat)
Packit Service 82fcde
	{
Packit Service 82fcde
	case YP_TRUE:
Packit Service 82fcde
	  {
Packit Service 82fcde
	    char key[resp.ypresp_all_u.val.key.keydat_len + 1];
Packit Service 82fcde
	    char val[resp.ypresp_all_u.val.val.valdat_len + 1];
Packit Service 82fcde
	    int keylen = resp.ypresp_all_u.val.key.keydat_len;
Packit Service 82fcde
	    int vallen = resp.ypresp_all_u.val.val.valdat_len;
Packit Service 82fcde
Packit Service 82fcde
	    /* We are not allowed to modify the key and val data.
Packit Service 82fcde
	       But we are allowed to add data behind the buffer,
Packit Service 82fcde
	       if we don't modify the length. So add an extra NUL
Packit Service 82fcde
	       character to avoid trouble with broken code. */
Packit Service 82fcde
	    objp->status = YP_TRUE;
Packit Service 82fcde
	    *((char *) __mempcpy (key, resp.ypresp_all_u.val.key.keydat_val,
Packit Service 82fcde
				  keylen)) = '\0';
Packit Service 82fcde
	    *((char *) __mempcpy (val, resp.ypresp_all_u.val.val.valdat_val,
Packit Service 82fcde
				  vallen)) = '\0';
Packit Service 82fcde
	    xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
Packit Service 82fcde
	    if ((*objp->foreach) (objp->status, key, keylen,
Packit Service 82fcde
				  val, vallen, objp->data))
Packit Service 82fcde
	      return TRUE;
Packit Service 82fcde
	  }
Packit Service 82fcde
	  break;
Packit Service 82fcde
	default:
Packit Service 82fcde
	  objp->status = resp.ypresp_all_u.val.stat;
Packit Service 82fcde
	  xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
Packit Service 82fcde
	  /* Sun says we don't need to make this call, but must return
Packit Service 82fcde
	     immediately. Since Solaris makes this call, we will call
Packit Service 82fcde
	     the callback function, too. */
Packit Service 82fcde
	  (*objp->foreach) (objp->status, NULL, 0, NULL, 0, objp->data);
Packit Service 82fcde
	  return TRUE;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
yp_all (const char *indomain, const char *inmap,
Packit Service 82fcde
	const struct ypall_callback *incallback)
Packit Service 82fcde
{
Packit Service 82fcde
  struct ypreq_nokey req;
Packit Service 82fcde
  dom_binding *ydb = NULL;
Packit Service 82fcde
  int try, res;
Packit Service 82fcde
  enum clnt_stat result;
Packit Service 82fcde
  struct sockaddr_in clnt_sin;
Packit Service 82fcde
  CLIENT *clnt;
Packit Service 82fcde
  struct ypresp_all_data data;
Packit Service 82fcde
  int clnt_sock;
Packit Service 82fcde
  int saved_errno = errno;
Packit Service 82fcde
Packit Service 82fcde
  if (indomain == NULL || indomain[0] == '\0'
Packit Service 82fcde
      || inmap == NULL || inmap[0] == '\0')
Packit Service 82fcde
    return YPERR_BADARGS;
Packit Service 82fcde
Packit Service 82fcde
  try = 0;
Packit Service 82fcde
  res = YPERR_YPERR;
Packit Service 82fcde
Packit Service 82fcde
  while (try < MAXTRIES && res != YPERR_SUCCESS)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (__yp_bind (indomain, &ydb) != 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  __set_errno (saved_errno);
Packit Service 82fcde
	  return YPERR_DOMAIN;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      clnt_sock = RPC_ANYSOCK;
Packit Service 82fcde
      clnt_sin = ydb->dom_server_addr;
Packit Service 82fcde
      clnt_sin.sin_port = 0;
Packit Service 82fcde
Packit Service 82fcde
      /* We don't need the UDP connection anymore.  */
Packit Service 82fcde
      __yp_unbind (ydb);
Packit Service 82fcde
      ydb = NULL;
Packit Service 82fcde
Packit Service 82fcde
      clnt = clnttcp_create (&clnt_sin, YPPROG, YPVERS, &clnt_sock, 0, 0);
Packit Service 82fcde
      if (clnt == NULL)
Packit Service 82fcde
	{
Packit Service 82fcde
	  __set_errno (saved_errno);
Packit Service 82fcde
	  return YPERR_PMAP;
Packit Service 82fcde
	}
Packit Service 82fcde
      req.domain = (char *) indomain;
Packit Service 82fcde
      req.map = (char *) inmap;
Packit Service 82fcde
Packit Service 82fcde
      data.foreach = incallback->foreach;
Packit Service 82fcde
      data.data = (void *) incallback->data;
Packit Service 82fcde
Packit Service 82fcde
      result = clnt_call (clnt, YPPROC_ALL, (xdrproc_t) xdr_ypreq_nokey,
Packit Service 82fcde
			  (caddr_t) &req, (xdrproc_t) __xdr_ypresp_all,
Packit Service 82fcde
			  (caddr_t) &data, RPCTIMEOUT);
Packit Service 82fcde
Packit Service 82fcde
      if (__glibc_unlikely (result != RPC_SUCCESS))
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* Print the error message only on the last try.  */
Packit Service 82fcde
	  if (try == MAXTRIES - 1)
Packit Service 82fcde
	    clnt_perror (clnt, "yp_all: clnt_call");
Packit Service 82fcde
	  res = YPERR_RPC;
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	res = YPERR_SUCCESS;
Packit Service 82fcde
Packit Service 82fcde
      clnt_destroy (clnt);
Packit Service 82fcde
Packit Service 82fcde
      if (res == YPERR_SUCCESS && data.status != YP_NOMORE)
Packit Service 82fcde
	{
Packit Service 82fcde
	  __set_errno (saved_errno);
Packit Service 82fcde
	  return ypprot_err (data.status);
Packit Service 82fcde
	}
Packit Service 82fcde
      ++try;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  __set_errno (saved_errno);
Packit Service 82fcde
Packit Service 82fcde
  return res;
Packit Service 82fcde
}
Packit Service 82fcde
libnsl_hidden_nolink_def (yp_all, GLIBC_2_0)
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
yp_maplist (const char *indomain, struct ypmaplist **outmaplist)
Packit Service 82fcde
{
Packit Service 82fcde
  struct ypresp_maplist resp;
Packit Service 82fcde
  enum clnt_stat result;
Packit Service 82fcde
Packit Service 82fcde
  if (indomain == NULL || indomain[0] == '\0')
Packit Service 82fcde
    return YPERR_BADARGS;
Packit Service 82fcde
Packit Service 82fcde
  memset (&resp, '\0', sizeof (resp));
Packit Service 82fcde
Packit Service 82fcde
  result = do_ypcall_tr (indomain, YPPROC_MAPLIST, (xdrproc_t) xdr_domainname,
Packit Service 82fcde
			 (caddr_t) &indomain, (xdrproc_t) xdr_ypresp_maplist,
Packit Service 82fcde
			 (caddr_t) &resp);
Packit Service 82fcde
Packit Service 82fcde
  if (__glibc_likely (result == YPERR_SUCCESS))
Packit Service 82fcde
    {
Packit Service 82fcde
      *outmaplist = resp.maps;
Packit Service 82fcde
      /* We don't free the list, this will be done by ypserv
Packit Service 82fcde
	 xdr_free((xdrproc_t)xdr_ypresp_maplist, (char *)&resp); */
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
libnsl_hidden_nolink_def (yp_maplist, GLIBC_2_0)
Packit Service 82fcde
Packit Service 82fcde
const char *
Packit Service 82fcde
yperr_string (const int error)
Packit Service 82fcde
{
Packit Service 82fcde
  const char *str;
Packit Service 82fcde
  switch (error)
Packit Service 82fcde
    {
Packit Service 82fcde
    case YPERR_SUCCESS:
Packit Service 82fcde
      str = N_("Success");
Packit Service 82fcde
      break;
Packit Service 82fcde
    case YPERR_BADARGS:
Packit Service 82fcde
      str = N_("Request arguments bad");
Packit Service 82fcde
      break;
Packit Service 82fcde
    case YPERR_RPC:
Packit Service 82fcde
      str = N_("RPC failure on NIS operation");
Packit Service 82fcde
      break;
Packit Service 82fcde
    case YPERR_DOMAIN:
Packit Service 82fcde
      str = N_("Can't bind to server which serves this domain");
Packit Service 82fcde
      break;
Packit Service 82fcde
    case YPERR_MAP:
Packit Service 82fcde
      str = N_("No such map in server's domain");
Packit Service 82fcde
      break;
Packit Service 82fcde
    case YPERR_KEY:
Packit Service 82fcde
      str = N_("No such key in map");
Packit Service 82fcde
      break;
Packit Service 82fcde
    case YPERR_YPERR:
Packit Service 82fcde
      str = N_("Internal NIS error");
Packit Service 82fcde
      break;
Packit Service 82fcde
    case YPERR_RESRC:
Packit Service 82fcde
      str = N_("Local resource allocation failure");
Packit Service 82fcde
      break;
Packit Service 82fcde
    case YPERR_NOMORE:
Packit Service 82fcde
      str = N_("No more records in map database");
Packit Service 82fcde
      break;
Packit Service 82fcde
    case YPERR_PMAP:
Packit Service 82fcde
      str = N_("Can't communicate with portmapper");
Packit Service 82fcde
      break;
Packit Service 82fcde
    case YPERR_YPBIND:
Packit Service 82fcde
      str = N_("Can't communicate with ypbind");
Packit Service 82fcde
      break;
Packit Service 82fcde
    case YPERR_YPSERV:
Packit Service 82fcde
      str = N_("Can't communicate with ypserv");
Packit Service 82fcde
      break;
Packit Service 82fcde
    case YPERR_NODOM:
Packit Service 82fcde
      str = N_("Local domain name not set");
Packit Service 82fcde
      break;
Packit Service 82fcde
    case YPERR_BADDB:
Packit Service 82fcde
      str = N_("NIS map database is bad");
Packit Service 82fcde
      break;
Packit Service 82fcde
    case YPERR_VERS:
Packit Service 82fcde
      str = N_("NIS client/server version mismatch - can't supply service");
Packit Service 82fcde
      break;
Packit Service 82fcde
    case YPERR_ACCESS:
Packit Service 82fcde
      str = N_("Permission denied");
Packit Service 82fcde
      break;
Packit Service 82fcde
    case YPERR_BUSY:
Packit Service 82fcde
      str = N_("Database is busy");
Packit Service 82fcde
      break;
Packit Service 82fcde
    default:
Packit Service 82fcde
      str = N_("Unknown NIS error code");
Packit Service 82fcde
      break;
Packit Service 82fcde
    }
Packit Service 82fcde
  return _(str);
Packit Service 82fcde
}
Packit Service 82fcde
libnsl_hidden_nolink_def(yperr_string, GLIBC_2_0)
Packit Service 82fcde
Packit Service 82fcde
static const int8_t yp_2_yperr[] =
Packit Service 82fcde
  {
Packit Service 82fcde
#define YP2YPERR(yp, yperr)  [YP_##yp - YP_VERS] = YPERR_##yperr
Packit Service 82fcde
    YP2YPERR (TRUE, SUCCESS),
Packit Service 82fcde
    YP2YPERR (NOMORE, NOMORE),
Packit Service 82fcde
    YP2YPERR (FALSE, YPERR),
Packit Service 82fcde
    YP2YPERR (NOMAP, MAP),
Packit Service 82fcde
    YP2YPERR (NODOM, DOMAIN),
Packit Service 82fcde
    YP2YPERR (NOKEY, KEY),
Packit Service 82fcde
    YP2YPERR (BADOP, YPERR),
Packit Service 82fcde
    YP2YPERR (BADDB, BADDB),
Packit Service 82fcde
    YP2YPERR (YPERR, YPERR),
Packit Service 82fcde
    YP2YPERR (BADARGS, BADARGS),
Packit Service 82fcde
    YP2YPERR (VERS, VERS)
Packit Service 82fcde
  };
Packit Service 82fcde
int
Packit Service 82fcde
ypprot_err (const int code)
Packit Service 82fcde
{
Packit Service 82fcde
  if (code < YP_VERS || code > YP_NOMORE)
Packit Service 82fcde
    return YPERR_YPERR;
Packit Service 82fcde
  return yp_2_yperr[code - YP_VERS];
Packit Service 82fcde
}
Packit Service 82fcde
libnsl_hidden_nolink_def (ypprot_err, GLIBC_2_0)
Packit Service 82fcde
Packit Service 82fcde
const char *
Packit Service 82fcde
ypbinderr_string (const int error)
Packit Service 82fcde
{
Packit Service 82fcde
  const char *str;
Packit Service 82fcde
  switch (error)
Packit Service 82fcde
    {
Packit Service 82fcde
    case 0:
Packit Service 82fcde
      str = N_("Success");
Packit Service 82fcde
      break;
Packit Service 82fcde
    case YPBIND_ERR_ERR:
Packit Service 82fcde
      str = N_("Internal ypbind error");
Packit Service 82fcde
      break;
Packit Service 82fcde
    case YPBIND_ERR_NOSERV:
Packit Service 82fcde
      str = N_("Domain not bound");
Packit Service 82fcde
      break;
Packit Service 82fcde
    case YPBIND_ERR_RESC:
Packit Service 82fcde
      str = N_("System resource allocation failure");
Packit Service 82fcde
      break;
Packit Service 82fcde
    default:
Packit Service 82fcde
      str = N_("Unknown ypbind error");
Packit Service 82fcde
      break;
Packit Service 82fcde
    }
Packit Service 82fcde
  return _(str);
Packit Service 82fcde
}
Packit Service 82fcde
libnsl_hidden_nolink_def (ypbinderr_string, GLIBC_2_0)
Packit Service 82fcde
Packit Service 82fcde
#define WINDOW 60
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
yp_update (char *domain, char *map, unsigned ypop,
Packit Service 82fcde
	   char *key, int keylen, char *data, int datalen)
Packit Service 82fcde
{
Packit Service 82fcde
  union
Packit Service 82fcde
    {
Packit Service 82fcde
      ypupdate_args update_args;
Packit Service 82fcde
      ypdelete_args delete_args;
Packit Service 82fcde
    }
Packit Service 82fcde
  args;
Packit Service 82fcde
  xdrproc_t xdr_argument;
Packit Service 82fcde
  unsigned res = 0;
Packit Service 82fcde
  CLIENT *clnt;
Packit Service 82fcde
  char *master;
Packit Service 82fcde
  struct sockaddr saddr;
Packit Service 82fcde
  char servername[MAXNETNAMELEN + 1];
Packit Service 82fcde
  int r;
Packit Service 82fcde
Packit Service 82fcde
  if (!domain || !map || !key || (ypop != YPOP_DELETE && !data))
Packit Service 82fcde
    return YPERR_BADARGS;
Packit Service 82fcde
Packit Service 82fcde
  args.update_args.mapname = map;
Packit Service 82fcde
  args.update_args.key.yp_buf_len = keylen;
Packit Service 82fcde
  args.update_args.key.yp_buf_val = key;
Packit Service 82fcde
  args.update_args.datum.yp_buf_len = datalen;
Packit Service 82fcde
  args.update_args.datum.yp_buf_val = data;
Packit Service 82fcde
Packit Service 82fcde
  if ((r = yp_master (domain, map, &master)) != YPERR_SUCCESS)
Packit Service 82fcde
    return r;
Packit Service 82fcde
Packit Service 82fcde
  if (!host2netname (servername, master, domain))
Packit Service 82fcde
    {
Packit Service 82fcde
      fputs (_("yp_update: cannot convert host to netname\n"), stderr);
Packit Service 82fcde
      free (master);
Packit Service 82fcde
      return YPERR_YPERR;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  clnt = clnt_create (master, YPU_PROG, YPU_VERS, "tcp");
Packit Service 82fcde
Packit Service 82fcde
  /* We do not need the string anymore.  */
Packit Service 82fcde
  free (master);
Packit Service 82fcde
Packit Service 82fcde
  if (clnt == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      clnt_pcreateerror ("yp_update: clnt_create");
Packit Service 82fcde
      return YPERR_RPC;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (!clnt_control (clnt, CLGET_SERVER_ADDR, (char *) &saddr))
Packit Service 82fcde
    {
Packit Service 82fcde
      fputs (_("yp_update: cannot get server address\n"), stderr);
Packit Service 82fcde
      return YPERR_RPC;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  switch (ypop)
Packit Service 82fcde
    {
Packit Service 82fcde
    case YPOP_CHANGE:
Packit Service 82fcde
    case YPOP_INSERT:
Packit Service 82fcde
    case YPOP_STORE:
Packit Service 82fcde
      xdr_argument = (xdrproc_t) xdr_ypupdate_args;
Packit Service 82fcde
      break;
Packit Service 82fcde
    case YPOP_DELETE:
Packit Service 82fcde
      xdr_argument = (xdrproc_t) xdr_ypdelete_args;
Packit Service 82fcde
      break;
Packit Service 82fcde
    default:
Packit Service 82fcde
      return YPERR_BADARGS;
Packit Service 82fcde
      break;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  clnt->cl_auth = authdes_create (servername, WINDOW, &saddr, NULL);
Packit Service 82fcde
Packit Service 82fcde
  if (clnt->cl_auth == NULL)
Packit Service 82fcde
    clnt->cl_auth = authunix_create_default ();
Packit Service 82fcde
Packit Service 82fcde
again:
Packit Service 82fcde
  r = clnt_call (clnt, ypop, xdr_argument, (caddr_t) &args,
Packit Service 82fcde
		 (xdrproc_t) xdr_u_int, (caddr_t) &res, RPCTIMEOUT);
Packit Service 82fcde
Packit Service 82fcde
  if (r == RPC_AUTHERROR)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (clnt->cl_auth->ah_cred.oa_flavor == AUTH_DES)
Packit Service 82fcde
	{
Packit Service 82fcde
	  auth_destroy (clnt->cl_auth);
Packit Service 82fcde
	  clnt->cl_auth = authunix_create_default ();
Packit Service 82fcde
	  goto again;
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	return YPERR_ACCESS;
Packit Service 82fcde
    }
Packit Service 82fcde
  if (r != RPC_SUCCESS)
Packit Service 82fcde
    {
Packit Service 82fcde
      clnt_perror (clnt, "yp_update: clnt_call");
Packit Service 82fcde
      return YPERR_RPC;
Packit Service 82fcde
    }
Packit Service 82fcde
  return res;
Packit Service 82fcde
}
Packit Service 82fcde
libnsl_hidden_nolink_def(yp_update, GLIBC_2_0)