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