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

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

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, see <http://www.gnu.org/licenses/>.  */

#include <alloca.h>
#include <assert.h>
#include <errno.h>
#include <libintl.h>
#include <stdbool.h>
#include <unistd.h>
#include <sys/mman.h>

#include "../inet/netgroup.h"
#include "nscd.h"
#include "dbg_log.h"

#include <kernel-features.h>


/* This is the standard reply in case the service is disabled.  */
static const netgroup_response_header disabled =
{
  .version = NSCD_VERSION,
  .found = -1,
  .nresults = 0,
  .result_len = 0
};

/* This is the struct describing how to write this record.  */
const struct iovec netgroup_iov_disabled =
{
  .iov_base = (void *) &disabled,
  .iov_len = sizeof (disabled)
};


/* This is the standard reply in case we haven't found the dataset.  */
static const netgroup_response_header notfound =
{
  .version = NSCD_VERSION,
  .found = 0,
  .nresults = 0,
  .result_len = 0
};


struct dataset
{
  struct datahead head;
  netgroup_response_header resp;
  char strdata[0];
};

/* Sends a notfound message and prepares a notfound dataset to write to the
   cache.  Returns true if there was enough memory to allocate the dataset and
   returns the dataset in DATASETP, total bytes to write in TOTALP and the
   timeout in TIMEOUTP.  KEY_COPY is set to point to the copy of the key in the
   dataset. */
static bool
do_notfound (struct database_dyn *db, int fd, request_header *req,
	       const char *key, struct dataset **datasetp, ssize_t *totalp,
	       time_t *timeoutp, char **key_copy)
{
  struct dataset *dataset;
  ssize_t total;
  time_t timeout;
  bool cacheable = false;

  total = sizeof (notfound);
  timeout = time (NULL) + db->negtimeout;

  if (fd != -1)
    TEMP_FAILURE_RETRY (send (fd, &notfound, total, MSG_NOSIGNAL));

  dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len, 1);
  /* If we cannot permanently store the result, so be it.  */
  if (dataset != NULL)
    {
      dataset->head.allocsize = sizeof (struct dataset) + req->key_len;
      dataset->head.recsize = total;
      dataset->head.notfound = true;
      dataset->head.nreloads = 0;
      dataset->head.usable = true;

      /* Compute the timeout time.  */
      timeout = dataset->head.timeout = time (NULL) + db->negtimeout;
      dataset->head.ttl = db->negtimeout;

      /* This is the reply.  */
      memcpy (&dataset->resp, &notfound, total);

      /* Copy the key data.  */
      memcpy (dataset->strdata, key, req->key_len);
      *key_copy = dataset->strdata;

      cacheable = true;
    }
  *timeoutp = timeout;
  *totalp = total;
  *datasetp = dataset;
  return cacheable;
}

static time_t
addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
		 const char *key, uid_t uid, struct hashentry *he,
		 struct datahead *dh, struct dataset **resultp)
{
  if (__builtin_expect (debug_level > 0, 0))
    {
      if (he == NULL)
	dbg_log (_("Haven't found \"%s\" in netgroup cache!"), key);
      else
	dbg_log (_("Reloading \"%s\" in netgroup cache!"), key);
    }

  static service_user *netgroup_database;
  time_t timeout;
  struct dataset *dataset;
  bool cacheable = false;
  ssize_t total;
  bool found = false;

  char *key_copy = NULL;
  struct __netgrent data;
  size_t buflen = MAX (1024, sizeof (*dataset) + req->key_len);
  size_t buffilled = sizeof (*dataset);
  char *buffer = NULL;
  size_t nentries = 0;
  size_t group_len = strlen (key) + 1;
  union
  {
    struct name_list elem;
    char mem[sizeof (struct name_list) + group_len];
  } first_needed;

