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