X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Ffrontend%2Fconnection.c;h=fdbb26fe60518a0b1834d4c809a3f27915f54d74;hb=8fae96642304f80a5ce343626970b1cff87123f2;hp=f780979cac6ed333104d26f15bf2c8829184fb24;hpb=e8f6d4bbe38e80978db64b8554883795007c8b0d;p=sysdb.git diff --git a/src/frontend/connection.c b/src/frontend/connection.c index f780979..fdbb26f 100644 --- a/src/frontend/connection.c +++ b/src/frontend/connection.c @@ -27,6 +27,7 @@ #include "sysdb.h" #include "core/object.h" +#include "core/plugin.h" #include "frontend/connection-private.h" #include "utils/error.h" #include "utils/strbuf.h" @@ -38,10 +39,20 @@ #include #include +#include #include +#include + +/* + * private variables + */ + +static pthread_key_t conn_ctx_key; +static _Bool conn_ctx_key_initialized = 0; + /* - * private data types + * private types */ /* name of connection objects */ @@ -145,10 +156,78 @@ static sdb_type_t connection_type = { /* destroy = */ connection_destroy, }; +/* + * private helper functions + */ + +static void +sdb_conn_ctx_destructor(void *c) +{ + sdb_object_t *conn = c; + + if (! conn) + return; + sdb_object_deref(conn); +} /* sdb_conn_ctx_destructor */ + +static void +sdb_conn_ctx_init(void) +{ + if (conn_ctx_key_initialized) + return; + + pthread_key_create(&conn_ctx_key, sdb_conn_ctx_destructor); + conn_ctx_key_initialized = 1; +} /* sdb_conn_ctx_init */ + +static void +sdb_conn_set_ctx(sdb_conn_t *conn) +{ + sdb_conn_ctx_init(); + if (conn) + sdb_object_ref(SDB_OBJ(conn)); + pthread_setspecific(conn_ctx_key, conn); +} /* sdb_conn_set_ctx */ + +static sdb_conn_t * +sdb_conn_get_ctx(void) +{ + if (! conn_ctx_key_initialized) + return NULL; + return pthread_getspecific(conn_ctx_key); +} /* sdb_conn_get_ctx */ + /* * connection handler functions */ +/* + * connection_log: + * Send a log message originating from the current thread to the client. + */ +static int +connection_log(int prio, const char *msg, + sdb_object_t __attribute__((unused)) *user_data) +{ + sdb_conn_t *conn; + + conn = sdb_conn_get_ctx(); + /* no connection associated to this thread + * or user not authenticated yet => don't leak any information */ + if ((! conn) || (! conn->username)) + return 0; + + /* XXX: make the log-level configurable by the client at runtime */ + if (prio >= SDB_LOG_DEBUG) + return 0; + + /* TODO: Use CONNECTION_LOG_? */ + if (sdb_connection_send(conn, CONNECTION_LOG, + (uint32_t)strlen(msg), msg) < 0) + return -1; + return 0; +} /* connection_log */ + static uint32_t connection_get_int32(sdb_conn_t *conn, size_t offset) { @@ -173,6 +252,13 @@ command_handle(sdb_conn_t *conn) sdb_log(SDB_LOG_DEBUG, "frontend: Handling command %u (len: %u)", conn->cmd, conn->cmd_len); + if ((! conn->username) && (conn->cmd != CONNECTION_STARTUP)) { + const char *errmsg = "Authentication required"; + sdb_connection_send(conn, CONNECTION_ERROR, + (uint32_t)strlen(errmsg), errmsg); + return -1; + } + /* reset */ sdb_strbuf_sprintf(conn->errbuf, ""); @@ -215,8 +301,10 @@ command_handle(sdb_conn_t *conn) node = SDB_CONN_NODE(sdb_llist_get(parsetree, 0)); } - if (node) + if (node) { status = sdb_fe_exec(conn, node); + sdb_object_deref(SDB_OBJ(node)); + } sdb_llist_destroy(parsetree); break; @@ -296,6 +384,13 @@ connection_read(sdb_conn_t *conn) * public API */ +int +sdb_connection_enable_logging(void) +{ + return sdb_plugin_register_log("connection-logger", connection_log, + /* user_data = */ NULL); +} /* sdb_connection_enable_logging */ + sdb_conn_t * sdb_connection_accept(int fd) { @@ -319,6 +414,8 @@ sdb_connection_read(sdb_conn_t *conn) { ssize_t n = 0; + sdb_conn_set_ctx(conn); + while (42) { ssize_t status = connection_read(conn); @@ -334,6 +431,8 @@ sdb_connection_read(sdb_conn_t *conn) n += status; } + + sdb_conn_set_ctx(NULL); return n; } /* sdb_connection_read */