  if (netgroup_database == NULL
      && __nss_database_lookup ("netgroup", NULL, NULL, &netgroup_database))
    {
      /* No such service.  */
      cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
			       &key_copy);
      goto writeout;
    }

  memset (&data, '\0', sizeof (data));
  buffer = xmalloc (buflen);
  first_needed.elem.next = &first_needed.elem;
  memcpy (first_needed.elem.name, key, group_len);
  data.needed_groups = &first_needed.elem;

  while (data.needed_groups != NULL)
    {
      /* Add the next group to the list of those which are known.  */
      struct name_list *this_group = data.needed_groups->next;
      if (this_group == data.needed_groups)
	data.needed_groups = NULL;
      else
	data.needed_groups->next = this_group->next;
      this_group->next = data.known_groups;
      data.known_groups = this_group;

      union
      {
	enum nss_status (*f) (const char *, struct __netgrent *);
	void *ptr;
      } setfct;

      service_user *nip = netgroup_database;
      int no_more = __nss_lookup (&nip, "setnetgrent", NULL, &setfct.ptr);
      while (!no_more)
	{
	  enum nss_status status
	    = DL_CALL_FCT (*setfct.f, (data.known_groups->name, &data));

	  if (status == NSS_STATUS_SUCCESS)
	    {
	      found = true;
	      union
	      {
		enum nss_status (*f) (struct __netgrent *, char *, size_t,
				      int *);
		void *ptr;
	      } getfct;
	      getfct.ptr = __nss_lookup_function (nip, "getnetgrent_r");
	      if (getfct.f != NULL)
		while (1)
		  {
		    int e;
		    status = getfct.f (&data, buffer + buffilled,
				       buflen - buffilled, &e);
		    if (status == NSS_STATUS_RETURN
			|| status == NSS_STATUS_NOTFOUND)
		      /* This was either the last one for this group or the
			 group was empty.  Look at next group if available.  */
		      break;
		    if (status == NSS_STATUS_SUCCESS)
		      {
			if (data.type == triple_val)
			  {
			    const char *nhost = data.val.triple.host;
			    const char *nuser = data.val.triple.user;
			    const char *ndomain = data.val.triple.domain;

			    if (nhost == NULL || nuser == NULL || ndomain == NULL
				|| nhost > nuser || nuser > ndomain)
			      {
				const char *last = nhost;
				if (last == NULL
				    || (nuser != NULL && nuser > last))
				  last = nuser;
				if (last == NULL
				    || (ndomain != NULL && ndomain > last))
				  last = ndomain;

				size_t bufused
				  = (last == NULL
				     ? buffilled
				     : last + strlen (last) + 1 - buffer);

				/* We have to make temporary copies.  */
				size_t hostlen = strlen (nhost ?: "") + 1;
				size_t userlen = strlen (nuser ?: "") + 1;
				size_t domainlen = strlen (ndomain ?: "") + 1;
				size_t needed = hostlen + userlen + domainlen;

				if (buflen - req->key_len - bufused < needed)
				  {
				    buflen += MAX (buflen, 2 * needed);
				    /* Save offset in the old buffer.  We don't
				       bother with the NULL check here since
				       we'll do that later anyway.  */
				    size_t nhostdiff = nhost - buffer;
				    size_t nuserdiff = nuser - buffer;
				    size_t ndomaindiff = ndomain - buffer;

				    char *newbuf = xrealloc (buffer, buflen);
				    /* Fix up the triplet pointers into the new
				       buffer.  */
				    nhost = (nhost ? newbuf + nhostdiff
					     : NULL);
				    nuser = (nuser ? newbuf + nuserdiff
					     : NULL);
				    ndomain = (ndomain ? newbuf + ndomaindiff
					       : NULL);
				    buffer = newbuf;
				  }

				nhost = memcpy (buffer + bufused,
						nhost ?: "", hostlen);
				nuser = memcpy ((char *) nhost + hostlen,
						nuser ?: "", userlen);
				ndomain = memcpy ((char *) nuser + userlen,
						  ndomain ?: "", domainlen);
			      }

			    char *wp = buffer + buffilled;
			    wp = stpcpy (wp, nhost) + 1;
			    wp = stpcpy (wp, nuser) + 1;
			    wp = stpcpy (wp, ndomain) + 1;
			    buffilled = wp - buffer;
			    ++nentries;
			  }
			else
			  {
			    /* Check that the group has not been
			       requested before.  */
			    struct name_list *runp = data.needed_groups;
			    if (runp != NULL)
			      while (1)
				{
				  if (strcmp (runp->name, data.val.group) == 0)
				    break;

				  runp = runp->next;
				  if (runp == data.needed_groups)
				    {
				      runp = NULL;
				      break;
				    }
				}

			    if (runp == NULL)
			      {
				runp = data.known_groups;
				while (runp != NULL)
				  if (strcmp (runp->name, data.val.group) == 0)
				    break;
				  else
				    runp = runp->next;
				}

			    if (runp == NULL)
			      {
				/* A new group is requested.  */
				size_t namelen = strlen (data.val.group) + 1;
				struct name_list *newg = alloca (sizeof (*newg)
								 + namelen);
				memcpy (newg->name, data.val.group, namelen);
				if (data.needed_groups == NULL)
				  data.needed_groups = newg->next = newg;
				else
				  {
				    newg->next = data.needed_groups->next;
				    data.needed_groups->next = newg;
				    data.needed_groups = newg;
				  }
			      }
			  }
		      }
		    else if (status == NSS_STATUS_UNAVAIL && e == ERANGE)
		      {
			buflen *= 2;
			buffer = xrealloc (buffer, buflen);
		      }
		  }

	      enum nss_status (*endfct) (struct __netgrent *);
	      endfct = __nss_lookup_function (nip, "endnetgrent");
	      if (endfct != NULL)
		(void) DL_CALL_FCT (*endfct, (&data));

	      break;
	    }

	  no_more = __nss_next2 (&nip, "setnetgrent", NULL, &setfct.ptr,
				 status, 0);
	}
    }

  /* No results.  Return a failure and write out a notfound record in the
     cache.  */
  if (!found)
    {
      cacheable = do_notfound (db, fd, req, key, &dataset, &total, &timeout,
			       &key_copy);
      goto writeout;
    }

  total = buffilled;

  /* Fill in the dataset.  */
  dataset = (struct dataset *) buffer;
  dataset->head.allocsize = total + req->key_len;
  dataset->head.recsize = total - offsetof (struct dataset, resp);
  dataset->head.notfound = false;
  dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
  dataset->head.usable = true;
  dataset->head.ttl = db->postimeout;
  timeout = dataset->head.timeout = time (NULL) + dataset->head.ttl;

  dataset->resp.version = NSCD_VERSION;
  dataset->resp.found = 1;
  dataset->resp.nresults = nentries;
  dataset->resp.result_len = buffilled - sizeof (*dataset);

  assert (buflen - buffilled >= req->key_len);
  key_copy = memcpy (buffer + buffilled, key, req->key_len);
  buffilled += req->key_len;

  /* Now we can determine whether on refill we have to create a new
     record or not.  */
  if (he != NULL)
    {
      assert (fd == -1);

      if (dataset->head.allocsize == dh->allocsize
	  && dataset->head.recsize == dh->recsize
	  && memcmp (&dataset->resp, dh->data,
		     dh->allocsize - offsetof (struct dataset, resp)) == 0)
	{
	  /* The data has not changed.  We will just bump the timeout
	     value.  Note that the new record has been allocated on
	     the stack and need not be freed.  */
	  dh->timeout = dataset->head.timeout;
	  dh->ttl = dataset->head.ttl;
	  ++dh->nreloads;
	  dataset = (struct dataset *) dh;

	  goto out;
	}
    }

  {
    struct dataset *newp
      = (struct dataset *) mempool_alloc (db, total + req->key_len, 1);
    if (__builtin_expect (newp != NULL, 1))
      {
	/* Adjust pointer into the memory block.  */
	key_copy = (char *) newp + (key_copy - buffer);

	dataset = memcpy (newp, dataset, total + req->key_len);
	cacheable = true;

	if (he != NULL)
	  /* Mark the old record as obsolete.  */
	  dh->usable = false;
      }
  }

  if (he == NULL && fd != -1)
    {
      /* We write the dataset before inserting it to the database
	 since while inserting this thread might block and so would
	 unnecessarily let the receiver wait.  */
    writeout:
#ifdef HAVE_SENDFILE
      if (__builtin_expect (db->mmap_used, 1) && cacheable)
	{
	  assert (db->wr_fd != -1);
	  assert ((char *) &dataset->resp > (char *) db->data);
	  assert ((char *) dataset - (char *) db->head + total
		  <= (sizeof (struct database_pers_head)
		      + db->head->module * sizeof (ref_t)
		      + db->head->data_size));
# ifndef __ASSUME_SENDFILE
	  ssize_t written =
# endif
	    sendfileall (fd, db->wr_fd, (char *) &dataset->resp
			 - (char *) db->head, dataset->head.recsize);
# ifndef __ASSUME_SENDFILE
	  if (written == -1 && errno == ENOSYS)
	    goto use_write;
# endif
	}
      else
#endif
	{
#if defined HAVE_SENDFILE && !defined __ASSUME_SENDFILE
	use_write:
#endif
	  writeall (fd, &dataset->resp, dataset->head.recsize);
	}
    }

  if (cacheable)
    {
      /* If necessary, we also propagate the data to disk.  */
      if (db->persistent)
	{
	  // XXX async OK?
	  uintptr_t pval = (uintptr_t) dataset & ~pagesize_m1;
	  msync ((void *) pval,
		 ((uintptr_t) dataset & pagesize_m1) + total + req->key_len,
		 MS_ASYNC);
	}

      (void) cache_add (req->type, key_copy, req->key_len, &dataset->head,
			true, db, uid, he == NULL);

      pthread_rwlock_unlock (&db->lock);

      /* Mark the old entry as obsolete.  */
      if (dh != NULL)
	dh->usable = false;
    }

 out:
  free (buffer);

  *resultp = dataset;

  return timeout;
}


