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