Blame nss/getent.c

Packit Service 82fcde
/* Copyright (c) 1998-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>, 1998.
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
/* getent: get entries from administrative database.  */
Packit Service 82fcde
Packit Service 82fcde
#include <aliases.h>
Packit Service 82fcde
#include <argp.h>
Packit Service 82fcde
#include <ctype.h>
Packit Service 82fcde
#include <error.h>
Packit Service 82fcde
#include <grp.h>
Packit Service 82fcde
#include <gshadow.h>
Packit Service 82fcde
#include <libintl.h>
Packit Service 82fcde
#include <locale.h>
Packit Service 82fcde
#include <mcheck.h>
Packit Service 82fcde
#include <netdb.h>
Packit Service 82fcde
#include <pwd.h>
Packit Service 82fcde
#include <shadow.h>
Packit Service 82fcde
#include <stdbool.h>
Packit Service 82fcde
#include <stdio.h>
Packit Service 82fcde
#include <stdlib.h>
Packit Service 82fcde
#include <string.h>
Packit Service 82fcde
#include <arpa/inet.h>
Packit Service 82fcde
#include <arpa/nameser.h>
Packit Service 82fcde
#include <netinet/ether.h>
Packit Service 82fcde
#include <netinet/in.h>
Packit Service 82fcde
#include <sys/socket.h>
Packit Service 82fcde
#include <scratch_buffer.h>
Packit Service 82fcde
Packit Service 82fcde
/* Get libc version number.  */
Packit Service 82fcde
#include <version.h>
Packit Service 82fcde
Packit Service 82fcde
#define PACKAGE _libc_intl_domainname
Packit Service 82fcde
Packit Service 82fcde
/* Name and version of program.  */
Packit Service 82fcde
static void print_version (FILE *stream, struct argp_state *state);
Packit Service 82fcde
void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
Packit Service 82fcde
Packit Service 82fcde
/* Short description of parameters.  */
Packit Service 82fcde
static const char args_doc[] = N_("database [key ...]");
Packit Service 82fcde
Packit Service 82fcde
/* Supported options. */
Packit Service 82fcde
static const struct argp_option args_options[] =
Packit Service 82fcde
  {
Packit Service 82fcde
    { "service", 's', N_("CONFIG"), 0, N_("Service configuration to be used") },
Packit Service 82fcde
    { "no-idn", 'i', NULL, 0, N_("disable IDN encoding") },
Packit Service 82fcde
    { NULL, 0, NULL, 0, NULL },
Packit Service 82fcde
  };
Packit Service 82fcde
Packit Service 82fcde
/* Short description of program.  */
Packit Service 82fcde
static const char doc[] = N_("Get entries from administrative database.");
Packit Service 82fcde
Packit Service 82fcde
/* Prototype for option handler.  */
Packit Service 82fcde
static error_t parse_option (int key, char *arg, struct argp_state *state);
Packit Service 82fcde
Packit Service 82fcde
/* Function to print some extra text in the help message.  */
Packit Service 82fcde
static char *more_help (int key, const char *text, void *input);
Packit Service 82fcde
Packit Service 82fcde
/* Data structure to communicate with argp functions.  */
Packit Service 82fcde
static struct argp argp =
Packit Service 82fcde
  {
Packit Service 82fcde
    args_options, parse_option, args_doc, doc, NULL, more_help
Packit Service 82fcde
  };