static time_t
addinnetgrX (struct database_dyn *db, int fd, request_header *req,
	     char *key, uid_t uid, struct hashentry *he,
	     struct datahead *dh)
{
  const char *group = key;
  key = (char *) rawmemchr (key, '\0') + 1;
  size_t group_len = key - group - 1;
  const char *host = *key++ ? key : NULL;
  if (host != NULL)
    key = (char *) rawmemchr (key, '\0') + 1;
  const char *user = *key++ ? key : NULL;
  if (user != NULL)
    key = (char *) rawmemchr (key, '\0') + 1;
  const char *domain = *key++ ? key : NULL;

  if (__builtin_expect (debug_level > 0, 0))
    {
      if (he == NULL)
	dbg_log (_("Haven't found \"%s (%s,%s,%s)\" in netgroup cache!"),
		 group, host ?: "", user ?: "", domain ?: "");
      else
	dbg_log (_("Reloading \"%s (%s,%s,%s)\" in netgroup cache!"),
		 group, host ?: "", user ?: "", domain ?: "");
    }

  struct dataset *result = (struct dataset *) cache_search (GETNETGRENT,
							    group, group_len,
							    db, uid);
  time_t timeout;
  if (result != NULL)
    timeout = result->head.timeout;
  else
    {
      request_header req_get =
	{
	  .type = GETNETGRENT,
	  .key_len = group_len
	};
      timeout = addgetnetgrentX (db, -1, &req_get, group, uid, NULL, NULL,
				 &result);
    }

