Blame nss/ethers.c

Packit 6bd9ab
/*
Packit 6bd9ab
   ethers.c - NSS lookup functions for ethers database
Packit 6bd9ab
Packit 6bd9ab
   Copyright (C) 2006 West Consulting
Packit 6bd9ab
   Copyright (C) 2006-2015 Arthur de Jong
Packit 6bd9ab
   Copyright (C) 2010 Symas Corporation
Packit 6bd9ab
Packit 6bd9ab
   This library is free software; you can redistribute it and/or
Packit 6bd9ab
   modify it under the terms of the GNU Lesser General Public
Packit 6bd9ab
   License as published by the Free Software Foundation; either
Packit 6bd9ab
   version 2.1 of the License, or (at your option) any later version.
Packit 6bd9ab
Packit 6bd9ab
   This library is distributed in the hope that it will be useful,
Packit 6bd9ab
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6bd9ab
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6bd9ab
   Lesser General Public License for more details.
Packit 6bd9ab
Packit 6bd9ab
   You should have received a copy of the GNU Lesser General Public
Packit 6bd9ab
   License along with this library; if not, write to the Free Software
Packit 6bd9ab
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit 6bd9ab
   02110-1301 USA
Packit 6bd9ab
*/
Packit 6bd9ab
Packit 6bd9ab
#include "config.h"
Packit 6bd9ab
Packit 6bd9ab
#include <string.h>
Packit 6bd9ab
#include <errno.h>
Packit 6bd9ab
Packit 6bd9ab
#include "prototypes.h"
Packit 6bd9ab
#include "common.h"
Packit 6bd9ab
#include "compat/attrs.h"
Packit 6bd9ab
Packit 6bd9ab
/* read an ethernet entry from the stream */
Packit 6bd9ab
static nss_status_t read_etherent(TFILE *fp, struct etherent *result,
Packit 6bd9ab
                                  char *buffer, size_t buflen, int *errnop)