Packit Service 82fcde
Packit Service 82fcde
/* Additional getaddrinfo flags for IDN encoding.  */
Packit Service 82fcde
static int idn_flags = AI_IDN | AI_CANONIDN;
Packit Service 82fcde
Packit Service 82fcde
/* Print the version information.  */
Packit Service 82fcde
static void
Packit Service 82fcde
print_version (FILE *stream, struct argp_state *state)
Packit Service 82fcde
{
Packit Service 82fcde
  fprintf (stream, "getent %s%s\n", PKGVERSION, VERSION);
Packit Service 82fcde
  fprintf (stream, gettext ("\
Packit Service 82fcde
Copyright (C) %s Free Software Foundation, Inc.\n\
Packit Service 82fcde
This is free software; see the source for copying conditions.  There is NO\n\
Packit Service 82fcde
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
Packit Service 82fcde
"), "2018");
Packit Service 82fcde
  fprintf (stream, gettext ("Written by %s.\n"), "Thorsten Kukuk");
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* This is for aliases */
Packit Service 82fcde
static void
Packit Service 82fcde
print_aliases (struct aliasent *alias)
Packit Service 82fcde
{
Packit Service 82fcde
  unsigned int i = 0;
Packit Service 82fcde
Packit Service 82fcde
  printf ("%s: ", alias->alias_name);
Packit Service 82fcde
  for  (i = strlen (alias->alias_name); i < 14; ++i)
Packit Service 82fcde
    fputs_unlocked (" ", stdout);
Packit Service 82fcde
Packit Service 82fcde
  for (i = 0; i < alias->alias_members_len; ++i)
Packit Service 82fcde
    printf ("%s%s",
Packit Service 82fcde
	    alias->alias_members [i],
Packit Service 82fcde
	    i + 1 == alias->alias_members_len ? "\n" : ", ");
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
aliases_keys (int number, char *key[])
Packit Service 82fcde
{
Packit Service 82fcde
  int result = 0;
Packit Service 82fcde
  int i;
Packit Service 82fcde
  struct aliasent *alias;
Packit Service 82fcde
Packit Service 82fcde
  if (number == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      setaliasent ();
Packit Service 82fcde
      while ((alias = getaliasent ()) != NULL)
Packit Service 82fcde
	print_aliases (alias);
Packit Service 82fcde
      endaliasent ();
Packit Service 82fcde
      return result;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  for (i = 0; i < number; ++i)
Packit Service 82fcde
    {
Packit Service 82fcde
      alias = getaliasbyname (key[i]);
Packit Service 82fcde
Packit Service 82fcde
      if (alias == NULL)
Packit Service 82fcde
	result = 2;
Packit Service 82fcde
      else
Packit Service 82fcde
	print_aliases (alias);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* This is for ethers */
Packit Service 82fcde
static int
Packit Service 82fcde
ethers_keys (int number, char *key[])
Packit Service 82fcde
{
Packit Service 82fcde
  int result = 0;
Packit Service 82fcde
  int i;
Packit Service 82fcde
Packit Service 82fcde
  if (number == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      fprintf (stderr, _("Enumeration not supported on %s\n"), "ethers");
Packit Service 82fcde
      return 3;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  for (i = 0; i < number; ++i)
Packit Service 82fcde
    {
Packit Service 82fcde
      struct ether_addr *ethp, eth;
Packit Service 82fcde
      char buffer [1024], *p;
Packit Service 82fcde
Packit Service 82fcde
      ethp = ether_aton (key[i]);
Packit Service 82fcde
      if (ethp != NULL)
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (ether_ntohost (buffer, ethp))
Packit Service 82fcde
	    {
Packit Service 82fcde
	      result = 2;
Packit Service 82fcde
	      continue;
Packit Service 82fcde
	    }
Packit Service 82fcde
	  p = buffer;
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (ether_hostton (key[i], &eth))
Packit Service 82fcde
	    {
Packit Service 82fcde
	      result = 2;
Packit Service 82fcde
	      continue;
Packit Service 82fcde
	    }
Packit Service 82fcde
	  p = key[i];
Packit Service 82fcde
	  ethp = ð
Packit Service 82fcde
	}
Packit Service 82fcde
      printf ("%s %s\n", ether_ntoa (ethp), p);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* This is for group */
Packit Service 82fcde
static void
Packit Service 82fcde
print_group (struct group *grp)
Packit Service 82fcde
{
Packit Service 82fcde
  if (putgrent (grp, stdout) != 0)
Packit Service 82fcde
    fprintf (stderr, "error writing group entry: %m\n");
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
group_keys (int number, char *key[])
Packit Service 82fcde
{
Packit Service 82fcde
  int result = 0;
Packit Service 82fcde
  int i;
Packit Service 82fcde
  struct group *grp;
Packit Service 82fcde
Packit Service 82fcde
  if (number == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      setgrent ();
Packit Service 82fcde
      while ((grp = getgrent ()) != NULL)
Packit Service 82fcde
	print_group (grp);
Packit Service 82fcde
      endgrent ();
Packit Service 82fcde
      return result;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  for (i = 0; i < number; ++i)
Packit Service 82fcde
    {
Packit Service 82fcde
      errno = 0;
Packit Service 82fcde
      char *ep;
Packit Service 82fcde
      gid_t arg_gid = strtoul(key[i], &ep, 10);
Packit Service 82fcde
Packit Service 82fcde
      if (errno != EINVAL && *key[i] != '\0' && *ep == '\0')
Packit Service 82fcde
	/* Valid numeric gid.  */
Packit Service 82fcde
	grp = getgrgid (arg_gid);
Packit Service 82fcde
      else
Packit Service 82fcde
	grp = getgrnam (key[i]);
Packit Service 82fcde
Packit Service 82fcde
      if (grp == NULL)
Packit Service 82fcde
	result = 2;
Packit Service 82fcde
      else
Packit Service 82fcde
	print_group (grp);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* This is for gshadow */
Packit Service 82fcde
static void
Packit Service 82fcde
print_gshadow (struct sgrp *sg)
Packit Service 82fcde
{
Packit Service 82fcde
  if (putsgent (sg, stdout) != 0)
Packit Service 82fcde
    fprintf (stderr, "error writing gshadow entry: %m\n");
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
gshadow_keys (int number, char *key[])
Packit Service 82fcde
{
Packit Service 82fcde
  int result = 0;
Packit Service 82fcde
  int i;
Packit Service 82fcde
Packit Service 82fcde
  if (number == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      struct sgrp *sg;
Packit Service 82fcde
Packit Service 82fcde
      setsgent ();
Packit Service 82fcde
      while ((sg = getsgent ()) != NULL)
Packit Service 82fcde
	print_gshadow (sg);
Packit Service 82fcde
      endsgent ();
Packit Service 82fcde
      return result;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  for (i = 0; i < number; ++i)
Packit Service 82fcde
    {
Packit Service 82fcde
      struct sgrp *sg;
Packit Service 82fcde
Packit Service 82fcde
      sg = getsgnam (key[i]);
Packit Service 82fcde
Packit Service 82fcde
      if (sg == NULL)
Packit Service 82fcde
	result = 2;
Packit Service 82fcde
      else
Packit Service 82fcde
	print_gshadow (sg);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* This is for hosts */
Packit Service 82fcde
static void
Packit Service 82fcde
print_hosts (struct hostent *host)
Packit Service 82fcde
{
Packit Service 82fcde
  unsigned int cnt;
Packit Service 82fcde
Packit Service 82fcde
  for (cnt = 0; host->h_addr_list[cnt] != NULL; ++cnt)
Packit Service 82fcde
    {
Packit Service 82fcde
      char buf[INET6_ADDRSTRLEN];
Packit Service 82fcde
      const char *ip = inet_ntop (host->h_addrtype, host->h_addr_list[cnt],
Packit Service 82fcde
				  buf, sizeof (buf));
Packit Service 82fcde
Packit Service 82fcde
      printf ("%-15s %s", ip, host->h_name);
Packit Service 82fcde
Packit Service 82fcde
      unsigned int i;
Packit Service 82fcde
      for (i = 0; host->h_aliases[i] != NULL; ++i)
Packit Service 82fcde
	{
Packit Service 82fcde
	  putchar_unlocked (' ');
Packit Service 82fcde
	  fputs_unlocked (host->h_aliases[i], stdout);
Packit Service 82fcde
	}
Packit Service 82fcde
      putchar_unlocked ('\n');
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
hosts_keys (int number, char *key[])
Packit Service 82fcde
{
Packit Service 82fcde
  int result = 0;
Packit Service 82fcde
  int i;
Packit Service 82fcde
  struct hostent *host;
Packit Service 82fcde
Packit Service 82fcde
  if (number == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      sethostent (0);
Packit Service 82fcde
      while ((host = gethostent ()) != NULL)
Packit Service 82fcde
	print_hosts (host);
Packit Service 82fcde
      endhostent ();
Packit Service 82fcde
      return result;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  for (i = 0; i < number; ++i)
Packit Service 82fcde
    {
Packit Service 82fcde
      struct hostent *host = NULL;
Packit Service 82fcde
      char addr[IN6ADDRSZ];
Packit Service 82fcde
Packit Service 82fcde
      if (inet_pton (AF_INET6, key[i], &addr) > 0)
Packit Service 82fcde
	host = gethostbyaddr (addr, IN6ADDRSZ, AF_INET6);
Packit Service 82fcde
      else if (inet_pton (AF_INET, key[i], &addr) > 0)
Packit Service 82fcde
	host = gethostbyaddr (addr, INADDRSZ, AF_INET);
Packit Service 82fcde
      else if ((host = gethostbyname2 (key[i], AF_INET6)) == NULL)
Packit Service 82fcde
	host = gethostbyname2 (key[i], AF_INET);
Packit Service 82fcde
Packit Service 82fcde
      if (host == NULL)
Packit Service 82fcde
	result = 2;
Packit Service 82fcde
      else
Packit Service 82fcde
	print_hosts (host);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* This is for hosts, but using getaddrinfo */
Packit Service 82fcde
static int
Packit Service 82fcde
ahosts_keys_int (int af, int xflags, int number, char *key[])
Packit Service 82fcde
{
Packit Service 82fcde
  int result = 0;
Packit Service 82fcde
  int i;
Packit Service 82fcde
  struct hostent *host;
Packit Service 82fcde
Packit Service 82fcde
  if (number == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      sethostent (0);
Packit Service 82fcde
      while ((host = gethostent ()) != NULL)
Packit Service 82fcde
	print_hosts (host);
Packit Service 82fcde
      endhostent ();
Packit Service 82fcde
      return result;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  struct addrinfo hint;
Packit Service 82fcde
  memset (&hint, '\0', sizeof (hint));
Packit Service 82fcde
  hint.ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME
Packit Service 82fcde
		   | idn_flags | xflags);
Packit Service 82fcde
  hint.ai_family = af;
Packit Service 82fcde
Packit Service 82fcde
  for (i = 0; i < number; ++i)
Packit Service 82fcde
    {
Packit Service 82fcde
      struct addrinfo *res;
Packit Service 82fcde
Packit Service 82fcde
      if (getaddrinfo (key[i], NULL, &hint, &res) != 0)
Packit Service 82fcde
	result = 2;
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  struct addrinfo *runp = res;
Packit Service 82fcde
Packit Service 82fcde
	  while (runp != NULL)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      char sockbuf[20];
Packit Service 82fcde
	      const char *sockstr;
Packit Service 82fcde
	      if (runp->ai_socktype == SOCK_STREAM)
Packit Service 82fcde
		sockstr = "STREAM";
Packit Service 82fcde
	      else if (runp->ai_socktype == SOCK_DGRAM)
Packit Service 82fcde
		sockstr = "DGRAM";
Packit Service 82fcde
	      else if (runp->ai_socktype == SOCK_RAW)
Packit Service 82fcde
		sockstr = "RAW";
Packit Service 82fcde
#ifdef SOCK_SEQPACKET
Packit Service 82fcde
	      else if (runp->ai_socktype == SOCK_SEQPACKET)
Packit Service 82fcde
		sockstr = "SEQPACKET";
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifdef SOCK_RDM
Packit Service 82fcde
	      else if (runp->ai_socktype == SOCK_RDM)
Packit Service 82fcde
		sockstr = "RDM";
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifdef SOCK_DCCP
Packit Service 82fcde
	      else if (runp->ai_socktype == SOCK_DCCP)
Packit Service 82fcde
		sockstr = "DCCP";
Packit Service 82fcde
#endif
Packit Service 82fcde
#ifdef SOCK_PACKET
Packit Service 82fcde
	      else if (runp->ai_socktype == SOCK_PACKET)
Packit Service 82fcde
		sockstr = "PACKET";
Packit Service 82fcde
#endif
Packit Service 82fcde
	      else
Packit Service 82fcde
		{
Packit Service 82fcde
		  snprintf (sockbuf, sizeof (sockbuf), "%d",
Packit Service 82fcde
			    runp->ai_socktype);
Packit Service 82fcde
		  sockstr = sockbuf;
Packit Service 82fcde
		}
Packit Service 82fcde
Packit Service 82fcde
	      char buf[INET6_ADDRSTRLEN];
Packit Service 82fcde
	      printf ("%-15s %-6s %s\n",
Packit Service 82fcde
		      inet_ntop (runp->ai_family,
Packit Service 82fcde
				 runp->ai_family == AF_INET
Packit Service 82fcde
				 ? (void *) &((struct sockaddr_in *) runp->ai_addr)->sin_addr
Packit Service 82fcde
				 : (void *) &((struct sockaddr_in6 *) runp->ai_addr)->sin6_addr,
Packit Service 82fcde
				 buf, sizeof (buf)),
Packit Service 82fcde
		      sockstr,
Packit Service 82fcde
		      runp->ai_canonname ?: "");
Packit Service 82fcde
Packit Service 82fcde
	      runp = runp->ai_next;
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  freeaddrinfo (res);
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
ahosts_keys (int number, char *key[])
Packit Service 82fcde
{
Packit Service 82fcde
  return ahosts_keys_int (AF_UNSPEC, 0, number, key);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
ahostsv4_keys (int number, char *key[])
Packit Service 82fcde
{
Packit Service 82fcde
  return ahosts_keys_int (AF_INET, 0, number, key);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
ahostsv6_keys (int number, char *key[])
Packit Service 82fcde
{
Packit Service 82fcde
  return ahosts_keys_int (AF_INET6, AI_V4MAPPED, number, key);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* This is for netgroup */
Packit Service 82fcde
static int
Packit Service 82fcde
netgroup_keys (int number, char *key[])
Packit Service 82fcde
{
Packit Service 82fcde
  int result = 0;
Packit Service 82fcde
Packit Service 82fcde
  if (number == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      fprintf (stderr, _("Enumeration not supported on %s\n"), "netgroup");
Packit Service 82fcde
      return 3;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  if (number == 4)
Packit Service 82fcde
    {
Packit Service 82fcde
      char *host = strcmp (key[1], "*") == 0 ? NULL : key[1];
Packit Service 82fcde
      char *user = strcmp (key[2], "*") == 0 ? NULL : key[2];
Packit Service 82fcde
      char *domain = strcmp (key[3], "*") == 0 ? NULL : key[3];
Packit Service 82fcde
Packit Service 82fcde
      printf ("%-21s (%s,%s,%s) = %d\n",
Packit Service 82fcde
	      key[0], host ?: "", user ?: "", domain ?: "",
Packit Service 82fcde
	      innetgr (key[0], host, user, domain));
Packit Service 82fcde
    }
Packit Service 82fcde
  else if (number == 1)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (!setnetgrent (key[0]))
Packit Service 82fcde
	result = 2;
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  char *p[3];
Packit Service 82fcde
Packit Service 82fcde
	  printf ("%-21s", key[0]);
Packit Service 82fcde
Packit Service 82fcde
	  while (getnetgrent (p, p + 1, p + 2))
Packit Service 82fcde
	    printf (" (%s,%s,%s)", p[0] ?: " ", p[1] ?: "", p[2] ?: "");
Packit Service 82fcde
	  putchar_unlocked ('\n');
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  endnetgrent ();
Packit Service 82fcde
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#define DYNARRAY_STRUCT gid_list
Packit Service 82fcde
#define DYNARRAY_ELEMENT gid_t
Packit Service 82fcde
#define DYNARRAY_PREFIX gid_list_
Packit Service 82fcde
#define DYNARRAY_INITIAL_SIZE 10
Packit Service 82fcde
#include <malloc/dynarray-skeleton.c>
Packit Service 82fcde
Packit Service 82fcde
/* This is for initgroups */
Packit Service 82fcde
static int
Packit Service 82fcde
initgroups_keys (int number, char *key[])
Packit Service 82fcde
{
Packit Service 82fcde
  if (number == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      fprintf (stderr, _("Enumeration not supported on %s\n"), "initgroups");
Packit Service 82fcde
      return 3;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  struct gid_list list;
Packit Service 82fcde
  gid_list_init (&list);
Packit Service 82fcde
  if (!gid_list_resize (&list, 10))
Packit Service 82fcde
    {
Packit Service 82fcde
      fprintf (stderr, _("Could not allocate group list: %m\n"));
Packit Service 82fcde
      return 3;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  for (int i = 0; i < number; ++i)
Packit Service 82fcde
    {
Packit Service 82fcde
      int no = gid_list_size (&list);
Packit Service 82fcde
      int n;
Packit Service 82fcde
      while ((n = getgrouplist (key[i], -1, gid_list_begin (&list), &no)) == -1
Packit Service 82fcde
	     && no > gid_list_size (&list))
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (!gid_list_resize (&list, no))
Packit Service 82fcde
	    {
Packit Service 82fcde
	      fprintf (stderr, _("Could not allocate group list: %m\n"));
Packit Service 82fcde
	      return 3;
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      if (n == -1)
Packit Service 82fcde
	{
Packit Service 82fcde
	  gid_list_free (&list);
Packit Service 82fcde
	  return 1;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      const gid_t *grps = gid_list_begin (&list);
Packit Service 82fcde
      printf ("%-21s", key[i]);
Packit Service 82fcde
      for (int j = 0; j < n; ++j)
Packit Service 82fcde
	if (grps[j] != -1)
Packit Service 82fcde
	  printf (" %ld", (long int) grps[j]);
Packit Service 82fcde
      putchar_unlocked ('\n');
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  gid_list_free (&list);
Packit Service 82fcde
Packit Service 82fcde
  return 0;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* This is for networks */
Packit Service 82fcde
static void
Packit Service 82fcde
print_networks (struct netent *net)
Packit Service 82fcde
{
Packit Service 82fcde
  unsigned int i;
Packit Service 82fcde
  struct in_addr ip;
Packit Service 82fcde
  ip.s_addr = htonl (net->n_net);
Packit Service 82fcde
Packit Service 82fcde
  printf ("%-21s %s", net->n_name, inet_ntoa (ip));
Packit Service 82fcde
Packit Service 82fcde
  i = 0;
Packit Service 82fcde
  while (net->n_aliases[i] != NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      putchar_unlocked (' ');
Packit Service 82fcde
      fputs_unlocked (net->n_aliases[i], stdout);
Packit Service 82fcde
      ++i;
Packit Service 82fcde
    }
Packit Service 82fcde
  putchar_unlocked ('\n');
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
networks_keys (int number, char *key[])
Packit Service 82fcde
{
Packit Service 82fcde
  int result = 0;
Packit Service 82fcde
  int i;
Packit Service 82fcde
  struct netent *net;
Packit Service 82fcde
Packit Service 82fcde
  if (number == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      setnetent (0);
Packit Service 82fcde
      while ((net = getnetent ()) != NULL)
Packit Service 82fcde
	print_networks (net);
Packit Service 82fcde
      endnetent ();
Packit Service 82fcde
      return result;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  for (i = 0; i < number; ++i)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (isdigit (key[i][0]))
Packit Service 82fcde
	net = getnetbyaddr (ntohl (inet_addr (key[i])), AF_UNSPEC);
Packit Service 82fcde
      else
Packit Service 82fcde
	net = getnetbyname (key[i]);
Packit Service 82fcde
Packit Service 82fcde
      if (net == NULL)
Packit Service 82fcde
	result = 2;
Packit Service 82fcde
      else
Packit Service 82fcde
	print_networks (net);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* Now is all for passwd */
Packit Service 82fcde
static void
Packit Service 82fcde
print_passwd (struct passwd *pwd)
Packit Service 82fcde
{
Packit Service 82fcde
  if (putpwent (pwd, stdout) != 0)
Packit Service 82fcde
    fprintf (stderr, "error writing passwd entry: %m\n");
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
passwd_keys (int number, char *key[])
Packit Service 82fcde
{
Packit Service 82fcde
  int result = 0;
Packit Service 82fcde
  int i;
Packit Service 82fcde
  struct passwd *pwd;
Packit Service 82fcde
Packit Service 82fcde
  if (number == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      setpwent ();
Packit Service 82fcde
      while ((pwd = getpwent ()) != NULL)
Packit Service 82fcde
	print_passwd (pwd);
Packit Service 82fcde
      endpwent ();
Packit Service 82fcde
      return result;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  for (i = 0; i < number; ++i)
Packit Service 82fcde
    {
Packit Service 82fcde
      errno = 0;
Packit Service 82fcde
      char *ep;
Packit Service 82fcde
      uid_t arg_uid = strtoul(key[i], &ep, 10);
Packit Service 82fcde
Packit Service 82fcde
      if (errno != EINVAL && *key[i] != '\0' && *ep == '\0')
Packit Service 82fcde
	/* Valid numeric uid.  */
Packit Service 82fcde
	pwd = getpwuid (arg_uid);
Packit Service 82fcde
      else
Packit Service 82fcde
	pwd = getpwnam (key[i]);
Packit Service 82fcde
Packit Service 82fcde
      if (pwd == NULL)
Packit Service 82fcde
	result = 2;
Packit Service 82fcde
      else
Packit Service 82fcde
	print_passwd (pwd);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* This is for protocols */
Packit Service 82fcde
static void
Packit Service 82fcde
print_protocols (struct protoent *proto)
Packit Service 82fcde
{
Packit Service 82fcde
  unsigned int i;
Packit Service 82fcde
Packit Service 82fcde
  printf ("%-21s %d", proto->p_name, proto->p_proto);
Packit Service 82fcde
Packit Service 82fcde
  i = 0;
Packit Service 82fcde
  while (proto->p_aliases[i] != NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      putchar_unlocked (' ');
Packit Service 82fcde
      fputs_unlocked (proto->p_aliases[i], stdout);
Packit Service 82fcde
      ++i;
Packit Service 82fcde
    }
Packit Service 82fcde
  putchar_unlocked ('\n');
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
protocols_keys (int number, char *key[])
Packit Service 82fcde
{
Packit Service 82fcde
  int result = 0;
Packit Service 82fcde
  int i;
Packit Service 82fcde
  struct protoent *proto;
Packit Service 82fcde
Packit Service 82fcde
  if (number == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      setprotoent (0);
Packit Service 82fcde
      while ((proto = getprotoent ()) != NULL)
Packit Service 82fcde
	print_protocols (proto);
Packit Service 82fcde
      endprotoent ();
Packit Service 82fcde
      return result;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  for (i = 0; i < number; ++i)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (isdigit (key[i][0]))
Packit Service 82fcde
	proto = getprotobynumber (atol (key[i]));
Packit Service 82fcde
      else
Packit Service 82fcde
	proto = getprotobyname (key[i]);
Packit Service 82fcde
Packit Service 82fcde
      if (proto == NULL)
Packit Service 82fcde
	result = 2;
Packit Service 82fcde
      else
Packit Service 82fcde
	print_protocols (proto);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#if HAVE_SUNRPC
Packit Service 82fcde
/* Now is all for rpc */
Packit Service 82fcde
static void
Packit Service 82fcde
print_rpc (struct rpcent *rpc)
Packit Service 82fcde
{
Packit Service 82fcde
  int i;
Packit Service 82fcde
Packit Service 82fcde
  printf ("%-15s %d%s",
Packit Service 82fcde
	  rpc->r_name, rpc->r_number, rpc->r_aliases[0] ? " " : "");
Packit Service 82fcde
Packit Service 82fcde
  for (i = 0; rpc->r_aliases[i]; ++i)
Packit Service 82fcde
    printf (" %s", rpc->r_aliases[i]);
Packit Service 82fcde
  putchar_unlocked ('\n');
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
rpc_keys (int number, char *key[])
Packit Service 82fcde
{
Packit Service 82fcde
  int result = 0;
Packit Service 82fcde
  int i;
Packit Service 82fcde
  struct rpcent *rpc;
Packit Service 82fcde
Packit Service 82fcde
  if (number == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      setrpcent (0);
Packit Service 82fcde
      while ((rpc = getrpcent ()) != NULL)
Packit Service 82fcde
	print_rpc (rpc);
Packit Service 82fcde
      endrpcent ();
Packit Service 82fcde
      return result;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  for (i = 0; i < number; ++i)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (isdigit (key[i][0]))
Packit Service 82fcde
	rpc = getrpcbynumber (atol (key[i]));
Packit Service 82fcde
      else
Packit Service 82fcde
	rpc = getrpcbyname (key[i]);
Packit Service 82fcde
Packit Service 82fcde
      if (rpc == NULL)
Packit Service 82fcde
	result = 2;
Packit Service 82fcde
      else
Packit Service 82fcde
	print_rpc (rpc);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* for services */
Packit Service 82fcde
static void
Packit Service 82fcde
print_services (struct servent *serv)
Packit Service 82fcde
{
Packit Service 82fcde
  unsigned int i;
Packit Service 82fcde
Packit Service 82fcde
  printf ("%-21s %d/%s", serv->s_name, ntohs (serv->s_port), serv->s_proto);
Packit Service 82fcde
Packit Service 82fcde
  i = 0;
Packit Service 82fcde
  while (serv->s_aliases[i] != NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      putchar_unlocked (' ');
Packit Service 82fcde
      fputs_unlocked (serv->s_aliases[i], stdout);
Packit Service 82fcde
      ++i;
Packit Service 82fcde
    }
Packit Service 82fcde
  putchar_unlocked ('\n');
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
services_keys (int number, char *key[])
Packit Service 82fcde
{
Packit Service 82fcde
  int result = 0;
Packit Service 82fcde
  int i;
Packit Service 82fcde
  struct servent *serv;
Packit Service 82fcde
Packit Service 82fcde
  if (!number)
Packit Service 82fcde
    {
Packit Service 82fcde
      setservent (0);
Packit Service 82fcde
      while ((serv = getservent ()) != NULL)
Packit Service 82fcde
	print_services (serv);
Packit Service 82fcde
      endservent ();
Packit Service 82fcde
      return result;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  for (i = 0; i < number; ++i)
Packit Service 82fcde
    {
Packit Service 82fcde
      struct servent *serv;
Packit Service 82fcde
      char *proto = strchr (key[i], '/');
Packit Service 82fcde
Packit Service 82fcde
      if (proto != NULL)
Packit Service 82fcde
	*proto++ = '\0';
Packit Service 82fcde
Packit Service 82fcde
      char *endptr;
Packit Service 82fcde
      long port = strtol (key[i], &endptr, 10);
Packit Service 82fcde
Packit Service 82fcde
      if (isdigit (key[i][0]) && *endptr == '\0'
Packit Service 82fcde
	  && 0 <= port && port <= 65535)
Packit Service 82fcde
	serv = getservbyport (htons (port), proto);
Packit Service 82fcde
      else
Packit Service 82fcde
	serv = getservbyname (key[i], proto);
Packit Service 82fcde
Packit Service 82fcde
      if (serv == NULL)
Packit Service 82fcde
	result = 2;
Packit Service 82fcde
      else
Packit Service 82fcde
	print_services (serv);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
/* This is for shadow */
Packit Service 82fcde
static void
Packit Service 82fcde
print_shadow (struct spwd *sp)
Packit Service 82fcde
{
Packit Service 82fcde
  if (putspent (sp, stdout) != 0)
Packit Service 82fcde
    fprintf (stderr, "error writing shadow entry: %m\n");
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
shadow_keys (int number, char *key[])
Packit Service 82fcde
{
Packit Service 82fcde
  int result = 0;
Packit Service 82fcde
  int i;
Packit Service 82fcde
Packit Service 82fcde
  if (number == 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      struct spwd *sp;
Packit Service 82fcde
Packit Service 82fcde
      setspent ();
Packit Service 82fcde
      while ((sp = getspent ()) != NULL)
Packit Service 82fcde
	print_shadow (sp);
Packit Service 82fcde
      endspent ();
Packit Service 82fcde
      return result;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  for (i = 0; i < number; ++i)
Packit Service 82fcde
    {
Packit Service 82fcde
      struct spwd *sp;
Packit Service 82fcde
Packit Service 82fcde
      sp = getspnam (key[i]);
Packit Service 82fcde
Packit Service 82fcde
      if (sp == NULL)
Packit Service 82fcde
	result = 2;
Packit Service 82fcde
      else
Packit Service 82fcde
	print_shadow (sp);
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
struct
Packit Service 82fcde
  {
Packit Service 82fcde
    const char *name;
Packit Service 82fcde
    int (*func) (int number, char *key[]);
Packit Service 82fcde
  } databases[] =
Packit Service 82fcde
  {
Packit Service 82fcde
#define D(name) { #name, name ## _keys },
Packit Service 82fcde
D(ahosts)
Packit Service 82fcde
D(ahostsv4)
Packit Service 82fcde
D(ahostsv6)
Packit Service 82fcde
D(aliases)
Packit Service 82fcde
D(ethers)
Packit Service 82fcde
D(group)
Packit Service 82fcde
D(gshadow)
Packit Service 82fcde
D(hosts)
Packit Service 82fcde
D(initgroups)
Packit Service 82fcde
D(netgroup)
Packit Service 82fcde
D(networks)
Packit Service 82fcde
D(passwd)
Packit Service 82fcde
D(protocols)
Packit Service 82fcde
#if HAVE_SUNRPC
Packit Service 82fcde
D(rpc)
Packit Service 82fcde
#endif
Packit Service 82fcde
D(services)
Packit Service 82fcde
D(shadow)
Packit Service 82fcde
#undef D
Packit Service 82fcde
    { NULL, NULL }
Packit Service 82fcde
  };
Packit Service 82fcde
Packit Service 82fcde
/* Handle arguments found by argp. */
Packit Service 82fcde
static error_t
Packit Service 82fcde
parse_option (int key, char *arg, struct argp_state *state)
Packit Service 82fcde
{
Packit Service 82fcde
  char *endp;
Packit Service 82fcde
  switch (key)
Packit Service 82fcde
    {
Packit Service 82fcde
    case 's':
Packit Service 82fcde
      endp = strchr (arg, ':');
Packit Service 82fcde
      if (endp == NULL)
Packit Service 82fcde
	/* No specific database, change them all.  */
Packit Service 82fcde
	for (int i = 0; databases[i].name != NULL; ++i)
Packit Service 82fcde
	  __nss_configure_lookup (databases[i].name, arg);
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  int i;
Packit Service 82fcde
	  for (i = 0; databases[i].name != NULL; ++i)
Packit Service 82fcde
	    if (strncmp (databases[i].name, arg, endp - arg) == 0)
Packit Service 82fcde
	      {
Packit Service 82fcde
		__nss_configure_lookup (databases[i].name, endp + 1);
Packit Service 82fcde
		break;
Packit Service 82fcde
	      }
Packit Service 82fcde
	  if (databases[i].name == NULL)
Packit Service 82fcde
	    error (EXIT_FAILURE, 0, gettext ("Unknown database name"));
Packit Service 82fcde
	}
Packit Service 82fcde
      break;
Packit Service 82fcde
Packit Service 82fcde
    case 'i':
Packit Service 82fcde
      idn_flags = 0;
Packit Service 82fcde
      break;
Packit Service 82fcde
Packit Service 82fcde
    default:
Packit Service 82fcde
      return ARGP_ERR_UNKNOWN;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  return 0;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
static char *
Packit Service 82fcde
more_help (int key, const char *text, void *input)
Packit Service 82fcde
{
Packit Service 82fcde
  switch (key)
Packit Service 82fcde
    {
Packit Service 82fcde
      size_t len;
Packit Service 82fcde
      char *doc;
Packit Service 82fcde
      FILE *fp;
Packit Service 82fcde
Packit Service 82fcde
    case ARGP_KEY_HELP_EXTRA:
Packit Service 82fcde
      /* We print some extra information.  */
Packit Service 82fcde
      fp = open_memstream (&doc, &len;;
Packit Service 82fcde
      if (fp != NULL)
Packit Service 82fcde
	{
Packit Service 82fcde
	  fputs_unlocked (_("Supported databases:\n"), fp);
Packit Service 82fcde
Packit Service 82fcde
	  for (int i = 0, col = 0; databases[i].name != NULL; ++i)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      len = strlen (databases[i].name);
Packit Service 82fcde
	      if (i != 0)
Packit Service 82fcde
		{
Packit Service 82fcde
		  if (col + len > 72)
Packit Service 82fcde
		    {
Packit Service 82fcde
		      col = 0;
Packit Service 82fcde
		      fputc_unlocked ('\n', fp);
Packit Service 82fcde
		    }
Packit Service 82fcde
		  else
Packit Service 82fcde
		    fputc_unlocked (' ', fp);
Packit Service 82fcde
		}
Packit Service 82fcde
Packit Service 82fcde
	      fputs_unlocked (databases[i].name, fp);
Packit Service 82fcde
	      col += len + 1;
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  fputs ("\n\n", fp);
Packit Service 82fcde
Packit Service 82fcde
	  fprintf (fp, gettext ("\
Packit Service 82fcde
For bug reporting instructions, please see:\n\
Packit Service 82fcde
%s.\n"), REPORT_BUGS_TO);
Packit Service 82fcde
Packit Service 82fcde
	  if (fclose (fp) == 0)
Packit Service 82fcde
	    return doc;
Packit Service 82fcde
	}
Packit Service 82fcde
      break;
Packit Service 82fcde
Packit Service 82fcde
    default:
Packit Service 82fcde
      break;
Packit Service 82fcde
    }
Packit Service 82fcde
  return (char *) text;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* the main function */
Packit Service 82fcde
int
Packit Service 82fcde
main (int argc, char *argv[])
Packit Service 82fcde
{
Packit Service 82fcde
  /* Debugging support.  */
Packit Service 82fcde
  mtrace ();
Packit Service 82fcde
Packit Service 82fcde
  /* Set locale via LC_ALL.  */
Packit Service 82fcde
  setlocale (LC_ALL, "");
Packit Service 82fcde
  /* Set the text message domain.  */
Packit Service 82fcde
  textdomain (PACKAGE);
Packit Service 82fcde
Packit Service 82fcde
  /* Parse and process arguments.  */
Packit Service 82fcde
  int remaining;
Packit Service 82fcde
  argp_parse (&argp, argc, argv, 0, &remaining, NULL);
Packit Service 82fcde
Packit Service 82fcde
  if ((argc - remaining) < 1)
Packit Service 82fcde
    {
Packit Service 82fcde
      error (0, 0, gettext ("wrong number of arguments"));
Packit Service 82fcde
      argp_help (&argp, stdout, ARGP_HELP_SEE, program_invocation_short_name);
Packit Service 82fcde
      return 1;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  for (int i = 0; databases[i].name; ++i)
Packit Service 82fcde
    if (argv[remaining][0] == databases[i].name[0]
Packit Service 82fcde
	&& !strcmp (argv[remaining], databases[i].name))
Packit Service 82fcde
      return databases[i].func (argc - remaining - 1, &argv[remaining + 1]);
Packit Service 82fcde
Packit Service 82fcde
  fprintf (stderr, _("Unknown database: %s\n"), argv[remaining]);
Packit Service 82fcde
  argp_help (&argp, stdout, ARGP_HELP_SEE, program_invocation_short_name);
Packit Service 82fcde
  return 1;
Packit Service 82fcde
}