  struct indataset
  {
    struct datahead head;
    innetgroup_response_header resp;
  } *dataset
      = (struct indataset *) mempool_alloc (db,
					    sizeof (*dataset) + req->key_len,
					    1);
  struct indataset dataset_mem;
  bool cacheable = true;
  if (__builtin_expect (dataset == NULL, 0))
    {
      cacheable = false;
      dataset = &dataset_mem;
    }

  dataset->head.allocsize = sizeof (*dataset) + req->key_len;
  dataset->head.recsize = sizeof (innetgroup_response_header);
  dataset->head.notfound = result->head.notfound;
  dataset->head.nreloads = he == NULL ? 0 : (dh->nreloads + 1);
  dataset->head.usable = true;
  dataset->head.ttl = result->head.ttl;
  dataset->head.timeout = timeout;

  dataset->resp.version = NSCD_VERSION;
  dataset->resp.found = result->resp.found;
  /* Until we find a matching entry the result is 0.  */
  dataset->resp.result = 0;

  char *key_copy = memcpy ((char *) (dataset + 1), group, req->key_len);

  if (dataset->resp.found)
    {
      const char *triplets = (const char *) (&result->resp + 1);

      for (nscd_ssize_t i = result->resp.nresults; i > 0; --i)
	{
	  bool success = true;

	  if (host != NULL)
	    success = strcmp (host, triplets) == 0;
	  triplets = (const char *) rawmemchr (triplets, '\0') + 1;

	  if (success && user != NULL)
	    success = strcmp (user, triplets) == 0;
	  triplets = (const char *) rawmemchr (triplets, '\0') + 1;

	  if (success && (domain == NULL || strcmp (domain, triplets) == 0))
	    {
	      dataset->resp.result = 1;
	      break;
	    }
	  triplets = (const char *) rawmemchr (triplets, '\0') + 1;
	}
    }

