[dovecot-cvs] dovecot/src/auth Makefile.am, 1.35, 1.36 auth-master-connection.c, 1.13, 1.14 db-mysql.c, 1.12, NONE db-mysql.h, 1.5, NONE db-pgsql.c, 1.9, NONE db-pgsql.h, 1.4, NONE db-sql.c, NONE, 1.1 db-sql.h, NONE, 1.1 passdb-mysql.c, 1.4, NONE passdb-pgsql.c, 1.6, NONE passdb-sql.c, NONE, 1.1 passdb.c, 1.23, 1.24 passdb.h, 1.14, 1.15 userdb-mysql.c, 1.3, NONE userdb-pgsql.c, 1.7, NONE userdb-sql.c, NONE, 1.1 userdb.c, 1.11, 1.12 userdb.h, 1.11, 1.12

cras at dovecot.org cras at dovecot.org
Sat Oct 16 02:12:54 EEST 2004


Update of /var/lib/cvs/dovecot/src/auth
In directory talvi:/tmp/cvs-serv14242/src/auth

Modified Files:
	Makefile.am auth-master-connection.c passdb.c passdb.h 
	userdb.c userdb.h 
Added Files:
	db-sql.c db-sql.h passdb-sql.c userdb-sql.c 
Removed Files:
	db-mysql.c db-mysql.h db-pgsql.c db-pgsql.h passdb-mysql.c 
	passdb-pgsql.c userdb-mysql.c userdb-pgsql.c 
Log Message:
Created generic asynchronous SQL API and implemented MySQL and PostgreSQL
drivers. MySQL is implemented synchronously because it's API doesn't provide
async way to do it.

Replaced pgsql and mysql userdb/passdb with generic sql userdb/passdb.



Index: Makefile.am
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/Makefile.am,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -r1.35 -r1.36
--- Makefile.am	13 Oct 2004 16:38:32 -0000	1.35
+++ Makefile.am	15 Oct 2004 23:12:52 -0000	1.36
@@ -6,6 +6,7 @@
 
 INCLUDES = \
 	-I$(top_srcdir)/src/lib \
+	-I$(top_srcdir)/src/lib-sql \
 	-I$(top_srcdir)/src/lib-settings \
 	-I$(top_srcdir)/src/lib-ntlm \
 	-DAUTH_MODULE_DIR=\""$(moduledir)/auth"\" \
@@ -24,6 +25,7 @@
 	libpassword.a \
 	../lib-settings/libsettings.a \
 	../lib-ntlm/libntlm.a \
+	../lib-sql/libsql.a \
 	../lib/liblib.a \
 	$(AUTH_LIBS) \
 	$(RAND_LIBS) \
@@ -34,8 +36,7 @@
 	auth-master-connection.c \
 	auth-module.c \
 	db-ldap.c \
-	db-mysql.c \
-	db-pgsql.c \
+	db-sql.c \
 	db-passwd-file.c \
 	main.c \
 	mech.c \
@@ -56,16 +57,14 @@
 	passdb-checkpassword.c \
 	passdb-shadow.c \
 	passdb-vpopmail.c \
-	passdb-mysql.c \
-	passdb-pgsql.c \
+	passdb-sql.c \
 	userdb.c \
 	userdb-ldap.c \
 	userdb-passwd.c \
 	userdb-passwd-file.c \
 	userdb-static.c \
 	userdb-vpopmail.c \
-	userdb-mysql.c \
-	userdb-pgsql.c
+	userdb-sql.c
 
 noinst_HEADERS = \
 	auth-client-connection.h \
@@ -73,8 +72,7 @@
 	auth-master-connection.h \
 	auth-module.h \
 	db-ldap.h \
-	db-mysql.h \
-	db-pgsql.h \
+	db-sql.h \
 	db-passwd-file.h \
 	common.h \
 	mech.h \

