示例#1
0
文件: auth.c 项目: Distrotech/proftpd
static void uidcache_create(void) {
  if ((auth_caching & PR_AUTH_CACHE_FL_UID2NAME) &&
      !uid_tab &&
      auth_pool) {
    int ok = TRUE;

    uid_tab = pr_table_alloc(auth_pool, 0);

    if (pr_table_ctl(uid_tab, PR_TABLE_CTL_SET_KEY_CMP, uid_keycmp_cb) < 0) {
      pr_trace_msg(trace_channel, 2,
        "error setting key comparison callback for uidcache: %s",
        strerror(errno));
      ok = FALSE;
    }

    if (pr_table_ctl(uid_tab, PR_TABLE_CTL_SET_KEY_HASH, uid_hash_cb) < 0) {
      pr_trace_msg(trace_channel, 2,
        "error setting key hash callback for uidcache: %s",
        strerror(errno));
      ok = FALSE;
    }

    if (!ok) {
      pr_trace_msg(trace_channel, 2, "%s",
        "destroying unusable uidcache table");
      pr_table_free(uid_tab);
      uid_tab = NULL;
    }
  }
}
示例#2
0
int pr_memcache_conn_set_namespace(pr_memcache_t *mcache, module *m,
    const char *prefix) {

  if (mcache == NULL ||
      m == NULL) {
    errno = EINVAL;
    return -1;
  }

  if (mcache->namespace_tab == NULL) {
    pr_table_t *tab;

    tab = pr_table_alloc(mcache->pool, 0);

    if (pr_table_ctl(tab, PR_TABLE_CTL_SET_KEY_CMP, modptr_cmp_cb) < 0) {
      pr_trace_msg(trace_channel, 4,
        "error setting key comparison callback for namespace table: %s",
        strerror(errno));
    }

    if (pr_table_ctl(tab, PR_TABLE_CTL_SET_KEY_HASH, modptr_hash_cb) < 0) {
      pr_trace_msg(trace_channel, 4,
        "error setting key hash callback for namespace table: %s",
        strerror(errno));
    }

    mcache->namespace_tab = tab;
  }

  if (prefix != NULL) {
    int count;
    size_t prefix_len;

    prefix_len = strlen(prefix);

    count = pr_table_kexists(mcache->namespace_tab, m, sizeof(module *));
    if (count <= 0) {
      if (pr_table_kadd(mcache->namespace_tab, m, sizeof(module *),
          pstrndup(mcache->pool, prefix, prefix_len), prefix_len) < 0) {
        pr_trace_msg(trace_channel, 7,
          "error adding namespace prefix '%s' for module 'mod_%s.c': %s",
          prefix, m->name, strerror(errno));
      }

    } else {
      if (pr_table_kset(mcache->namespace_tab, m, sizeof(module *),
          pstrndup(mcache->pool, prefix, prefix_len), prefix_len) < 0) {
        pr_trace_msg(trace_channel, 7,
          "error setting namespace prefix '%s' for module 'mod_%s.c': %s",
          prefix, m->name, strerror(errno));
      }
    }

  } else {
    /* A NULL prefix means the caller is removing their namespace maping. */
    (void) pr_table_kremove(mcache->namespace_tab, m, sizeof(module *), NULL);
  }

  return 0;
}
示例#3
0
void *vroot_fsio_opendir(pr_fs_t *fs, const char *orig_path) {
  int res, xerrno;
  char vpath[PR_TUNABLE_PATH_MAX + 1], *path = NULL;
  void *dirh = NULL;
  struct stat st;
  size_t pathlen = 0;
  pool *tmp_pool = NULL;
  unsigned int alias_count;

  if (session.curr_phase == LOG_CMD ||
      session.curr_phase == LOG_CMD_ERR ||
      (session.sf_flags & SF_ABORT) ||
      vroot_path_have_base() == FALSE) {
    /* NOTE: once stackable FS modules are supported, have this fall through
     * to the next module in the stack.
     */
    return opendir(orig_path);
  }

  tmp_pool = make_sub_pool(session.pool);
  pr_pool_tag(tmp_pool, "VRoot FSIO opendir pool");

  /* If the given path ends in a slash, remove it.  The handling of
   * VRootAliases is sensitive to trailing slashes.
   */
  path = pstrdup(tmp_pool, orig_path);
  vroot_path_clean(path);

  /* If the given path ends in a slash, remove it.  The handling of
   * VRootAliases is sensitive to such things.
   */
  pathlen = strlen(path);
  if (pathlen > 1 &&
      path[pathlen-1] == '/') {
    path[pathlen-1] = '\0';
    pathlen--;
  }

  if (vroot_path_lookup(NULL, vpath, sizeof(vpath)-1, path, 0, NULL) < 0) {
    xerrno = errno;

    destroy_pool(tmp_pool);
    errno = xerrno;
    return NULL;
  }

  /* Check if the looked-up vpath is a symlink; we may need to resolve any
   * links ourselves, rather than assuming that the system opendir(3) can
   * handle it.
   */

  res = vroot_fsio_lstat(fs, vpath, &st);
  while (res == 0 &&
         S_ISLNK(st.st_mode)) {
    char data[PR_TUNABLE_PATH_MAX + 1];

    pr_signals_handle();

    memset(data, '\0', sizeof(data));
    res = vroot_fsio_readlink(fs, vpath, data, sizeof(data)-1);
    if (res < 0) {
      break;
    }

    data[res] = '\0';

    sstrncpy(vpath, data, sizeof(vpath));
    res = vroot_fsio_lstat(fs, vpath, &st);
  }

  dirh = opendir(vpath);
  if (dirh == NULL) {
    xerrno = errno;

    (void) pr_log_writefile(vroot_logfd, MOD_VROOT_VERSION,
      "error opening virtualized directory '%s' (from '%s'): %s", vpath, path,
      strerror(xerrno));
    destroy_pool(tmp_pool);

    errno = xerrno;
    return NULL;
  }

  alias_count = vroot_alias_count();
  if (alias_count > 0) {
    unsigned long *cache_dirh = NULL;

    if (vroot_dirtab == NULL) {
      vroot_dir_pool = make_sub_pool(session.pool);
      pr_pool_tag(vroot_dir_pool, "VRoot Directory Pool");

      vroot_dirtab = pr_table_alloc(vroot_dir_pool, 0);

      /* Since this table will use DIR pointers as keys, we want to override
       * the default hashing and key comparison functions used.
       */
    
      pr_table_ctl(vroot_dirtab, PR_TABLE_CTL_SET_KEY_HASH,
        vroot_dirtab_hash_cb);
      pr_table_ctl(vroot_dirtab, PR_TABLE_CTL_SET_KEY_CMP,
        vroot_dirtab_keycmp_cb);
    }

    cache_dirh = palloc(vroot_dir_pool, sizeof(unsigned long));
    *cache_dirh = (unsigned long) dirh;

    if (pr_table_kadd(vroot_dirtab, cache_dirh, sizeof(unsigned long),
        pstrdup(vroot_dir_pool, vpath), strlen(vpath) + 1) < 0) {
      (void) pr_log_writefile(vroot_logfd, MOD_VROOT_VERSION,
        "error stashing path '%s' (key %p) in directory table: %s", vpath,
        dirh, strerror(errno));

    } else {
      vroot_dir_aliases = make_array(vroot_dir_pool, 0, sizeof(char *));

      res = vroot_alias_do(vroot_alias_dirscan, vpath);
      if (res < 0) {
        (void) pr_log_writefile(vroot_logfd, MOD_VROOT_VERSION,
          "error doing dirscan on aliases table: %s", strerror(errno));

      } else {
        register unsigned int i;

        (void) pr_log_writefile(vroot_logfd, MOD_VROOT_VERSION,
          "found %d %s in directory '%s'", vroot_dir_aliases->nelts,
          vroot_dir_aliases->nelts != 1 ? "VRootAliases" : "VRootAlias",
          vpath);
        vroot_dir_idx = 0;

        for (i = 0; i < vroot_dir_aliases->nelts; i++) {
          char **elts = vroot_dir_aliases->elts;

          (void) pr_log_writefile(vroot_logfd, MOD_VROOT_VERSION,
            "'%s' aliases: [%u] %s", vpath, i, elts[i]);
        }
      }
    }
  }

  destroy_pool(tmp_pool);
  return dirh;
}
static int log_failure_mkfields(pool *p) {
  pr_table_t *fields;

  fields = pr_table_alloc(p, 0);
  if (pr_table_ctl(fields, PR_TABLE_CTL_SET_KEY_CMP,
      (void *) field_id_cmp) < 0) {
    int xerrno = errno;

    pr_log_pri(PR_LOG_INFO, "error setting key comparison callback for "
      "field ID/names: %s", strerror(errno));
    pr_table_free(fields);

    errno = xerrno;
    return -1;
  }

  if (pr_table_ctl(fields, PR_TABLE_CTL_SET_KEY_HASH,
      (void *) field_id_hash) < 0) {
    int xerrno = errno;

    pr_log_pri(PR_LOG_INFO, "error setting key hash callback for "
      "field ID/names: %s", strerror(errno));
    pr_table_free(fields);

    errno = xerrno;
    return -1;
  }

  /* Now populate the table with the ID/name values.  The key is the
   * LogFormat "meta" ID, and the value is the corresponding name string,
   * for use e.g. as JSON object member names.
   */

  field_add(p, fields, LOGFMT_META_BYTES_SENT, "bytes_sent",
    LOG_FAILURE_FIELD_TYPE_NUMBER);

  field_add(p, fields, LOGFMT_META_FILENAME, "file",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_ENV_VAR, "ENV:",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_REMOTE_HOST, "remote_dns",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_REMOTE_IP, "remote_ip",
    LOG_FAILURE_FIELD_TYPE_STRING);

#if defined(LOGFMT_META_REMOTE_PORT)
  field_add(p, fields, LOGFMT_META_REMOTE_PORT, "remote_port",
    LOG_FAILURE_FIELD_TYPE_NUMBER);
#endif /* LOGFMT_META_REMOTE_PORT */

  field_add(p, fields, LOGFMT_META_IDENT_USER, "identd_user",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_PID, "pid",
    LOG_FAILURE_FIELD_TYPE_NUMBER);

  field_add(p, fields, LOGFMT_META_TIME, "local_time",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_SECONDS, "transfer_secs",
    LOG_FAILURE_FIELD_TYPE_NUMBER);

  field_add(p, fields, LOGFMT_META_COMMAND, "raw_command",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_LOCAL_NAME, "server_name",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_LOCAL_PORT, "local_port",
    LOG_FAILURE_FIELD_TYPE_NUMBER);

  field_add(p, fields, LOGFMT_META_LOCAL_IP, "local_ip",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_LOCAL_FQDN, "server_dns",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_USER, "user",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_ORIGINAL_USER, "original_user",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_RESPONSE_CODE, "response_code",
    LOG_FAILURE_FIELD_TYPE_NUMBER);

#if defined(LOGFMT_META_RESPONSE_MS)
  field_add(p, fields, LOGFMT_META_RESPONSE_MS, "response_ms",
    LOG_FAILURE_FIELD_TYPE_NUMBER);
#endif /* LOGFMT_META_RESPONSE_MS */

  field_add(p, fields, LOGFMT_META_CLASS, "connection_class",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_ANON_PASS, "anon_password",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_METHOD, "command",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_XFER_PATH, "transfer_path",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_DIR_NAME, "dir_name",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_DIR_PATH, "dir_path",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_CMD_PARAMS, "command_params",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_RESPONSE_STR, "response_msg",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_PROTOCOL, "protocol",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_VERSION, "server_version",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_RENAME_FROM, "rename_from",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_FILE_MODIFIED, "file_modified",
    LOG_FAILURE_FIELD_TYPE_BOOLEAN);

  field_add(p, fields, LOGFMT_META_UID, "uid",
    LOG_FAILURE_FIELD_TYPE_NUMBER);

  field_add(p, fields, LOGFMT_META_GID, "gid",
    LOG_FAILURE_FIELD_TYPE_NUMBER);

  field_add(p, fields, LOGFMT_META_RAW_BYTES_IN, "session_bytes_rcvd",
    LOG_FAILURE_FIELD_TYPE_NUMBER);

  field_add(p, fields, LOGFMT_META_RAW_BYTES_OUT, "session_bytes_sent",
    LOG_FAILURE_FIELD_TYPE_NUMBER);

  field_add(p, fields, LOGFMT_META_EOS_REASON, "session_end_reason",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_VHOST_IP, "server_ip",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_NOTE_VAR, "NOTE:",
    LOG_FAILURE_FIELD_TYPE_STRING);

#if defined(LOGFMT_META_XFER_MS)
  field_add(p, fields, LOGFMT_META_XFER_MS, "transfer_ms",
    LOG_FAILURE_FIELD_TYPE_NUMBER);
#endif /* LOGFMT_META_XFER_MS */

  field_add(p, fields, LOGFMT_META_XFER_STATUS, "transfer_status",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_XFER_FAILURE, "transfer_failure",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_MICROSECS, "microsecs",
    LOG_FAILURE_FIELD_TYPE_NUMBER);

  field_add(p, fields, LOGFMT_META_MILLISECS, "millisecs",
    LOG_FAILURE_FIELD_TYPE_NUMBER);

  field_add(p, fields, LOGFMT_META_ISO8601, "timestamp",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOGFMT_META_GROUP, "group",
    LOG_FAILURE_FIELD_TYPE_STRING);

  field_add(p, fields, LOG_FAILURE_META_CONNECT, "connecting",
    LOG_FAILURE_FIELD_TYPE_BOOLEAN);

  field_add(p, fields, LOG_FAILURE_META_DISCONNECT, "disconnecting",
    LOG_FAILURE_FIELD_TYPE_BOOLEAN);

  log_failure_fields = fields;
  return 0;
}