Packit 6bd9ab
{
Packit 6bd9ab
  int32_t tmpint32;
Packit 6bd9ab
  size_t bufptr = 0;
Packit 6bd9ab
  memset(result, 0, sizeof(struct etherent));
Packit 6bd9ab
  READ_BUF_STRING(fp, result->e_name);
Packit 6bd9ab
  READ(fp, &(result->e_addr), sizeof(uint8_t[6]));
Packit 6bd9ab
  return NSS_STATUS_SUCCESS;
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
#ifdef NSS_FLAVOUR_GLIBC
Packit 6bd9ab
Packit 6bd9ab
/* map a hostname to the corresponding ethernet address */
Packit 6bd9ab
nss_status_t NSS_NAME(gethostton_r)(const char *name,
Packit 6bd9ab
                                    struct etherent *result, char *buffer,
Packit 6bd9ab
                                    size_t buflen, int *errnop)
Packit 6bd9ab
{
Packit 6bd9ab
  NSS_GETONE(NSLCD_ACTION_ETHER_BYNAME,
Packit 6bd9ab
             WRITE_STRING(fp, name),
Packit 6bd9ab
             read_etherent(fp, result, buffer, buflen, errnop));
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
/* map an ethernet address to the corresponding hostname */
Packit 6bd9ab
nss_status_t NSS_NAME(getntohost_r)(const struct ether_addr *addr,
Packit 6bd9ab
                                    struct etherent *result, char *buffer,
Packit 6bd9ab
                                    size_t buflen, int *errnop)
Packit 6bd9ab
{
Packit 6bd9ab
  NSS_GETONE(NSLCD_ACTION_ETHER_BYETHER,
Packit 6bd9ab
             WRITE(fp, addr, sizeof(uint8_t[6])),
Packit 6bd9ab
             read_etherent(fp, result, buffer, buflen, errnop));
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
/* thread-local file pointer to an ongoing request */
Packit 6bd9ab
static TLS TFILE *etherentfp;
Packit 6bd9ab
Packit 6bd9ab
/* open a connection to read all ether entries */
Packit 6bd9ab
nss_status_t NSS_NAME(setetherent)(int UNUSED(stayopen))
Packit 6bd9ab
{
Packit 6bd9ab
  NSS_SETENT(etherentfp);
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
/* read a single ethernet entry from the stream */
Packit 6bd9ab
nss_status_t NSS_NAME(getetherent_r)(struct etherent *result,
Packit 6bd9ab
                                     char *buffer, size_t buflen, int *errnop)
Packit 6bd9ab
{
Packit 6bd9ab
  NSS_GETENT(etherentfp, NSLCD_ACTION_ETHER_ALL,
Packit 6bd9ab
             read_etherent(etherentfp, result, buffer, buflen, errnop));
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
/* close the stream opened with setetherent() above */
Packit 6bd9ab
nss_status_t NSS_NAME(endetherent)(void)
Packit 6bd9ab
{
Packit 6bd9ab
  NSS_ENDENT(etherentfp);
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
#endif /* NSS_FLAVOUR_GLIBC */
Packit 6bd9ab
Packit 6bd9ab
#ifdef NSS_FLAVOUR_SOLARIS
Packit 6bd9ab
Packit 6bd9ab
/* we disable NSS_BUFCHECK because these functions do not use the buffer */
Packit 6bd9ab
#undef NSS_BUFCHECK
Packit 6bd9ab
#define NSS_BUFCHECK ;
Packit 6bd9ab
Packit 6bd9ab
/* provide a fallback definition */
Packit 6bd9ab
#ifndef NSS_BUFLEN_ETHERS
Packit 6bd9ab
#define NSS_BUFLEN_ETHERS HOST_NAME_MAX
Packit 6bd9ab
#endif /* NSS_BUFLEN_ETHERS */
Packit 6bd9ab
Packit 6bd9ab
#ifdef HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN
Packit 6bd9ab
static char *etherent2str(struct etherent *result, char *buffer,
Packit 6bd9ab
                          size_t buflen)
Packit 6bd9ab
{
Packit 6bd9ab
  int res;
Packit 6bd9ab
  res = snprintf(buffer, buflen, "%s %s", ether_ntoa(&result->e_addr),
Packit 6bd9ab
                 result->e_name);
Packit 6bd9ab
  if ((res < 0) || (res >= (int)buflen))
Packit 6bd9ab
    return NULL;
Packit 6bd9ab
  return buffer;
Packit 6bd9ab
}
Packit 6bd9ab
#endif /* HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN */
Packit 6bd9ab
Packit 6bd9ab
static nss_status_t read_result(TFILE *fp, nss_XbyY_args_t *args, int wantname)
Packit 6bd9ab
{
Packit 6bd9ab
  struct etherent result;
Packit 6bd9ab
  char buffer[NSS_BUFLEN_ETHERS];
Packit 6bd9ab
  nss_status_t retv;
Packit 6bd9ab
  /* read the result entry from the stream */
Packit 6bd9ab
  retv = read_etherent(fp, &result, buffer, sizeof(buffer), &args->erange);
Packit 6bd9ab
  if (retv != NSS_STATUS_SUCCESS)
Packit 6bd9ab
    return retv;
Packit 6bd9ab
#ifdef HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN
Packit 6bd9ab
  /* try to return in string format if requested */
Packit 6bd9ab
  if ((args->buf.buffer != NULL) && (args->buf.buflen > 0))
Packit 6bd9ab
  {
Packit 6bd9ab
    if (etherent2str(&result, args->buf.buffer, args->buf.buflen) == NULL)
Packit 6bd9ab
    {
Packit 6bd9ab
      args->erange = 1;
Packit 6bd9ab
      return NSS_NOTFOUND;
Packit 6bd9ab
    }
Packit 6bd9ab
    args->returnval = args->buf.buffer;
Packit 6bd9ab
    args->returnlen = strlen(args->returnval);
Packit 6bd9ab
    return NSS_SUCCESS;
Packit 6bd9ab
  }
Packit 6bd9ab
#endif /* HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN */
Packit 6bd9ab
  /* return the result entry */
Packit 6bd9ab
  if (wantname)
Packit 6bd9ab
  {
Packit 6bd9ab
    /* we expect the buffer to have enough room for the name (buflen == 0) */
Packit 6bd9ab
    strcpy(args->buf.buffer, result.e_name);
Packit 6bd9ab
    args->returnval = args->buf.buffer;
Packit 6bd9ab
  }
Packit 6bd9ab
  else /* address */
Packit 6bd9ab
  {
Packit 6bd9ab
    memcpy(args->buf.result, &result.e_addr, sizeof(result.e_addr));
Packit 6bd9ab
    args->returnval = args->buf.result;
Packit 6bd9ab
  }
Packit 6bd9ab
  return NSS_SUCCESS;
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
/* map a hostname to the corresponding ethernet address */
Packit 6bd9ab
static nss_status_t ethers_gethostton(nss_backend_t UNUSED(*be), void *args)
Packit 6bd9ab
{
Packit 6bd9ab
  NSS_GETONE(NSLCD_ACTION_ETHER_BYNAME,
Packit 6bd9ab
             WRITE_STRING(fp, NSS_ARGS(args)->key.name),
Packit 6bd9ab
             read_result(fp, args, 0));
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
/* map an ethernet address to the corresponding hostname */
Packit 6bd9ab
static nss_status_t ethers_getntohost(nss_backend_t UNUSED(*be), void *args)
Packit 6bd9ab
{
Packit 6bd9ab
  struct ether_addr *addr = (struct ether_addr *)(NSS_ARGS(args)->key.ether);
Packit 6bd9ab
  NSS_GETONE(NSLCD_ACTION_ETHER_BYETHER,
Packit 6bd9ab
             WRITE(fp, addr, sizeof(uint8_t[6])),
Packit 6bd9ab
             read_result(fp, args, 1));
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static nss_backend_op_t ethers_ops[] = {
Packit 6bd9ab
  nss_ldap_destructor,
Packit 6bd9ab
  ethers_gethostton,
Packit 6bd9ab
  ethers_getntohost
Packit 6bd9ab
};
Packit 6bd9ab
Packit 6bd9ab
nss_backend_t *NSS_NAME(ethers_constr)(const char UNUSED(*db_name),
Packit 6bd9ab
                                       const char UNUSED(*src_name),
Packit 6bd9ab
                                       const char UNUSED(*cfg_args))
Packit 6bd9ab
{
Packit 6bd9ab
  return nss_ldap_constructor(ethers_ops, sizeof(ethers_ops));
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
#endif /* NSS_FLAVOUR_SOLARIS */