Index: auth-master-connection.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-master-connection.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- auth-master-connection.c	13 Oct 2004 19:13:31 -0000	1.13
+++ auth-master-connection.c	15 Oct 2004 23:12:52 -0000	1.14
@@ -30,6 +30,7 @@
 struct master_userdb_request {
 	struct auth_master_connection *conn;
 	unsigned int id;
+	struct auth_request *auth_request;
 };
 
 static void master_output(void *context);
@@ -93,6 +94,7 @@
 			master_send(master_request->conn, "%s", str_c(str));
 		}
 	}
+	auth_request_destroy(master_request->auth_request);
 	i_free(master_request);
 }
 
@@ -131,12 +133,10 @@
 		master_request = i_new(struct master_userdb_request, 1);
 		master_request->conn = conn;
 		master_request->id = id;
+		master_request->auth_request = request;
 
 		conn->refcount++;
 		userdb->lookup(request, userdb_callback, master_request);
-
-		/* the auth request is finished, we don't need it anymore */
-		auth_request_destroy(request);
 	}
 	return TRUE;
 }

--- db-mysql.c DELETED ---

--- db-mysql.h DELETED ---

--- db-pgsql.c DELETED ---

--- db-pgsql.h DELETED ---

--- NEW FILE: db-sql.c ---
/* Copyright (C) 2003-2004 Timo Sirainen */

#include "config.h"
#undef HAVE_CONFIG_H

#if defined(PASSDB_SQL) || defined(USERDB_SQL)
#include "common.h"
#include "settings.h"
#include "db-sql.h"

#include <stddef.h>
#include <stdlib.h>

#define DEF(type, name) { type, #name, offsetof(struct sql_settings, name) }

static struct setting_def setting_defs[] = {
	DEF(SET_STR, driver),
	DEF(SET_STR, connect),
	DEF(SET_STR, password_query),
	DEF(SET_STR, user_query),
	DEF(SET_STR, default_pass_scheme)
};

struct sql_settings default_sql_settings = {
	MEMBER(driver) NULL,
	MEMBER(connect) NULL,
	MEMBER(password_query) "SELECT password FROM users WHERE userid = '%u'",
	MEMBER(user_query) "SELECT home, uid, gid FROM users WHERE userid = '%u'",
	MEMBER(default_pass_scheme) "PLAIN-MD5"
};

static struct sql_connection *connections = NULL;

static struct sql_connection *sql_conn_find(const char *config_path)
{
	struct sql_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,
				 void *context)
{
	struct sql_connection *conn = context;

	return parse_setting_from_defs(conn->pool, setting_defs,
				       &conn->set, key, value);
}

struct sql_connection *db_sql_init(const char *config_path)
{
	struct sql_connection *conn;
	pool_t pool;

	conn = sql_conn_find(config_path);
	if (conn != NULL) {
		conn->refcount++;
		return conn;
	}

	pool = pool_alloconly_create("sql_connection", 1024);
	conn = p_new(pool, struct sql_connection, 1);
	conn->pool = pool;

	conn->refcount = 1;

	conn->config_path = p_strdup(pool, config_path);
	conn->set = default_sql_settings;
	if (!settings_read(config_path, NULL, parse_setting, NULL, conn))
		exit(FATAL_DEFAULT);

	if (conn->set.driver == NULL) {
		i_fatal("sql: driver not set in configuration file %s",
			config_path);
	}
	if (conn->set.connect == NULL) {
		i_fatal("sql: connect string not set in configuration file %s",
			config_path);
	}

	conn->next = connections;
	connections = conn;
	return conn;
}

void db_sql_connect(struct sql_connection *conn)
{
	if (conn->db == NULL)
		conn->db = sql_init(conn->set.driver, conn->set.connect);
}

void db_sql_unref(struct sql_connection *conn)
{
	if (--conn->refcount > 0)
		return;

	sql_deinit(conn->db);
	pool_unref(conn->pool);
}

#endif

--- NEW FILE: db-sql.h ---
#ifndef __DB_SQL_H
#define __DB_SQL_H

#include "sql-api.h"

