dovecot-2.1: auth: Added "dict" passdb/userdb.

dovecot at dovecot.org dovecot at dovecot.org
Sun Jul 8 09:01:11 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.1/rev/523c19238a8b
changeset: 14606:523c19238a8b
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Jul 08 07:45:17 2012 +0300
description:
auth: Added "dict" passdb/userdb.

diffstat:

 doc/example-config/conf.d/auth-dict.conf.ext  |   16 ++
 doc/example-config/dovecot-dict-auth.conf.ext |   22 ++
 src/auth/Makefile.am                          |    5 +
 src/auth/db-dict.c                            |  177 ++++++++++++++++++++++
 src/auth/db-dict.h                            |   37 ++++
 src/auth/main.c                               |    3 +
 src/auth/passdb-dict.c                        |  197 ++++++++++++++++++++++++
 src/auth/passdb.c                             |    2 +
 src/auth/userdb-dict.c                        |  207 ++++++++++++++++++++++++++
 src/auth/userdb.c                             |    2 +
 10 files changed, 668 insertions(+), 0 deletions(-)

diffs (truncated from 788 to 300 lines):

diff -r 01cdca5817f2 -r 523c19238a8b doc/example-config/conf.d/auth-dict.conf.ext
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/example-config/conf.d/auth-dict.conf.ext	Sun Jul 08 07:45:17 2012 +0300
@@ -0,0 +1,16 @@
+# Authentication via dict backend. Included from auth.conf.
+#
+# <doc/wiki/AuthDatabase.Dict.txt>
+
+passdb {
+  driver = dict
+
+  # Path for dict configuration file, see
+  # example-config/dovecot-dict-auth.conf.ext
+  args = /etc/dovecot/dovecot-dict-auth.conf.ext
+}
+
+userdb {
+  driver = dict
+  args = /etc/dovecot/dovecot-dict-auth.conf.ext
+}
diff -r 01cdca5817f2 -r 523c19238a8b doc/example-config/dovecot-dict-auth.conf.ext
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/example-config/dovecot-dict-auth.conf.ext	Sun Jul 08 07:45:17 2012 +0300
@@ -0,0 +1,22 @@
+# Dictionary URI
+#uri = 
+
+# Key for passdb lookups
+password_key = dovecot/passdb/%u
+
+# Key for userdb lookups
+user_key = dovecot/userdb/%u
+
+# How to parse the value for key=value pairs. Currently we support only JSON
+# format with { "key": "value", ... } object.
+#value_format = json
+
+# Username iteration prefix. Keys under this are assumed to contain usernames.
+iterate_prefix = dovecot/userdb/
+
+# Should iteration be disabled for this userdb? If this userdb acts only as a
+# cache there's no reason to try to iterate the (partial & duplicate) users.
+#iterate_disable = no
+
+# Default password scheme
+default_pass_scheme = MD5
diff -r 01cdca5817f2 -r 523c19238a8b src/auth/Makefile.am
--- a/src/auth/Makefile.am	Sun Jul 08 07:37:28 2012 +0300
+++ b/src/auth/Makefile.am	Sun Jul 08 07:45:17 2012 +0300
@@ -25,6 +25,7 @@
 	-I$(top_srcdir)/src/lib \
 	-I$(top_srcdir)/src/lib-auth \
 	-I$(top_srcdir)/src/lib-test \
+	-I$(top_srcdir)/src/lib-dict \
 	-I$(top_srcdir)/src/lib-dns \
 	-I$(top_srcdir)/src/lib-sql \
 	-I$(top_srcdir)/src/lib-settings \
@@ -73,6 +74,7 @@
 	auth-worker-client.c \
 	auth-worker-server.c \
 	db-checkpassword.c \
+	db-dict.c \
 	db-sql.c \
 	db-passwd-file.c \
 	main.c \
@@ -96,6 +98,7 @@
 	passdb-bsdauth.c \
 	passdb-cache.c \
 	passdb-checkpassword.c \
+	passdb-dict.c \
 	passdb-passwd.c \
 	passdb-passwd-file.c \
 	passdb-pam.c \
@@ -108,6 +111,7 @@
 	userdb.c \
 	userdb-blocking.c \
 	userdb-checkpassword.c \
+	userdb-dict.c \
 	userdb-nss.c \
 	userdb-passwd.c \
 	userdb-passwd-file.c \
@@ -134,6 +138,7 @@
 	auth-stream.h \
 	auth-worker-client.h \
 	auth-worker-server.h \
+	db-dict.h \
 	db-ldap.h \
 	db-sql.h \
 	db-passwd-file.h \
