Blame nslcd/cfg.c

Packit 6bd9ab
/*
Packit 6bd9ab
   cfg.c - functions for configuration information
Packit 6bd9ab
   This file contains parts that were part of the nss_ldap
Packit 6bd9ab
   library which has been forked into the nss-pam-ldapd library.
Packit 6bd9ab
Packit 6bd9ab
   Copyright (C) 1997-2005 Luke Howard
Packit 6bd9ab
   Copyright (C) 2007 West Consulting
Packit 6bd9ab
   Copyright (C) 2007-2018 Arthur de Jong
Packit 6bd9ab
Packit 6bd9ab
   This library is free software; you can redistribute it and/or
Packit 6bd9ab
   modify it under the terms of the GNU Lesser General Public
Packit 6bd9ab
   License as published by the Free Software Foundation; either
Packit 6bd9ab
   version 2.1 of the License, or (at your option) any later version.
Packit 6bd9ab
Packit 6bd9ab
   This library is distributed in the hope that it will be useful,
Packit 6bd9ab
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6bd9ab
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6bd9ab
   Lesser General Public License for more details.
Packit 6bd9ab
Packit 6bd9ab
   You should have received a copy of the GNU Lesser General Public
Packit 6bd9ab
   License along with this library; if not, write to the Free Software
Packit 6bd9ab
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit 6bd9ab
   02110-1301 USA
Packit 6bd9ab
*/
Packit 6bd9ab
Packit 6bd9ab
#include "config.h"
Packit 6bd9ab
Packit 6bd9ab
#include <stdio.h>
Packit 6bd9ab
#include <stdlib.h>
Packit 6bd9ab
#include <string.h>
Packit 6bd9ab
#include <strings.h>
Packit 6bd9ab
#include <ctype.h>
Packit 6bd9ab
#include <assert.h>
Packit 6bd9ab
#include <sys/types.h>
Packit 6bd9ab
#include <sys/stat.h>
Packit 6bd9ab
#include <unistd.h>
Packit 6bd9ab
#include <errno.h>
Packit 6bd9ab
#include <netdb.h>
Packit 6bd9ab
#include <sys/socket.h>
Packit 6bd9ab
#ifdef HAVE_GSSAPI_H
Packit 6bd9ab
#include <gssapi.h>
Packit 6bd9ab
#endif /* HAVE_GSSAPI_H */
Packit 6bd9ab
#ifdef HAVE_GSSAPI_GSSAPI_H
Packit 6bd9ab
#include <gssapi/gssapi.h>
Packit 6bd9ab
#endif /* HAVE_GSSAPI_GSSAPI_H */
Packit 6bd9ab
#ifdef HAVE_GSSAPI_GSSAPI_KRB5_H
Packit 6bd9ab
#include <gssapi/gssapi_krb5.h>
Packit 6bd9ab
#endif /* HAVE_GSSAPI_GSSAPI_KRB5_H */
Packit 6bd9ab
#ifdef HAVE_GSSAPI_GSSAPI_GENERIC_H
Packit 6bd9ab
#include <gssapi/gssapi_generic.h>
Packit 6bd9ab
#endif /* HAVE_GSSAPI_GSSAPI_GENERIC_H */
Packit 6bd9ab
#include <sys/types.h>
Packit 6bd9ab
#include <pwd.h>
Packit 6bd9ab
#include <grp.h>
Packit 6bd9ab
Packit 6bd9ab
#include "common.h"
Packit 6bd9ab
#include "log.h"
Packit 6bd9ab
#include "cfg.h"
Packit 6bd9ab
#include "attmap.h"
Packit 6bd9ab
#include "common/expr.h"
Packit 6bd9ab
Packit 6bd9ab
struct ldap_config *nslcd_cfg = NULL;
Packit 6bd9ab
Packit 6bd9ab
/* the maximum line length in the configuration file */
Packit 6bd9ab
#define MAX_LINE_LENGTH          4096
Packit 6bd9ab
Packit 6bd9ab
/* the delimiters of tokens */
Packit 6bd9ab
#define TOKEN_DELIM " \t\n\r"
Packit 6bd9ab
Packit 6bd9ab
/* convenient wrapper macro for ldap_set_option() */
Packit 6bd9ab
#define LDAP_SET_OPTION(ld, option, invalue)                                \
Packit 6bd9ab
  rc = ldap_set_option(ld, option, invalue);                                \
Packit 6bd9ab
  if (rc != LDAP_SUCCESS)                                                   \
Packit 6bd9ab
  {                                                                         \
Packit 6bd9ab
    log_log(LOG_ERR, "ldap_set_option(" #option ") failed: %s",             \
Packit 6bd9ab
            ldap_err2string(rc));                                           \
Packit 6bd9ab
    exit(EXIT_FAILURE);                                                     \
Packit 6bd9ab
  }
