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; }
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); } } } }
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; }