From: Timo Sirainen Date: Thu, 7 Oct 2021 16:59:52 +0000 (+0300) Subject: lib-dict: dict-lua - Throw Lua error if dict key is invalid or username is missing X-Git-Tag: 2.3.18~198 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=859529c80261e51705fb4ff51392cbbc3f8398d3;p=thirdparty%2Fdovecot%2Fcore.git lib-dict: dict-lua - Throw Lua error if dict key is invalid or username is missing This prevents assert-crashes in the C code. --- diff --git a/src/lib-dict/dict-iter-lua.c b/src/lib-dict/dict-iter-lua.c index 1af3009be0..780de0316a 100644 --- a/src/lib-dict/dict-iter-lua.c +++ b/src/lib-dict/dict-iter-lua.c @@ -168,6 +168,7 @@ int lua_dict_iterate(lua_State *L) flags = luaL_checkinteger(L, 3); if (lua_gettop(L) >= 4) username = luaL_checkstring(L, 4); + lua_dict_check_key_prefix(L, path, username); struct dict_op_settings set = { .username = username, diff --git a/src/lib-dict/dict-lua.c b/src/lib-dict/dict-lua.c index abab8c7f93..d5de534218 100644 --- a/src/lib-dict/dict-lua.c +++ b/src/lib-dict/dict-lua.c @@ -58,6 +58,19 @@ static void lua_dict_lookup_callback(const struct dict_lookup_result *result, dlua_pcall_yieldable_resume(L, 1); } +void lua_dict_check_key_prefix(lua_State *L, const char *key, + const char *username) +{ + if (str_begins(key, DICT_PATH_SHARED)) + ; + else if (str_begins(key, DICT_PATH_PRIVATE)) { + if (username == NULL || username[0] == '\0') + luaL_error(L, DICT_PATH_PRIVATE" dict key prefix requires username"); + } else { + luaL_error(L, "Invalid dict key prefix"); + } +} + /* * Lookup a key in dict [-(2|3),+1,e] * @@ -82,6 +95,7 @@ static int lua_dict_lookup(lua_State *L) key = luaL_checkstring(L, 2); if (lua_gettop(L) >= 3) username = luaL_checkstring(L, 3); + lua_dict_check_key_prefix(L, key, username); struct dict_op_settings set = { .username = username, diff --git a/src/lib-dict/dict-lua.h b/src/lib-dict/dict-lua.h index 186f4e9974..bf4255cc0a 100644 --- a/src/lib-dict/dict-lua.h +++ b/src/lib-dict/dict-lua.h @@ -7,6 +7,9 @@ * 5.3 and newer. */ +void lua_dict_check_key_prefix(lua_State *L, const char *key, + const char *username); + void dlua_push_dict(lua_State *L, struct dict *dict); struct dict *dlua_check_dict(lua_State *L, int idx); diff --git a/src/lib-dict/dict-txn-lua.c b/src/lib-dict/dict-txn-lua.c index a7503ba136..34a475dc54 100644 --- a/src/lib-dict/dict-txn-lua.c +++ b/src/lib-dict/dict-txn-lua.c @@ -17,6 +17,7 @@ struct lua_dict_txn { } state; lua_State *L; + const char *username; }; static int lua_dict_transaction_rollback(lua_State *L); @@ -161,6 +162,7 @@ static int lua_dict_set(lua_State *L) txn = xlua_dict_txn_getptr(L, 1, NULL); key = luaL_checkstring(L, 2); value = luaL_checkstring(L, 3); + lua_dict_check_key_prefix(L, key, txn->username); dict_set(txn->txn, key, value); @@ -183,6 +185,7 @@ static int lua_dict_unset(lua_State *L) txn = xlua_dict_txn_getptr(L, 1, NULL); key = luaL_checkstring(L, 2); + lua_dict_check_key_prefix(L, key, txn->username); dict_unset(txn->txn, key); @@ -223,6 +226,7 @@ int lua_dict_transaction_begin(lua_State *L) txn->txn = dict_transaction_begin(dict, &set); txn->state = STATE_OPEN; txn->L = L; + txn->username = p_strdup(txn->pool, username); xlua_pushdict_txn(L, txn, FALSE);