X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Ffrontend%2Fconnection.c;h=b48de2c893ccbc9d9c65de335fecbb66c3421733;hb=e7edc6432f63f36a2508b4c426876593678c8434;hp=5ed49ddebfeb0584a69b55ac06fb06c7a1d5801e;hpb=dd7ed3afe782c891a8a1c11e2dbeaf2af3dd910e;p=sysdb.git diff --git a/src/frontend/connection.c b/src/frontend/connection.c index 5ed49dd..b48de2c 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, ""); @@ -219,6 +305,7 @@ command_handle(sdb_conn_t *conn) status = sdb_fe_exec(conn, node); sdb_llist_destroy(parsetree); + break; } case CONNECTION_LIST: @@ -295,6 +382,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) { @@ -318,6 +412,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); @@ -333,6 +429,8 @@ sdb_connection_read(sdb_conn_t *conn) n += status; } + + sdb_conn_set_ctx(NULL); return n; } /* sdb_connection_read */