struct sql_settings {
	const char *driver;
	const char *connect;
	const char *password_query;
	const char *user_query;
	const char *default_pass_scheme;
};

struct sql_connection {
	struct sql_connection *next;

	pool_t pool;
	int refcount;

	char *config_path;
	struct sql_settings set;
	struct sql_db *db;
};

struct sql_connection *db_sql_init(const char *config_path);
void db_sql_unref(struct sql_connection *conn);

void db_sql_connect(struct sql_connection *conn);

#endif

--- passdb-mysql.c DELETED ---

--- passdb-pgsql.c DELETED ---

--- NEW FILE: passdb-sql.c ---
/* Copyright (C) 2004 Timo Sirainen, Alex Howansky */

#include "config.h"
#undef HAVE_CONFIG_H

#ifdef PASSDB_SQL

#include "common.h"
#include "str.h"
#include "strescape.h"
#include "var-expand.h"
#include "password-scheme.h"
#include "db-sql.h"
#include "passdb.h"

#include <stdlib.h>
#include <string.h>

struct passdb_sql_request {
	struct auth_request *auth_request;
	enum passdb_credentials credentials;
	union {
		verify_plain_callback_t *verify_plain;
                lookup_credentials_callback_t *lookup_credentials;
	} callback;

	char password[1];
};

static struct sql_connection *passdb_sql_conn;

static void sql_query_callback(struct sql_result *result, void *context)
{
	struct passdb_sql_request *sql_request = context;
	struct auth_request *auth_request = sql_request->auth_request;
	const char *user, *password, *scheme;
	int ret;

	user = auth_request->user;
	password = NULL;

	ret = sql_result_next_row(result);
	if (ret < 0) {
		i_error("sql(%s): Password query failed: %s",
			get_log_prefix(auth_request),
			sql_result_get_error(result));
	} else if (ret == 0) {
		if (verbose) {
			i_info("sql(%s): Unknown user",
			       get_log_prefix(auth_request));
		}
	} else {
		password = sql_result_find_field_value(result, "password");
		if (password != NULL)
			password = t_strdup(password);
		else {
			i_error("sql(%s): Password query didn't return "
				"password, or it was NULL",
				get_log_prefix(auth_request));
		}

		/* make sure there was only one row returned */
		if (sql_result_next_row(result) > 0) {
			i_error("sql(%s): Password query returned multiple "
				"matches", get_log_prefix(auth_request));
			password = NULL;
		}
	}

	scheme = password_get_scheme(&password);
	if (scheme == NULL) {
		scheme = passdb_sql_conn->set.default_pass_scheme;
		i_assert(scheme != NULL);
	}

	if (sql_request->credentials != -1) {
		passdb_handle_credentials(sql_request->credentials,
			user, password, scheme,
			sql_request->callback.lookup_credentials,
			auth_request);
		return;
	}

	/* verify plain */
	if (password == NULL) {
		sql_request->callback.verify_plain(PASSDB_RESULT_USER_UNKNOWN,
						   auth_request);
		return;
	}

	ret = password_verify(sql_request->password, password, scheme, user);
	if (ret < 0) {
		i_error("sql(%s): Unknown password scheme %s",
			get_log_prefix(auth_request), scheme);
	} else if (ret == 0) {
		if (verbose) {
			i_info("sql(%s): Password mismatch",
			       get_log_prefix(auth_request));
		}
	}

	sql_request->callback.verify_plain(ret > 0 ? PASSDB_RESULT_OK :
					     PASSDB_RESULT_PASSWORD_MISMATCH,
					     auth_request);
}

static void sql_lookup_pass(struct passdb_sql_request *sql_request)
{
	string_t *query;

	query = t_str_new(512);
	var_expand(query, passdb_sql_conn->set.password_query,
		   auth_request_get_var_expand_table(sql_request->auth_request,
						     str_escape));

	sql_query(passdb_sql_conn->db, str_c(query),
		  sql_query_callback, sql_request);
}

