/* Copyright (C) 1996, 1997, 1998, 1999, 2002, 2004, 2005, 2007
   Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <assert.h>
#include <atomic.h>
#include <bits/libc-lock.h>
#include <errno.h>
#include <netdb.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include "netgroup.h"
#include "nsswitch.h"
#include <sysdep.h>


/* Protect above variable against multiple uses at the same time.  */
__libc_lock_define_initialized (static, lock)

/* The whole information for the set/get/endnetgrent functions are
   kept in this structure.  */
static struct __netgrent dataset;

/* The lookup function for the first entry of this service.  */
extern int __nss_netgroup_lookup (service_user **nipp, const char *name,
				  void **fctp) internal_function;

/* Set up NIP to run through the services.  Return nonzero if there are no
   services (left).  */
static int
setup (void **fctp, service_user **nipp)
{
  /* Remember the first service_entry, it's always the same.  */
  static bool startp_initialized;
  static service_user *startp;
  int no_more;

  if (!startp_initialized)
    {
      /* Executing this more than once at the same time must yield the
	 same result every time.  So we need no locking.  */
      no_more = __nss_netgroup_lookup (nipp, "setnetgrent", fctp);
      startp = no_more ? (service_user *) -1 : *nipp;
      PTR_MANGLE (startp);
      atomic_write_barrier ();
      startp_initialized = true;
    }
  else
    {
      service_user *nip = startp;
      PTR_DEMANGLE (nip);
      if (nip == (service_user *) -1)
	/* No services at all.  */
	return 1;

      /* Reset to the beginning of the service list.  */
      *nipp = nip;
      /* Look up the first function.  */
      no_more = __nss_lookup (nipp, "setnetgrent", NULL, fctp);
    }
  return no_more;
}

/* Free used memory.  */
static void
free_memory (struct __netgrent *data)
{
  while (data->known_groups != NULL)
    {
      struct name_list *tmp = data->known_groups;
      data->known_groups = data->known_groups->next;
      free (tmp);
    }

  while (data->needed_groups != NULL)
    {
      struct name_list *tmp = data->needed_groups;
      data->needed_groups = data->needed_groups->next;
      free (tmp);
    }
}

static void
endnetgrent_hook (struct __netgrent *datap)
{
  enum nss_status (*endfct) (struct __netgrent *);

  if (datap->nip == NULL)
    return;

  endfct = __nss_lookup_function (datap->nip, "endnetgrent");
  if (endfct != NULL)
    (void) (*endfct) (datap);
  datap->nip = NULL;
}

static int
internal_function
__internal_setnetgrent_reuse (const char *group, struct __netgrent *datap,
			      int *errnop)
{
  union
  {
    enum nss_status (*f) (const char *, struct __netgrent *);
    void *ptr;
  } fct;
  enum nss_status status = NSS_STATUS_UNAVAIL;
  struct name_list *new_elem;

  /* Free data from previous service.  */
  endnetgrent_hook (datap);

  /* Cycle through all the services and run their setnetgrent functions.  */
  int no_more = setup (&fct.ptr, &datap->nip);
  while (! no_more)
    {
      assert (datap->data == NULL);

      /* Ignore status, we force check in `__nss_next2'.  */
      status = (*fct.f) (group, datap);

      service_user *old_nip = datap->nip;
      no_more = __nss_next2 (&datap->nip, "setnetgrent", NULL, &fct.ptr,
			     status, 0);

      if (status == NSS_STATUS_SUCCESS && ! no_more)
	{
	  enum nss_status (*endfct) (struct __netgrent *);

	  endfct = __nss_lookup_function (old_nip, "endnetgrent");
	  if (endfct != NULL)
	    (void) (*endfct) (datap);
	}
    }

  /* Add the current group to the list of known groups.  */
  size_t group_len = strlen (group) + 1;
  new_elem = (struct name_list *) malloc (sizeof (struct name_list)
					  + group_len);
  if (new_elem == NULL)
    {
      *errnop = errno;
      status = NSS_STATUS_TRYAGAIN;
    }
  else
    {
      new_elem->next = datap->known_groups;
      memcpy (new_elem->name, group, group_len);
      datap->known_groups = new_elem;
    }

  return status == NSS_STATUS_SUCCESS;
}