Packit 6bd9ab
Packit 6bd9ab
/* simple strdup wrapper */
Packit 6bd9ab
static char *xstrdup(const char *s)
Packit 6bd9ab
{
Packit 6bd9ab
  char *tmp;
Packit 6bd9ab
  if (s == NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_CRIT, "xstrdup() called with NULL");
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  tmp = strdup(s);
Packit 6bd9ab
  if (tmp == NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_CRIT, "strdup() failed to allocate memory");
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  return tmp;
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
/* check that the condition is true and otherwise log an error
Packit 6bd9ab
   and bail out */
Packit 6bd9ab
static inline void check_argumentcount(const char *filename, int lnr,
Packit 6bd9ab
                                       const char *keyword, int condition)
Packit 6bd9ab
{
Packit 6bd9ab
  if (!condition)
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: %s: wrong number of arguments",
Packit 6bd9ab
            filename, lnr, keyword);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
/* This function works like strtok() except that the original string is
Packit 6bd9ab
   not modified and a pointer within str to where the next token begins
Packit 6bd9ab
   is returned (this can be used to pass to the function on the next
Packit 6bd9ab
   iteration). If no more tokens are found or the token will not fit in
Packit 6bd9ab
   the buffer, NULL is returned. */
Packit 6bd9ab
static char *get_token(char **line, char *buf, size_t buflen)
Packit 6bd9ab
{
Packit 6bd9ab
  size_t len;
Packit 6bd9ab
  if ((line == NULL) || (*line == NULL) || (**line == '\0') || (buf == NULL))
Packit 6bd9ab
    return NULL;
Packit 6bd9ab
  /* find the beginning and length of the token */
Packit 6bd9ab
  *line += strspn(*line, TOKEN_DELIM);
Packit 6bd9ab
  len = strcspn(*line, TOKEN_DELIM);
Packit 6bd9ab
  /* check if there is a token */
Packit 6bd9ab
  if (len == 0)
Packit 6bd9ab
  {
Packit 6bd9ab
    *line = NULL;
Packit 6bd9ab
    return NULL;
Packit 6bd9ab
  }
Packit 6bd9ab
  /* limit the token length */
Packit 6bd9ab
  if (len >= buflen)
Packit 6bd9ab
    len = buflen - 1;
Packit 6bd9ab
  /* copy the token */
Packit 6bd9ab
  strncpy(buf, *line, len);
Packit 6bd9ab
  buf[len] = '\0';
Packit 6bd9ab
  /* skip to the next token */
Packit 6bd9ab
  *line += len;
Packit 6bd9ab
  *line += strspn(*line, TOKEN_DELIM);
Packit 6bd9ab
  /* return the token */
Packit 6bd9ab
  return buf;
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static char *get_strdup(const char *filename, int lnr,
Packit 6bd9ab
                        const char *keyword, char **line)
Packit 6bd9ab
{
Packit 6bd9ab
  char token[MAX_LINE_LENGTH];
Packit 6bd9ab
  check_argumentcount(filename, lnr, keyword,
Packit 6bd9ab
                      get_token(line, token, sizeof(token)) != NULL);
Packit 6bd9ab
  return xstrdup(token);
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static char *get_linedup(const char *filename, int lnr,
Packit 6bd9ab
                         const char *keyword, char **line)
Packit 6bd9ab
{
Packit 6bd9ab
  char *var;
Packit 6bd9ab
  check_argumentcount(filename, lnr, keyword, (*line != NULL) && (**line != '\0'));
Packit 6bd9ab
  var = xstrdup(*line);
Packit 6bd9ab
  /* mark that we are at the end of the line */
Packit 6bd9ab
  *line = NULL;
Packit 6bd9ab
  return var;
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static void get_eol(const char *filename, int lnr,
Packit 6bd9ab
                    const char *keyword, char **line)
Packit 6bd9ab
{
Packit 6bd9ab
  if ((line != NULL) && (*line != NULL) && (**line != '\0'))
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: %s: too many arguments", filename, lnr, keyword);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static int get_int(const char *filename, int lnr,
Packit 6bd9ab
                   const char *keyword, char **line)
Packit 6bd9ab
{
Packit 6bd9ab
  char token[32];
Packit 6bd9ab
  check_argumentcount(filename, lnr, keyword,
Packit 6bd9ab
                      get_token(line, token, sizeof(token)) != NULL);
Packit 6bd9ab
  /* TODO: replace with correct numeric parse */
Packit 6bd9ab
  return atoi(token);
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static int parse_boolean(const char *filename, int lnr, const char *value)
Packit 6bd9ab
{
Packit 6bd9ab
  if ((strcasecmp(value, "on") == 0) ||
Packit 6bd9ab
      (strcasecmp(value, "yes") == 0) ||
Packit 6bd9ab
      (strcasecmp(value, "true") == 0) || (strcasecmp(value, "1") == 0))
Packit 6bd9ab
    return 1;
Packit 6bd9ab
  else if ((strcasecmp(value, "off") == 0) ||
Packit 6bd9ab
           (strcasecmp(value, "no") == 0) ||
Packit 6bd9ab
           (strcasecmp(value, "false") == 0) || (strcasecmp(value, "0") == 0))
Packit 6bd9ab
    return 0;
Packit 6bd9ab
  else
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: not a boolean argument: '%s'",
Packit 6bd9ab
            filename, lnr, value);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static int get_boolean(const char *filename, int lnr,
Packit 6bd9ab
                       const char *keyword, char **line)
Packit 6bd9ab
{
Packit 6bd9ab
  char token[32];
Packit 6bd9ab
  check_argumentcount(filename, lnr, keyword,
Packit 6bd9ab
                      get_token(line, token, sizeof(token)) != NULL);
Packit 6bd9ab
  return parse_boolean(filename, lnr, token);
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static const char *print_boolean(int bool)
Packit 6bd9ab
{
Packit 6bd9ab
  if (bool) return "yes";
Packit 6bd9ab
  else      return "no";
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
#define TIME_MINUTES 60
Packit 6bd9ab
#define TIME_HOURS (60 * 60)
Packit 6bd9ab
#define TIME_DAYS (60 * 60 * 24)
Packit 6bd9ab
Packit 6bd9ab
static time_t parse_time(const char *filename, int lnr, const char *value)
Packit 6bd9ab
{
Packit 6bd9ab
  time_t t;
Packit 6bd9ab
  char *tmp = NULL;
Packit 6bd9ab
  if (strcasecmp(value, "off") == 0)
Packit 6bd9ab
    return 0;
Packit 6bd9ab
  errno = 0;
Packit 6bd9ab
  t = strtol(value, &tmp, 10);
Packit 6bd9ab
  if (errno != 0)
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: value out of range: '%s'",
Packit 6bd9ab
            filename, lnr, value);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  if ((strcasecmp(tmp, "") == 0) || (strcasecmp(tmp, "s") == 0))
Packit 6bd9ab
    return t;
Packit 6bd9ab
  else if (strcasecmp(tmp, "m") == 0)
Packit 6bd9ab
    return t * TIME_MINUTES;
Packit 6bd9ab
  else if (strcasecmp(tmp, "h") == 0)
Packit 6bd9ab
    return t * TIME_HOURS;
Packit 6bd9ab
  else if (strcasecmp(tmp, "d") == 0)
Packit 6bd9ab
    return t * TIME_DAYS;
Packit 6bd9ab
  else
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: invalid time value: '%s'",
Packit 6bd9ab
            filename, lnr, value);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static time_t get_time(const char *filename, int lnr,
Packit 6bd9ab
                       const char *keyword, char **line)
Packit 6bd9ab
{
Packit 6bd9ab
  char token[32];
Packit 6bd9ab
  check_argumentcount(filename, lnr, keyword,
Packit 6bd9ab
                      get_token(line, token, sizeof(token)) != NULL);
Packit 6bd9ab
  return parse_time(filename, lnr, token);
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static void print_time(time_t t, char *buffer, size_t buflen)
Packit 6bd9ab
{
Packit 6bd9ab
  if (t == 0)
Packit 6bd9ab
    mysnprintf(buffer, buflen, "off");
Packit 6bd9ab
  else if ((t % TIME_DAYS) == 0)
Packit 6bd9ab
    mysnprintf(buffer, buflen, "%ldd", (long)(t / TIME_DAYS));
Packit 6bd9ab
  else if ((t % TIME_HOURS) == 0)
Packit 6bd9ab
    mysnprintf(buffer, buflen, "%ldh", (long)(t / TIME_HOURS));
Packit 6bd9ab
  else if ((t % TIME_MINUTES) == 0)
Packit 6bd9ab
    mysnprintf(buffer, buflen, "%ldm", (long)(t / TIME_MINUTES));
Packit 6bd9ab
  else
Packit 6bd9ab
    mysnprintf(buffer, buflen, "%lds", (long)t);
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static void handle_uid(const char *filename, int lnr,
Packit 6bd9ab
                       const char *keyword, char *line,
Packit 6bd9ab
                       struct ldap_config *cfg)
Packit 6bd9ab
{
Packit 6bd9ab
  char token[32];
Packit 6bd9ab
  struct passwd *pwent;
Packit 6bd9ab
  char *tmp;
Packit 6bd9ab
  check_argumentcount(filename, lnr, keyword,
Packit 6bd9ab
                      get_token(&line, token, sizeof(token)) != NULL);
Packit 6bd9ab
  get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
  /* check if it is a valid numerical uid */
Packit 6bd9ab
  errno = 0;
Packit 6bd9ab
  cfg->uid = strtouid(token, &tmp, 10);
Packit 6bd9ab
  if ((*token != '\0') && (*tmp == '\0') && (errno == 0) && (strchr(token, '-') == NULL))
Packit 6bd9ab
  {
Packit 6bd9ab
    /* get the name and gid from the passwd database */
Packit 6bd9ab
    pwent = getpwuid(cfg->uid);
Packit 6bd9ab
    if (pwent != NULL)
Packit 6bd9ab
    {
Packit 6bd9ab
      if (cfg->gid == NOGID)
Packit 6bd9ab
        cfg->gid = pwent->pw_gid;
Packit 6bd9ab
      cfg->uidname = strdup(pwent->pw_name);
Packit 6bd9ab
      return;
Packit 6bd9ab
    }
Packit 6bd9ab
  }
Packit 6bd9ab
  /* find by name */
Packit 6bd9ab
  pwent = getpwnam(token);
Packit 6bd9ab
  if (pwent != NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    cfg->uid = pwent->pw_uid;
Packit 6bd9ab
    if (cfg->gid == NOGID)
Packit 6bd9ab
      cfg->gid = pwent->pw_gid;
Packit 6bd9ab
    cfg->uidname = strdup(token);
Packit 6bd9ab
    return;
Packit 6bd9ab
  }
Packit 6bd9ab
  /* log an error */
Packit 6bd9ab
  log_log(LOG_ERR, "%s:%d: %s: not a valid uid: '%s'",
Packit 6bd9ab
          filename, lnr, keyword, token);
Packit 6bd9ab
  exit(EXIT_FAILURE);
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static void handle_gid(const char *filename, int lnr,
Packit 6bd9ab
                       const char *keyword, char *line,
Packit 6bd9ab
                       gid_t *gid)
Packit 6bd9ab
{
Packit 6bd9ab
  char token[32];
Packit 6bd9ab
  struct group *grent;
Packit 6bd9ab
  char *tmp;
Packit 6bd9ab
  check_argumentcount(filename, lnr, keyword,
Packit 6bd9ab
                      get_token(&line, token, sizeof(token)) != NULL);
Packit 6bd9ab
  get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
  /* check if it is a valid numerical gid */
Packit 6bd9ab
  errno = 0;
Packit 6bd9ab
  *gid = strtogid(token, &tmp, 10);
Packit 6bd9ab
  if ((*token != '\0') && (*tmp == '\0') && (errno == 0) && (strchr(token, '-') == NULL))
Packit 6bd9ab
    return;
Packit 6bd9ab
  /* find by name */
Packit 6bd9ab
  grent = getgrnam(token);
Packit 6bd9ab
  if (grent != NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    *gid = grent->gr_gid;
Packit 6bd9ab
    return;
Packit 6bd9ab
  }
Packit 6bd9ab
  /* log an error */
Packit 6bd9ab
  log_log(LOG_ERR, "%s:%d: %s: not a valid gid: '%s'",
Packit 6bd9ab
          filename, lnr, keyword, token);
Packit 6bd9ab
  exit(EXIT_FAILURE);
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static int parse_loglevel(const char *filename, int lnr, const char *value)
Packit 6bd9ab
{
Packit 6bd9ab
  if (strcasecmp(value, "crit") == 0)
Packit 6bd9ab
    return LOG_CRIT;
Packit 6bd9ab
  else if ((strcasecmp(value, "error") == 0) || (strcasecmp(value, "err") == 0))
Packit 6bd9ab
    return LOG_ERR;
Packit 6bd9ab
  else if (strcasecmp(value, "warning")==0)
Packit 6bd9ab
    return LOG_WARNING;
Packit 6bd9ab
  else if (strcasecmp(value, "notice")==0)
Packit 6bd9ab
    return LOG_NOTICE;
Packit 6bd9ab
  else if (strcasecmp(value, "info")==0)
Packit 6bd9ab
    return LOG_INFO;
Packit 6bd9ab
  else if (strcasecmp(value, "debug")==0)
Packit 6bd9ab
    return LOG_DEBUG;
Packit 6bd9ab
  else
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: not a log level '%s'",
Packit 6bd9ab
            filename, lnr, value);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static void handle_log(const char *filename, int lnr,
Packit 6bd9ab
                       const char *keyword, char *line)
Packit 6bd9ab
{
Packit 6bd9ab
  int level = LOG_INFO;
Packit 6bd9ab
  char scheme[64];
Packit 6bd9ab
  char loglevel[32];
Packit 6bd9ab
  check_argumentcount(filename, lnr, keyword,
Packit 6bd9ab
                      get_token(&line, scheme, sizeof(scheme)) != NULL);
Packit 6bd9ab
  if (get_token(&line, loglevel, sizeof(loglevel)) != NULL)
Packit 6bd9ab
    level = parse_loglevel(filename, lnr, loglevel);
Packit 6bd9ab
  get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
  if (strcasecmp(scheme, "none") == 0)
Packit 6bd9ab
    log_addlogging_none();
Packit 6bd9ab
  else if (strcasecmp(scheme, "syslog") == 0)
Packit 6bd9ab
    log_addlogging_syslog(level);
Packit 6bd9ab
  else if (scheme[0] == '/')
Packit 6bd9ab
    log_addlogging_file(level, scheme);
Packit 6bd9ab
  else
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: %s: invalid argument '%s'",
Packit 6bd9ab
            filename, lnr, keyword, scheme);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
/* add a single URI to the list of URIs in the configuration */
Packit 6bd9ab
static void add_uri(const char *filename, int lnr,
Packit 6bd9ab
                    struct ldap_config *cfg, const char *uri)
Packit 6bd9ab
{
Packit 6bd9ab
  int i;
Packit 6bd9ab
  /* find the place where to insert the URI */
Packit 6bd9ab
  for (i = 0; cfg->uris[i].uri != NULL; i++)
Packit 6bd9ab
    /* nothing */ ;
Packit 6bd9ab
  /* check for room */
Packit 6bd9ab
  if (i >= NSS_LDAP_CONFIG_MAX_URIS)
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: maximum number of URIs exceeded",
Packit 6bd9ab
            filename, lnr);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  /* append URI to list */
Packit 6bd9ab
  cfg->uris[i].uri = xstrdup(uri);
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
#ifdef HAVE_LDAP_DOMAIN2HOSTLIST
Packit 6bd9ab
/* return the domain name of the current host
Packit 6bd9ab
   the returned string must be freed by caller */
Packit 6bd9ab
static const char *cfg_getdomainname(const char *filename, int lnr)
Packit 6bd9ab
{
Packit 6bd9ab
  const char *fqdn, *domain;
Packit 6bd9ab
  fqdn = getfqdn();
Packit 6bd9ab
  if ((fqdn != NULL) && ((domain = strchr(fqdn, '.')) != NULL) && (domain[1] != '\0'))
Packit 6bd9ab
    return domain + 1;
Packit 6bd9ab
  log_log(LOG_ERR, "%s:%d: unable to determinate a domain name",
Packit 6bd9ab
          filename, lnr);
Packit 6bd9ab
  exit(EXIT_FAILURE);
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
/* add URIs by doing DNS queries for SRV records */
Packit 6bd9ab
static void add_uris_from_dns(const char *filename, int lnr,
Packit 6bd9ab
                              struct ldap_config *cfg, const char *domain)
Packit 6bd9ab
{
Packit 6bd9ab
  int rc;
Packit 6bd9ab
  char *hostlist = NULL, *nxt;
Packit 6bd9ab
  char buf[BUFLEN_HOSTNAME + sizeof("ldap://")];
Packit 6bd9ab
  log_log(LOG_DEBUG, "query %s for SRV records", domain);
Packit 6bd9ab
  rc = ldap_domain2hostlist(domain, &hostlist);
Packit 6bd9ab
  if (rc != LDAP_SUCCESS)
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: no servers found in DNS zone %s: %s",
Packit 6bd9ab
            filename, lnr, domain, ldap_err2string(rc));
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  if ((hostlist == NULL) || (*hostlist == '\0'))
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: no servers found in DNS zone %s",
Packit 6bd9ab
            filename, lnr, domain);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  /* hostlist is a space-separated list of host names that we use to build
Packit 6bd9ab
     URIs */
Packit 6bd9ab
  while (hostlist != NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    /* find the next space and split the string there */
Packit 6bd9ab
    nxt = strchr(hostlist, ' ');
Packit 6bd9ab
    if (nxt != NULL)
Packit 6bd9ab
    {
Packit 6bd9ab
      *nxt = '\0';
Packit 6bd9ab
      nxt++;
Packit 6bd9ab
    }
Packit 6bd9ab
    /* if port is 636, use ldaps:// URI */
Packit 6bd9ab
    if ((strlen(hostlist) > 4) && (strcmp(hostlist + strlen(hostlist) - 4, ":636") == 0))
Packit 6bd9ab
    {
Packit 6bd9ab
      hostlist[strlen(hostlist) - 4] = '\0';
Packit 6bd9ab
      if (mysnprintf(buf, sizeof(buf), "ldaps://%s", hostlist))
Packit 6bd9ab
      {
Packit 6bd9ab
        log_log(LOG_ERR, "add_uris_from_dns(): buf buffer too small (%lu required)",
Packit 6bd9ab
                (unsigned long) strlen(hostlist) + 8);
Packit 6bd9ab
        exit(EXIT_FAILURE);
Packit 6bd9ab
      }
Packit 6bd9ab
    }
Packit 6bd9ab
    else
Packit 6bd9ab
    {
Packit 6bd9ab
      /* strip default port number */
Packit 6bd9ab
      if ((strlen(hostlist) > 4) && (strcmp(hostlist + strlen(hostlist) - 4, ":389") == 0))
Packit 6bd9ab
        hostlist[strlen(hostlist) - 4] = '\0';
Packit 6bd9ab
      if (mysnprintf(buf, sizeof(buf), "ldap://%s", hostlist))
Packit 6bd9ab
      {
Packit 6bd9ab
        log_log(LOG_ERR, "add_uris_from_dns(): buf buffer too small (%lu required)",
Packit 6bd9ab
                (unsigned long) strlen(hostlist) + 7);
Packit 6bd9ab
        exit(EXIT_FAILURE);
Packit 6bd9ab
      }
Packit 6bd9ab
    }
Packit 6bd9ab
    log_log(LOG_DEBUG, "add_uris_from_dns(): found uri: %s", buf);
Packit 6bd9ab
    add_uri(filename, lnr, cfg, buf);
Packit 6bd9ab
    /* get next entry from list */
Packit 6bd9ab
    hostlist = nxt;
Packit 6bd9ab
  }
Packit 6bd9ab
}
Packit 6bd9ab
#endif /* HAVE_LDAP_DOMAIN2HOSTLIST */
Packit 6bd9ab
Packit 6bd9ab
/* check that the file is not world readable */
Packit 6bd9ab
static void check_permissions(const char *filename, const char *keyword)
Packit 6bd9ab
{
Packit 6bd9ab
  struct stat sb;
Packit 6bd9ab
  /* get file status */
Packit 6bd9ab
  if (stat(filename, &sb))
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "cannot stat() %s: %s", filename, strerror(errno));
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  /* check permissions */
Packit 6bd9ab
  if ((sb.st_mode & 0007) != 0)
Packit 6bd9ab
  {
Packit 6bd9ab
    if (keyword != NULL)
Packit 6bd9ab
      log_log(LOG_ERR, "%s: file should not be world readable if %s is set",
Packit 6bd9ab
              filename, keyword);
Packit 6bd9ab
    else
Packit 6bd9ab
      log_log(LOG_ERR, "%s: file should not be world readable", filename);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
/* check whether the specified path is readable */
Packit 6bd9ab
static void check_readable(const char *filename, int lnr,
Packit 6bd9ab
                       const char *keyword, const char *path)
Packit 6bd9ab
{
Packit 6bd9ab
  if (access(path, R_OK) != 0)
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: %s: error accessing %s: %s",
Packit 6bd9ab
            filename, lnr, keyword, path, strerror(errno));
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
/* check whether the specified path is a directory */
Packit 6bd9ab
static void check_dir(const char *filename, int lnr,
Packit 6bd9ab
                      const char *keyword, const char *path)
Packit 6bd9ab
{
Packit 6bd9ab
  struct stat sb;
Packit 6bd9ab
  if (stat(path, &sb))
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: %s: cannot stat() %s: %s",
Packit 6bd9ab
            filename, lnr, keyword, path, strerror(errno));
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  if (!S_ISDIR(sb.st_mode))
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: %s: %s is not a directory",
Packit 6bd9ab
            filename, lnr, keyword, path);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static void handle_krb5_ccname(const char *filename, int lnr,
Packit 6bd9ab
                               const char *keyword, char *line)
Packit 6bd9ab
{
Packit 6bd9ab
  char token[80];
Packit 6bd9ab
  const char *ccname;
Packit 6bd9ab
  const char *ccfile;
Packit 6bd9ab
  size_t ccenvlen;
Packit 6bd9ab
  char *ccenv;
Packit 6bd9ab
#ifdef HAVE_GSS_KRB5_CCACHE_NAME
Packit 6bd9ab
  OM_uint32 minor_status;
Packit 6bd9ab
#endif /* HAVE_GSS_KRB5_CCACHE_NAME */
Packit 6bd9ab
  /* get token */
Packit 6bd9ab
  check_argumentcount(filename, lnr, keyword,
Packit 6bd9ab
                      (get_token(&line, token, sizeof(token)) != NULL));
Packit 6bd9ab
  get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
  /* set default kerberos ticket cache for SASL-GSSAPI */
Packit 6bd9ab
  ccname = token;
Packit 6bd9ab
  /* check that cache exists and is readable if it is a file */
Packit 6bd9ab
  if ((strncasecmp(ccname, "FILE:", sizeof("FILE:") - 1) == 0) ||
Packit 6bd9ab
      (strncasecmp(ccname, "WRFILE:", sizeof("WRFILE:") - 1) == 0))
Packit 6bd9ab
  {
Packit 6bd9ab
    ccfile = strchr(ccname, ':') + 1;
Packit 6bd9ab
    check_readable(filename, lnr, keyword, ccfile);
Packit 6bd9ab
  }
Packit 6bd9ab
  /* set the environment variable (we have a memory leak if this option
Packit 6bd9ab
     is set multiple times) */
Packit 6bd9ab
  ccenvlen = strlen(ccname) + sizeof("KRB5CCNAME=");
Packit 6bd9ab
  ccenv = (char *)malloc(ccenvlen);
Packit 6bd9ab
  if (ccenv == NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_CRIT, "malloc() failed to allocate memory");
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  mysnprintf(ccenv, ccenvlen, "KRB5CCNAME=%s", ccname);
Packit 6bd9ab
  putenv(ccenv);
Packit 6bd9ab
#ifdef HAVE_GSS_KRB5_CCACHE_NAME
Packit 6bd9ab
  /* set the name with gss_krb5_ccache_name() */
Packit 6bd9ab
  if (gss_krb5_ccache_name(&minor_status, ccname, NULL) != GSS_S_COMPLETE)
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: unable to set default credential cache: %s",
Packit 6bd9ab
            filename, lnr, ccname);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
#endif /* HAVE_GSS_KRB5_CCACHE_NAME */
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static enum ldap_map_selector parse_map(const char *value)
Packit 6bd9ab
{
Packit 6bd9ab
  if ((strcasecmp(value, "alias") == 0) || (strcasecmp(value, "aliases") == 0))
Packit 6bd9ab
    return LM_ALIASES;
Packit 6bd9ab
  else if ((strcasecmp(value, "ether") == 0) || (strcasecmp(value, "ethers") == 0))
Packit 6bd9ab
    return LM_ETHERS;
Packit 6bd9ab
  else if (strcasecmp(value, "group") == 0)
Packit 6bd9ab
    return LM_GROUP;
Packit 6bd9ab
  else if ((strcasecmp(value, "host") == 0) || (strcasecmp(value, "hosts") == 0))
Packit 6bd9ab
    return LM_HOSTS;
Packit 6bd9ab
  else if (strcasecmp(value, "netgroup") == 0)
Packit 6bd9ab
    return LM_NETGROUP;
Packit 6bd9ab
  else if ((strcasecmp(value, "network") == 0) || (strcasecmp(value, "networks") == 0))
Packit 6bd9ab
    return LM_NETWORKS;
Packit 6bd9ab
  else if (strcasecmp(value, "passwd") == 0)
Packit 6bd9ab
    return LM_PASSWD;
Packit 6bd9ab
  else if ((strcasecmp(value, "protocol") == 0) || (strcasecmp(value, "protocols") == 0))
Packit 6bd9ab
    return LM_PROTOCOLS;
Packit 6bd9ab
  else if (strcasecmp(value, "rpc") == 0)
Packit 6bd9ab
    return LM_RPC;
Packit 6bd9ab
  else if ((strcasecmp(value, "service") == 0) || (strcasecmp(value, "services") == 0))
Packit 6bd9ab
    return LM_SERVICES;
Packit 6bd9ab
  else if (strcasecmp(value, "shadow") == 0)
Packit 6bd9ab
    return LM_SHADOW;
Packit 6bd9ab
  else if (strcasecmp(value, "nfsidmap") == 0)
Packit 6bd9ab
    return LM_NFSIDMAP;
Packit 6bd9ab
  /* unknown map */
Packit 6bd9ab
  return LM_NONE;
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
/* check to see if the line begins with a named map */
Packit 6bd9ab
static enum ldap_map_selector get_map(char **line)
Packit 6bd9ab
{
Packit 6bd9ab
  char token[32];
Packit 6bd9ab
  char *old;
Packit 6bd9ab
  enum ldap_map_selector map;
Packit 6bd9ab
  /* get the token */
Packit 6bd9ab
  old = *line;
Packit 6bd9ab
  if (get_token(line, token, sizeof(token)) == NULL)
Packit 6bd9ab
    return LM_NONE;
Packit 6bd9ab
  /* see if we found a map */
Packit 6bd9ab
  map = parse_map(token);
Packit 6bd9ab
  /* unknown map, return to the previous state */
Packit 6bd9ab
  if (map == LM_NONE)
Packit 6bd9ab
    *line = old;
Packit 6bd9ab
  return map;
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static const char *print_map(enum ldap_map_selector map)
Packit 6bd9ab
{
Packit 6bd9ab
  switch (map)
Packit 6bd9ab
  {
Packit 6bd9ab
    case LM_ALIASES:   return "aliases";
Packit 6bd9ab
    case LM_ETHERS:    return "ethers";
Packit 6bd9ab
    case LM_GROUP:     return "group";
Packit 6bd9ab
    case LM_HOSTS:     return "hosts";
Packit 6bd9ab
    case LM_NETGROUP:  return "netgroup";
Packit 6bd9ab
    case LM_NETWORKS:  return "networks";
Packit 6bd9ab
    case LM_PASSWD:    return "passwd";
Packit 6bd9ab
    case LM_PROTOCOLS: return "protocols";
Packit 6bd9ab
    case LM_RPC:       return "rpc";
Packit 6bd9ab
    case LM_SERVICES:  return "services";
Packit 6bd9ab
    case LM_SHADOW:    return "shadow";
Packit 6bd9ab
    case LM_NFSIDMAP:  return "nfsidmap";
Packit 6bd9ab
    case LM_NONE:
Packit 6bd9ab
    default:           return "???";
Packit 6bd9ab
  }
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static void handle_base(const char *filename, int lnr,
Packit 6bd9ab
                        const char *keyword, char *line,
Packit 6bd9ab
                        struct ldap_config *cfg)
Packit 6bd9ab
{
Packit 6bd9ab
  const char **bases;
Packit 6bd9ab
  int i;
Packit 6bd9ab
  char *value;
Packit 6bd9ab
#ifdef HAVE_LDAP_DOMAIN2DN
Packit 6bd9ab
  const char *domain = NULL;
Packit 6bd9ab
  char *domaindn = NULL;
Packit 6bd9ab
#endif /* HAVE_LDAP_DOMAIN2DN */
Packit 6bd9ab
  /* get the list of bases to update */
Packit 6bd9ab
  bases = base_get_var(get_map(&line));
Packit 6bd9ab
  if (bases == NULL)
Packit 6bd9ab
    bases = cfg->bases;
Packit 6bd9ab
  /* rest of the line is the value */
Packit 6bd9ab
  value = get_linedup(filename, lnr, keyword, &line);
Packit 6bd9ab
  /* if the base is "DOMAIN" use the domain name */
Packit 6bd9ab
  if (strcasecmp(value, "domain") == 0)
Packit 6bd9ab
  {
Packit 6bd9ab
#ifdef HAVE_LDAP_DOMAIN2DN
Packit 6bd9ab
    free(value);
Packit 6bd9ab
    domain = cfg_getdomainname(filename, lnr);
Packit 6bd9ab
    ldap_domain2dn(domain, &domaindn);
Packit 6bd9ab
    log_log(LOG_DEBUG, "set_base(): setting base to %s from domain",
Packit 6bd9ab
            domaindn);
Packit 6bd9ab
    value = xstrdup(domaindn);
Packit 6bd9ab
#else /* not HAVE_LDAP_DOMAIN2DN */
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: value %s not supported on platform",
Packit 6bd9ab
            filename, lnr, value);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
#endif /* not HAVE_LDAP_DOMAIN2DN */
Packit 6bd9ab
  }
Packit 6bd9ab
  /* find the spot in the list of bases */
Packit 6bd9ab
  for (i = 0; i < NSS_LDAP_CONFIG_MAX_BASES; i++)
Packit 6bd9ab
    if (bases[i] == NULL)
Packit 6bd9ab
    {
Packit 6bd9ab
      bases[i] = value;
Packit 6bd9ab
      return;
Packit 6bd9ab
    }
Packit 6bd9ab
  /* no free spot found */
Packit 6bd9ab
  log_log(LOG_ERR, "%s:%d: maximum number of base options per map (%d) exceeded",
Packit 6bd9ab
          filename, lnr, NSS_LDAP_CONFIG_MAX_BASES);
Packit 6bd9ab
  exit(EXIT_FAILURE);
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static void handle_scope(const char *filename, int lnr,
Packit 6bd9ab
                         const char *keyword, char *line,
Packit 6bd9ab
                         struct ldap_config *cfg)
Packit 6bd9ab
{
Packit 6bd9ab
  char token[32];
Packit 6bd9ab
  int *var;
Packit 6bd9ab
  var = scope_get_var(get_map(&line));
Packit 6bd9ab
  check_argumentcount(filename, lnr, keyword,
Packit 6bd9ab
                      get_token(&line, token, sizeof(token)) != NULL);
Packit 6bd9ab
  get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
  if (var == NULL)
Packit 6bd9ab
    var = &cfg->scope;
Packit 6bd9ab
  if ((strcasecmp(token, "sub") == 0) || (strcasecmp(token, "subtree") == 0))
Packit 6bd9ab
    *var = LDAP_SCOPE_SUBTREE;
Packit 6bd9ab
  else if ((strcasecmp(token, "one") == 0) || (strcasecmp(token, "onelevel") == 0))
Packit 6bd9ab
    *var = LDAP_SCOPE_ONELEVEL;
Packit 6bd9ab
  else if (strcasecmp(token, "base") == 0)
Packit 6bd9ab
    *var = LDAP_SCOPE_BASE;
Packit 6bd9ab
#ifdef LDAP_SCOPE_CHILDREN
Packit 6bd9ab
  else if (strcasecmp(token, "children") == 0)
Packit 6bd9ab
    *var = LDAP_SCOPE_CHILDREN;
Packit 6bd9ab
#endif /* LDAP_SCOPE_CHILDREN */
Packit 6bd9ab
  else
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: not a scope argument: '%s'",
Packit 6bd9ab
            filename, lnr, token);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static const char *print_scope(int scope)
Packit 6bd9ab
{
Packit 6bd9ab
  switch (scope)
Packit 6bd9ab
  {
Packit 6bd9ab
    case LDAP_SCOPE_SUBTREE:  return "sub";
Packit 6bd9ab
    case LDAP_SCOPE_ONELEVEL: return "one";
Packit 6bd9ab
    case LDAP_SCOPE_BASE:     return "base";
Packit 6bd9ab
#ifdef LDAP_SCOPE_CHILDREN
Packit 6bd9ab
    case LDAP_SCOPE_CHILDREN: return "children";
Packit 6bd9ab
#endif /* LDAP_SCOPE_CHILDREN */
Packit 6bd9ab
    default:                  return "???";
Packit 6bd9ab
  }
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static void handle_deref(const char *filename, int lnr,
Packit 6bd9ab
                         const char *keyword, char *line,
Packit 6bd9ab
                         struct ldap_config *cfg)
Packit 6bd9ab
{
Packit 6bd9ab
  char token[32];
Packit 6bd9ab
  check_argumentcount(filename, lnr, keyword,
Packit 6bd9ab
                      get_token(&line, token, sizeof(token)) != NULL);
Packit 6bd9ab
  get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
  if (strcasecmp(token, "never") == 0)
Packit 6bd9ab
    cfg->deref = LDAP_DEREF_NEVER;
Packit 6bd9ab
  else if (strcasecmp(token, "searching") == 0)
Packit 6bd9ab
    cfg->deref = LDAP_DEREF_SEARCHING;
Packit 6bd9ab
  else if (strcasecmp(token, "finding") == 0)
Packit 6bd9ab
    cfg->deref = LDAP_DEREF_FINDING;
Packit 6bd9ab
  else if (strcasecmp(token, "always") == 0)
Packit 6bd9ab
    cfg->deref = LDAP_DEREF_ALWAYS;
Packit 6bd9ab
  else
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: wrong argument: '%s'", filename, lnr, token);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static const char *print_deref(int deref)
Packit 6bd9ab
{
Packit 6bd9ab
  switch (deref)
Packit 6bd9ab
  {
Packit 6bd9ab
    case LDAP_DEREF_NEVER:     return "never";
Packit 6bd9ab
    case LDAP_DEREF_SEARCHING: return "searching";
Packit 6bd9ab
    case LDAP_DEREF_FINDING:   return "finding";
Packit 6bd9ab
    case LDAP_DEREF_ALWAYS:    return "always";
Packit 6bd9ab
    default:                   return "???";
Packit 6bd9ab
  }
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static void handle_filter(const char *filename, int lnr,
Packit 6bd9ab
                          const char *keyword, char *line)
Packit 6bd9ab
{
Packit 6bd9ab
  const char **var;
Packit 6bd9ab
  const char *map = line;
Packit 6bd9ab
  var = filter_get_var(get_map(&line));
Packit 6bd9ab
  if (var == NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: unknown map: '%s'", filename, lnr, map);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  check_argumentcount(filename, lnr, keyword, (line != NULL) && (*line != '\0'));
Packit 6bd9ab
  /* check if the value will be changed */
Packit 6bd9ab
  if (strcmp(*var, line) != 0)
Packit 6bd9ab
  {
Packit 6bd9ab
    /* Note: we have a memory leak here if a single mapping is changed
Packit 6bd9ab
       multiple times in one config (deemed not a problem) */
Packit 6bd9ab
    *var = xstrdup(line);
Packit 6bd9ab
  }
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
/* this function modifies the statement argument passed */
Packit 6bd9ab
static void handle_map(const char *filename, int lnr,
Packit 6bd9ab
                       const char *keyword, char *line)
Packit 6bd9ab
{
Packit 6bd9ab
  enum ldap_map_selector map;
Packit 6bd9ab
  const char **var;
Packit 6bd9ab
  char oldatt[32], *newatt;
Packit 6bd9ab
  /* get the map */
Packit 6bd9ab
  if ((map = get_map(&line)) == LM_NONE)
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: unknown map: '%s'", filename, lnr, line);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  /* read the other tokens */
Packit 6bd9ab
  check_argumentcount(filename, lnr, keyword,
Packit 6bd9ab
                      (get_token(&line, oldatt, sizeof(oldatt)) != NULL));
Packit 6bd9ab
  newatt = get_linedup(filename, lnr, keyword, &line);
Packit 6bd9ab
  /* change attribute mapping */
Packit 6bd9ab
  var = attmap_get_var(map, oldatt);
Packit 6bd9ab
  if (var == NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: unknown attribute to map: '%s'",
Packit 6bd9ab
            filename, lnr, oldatt);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  if (attmap_set_mapping(var, newatt) == NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: attribute %s cannot be an expression",
Packit 6bd9ab
            filename, lnr, oldatt);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  free(newatt);
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
#ifdef LDAP_OPT_X_TLS
Packit 6bd9ab
static const char *print_ssl(int ssl)
Packit 6bd9ab
{
Packit 6bd9ab
  switch (ssl)
Packit 6bd9ab
  {
Packit 6bd9ab
    case SSL_OFF:       return "off";
Packit 6bd9ab
    case SSL_START_TLS: return "start_tls";
Packit 6bd9ab
    case SSL_LDAPS:     return "on";
Packit 6bd9ab
    default:            return "???";
Packit 6bd9ab
  }
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static void handle_tls_reqcert(const char *filename, int lnr,
Packit 6bd9ab
                               const char *keyword, char *line)
Packit 6bd9ab
{
Packit 6bd9ab
  char token[16];
Packit 6bd9ab
  int value, rc;
Packit 6bd9ab
  /* get token */
Packit 6bd9ab
  check_argumentcount(filename, lnr, keyword,
Packit 6bd9ab
                      get_token(&line, token, sizeof(token)) != NULL);
Packit 6bd9ab
  get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
  /* check if it is a valid value for tls_reqcert option */
Packit 6bd9ab
  if ((strcasecmp(token, "never") == 0) || (strcasecmp(token, "no") == 0))
Packit 6bd9ab
    value = LDAP_OPT_X_TLS_NEVER;
Packit 6bd9ab
  else if (strcasecmp(token, "allow") == 0)
Packit 6bd9ab
    value = LDAP_OPT_X_TLS_ALLOW;
Packit 6bd9ab
  else if (strcasecmp(token, "try") == 0)
Packit 6bd9ab
    value = LDAP_OPT_X_TLS_TRY;
Packit 6bd9ab
  else if ((strcasecmp(token, "demand") == 0) ||
Packit 6bd9ab
           (strcasecmp(token, "yes") == 0))
Packit 6bd9ab
    value = LDAP_OPT_X_TLS_DEMAND;
Packit 6bd9ab
  else if (strcasecmp(token, "hard") == 0)
Packit 6bd9ab
    value = LDAP_OPT_X_TLS_HARD;
Packit 6bd9ab
  else
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: %s: invalid argument: '%s'",
Packit 6bd9ab
            filename, lnr, keyword, token);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  log_log(LOG_DEBUG, "ldap_set_option(LDAP_OPT_X_TLS_REQUIRE_CERT,%s)", token);
Packit 6bd9ab
  LDAP_SET_OPTION(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &value);
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static const char *print_tls_reqcert(int value)
Packit 6bd9ab
{
Packit 6bd9ab
  switch (value)
Packit 6bd9ab
  {
Packit 6bd9ab
    case LDAP_OPT_X_TLS_NEVER:  return "never";
Packit 6bd9ab
    case LDAP_OPT_X_TLS_ALLOW:  return "allow";
Packit 6bd9ab
    case LDAP_OPT_X_TLS_TRY:    return "try";
Packit 6bd9ab
    case LDAP_OPT_X_TLS_DEMAND: return "demand";
Packit 6bd9ab
    case LDAP_OPT_X_TLS_HARD:   return "hard";
Packit 6bd9ab
    default:                    return "???";
Packit 6bd9ab
  }
Packit 6bd9ab
}
Packit 6bd9ab
#endif /* LDAP_OPT_X_TLS */
Packit 6bd9ab
Packit 6bd9ab
/* this function modifies the line argument passed */
Packit 6bd9ab
static void handle_nss_initgroups_ignoreusers(
Packit 6bd9ab
                const char *filename, int lnr,
Packit 6bd9ab
                const char *keyword, char *line, struct ldap_config *cfg)
Packit 6bd9ab
{
Packit 6bd9ab
  char token[MAX_LINE_LENGTH];
Packit 6bd9ab
  char *username, *next;
Packit 6bd9ab
  struct passwd *pwent;
Packit 6bd9ab
  check_argumentcount(filename, lnr, keyword, (line != NULL) && (*line != '\0'));
Packit 6bd9ab
  if (cfg->nss_initgroups_ignoreusers == NULL)
Packit 6bd9ab
    cfg->nss_initgroups_ignoreusers = set_new();
Packit 6bd9ab
  while (get_token(&line, token, sizeof(token)) != NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    if (strcasecmp(token, "alllocal") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      /* go over all users (this will work because nslcd is not yet running) */
Packit 6bd9ab
      setpwent();
Packit 6bd9ab
      while ((pwent = getpwent()) != NULL)
Packit 6bd9ab
        set_add(cfg->nss_initgroups_ignoreusers, pwent->pw_name);
Packit 6bd9ab
      endpwent();
Packit 6bd9ab
    }
Packit 6bd9ab
    else
Packit 6bd9ab
    {
Packit 6bd9ab
      next = token;
Packit 6bd9ab
      while (*next != '\0')
Packit 6bd9ab
      {
Packit 6bd9ab
        username = next;
Packit 6bd9ab
        /* find the end of the current username */
Packit 6bd9ab
        while ((*next != '\0') && (*next != ','))
Packit 6bd9ab
          next++;
Packit 6bd9ab
        if (*next == ',')
Packit 6bd9ab
        {
Packit 6bd9ab
          *next = '\0';
Packit 6bd9ab
          next++;
Packit 6bd9ab
        }
Packit 6bd9ab
        /* check if user exists (but add anyway) */
Packit 6bd9ab
        pwent = getpwnam(username);
Packit 6bd9ab
        if (pwent == NULL)
Packit 6bd9ab
          log_log(LOG_ERR, "%s:%d: user '%s' does not exist",
Packit 6bd9ab
                  filename, lnr, username);
Packit 6bd9ab
        set_add(cfg->nss_initgroups_ignoreusers, username);
Packit 6bd9ab
      }
Packit 6bd9ab
    }
Packit 6bd9ab
  }
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static void handle_validnames(const char *filename, int lnr,
Packit 6bd9ab
                              const char *keyword, char *line,
Packit 6bd9ab
                              struct ldap_config *cfg)
Packit 6bd9ab
{
Packit 6bd9ab
  char *value;
Packit 6bd9ab
  int i, l;
Packit 6bd9ab
  int flags = REG_EXTENDED | REG_NOSUB;
Packit 6bd9ab
  /* the rest of the line should be a regular expression */
Packit 6bd9ab
  value = get_linedup(filename, lnr, keyword, &line);
Packit 6bd9ab
  if (cfg->validnames_str != NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    free(cfg->validnames_str);
Packit 6bd9ab
    regfree(&cfg->validnames);
Packit 6bd9ab
  }
Packit 6bd9ab
  cfg->validnames_str = strdup(value);
Packit 6bd9ab
  /* check formatting and update flags */
Packit 6bd9ab
  if (value[0] != '/')
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: regular expression incorrectly delimited",
Packit 6bd9ab
            filename, lnr);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  l = strlen(value);
Packit 6bd9ab
  if (value[l - 1] == 'i')
Packit 6bd9ab
  {
Packit 6bd9ab
    value[l - 1] = '\0';
Packit 6bd9ab
    l--;
Packit 6bd9ab
    flags |= REG_ICASE;
Packit 6bd9ab
  }
Packit 6bd9ab
  if (value[l - 1] != '/')
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: regular expression incorrectly delimited",
Packit 6bd9ab
            filename, lnr);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  value[l - 1] = '\0';
Packit 6bd9ab
  /* compile the regular expression */
Packit 6bd9ab
  if ((i = regcomp(&cfg->validnames, value + 1, flags)) != 0)
Packit 6bd9ab
  {
Packit 6bd9ab
    /* get the error message */
Packit 6bd9ab
    l = regerror(i, &cfg->validnames, NULL, 0);
Packit 6bd9ab
    value = malloc(l);
Packit 6bd9ab
    if (value == NULL)
Packit 6bd9ab
      log_log(LOG_ERR, "%s:%d: invalid regular expression", filename, lnr);
Packit 6bd9ab
    else
Packit 6bd9ab
    {
Packit 6bd9ab
      regerror(i, &cfg->validnames, value, l);
Packit 6bd9ab
      log_log(LOG_ERR, "%s:%d: invalid regular expression: %s",
Packit 6bd9ab
              filename, lnr, value);
Packit 6bd9ab
    }
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  free(value);
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static void check_search_variables(
Packit 6bd9ab
                const char *filename, int lnr,
Packit 6bd9ab
                const char *expression)
Packit 6bd9ab
{
Packit 6bd9ab
  SET *set;
Packit 6bd9ab
  const char **list;
Packit 6bd9ab
  int i;
Packit 6bd9ab
  set = expr_vars(expression, NULL);
Packit 6bd9ab
  list = set_tolist(set);
Packit 6bd9ab
  if (list == NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_CRIT,
Packit 6bd9ab
            "check_search_variables(): malloc() failed to allocate memory");
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  for (i = 0; list[i] != NULL; i++)
Packit 6bd9ab
  {
Packit 6bd9ab
    if ((strcmp(list[i], "username") != 0) &&
Packit 6bd9ab
        (strcmp(list[i], "service") != 0) &&
Packit 6bd9ab
        (strcmp(list[i], "ruser") != 0) &&
Packit 6bd9ab
        (strcmp(list[i], "rhost") != 0) &&
Packit 6bd9ab
        (strcmp(list[i], "tty") != 0) &&
Packit 6bd9ab
        (strcmp(list[i], "hostname") != 0) &&
Packit 6bd9ab
        (strcmp(list[i], "fqdn") != 0) &&
Packit 6bd9ab
        (strcmp(list[i], "dn") != 0) &&
Packit 6bd9ab
        (strcmp(list[i], "uid") != 0))
Packit 6bd9ab
    {
Packit 6bd9ab
      log_log(LOG_ERR, "%s:%d: unknown variable $%s", filename, lnr, list[i]);
Packit 6bd9ab
      exit(EXIT_FAILURE);
Packit 6bd9ab
    }
Packit 6bd9ab
  }
Packit 6bd9ab
  /* free memory */
Packit 6bd9ab
  set_free(set);
Packit 6bd9ab
  free(list);
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static void handle_pam_authc_search(
Packit 6bd9ab
                const char *filename, int lnr,
Packit 6bd9ab
                const char *keyword, char *line, struct ldap_config *cfg)
Packit 6bd9ab
{
Packit 6bd9ab
  check_argumentcount(filename, lnr, keyword, (line != NULL) && (*line != '\0'));
Packit 6bd9ab
  cfg->pam_authc_search = xstrdup(line);
Packit 6bd9ab
  /* check the variables used in the expression */
Packit 6bd9ab
  check_search_variables(filename, lnr, cfg->pam_authc_search);
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static void handle_pam_authz_search(
Packit 6bd9ab
                const char *filename, int lnr,
Packit 6bd9ab
                const char *keyword, char *line, struct ldap_config *cfg)
Packit 6bd9ab
{
Packit 6bd9ab
  int i;
Packit 6bd9ab
  check_argumentcount(filename, lnr, keyword, (line != NULL) && (*line != '\0'));
Packit 6bd9ab
  /* find free spot for search filter */
Packit 6bd9ab
  for (i = 0; (i < NSS_LDAP_CONFIG_MAX_AUTHZ_SEARCHES) && (cfg->pam_authz_searches[i] != NULL);
Packit 6bd9ab
       i++)
Packit 6bd9ab
    /* nothing */ ;
Packit 6bd9ab
  if (i >= NSS_LDAP_CONFIG_MAX_AUTHZ_SEARCHES)
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: maximum number of pam_authz_search options (%d) exceeded",
Packit 6bd9ab
            filename, lnr, NSS_LDAP_CONFIG_MAX_AUTHZ_SEARCHES);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  cfg->pam_authz_searches[i] = xstrdup(line);
Packit 6bd9ab
  /* check the variables used in the expression */
Packit 6bd9ab
  check_search_variables(filename, lnr, cfg->pam_authz_searches[i]);
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static void handle_pam_password_prohibit_message(
Packit 6bd9ab
                const char *filename, int lnr,
Packit 6bd9ab
                const char *keyword, char *line, struct ldap_config *cfg)
Packit 6bd9ab
{
Packit 6bd9ab
  char *value;
Packit 6bd9ab
  int l;
Packit 6bd9ab
  /* the rest of the line should be a message */
Packit 6bd9ab
  value = get_linedup(filename, lnr, keyword, &line);
Packit 6bd9ab
  /* strip quotes if they are present */
Packit 6bd9ab
  l = strlen(value);
Packit 6bd9ab
  if ((value[0] == '\"') && (value[l - 1] == '\"'))
Packit 6bd9ab
  {
Packit 6bd9ab
    value[l - 1] = '\0';
Packit 6bd9ab
    value++;
Packit 6bd9ab
  }
Packit 6bd9ab
  cfg->pam_password_prohibit_message = value;
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static void handle_reconnect_invalidate(
Packit 6bd9ab
                const char *filename, int lnr,
Packit 6bd9ab
                const char *keyword, char *line, struct ldap_config *cfg)
Packit 6bd9ab
{
Packit 6bd9ab
  char token[MAX_LINE_LENGTH];
Packit 6bd9ab
  char *name, *next;
Packit 6bd9ab
  enum ldap_map_selector map;
Packit 6bd9ab
  check_argumentcount(filename, lnr, keyword, (line != NULL) && (*line != '\0'));
Packit 6bd9ab
  while (get_token(&line, token, sizeof(token)) != NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    next = token;
Packit 6bd9ab
    while (*next != '\0')
Packit 6bd9ab
    {
Packit 6bd9ab
      name = next;
Packit 6bd9ab
      /* find the end of the current map name */
Packit 6bd9ab
      while ((*next != '\0') && (*next != ','))
Packit 6bd9ab
        next++;
Packit 6bd9ab
      if (*next == ',')
Packit 6bd9ab
      {
Packit 6bd9ab
        *next = '\0';
Packit 6bd9ab
        next++;
Packit 6bd9ab
      }
Packit 6bd9ab
      /* check if map name exists */
Packit 6bd9ab
      map = parse_map(name);
Packit 6bd9ab
      if (map == LM_NONE)
Packit 6bd9ab
      {
Packit 6bd9ab
        log_log(LOG_ERR, "%s:%d: unknown map: '%s'", filename, lnr, name);
Packit 6bd9ab
        exit(EXIT_FAILURE);
Packit 6bd9ab
      }
Packit 6bd9ab
      cfg->reconnect_invalidate[map] = 1;
Packit 6bd9ab
    }
Packit 6bd9ab
  }
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static void handle_cache(const char *filename, int lnr,
Packit 6bd9ab
                         const char *keyword, char *line,
Packit 6bd9ab
                         struct ldap_config *cfg)
Packit 6bd9ab
{
Packit 6bd9ab
  char cache[16];
Packit 6bd9ab
  time_t value1, value2;
Packit 6bd9ab
  /* get cache map and values */
Packit 6bd9ab
  check_argumentcount(filename, lnr, keyword,
Packit 6bd9ab
                      get_token(&line, cache, sizeof(cache)) != NULL);
Packit 6bd9ab
  value1 = get_time(filename, lnr, keyword, &line);
Packit 6bd9ab
  if ((line != NULL) && (*line != '\0'))
Packit 6bd9ab
    value2 = get_time(filename, lnr, keyword, &line);
Packit 6bd9ab
  else
Packit 6bd9ab
    value2 = value1;
Packit 6bd9ab
  get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
  /* check the cache */
Packit 6bd9ab
  if (strcasecmp(cache, "dn2uid") == 0)
Packit 6bd9ab
  {
Packit 6bd9ab
    cfg->cache_dn2uid_positive = value1;
Packit 6bd9ab
    cfg->cache_dn2uid_negative = value2;
Packit 6bd9ab
  }
Packit 6bd9ab
  else
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:%d: unknown cache: '%s'", filename, lnr, cache);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
/* This function tries to get the LDAP search base from the LDAP server.
Packit 6bd9ab
   Note that this returns a string that has been allocated with strdup().
Packit 6bd9ab
   For this to work the myldap module needs enough configuration information
Packit 6bd9ab
   to make an LDAP connection. */
Packit 6bd9ab
static MUST_USE char *get_base_from_rootdse(void)
Packit 6bd9ab
{
Packit 6bd9ab
  MYLDAP_SESSION *session;
Packit 6bd9ab
  MYLDAP_SEARCH *search;
Packit 6bd9ab
  MYLDAP_ENTRY *entry;
Packit 6bd9ab
  const char *attrs[] = { "+", NULL };
Packit 6bd9ab
  int i;
Packit 6bd9ab
  int rc;
Packit 6bd9ab
  const char **values;
Packit 6bd9ab
  char *base = NULL;
Packit 6bd9ab
  /* initialize session */
Packit 6bd9ab
  session = myldap_create_session();
Packit 6bd9ab
  assert(session != NULL);
Packit 6bd9ab
  /* perform search */
Packit 6bd9ab
  search = myldap_search(session, "", LDAP_SCOPE_BASE, "(objectClass=*)",
Packit 6bd9ab
                         attrs, NULL);
Packit 6bd9ab
  if (search == NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    myldap_session_close(session);
Packit 6bd9ab
    return NULL;
Packit 6bd9ab
  }
Packit 6bd9ab
  /* go over results */
Packit 6bd9ab
  for (i = 0; (entry = myldap_get_entry(search, &rc)) != NULL; i++)
Packit 6bd9ab
  {
Packit 6bd9ab
    /* get defaultNamingContext */
Packit 6bd9ab
    values = myldap_get_values(entry, "defaultNamingContext");
Packit 6bd9ab
    if ((values != NULL) && (values[0] != NULL))
Packit 6bd9ab
    {
Packit 6bd9ab
      base = xstrdup(values[0]);
Packit 6bd9ab
      log_log(LOG_DEBUG, "get_basedn_from_rootdse(): found attribute defaultNamingContext with value %s",
Packit 6bd9ab
              values[0]);
Packit 6bd9ab
      break;
Packit 6bd9ab
    }
Packit 6bd9ab
    /* get namingContexts */
Packit 6bd9ab
    values = myldap_get_values(entry, "namingContexts");
Packit 6bd9ab
    if ((values != NULL) && (values[0] != NULL))
Packit 6bd9ab
    {
Packit 6bd9ab
      base = xstrdup(values[0]);
Packit 6bd9ab
      log_log(LOG_DEBUG, "get_basedn_from_rootdse(): found attribute namingContexts with value %s",
Packit 6bd9ab
              values[0]);
Packit 6bd9ab
      break;
Packit 6bd9ab
    }
Packit 6bd9ab
  }
Packit 6bd9ab
  /* clean up */
Packit 6bd9ab
  myldap_session_close(session);
Packit 6bd9ab
  return base;
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
/* set the configuration information to the defaults */
Packit 6bd9ab
static void cfg_defaults(struct ldap_config *cfg)
Packit 6bd9ab
{
Packit 6bd9ab
  int i;
Packit 6bd9ab
  memset(cfg, 0, sizeof(struct ldap_config));
Packit 6bd9ab
  cfg->threads = 5;
Packit 6bd9ab
  cfg->uidname = NULL;
Packit 6bd9ab
  cfg->uid = NOUID;
Packit 6bd9ab
  cfg->gid = NOGID;
Packit 6bd9ab
  for (i = 0; i < (NSS_LDAP_CONFIG_MAX_URIS + 1); i++)
Packit 6bd9ab
  {
Packit 6bd9ab
    cfg->uris[i].uri = NULL;
Packit 6bd9ab
    cfg->uris[i].firstfail = 0;
Packit 6bd9ab
    cfg->uris[i].lastfail = 0;
Packit 6bd9ab
  }
Packit 6bd9ab
#ifdef LDAP_VERSION3
Packit 6bd9ab
  cfg->ldap_version = LDAP_VERSION3;
Packit 6bd9ab
#else /* LDAP_VERSION3 */
Packit 6bd9ab
  cfg->ldap_version = LDAP_VERSION2;
Packit 6bd9ab
#endif /* not LDAP_VERSION3 */
Packit 6bd9ab
  cfg->binddn = NULL;
Packit 6bd9ab
  cfg->bindpw = NULL;
Packit 6bd9ab
  cfg->rootpwmoddn = NULL;
Packit 6bd9ab
  cfg->rootpwmodpw = NULL;
Packit 6bd9ab
  cfg->sasl_mech = NULL;
Packit 6bd9ab
  cfg->sasl_realm = NULL;
Packit 6bd9ab
  cfg->sasl_authcid = NULL;
Packit 6bd9ab
  cfg->sasl_authzid = NULL;
Packit 6bd9ab
  cfg->sasl_secprops = NULL;
Packit 6bd9ab
#ifdef LDAP_OPT_X_SASL_NOCANON
Packit 6bd9ab
  cfg->sasl_canonicalize = -1;
Packit 6bd9ab
#endif /* LDAP_OPT_X_SASL_NOCANON */
Packit 6bd9ab
  for (i = 0; i < NSS_LDAP_CONFIG_MAX_BASES; i++)
Packit 6bd9ab
    cfg->bases[i] = NULL;
Packit 6bd9ab
  cfg->scope = LDAP_SCOPE_SUBTREE;
Packit 6bd9ab
  cfg->deref = LDAP_DEREF_NEVER;
Packit 6bd9ab
  cfg->referrals = 1;
Packit 6bd9ab
#if defined(HAVE_LDAP_SASL_BIND) && defined(LDAP_SASL_SIMPLE)
Packit 6bd9ab
  cfg->pam_authc_ppolicy = 1;
Packit 6bd9ab
#endif
Packit 6bd9ab
  cfg->bind_timelimit = 10;
Packit 6bd9ab
  cfg->timelimit = LDAP_NO_LIMIT;
Packit 6bd9ab
  cfg->idle_timelimit = 0;
Packit 6bd9ab
  cfg->reconnect_sleeptime = 1;
Packit 6bd9ab
  cfg->reconnect_retrytime = 10;
Packit 6bd9ab
#ifdef LDAP_OPT_X_TLS
Packit 6bd9ab
  cfg->ssl = SSL_OFF;
Packit 6bd9ab
#endif /* LDAP_OPT_X_TLS */
Packit 6bd9ab
  cfg->pagesize = 0;
Packit 6bd9ab
  cfg->nss_initgroups_ignoreusers = NULL;
Packit 6bd9ab
  cfg->nss_min_uid = 0;
Packit 6bd9ab
  cfg->nss_uid_offset = 0;
Packit 6bd9ab
  cfg->nss_gid_offset = 0;
Packit 6bd9ab
  cfg->nss_nested_groups = 0;
Packit 6bd9ab
  cfg->nss_getgrent_skipmembers = 0;
Packit 6bd9ab
  cfg->nss_disable_enumeration = 0;
Packit 6bd9ab
  cfg->validnames_str = NULL;
Packit 6bd9ab
  handle_validnames(__FILE__, __LINE__, "",
Packit 6bd9ab
                    "/^[a-z0-9._@$()]([a-z0-9._@$() \\~-]*[a-z0-9._@$()~-])?$/i",
Packit 6bd9ab
                    cfg);
Packit 6bd9ab
  cfg->ignorecase = 0;
Packit 6bd9ab
  cfg->pam_authc_search = "BASE";
Packit 6bd9ab
  for (i = 0; i < NSS_LDAP_CONFIG_MAX_AUTHZ_SEARCHES; i++)
Packit 6bd9ab
    cfg->pam_authz_searches[i] = NULL;
Packit 6bd9ab
  cfg->pam_password_prohibit_message = NULL;
Packit 6bd9ab
  for (i = 0; i < LM_NONE; i++)
Packit 6bd9ab
    cfg->reconnect_invalidate[i] = 0;
Packit 6bd9ab
  cfg->cache_dn2uid_positive = 15 * TIME_MINUTES;
Packit 6bd9ab
  cfg->cache_dn2uid_negative = 15 * TIME_MINUTES;
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static void cfg_read(const char *filename, struct ldap_config *cfg)
Packit 6bd9ab
{
Packit 6bd9ab
  FILE *fp;
Packit 6bd9ab
  int lnr = 0;
Packit 6bd9ab
  char linebuf[MAX_LINE_LENGTH];
Packit 6bd9ab
  char *line;
Packit 6bd9ab
  char keyword[32];
Packit 6bd9ab
  char token[256];
Packit 6bd9ab
  int i;
Packit 6bd9ab
#ifdef LDAP_OPT_X_TLS
Packit 6bd9ab
  int rc;
Packit 6bd9ab
  char *value;
Packit 6bd9ab
#endif
Packit 6bd9ab
  /* open config file */
Packit 6bd9ab
  if ((fp = fopen(filename, "r")) == NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "cannot open config file (%s): %s",
Packit 6bd9ab
            filename, strerror(errno));
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  /* read file and parse lines */
Packit 6bd9ab
  while (fgets(linebuf, sizeof(linebuf), fp) != NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    lnr++;
Packit 6bd9ab
    line = linebuf;
Packit 6bd9ab
    /* strip newline */
Packit 6bd9ab
    i = (int)strlen(line);
Packit 6bd9ab
    if ((i <= 0) || (line[i - 1] != '\n'))
Packit 6bd9ab
    {
Packit 6bd9ab
      log_log(LOG_ERR, "%s:%d: line too long or last line missing newline",
Packit 6bd9ab
              filename, lnr);
Packit 6bd9ab
      exit(EXIT_FAILURE);
Packit 6bd9ab
    }
Packit 6bd9ab
    line[i - 1] = '\0';
Packit 6bd9ab
    /* ignore comment lines */
Packit 6bd9ab
    if (line[0] == '#')
Packit 6bd9ab
      continue;
Packit 6bd9ab
    /* strip trailing spaces */
Packit 6bd9ab
    for (i--; (i > 0) && isspace(line[i - 1]); i--)
Packit 6bd9ab
      line[i - 1] = '\0';
Packit 6bd9ab
    /* get keyword from line and ignore empty lines */
Packit 6bd9ab
    if (get_token(&line, keyword, sizeof(keyword)) == NULL)
Packit 6bd9ab
      continue;
Packit 6bd9ab
    /* runtime options */
Packit 6bd9ab
    if (strcasecmp(keyword, "threads") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->threads = get_int(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "uid") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      handle_uid(filename, lnr, keyword, line, cfg);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "gid") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      handle_gid(filename, lnr, keyword, line, &cfg->gid);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "log") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      handle_log(filename, lnr, keyword, line);
Packit 6bd9ab
    }
Packit 6bd9ab
    /* general connection options */
Packit 6bd9ab
    else if (strcasecmp(keyword, "uri") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      check_argumentcount(filename, lnr, keyword, (line != NULL) && (*line != '\0'));
Packit 6bd9ab
      while (get_token(&line, token, sizeof(token)) != NULL)
Packit 6bd9ab
      {
Packit 6bd9ab
        if (strcasecmp(token, "dns") == 0)
Packit 6bd9ab
        {
Packit 6bd9ab
#ifdef HAVE_LDAP_DOMAIN2HOSTLIST
Packit 6bd9ab
          add_uris_from_dns(filename, lnr, cfg,
Packit 6bd9ab
                            cfg_getdomainname(filename, lnr));
Packit 6bd9ab
#else /* not HAVE_LDAP_DOMAIN2HOSTLIST */
Packit 6bd9ab
          log_log(LOG_ERR, "%s:%d: value %s not supported on platform",
Packit 6bd9ab
                  filename, lnr, token);
Packit 6bd9ab
          exit(EXIT_FAILURE);
Packit 6bd9ab
#endif /* not HAVE_LDAP_DOMAIN2HOSTLIST */
Packit 6bd9ab
        }
Packit 6bd9ab
        else if (strncasecmp(token, "dns:", 4) == 0)
Packit 6bd9ab
        {
Packit 6bd9ab
#ifdef HAVE_LDAP_DOMAIN2HOSTLIST
Packit 6bd9ab
          add_uris_from_dns(filename, lnr, cfg, strdup(token + 4));
Packit 6bd9ab
#else /* not HAVE_LDAP_DOMAIN2HOSTLIST */
Packit 6bd9ab
          log_log(LOG_ERR, "%s:%d: value %s not supported on platform",
Packit 6bd9ab
                  filename, lnr, token);
Packit 6bd9ab
          exit(EXIT_FAILURE);
Packit 6bd9ab
#endif /* not HAVE_LDAP_DOMAIN2HOSTLIST */
Packit 6bd9ab
        }
Packit 6bd9ab
        else
Packit 6bd9ab
          add_uri(filename, lnr, cfg, token);
Packit 6bd9ab
      }
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "ldap_version") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->ldap_version = get_int(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "binddn") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->binddn = get_linedup(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "bindpw") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      check_permissions(filename, keyword);
Packit 6bd9ab
      cfg->bindpw = get_linedup(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "rootpwmoddn") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->rootpwmoddn = get_linedup(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "rootpwmodpw") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      check_permissions(filename, keyword);
Packit 6bd9ab
      cfg->rootpwmodpw = get_linedup(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    /* SASL authentication options */
Packit 6bd9ab
    else if (strcasecmp(keyword, "sasl_mech") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->sasl_mech = get_strdup(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "sasl_realm") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->sasl_realm = get_strdup(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "sasl_authcid") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->sasl_authcid = get_strdup(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "sasl_authzid") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->sasl_authzid = get_strdup(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "sasl_secprops") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->sasl_secprops = get_strdup(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
#ifdef LDAP_OPT_X_SASL_NOCANON
Packit 6bd9ab
    else if ((strcasecmp(keyword, "sasl_canonicalize") == 0) ||
Packit 6bd9ab
             (strcasecmp(keyword, "sasl_canonicalise") == 0) ||
Packit 6bd9ab
             (strcasecmp(keyword, "ldap_sasl_canonicalize") == 0) ||
Packit 6bd9ab
             (strcasecmp(keyword, "sasl_canon") == 0))
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->sasl_canonicalize = get_boolean(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "sasl_nocanon") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->sasl_canonicalize = get_boolean(filename, lnr, keyword, &line);
Packit 6bd9ab
      cfg->sasl_canonicalize = !cfg->sasl_canonicalize;
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
#endif /* LDAP_OPT_X_SASL_NOCANON */
Packit 6bd9ab
    /* Kerberos authentication options */
Packit 6bd9ab
    else if (strcasecmp(keyword, "krb5_ccname") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      handle_krb5_ccname(filename, lnr, keyword, line);
Packit 6bd9ab
    }
Packit 6bd9ab
    /* search/mapping options */
Packit 6bd9ab
    else if (strcasecmp(keyword, "base") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      handle_base(filename, lnr, keyword, line, cfg);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "scope") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      handle_scope(filename, lnr, keyword, line, cfg);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "deref") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      handle_deref(filename, lnr, keyword, line, cfg);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "referrals") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->referrals = get_boolean(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "filter") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      handle_filter(filename, lnr, keyword, line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "map") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      handle_map(filename, lnr, keyword, line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "pam_authc_ppolicy") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
#if defined(HAVE_LDAP_SASL_BIND) && defined(LDAP_SASL_SIMPLE)
Packit 6bd9ab
      cfg->pam_authc_ppolicy = get_boolean(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
#else
Packit 6bd9ab
      log_log(LOG_ERR, "%s:%d: value %s not supported on platform",
Packit 6bd9ab
              filename, lnr, value);
Packit 6bd9ab
      exit(EXIT_FAILURE);
Packit 6bd9ab
#endif
Packit 6bd9ab
    }
Packit 6bd9ab
    /* timing/reconnect options */
Packit 6bd9ab
    else if (strcasecmp(keyword, "bind_timelimit") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->bind_timelimit = get_int(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "timelimit") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->timelimit = get_int(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "idle_timelimit") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->idle_timelimit = get_int(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (!strcasecmp(keyword, "reconnect_sleeptime"))
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->reconnect_sleeptime = get_int(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "reconnect_retrytime") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->reconnect_retrytime = get_int(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
#ifdef LDAP_OPT_X_TLS
Packit 6bd9ab
    /* SSL/TLS options */
Packit 6bd9ab
    else if (strcasecmp(keyword, "ssl") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      check_argumentcount(filename, lnr, keyword,
Packit 6bd9ab
                          (get_token(&line, token, sizeof(token)) != NULL));
Packit 6bd9ab
      if ((strcasecmp(token, "start_tls") == 0) ||
Packit 6bd9ab
          (strcasecmp(token, "starttls") == 0))
Packit 6bd9ab
        cfg->ssl = SSL_START_TLS;
Packit 6bd9ab
      else if (parse_boolean(filename, lnr, token))
Packit 6bd9ab
        cfg->ssl = SSL_LDAPS;
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "tls_reqcert") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      handle_tls_reqcert(filename, lnr, keyword, line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "tls_cacertdir") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      value = get_strdup(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
      check_dir(filename, lnr, token, value);
Packit 6bd9ab
      log_log(LOG_DEBUG, "ldap_set_option(LDAP_OPT_X_TLS_CACERTDIR,\"%s\")",
Packit 6bd9ab
              value);
Packit 6bd9ab
      LDAP_SET_OPTION(NULL, LDAP_OPT_X_TLS_CACERTDIR, value);
Packit 6bd9ab
      free(value);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if ((strcasecmp(keyword, "tls_cacertfile") == 0) ||
Packit 6bd9ab
             (strcasecmp(keyword, "tls_cacert") == 0))
Packit 6bd9ab
    {
Packit 6bd9ab
      value = get_strdup(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
      check_readable(filename, lnr, keyword, value);
Packit 6bd9ab
      log_log(LOG_DEBUG, "ldap_set_option(LDAP_OPT_X_TLS_CACERTFILE,\"%s\")",
Packit 6bd9ab
              value);
Packit 6bd9ab
      LDAP_SET_OPTION(NULL, LDAP_OPT_X_TLS_CACERTFILE, value);
Packit 6bd9ab
      free(value);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "tls_randfile") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      value = get_strdup(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
      check_readable(filename, lnr, keyword, value);
Packit 6bd9ab
      log_log(LOG_DEBUG, "ldap_set_option(LDAP_OPT_X_TLS_RANDOM_FILE,\"%s\")",
Packit 6bd9ab
              value);
Packit 6bd9ab
      LDAP_SET_OPTION(NULL, LDAP_OPT_X_TLS_RANDOM_FILE, value);
Packit 6bd9ab
      free(value);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "tls_ciphers") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      value = get_linedup(filename, lnr, keyword, &line);
Packit 6bd9ab
      log_log(LOG_DEBUG, "ldap_set_option(LDAP_OPT_X_TLS_CIPHER_SUITE,\"%s\")",
Packit 6bd9ab
              value);
Packit 6bd9ab
      LDAP_SET_OPTION(NULL, LDAP_OPT_X_TLS_CIPHER_SUITE, value);
Packit 6bd9ab
      free(value);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "tls_cert") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      value = get_strdup(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
      check_readable(filename, lnr, keyword, value);
Packit 6bd9ab
      log_log(LOG_DEBUG, "ldap_set_option(LDAP_OPT_X_TLS_CERTFILE,\"%s\")",
Packit 6bd9ab
              value);
Packit 6bd9ab
      LDAP_SET_OPTION(NULL, LDAP_OPT_X_TLS_CERTFILE, value);
Packit 6bd9ab
      free(value);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "tls_key") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      value = get_strdup(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
      check_readable(filename, lnr, keyword, value);
Packit 6bd9ab
      log_log(LOG_DEBUG, "ldap_set_option(LDAP_OPT_X_TLS_KEYFILE,\"%s\")",
Packit 6bd9ab
              value);
Packit 6bd9ab
      LDAP_SET_OPTION(NULL, LDAP_OPT_X_TLS_KEYFILE, value);
Packit 6bd9ab
      free(value);
Packit 6bd9ab
    }
Packit 6bd9ab
#endif /* LDAP_OPT_X_TLS */
Packit 6bd9ab
    /* other options */
Packit 6bd9ab
    else if (strcasecmp(keyword, "pagesize") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->pagesize = get_int(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "nss_initgroups_ignoreusers") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      handle_nss_initgroups_ignoreusers(filename, lnr, keyword, line,
Packit 6bd9ab
                                                 cfg);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "nss_min_uid") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->nss_min_uid = get_int(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "nss_uid_offset") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->nss_uid_offset = get_int(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "nss_gid_offset") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->nss_gid_offset = get_int(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "nss_nested_groups") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->nss_nested_groups = get_boolean(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "nss_getgrent_skipmembers") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->nss_getgrent_skipmembers = get_boolean(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "nss_disable_enumeration") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->nss_disable_enumeration = get_boolean(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "validnames") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      handle_validnames(filename, lnr, keyword, line, cfg);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "ignorecase") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      cfg->ignorecase = get_boolean(filename, lnr, keyword, &line);
Packit 6bd9ab
      get_eol(filename, lnr, keyword, &line);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "pam_authc_search") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      handle_pam_authc_search(filename, lnr, keyword, line, cfg);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "pam_authz_search") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      handle_pam_authz_search(filename, lnr, keyword, line, cfg);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "pam_password_prohibit_message") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      handle_pam_password_prohibit_message(filename, lnr, keyword, line, cfg);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "reconnect_invalidate") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      handle_reconnect_invalidate(filename, lnr, keyword, line, cfg);
Packit 6bd9ab
    }
Packit 6bd9ab
    else if (strcasecmp(keyword, "cache") == 0)
Packit 6bd9ab
    {
Packit 6bd9ab
      handle_cache(filename, lnr, keyword, line, cfg);
Packit 6bd9ab
    }
Packit 6bd9ab
#ifdef ENABLE_CONFIGFILE_CHECKING
Packit 6bd9ab
    /* fallthrough */
Packit 6bd9ab
    else
Packit 6bd9ab
    {
Packit 6bd9ab
      log_log(LOG_ERR, "%s:%d: unknown keyword: '%s'", filename, lnr, keyword);
Packit 6bd9ab
      exit(EXIT_FAILURE);
Packit 6bd9ab
    }
Packit 6bd9ab
#endif
Packit 6bd9ab
  }
Packit 6bd9ab
  /* we're done reading file, close */
Packit 6bd9ab
  fclose(fp);
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
#ifdef NSLCD_BINDPW_PATH
Packit 6bd9ab
static void bindpw_read(const char *filename, struct ldap_config *cfg)
Packit 6bd9ab
{
Packit 6bd9ab
  FILE *fp;
Packit 6bd9ab
  char linebuf[MAX_LINE_LENGTH];
Packit 6bd9ab
  int i;
Packit 6bd9ab
  /* open config file */
Packit 6bd9ab
  errno = 0;
Packit 6bd9ab
  if ((fp = fopen(filename, "r")) == NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    if (errno == ENOENT)
Packit 6bd9ab
    {
Packit 6bd9ab
      log_log(LOG_DEBUG, "no bindpw file (%s)", filename);
Packit 6bd9ab
      return; /* ignore */
Packit 6bd9ab
    }
Packit 6bd9ab
    else
Packit 6bd9ab
    {
Packit 6bd9ab
      log_log(LOG_ERR, "cannot open bindpw file (%s): %s",
Packit 6bd9ab
              filename, strerror(errno));
Packit 6bd9ab
      exit(EXIT_FAILURE);
Packit 6bd9ab
    }
Packit 6bd9ab
  }
Packit 6bd9ab
  /* check permissions */
Packit 6bd9ab
  check_permissions(filename, NULL);
Packit 6bd9ab
  /* read the first line */
Packit 6bd9ab
  if (fgets(linebuf, sizeof(linebuf), fp) == NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s: error reading first line", filename);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  /* chop the last char off and save the rest as bindpw */
Packit 6bd9ab
  i = (int)strlen(linebuf);
Packit 6bd9ab
  if ((i <= 0) || (linebuf[i - 1] != '\n'))
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:1: line too long or missing newline", filename);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  linebuf[i - 1] = '\0';
Packit 6bd9ab
  if (strlen(linebuf) == 0)
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:1: the password is empty", filename);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  cfg->bindpw = strdup(linebuf);
Packit 6bd9ab
  /* check if there is no more data in the file */
Packit 6bd9ab
  if (fgets(linebuf, sizeof(linebuf), fp) != NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "%s:2: there is more than one line in the bindpw file",
Packit 6bd9ab
            filename);
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  fclose(fp);
Packit 6bd9ab
}
Packit 6bd9ab
#endif /* NSLCD_BINDPW_PATH */
Packit 6bd9ab
Packit 6bd9ab
/* dump configuration */
Packit 6bd9ab
static void cfg_dump(void)
Packit 6bd9ab
{
Packit 6bd9ab
  int i;
Packit 6bd9ab
#ifdef LDAP_OPT_X_TLS
Packit 6bd9ab
  int rc;
Packit 6bd9ab
#endif /* LDAP_OPT_X_TLS */
Packit 6bd9ab
  enum ldap_map_selector map;
Packit 6bd9ab
  char *str;
Packit 6bd9ab
  const char **strp;
Packit 6bd9ab
  char buffer[1024];
Packit 6bd9ab
  int *scopep;
Packit 6bd9ab
  log_log(LOG_DEBUG, "CFG: threads %d", nslcd_cfg->threads);
Packit 6bd9ab
  if (nslcd_cfg->uidname != NULL)
Packit 6bd9ab
    log_log(LOG_DEBUG, "CFG: uid %s", nslcd_cfg->uidname);
Packit 6bd9ab
  else if (nslcd_cfg->uid != NOUID)
Packit 6bd9ab
    log_log(LOG_DEBUG, "CFG: uid %lu", (unsigned long int)nslcd_cfg->uid);
Packit 6bd9ab
  else
Packit 6bd9ab
    log_log(LOG_DEBUG, "CFG: # uid not set");
Packit 6bd9ab
  if (nslcd_cfg->gid != NOGID)
Packit 6bd9ab
    log_log(LOG_DEBUG, "CFG: gid %lu", (unsigned long int)nslcd_cfg->gid);
Packit 6bd9ab
  else
Packit 6bd9ab
    log_log(LOG_DEBUG, "CFG: # gid not set");
Packit 6bd9ab
  log_log_config();
Packit 6bd9ab
  for (i = 0; i < (NSS_LDAP_CONFIG_MAX_URIS + 1); i++)
Packit 6bd9ab
    if (nslcd_cfg->uris[i].uri != NULL)
Packit 6bd9ab
      log_log(LOG_DEBUG, "CFG: uri %s", nslcd_cfg->uris[i].uri);
Packit 6bd9ab
  log_log(LOG_DEBUG, "CFG: ldap_version %d", nslcd_cfg->ldap_version);
Packit 6bd9ab
  if (nslcd_cfg->binddn != NULL)
Packit 6bd9ab
    log_log(LOG_DEBUG, "CFG: binddn %s", nslcd_cfg->binddn);
Packit 6bd9ab
  if (nslcd_cfg->bindpw != NULL)
Packit 6bd9ab
    log_log(LOG_DEBUG, "CFG: bindpw ***");
Packit 6bd9ab
  if (nslcd_cfg->rootpwmoddn != NULL)
Packit 6bd9ab
    log_log(LOG_DEBUG, "CFG: rootpwmoddn %s", nslcd_cfg->rootpwmoddn);
Packit 6bd9ab
  if (nslcd_cfg->rootpwmodpw != NULL)
Packit 6bd9ab
    log_log(LOG_DEBUG, "CFG: rootpwmodpw ***");
Packit 6bd9ab
  if (nslcd_cfg->sasl_mech != NULL)
Packit 6bd9ab
    log_log(LOG_DEBUG, "CFG: sasl_mech %s", nslcd_cfg->sasl_mech);
Packit 6bd9ab
  if (nslcd_cfg->sasl_realm != NULL)
Packit 6bd9ab
    log_log(LOG_DEBUG, "CFG: sasl_realm %s", nslcd_cfg->sasl_realm);
Packit 6bd9ab
  if (nslcd_cfg->sasl_authcid != NULL)
Packit 6bd9ab
    log_log(LOG_DEBUG, "CFG: sasl_authcid %s", nslcd_cfg->sasl_authcid);
Packit 6bd9ab
  if (nslcd_cfg->sasl_authzid != NULL)
Packit 6bd9ab
    log_log(LOG_DEBUG, "CFG: sasl_authzid %s", nslcd_cfg->sasl_authzid);
Packit 6bd9ab
  if (nslcd_cfg->sasl_secprops != NULL)
Packit 6bd9ab
    log_log(LOG_DEBUG, "CFG: sasl_secprops %s", nslcd_cfg->sasl_secprops);
Packit 6bd9ab
#ifdef LDAP_OPT_X_SASL_NOCANON
Packit 6bd9ab
  if (nslcd_cfg->sasl_canonicalize >= 0)
Packit 6bd9ab
    log_log(LOG_DEBUG, "CFG: sasl_canonicalize %s", print_boolean(nslcd_cfg->sasl_canonicalize));
Packit 6bd9ab
#endif /* LDAP_OPT_X_SASL_NOCANON */
Packit 6bd9ab
  str = getenv("KRB5CCNAME");
Packit 6bd9ab
  if (str != NULL)
Packit 6bd9ab
    log_log(LOG_DEBUG, "CFG: krb5_ccname %s", str);
Packit 6bd9ab
  for (i = 0; i < NSS_LDAP_CONFIG_MAX_BASES; i++)
Packit 6bd9ab
    if (nslcd_cfg->bases[i] != NULL)
Packit 6bd9ab
      log_log(LOG_DEBUG, "CFG: base %s", nslcd_cfg->bases[i]);
Packit 6bd9ab
  for (map = LM_ALIASES; map < LM_NONE; map++)
Packit 6bd9ab
  {
Packit 6bd9ab
    strp = base_get_var(map);
Packit 6bd9ab
    if (strp != NULL)
Packit 6bd9ab
      for (i = 0; i < NSS_LDAP_CONFIG_MAX_BASES; i++)
Packit 6bd9ab
        if (strp[i] != NULL)
Packit 6bd9ab
          log_log(LOG_DEBUG, "CFG: base %s %s", print_map(map), strp[i]);
Packit 6bd9ab
  }
Packit 6bd9ab
  log_log(LOG_DEBUG, "CFG: scope %s", print_scope(nslcd_cfg->scope));
Packit 6bd9ab
  for (map = LM_ALIASES; map < LM_NONE; map++)
Packit 6bd9ab
  {
Packit 6bd9ab
    scopep = scope_get_var(map);
Packit 6bd9ab
    if ((scopep != NULL) && (*scopep != LDAP_SCOPE_DEFAULT))
Packit 6bd9ab
      log_log(LOG_DEBUG, "CFG: scope %s %s", print_map(map), print_scope(*scopep));
Packit 6bd9ab
  }
Packit 6bd9ab
  log_log(LOG_DEBUG, "CFG: deref %s", print_deref(nslcd_cfg->deref));
Packit 6bd9ab
  log_log(LOG_DEBUG, "CFG: referrals %s", print_boolean(nslcd_cfg->referrals));
Packit 6bd9ab
  for (map = LM_ALIASES; map < LM_NONE; map++)
Packit 6bd9ab
  {
Packit 6bd9ab
    strp = filter_get_var(map);
Packit 6bd9ab
    if ((strp != NULL) && (*strp != NULL))
Packit 6bd9ab
      log_log(LOG_DEBUG, "CFG: filter %s %s", print_map(map), *strp);
Packit 6bd9ab
  }
Packit 6bd9ab
#define LOG_ATTMAP(map, mapl, att)                                          \
Packit 6bd9ab
  if (strcmp(attmap_##mapl##_##att, __STRING(att)) != 0)                    \
Packit 6bd9ab
    log_log(LOG_DEBUG, "CFG: map %s %s %s",                                 \
Packit 6bd9ab
            print_map(map), __STRING(att), attmap_##mapl##_##att);
Packit 6bd9ab
  LOG_ATTMAP(LM_ALIASES, alias, cn);
Packit 6bd9ab
  LOG_ATTMAP(LM_ALIASES, alias, rfc822MailMember);
Packit 6bd9ab
  LOG_ATTMAP(LM_ETHERS, ether, cn);
Packit 6bd9ab
  LOG_ATTMAP(LM_ETHERS, ether, macAddress);
Packit 6bd9ab
  LOG_ATTMAP(LM_GROUP, group, cn);
Packit 6bd9ab
  LOG_ATTMAP(LM_GROUP, group, userPassword);
Packit 6bd9ab
  LOG_ATTMAP(LM_GROUP, group, gidNumber);
Packit 6bd9ab
  LOG_ATTMAP(LM_GROUP, group, memberUid);
Packit 6bd9ab
  LOG_ATTMAP(LM_GROUP, group, member);
Packit 6bd9ab
  LOG_ATTMAP(LM_HOSTS, host, cn);
Packit 6bd9ab
  LOG_ATTMAP(LM_HOSTS, host, ipHostNumber);
Packit 6bd9ab
  LOG_ATTMAP(LM_NETGROUP, netgroup, cn);
Packit 6bd9ab
  LOG_ATTMAP(LM_NETGROUP, netgroup, nisNetgroupTriple);
Packit 6bd9ab
  LOG_ATTMAP(LM_NETGROUP, netgroup, memberNisNetgroup);
Packit 6bd9ab
  LOG_ATTMAP(LM_NETWORKS, network, cn);
Packit 6bd9ab
  LOG_ATTMAP(LM_NETWORKS, network, ipNetworkNumber);
Packit 6bd9ab
  LOG_ATTMAP(LM_PASSWD, passwd, uid);
Packit 6bd9ab
  LOG_ATTMAP(LM_PASSWD, passwd, userPassword);
Packit 6bd9ab
  LOG_ATTMAP(LM_PASSWD, passwd, uidNumber);
Packit 6bd9ab
  LOG_ATTMAP(LM_PASSWD, passwd, gidNumber);
Packit 6bd9ab
  LOG_ATTMAP(LM_PASSWD, passwd, gecos);
Packit 6bd9ab
  LOG_ATTMAP(LM_PASSWD, passwd, homeDirectory);
Packit 6bd9ab
  LOG_ATTMAP(LM_PASSWD, passwd, loginShell);
Packit 6bd9ab
  LOG_ATTMAP(LM_PROTOCOLS, protocol, cn);
Packit 6bd9ab
  LOG_ATTMAP(LM_PROTOCOLS, protocol, ipProtocolNumber);
Packit 6bd9ab
  LOG_ATTMAP(LM_RPC, rpc, cn);
Packit 6bd9ab
  LOG_ATTMAP(LM_RPC, rpc, oncRpcNumber);
Packit 6bd9ab
  LOG_ATTMAP(LM_SERVICES, service, cn);
Packit 6bd9ab
  LOG_ATTMAP(LM_SERVICES, service, ipServicePort);
Packit 6bd9ab
  LOG_ATTMAP(LM_SERVICES, service, ipServiceProtocol);
Packit 6bd9ab
  LOG_ATTMAP(LM_SHADOW, shadow, uid);
Packit 6bd9ab
  LOG_ATTMAP(LM_SHADOW, shadow, userPassword);
Packit 6bd9ab
  LOG_ATTMAP(LM_SHADOW, shadow, shadowLastChange);
Packit 6bd9ab
  LOG_ATTMAP(LM_SHADOW, shadow, shadowMin);
Packit 6bd9ab
  LOG_ATTMAP(LM_SHADOW, shadow, shadowMax);
Packit 6bd9ab
  LOG_ATTMAP(LM_SHADOW, shadow, shadowWarning);
Packit 6bd9ab
  LOG_ATTMAP(LM_SHADOW, shadow, shadowInactive);
Packit 6bd9ab
  LOG_ATTMAP(LM_SHADOW, shadow, shadowExpire);
Packit 6bd9ab
  LOG_ATTMAP(LM_SHADOW, shadow, shadowFlag);
Packit 6bd9ab
#if defined(HAVE_LDAP_SASL_BIND) && defined(LDAP_SASL_SIMPLE)
Packit 6bd9ab
  log_log(LOG_DEBUG, "CFG: pam_authc_ppolicy %s", print_boolean(nslcd_cfg->pam_authc_ppolicy));
Packit 6bd9ab
#endif
Packit 6bd9ab
  log_log(LOG_DEBUG, "CFG: bind_timelimit %d", nslcd_cfg->bind_timelimit);
Packit 6bd9ab
  log_log(LOG_DEBUG, "CFG: timelimit %d", nslcd_cfg->timelimit);
Packit 6bd9ab
  log_log(LOG_DEBUG, "CFG: idle_timelimit %d", nslcd_cfg->idle_timelimit);
Packit 6bd9ab
  log_log(LOG_DEBUG, "CFG: reconnect_sleeptime %d", nslcd_cfg->reconnect_sleeptime);
Packit 6bd9ab
  log_log(LOG_DEBUG, "CFG: reconnect_retrytime %d", nslcd_cfg->reconnect_retrytime);
Packit 6bd9ab
#ifdef LDAP_OPT_X_TLS
Packit 6bd9ab
  log_log(LOG_DEBUG, "CFG: ssl %s", print_ssl(nslcd_cfg->ssl));
Packit 6bd9ab
  rc = ldap_get_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &i);
Packit 6bd9ab
  if (rc != LDAP_SUCCESS)
Packit 6bd9ab
    log_log(LOG_DEBUG, "CFG: # tls_reqcert ERROR: %s", ldap_err2string(rc));
Packit 6bd9ab
  else
Packit 6bd9ab
    log_log(LOG_DEBUG, "CFG: tls_reqcert %s", print_tls_reqcert(i));
Packit 6bd9ab
  #define LOG_LDAP_OPT_STRING(cfg, option)                                  \
Packit 6bd9ab
    str = NULL;                                                             \
Packit 6bd9ab
    rc = ldap_get_option(NULL, option, &str);                               \
Packit 6bd9ab
    if (rc != LDAP_SUCCESS)                                                 \
Packit 6bd9ab
      log_log(LOG_DEBUG, "CFG: # %s ERROR: %s", cfg, ldap_err2string(rc));  \
Packit 6bd9ab
    else if ((str != NULL) && (*str != '\0'))                               \
Packit 6bd9ab
      log_log(LOG_DEBUG, "CFG: %s %s", cfg, str);                           \
Packit 6bd9ab
    if (str != NULL)                                                        \
Packit 6bd9ab
      ldap_memfree(str);
Packit 6bd9ab
  LOG_LDAP_OPT_STRING("tls_cacertdir", LDAP_OPT_X_TLS_CACERTDIR);
Packit 6bd9ab
  LOG_LDAP_OPT_STRING("tls_cacertfile", LDAP_OPT_X_TLS_CACERTFILE);
Packit 6bd9ab
  LOG_LDAP_OPT_STRING("tls_randfile", LDAP_OPT_X_TLS_RANDOM_FILE);
Packit 6bd9ab
  LOG_LDAP_OPT_STRING("tls_ciphers", LDAP_OPT_X_TLS_CIPHER_SUITE);
Packit 6bd9ab
  LOG_LDAP_OPT_STRING("tls_cert", LDAP_OPT_X_TLS_CERTFILE);
Packit 6bd9ab
  LOG_LDAP_OPT_STRING("tls_key", LDAP_OPT_X_TLS_KEYFILE);
Packit 6bd9ab
#endif /* LDAP_OPT_X_TLS */
Packit 6bd9ab
  log_log(LOG_DEBUG, "CFG: pagesize %d", nslcd_cfg->pagesize);
Packit 6bd9ab
  if (nslcd_cfg->nss_initgroups_ignoreusers != NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    /* allocate memory for a comma-separated list */
Packit 6bd9ab
    strp = set_tolist(nslcd_cfg->nss_initgroups_ignoreusers);
Packit 6bd9ab
    if (strp == NULL)
Packit 6bd9ab
    {
Packit 6bd9ab
      log_log(LOG_CRIT, "malloc() failed to allocate memory");
Packit 6bd9ab
      exit(EXIT_FAILURE);
Packit 6bd9ab
    }
Packit 6bd9ab
    /* turn the set into a comma-separated list */
Packit 6bd9ab
    buffer[0] = '\0';
Packit 6bd9ab
    for (i = 0; strp[i] != NULL; i++)
Packit 6bd9ab
    {
Packit 6bd9ab
      if (i > 0)
Packit 6bd9ab
        strncat(buffer, ",", sizeof(buffer) - 1 - strlen(buffer));
Packit 6bd9ab
      strncat(buffer, strp[i], sizeof(buffer) - 1 - strlen(buffer));
Packit 6bd9ab
    }
Packit 6bd9ab
    free(strp);
Packit 6bd9ab
    if (strlen(buffer) >= (sizeof(buffer) - 4))
Packit 6bd9ab
      strcpy(buffer + sizeof(buffer) - 4, "...");
Packit 6bd9ab
    log_log(LOG_DEBUG, "CFG: nss_initgroups_ignoreusers %s", buffer);
Packit 6bd9ab
  }
Packit 6bd9ab
  log_log(LOG_DEBUG, "CFG: nss_min_uid %lu", (unsigned long int)nslcd_cfg->nss_min_uid);
Packit 6bd9ab
  log_log(LOG_DEBUG, "CFG: nss_uid_offset %lu", (unsigned long int)nslcd_cfg->nss_uid_offset);
Packit 6bd9ab
  log_log(LOG_DEBUG, "CFG: nss_gid_offset %lu", (unsigned long int)nslcd_cfg->nss_gid_offset);
Packit 6bd9ab
  log_log(LOG_DEBUG, "CFG: nss_nested_groups %s", print_boolean(nslcd_cfg->nss_nested_groups));
Packit 6bd9ab
  log_log(LOG_DEBUG, "CFG: nss_getgrent_skipmembers %s", print_boolean(nslcd_cfg->nss_getgrent_skipmembers));
Packit 6bd9ab
  log_log(LOG_DEBUG, "CFG: nss_disable_enumeration %s", print_boolean(nslcd_cfg->nss_disable_enumeration));
Packit 6bd9ab
  log_log(LOG_DEBUG, "CFG: validnames %s", nslcd_cfg->validnames_str);
Packit 6bd9ab
  log_log(LOG_DEBUG, "CFG: ignorecase %s", print_boolean(nslcd_cfg->ignorecase));
Packit 6bd9ab
  log_log(LOG_DEBUG, "CFG: pam_authc_search %s", nslcd_cfg->pam_authc_search);
Packit 6bd9ab
  for (i = 0; i < NSS_LDAP_CONFIG_MAX_AUTHZ_SEARCHES; i++)
Packit 6bd9ab
    if (nslcd_cfg->pam_authz_searches[i] != NULL)
Packit 6bd9ab
      log_log(LOG_DEBUG, "CFG: pam_authz_search %s", nslcd_cfg->pam_authz_searches[i]);
Packit 6bd9ab
  if (nslcd_cfg->pam_password_prohibit_message != NULL)
Packit 6bd9ab
    log_log(LOG_DEBUG, "CFG: pam_password_prohibit_message \"%s\"", nslcd_cfg->pam_password_prohibit_message);
Packit 6bd9ab
  /* build a comma-separated list */
Packit 6bd9ab
  buffer[0] = '\0';
Packit 6bd9ab
  for (i = 0; i < LM_NONE ; i++)
Packit 6bd9ab
    if (nslcd_cfg->reconnect_invalidate[i])
Packit 6bd9ab
    {
Packit 6bd9ab
      if (buffer[0] != '\0')
Packit 6bd9ab
        strncat(buffer, ",", sizeof(buffer) - 1 - strlen(buffer));
Packit 6bd9ab
      strncat(buffer, print_map(i), sizeof(buffer) - 1 - strlen(buffer));
Packit 6bd9ab
    }
Packit 6bd9ab
  if (buffer[0] != '\0')
Packit 6bd9ab
    log_log(LOG_DEBUG, "CFG: reconnect_invalidate %s", buffer);
Packit 6bd9ab
  print_time(nslcd_cfg->cache_dn2uid_positive, buffer, sizeof(buffer) / 2);
Packit 6bd9ab
  print_time(nslcd_cfg->cache_dn2uid_positive, buffer + (sizeof(buffer) / 2), sizeof(buffer) / 2);
Packit 6bd9ab
  log_log(LOG_DEBUG, "CFG: cache dn2uid %s %s", buffer, buffer + (sizeof(buffer) / 2));
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
void cfg_init(const char *fname)
Packit 6bd9ab
{
Packit 6bd9ab
#ifdef LDAP_OPT_X_TLS
Packit 6bd9ab
  int i;
Packit 6bd9ab
#endif /* LDAP_OPT_X_TLS */
Packit 6bd9ab
  /* check if we were called before */
Packit 6bd9ab
  if (nslcd_cfg != NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_CRIT, "cfg_init() may only be called once");
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  /* allocate the memory (this memory is not freed anywhere) */
Packit 6bd9ab
  nslcd_cfg = (struct ldap_config *)malloc(sizeof(struct ldap_config));
Packit 6bd9ab
  if (nslcd_cfg == NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_CRIT, "malloc() failed to allocate memory");
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  /* clear configuration */
Packit 6bd9ab
  cfg_defaults(nslcd_cfg);
Packit 6bd9ab
  /* read configfile */
Packit 6bd9ab
  cfg_read(fname, nslcd_cfg);
Packit 6bd9ab
#ifdef NSLCD_BINDPW_PATH
Packit 6bd9ab
  bindpw_read(NSLCD_BINDPW_PATH, nslcd_cfg);
Packit 6bd9ab
#endif /* NSLCD_BINDPW_PATH */
Packit 6bd9ab
  /* do some sanity checks */
Packit 6bd9ab
  if (nslcd_cfg->uris[0].uri == NULL)
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "no URIs defined in config");
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  /* if ssl is on each URI should start with ldaps */
Packit 6bd9ab
#ifdef LDAP_OPT_X_TLS
Packit 6bd9ab
  if (nslcd_cfg->ssl == SSL_LDAPS)
Packit 6bd9ab
  {
Packit 6bd9ab
    for (i = 0; nslcd_cfg->uris[i].uri != NULL; i++)
Packit 6bd9ab
    {
Packit 6bd9ab
      if (strncasecmp(nslcd_cfg->uris[i].uri, "ldaps://", 8) != 0)
Packit 6bd9ab
        log_log(LOG_WARNING, "%s doesn't start with ldaps:// and \"ssl on\" is specified",
Packit 6bd9ab
                nslcd_cfg->uris[i].uri);
Packit 6bd9ab
    }
Packit 6bd9ab
  }
Packit 6bd9ab
  /* TODO: check that if some tls options are set the ssl option should be set to on (just warn) */
Packit 6bd9ab
#endif /* LDAP_OPT_X_TLS */
Packit 6bd9ab
  /* if basedn is not yet set,  get if from the rootDSE */
Packit 6bd9ab
  if (nslcd_cfg->bases[0] == NULL)
Packit 6bd9ab
    nslcd_cfg->bases[0] = get_base_from_rootdse();
Packit 6bd9ab
  /* TODO: handle the case gracefully when no LDAP server is available yet */
Packit 6bd9ab
  /* see if we have a valid basedn */
Packit 6bd9ab
  if ((nslcd_cfg->bases[0] == NULL) || (nslcd_cfg->bases[0][0] == '\0'))
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "no base defined in config and couldn't get one from server");
Packit 6bd9ab
    exit(EXIT_FAILURE);
Packit 6bd9ab
  }
Packit 6bd9ab
  /* dump configuration */
Packit 6bd9ab
  cfg_dump();
Packit 6bd9ab
  /* initialise all database modules */
Packit 6bd9ab
  alias_init();
Packit 6bd9ab
  ether_init();
Packit 6bd9ab
  group_init();
Packit 6bd9ab
  host_init();
Packit 6bd9ab
  netgroup_init();
Packit 6bd9ab
  network_init();
Packit 6bd9ab
  passwd_init();
Packit 6bd9ab
  protocol_init();
Packit 6bd9ab
  rpc_init();
Packit 6bd9ab
  service_init();
Packit 6bd9ab
  shadow_init();
Packit 6bd9ab
}