Blame nscd/nscd_conf.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
   This program is free software; you can redistribute it and/or modify
Packit Service 82fcde
   it under the terms of the GNU General Public License as published
Packit Service 82fcde
   by the Free Software Foundation; version 2 of the License, or
Packit Service 82fcde
   (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   This program 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
Packit Service 82fcde
   GNU General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU General Public License
Packit Service 82fcde
   along with this program; if not, see <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#include <ctype.h>
Packit Service 82fcde
#include <errno.h>
Packit Service 82fcde
#include <error.h>
Packit Service 82fcde
#include <libintl.h>
Packit Service 82fcde
#include <malloc.h>
Packit Service 82fcde
#include <pwd.h>
Packit Service 82fcde
#include <stdio.h>
Packit Service 82fcde
#include <stdio_ext.h>
Packit Service 82fcde
#include <stdlib.h>
Packit Service 82fcde
#include <string.h>
Packit Service 82fcde
#include <unistd.h>
Packit Service 82fcde
#include <sys/param.h>
Packit Service 82fcde
#include <sys/types.h>
Packit Service 82fcde
Packit Service 82fcde
#include "dbg_log.h"
Packit Service 82fcde
#include "nscd.h"
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Names of the databases.  */
Packit Service 82fcde
const char *const dbnames[lastdb] =
Packit Service 82fcde
{
Packit Service 82fcde
  [pwddb] = "passwd",
Packit Service 82fcde
  [grpdb] = "group",
Packit Service 82fcde
  [hstdb] = "hosts",
Packit Service 82fcde
  [servdb] = "services",
Packit Service 82fcde
  [netgrdb] = "netgroup"
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
find_db (const char *name)
Packit Service 82fcde
{
Packit Service 82fcde
  for (int cnt = 0; cnt < lastdb; ++cnt)
Packit Service 82fcde
    if (strcmp (name, dbnames[cnt]) == 0)
Packit Service 82fcde
      return cnt;
Packit Service 82fcde
Packit Service 82fcde
  error (0, 0, _("database %s is not supported"), name);
Packit Service 82fcde
  return -1;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
int
Packit Service 82fcde
nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
Packit Service 82fcde
{
Packit Service 82fcde
  FILE *fp;
Packit Service 82fcde
  char *line, *cp, *entry, *arg1, *arg2;
Packit Service 82fcde
  size_t len;
Packit Service 82fcde
  int cnt;
Packit Service 82fcde
  const unsigned int initial_error_message_count = error_message_count;
Packit Service 82fcde
Packit Service 82fcde
  /* Open the configuration file.  */
Packit Service 82fcde
  fp = fopen (fname, "r");
Packit Service 82fcde
  if (fp == NULL)
Packit Service 82fcde
    return -1;
Packit Service 82fcde
Packit Service 82fcde
  /* The stream is not used by more than one thread.  */
Packit Service 82fcde
  (void) __fsetlocking (fp, FSETLOCKING_BYCALLER);
Packit Service 82fcde
Packit Service 82fcde
  line = NULL;
Packit Service 82fcde
  len = 0;
Packit Service 82fcde
Packit Service 82fcde
  do
Packit Service 82fcde
    {
Packit Service 82fcde
      ssize_t n = getline (&line, &len, fp);
Packit Service 82fcde
      if (n < 0)
Packit Service 82fcde
	break;
Packit Service 82fcde
      if (line[n - 1] == '\n')
Packit Service 82fcde
	line[n - 1] = '\0';
Packit Service 82fcde
Packit Service 82fcde
      /* Because the file format does not know any form of quoting we
Packit Service 82fcde
	 can search forward for the next '#' character and if found
Packit Service 82fcde
	 make it terminating the line.  */
Packit Service 82fcde
      *strchrnul (line, '#') = '\0';
Packit Service 82fcde
Packit Service 82fcde
      /* If the line is blank it is ignored.  */
Packit Service 82fcde
      if (line[0] == '\0')
Packit Service 82fcde
	continue;
Packit Service 82fcde
Packit Service 82fcde
      entry = line;
Packit Service 82fcde
      while (isspace (*entry) && *entry != '\0')
Packit Service 82fcde
	++entry;
Packit Service 82fcde
      cp = entry;
Packit Service 82fcde
      while (!isspace (*cp) && *cp != '\0')
Packit Service 82fcde
	++cp;
Packit Service 82fcde
      arg1 = cp;
Packit Service 82fcde
      ++arg1;
Packit Service 82fcde
      *cp = '\0';
Packit Service 82fcde
      if (strlen (entry) == 0)
Packit Service 82fcde
	error (0, 0, _("Parse error: %s"), line);
Packit Service 82fcde
      while (isspace (*arg1) && *arg1 != '\0')
Packit Service 82fcde
	++arg1;
Packit Service 82fcde
      cp = arg1;
Packit Service 82fcde
      while (!isspace (*cp) && *cp != '\0')
Packit Service 82fcde
	++cp;
Packit Service 82fcde
      arg2 = cp;
Packit Service 82fcde
      ++arg2;
Packit Service 82fcde
      *cp = '\0';
Packit Service 82fcde
      if (strlen (arg2) > 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  while (isspace (*arg2) && *arg2 != '\0')
Packit Service 82fcde
	    ++arg2;
Packit Service 82fcde
	  cp = arg2;
Packit Service 82fcde
	  while (!isspace (*cp) && *cp != '\0')
Packit Service 82fcde
	    ++cp;
Packit Service 82fcde
	  *cp = '\0';
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      if (strcmp (entry, "positive-time-to-live") == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  int idx = find_db (arg1);
Packit Service 82fcde
	  if (idx >= 0)
Packit Service 82fcde
	    dbs[idx].postimeout = atol (arg2);
Packit Service 82fcde
	}
Packit Service 82fcde
      else if (strcmp (entry, "negative-time-to-live") == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  int idx = find_db (arg1);
Packit Service 82fcde
	  if (idx >= 0)
Packit Service 82fcde
	    dbs[idx].negtimeout = atol (arg2);
Packit Service 82fcde
	}
Packit Service 82fcde
      else if (strcmp (entry, "suggested-size") == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  int idx = find_db (arg1);
Packit Service 82fcde
	  if (idx >= 0)
Packit Service 82fcde
	    dbs[idx].suggested_module
Packit Service 82fcde
	      = atol (arg2) ?: DEFAULT_SUGGESTED_MODULE;
Packit Service 82fcde
	}
Packit Service 82fcde
      else if (strcmp (entry, "enable-cache") == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  int idx = find_db (arg1);
Packit Service 82fcde
	  if (idx >= 0)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      if (strcmp (arg2, "no") == 0)
Packit Service 82fcde
		dbs[idx].enabled = 0;
Packit Service 82fcde
	      else if (strcmp (arg2, "yes") == 0)
Packit Service 82fcde
		dbs[idx].enabled = 1;
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
      else if (strcmp (entry, "check-files") == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  int idx = find_db (arg1);
Packit Service 82fcde
	  if (idx >= 0)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      if (strcmp (arg2, "no") == 0)
Packit Service 82fcde
		dbs[idx].check_file = 0;
Packit Service 82fcde
	      else if (strcmp (arg2, "yes") == 0)
Packit Service 82fcde
		dbs[idx].check_file = 1;
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
      else if (strcmp (entry, "max-db-size") == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  int idx = find_db (arg1);
Packit Service 82fcde
	  if (idx >= 0)
Packit Service 82fcde
	    dbs[idx].max_db_size = atol (arg2) ?: DEFAULT_MAX_DB_SIZE;
Packit Service 82fcde
	}
Packit Service 82fcde
      else if (strcmp (entry, "logfile") == 0)
Packit Service 82fcde
	set_logfile (arg1);
Packit Service 82fcde
      else if (strcmp (entry, "debug-level") == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  int level = atoi (arg1);
Packit Service 82fcde
	  if (level > 0)
Packit Service 82fcde
	    debug_level = level;
Packit Service 82fcde
	}
Packit Service 82fcde
      else if (strcmp (entry, "threads") == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (nthreads == -1)
Packit Service 82fcde
	    nthreads = MAX (atol (arg1), lastdb);
Packit Service 82fcde
	}
Packit Service 82fcde
      else if (strcmp (entry, "max-threads") == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  max_nthreads = MAX (atol (arg1), lastdb);
Packit Service 82fcde
	}
Packit Service 82fcde
      else if (strcmp (entry, "server-user") == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (!arg1)
Packit Service 82fcde
	    error (0, 0, _("Must specify user name for server-user option"));
Packit Service 82fcde
	  else
Packit Service 1c5418
	    server_user = xstrdup (arg1);
Packit Service 82fcde
	}
Packit Service 82fcde
      else if (strcmp (entry, "stat-user") == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (arg1 == NULL)
Packit Service 82fcde
	    error (0, 0, _("Must specify user name for stat-user option"));
Packit Service 82fcde
	  else
Packit Service 82fcde
	    {
Packit Service 82fcde
	      stat_user = xstrdup (arg1);
Packit Service 82fcde
Packit Service 82fcde
	      struct passwd *pw = getpwnam (stat_user);
Packit Service 82fcde
	      if (pw != NULL)
Packit Service 82fcde
		stat_uid = pw->pw_uid;
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
      else if (strcmp (entry, "persistent") == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  int idx = find_db (arg1);
Packit Service 82fcde
	  if (idx >= 0)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      if (strcmp (arg2, "no") == 0)
Packit Service 82fcde
		dbs[idx].persistent = 0;
Packit Service 82fcde
	      else if (strcmp (arg2, "yes") == 0)
Packit Service 82fcde
		dbs[idx].persistent = 1;
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
      else if (strcmp (entry, "shared") == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  int idx = find_db (arg1);
Packit Service 82fcde
	  if (idx >= 0)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      if (strcmp (arg2, "no") == 0)
Packit Service 82fcde
		dbs[idx].shared = 0;
Packit Service 82fcde
	      else if (strcmp (arg2, "yes") == 0)
Packit Service 82fcde
		dbs[idx].shared = 1;
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
      else if (strcmp (entry, "reload-count") == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (strcasecmp (arg1, "unlimited") == 0)
Packit Service 82fcde
	    reload_count = UINT_MAX;
Packit Service 82fcde
	  else
Packit Service 82fcde
	    {
Packit Service 82fcde
	      unsigned long int count = strtoul (arg1, NULL, 0);
Packit Service 82fcde
	      if (count > UINT8_MAX - 1)
Packit Service 82fcde
		reload_count = UINT_MAX;
Packit Service 82fcde
	      else
Packit Service 82fcde
		reload_count = count;
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
      else if (strcmp (entry, "paranoia") == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (strcmp (arg1, "no") == 0)
Packit Service 82fcde
	    paranoia = 0;
Packit Service 82fcde
	  else if (strcmp (arg1, "yes") == 0)
Packit Service 82fcde
	    paranoia = 1;
Packit Service 82fcde
	}
Packit Service 82fcde
      else if (strcmp (entry, "restart-interval") == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  if (arg1 != NULL)
Packit Service 82fcde
	    restart_interval = atol (arg1);
Packit Service 82fcde
	  else
Packit Service 82fcde
	    error (0, 0, _("Must specify value for restart-interval option"));
Packit Service 82fcde
	}
Packit Service 82fcde
      else if (strcmp (entry, "auto-propagate") == 0)
Packit Service 82fcde
	{
Packit Service 82fcde
	  int idx = find_db (arg1);
Packit Service 82fcde
	  if (idx >= 0)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      if (strcmp (arg2, "no") == 0)
Packit Service 82fcde
		dbs[idx].propagate = 0;
Packit Service 82fcde
	      else if (strcmp (arg2, "yes") == 0)
Packit Service 82fcde
		dbs[idx].propagate = 1;
Packit Service 82fcde
	    }
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	error (0, 0, _("Unknown option: %s %s %s"), entry, arg1, arg2);
Packit Service 82fcde
    }
Packit Service 82fcde
  while (!feof_unlocked (fp));
Packit Service 82fcde
Packit Service 82fcde
  if (paranoia)
Packit Service 82fcde
    {
Packit Service 82fcde
      restart_time = time (NULL) + restart_interval;
Packit Service 82fcde
Packit Service 82fcde
      /* Save the old current workding directory if we are in paranoia
Packit Service 82fcde
	 mode.  We have to change back to it.  */
Packit Service 82fcde
      oldcwd = get_current_dir_name ();
Packit Service 82fcde
      if (oldcwd == NULL)
Packit Service 82fcde
	{
Packit Service 82fcde
	  error (0, 0, _("\
Packit Service 82fcde
cannot get current working directory: %s; disabling paranoia mode"),
Packit Service 82fcde
		   strerror (errno));
Packit Service 82fcde
	  paranoia = 0;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* Enforce sanity.  */
Packit Service 82fcde
  if (max_nthreads < nthreads)
Packit Service 82fcde
    max_nthreads = nthreads;
Packit Service 82fcde
Packit Service 82fcde
  for (cnt = 0; cnt < lastdb; ++cnt)
Packit Service 82fcde
    {
Packit Service 82fcde
      size_t datasize = (sizeof (struct database_pers_head)
Packit Service 82fcde
			 + roundup (dbs[cnt].suggested_module
Packit Service 82fcde
				    * sizeof (ref_t), ALIGN)
Packit Service 82fcde
			 + (dbs[cnt].suggested_module
Packit Service 82fcde
			    * DEFAULT_DATASIZE_PER_BUCKET));
Packit Service 82fcde
      if (datasize > dbs[cnt].max_db_size)
Packit Service 82fcde
	{
Packit Service 82fcde
	  error (0, 0, _("maximum file size for %s database too small"),
Packit Service 82fcde
		   dbnames[cnt]);
Packit Service 82fcde
	  dbs[cnt].max_db_size = datasize;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* Free the buffer.  */
Packit Service 82fcde
  free (line);
Packit Service 82fcde
  /* Close configuration file.  */
Packit Service 82fcde
  fclose (fp);
Packit Service 82fcde
Packit Service 82fcde
  return error_message_count != initial_error_message_count;
Packit Service 82fcde
}