int internal_setnetgrent (const char *group, struct __netgrent *datap);
libc_hidden_proto (internal_setnetgrent)

int
internal_setnetgrent (const char *group, struct __netgrent *datap)
{
  /* Free list of all netgroup names from last run.  */
  free_memory (datap);

  return __internal_setnetgrent_reuse (group, datap, &errno);
}
libc_hidden_def (internal_setnetgrent)
strong_alias (internal_setnetgrent, __internal_setnetgrent)

int
setnetgrent (const char *group)
{
  int result;

  __libc_lock_lock (lock);

  result = internal_setnetgrent (group, &dataset);

  __libc_lock_unlock (lock);

  return result;
}

void internal_endnetgrent (struct __netgrent *datap);
libc_hidden_proto (internal_endnetgrent)

void
internal_endnetgrent (struct __netgrent *datap)
{
  endnetgrent_hook (datap);
  /* Now free list of all netgroup names from last run.  */
  free_memory (datap);
}
libc_hidden_def (internal_endnetgrent)
strong_alias (internal_endnetgrent, __internal_endnetgrent)


void
endnetgrent (void)
{
  __libc_lock_lock (lock);

  internal_endnetgrent (&dataset);

  __libc_lock_unlock (lock);
}


int internal_getnetgrent_r (char **hostp, char **userp, char **domainp,
			    struct __netgrent *datap,
			    char *buffer, size_t buflen, int *errnop);
libc_hidden_proto (internal_getnetgrent_r)

int
internal_getnetgrent_r (char **hostp, char **userp, char **domainp,
			  struct __netgrent *datap,
			  char *buffer, size_t buflen, int *errnop)
{
  enum nss_status (*fct) (struct __netgrent *, char *, size_t, int *);

  /* Initialize status to return if no more functions are found.  */
  enum nss_status status = NSS_STATUS_NOTFOUND;

  /* Run through available functions, starting with the same function last
     run.  We will repeat each function as long as it succeeds, and then go
     on to the next service action.  */
  int no_more = (datap->nip == NULL
		 || (fct = __nss_lookup_function (datap->nip, "getnetgrent_r"))
		    == NULL);
  while (! no_more)
    {
      status = (*fct) (datap, buffer, buflen, &errno);

      if (status == NSS_STATUS_RETURN)
	{
	  /* This was the last one for this group.  Look at next group
	     if available.  */
	  int found = 0;
	  while (datap->needed_groups != NULL && ! found)
	    {
	      struct name_list *tmp = datap->needed_groups;
	      datap->needed_groups = datap->needed_groups->next;
	      tmp->next = datap->known_groups;
	      datap->known_groups = tmp;

	      found = __internal_setnetgrent_reuse (datap->known_groups->name,
						    datap, errnop);
	    }

	  if (found && datap->nip != NULL)
	    {
	      fct = __nss_lookup_function (datap->nip, "getnetgrent_r");
	      if (fct != NULL)
		continue;
	    }
	}
      else if (status == NSS_STATUS_SUCCESS && datap->type == group_val)
	{
	  /* The last entry was a name of another netgroup.  */
	  struct name_list *namep;

	  /* Ignore if we've seen the name before.  */
	  for (namep = datap->known_groups; namep != NULL;
	       namep = namep->next)
	    if (strcmp (datap->val.group, namep->name) == 0)
	      break;
	  if (namep != NULL)
	    /* Really ignore.  */
	    continue;

	  size_t group_len = strlen (datap->val.group) + 1;
	  namep = (struct name_list *) malloc (sizeof (struct name_list)
					       + group_len);
	  if (namep == NULL)
	    /* We are out of memory.  */
	    status = NSS_STATUS_RETURN;
	  else
	    {
	      namep->next = datap->needed_groups;
	      memcpy (namep->name, datap->val.group, group_len);
	      datap->needed_groups = namep;
	      /* And get the next entry.  */
	      continue;
	    }
	}

      break;
    }

  if (status == NSS_STATUS_SUCCESS)
    {
      *hostp = (char *) datap->val.triple.host;
      *userp = (char *) datap->val.triple.user;
      *domainp = (char *) datap->val.triple.domain;
    }

  return status == NSS_STATUS_SUCCESS ? 1 : 0;
}
libc_hidden_def (internal_getnetgrent_r)
strong_alias (internal_getnetgrent_r, __internal_getnetgrent_r)

