[dovecot-cvs] dovecot/src/auth auth-client-connection.c, 1.34, 1.35 auth-master-connection.c, 1.27, 1.28 auth-request-handler-default.c, 1.3, 1.4 auth-request.c, 1.7, 1.8 auth-request.h, 1.7, 1.8 db-ldap.c, 1.25, 1.26 db-ldap.h, 1.12, 1.13 passdb-cache.c, 1.4, 1.5 passdb-ldap.c, 1.22, 1.23 passdb-sql.c, 1.12, 1.13 userdb-ldap.c, 1.26, 1.27 userdb-passdb.c, 1.2, 1.3 userdb-passwd-file.c, 1.11, 1.12 userdb-passwd.c, 1.12, 1.13 userdb-sql.c, 1.6, 1.7 userdb-static.c, 1.10, 1.11 userdb-vpopmail.c, 1.13, 1.14 userdb.h, 1.19, 1.20

cras at dovecot.org cras at dovecot.org
Sat Feb 12 15:47:23 EET 2005


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

Modified Files:
	auth-client-connection.c auth-master-connection.c 
	auth-request-handler-default.c auth-request.c auth-request.h 
	db-ldap.c db-ldap.h passdb-cache.c passdb-ldap.c passdb-sql.c 
	userdb-ldap.c userdb-passdb.c userdb-passwd-file.c 
	userdb-passwd.c userdb-sql.c userdb-static.c userdb-vpopmail.c 
	userdb.h 
Log Message:
userdb can now return extra parameters to master. Removed special handling
of home/mail wherever possible, they're just regular extra parameters now.
LDAP passdb and static userdb can return extra parameters now.



Index: auth-client-connection.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-client-connection.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -d -r1.34 -r1.35
--- auth-client-connection.c	9 Jan 2005 16:54:48 -0000	1.34
+++ auth-client-connection.c	12 Feb 2005 13:47:20 -0000	1.35
@@ -34,6 +34,10 @@
 	va_start(args, fmt);
 	str = t_str_new(256);
 	str_vprintfa(str, fmt, args);
+
+	if (conn->auth->verbose_debug)
+		i_info("client out: %s", str_c(str));
+
 	str_append_c(str, '\n');
 	(void)o_stream_send(conn->output, str_data(str), str_len(str));
 
@@ -133,6 +137,9 @@
 static int
 auth_client_handle_line(struct auth_client_connection *conn, const char *line)
 {
+	if (conn->auth->verbose_debug)
+		i_info("client in: %s", line);
+
 	if (strncmp(line, "AUTH\t", 5) == 0) {
 		return auth_request_handler_auth_begin(conn->request_handler,
 						       line + 5);

Index: auth-master-connection.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-master-connection.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- auth-master-connection.c	9 Jan 2005 19:10:13 -0000	1.27
+++ auth-master-connection.c	12 Feb 2005 13:47:20 -0000	1.28
@@ -45,6 +45,9 @@
 	struct auth_master_connection *conn = context;
 	struct const_iovec iov[2];
 
+	if (conn->auth->verbose_debug)
+		i_info("master out: %s", reply);
+
 	iov[0].iov_base = reply;
 	iov[0].iov_len = strlen(reply);
 	iov[1].iov_base = "\n";
@@ -129,6 +132,9 @@
 	}
 
 	while ((line = i_stream_next_line(conn->input)) != NULL) {
+		if (conn->auth->verbose_debug)
+			i_info("master in: %s", line);
+
 		t_push();
 		if (strncmp(line, "REQUEST\t", 8) == 0)
 			ret = master_input_request(conn, line + 8);

Index: auth-request-handler-default.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-request-handler-default.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- auth-request-handler-default.c	9 Jan 2005 20:29:08 -0000	1.3
+++ auth-request-handler-default.c	12 Feb 2005 13:47:20 -0000	1.4
@@ -376,51 +376,20 @@
 	return TRUE;
 }
 
-static void append_user_reply(string_t *str, const struct user_data *user)
-{
-	const char *p;
-
-	str_printfa(str, "%s\tuid=%s\tgid=%s", user->virtual_user,
-		    dec2str(user->uid), dec2str(user->gid));
-
-	if (user->system_user != NULL)
-		str_printfa(str, "\tsystem_user=%s", user->system_user);
-	if (user->mail != NULL)
-		str_printfa(str, "\tmail=%s", user->mail);
-
-	p = user->home != NULL ? strstr(user->home, "/./") : NULL;
-	if (p == NULL) {
-		if (user->home != NULL)
-			str_printfa(str, "\thome=%s", user->home);
-	} else {
-		/* wu-ftpd like <chroot>/./<home> */
-		str_printfa(str, "\thome=%s\tchroot=%s",
-			    p + 3, t_strdup_until(user->home, p));
-	}
-}
-
-static void userdb_callback(const struct user_data *user, void *context)
+static void userdb_callback(const char *result, void *context)
 {
         struct auth_request *request = context;
         struct auth_request_handler *handler = request->context;
 	string_t *reply;
 
-	if (user != NULL) {
-		auth_request_log_debug(request, "userdb",
-				       "uid=%s gid=%s home=%s mail=%s",
-				       dec2str(user->uid), dec2str(user->gid),
-				       user->home != NULL ? user->home : "",
-				       user->mail != NULL ? user->mail : "");
-	}
-
 	reply = t_str_new(256);
 	if (handler->prepend_connect_uid)
 		str_printfa(reply, "%u\t", request->connect_uid);
-	if (user == NULL)
+	if (result == NULL)
 		str_printfa(reply, "NOTFOUND\t%u", request->id);
 	else {
 		str_printfa(reply, "USER\t%u\t", request->id);
-		append_user_reply(reply, user);
+		str_append(reply, result);
 	}
 	handler->master_callback(str_c(reply), handler->master_context);
 

Index: auth-request.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-request.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- auth-request.c	9 Jan 2005 00:49:18 -0000	1.7
+++ auth-request.c	12 Feb 2005 13:47:20 -0000	1.8
@@ -143,14 +143,12 @@
 }
 
 struct auth_request_extra *
-auth_request_extra_begin(struct auth_request *request,
-			 const char *user_password)
+auth_request_extra_begin(struct auth_request *request)
 {
 	struct auth_request_extra *extra;
 
 	extra = i_new(struct auth_request_extra, 1);
 	extra->request = request;
-	extra->user_password = i_strdup(user_password);
 	return extra;
 }
 
@@ -199,7 +197,7 @@
 }
 
 void auth_request_extra_finish(struct auth_request_extra *extra,
-			       const char *cache_key)
+			       const char *user_password, const char *cache_key)
 {
 	string_t *str;
 
@@ -219,16 +217,12 @@
 					      str_c(str), NULL));
 	}
 