diff -r 01cdca5817f2 -r 523c19238a8b src/auth/db-dict.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/auth/db-dict.c	Sun Jul 08 07:45:17 2012 +0300
@@ -0,0 +1,177 @@
+/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */
+
+#include "auth-common.h"
+
+#include "settings.h"
+#include "dict.h"
+#include "json-parser.h"
+#include "str.h"
+#include "auth-request.h"
+#include "auth-worker-client.h"
+#include "db-dict.h"
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#define DEF_STR(name) DEF_STRUCT_STR(name, db_dict_settings)
+#define DEF_BOOL(name) DEF_STRUCT_BOOL(name, db_dict_settings)
+
+static struct setting_def setting_defs[] = {
+	DEF_STR(uri),
+	DEF_STR(password_key),
+	DEF_STR(user_key),
+ 	DEF_STR(iterate_prefix),
+ 	DEF_STR(value_format),
+ 	DEF_BOOL(iterate_disable),
+	DEF_STR(default_pass_scheme),
+
+	{ 0, NULL, 0 }
+};
+
+static struct db_dict_settings default_dict_settings = {
+	.uri = NULL,
+	.password_key = "",
+	.user_key = "",
+	.iterate_prefix = "",
+	.iterate_disable = FALSE,
+	.value_format = "json",
+	.default_pass_scheme = "MD5"
+};
+
+static struct dict_connection *connections = NULL;
+
+static struct dict_connection *dict_conn_find(const char *config_path)
+{
+	struct dict_connection *conn;
+
+	for (conn = connections; conn != NULL; conn = conn->next) {
+		if (strcmp(conn->config_path, config_path) == 0)
+			return conn;
+	}
+
+	return NULL;
+}
+
+static const char *parse_setting(const char *key, const char *value,
+				 struct dict_connection *conn)
+{
+	return parse_setting_from_defs(conn->pool, setting_defs,
+				       &conn->set, key, value);
+}
+
+struct dict_connection *db_dict_init(const char *config_path)
+{
+	struct dict_connection *conn;
+	pool_t pool;
+
+	conn = dict_conn_find(config_path);
+	if (conn != NULL) {
+		conn->refcount++;
+		return conn;
+	}
+
+	if (*config_path == '\0')
+		i_fatal("dict: Configuration file path not given");
+
+	pool = pool_alloconly_create("dict_connection", 1024);
+	conn = p_new(pool, struct dict_connection, 1);
+	conn->pool = pool;
+
+	conn->refcount = 1;
+
+	conn->config_path = p_strdup(pool, config_path);
+	conn->set = default_dict_settings;
+	if (!settings_read(config_path, NULL, parse_setting,
+			   null_settings_section_callback, conn))
+		exit(FATAL_DEFAULT);
+
+	if (conn->set.uri == NULL)
+		i_fatal("dict %s: Empty uri setting", config_path);
+	if (strcmp(conn->set.value_format, "json") != 0) {
+		i_fatal("dict %s: Unsupported value_format %s in ",
+			config_path, conn->set.value_format);
+	}
+	conn->dict = dict_init(conn->set.uri, DICT_DATA_TYPE_STRING, "",
+			       global_auth_settings->base_dir);
+
+	conn->next = connections;
+	connections = conn;
+	return conn;
+}
+
+void db_dict_unref(struct dict_connection **_conn)
+{
+	struct dict_connection *conn = *_conn;
+
+	*_conn = NULL;
+	if (--conn->refcount > 0)
+		return;
+
+	dict_deinit(&conn->dict);
+	pool_unref(&conn->pool);
+}
+
+struct db_dict_value_iter {
+	struct json_parser *parser;
+	string_t *key;
+	const char *error;
+};
+
+struct db_dict_value_iter *
+db_dict_value_iter_init(struct dict_connection *conn, const char *value)
+{
+	struct db_dict_value_iter *iter;
+
+	i_assert(strcmp(conn->set.value_format, "json") == 0);
+
+	/* hardcoded for now for JSON value. make it more modular when other
+	   value types are supported. */
+	iter = i_new(struct db_dict_value_iter, 1);
+	iter->key = str_new(default_pool, 64);
+	iter->parser = json_parser_init((const void *)value, strlen(value));
+	return iter;
+}
+
+bool db_dict_value_iter_next(struct db_dict_value_iter *iter,
+			     const char **key_r, const char **value_r)
+{
+	enum json_type type;
+	const char *value;
+
+	if (!json_parse_next(iter->parser, &type, &value))
+		return FALSE;
+	if (type != JSON_TYPE_OBJECT_KEY) {
+		iter->error = "Object expected";
+		return FALSE;
+	}
+	if (*value == '\0') {
+		iter->error = "Empty object key";
+		return FALSE;
+	}
+	str_truncate(iter->key, 0);
+	str_append(iter->key, value);
+
+	if (!json_parse_next(iter->parser, &type, &value)) {
+		iter->error = "Missing value";
+		return FALSE;
+	}
+	*key_r = str_c(iter->key);
+	*value_r = value;
+	return TRUE;
+}
+
+int db_dict_value_iter_deinit(struct db_dict_value_iter **_iter,
+			      const char **error_r)
+{
+	struct db_dict_value_iter *iter = *_iter;
+
+	*_iter = NULL;
+
+	*error_r = iter->error;
+	if (json_parser_deinit(&iter->parser, &iter->error) < 0 &&
+	    *error_r == NULL)
+		*error_r = iter->error;
+	str_free(&iter->key);
+	i_free(iter);
+	return *error_r != NULL ? -1 : 0;
+}
diff -r 01cdca5817f2 -r 523c19238a8b src/auth/db-dict.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/auth/db-dict.h	Sun Jul 08 07:45:17 2012 +0300
@@ -0,0 +1,37 @@
+#ifndef DB_DICT_H
+#define DB_DICT_H
+
+#include "sql-api.h"
+
+struct db_dict_settings {
+	const char *uri;
+	const char *password_key;
+	const char *user_key;
+	const char *iterate_prefix;
+	bool iterate_disable;
+	const char *value_format;
+	const char *default_pass_scheme;
+};
+
+struct dict_connection {
+	struct dict_connection *next;
+
+	pool_t pool;
+	int refcount;
+
+	char *config_path;
+	struct db_dict_settings set;
+	struct dict *dict;
+};
+


More information about the dovecot-cvs mailing list