Blame nis/nss_nis/nis-rpc.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 <nss.h>
Packit Service 82fcde
#include <netdb.h>
Packit Service 82fcde
#include <ctype.h>
Packit Service 82fcde
#include <errno.h>
Packit Service 82fcde
#include <string.h>
Packit Service 82fcde
#include <libc-lock.h>
Packit Service 82fcde
#include <rpcsvc/yp.h>
Packit Service 82fcde
#include <rpcsvc/ypclnt.h>
Packit Service 82fcde
Packit Service 82fcde
#include "nss-nis.h"
Packit Service 82fcde
Packit Service 82fcde
/* Get the declaration of the parser function.  */
Packit Service 82fcde
#define ENTNAME rpcent
Packit Service 82fcde
#define EXTERN_PARSER
Packit Service 82fcde
#include <nss/nss_files/files-parse.c>
Packit Service 82fcde
Packit Service 82fcde
__libc_lock_define_initialized (static, lock)
Packit Service 82fcde
Packit Service 82fcde
static intern_t intern;
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
internal_nis_endrpcent (intern_t *intern)
Packit Service 82fcde
{
Packit Service 82fcde
  struct response_t *curr = intern->next;
Packit Service 82fcde
Packit Service 82fcde
  while (curr != NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      struct response_t *last = curr;
Packit Service 82fcde
      curr = curr->next;
Packit Service 82fcde
      free (last);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  intern->next = intern->start = NULL;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static enum nss_status
Packit Service 82fcde
internal_nis_setrpcent (intern_t *intern)
Packit Service 82fcde
{
Packit Service 82fcde
  char *domainname;
Packit Service 82fcde
  struct ypall_callback ypcb;
Packit Service 82fcde
  enum nss_status status;
Packit Service 82fcde
Packit Service 82fcde
  if (yp_get_default_domain (&domainname))
Packit Service 82fcde
    return NSS_STATUS_UNAVAIL;
Packit Service 82fcde
Packit Service 82fcde
  internal_nis_endrpcent (intern);
Packit Service 82fcde
Packit Service 82fcde
  ypcb.foreach = _nis_saveit;
Packit Service 82fcde
  ypcb.data = (char *) intern;
Packit Service 82fcde
  status = yperr2nss (yp_all (domainname, "rpc.bynumber", &ypcb));
Packit Service 82fcde
Packit Service 82fcde
  /* Mark the last buffer as full.  */
Packit Service 82fcde
  if (intern->next != NULL)
Packit Service 82fcde
    intern->next->size = intern->offset;
Packit Service 82fcde
Packit Service 82fcde
  intern->next = intern->start;
Packit Service 82fcde
  intern->offset = 0;
Packit Service 82fcde
Packit Service 82fcde
  return status;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
enum nss_status
Packit Service 82fcde
_nss_nis_setrpcent (int stayopen)
Packit Service 82fcde
{
Packit Service 82fcde
  enum nss_status status;
Packit Service 82fcde
Packit Service 82fcde
  __libc_lock_lock (lock);
Packit Service 82fcde
Packit Service 82fcde
  status = internal_nis_setrpcent (&intern;;
Packit Service 82fcde
Packit Service 82fcde
  __libc_lock_unlock (lock);
Packit Service 82fcde
Packit Service 82fcde
  return status;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
enum nss_status
Packit Service 82fcde
_nss_nis_endrpcent (void)
Packit Service 82fcde
{
Packit Service 82fcde
  __libc_lock_lock (lock);
Packit Service 82fcde
Packit Service 82fcde
  internal_nis_endrpcent (&intern;;
Packit Service 82fcde
Packit Service 82fcde
  __libc_lock_unlock (lock);
Packit Service 82fcde
Packit Service 82fcde
  return NSS_STATUS_SUCCESS;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static enum nss_status
Packit Service 82fcde
internal_nis_getrpcent_r (struct rpcent *rpc, char *buffer, size_t buflen,
Packit Service 82fcde
			  int *errnop, intern_t *intern)
Packit Service 82fcde
{
Packit Service 82fcde
  struct parser_data *pdata = (void *) buffer;
Packit Service 82fcde
  int parse_res;
Packit Service 82fcde
  char *p;
Packit Service 82fcde
Packit Service 82fcde
  if (intern->start == NULL)
Packit Service 82fcde
    internal_nis_setrpcent (intern);
Packit Service 82fcde
Packit Service 82fcde
  if (intern->next == NULL)
Packit Service 82fcde
    /* Not one entry in the map.  */
Packit Service 82fcde
    return NSS_STATUS_NOTFOUND;
Packit Service 82fcde
Packit Service 82fcde
  /* Get the next entry until we found a correct one. */
Packit Service 82fcde
  do
Packit Service 82fcde
    {
Packit Service 82fcde
      struct response_t *bucket = intern->next;
Packit Service 82fcde
Packit Service 82fcde
      if (__glibc_unlikely (intern->offset >= bucket->size))
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (bucket->next == NULL)
Packit Service 82fcde
	    return NSS_STATUS_NOTFOUND;
Packit Service 82fcde
Packit Service 82fcde
	  /* We look at all the content in the current bucket.  Go on
Packit Service 82fcde
	     to the next.  */
Packit Service 82fcde
	  bucket = intern->next = bucket->next;
Packit Service 82fcde
	  intern->offset = 0;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      for (p = &bucket->mem[intern->offset]; isspace (*p); ++p)
Packit Service 82fcde
        ++intern->offset;
Packit Service 82fcde
Packit Service 82fcde
      size_t len = strlen (p) + 1;
Packit Service 82fcde
      if (__glibc_unlikely (len > buflen))
Packit Service 82fcde
	{
Packit Service 82fcde
	  *errnop = ERANGE;
Packit Service 82fcde
	  return NSS_STATUS_TRYAGAIN;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* We unfortunately have to copy the data in the user-provided
Packit Service 82fcde
	 buffer because that buffer might be around for a very long
Packit Service 82fcde
	 time and the servent structure must remain valid.  If we would
Packit Service 82fcde
	 rely on the BUCKET memory the next 'setservent' or 'endservent'
Packit Service 82fcde
	 call would destroy it.
Packit Service 82fcde
Packit Service 82fcde
	 The important thing is that it is a single NUL-terminated
Packit Service 82fcde
	 string.  This is what the parsing routine expects.  */
Packit Service 82fcde
      p = memcpy (buffer, &bucket->mem[intern->offset], len);
Packit Service 82fcde
Packit Service 82fcde
      parse_res = _nss_files_parse_rpcent (p, rpc, pdata, buflen, errnop);
Packit Service 82fcde
      if (__glibc_unlikely (parse_res == -1))
Packit Service 82fcde
	return NSS_STATUS_TRYAGAIN;
Packit Service 82fcde
Packit Service 82fcde
      intern->offset += len;
Packit Service 82fcde
    }
Packit Service 82fcde
  while (!parse_res);
Packit Service 82fcde
Packit Service 82fcde
  return NSS_STATUS_SUCCESS;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
enum nss_status
Packit Service 82fcde
_nss_nis_getrpcent_r (struct rpcent *rpc, char *buffer, size_t buflen,
Packit Service 82fcde
		      int *errnop)
Packit Service 82fcde
{
Packit Service 82fcde
  enum nss_status status;
Packit Service 82fcde
Packit Service 82fcde
  __libc_lock_lock (lock);
Packit Service 82fcde
Packit Service 82fcde
  status = internal_nis_getrpcent_r (rpc, buffer, buflen, errnop, &intern;;
Packit Service 82fcde
Packit Service 82fcde
  __libc_lock_unlock (lock);
Packit Service 82fcde
Packit Service 82fcde
  return status;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
enum nss_status
Packit Service 82fcde
_nss_nis_getrpcbyname_r (const char *name, struct rpcent *rpc,
Packit Service 82fcde
			 char *buffer, size_t buflen, int *errnop)
Packit Service 82fcde
{
Packit Service 82fcde
  if (name == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      *errnop = EINVAL;
Packit Service 82fcde
      return NSS_STATUS_UNAVAIL;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  intern_t data = { NULL, NULL, 0 };
Packit Service 82fcde
  enum nss_status status = internal_nis_setrpcent (&data);
Packit Service 82fcde
  if (__glibc_unlikely (status != NSS_STATUS_SUCCESS))
Packit Service 82fcde
    return status;
Packit Service 82fcde
Packit Service 82fcde
  int found = 0;
Packit Service 82fcde
  while (!found &&
Packit Service 82fcde
         ((status = internal_nis_getrpcent_r (rpc, buffer, buflen, errnop,
Packit Service 82fcde
					      &data)) == NSS_STATUS_SUCCESS))
Packit Service 82fcde
    {
Packit Service 82fcde
      if (strcmp (rpc->r_name, name) == 0)
Packit Service 82fcde
	found = 1;
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  int i = 0;
Packit Service 82fcde
Packit Service 82fcde
	  while (rpc->r_aliases[i] != NULL)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      if (strcmp (rpc->r_aliases[i], name) == 0)
Packit Service 82fcde
		{
Packit Service 82fcde
		  found = 1;
Packit Service 82fcde
		  break;
Packit Service 82fcde
		}
Packit Service 82fcde
	      else
Packit Service 82fcde
		++i;
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  internal_nis_endrpcent (&data);
Packit Service 82fcde
Packit Service 82fcde
  if (__glibc_unlikely (!found && status == NSS_STATUS_SUCCESS))
Packit Service 82fcde
    return NSS_STATUS_NOTFOUND;
Packit Service 82fcde
Packit Service 82fcde
  return status;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
enum nss_status
Packit Service 82fcde
_nss_nis_getrpcbynumber_r (int number, struct rpcent *rpc,
Packit Service 82fcde
			   char *buffer, size_t buflen, int *errnop)
Packit Service 82fcde
{
Packit Service 82fcde
  char *domain;
Packit Service 82fcde
  if (__glibc_unlikely (yp_get_default_domain (&domain)))
Packit Service 82fcde
    return NSS_STATUS_UNAVAIL;
Packit Service 82fcde
Packit Service 82fcde
  char buf[32];
Packit Service 82fcde
  int nlen = snprintf (buf, sizeof (buf), "%d", number);
Packit Service 82fcde
Packit Service 82fcde
  char *result;
Packit Service 82fcde
  int len;
Packit Service 82fcde
  int yperr = yp_match (domain, "rpc.bynumber", buf, nlen, &result, &len;;
Packit Service 82fcde
Packit Service 82fcde
  if (__glibc_unlikely (yperr != YPERR_SUCCESS))
Packit Service 82fcde
    {
Packit Service 82fcde
      enum nss_status retval = yperr2nss (yperr);
Packit Service 82fcde
Packit Service 82fcde
      if (retval == NSS_STATUS_TRYAGAIN)
Packit Service 82fcde
	*errnop = errno;
Packit Service 82fcde
      return retval;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (__glibc_unlikely ((size_t) (len + 1) > buflen))
Packit Service 82fcde
    {
Packit Service 82fcde
      free (result);
Packit Service 82fcde
      *errnop = ERANGE;
Packit Service 82fcde
      return NSS_STATUS_TRYAGAIN;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  char *p = strncpy (buffer, result, len);
Packit Service 82fcde
  buffer[len] = '\0';
Packit Service 82fcde
  while (isspace (*p))
Packit Service 82fcde
    ++p;
Packit Service 82fcde
  free (result);
Packit Service 82fcde
Packit Service 82fcde
  int parse_res = _nss_files_parse_rpcent (p, rpc, (void  *) buffer, buflen,
Packit Service 82fcde
					   errnop);
Packit Service 82fcde
  if (__glibc_unlikely (parse_res < 1))
Packit Service 82fcde
    {
Packit Service 82fcde
      if (parse_res == -1)
Packit Service 82fcde
	return NSS_STATUS_TRYAGAIN;
Packit Service 82fcde
      else
Packit Service 82fcde
	return NSS_STATUS_NOTFOUND;
Packit Service 82fcde
    }
Packit Service 82fcde
  else
Packit Service 82fcde
    return NSS_STATUS_SUCCESS;
Packit Service 82fcde
}