예제 #1
0
파일: memcache.c 프로젝트: laoflch/proftpd
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;
}
static int field_add(pool *p, pr_table_t *tab, unsigned int id,
    const char *name, unsigned int field_type) {
  unsigned int *k;
  struct field_info *fi;
  int res;

  k = palloc(p, sizeof(unsigned int));
  *k = id;

  fi = palloc(p, sizeof(struct field_info));
  fi->field_type = field_type;
  fi->field_name = name;
  fi->field_namelen = strlen(name) + 1;

  res = pr_table_kadd(tab, (const void *) k, sizeof(unsigned int),
    fi, sizeof(struct field_info *));
  return res;
}
예제 #3
0
파일: auth.c 프로젝트: Distrotech/proftpd
static void gidcache_add(gid_t gid, const char *name) {
  if (!(auth_caching & PR_AUTH_CACHE_FL_GID2NAME)) {
    return;
  }

  gidcache_create();

  if (gid_tab) {
    int count;

    (void) pr_table_rewind(gid_tab);
    count = pr_table_kexists(gid_tab, (const void *) &gid, sizeof(gid_t));
    if (count <= 0) {
      gid_t *cache_gid;

      /* Allocate memory for a GID out of the ID cache pool, so that this
       * GID can be used as a key.
       */
      cache_gid = palloc(auth_pool, sizeof(gid_t));
      *cache_gid = gid;

      if (pr_table_kadd(gid_tab, (const void *) cache_gid, sizeof(gid_t),
          pstrdup(auth_pool, name), strlen(name) + 1) < 0 &&
          errno != EEXIST) {
        pr_trace_msg(trace_channel, 3,
          "error adding name '%s' for GID %lu to the gidcache: %s", name,
          (unsigned long) gid, strerror(errno));

      } else {
        pr_trace_msg(trace_channel, 5,
          "stashed name '%s' for GID %lu in the gidcache", name,
          (unsigned long) gid);
      }
    }
  }
}
예제 #4
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;
}