static void sql_verify_plain(struct auth_request *request, const char *password,
			     verify_plain_callback_t *callback)
{
	struct passdb_sql_request *sql_request;

	sql_request = i_malloc(sizeof(struct passdb_sql_request) +
			       strlen(password));
	sql_request->auth_request = request;
	sql_request->credentials = -1;
	sql_request->callback.verify_plain = callback;
	strcpy(sql_request->password, password);

	sql_lookup_pass(sql_request);
}

static void sql_lookup_credentials(struct auth_request *request,
				   enum passdb_credentials credentials,
				   lookup_credentials_callback_t *callback)
{
	struct passdb_sql_request *sql_request;

	sql_request = i_new(struct passdb_sql_request, 1);
	sql_request->auth_request = request;
	sql_request->credentials = credentials;
	sql_request->callback.lookup_credentials = callback;

        sql_lookup_pass(sql_request);
}

static void passdb_sql_preinit(const char *args)
{
	passdb_sql_conn = db_sql_init(args);
}

static void passdb_sql_init(const char *args __attr_unused__)
{
	db_sql_connect(passdb_sql_conn);
}

static void passdb_sql_deinit(void)
{
	db_sql_unref(passdb_sql_conn);
}

struct passdb_module passdb_sql = {
	passdb_sql_preinit,
	passdb_sql_init,
	passdb_sql_deinit,

	sql_verify_plain,
	sql_lookup_credentials
};

#endif

Index: passdb.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb.c,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -d -r1.23 -r1.24
--- passdb.c	20 Sep 2004 21:47:30 -0000	1.23
+++ passdb.c	15 Oct 2004 23:12:52 -0000	1.24
@@ -150,13 +150,9 @@
 	if (strcasecmp(name, "ldap") == 0)
 		passdb = &passdb_ldap;
 #endif
-#ifdef PASSDB_PGSQL
-	if (strcasecmp(name, "pgsql") == 0)
-		passdb = &passdb_pgsql;
-#endif
-#ifdef PASSDB_MYSQL
-	if (strcasecmp(name, "mysql") == 0)
-		passdb = &passdb_mysql;
+#ifdef PASSDB_SQL
+	if (strcasecmp(name, "sql") == 0)
+		passdb = &passdb_sql;
 #endif
 #ifdef HAVE_MODULES
 	passdb_module = passdb != NULL ? NULL : auth_module_open(name);

Index: passdb.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- passdb.h	20 Sep 2004 21:47:30 -0000	1.14
+++ passdb.h	15 Oct 2004 23:12:52 -0000	1.15
@@ -64,8 +64,7 @@
 extern struct passdb_module passdb_checkpassword;
 extern struct passdb_module passdb_vpopmail;
 extern struct passdb_module passdb_ldap;
-extern struct passdb_module passdb_pgsql;
-extern struct passdb_module passdb_mysql;
+extern struct passdb_module passdb_sql;
 
 void passdb_preinit(void);
 void passdb_init(void);

--- userdb-mysql.c DELETED ---

--- userdb-pgsql.c DELETED ---

--- NEW FILE: userdb-sql.c ---
/* Copyright (C) 2004 Timo Sirainen, Alex Howansky */

#include "config.h"
#undef HAVE_CONFIG_H

#ifdef USERDB_SQL

#include "common.h"
#include "str.h"
#include "strescape.h"
#include "var-expand.h"
#include "db-sql.h"
#include "userdb.h"

#include <stdlib.h>
#include <string.h>

struct userdb_sql_request {
	struct auth_request *auth_request;
	userdb_callback_t *callback;
	void *context;
};

static struct sql_connection *userdb_sql_conn;

