static int find_next_meta(pool *p, int flags, cmd_rec *cmd, unsigned char **fmt, void *obj, void (*mkfield)(void *, const char *, size_t, unsigned int, const void *)) { struct field_info *fi; unsigned char *m; unsigned int meta; m = (*fmt) + 1; meta = *m; fi = pr_table_kget(log_failure_fields, (const void *) &meta, sizeof(unsigned int), NULL); switch (*m) { /* XXX How to deal with the fact that we're not dealing with cmd_recs here, * but rather other events. The issue isn't the cmd so much as the LogFormat * variables which MAY be predicated on commands (e.g. %m, %r). Skip them? * Ignore them, perhaps? * * For some (e.g. failed transfers), the paths/filenames would be useful, * but they would need to be provided via event data (perhaps?), rather than * a cmd_rec (or not). */ default: pr_trace_msg(trace_channel, 7, "skipping unsupported LogFormat meta %d", *m); break; } *fmt = m; return 0; }
const char *pr_auth_gid2name(pool *p, gid_t gid) { cmd_rec *cmd = NULL; modret_t *mr = NULL; static char namebuf[64]; char *res = NULL; int have_name = FALSE; memset(namebuf, '\0', sizeof(namebuf)); gidcache_create(); if ((auth_caching & PR_AUTH_CACHE_FL_GID2NAME) && gid_tab) { void *v = NULL; v = pr_table_kget(gid_tab, (const void *) &gid, sizeof(gid_t), NULL); if (v) { sstrncpy(namebuf, v, sizeof(namebuf)); pr_trace_msg(trace_channel, 8, "using name '%s' from gidcache for GID %lu", namebuf, (unsigned long) gid); res = namebuf; return res; } else { pr_trace_msg(trace_channel, 9, "no value found in gidcache for GID %lu: %s", (unsigned long) gid, strerror(errno)); } } cmd = make_cmd(p, 1, (void *) &gid); mr = dispatch_auth(cmd, "gid2name", NULL); if (MODRET_ISHANDLED(mr) && MODRET_HASDATA(mr)) { res = mr->data; sstrncpy(namebuf, res, sizeof(namebuf)); res = namebuf; gidcache_add(gid, res); have_name = TRUE; } if (cmd->tmp_pool) { destroy_pool(cmd->tmp_pool); cmd->tmp_pool = NULL; } if (!have_name) { snprintf(namebuf, sizeof(namebuf)-1, "%lu", (unsigned long) gid); } res = namebuf; return res; }
static int log_failure_mkmsg(int flags, pool *p, const unsigned char *fmt, void *json, void (*mkfield)(void *, const char *, size_t, unsigned int, const void *)) { if (flags == LOG_FAILURE_EVENT_FL_CONNECT && session.prev_server == NULL) { unsigned int meta = LOG_FAILURE_META_CONNECT; const struct field_info *fi; bool connecting = true; fi = pr_table_kget(log_failure_fields, (const void *) &meta, sizeof(unsigned int), NULL); mkfield(json, fi->field_name, fi->field_namelen, fi->field_type, &connecting); } else if (flags == LOG_FAILURE_EVENT_FL_DISCONNECT) { unsigned int meta = LOG_FAILURE_META_DISCONNECT; struct field_info *fi; bool disconnecting = true; fi = pr_table_kget(field_idtab, (const void *) &meta, sizeof(unsigned int), NULL); mkfield(json, fi->field_name, fi->field_namelen, fi->field_type, &disconnecting); } while (*fmt) { pr_signals_handle(); if (*fmt == LOGFMT_META_START) { find_next_meta(p, flags, cmd, &fmt, json, mkfield); } else { fmt++; } } return 0; }
static void mcache_set_module_namespace(pr_memcache_t *mcache, module *m) { memcached_return res = MEMCACHED_SUCCESS; if (m == NULL) { res = memcached_callback_set(mcache->mc, MEMCACHED_CALLBACK_PREFIX_KEY, NULL); } else { if (mcache->namespace_tab != NULL) { const char *v; v = pr_table_kget(mcache->namespace_tab, m, sizeof(module *), NULL); if (v != NULL) { pr_trace_msg(trace_channel, 25, "using namespace prefix '%s' for module 'mod_%s.c'", v, m->name); res = memcached_callback_set(mcache->mc, MEMCACHED_CALLBACK_PREFIX_KEY, (void *) v); } } else { res = MEMCACHED_SUCCESS; } } if (res != MEMCACHED_SUCCESS) { if (m != NULL) { pr_trace_msg(trace_channel, 9, "unable to set MEMCACHED_CALLBACK_PREFIX_KEY for module 'mod_%s.c': %s", m->name, memcached_strerror(mcache->mc, res)); } else { pr_trace_msg(trace_channel, 9, "unable to clear MEMCACHED_CALLBACK_PREFIX_KEY: %s", memcached_strerror(mcache->mc, res)); } } }