/* Initgroups handling in nss_db module.
   Copyright (C) 2011-2014 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Ulrich Drepper <drepper@gmail.com>.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with the GNU C Library; see the file COPYING.LIB.  If
   not, see <http://www.gnu.org/licenses/>.  */

#include <ctype.h>
#include <errno.h>
#include <grp.h>
#include <limits.h>
#include <paths.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <sys/param.h>

#include "nss_db.h"

/* The hashing function we use.  */
#include "../intl/hash-string.h"


enum nss_status
_nss_db_initgroups_dyn (const char *user, gid_t group, long int *start,
			long int *size, gid_t **groupsp, long int limit,
			int *errnop)
{
  struct nss_db_map state = { NULL, 0 };
  enum nss_status status = internal_setent (_PATH_VARDB "group.db", &state);
  if (status != NSS_STATUS_SUCCESS)
    {
      *errnop = errno;
      return status;
    }

  const struct nss_db_header *header = state.header;
  int i;
  for (i = 0; i < header->ndbs; ++i)
    if (header->dbs[i].id == ':')
      break;
  if (i == header->ndbs)
    {
      status = NSS_STATUS_UNAVAIL;
      goto out;
    }

  const stridx_t *hashtable
    = (const stridx_t *) ((const char *) header
			  + header->dbs[i].hashoffset);
  const char *valstrtab = (const char *) header + header->valstroffset;
  size_t userlen = strlen (user);
  uint32_t hashval = __hash_string (user);
  size_t hidx = hashval % header->dbs[i].hashsize;
  size_t hval2 = 1 + hashval % (header->dbs[i].hashsize - 2);

  gid_t *groups = *groupsp;

  status = NSS_STATUS_NOTFOUND;
  while (hashtable[hidx] != ~((stridx_t) 0))
    {
      const char *valstr = valstrtab + hashtable[hidx];
      while (isblank (*valstr))
	++valstr;

      if (strncmp (valstr, user, userlen) == 0 && isblank (valstr[userlen]))
	{
	  valstr += userlen + 1;
	  while (isblank (*valstr))
	    ++valstr;

	  while (*valstr != '\0')
	    {
	      errno = 0;
	      char *endp;
	      unsigned long int n = strtoul (valstr, &endp, 10);
	      if (*endp != ',' && *endp != '\0')
		break;
	      valstr = *endp == '\0' ? endp : endp + 1;

	      if (n != ULONG_MAX || errno != ERANGE)
		{
		  /* Insert the group.  */
		  if (*start == *size)
		    {
		      /* Need a bigger buffer.  */
		      if (limit > 0 && *size == limit)
			{
			  /* We reached the maximum.  */
			  status = NSS_STATUS_SUCCESS;
			  goto out;
			}

		      long int newsize;
		      if (limit <= 0)
			newsize = 2 * *size;
		      else
			newsize = MIN (limit, 2 * *size);

		      gid_t *newgroups = realloc (groups,
						  newsize * sizeof (*groups));
		      if (newgroups == NULL)
			{
			  *errnop = ENOMEM;
			  status = NSS_STATUS_TRYAGAIN;
			  goto out;
			}

		      *groupsp = groups = newgroups;
		      *size = newsize;
		    }

		  groups[*start] = n;
		  *start += 1;
		}
	    }

	  status = NSS_STATUS_SUCCESS;
	  break;
	}

      if ((hidx += hval2) >= header->dbs[i].hashsize)
	hidx -= header->dbs[i].hashsize;
    }

 out:
  internal_endent (&state);

  return status;
}