-	if (extra->user_password != NULL) {
+	if (user_password != NULL) {
 		if (extra->request->proxy) {
 			/* we're proxying - send back the password that was
 			   sent by user (not the password in passdb). */
-			str_printfa(extra->str, "\tpass=%s",
-				    extra->user_password);
+			str_printfa(extra->str, "\tpass=%s", user_password);
 		}
-		safe_memset(extra->user_password, 0,
-			    strlen(extra->user_password));
-		i_free(extra->user_password);
 	}
 
 	if (extra->str != NULL)
@@ -353,7 +347,7 @@
 
 	va_start(va, format);
 	t_push();
-	i_info("%s", get_log_str(auth_request, subsystem, format, va));
+	i_error("%s", get_log_str(auth_request, subsystem, format, va));
 	t_pop();
 	va_end(va);
 }

Index: auth-request.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/auth-request.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- auth-request.h	9 Jan 2005 00:49:18 -0000	1.7
+++ auth-request.h	12 Feb 2005 13:47:20 -0000	1.8
@@ -69,10 +69,11 @@
 			      const char *username, const char **error_r);
 
 struct auth_request_extra *
-auth_request_extra_begin(struct auth_request *request, const char *password);
+auth_request_extra_begin(struct auth_request *request);
 void auth_request_extra_next(struct auth_request_extra *extra,
 			     const char *name, const char *value);
 void auth_request_extra_finish(struct auth_request_extra *extra,
+			       const char *user_password,
 			       const char *cache_key);
 
 const struct var_expand_table *

Index: db-ldap.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/db-ldap.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- db-ldap.c	13 Jan 2005 18:37:00 -0000	1.25
+++ db-ldap.c	12 Feb 2005 13:47:20 -0000	1.26
@@ -272,28 +272,41 @@
 	}
 }
 
-void db_ldap_set_attrs(struct ldap_connection *conn, const char *value,
-		       unsigned int **attrs, char ***attr_names)
+void db_ldap_set_attrs(struct ldap_connection *conn, const char *attrlist,
+		       const char *const default_attr_map[])
 {
 	const char *const *attr;
-	unsigned int i, dest, size;
+	char *name, *value, *p;
+	unsigned int i, size;
 
-	attr = t_strsplit(value, ",");
-	if (*attr == NULL || **attr == '\0')
-		i_fatal("Missing uid field in attrs");
+	if (*attrlist == '\0')
+		return;
+
+	t_push();
+	attr = t_strsplit(attrlist, ",");
 
 	for (size = 0; attr[size] != NULL; size++) ;
+	conn->attr_names = p_new(conn->pool, char *, size);
 
-	/* +1 for terminating NULL */
-	*attrs = p_new(conn->pool, unsigned int, size);
-	*attr_names = p_new(conn->pool, char *, size + 1);
-	for (i = 0, dest = 0; *attr != NULL; i++, attr++) {
-		if (**attr != '\0') {
-			(*attrs)[dest] = i;
-			(*attr_names)[dest] = p_strdup(conn->pool, *attr);
-			dest++;
+	for (i = 0; i < size; i++) {
+		p = strchr(attr[i], '=');
+		if (p == NULL) {
+			name = p_strdup(conn->pool, attr[i]);
+			value = *default_attr_map == NULL ? name :
+				p_strdup(conn->pool, *default_attr_map);
+		} else {
+			name = p_strdup_until(conn->pool, attr[i], p);
+			value = p_strdup(conn->pool, p + 1);
 		}
+
+		conn->attr_names[i] = name;
+		if (*name != '\0')
+			hash_insert(conn->attr_map, name, value);
+
+		if (*default_attr_map != NULL)
+			default_attr_map++;
 	}
+	t_pop();
 }
 
 #define IS_LDAP_ESCAPED_CHAR(c) \
@@ -362,6 +375,8 @@
 
 	conn->refcount = 1;
 	conn->requests = hash_create(default_pool, pool, 0, NULL, NULL);
+	conn->attr_map = hash_create(default_pool, pool, 0, str_hash,
+				     (hash_cmp_callback_t *)strcmp);
 
 	conn->config_path = p_strdup(pool, config_path);
 	conn->set = default_ldap_settings;
@@ -387,6 +402,7 @@
 	ldap_conn_close(conn);
 
 	hash_destroy(conn->requests);
+	hash_destroy(conn->attr_map);
 	pool_unref(conn->pool);
 }
 

Index: db-ldap.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/db-ldap.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- db-ldap.h	20 Sep 2004 21:47:30 -0000	1.12
+++ db-ldap.h	12 Feb 2005 13:47:20 -0000	1.13
@@ -45,6 +45,9 @@
 	struct io *io;
 	struct hash_table *requests;
 
+	char **attr_names;
+	struct hash_table *attr_map;
+
 	unsigned int connected:1;
 };
 
@@ -57,8 +60,8 @@
 		    const char *filter, char **attributes,
 		    struct ldap_request *request);
 
