Esempio n. 1
0
/* usage: ModulePath path */
MODRET set_modulepath(cmd_rec *cmd) {
  int res;
  struct stat st;

  CHECK_ARGS(cmd, 1);
  CHECK_CONF(cmd, CONF_ROOT);

  if (pr_fs_valid_path(cmd->argv[1]) < 0)
    CONF_ERROR(cmd, "must be an absolute path");

  /* Make sure that the configured path is not world-writeable. */
  res = pr_fsio_stat(cmd->argv[1], &st);
  if (res < 0)
    CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "error checking '",
      cmd->argv[1], "': ", strerror(errno), NULL)); 

  if (!S_ISDIR(st.st_mode))
    CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, cmd->argv[1], " is not a directory",
      NULL));

  if (st.st_mode & S_IWOTH)
    CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, cmd->argv[1], " is world-writable",
      NULL));

  if (lt_dlsetsearchpath(cmd->argv[1]) < 0)
    CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "error setting module path: ",
      lt_dlerror(), NULL));

  dso_module_path = pstrdup(dso_pool, cmd->argv[1]);
  return PR_HANDLED(cmd);
}
/* usage: CounterLog path|"none" */
MODRET set_counterlog(cmd_rec *cmd) {
  CHECK_ARGS(cmd, 1);
  CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);

  if (pr_fs_valid_path(cmd->argv[1]) < 0) {
    CONF_ERROR(cmd, "must be an absolute path");
  }

  add_config_param_str(cmd->argv[0], 1, cmd->argv[1]);
  return PR_HANDLED(cmd);
}
Esempio n. 3
0
/* usage: LoadFile path */
MODRET set_loadfile(cmd_rec *cmd) {

  CHECK_ARGS(cmd, 1);
  CHECK_CONF(cmd, CONF_ROOT);

  if (pr_fs_valid_path(cmd->argv[1]) < 0)
    CONF_ERROR(cmd, "must be an absolute path");

  if (dso_load_file(cmd->argv[1]) < 0)
    CONF_ERROR(cmd, pstrcat(cmd->tmp_pool, "error loading '", cmd->argv[1],
      "': ", strerror(errno), NULL));

  return PR_HANDLED(cmd);
}
Esempio n. 4
0
int parse_config_path2(pool *p, const char *path, unsigned int depth) {
  struct stat st;
  int have_glob;
  void *dirh;
  struct dirent *dent;
  array_header *file_list;
  char *dup_path, *ptr;
  pool *tmp_pool;

  if (p == NULL ||
      path == NULL ||
      (depth > PR_PARSER_INCLUDE_MAX_DEPTH)) {
    errno = EINVAL;
    return -1;
  }

  if (pr_fs_valid_path(path) < 0) {
    errno = EINVAL;
    return -1;
  }

  have_glob = pr_str_is_fnmatch(path);
  if (have_glob) {
    /* Even though the path may be valid, it also may not be a filesystem
     * path; consider custom FSIO modules.  Thus if the path does not start
     * with a slash, it should not be treated as having globs.
     */
    if (*path != '/') {
      have_glob = FALSE;
    }
  }

  pr_fs_clear_cache2(path);

  if (have_glob) {
    pr_trace_msg(trace_channel, 19, "parsing '%s' as a globbed path", path);
  }

  if (!have_glob &&
      pr_fsio_lstat(path, &st) < 0) {
    return -1;
  }

  /* If path is not a glob pattern, and is a symlink OR is not a directory,
   * then use the normal parsing function for the file.
   */
  if (have_glob == FALSE &&
      (S_ISLNK(st.st_mode) ||
       !S_ISDIR(st.st_mode))) {
    int res, xerrno;

    PRIVS_ROOT
    res = pr_parser_parse_file(p, path, NULL, 0);
    xerrno = errno;
    PRIVS_RELINQUISH

    errno = xerrno;
    return res;
  }

  tmp_pool = make_sub_pool(p);
  pr_pool_tag(tmp_pool, "Include sub-pool");

  /* Handle the glob/directory. */
  dup_path = pstrdup(tmp_pool, path);

  ptr = strrchr(dup_path, '/');

  if (have_glob) {
    int have_glob_dir;

    /* Note that we know, by definition, that ptr CANNOT be null here; dup_path
     * is a duplicate of path, and the first character (if nothing else) of
     * path MUST be a slash, per earlier checks.
     */
    *ptr = '\0';

    /* We just changed ptr, thus we DO need to check whether the now-modified
     * path contains fnmatch(3) characters again.
     */
    have_glob_dir = pr_str_is_fnmatch(dup_path);
    if (have_glob_dir) {
      const char *glob_dir;

      if (parser_include_opts & PR_PARSER_INCLUDE_OPT_IGNORE_WILDCARDS) {
        pr_log_pri(PR_LOG_WARNING, "error: wildcard patterns not allowed in "
          "configuration directory name '%s'", dup_path);
        destroy_pool(tmp_pool);
        errno = EINVAL;
        return -1;
      }

      *ptr = '/';
      glob_dir = pstrdup(p, dup_path);
      destroy_pool(tmp_pool);

      return parse_wildcard_config_path(p, glob_dir, depth);
    }

    ptr++;

    /* Check the directory component. */
    pr_fs_clear_cache2(dup_path);
    if (pr_fsio_lstat(dup_path, &st) < 0) {
      int xerrno = errno;

      pr_log_pri(PR_LOG_WARNING,
        "error: failed to check configuration path '%s': %s", dup_path,
        strerror(xerrno));

      destroy_pool(tmp_pool);
      errno = xerrno;
      return -1;
    }

    if (S_ISLNK(st.st_mode) &&
        !(parser_include_opts & PR_PARSER_INCLUDE_OPT_ALLOW_SYMLINKS)) {
      pr_log_pri(PR_LOG_WARNING,
        "error: cannot read configuration path '%s': Symbolic link", path);
      destroy_pool(tmp_pool);
      errno = ENOTDIR;
      return -1;
    }

    if (have_glob_dir == FALSE &&
        pr_str_is_fnmatch(ptr) == FALSE) {
      pr_log_pri(PR_LOG_WARNING,
        "error: wildcard pattern required for file '%s'", ptr);
      destroy_pool(tmp_pool);
      errno = EINVAL;
      return -1;
    }
  }

  pr_log_pri(PR_LOG_DEBUG, "processing configuration directory '%s'", dup_path);

  dirh = pr_fsio_opendir(dup_path);
  if (dirh == NULL) {
    pr_log_pri(PR_LOG_WARNING,
      "error: unable to open configuration directory '%s': %s", dup_path,
      strerror(errno));
    destroy_pool(tmp_pool);
    errno = EINVAL;
    return -1;
  }

  file_list = make_array(tmp_pool, 0, sizeof(char *));

  while ((dent = pr_fsio_readdir(dirh)) != NULL) {
    pr_signals_handle();

    if (strncmp(dent->d_name, ".", 2) == 0 ||
        strncmp(dent->d_name, "..", 3) == 0) {
      continue;
    }

    if (parser_include_opts & PR_PARSER_INCLUDE_OPT_IGNORE_TMP_FILES) {
      if (is_tmp_file(dent->d_name) == TRUE) {
        pr_trace_msg(trace_channel, 19,
          "ignoring temporary file '%s' found in directory '%s'", dent->d_name,
          dup_path);
        continue;
      }
    }

    if (have_glob == FALSE ||
        (ptr != NULL &&
         pr_fnmatch(ptr, dent->d_name, PR_FNM_PERIOD) == 0)) {
      *((char **) push_array(file_list)) = pdircat(tmp_pool, dup_path,
        dent->d_name, NULL);
    }
  }

  pr_fsio_closedir(dirh);

  if (file_list->nelts) {
    register unsigned int i;

    qsort((void *) file_list->elts, file_list->nelts, sizeof(char *),
      config_filename_cmp);

    for (i = 0; i < file_list->nelts; i++) {
      int res, xerrno;
      char *file;

      file = ((char **) file_list->elts)[i];

      /* Make sure we always parse the files with root privs.  The
       * previously parsed file might have had root privs relinquished
       * (e.g. by its directive handlers), but when we first start up,
       * we have root privs.  See Bug#3855.
       */
      PRIVS_ROOT
      res = pr_parser_parse_file(tmp_pool, file, NULL, 0);
      xerrno = errno;
      PRIVS_RELINQUISH

      if (res < 0) {
        pr_log_pri(PR_LOG_WARNING,
          "error: unable to open parse file '%s': %s", file,
          strerror(xerrno));
      }
    }
  }

  destroy_pool(tmp_pool);
  return 0;
}