dovecot-2.2: last-login plugin added. It updates user's login ti...
dovecot at dovecot.org
dovecot at dovecot.org
Fri Jul 25 11:11:52 UTC 2014
details: http://hg.dovecot.org/dovecot-2.2/rev/2d2d75ac6715
changeset: 17632:2d2d75ac6715
user: Timo Sirainen <tss at iki.fi>
date: Fri Jul 25 14:10:04 2014 +0300
description:
last-login plugin added. It updates user's login timestamp to configured dict.
Example config:
plugin {
last_login_dict = redis:host=127.0.0.1:port=6379
#last_login_key = last-login/%u # default
}
diffstat:
src/plugins/last-login/Makefile.am | 19 ++++
src/plugins/last-login/last-login-plugin.c | 112 +++++++++++++++++++++++++++++
src/plugins/last-login/last-login-plugin.h | 7 +
3 files changed, 138 insertions(+), 0 deletions(-)
diffs (150 lines):
diff -r 023c6a6af008 -r 2d2d75ac6715 src/plugins/last-login/Makefile.am
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plugins/last-login/Makefile.am Fri Jul 25 14:10:04 2014 +0300
@@ -0,0 +1,19 @@
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/src/lib \
+ -I$(top_srcdir)/src/lib-dict \
+ -I$(top_srcdir)/src/lib-mail \
+ -I$(top_srcdir)/src/lib-imap \
+ -I$(top_srcdir)/src/lib-index \
+ -I$(top_srcdir)/src/lib-storage
+
+NOPLUGIN_LDFLAGS =
+lib10_last_login_plugin_la_LDFLAGS = -module -avoid-version
+
+module_LTLIBRARIES = \
+ lib10_last_login_plugin.la
+
+lib10_last_login_plugin_la_SOURCES = \
+ last-login-plugin.c
+
+noinst_HEADERS = \
+ last-login-plugin.h
diff -r 023c6a6af008 -r 2d2d75ac6715 src/plugins/last-login/last-login-plugin.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plugins/last-login/last-login-plugin.c Fri Jul 25 14:10:04 2014 +0300
@@ -0,0 +1,112 @@
+/* Copyright (c) 2014 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "ioloop.h"
+#include "dict.h"
+#include "mail-user.h"
+#include "mail-namespace.h"
+#include "mail-storage-private.h"
+#include "mail-storage-hooks.h"
+#include "last-login-plugin.h"
+
+#define LAST_LOGIN_USER_CONTEXT(obj) \
+ MODULE_CONTEXT(obj, last_login_user_module)
+
+#define LAST_LOGIN_DEFAULT_KEY_PREFIX "last-login/"
+
+struct last_login_user {
+ union mail_user_module_context module_ctx;
+ struct dict *dict;
+ struct timeout *to;
+};
+
+static MODULE_CONTEXT_DEFINE_INIT(last_login_user_module,
+ &mail_user_module_register);
+
+static void last_login_dict_deinit(struct mail_user *user)
+{
+ struct last_login_user *luser = LAST_LOGIN_USER_CONTEXT(user);
+
+ if (luser->to != NULL)
+ timeout_remove(&luser->to);
+ if (luser->dict != NULL) {
+ (void)dict_wait(luser->dict);
+ dict_deinit(&luser->dict);
+ }
+}
+
+static void last_login_user_deinit(struct mail_user *user)
+{
+ struct last_login_user *luser = LAST_LOGIN_USER_CONTEXT(user);
+
+ last_login_dict_deinit(user);
+ luser->module_ctx.super.deinit(user);
+}
+
+static void last_login_dict_commit(int ret ATTR_UNUSED, void *context)
+{
+ struct mail_user *user = context;
+ struct last_login_user *luser = LAST_LOGIN_USER_CONTEXT(user);
+
+ /* don't deinit the dict immediately here, lib-dict will just crash */
+ luser->to = timeout_add(0, last_login_dict_deinit, user);
+}
+
+static void last_login_mail_user_created(struct mail_user *user)
+{
+ struct mail_user_vfuncs *v = user->vlast;
+ struct last_login_user *luser;
+ struct dict *dict;
+ struct dict_transaction_context *trans;
+ const char *dict_value, *key_name, *error;
+
+ if (user->autocreated) {
+ /* we want to handle only logged in users,
+ not lda's raw user or accessed shared users */
+ return;
+ }
+
+ dict_value = mail_user_plugin_getenv(user, "last_login_dict");
+ if (dict_value == NULL)
+ return;
+
+ if (dict_init(dict_value, DICT_DATA_TYPE_STRING, user->username,
+ user->set->base_dir, &dict, &error) < 0) {
+ i_error("last_login_dict: dict_init(%s) failed: %s",
+ dict_value, error);
+ return;
+ }
+
+ luser = p_new(user->pool, struct last_login_user, 1);
+ luser->module_ctx.super = *v;
+ user->vlast = &luser->module_ctx.super;
+ v->deinit = last_login_user_deinit;
+
+ luser->dict = dict;
+ MODULE_CONTEXT_SET(user, last_login_user_module, luser);
+
+ key_name = mail_user_plugin_getenv(user, "last_login_key");
+ if (key_name == NULL) {
+ key_name = t_strdup_printf(LAST_LOGIN_DEFAULT_KEY_PREFIX"%s",
+ user->username);
+ }
+ key_name = t_strconcat(DICT_PATH_SHARED, key_name, NULL);
+
+ trans = dict_transaction_begin(dict);
+ dict_set(trans, key_name, dec2str(ioloop_time));
+ dict_transaction_commit_async(&trans, last_login_dict_commit, user);
+}
+
+static struct mail_storage_hooks last_login_mail_storage_hooks = {
+ .mail_user_created = last_login_mail_user_created
+};
+
+void last_login_plugin_init(struct module *module)
+{
+ mail_storage_hooks_add(module, &last_login_mail_storage_hooks);
+}
+
+void last_login_plugin_deinit(void)
+{
+ mail_storage_hooks_remove(&last_login_mail_storage_hooks);
+}
diff -r 023c6a6af008 -r 2d2d75ac6715 src/plugins/last-login/last-login-plugin.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plugins/last-login/last-login-plugin.h Fri Jul 25 14:10:04 2014 +0300
@@ -0,0 +1,7 @@
+#ifndef LAST_LOGIN_PLUGIN_H
+#define LAST_LOGIN_PLUGIN_H
+
+void last_login_plugin_init(struct module *module);
+void last_login_plugin_deinit(void);
+
+#endif
More information about the dovecot-cvs
mailing list