summaryrefslogtreecommitdiffstats
path: root/src/plugins/mail-lua/mail-lua-plugin.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:51:24 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:51:24 +0000
commitf7548d6d28c313cf80e6f3ef89aed16a19815df1 (patch)
treea3f6f2a3f247293bee59ecd28e8cd8ceb6ca064a /src/plugins/mail-lua/mail-lua-plugin.c
parentInitial commit. (diff)
downloaddovecot-f7548d6d28c313cf80e6f3ef89aed16a19815df1.tar.xz
dovecot-f7548d6d28c313cf80e6f3ef89aed16a19815df1.zip
Adding upstream version 1:2.3.19.1+dfsg1.upstream/1%2.3.19.1+dfsg1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/plugins/mail-lua/mail-lua-plugin.c')
-rw-r--r--src/plugins/mail-lua/mail-lua-plugin.c167
1 files changed, 167 insertions, 0 deletions
diff --git a/src/plugins/mail-lua/mail-lua-plugin.c b/src/plugins/mail-lua/mail-lua-plugin.c
new file mode 100644
index 0000000..146d95b
--- /dev/null
+++ b/src/plugins/mail-lua/mail-lua-plugin.c
@@ -0,0 +1,167 @@
+/* Copyright (c) 2018 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "module-dir.h"
+#include "mail-lua-plugin.h"
+#include "mail-storage-lua.h"
+#include "mail-storage-private.h"
+#include "mail-storage-hooks.h"
+#include "dlua-script-private.h"
+
+#define MAIL_LUA_SCRIPT "mail_lua_script"
+#define MAIL_LUA_USER_CREATED_FN "mail_user_created"
+#define MAIL_LUA_USER_DEINIT_FN "mail_user_deinit"
+#define MAIL_LUA_USER_DEINIT_PRE_FN "mail_user_deinit_pre"
+#define MAIL_LUA_USER_CONTEXT(obj) \
+ MODULE_CONTEXT(obj, mail_lua_user_module)
+
+static MODULE_CONTEXT_DEFINE_INIT(mail_lua_user_module,
+ &mail_user_module_register);
+
+struct mail_lua_user_context {
+ union mail_user_module_context module_ctx;
+ struct dlua_script *script;
+};
+
+static int mail_lua_call_hook(struct dlua_script *script,
+ struct mail_user *user,
+ const char *hook,
+ const char **error_r)
+{
+ const char *error;
+
+ if (!dlua_script_has_function(script, hook))
+ return 0;
+
+ if (user->mail_debug)
+ e_debug(user->event, "mail-lua: Calling %s(user)", hook);
+
+ dlua_push_mail_user(script->L, user);
+
+ if (dlua_pcall(script->L, hook, 1, 2, &error) < 0) {
+ *error_r = t_strdup_printf("%s(user) failed: %s", hook, error);
+ return -1;
+ }
+
+ int ret = lua_tonumber(script->L, -2);
+ const char *errmsg = lua_tostring(script->L, -1);
+
+ if (ret < 0) {
+ *error_r = t_strdup_printf("%s(user) failed: %s",
+ hook, errmsg);
+ }
+
+ lua_pop(script->L, 2);
+ (void)lua_gc(script->L, LUA_GCCOLLECT, 0);
+
+ return ret < 0 ? -1 : 1;
+}
+
+static void mail_lua_user_deinit_pre(struct mail_user *user)
+{
+ struct mail_lua_user_context *luser = MAIL_LUA_USER_CONTEXT(user);
+ const char *error;
+
+ if (luser == NULL)
+ return;
+
+ if (mail_lua_call_hook(luser->script, user, MAIL_LUA_USER_DEINIT_PRE_FN,
+ &error) < 0) {
+ e_error(user->event, "mail-lua: %s", error);
+ }
+
+ luser->module_ctx.super.deinit_pre(user);
+}
+
+static void mail_lua_user_deinit(struct mail_user *user)
+{
+ struct mail_lua_user_context *luser = MAIL_LUA_USER_CONTEXT(user);
+ const char *error;
+
+ if (luser == NULL)
+ return;
+
+ luser->module_ctx.super.deinit(user);
+
+ if (mail_lua_call_hook(luser->script, user, MAIL_LUA_USER_DEINIT_FN,
+ &error) < 0) {
+ e_error(user->event, "mail-lua: %s", error);
+ }
+
+ dlua_script_unref(&luser->script);
+}
+
+static void mail_lua_user_created(struct mail_user *user)
+{
+ struct mail_lua_user_context *luser;
+ struct mail_user_vfuncs *v = user->vlast;
+ struct dlua_script *script;
+ const char *error;
+ const char *script_fn = mail_user_plugin_getenv(user, MAIL_LUA_SCRIPT);
+ int ret;
+
+ if (script_fn == NULL)
+ return;
+
+ if (dlua_script_create_file(script_fn, &script, user->event, &error) < 0) {
+ user->error = p_strdup_printf(user->pool, "dlua_script_create_file(%s) failed: %s",
+ script_fn, error);
+ return;
+ }
+
+ dlua_dovecot_register(script);
+ dlua_register_mail_storage(script);
+
+ /* init */
+ if (dlua_script_init(script, &error) < 0) {
+ user->error = p_strdup_printf(user->pool, "dlua_script_init(%s) failed: %s",
+ script_fn, error);
+ dlua_script_unref(&script);
+ return;
+ }
+
+ /* call postlogin hook */
+ if ((ret = mail_lua_call_hook(script, user, MAIL_LUA_USER_CREATED_FN,
+ &error)) <= 0) {
+ if (ret < 0)
+ user->error = p_strdup(user->pool, error);
+ dlua_script_unref(&script);
+ return;
+ }
+
+ luser = p_new(user->pool, struct mail_lua_user_context, 1);
+ luser->module_ctx.super = *v;
+ v->deinit_pre = mail_lua_user_deinit_pre;
+ v->deinit = mail_lua_user_deinit;
+ luser->script = script;
+ user->vlast = &luser->module_ctx.super;
+
+ MODULE_CONTEXT_SET(user, mail_lua_user_module, luser);
+}
+
+bool mail_lua_plugin_get_script(struct mail_user *user,
+ struct dlua_script **script_r)
+{
+ struct mail_lua_user_context *luser = MAIL_LUA_USER_CONTEXT(user);
+ if (luser != NULL) {
+ *script_r = luser->script;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static const struct mail_storage_hooks mail_lua_hooks = {
+ .mail_user_created = mail_lua_user_created,
+};
+
+void mail_lua_plugin_init(struct module *module)
+{
+ mail_storage_hooks_add(module, &mail_lua_hooks);
+}
+
+void mail_lua_plugin_deinit(void)
+{
+ mail_storage_hooks_remove(&mail_lua_hooks);
+}
+
+const char *mail_lua_plugin_dependencies[] = { NULL };