  if (he != NULL && dh->data[0].innetgroupdata.result == dataset->resp.result)
    {
      /* The data has not changed.  We will just bump the timeout
	 value.  Note that the new record has been allocated on
	 the stack and need not be freed.  */
      dh->timeout = timeout;
      dh->ttl = dataset->head.ttl;
      ++dh->nreloads;
      return timeout;
    }

  if (he == NULL)
    {
      /* We write the dataset before inserting it to the database
	 since while inserting this thread might block and so would
	 unnecessarily let the receiver wait.  */
       assert (fd != -1);

#ifdef HAVE_SENDFILE
      if (__builtin_expect (db->mmap_used, 1) && cacheable)
	{
	  assert (db->wr_fd != -1);
	  assert ((char *) &dataset->resp > (char *) db->data);
	  assert ((char *) dataset - (char *) db->head + sizeof (*dataset)
		  <= (sizeof (struct database_pers_head)
		      + db->head->module * sizeof (ref_t)
		      + db->head->data_size));
# ifndef __ASSUME_SENDFILE
	  ssize_t written =
# endif
	    sendfileall (fd, db->wr_fd,
			 (char *) &dataset->resp - (char *) db->head,
			 sizeof (innetgroup_response_header));
# ifndef __ASSUME_SENDFILE
	  if (written == -1 && errno == ENOSYS)
	    goto use_write;
# endif
	}
      else
#endif
	{
#if defined HAVE_SENDFILE && !defined __ASSUME_SENDFILE
	use_write:
#endif
	  writeall (fd, &dataset->resp, sizeof (innetgroup_response_header));
	}
    }

  if (cacheable)
    {
      /* If necessary, we also propagate the data to disk.  */
      if (db->persistent)
	{
	  // XXX async OK?
	  uintptr_t pval = (uintptr_t) dataset & ~pagesize_m1;
	  msync ((void *) pval,
		 ((uintptr_t) dataset & pagesize_m1) + sizeof (*dataset)
		 + req->key_len,
		 MS_ASYNC);
	}

      (void) cache_add (req->type, key_copy, req->key_len, &dataset->head,
			true, db, uid, he == NULL);

      pthread_rwlock_unlock (&db->lock);

      /* Mark the old entry as obsolete.  */
      if (dh != NULL)
	dh->usable = false;
    }

  return timeout;
}


void
addgetnetgrent (struct database_dyn *db, int fd, request_header *req,
		void *key, uid_t uid)
{
  struct dataset *ignore;

  addgetnetgrentX (db, fd, req, key, uid, NULL, NULL, &ignore);
}


time_t
readdgetnetgrent (struct database_dyn *db, struct hashentry *he,
		  struct datahead *dh)
{
  request_header req =
    {
      .type = GETNETGRENT,
      .key_len = he->len
    };
  struct dataset *ignore;

  return addgetnetgrentX (db, -1, &req, db->data + he->key, he->owner, he, dh,
			  &ignore);
}


void
addinnetgr (struct database_dyn *db, int fd, request_header *req,
	    void *key, uid_t uid)
{
  addinnetgrX (db, fd, req, key, uid, NULL, NULL);
}


time_t
readdinnetgr (struct database_dyn *db, struct hashentry *he,
	      struct datahead *dh)
{
  request_header req =
    {
      .type = INNETGR,
      .key_len = he->len
    };

  return addinnetgrX (db, -1, &req, db->data + he->key, he->owner, he, dh);
}