-void db_ldap_set_attrs(struct ldap_connection *conn, const char *value,
-		       unsigned int **attrs, char ***attr_names);
+void db_ldap_set_attrs(struct ldap_connection *conn, const char *attrlist,
+		       const char *const default_attr_map[]);
 
 struct ldap_connection *db_ldap_init(const char *config_path);
 void db_ldap_unref(struct ldap_connection *conn);

Index: passdb-cache.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-cache.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- passdb-cache.c	8 Jan 2005 16:56:04 -0000	1.4
+++ passdb-cache.c	12 Feb 2005 13:47:20 -0000	1.5
@@ -18,7 +18,7 @@
 	if (*list == NULL)
 		return;
 
-	extra = auth_request_extra_begin(request, password);
+	extra = auth_request_extra_begin(request);
 	for (; *list != NULL; list++) {
 		t_push();
 		value = strchr(*list, '=');
@@ -33,7 +33,7 @@
 		auth_request_extra_next(extra, name, value);
 		t_pop();
 	}
-	auth_request_extra_finish(extra, NULL);
+	auth_request_extra_finish(extra, password, NULL);
 }
 
 int passdb_cache_verify_plain(struct auth_request *request, const char *key,

Index: passdb-ldap.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-ldap.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- passdb-ldap.c	16 Jan 2005 17:11:49 -0000	1.22
+++ passdb-ldap.c	12 Feb 2005 13:47:20 -0000	1.23
@@ -6,6 +6,7 @@
 #ifdef PASSDB_LDAP
 
 #include "common.h"
+#include "hash.h"
 #include "str.h"
 #include "var-expand.h"
 #include "password-scheme.h"
@@ -16,18 +17,8 @@
 #include <ldap.h>
 #include <stdlib.h>
 
-enum ldap_user_attr {
-	ATTR_VIRTUAL_USER = 0,
-	ATTR_PASSWORD,
-
-	ATTR_COUNT
-};
-
-struct passdb_ldap_connection {
-	struct ldap_connection *conn;
-
-        unsigned int *attrs;
-	char **attr_names;
+static const char *default_attr_map[] = {
+	"user", "password", NULL
 };
 
 struct passdb_ldap_request {
@@ -42,9 +33,45 @@
 	char password[1]; /* variable width */
 };
 
-static struct passdb_ldap_connection *passdb_ldap_conn;
+static struct ldap_connection *passdb_ldap_conn;
 static char *passdb_ldap_cache_key;
 
+static const char *
+ldap_query_save_result(struct ldap_connection *conn, LDAPMessage *entry,
+                       struct passdb_ldap_request *ldap_request,
+		       struct auth_request *auth_request)
+{
+	struct auth_request_extra *extra;
+	BerElement *ber;
+	const char *name, *password;
+	char *attr, **vals;
+	unsigned int i;
+
+	extra = auth_request_extra_begin(auth_request);
+
+	password = NULL;
+	attr = ldap_first_attribute(conn->ld, entry, &ber);
+	while (attr != NULL) {
+		name = hash_lookup(passdb_ldap_conn->attr_map, attr);
+		vals = ldap_get_values(conn->ld, entry, attr);
+
+		if (name != NULL && vals != NULL && vals[0] != NULL) {
+			if (strcmp(name, "password") == 0 && vals[1] == NULL)
+				password = t_strdup(vals[0]);
+			for (i = 0; vals[i] != NULL; i++)
+				auth_request_extra_next(extra, name, vals[i]);
+		}
+
+		ldap_value_free(vals);
+		ldap_memfree(attr);
+
+		attr = ldap_next_attribute(conn->ld, entry, ber);
+	}
+
+	auth_request_extra_finish(extra, ldap_request->password, NULL);
+	return password;
+}
+
 static void handle_request(struct ldap_connection *conn,
 			   struct ldap_request *request, LDAPMessage *res)
 {
@@ -53,13 +80,10 @@
         struct auth_request *auth_request = request->context;
 	enum passdb_result result;
 	LDAPMessage *entry;
-	BerElement *ber;
-	char *attr, **vals;
-	const char *user, *password, *scheme;
+	const char *password, *scheme;
 	int ret;
 
 	result = PASSDB_RESULT_USER_UNKNOWN;
-	user = auth_request->user;
 	password = NULL;
 
 	if (res != NULL) {
@@ -81,20 +105,8 @@
 					      "unknown user");
 		}
 	} else {
-		attr = ldap_first_attribute(conn->ld, entry, &ber);
-		while (attr != NULL) {
-			vals = ldap_get_values(conn->ld, entry, attr);
-			if (vals != NULL && vals[0] != NULL &&
-			    vals[1] == NULL) {
-				if (strcasecmp(attr, passdb_ldap_conn->
-					       attr_names[ATTR_PASSWORD]) == 0)
-					password = t_strdup(vals[0]);
-			}
-			ldap_value_free(vals);
-			ldap_memfree(attr);
-
-			attr = ldap_next_attribute(conn->ld, entry, ber);
-		}
+		password = ldap_query_save_result(conn, entry, ldap_request,
+						  auth_request);
 
 		if (password == NULL) {
 			auth_request_log_error(auth_request, "ldap",
@@ -131,7 +143,8 @@
 		return;
 	}
 
-	ret = password_verify(ldap_request->password, password, scheme, user);
+	ret = password_verify(ldap_request->password, password, scheme,
+			      auth_request->user);
 	if (ret < 0) {
 		auth_request_log_error(auth_request, "ldap",
 			"Unknown password scheme %s", scheme);
@@ -148,9 +161,9 @@
 static void ldap_lookup_pass(struct auth_request *auth_request,
 			     struct ldap_request *ldap_request)
 {
-	struct ldap_connection *conn = passdb_ldap_conn->conn;
+	struct ldap_connection *conn = passdb_ldap_conn;
         const struct var_expand_table *vars;
-	const char **attr_names = (const char **)passdb_ldap_conn->attr_names;
+	const char **attr_names = (const char **)conn->attr_names;
 	const char *filter, *base;
 	string_t *str;
 
@@ -182,12 +195,12 @@
 ldap_verify_plain(struct auth_request *request, const char *password,
 		  verify_plain_callback_t *callback)
 {
-	struct ldap_connection *conn = passdb_ldap_conn->conn;
 	struct passdb_ldap_request *ldap_request;
 	enum passdb_result result;
 
 	if (passdb_cache_verify_plain(request, passdb_ldap_cache_key, password,
-				      conn->set.default_pass_scheme, &result)) {
+				      passdb_ldap_conn->set.default_pass_scheme,
+				      &result)) {
 		callback(result, request);
 		return;
 	}
@@ -210,10 +223,8 @@
 
 	if (passdb_cache_lookup_credentials(request, passdb_ldap_cache_key,
 					    &result, &scheme)) {
-		if (scheme == NULL) {
-			scheme = passdb_ldap_conn->conn->set.
-				default_pass_scheme;
-		}
+		if (scheme == NULL)
+			scheme = passdb_ldap_conn->set.default_pass_scheme;
 		passdb_handle_credentials(result != NULL ? PASSDB_RESULT_OK :
 					  PASSDB_RESULT_USER_UNKNOWN,
 					  credentials, result, scheme,
@@ -230,24 +241,22 @@
 
 static void passdb_ldap_preinit(const char *args)
 {
-	struct ldap_connection *conn;
-
-	passdb_ldap_conn = i_new(struct passdb_ldap_connection, 1);
-	passdb_ldap_conn->conn = conn = db_ldap_init(args);
+	passdb_ldap_conn = db_ldap_init(args);
 
-	db_ldap_set_attrs(conn, conn->set.pass_attrs, &passdb_ldap_conn->attrs,
-			  &passdb_ldap_conn->attr_names);
-	passdb_ldap_cache_key = auth_cache_parse_key(conn->set.pass_filter);
+	db_ldap_set_attrs(passdb_ldap_conn, passdb_ldap_conn->set.pass_attrs,
+			  default_attr_map);
+	passdb_ldap_cache_key =
+		auth_cache_parse_key(passdb_ldap_conn->set.pass_filter);
 }
 
 static void passdb_ldap_init(const char *args __attr_unused__)
 {
-	(void)db_ldap_connect(passdb_ldap_conn->conn);
+	(void)db_ldap_connect(passdb_ldap_conn);
 }
 
 static void passdb_ldap_deinit(void)
 {
-	db_ldap_unref(passdb_ldap_conn->conn);
+	db_ldap_unref(passdb_ldap_conn);
 	i_free(passdb_ldap_cache_key);
 	i_free(passdb_ldap_conn);
 }

Index: passdb-sql.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/passdb-sql.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- passdb-sql.c	8 Feb 2005 10:52:40 -0000	1.12
+++ passdb-sql.c	12 Feb 2005 13:47:20 -0000	1.13
@@ -32,17 +32,21 @@
 static char *passdb_sql_cache_key;
 
 static void result_save_extra_fields(struct sql_result *result,
-				     struct passdb_sql_request *sql_request,
-				     struct auth_request *auth_request)
+				     unsigned int skip_idx,
+				     struct passdb_sql_request *sql_request)
 {
+	struct auth_request *auth_request = sql_request->auth_request;
 	struct auth_request_extra *extra;
 	unsigned int i, fields_count;
 	const char *name, *value;
 
-	extra = auth_request_extra_begin(auth_request, sql_request->password);
+	extra = auth_request_extra_begin(auth_request);
 
 	fields_count = sql_result_get_fields_count(result);
 	for (i = 0; i < fields_count; i++) {
+		if (i == skip_idx)
+			continue;
+
 		name = sql_result_get_field_name(result, i);
 		value = sql_result_get_field_value(result, i);
 
@@ -50,7 +54,8 @@
 			auth_request_extra_next(extra, name, value);
 	}
 
-	auth_request_extra_finish(extra, passdb_sql_cache_key);
+	auth_request_extra_finish(extra, sql_request->password,
+				  passdb_sql_cache_key);
 }
 
 static void sql_query_callback(struct sql_result *result, void *context)
@@ -82,7 +87,7 @@
 			"Password query must return a field named 'password'");
 	} else {
 		password = t_strdup(sql_result_get_field_value(result, idx));
-		result_save_extra_fields(result, sql_request, auth_request);
+		result_save_extra_fields(result, idx, sql_request);
 		passdb_result = PASSDB_RESULT_OK;
 	}
 

Index: userdb-ldap.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/userdb-ldap.c,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -d -r1.26 -r1.27
--- userdb-ldap.c	16 Jan 2005 17:11:49 -0000	1.26
+++ userdb-ldap.c	12 Feb 2005 13:47:20 -0000	1.27
@@ -6,6 +6,7 @@
 #ifdef USERDB_LDAP
 
 #include "common.h"
+#include "hash.h"
 #include "str.h"
 #include "var-expand.h"
 #include "db-ldap.h"
@@ -14,22 +15,8 @@
 #include <ldap.h>
 #include <stdlib.h>
 
-enum ldap_user_attr {
-	ATTR_VIRTUAL_USER = 0,
-	ATTR_HOME,
-	ATTR_MAIL,
-	ATTR_SYSTEM_USER,
-	ATTR_UID_NUMBER,
-	ATTR_GID_NUMBER,
-
-	ATTR_COUNT
-};
-
-struct userdb_ldap_connection {
-	struct ldap_connection *conn;
-
-        unsigned int *attrs;
-	char **attr_names;
+static const char *default_attr_map[] = {
+	"", "home", "mail", "system_user", "uid", "gid", NULL
 };
 
 struct userdb_ldap_request {
@@ -38,49 +25,103 @@
         userdb_callback_t *userdb_callback;
 };
 
-static struct userdb_ldap_connection *userdb_ldap_conn;
+static struct ldap_connection *userdb_ldap_conn;
 
-static void parse_attr(struct auth_request *auth_request,
-		       struct userdb_ldap_connection *conn,
-		       struct user_data *user,
-		       const char *attr, const char *value)
+static int append_uid_list(struct auth_request *auth_request, string_t *str,
+			   const char *name, char **vals)
 {
-	enum ldap_user_attr i;
+	uid_t uid;
 
-	for (i = 0; i < ATTR_COUNT; i++) {
-		if (strcasecmp(conn->attr_names[i], attr) == 0)
-			break;
+	for (; *vals != NULL; vals++) {
+		str_append_c(str, '\t');
+		str_append(str, name);
+		str_append_c(str, '=');
+
+		uid = userdb_parse_uid(auth_request, *vals);
+		if (uid == (uid_t)-1)
+			return FALSE;
+		str_append(str, dec2str(uid));
 	}
 
-	if (i == ATTR_COUNT) {
-		auth_request_log_error(auth_request, "ldap",
-				       "Unknown attribute '%s'", attr);
-		return;
+	return TRUE;
+}
+
+static int append_gid_list(struct auth_request *auth_request, string_t *str,
+			   const char *name, char **vals)
+{
+	gid_t gid;
+
+	for (; *vals != NULL; vals++) {
+		str_append_c(str, '\t');
+		str_append(str, name);
+		str_append_c(str, '=');
+
+		gid = userdb_parse_gid(auth_request, *vals);
+		if (gid == (gid_t)-1)
+			return FALSE;
+		str_append(str, dec2str(gid));
 	}
 
-	switch (conn->attrs[i]) {
-	case ATTR_VIRTUAL_USER:
-		user->virtual_user = t_strdup(value);
-		break;
-	case ATTR_HOME:
-		user->home = t_strdup(value);
-		break;
-	case ATTR_MAIL:
-		user->mail = t_strdup(value);
-		break;
-	case ATTR_SYSTEM_USER:
-		user->system_user = t_strdup(value);
-		break;
-	case ATTR_UID_NUMBER:
-		user->uid = userdb_parse_uid(auth_request, value);
-		break;
-	case ATTR_GID_NUMBER:
-		user->gid = userdb_parse_gid(auth_request, value);
-		break;
+	return TRUE;
+}
 
-	case ATTR_COUNT:
-		break;
+static const char *
+ldap_query_get_result(struct ldap_connection *conn, LDAPMessage *entry,
+		      struct auth_request *auth_request)
+{
+	string_t *str;
+	BerElement *ber;
+	const char *name;
+	char *attr, **vals;
+	unsigned int i;
+	int seen_uid = FALSE, seen_gid = FALSE;
+
+	str = t_str_new(256);
+	str_append(str, auth_request->user);
+
+	attr = ldap_first_attribute(conn->ld, entry, &ber);
+	while (attr != NULL) {
+		name = hash_lookup(userdb_ldap_conn->attr_map, attr);
+		vals = ldap_get_values(conn->ld, entry, attr);
+
+		if (name != NULL && vals != NULL && vals[0] != NULL) {
+			if (strcmp(name, "uid") == 0) {
+				if (!append_uid_list(auth_request, str,
+						     name, vals))
+					return NULL;
+				seen_uid = TRUE;
+			} else if (strcmp(name, "gid") == 0) {
+				if (!append_gid_list(auth_request, str,
+						     name, vals))
+					return NULL;
+				seen_gid = TRUE;
+			} else {
+				for (i = 0; vals[i] != NULL; i++) {
+					str_append_c(str, '\t');
+					str_append(str, name);
+					str_append_c(str, '=');
+					str_append(str, vals[i]);
+				}
+			}
+		}
+		ldap_value_free(vals);
+		ldap_memfree(attr);
+
+		attr = ldap_next_attribute(conn->ld, entry, ber);
 	}
+
+	if (!seen_uid) {
+		auth_request_log_error(auth_request, "ldap",
+			"uid not in user_attrs and no default given in "
+			"user_global_uid");
+	}
+	if (!seen_gid) {
+		auth_request_log_error(auth_request, "ldap",
+			"gid not in user_attrs and no default given in "
+			"user_global_gid");
+	}
+
+	return str_c(str);
 }
 
 static void handle_request(struct ldap_connection *conn,
@@ -89,10 +130,8 @@
 	struct userdb_ldap_request *urequest =
 		(struct userdb_ldap_request *) request;
 	struct auth_request *auth_request = urequest->auth_request;
-	struct user_data user;
 	LDAPMessage *entry;
-	BerElement *ber;
-	char *attr, **vals;
+	const char *result;
 	int ret;
 
 	ret = ldap_result2error(conn->ld, res, 0);
@@ -109,58 +148,23 @@
 			auth_request_log_error(auth_request, "ldap",
 					       "Authenticated user not found");
 		}
-		urequest->userdb_callback(NULL, request->context);
-		return;
-	}
-
-	t_push();
-	memset(&user, 0, sizeof(user));
-
-	user.uid = conn->set.user_global_uid;
-	user.gid = conn->set.user_global_gid;
-
-	attr = ldap_first_attribute(conn->ld, entry, &ber);
-	while (attr != NULL) {
-		vals = ldap_get_values(conn->ld, entry, attr);
-		if (vals != NULL && vals[0] != NULL && vals[1] == NULL) {
-			parse_attr(auth_request, userdb_ldap_conn,
-				   &user, attr, vals[0]);
-		}
-		ldap_value_free(vals);
-		ldap_memfree(attr);
-
-		attr = ldap_next_attribute(conn->ld, entry, ber);
-	}
-
-	if (user.virtual_user == NULL)
-		auth_request_log_error(auth_request, "ldap",
-				       "No username in reply");
-	else if (user.uid == (uid_t)-1) {
-		auth_request_log_error(auth_request, "ldap",
-			"uidNumber not set and no default given in "
-			"user_global_uid");
-	} else if (user.gid == (gid_t)-1) {
-		auth_request_log_error(auth_request, "ldap",
-			"gidNumber not set and no default given in "
-			"user_global_gid");
-	} else if (ldap_next_entry(conn->ld, entry) != NULL) {
-		auth_request_log_error(auth_request, "ldap",
-				       "Multiple replies found for user");
+		result = NULL;
 	} else {
-		urequest->userdb_callback(&user, request->context);
-		t_pop();
-		return;
+		result = ldap_query_get_result(conn, entry, auth_request);
+		if (ldap_next_entry(conn->ld, entry) != NULL) {
+			auth_request_log_error(auth_request, "ldap",
+				"Multiple replies found for user");
+			result = NULL;
+		}
 	}
 
-	/* error */
-	urequest->userdb_callback(NULL, request->context);
-	t_pop();
+	urequest->userdb_callback(result, request->context);
 }
 
 static void userdb_ldap_lookup(struct auth_request *auth_request,
 			       userdb_callback_t *callback, void *context)
 {
-	struct ldap_connection *conn = userdb_ldap_conn->conn;
+	struct ldap_connection *conn = userdb_ldap_conn;
         const struct var_expand_table *vars;
 	const char **attr_names = (const char **)userdb_ldap_conn->attr_names;
 	struct userdb_ldap_request *request;
@@ -195,23 +199,19 @@
 
 static void userdb_ldap_preinit(const char *args)
 {
-	struct ldap_connection *conn;
-
-	userdb_ldap_conn = i_new(struct userdb_ldap_connection, 1);
-	userdb_ldap_conn->conn = conn = db_ldap_init(args);
-
-	db_ldap_set_attrs(conn, conn->set.user_attrs, &userdb_ldap_conn->attrs,
-			  &userdb_ldap_conn->attr_names);
+	userdb_ldap_conn = db_ldap_init(args);
+	db_ldap_set_attrs(userdb_ldap_conn, userdb_ldap_conn->set.user_attrs,
+			  default_attr_map);
 }
 
 static void userdb_ldap_init(const char *args __attr_unused__)
 {
-	(void)db_ldap_connect(userdb_ldap_conn->conn);
+	(void)db_ldap_connect(userdb_ldap_conn);
 }
 
 static void userdb_ldap_deinit(void)
 {
-	db_ldap_unref(userdb_ldap_conn->conn);
+	db_ldap_unref(userdb_ldap_conn);
 	i_free(userdb_ldap_conn);
 }
 

Index: userdb-passdb.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/userdb-passdb.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- userdb-passdb.c	8 Jan 2005 16:56:04 -0000	1.2
+++ userdb-passdb.c	12 Feb 2005 13:47:20 -0000	1.3
@@ -15,18 +15,27 @@
 static void passdb_lookup(struct auth_request *auth_request,
 			  userdb_callback_t *callback, void *context)
 {
-	struct user_data data;
 	const char *const *args;
+	string_t *str;
+	uid_t uid;
+	gid_t gid;
 	int uid_seen, gid_seen;
 
-	memset(&data, 0, sizeof(data));
-	data.virtual_user = auth_request->user;
+	if (auth_request->extra_fields == NULL) {
+		auth_request_log_error(auth_request, "passdb",
+				       "passdb didn't return userdb entries");
+		callback(NULL, context);
+		return;
+	}
 
+	t_push();
+
+	uid = (uid_t)-1; gid = (gid_t)-1;
 	uid_seen = gid_seen = FALSE;
-	data.uid = (uid_t)-1;
-	data.gid = (gid_t)-1;
 
-	t_push();
+	str = t_str_new(256);
+	str_append(str, auth_request->user);
+
 	args = t_strsplit(auth_request->extra_fields, "\t");
 	for (; *args != NULL; args++) {
 		const char *arg = *args;
@@ -35,16 +44,26 @@
 			continue;
 		arg += 7;
 
+		str_append_c(str, '\t');
 		if (strncmp(arg, "uid=", 4) == 0) {
 			uid_seen = TRUE;
-                        data.uid = userdb_parse_uid(auth_request, arg+4);
+			uid = userdb_parse_uid(auth_request, arg+4);
+			if (uid == (uid_t)-1)
+				break;
+
+			str_append(str, "uid=");
+			str_append(str, dec2str(uid));
 		} else if (strncmp(arg, "gid=", 4) == 0) {
 			gid_seen = TRUE;
-			data.gid = userdb_parse_gid(auth_request, arg+4);
-		} else if (strncmp(arg, "home=", 5) == 0)
-			data.home = arg + 5;
-		else if (strncmp(arg, "mail=", 5) == 0)
-			data.mail = arg + 5;
+			gid = userdb_parse_gid(auth_request, arg+4);
+			if (gid == (gid_t)-1)
+				break;
+
+			str_append(str, "gid=");
+			str_append(str, dec2str(gid));
+		} else {
+			str_append(str, arg);
+		}
 	}
 
 	if (!uid_seen) {
@@ -56,10 +75,10 @@
 				       "userdb_gid not returned");
 	}
 
-	if (data.uid == (uid_t)-1 || data.gid == (gid_t)-1)
+	if (uid == (uid_t)-1 || gid == (gid_t)-1)
 		callback(NULL, context);
 	else
-		callback(&data, context);
+		callback(str_c(str), context);
 	t_pop();
 }
 

Index: userdb-passwd-file.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/userdb-passwd-file.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- userdb-passwd-file.c	30 Jan 2005 09:04:13 -0000	1.11
+++ userdb-passwd-file.c	12 Feb 2005 13:47:20 -0000	1.12
@@ -6,6 +6,7 @@
 #ifdef USERDB_PASSWD_FILE
 
 #include "common.h"
+#include "str.h"
 #include "userdb.h"
 #include "db-passwd-file.h"
 
@@ -14,8 +15,8 @@
 static void passwd_file_lookup(struct auth_request *auth_request,
 			       userdb_callback_t *callback, void *context)
 {
-	struct user_data data;
 	struct passwd_user *pu;
+	string_t *str;
 
 	pu = db_passwd_file_lookup(userdb_pwf, auth_request);
 	if (pu == NULL) {
@@ -23,15 +24,16 @@
 		return;
 	}
 
-	memset(&data, 0, sizeof(data));
-	data.uid = pu->uid;
-	data.gid = pu->gid;
+	str = t_str_new(128);
+	str_printfa(str, "%s\tuid=%s\tgid=%s",
+		    auth_request->user, dec2str(pu->uid), dec2str(pu->gid));
 
-	data.virtual_user = auth_request->user;
-	data.home = pu->home;
-	data.mail = pu->mail;
+	if (pu->home != NULL)
+		str_printfa(str, "\thome=%s", pu->home);
+	if (pu->mail != NULL)
+		str_printfa(str, "\tmail=%s", pu->mail);
 
-	callback(&data, context);
+	callback(str_c(str), context);
 }
 
 static void passwd_file_init(const char *args)

Index: userdb-passwd.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/userdb-passwd.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- userdb-passwd.c	8 Jan 2005 16:56:04 -0000	1.12
+++ userdb-passwd.c	12 Feb 2005 13:47:20 -0000	1.13
@@ -13,8 +13,8 @@
 static void passwd_lookup(struct auth_request *auth_request,
 			  userdb_callback_t *callback, void *context)
 {
-	struct user_data data;
 	struct passwd *pw;
+	const char *result;
 
 	pw = getpwnam(auth_request->user);
 	if (pw == NULL) {
@@ -23,14 +23,11 @@
 		return;
 	}
 
-	memset(&data, 0, sizeof(data));
-	data.uid = pw->pw_uid;
-	data.gid = pw->pw_gid;
-
-	data.virtual_user = data.system_user = pw->pw_name;
-	data.home = pw->pw_dir;
-
-	callback(&data, context);
+	result = t_strdup_printf("%s\tsystem_user=%s\tuid=%s\tgid=%s\t"
+				 "home=%s", pw->pw_name, pw->pw_name,
+				 dec2str(pw->pw_uid), dec2str(pw->pw_gid),
+				 pw->pw_dir);
+	callback(result, context);
 }
 
 struct userdb_module userdb_passwd = {

Index: userdb-sql.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/userdb-sql.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- userdb-sql.c	8 Jan 2005 16:56:04 -0000	1.6
+++ userdb-sql.c	12 Feb 2005 13:47:20 -0000	1.7
@@ -23,15 +23,67 @@
 
 static struct sql_connection *userdb_sql_conn;
 
+static const char *sql_query_get_result(struct sql_result *result,
+					struct auth_request *auth_request)
+{
+	string_t *str;
+	uid_t uid, gid;
+	const char *name, *value;
+	unsigned int i, fields_count;
+
+	uid = (uid_t)-1;
+	gid = (gid_t)-1;
+
+	str = t_str_new(256);
+	str_append(str, auth_request->user);
+
+	fields_count = sql_result_get_fields_count(result);
+	for (i = 0; i < fields_count; i++) {
+		name = sql_result_get_field_name(result, i);
+		value = sql_result_get_field_value(result, i);
+
+		if (value == NULL)
+			continue;
+
+		str_append_c(str, '\t');
+		str_append(str, name);
+		str_append_c(str, '=');
+
+		/* some special handling for UID and GID. */
+		if (strcmp(name, "uid") == 0) {
+			uid = userdb_parse_uid(auth_request, value);
+			if (uid == (uid_t)-1)
+				return NULL;
+			value = dec2str(uid);
+		} else if (strcmp(name, "gid") == 0) {
+			gid = userdb_parse_gid(auth_request, value);
+			if (gid == (gid_t)-1)
+				return NULL;
+			value = dec2str(gid);
+		}
+
+		str_append(str, value);
+	}
+
+	if (uid == (uid_t)-1) {
+		auth_request_log_error(auth_request, "sql",
+			"Password query didn't return uid, or it was NULL");
+	}
+	if (gid == (gid_t)-1) {
+		auth_request_log_error(auth_request, "sql",
+			"Password query didn't return gid, or it was NULL");
+	}
+
+	return str_c(str);
+}
+
 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;
+	const char *user_result = NULL;
 	int ret;
 
-	uid = gid = NULL;
 	ret = sql_result_next_row(result);
 	if (ret < 0) {
 		auth_request_log_error(auth_request, "sql",
@@ -39,37 +91,10 @@
 	} else if (ret == 0) {
 		auth_request_log_info(auth_request, "sql", "User not found");
 	} else {
-		uid = sql_result_find_field_value(result, "uid");
-		if (uid == NULL) {
-			auth_request_log_error(auth_request, "sql",
-				"Password query didn't return uid, "
-				"or it was NULL");
-		}
-		gid = sql_result_find_field_value(result, "gid");
-		if (gid == NULL) {
-			auth_request_log_error(auth_request, "sql",
-				"Password query didn't return gid, "
-				"or it was NULL");
-		}
+                user_result = sql_query_get_result(result, 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 = userdb_parse_uid(auth_request, uid);
-		user.gid = userdb_parse_gid(auth_request, uid);
-		if (user.uid == (uid_t)-1 || user.gid == (gid_t)-1)
-			sql_request->callback(NULL, sql_request->context);
-		else
-			sql_request->callback(&user, sql_request->context);
-	}
+	sql_request->callback(user_result, sql_request->context);
 	i_free(sql_request);
 }
 

Index: userdb-static.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/userdb-static.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- userdb-static.c	6 Jan 2005 20:13:26 -0000	1.10
+++ userdb-static.c	12 Feb 2005 13:47:20 -0000	1.11
@@ -12,83 +12,68 @@
 
 #include <stdlib.h>
 
-static uid_t static_uid;
-static gid_t static_gid;
-static char *static_home_template, *static_mail_template;
+static char *static_template;
 
 static void static_lookup(struct auth_request *auth_request,
 			  userdb_callback_t *callback, void *context)
 {
-	struct user_data data;
 	string_t *str;
 
-	memset(&data, 0, sizeof(data));
-	data.uid = static_uid;
-	data.gid = static_gid;
-
-	data.virtual_user = data.system_user = auth_request->user;
-
-	if (static_home_template != NULL) {
-		str = t_str_new(256);
-		var_expand(str, static_home_template,
-			   auth_request_get_var_expand_table(auth_request,
-							     NULL));
-		data.home = str_c(str);
-	}
-	if (static_mail_template != NULL) {
-		str = t_str_new(256);
-		var_expand(str, static_mail_template,
-			   auth_request_get_var_expand_table(auth_request,
-							     NULL));
-		data.mail = str_c(str);
-	}
-
-	callback(&data, context);
+	str = t_str_new(128);
+	str_append(str, auth_request->user);
+	var_expand(str, static_template,
+		   auth_request_get_var_expand_table(auth_request, NULL));
+	callback(str_c(str), context);
 }
 
 static void static_init(const char *args)
 {
 	const char *const *tmp;
+	uid_t uid;
+	gid_t gid;
+	string_t *str;
 
-	static_uid = 0;
-	static_gid = 0;
-	static_home_template = NULL;
-	static_mail_template = NULL;
+	uid = (uid_t)-1;
+	gid = (gid_t)-1;
+
+	t_push();
+	str = t_str_new(128);
 
 	for (tmp = t_strsplit_spaces(args, " "); *tmp != NULL; tmp++) {
+		str_append_c(str, '\t');
 		if (strncasecmp(*tmp, "uid=", 4) == 0) {
-			static_uid = userdb_parse_uid(NULL, *tmp + 4);
-			if (static_uid == (uid_t)-1) {
+			uid = userdb_parse_uid(NULL, *tmp + 4);
+			if (uid == (uid_t)-1) {
 				i_fatal("static userdb: Invalid uid: %s",
 					*tmp + 4);
 			}
+			str_append(str, "uid=");
+			str_append(str, dec2str(uid));
 		} else if (strncasecmp(*tmp, "gid=", 4) == 0) {
-			static_gid = userdb_parse_gid(NULL, *tmp + 4);
-			if (static_gid == (gid_t)-1) {
+			gid = userdb_parse_gid(NULL, *tmp + 4);
+			if (gid == (gid_t)-1) {
 				i_fatal("static userdb: Invalid gid: %s",
 					*tmp + 4);
 			}
-		} else if (strncasecmp(*tmp, "home=", 5) == 0) {
-			i_free(static_home_template);
-			static_home_template = i_strdup(*tmp + 5);
-		} else if (strncasecmp(*tmp, "mail=", 5) == 0) {
-			i_free(static_mail_template);
-			static_mail_template = i_strdup(*tmp + 5);
+			str_append(str, "gid=");
+			str_append(str, dec2str(gid));
 		} else {
-			i_fatal("static userdb: Invalid option: '%s'", *tmp);
+			str_append(str, *tmp);
 		}
 	}
 
-	if (static_uid == 0)
+	if (uid == (uid_t)-1)
 		i_fatal("static userdb: uid missing");
-	if (static_gid == 0)
+	if (gid == (gid_t)-1)
 		i_fatal("static userdb: gid missing");
+
+	static_template = i_strdup(str_c(str));
+	t_pop();
 }
 
 static void static_deinit(void)
 {
-	i_free(static_home_template);
-	i_free(static_mail_template);
+	i_free(static_template);
 }
 
 struct userdb_module userdb_static = {

Index: userdb-vpopmail.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/userdb-vpopmail.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- userdb-vpopmail.c	9 Feb 2005 20:13:36 -0000	1.13
+++ userdb-vpopmail.c	12 Feb 2005 13:47:20 -0000	1.14
@@ -46,10 +46,9 @@
 {
 	char vpop_user[VPOPMAIL_LIMIT], vpop_domain[VPOPMAIL_LIMIT];
 	struct vqpasswd *vpw;
-        struct user_data data;
+	const char *result;
 	uid_t uid;
 	gid_t gid;
-	pool_t pool;
 
 	vpw = vpopmail_lookup_vqp(auth_request, vpop_user, vpop_domain);
 	if (vpw == NULL) {
@@ -87,14 +86,11 @@
 		}
 	}
 
-	memset(&data, 0, sizeof(data));
-	data.uid = uid;
-	data.gid = gid;
-
-	data.virtual_user = vpw->pw_name;
-	data.home = vpw->pw_dir;
+	result = t_strdup_printf("%s\tuid=%s\tgid=%s\thome=%s",
+				 vpw->pw_name, dec2str(uid), dec2str(gid),
+				 vpw->pw_dir);
 
-	callback(&data, context);
+	callback(result, context);
 }
 
 struct userdb_module userdb_vpopmail = {

Index: userdb.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/auth/userdb.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- userdb.h	8 Jan 2005 15:59:49 -0000	1.19
+++ userdb.h	12 Feb 2005 13:47:20 -0000	1.20
@@ -3,17 +3,7 @@
 
 struct auth_request;
 
-struct user_data {
-	const char *virtual_user;
-	const char *home;
-	const char *mail;
-
-	const char *system_user;
-	uid_t uid;
-	gid_t gid;
-};
-
-typedef void userdb_callback_t(const struct user_data *user, void *context);
+typedef void userdb_callback_t(const char *result, void *context);
 
 struct userdb_module {
 	const char *name;



More information about the dovecot-cvs mailing list