diff --git a/src/box/authentication.cc b/src/box/authentication.cc index b0c730d929bac60d5f62c2ebcad11f376577c93f..53f9d6a214258893f6c6de4b5763207f9fdb0bf7 100644 --- a/src/box/authentication.cc +++ b/src/box/authentication.cc @@ -86,6 +86,6 @@ authenticate(const char *user_name, uint32_t len, if (! rlist_empty(&session_on_auth)) session_run_on_auth_triggers(user->def.name); ok: - credentials_init(&session->credentials, user); + credentials_init(&session->credentials, user->auth_token, + user->def.uid); } - diff --git a/src/box/box.cc b/src/box/box.cc index c8fc8a1656e3df804610b3d90beec25fc4ac9021..7a25ffb30c1c3601d5e2cbe1fc21c1baeeafb82d 100644 --- a/src/box/box.cc +++ b/src/box/box.cc @@ -1019,7 +1019,9 @@ box_process_call(struct request *request, struct obuf *out) * system spaces from a snapshot). */ struct user *owner = user_find_xc(func->def.uid); - credentials_init(&func->owner_credentials, owner); + credentials_init(&func->owner_credentials, + owner->auth_token, + owner->def.uid); } fiber_set_user(fiber(), &func->owner_credentials); } @@ -1310,9 +1312,7 @@ box_free(void) */ if (box_init_done) { #if 0 - session_free(); cluster_free(); - user_cache_free(); schema_free(); tuple_free(); port_free(); @@ -1483,13 +1483,6 @@ box_init(void) engine_init(); schema_init(); - user_cache_init(); - /* - * The order is important: to initialize sessions, - * we need to access the admin user, which is used - * as a default session user when running triggers. - */ - session_init(); cluster_init(); port_init(); diff --git a/src/box/iproto.cc b/src/box/iproto.cc index bb9ab676278b07011f57f72920c452a7df71792c..e5370e9403290c331da2c27b9d2b017b3913bed1 100644 --- a/src/box/iproto.cc +++ b/src/box/iproto.cc @@ -1053,14 +1053,18 @@ tx_process_connect(struct cmsg *m) struct obuf *out = &msg->iobuf->out; try { /* connect. */ con->session = session_create(con->input.fd); + if (con->session == NULL) + diag_raise(); static __thread char greeting[IPROTO_GREETING_SIZE]; /* TODO: dirty read from tx thread */ struct tt_uuid uuid = SERVER_UUID; greeting_encode(greeting, tarantool_version_id(), &uuid, con->session->salt, SESSION_SEED_SIZE); obuf_dup_xc(out, greeting, IPROTO_GREETING_SIZE); - if (! rlist_empty(&session_on_connect)) - session_run_on_connect_triggers(con->session); + if (! rlist_empty(&session_on_connect)) { + if (session_run_on_connect_triggers(con->session) != 0) + diag_raise(); + } msg->write_end = obuf_create_svp(out); } catch (Exception *e) { iproto_reply_error(out, e, 0 /* zero sync for connect error */); diff --git a/src/box/lua/console.c b/src/box/lua/console.c index e3fec23031f7d40243db41f55a4d704eb17bac47..e4c6ed295ea087dab1f0ba28de3bff2ee416571e 100644 --- a/src/box/lua/console.c +++ b/src/box/lua/console.c @@ -32,6 +32,7 @@ #include "box/lua/console.h" #include "lua/utils.h" #include "lua/fiber.h" +#include "box/session.h" #include "fiber.h" #include "coio.h" #include <lua.h> diff --git a/src/box/lua/load_cfg.lua b/src/box/lua/load_cfg.lua index 5e670ec5ccdc1df4f8c3a49de4630453a92a01b4..add4318de0659b704054097b08113d4a281956f9 100644 --- a/src/box/lua/load_cfg.lua +++ b/src/box/lua/load_cfg.lua @@ -254,7 +254,7 @@ local box_configured = {} for k, v in pairs(box) do box_configured[k] = v -- box.net.box uses box.error and box.internal - if k ~= 'error' and k ~= 'internal' and k ~= 'index' then + if k ~= 'error' and k ~= 'internal' and k ~= 'session' and k ~= 'index' then box[k] = nil end end diff --git a/src/box/lua/session.c b/src/box/lua/session.c index be6a3733ec79d10fc0623809ec08c777bdfce9b3..35bf386c386a65937d6414795733384303b2586f 100644 --- a/src/box/lua/session.c +++ b/src/box/lua/session.c @@ -42,6 +42,8 @@ static const char *sessionlib_name = "box.session"; +extern uint32_t sc_version; + /** * Return a unique monotonic session * identifier. The identifier can be used @@ -105,6 +107,8 @@ lbox_session_user(struct lua_State *L) static int lbox_session_su(struct lua_State *L) { + if (sc_version == 0) + luaL_error(L, "Please call box.cfg{} first"); int top = lua_gettop(L); if (top < 1) luaL_error(L, "session.su(): bad arguments"); @@ -123,7 +127,7 @@ lbox_session_su(struct lua_State *L) luaT_error(L); struct credentials orig_cr; credentials_copy(&orig_cr, &session->credentials); - credentials_init(&session->credentials, user); + credentials_init(&session->credentials, user->auth_token, user->def.uid); if (top == 1) return 0; /* su */ diff --git a/src/box/schema.cc b/src/box/schema.cc index 9b19ec9d33241aa7259c765d8a989a0126438df8..2506bf4b9b20aeb4599c1aa57826a078f31d3997 100644 --- a/src/box/schema.cc +++ b/src/box/schema.cc @@ -60,7 +60,7 @@ static struct mh_i32ptr_t *spaces; static struct mh_i32ptr_t *funcs; static struct mh_strnptr_t *funcs_by_name; -uint32_t sc_version; +uint32_t sc_version = 0; /** * Lock of scheme modification */ diff --git a/src/box/session.cc b/src/box/session.cc index 66fe50e5b712432389a67513d5a0dec1420af064..62796888fb67aadec369c4d69a7f2fddd4d675ee 100644 --- a/src/box/session.cc +++ b/src/box/session.cc @@ -32,6 +32,7 @@ #include "fiber.h" #include "memory.h" +#include "user_def.h" #include "assoc.h" #include "trigger.h" #include "random.h" @@ -73,13 +74,19 @@ session_on_stop(struct trigger *trigger, void * /* event */) struct session * session_create(int fd) { - struct session *session = (struct session *) - mempool_alloc_xc(&session_pool); + struct session *session = + (struct session *) mempool_alloc(&session_pool); + if (session == NULL) { + diag_set(OutOfMemory, session_pool.objsize, "mempool", + "new slab"); + return NULL; + } session->id = sid_max(); session->fd = fd; session->sync = 0; /* For on_connect triggers. */ - credentials_init(&session->credentials, guest_user); + credentials_init(&session->credentials, guest_user->auth_token, + guest_user->def.uid); if (fd >= 0) random_bytes(session->salt, SESSION_SEED_SIZE); struct mh_i32ptr_node_t node; @@ -90,7 +97,8 @@ session_create(int fd) if (k == mh_end(session_registry)) { mempool_free(&session_pool, session); - tnt_raise(OutOfMemory, 0, "session hash", "new session"); + diag_set(OutOfMemory, 0, "session hash", "new session"); + return NULL; } return session; } @@ -100,12 +108,15 @@ session_create_on_demand() { /* Create session on demand */ struct session *s = session_create(-1); + if (s == NULL) + return NULL; s->fiber_on_stop = { RLIST_LINK_INITIALIZER, session_on_stop, NULL, NULL }; /* Add a trigger to destroy session on fiber stop */ trigger_add(&fiber()->on_stop, &s->fiber_on_stop); - credentials_init(&s->credentials, admin_user); + credentials_init(&s->credentials, admin_user->auth_token, + admin_user->def.uid); fiber_set_session(fiber(), s); fiber_set_user(fiber(), &s->credentials); return s; @@ -117,7 +128,7 @@ session_create_on_demand() */ struct credentials admin_credentials; -void +int session_run_on_disconnect_triggers(struct session *session) { struct fiber *fiber = fiber(); @@ -130,17 +141,23 @@ session_run_on_disconnect_triggers(struct session *session) e->log(); } session_storage_cleanup(session->id); + return 0; } -void +int session_run_on_connect_triggers(struct session *session) { /* Run on_connect with admin credentals */ struct fiber *fiber = fiber(); fiber_set_session(fiber, session); fiber_set_user(fiber, &admin_credentials); - trigger_run(&session_on_connect, NULL); + try { + trigger_run(&session_on_connect, NULL); + } catch (Exception *) { + return -1; + } /* Set session user to guest, until it is authenticated. */ + return 0; } void @@ -174,7 +191,7 @@ session_init() if (session_registry == NULL) panic("out of memory"); mempool_create(&session_pool, &cord()->slabc, sizeof(struct session)); - credentials_init(&admin_credentials, admin_user); + credentials_init(&admin_credentials, ADMIN, ADMIN); /** * When session_init() is called, admin user access is not * loaded yet (is 0), force global access. diff --git a/src/box/session.h b/src/box/session.h index d45e1451b1ee674e5ae1ec30669d92c011414a6a..a51d2ce711c57adb92148d49d7263a73365265b8 100644 --- a/src/box/session.h +++ b/src/box/session.h @@ -105,11 +105,11 @@ fiber_set_session(struct fiber *fiber, struct session *session) } static inline void -credentials_init(struct credentials *cr, struct user *user) +credentials_init(struct credentials *cr, uint8_t auth_token, uint32_t uid) { - cr->auth_token = user->auth_token; + cr->auth_token = auth_token; cr->universal_access = universe.access[cr->auth_token].effective; - cr->uid = user->def.uid; + cr->uid = uid; } static inline void @@ -156,9 +156,6 @@ extern struct rlist session_on_disconnect; void session_storage_cleanup(int sid); -#if defined(__cplusplus) -} /* extern "C" */ - /** * Create a session. * Invokes a Lua trigger box.session.on_connect if it is @@ -186,13 +183,16 @@ void session_destroy(struct session *); /** Run on-connect triggers */ -void +int session_run_on_connect_triggers(struct session *session); /** Run on-disconnect triggers */ -void +int session_run_on_disconnect_triggers(struct session *session); +#if defined(__cplusplus) +} /* extern "C" */ + void session_run_on_auth_triggers(const char *user_name); diff --git a/src/main.cc b/src/main.cc index a5c7f13f2f6540b5e6546b46f9fe48514decf6ba..efab43c9736fd4a52cd07c172693c22ba03b458e 100644 --- a/src/main.cc +++ b/src/main.cc @@ -74,6 +74,7 @@ #include "title.h" #include <libutil.h> #include "box/lua/init.h" /* box_lua_init() */ +#include "box/session.h" static pid_t master_pid = getpid(); static struct pidfh *pid_file_handle; @@ -506,6 +507,8 @@ tarantool_free(void) * are too interconnected. */ tarantool_lua_free(); + session_free(); + user_cache_free(); fiber_free(); memory_free(); random_free(); @@ -617,6 +620,10 @@ main(int argc, char **argv) coeio_enable(); signal_init(); cbus_init(); + + user_cache_init(); + session_init(); + tarantool_lua_init(tarantool_bin, main_argc, main_argv); box_lua_init(tarantool_L);