/* The real entry point.  */
int
__getnetgrent_r (char **hostp, char **userp, char **domainp,
		 char *buffer, size_t buflen)
{
  enum nss_status status;

  __libc_lock_lock (lock);

  status = internal_getnetgrent_r (hostp, userp, domainp, &dataset,
				   buffer, buflen, &errno);

  __libc_lock_unlock (lock);

  return status;
}
weak_alias (__getnetgrent_r, getnetgrent_r)

/* Test whether given (host,user,domain) triple is in NETGROUP.  */
int
innetgr (const char *netgroup, const char *host, const char *user,
	 const char *domain)
{
  union
  {
    int (*f) (const char *, struct __netgrent *);
    void *ptr;
  } setfct;
  void (*endfct) (struct __netgrent *);
  int (*getfct) (struct __netgrent *, char *, size_t, int *);
  struct __netgrent entry;
  int result = 0;
  const char *current_group = netgroup;
  int real_entry = 0;

  memset (&entry, '\0', sizeof (entry));

  /* Walk through the services until we found an answer or we shall
     not work further.  We can do some optimization here.  Since all
     services must provide the `setnetgrent' function we can do all
     the work during one walk through the service list.  */
  while (1)
    {
      int no_more = setup (&setfct.ptr, &entry.nip);
      while (! no_more)
	{
	  assert (entry.data == NULL);

	  /* Open netgroup.  */
	  enum nss_status status = (*setfct.f) (current_group, &entry);

	  if (status == NSS_STATUS_SUCCESS
	      && (getfct = __nss_lookup_function (entry.nip, "getnetgrent_r"))
		 != NULL)
	    {
	      char buffer[1024];

	      while ((*getfct) (&entry, buffer, sizeof buffer, &errno)
		     == NSS_STATUS_SUCCESS)
		{
		  if (entry.type == group_val)
		    {
		      /* Make sure we haven't seen the name before.  */
		      struct name_list *namep;

		      for (namep = entry.known_groups; namep != NULL;
			   namep = namep->next)
			if (strcmp (entry.val.group, namep->name) == 0)
			  break;
		      if (namep == NULL
			  && strcmp (netgroup, entry.val.group) != 0)
			{
			  size_t group_len = strlen (entry.val.group) + 1;
			  namep =
			    (struct name_list *) malloc (sizeof (*namep)
							 + group_len);
			  if (namep == NULL)
			    {
			      /* Out of memory, simply return.  */
			      result = -1;
			      break;
			    }

			  namep->next = entry.needed_groups;
			  memcpy (namep->name, entry.val.group, group_len);
			  entry.needed_groups = namep;
			}
		    }
		  else
		    {
		      real_entry = 1;

		      if ((entry.val.triple.host == NULL || host == NULL
			   || __strcasecmp (entry.val.triple.host, host) == 0)
			  && (entry.val.triple.user == NULL || user == NULL
			      || strcmp (entry.val.triple.user, user) == 0)
			  && (entry.val.triple.domain == NULL || domain == NULL
			      || __strcasecmp (entry.val.triple.domain,
					       domain) == 0))
			{
			  result = 1;
			  break;
			}
		    }
		}

	      /* If we found one service which does know the given
		 netgroup we don't try further.  */
	      status = NSS_STATUS_RETURN;
	    }

	  /* Free all resources of the service.  */
	  endfct = __nss_lookup_function (entry.nip, "endnetgrent");
	  if (endfct != NULL)
	    (*endfct) (&entry);

	  if (result != 0)
	    break;

	  /* Look for the next service.  */
	  no_more = __nss_next2 (&entry.nip, "setnetgrent", NULL,
				 &setfct.ptr, status, 0);
	}

      if (result == 0 && entry.needed_groups != NULL)
	{
	  struct name_list *tmp = entry.needed_groups;
	  entry.needed_groups = tmp->next;
	  tmp->next = entry.known_groups;
	  entry.known_groups = tmp;
	  current_group = entry.known_groups->name;
	  continue;
	}

      /* No way out.  */
      break;
    }

  /* Free the memory.  */
  free_memory (&entry);

  return result == 1;
}
libc_hidden_def (innetgr)