static void sql_query_callback(struct sql_result *result, void *context)
{
	struct userdb_sql_request *sql_request = context;
	struct auth_request *auth_request = sql_request->auth_request;
	struct user_data user;
	const char *uid, *gid;
	int ret;

	uid = gid = NULL;
	ret = sql_result_next_row(result);
	if (ret < 0) {
		i_error("sql(%s): User query failed: %s",
			get_log_prefix(auth_request),
			sql_result_get_error(result));
	} else if (ret == 0) {
		if (verbose) {
			i_error("sql(%s): User not found",
				get_log_prefix(auth_request));
		}
	} else {
		uid = sql_result_find_field_value(result, "uid");
		if (uid == NULL) {
			i_error("sql(%s): Password query didn't return uid, "
				"or it was NULL", get_log_prefix(auth_request));
		}
		gid = sql_result_find_field_value(result, "gid");
		if (gid == NULL) {
			i_error("sql(%s): Password query didn't return gid, "
				"or it was NULL", get_log_prefix(auth_request));
		}
	}

	if (uid == NULL || gid == NULL)
		sql_request->callback(NULL, sql_request->context);
	else {
		memset(&user, 0, sizeof(user));
		user.virtual_user = auth_request->user;
		user.system_user =
			sql_result_find_field_value(result, "system_user");
		user.home = sql_result_find_field_value(result, "home");
		user.mail = sql_result_find_field_value(result, "mail");
		user.uid = (uid_t)strtoul(uid, NULL, 10);
		user.gid = (gid_t)strtoul(gid, NULL, 10);
		sql_request->callback(&user, sql_request->context);
	}
}

static void userdb_sql_lookup(struct auth_request *auth_request,
			      userdb_callback_t *callback, void *context)
{
	struct userdb_sql_request *sql_request;
	string_t *query;

	query = t_str_new(512);
	var_expand(query, userdb_sql_conn->set.user_query,
		   auth_request_get_var_expand_table(auth_request,
						     str_escape));

	sql_request = i_new(struct userdb_sql_request, 1);
	sql_request->callback = callback;
	sql_request->context = context;
	sql_request->auth_request = auth_request;

	sql_query(userdb_sql_conn->db, str_c(query),
		  sql_query_callback, sql_request);
}

static void userdb_sql_preinit(const char *args)
{
	userdb_sql_conn = db_sql_init(args);
}

static void userdb_sql_init(const char *args __attr_unused__)
{
	db_sql_connect(userdb_sql_conn);
}

static void userdb_sql_deinit(void)
{
	db_sql_unref(userdb_sql_conn);
}

struct userdb_module userdb_sql = {
	userdb_sql_preinit,
	userdb_sql_init,
	userdb_sql_deinit,

	userdb_sql_lookup
};

#endif

Index: userdb.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/userdb.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- userdb.c	20 Sep 2004 21:47:31 -0000	1.11
+++ userdb.c	15 Oct 2004 23:12:52 -0000	1.12
@@ -52,13 +52,9 @@
 	if (strcasecmp(name, "ldap") == 0)
 		userdb = &userdb_ldap;
 #endif
-#ifdef USERDB_PGSQL
-	if (strcasecmp(name, "pgsql") == 0)
-		userdb = &userdb_pgsql;
-#endif
-#ifdef USERDB_MYSQL
-	if (strcasecmp(name, "mysql") == 0)
-		userdb = &userdb_mysql;
+#ifdef USERDB_SQL
+	if (strcasecmp(name, "sql") == 0)
+		userdb = &userdb_sql;
 #endif
 #ifdef HAVE_MODULES
 	userdb_module = userdb != NULL ? NULL : auth_module_open(name);

Index: userdb.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/userdb.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- userdb.h	13 Oct 2004 16:38:32 -0000	1.11
+++ userdb.h	15 Oct 2004 23:12:52 -0000	1.12
@@ -31,8 +31,7 @@
 extern struct userdb_module userdb_passwd_file;
 extern struct userdb_module userdb_vpopmail;
 extern struct userdb_module userdb_ldap;
-extern struct userdb_module userdb_pgsql;
-extern struct userdb_module userdb_mysql;
+extern struct userdb_module userdb_sql;
 
 void userdb_preinit(void);
 void userdb_init(void);



More information about the dovecot-cvs mailing list