dovecot: userdb passwd supports now adding key=value fields to a...

dovecot at dovecot.org dovecot at dovecot.org
Thu Aug 9 17:17:23 EEST 2007


details:   http://hg.dovecot.org/dovecot/rev/1cc70ab3482a
changeset: 6246:1cc70ab3482a
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Aug 09 17:17:19 2007 +0300
description:
userdb passwd supports now adding key=value fields to args. They can
override settings found from passwd file. Typically you'd use this to
override a home directory, but it's also possible to override uid/gid.

diffstat:

2 files changed, 172 insertions(+), 84 deletions(-)
src/auth/userdb-passwd.c |   52 +++++++++--
src/auth/userdb-static.c |  204 +++++++++++++++++++++++++++++-----------------

diffs (truncated from 333 to 300 lines):

diff -r 007eee01749f -r 1cc70ab3482a src/auth/userdb-passwd.c
--- a/src/auth/userdb-passwd.c	Thu Aug 09 16:58:07 2007 +0300
+++ b/src/auth/userdb-passwd.c	Thu Aug 09 17:17:19 2007 +0300
@@ -5,14 +5,23 @@
 #ifdef USERDB_PASSWD
 
 #include "userdb.h"
+#include "userdb-static.h"
 
 #include <pwd.h>
 
 #define USER_CACHE_KEY "%u"
 
+struct passwd_userdb_module {
+	struct userdb_module module;
+	struct userdb_static_template *tmpl;
+};
+
 static void passwd_lookup(struct auth_request *auth_request,
 			  userdb_callback_t *callback)
 {
+	struct userdb_module *_module = auth_request->userdb->userdb;
+	struct passwd_userdb_module *module =
+		(struct passwd_userdb_module *)_module;
 	struct passwd *pw;
 
 	auth_request_log_debug(auth_request, "passwd", "lookup");
@@ -35,27 +44,50 @@ static void passwd_lookup(struct auth_re
 	auth_request_set_field(auth_request, "user", pw->pw_name, NULL);
 
 	auth_request_init_userdb_reply(auth_request);
-	auth_request_set_userdb_field(auth_request, "system_user", pw->pw_name);
-	auth_request_set_userdb_field(auth_request, "uid", dec2str(pw->pw_uid));
-	auth_request_set_userdb_field(auth_request, "gid", dec2str(pw->pw_gid));
-	auth_request_set_userdb_field(auth_request, "home", pw->pw_dir);
+	userdb_static_template_export(module->tmpl, auth_request);
+
+	if (!userdb_static_template_isset(module->tmpl, "system_user")) {
+		auth_request_set_userdb_field(auth_request,
+					      "system_user", pw->pw_name);
+	}
+	if (!userdb_static_template_isset(module->tmpl, "uid")) {
+		auth_request_set_userdb_field(auth_request,
+					      "uid", dec2str(pw->pw_uid));
+	}
+	if (!userdb_static_template_isset(module->tmpl, "gid")) {
+		auth_request_set_userdb_field(auth_request,
+					      "gid", dec2str(pw->pw_gid));
+	}
+	if (!userdb_static_template_isset(module->tmpl, "home"))
+		auth_request_set_userdb_field(auth_request, "home", pw->pw_dir);
 
 	callback(USERDB_RESULT_OK, auth_request);
 }
 
-static void passwd_passwd_init(struct userdb_module *module,
-			       const char *args)
+static struct userdb_module *
+passwd_passwd_preinit(struct auth_userdb *auth_userdb, const char *args)
 {
-	if (strcmp(args, "blocking=yes") == 0)
-		module->blocking = TRUE;
-	module->cache_key = USER_CACHE_KEY;
+	struct passwd_userdb_module *module;
+	const char *value;
+
+	module = p_new(auth_userdb->auth->pool, struct passwd_userdb_module, 1);
+	module->module.cache_key = USER_CACHE_KEY;
+	module->tmpl = userdb_static_template_build(auth_userdb->auth->pool,
+						    "passwd", args);
+
+	if (userdb_static_template_remove(module->tmpl, "blocking",
+					  &value)) {
+		module->module.blocking = value == NULL ||
+			strcasecmp(value, "yes") == 0;
+	}
+	return &module->module;
 }
 
 struct userdb_module_interface userdb_passwd = {
 	"passwd",
 
+	passwd_passwd_preinit,
 	NULL,
-	passwd_passwd_init,
 	NULL,
 
 	passwd_lookup
diff -r 007eee01749f -r 1cc70ab3482a src/auth/userdb-static.c
--- a/src/auth/userdb-static.c	Thu Aug 09 16:58:07 2007 +0300
+++ b/src/auth/userdb-static.c	Thu Aug 09 17:17:19 2007 +0300
@@ -1,35 +1,107 @@
 /* Copyright (C) 2003 Timo Sirainen */
 
 #include "common.h"
-
-#ifdef USERDB_STATIC
 
 #include "array.h"
 #include "str.h"
 #include "var-expand.h"
 #include "userdb.h"
+#include "userdb-static.h"
 
 #include <stdlib.h>
 
-struct static_context {
-	userdb_callback_t *callback, *old_callback;
-	void *old_context;
-};
-
-struct static_userdb_module {
-	struct userdb_module module;
-
-	ARRAY_DEFINE(template, const char *);
-
-	unsigned int allow_all_users:1;
-};
-
-static void static_lookup_real(struct auth_request *auth_request,
-			       userdb_callback_t *callback)
-{
-	struct userdb_module *_module = auth_request->userdb->userdb;
-	struct static_userdb_module *module =
-		(struct static_userdb_module *)_module;
+struct userdb_static_template {
+	ARRAY_DEFINE(args, const char *);
+};
+
+struct userdb_static_template *
+userdb_static_template_build(pool_t pool, const char *userdb_name,
+			     const char *args)
+{
+	struct userdb_static_template *tmpl;
+	const char *const *tmp, *key, *value;
+	uid_t uid;
+	gid_t gid;
+
+	t_push();
+	tmpl = p_new(pool, struct userdb_static_template, 1);
+
+	tmp = t_strsplit_spaces(args, " ");
+	p_array_init(&tmpl->args, pool, strarray_length(tmp));
+
+	for (; *tmp != NULL; tmp++) {
+		value = strchr(*tmp, '=');
+		if (value == NULL)
+			key = *tmp;
+		else {
+			key = t_strdup_until(*tmp, value);
+			value++;
+		}
+
+		if (strcasecmp(key, "uid") == 0) {
+			uid = userdb_parse_uid(NULL, value);
+			if (uid == (uid_t)-1) {
+				i_fatal("%s userdb: Invalid uid: %s",
+					userdb_name, value);
+			}
+			value = dec2str(uid);
+		} else if (strcasecmp(key, "gid") == 0) {
+			gid = userdb_parse_gid(NULL, value);
+			if (gid == (gid_t)-1) {
+				i_fatal("%s userdb: Invalid gid: %s",
+					userdb_name, value);
+			}
+			value = dec2str(gid);
+		} else if (*key == '\0') {
+			i_fatal("%s userdb: Empty key (=%s)",
+				userdb_name, value);
+		}
+		key = p_strdup(pool, key);
+		value = p_strdup(pool, value);
+
+		array_append(&tmpl->args, &key, 1);
+		array_append(&tmpl->args, &value, 1);
+	}
+	t_pop();
+	return tmpl;
+}
+
+bool userdb_static_template_isset(struct userdb_static_template *tmpl,
+				  const char *key)
+{
+	const char *const *args;
+	unsigned int i, count;
+
+	args = array_get(&tmpl->args, &count);
+	i_assert((count % 2) == 0);
+	for (i = 0; i < count; i += 2) {
+		if (strcmp(args[i], key) == 0)
+			return TRUE;
+	}
+	return FALSE;
+}
+
+bool userdb_static_template_remove(struct userdb_static_template *tmpl,
+				   const char *key, const char **value_r)
+{
+	const char *const *args;
+	unsigned int i, count;
+
+	args = array_get(&tmpl->args, &count);
+	i_assert((count % 2) == 0);
+	for (i = 0; i < count; i += 2) {
+		if (strcmp(args[i], key) == 0) {
+			*value_r = args[i+1];
+			array_delete(&tmpl->args, i, 2);
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
+void userdb_static_template_export(struct userdb_static_template *tmpl,
+				   struct auth_request *auth_request)
+{
         const struct var_expand_table *table;
 	string_t *str;
 	const char *const *args, *value;
@@ -39,9 +111,7 @@ static void static_lookup_real(struct au
 	str = t_str_new(256);
 	table = auth_request_get_var_expand_table(auth_request, NULL);
 
-	auth_request_init_userdb_reply(auth_request);
-
-	args = array_get(&module->template, &count);
+	args = array_get(&tmpl->args, &count);
 	i_assert((count % 2) == 0);
 	for (i = 0; i < count; i += 2) {
 		if (args[i+1] == NULL)
@@ -53,9 +123,33 @@ static void static_lookup_real(struct au
 		}
 		auth_request_set_userdb_field(auth_request, args[i], value);
 	}
-
+	t_pop();
+}
+
+#ifdef USERDB_STATIC
+
+struct static_context {
+	userdb_callback_t *callback, *old_callback;
+	void *old_context;
+};
+
+struct static_userdb_module {
+	struct userdb_module module;
+	struct userdb_static_template *tmpl;
+
+	unsigned int allow_all_users:1;
+};
+
+static void static_lookup_real(struct auth_request *auth_request,
+			       userdb_callback_t *callback)
+{
+	struct userdb_module *_module = auth_request->userdb->userdb;
+	struct static_userdb_module *module =
+		(struct static_userdb_module *)_module;
+
+	auth_request_init_userdb_reply(auth_request);
+	userdb_static_template_export(module->tmpl, auth_request);
 	callback(USERDB_RESULT_OK, auth_request);
-	t_pop();
 }
 
 static void
@@ -125,55 +219,17 @@ static_preinit(struct auth_userdb *auth_
 static_preinit(struct auth_userdb *auth_userdb, const char *args)
 {
 	struct static_userdb_module *module;
-	const char *const *tmp, *key, *value;
-	uid_t uid;
-	gid_t gid;
-
-	t_push();
+	const char *value;
+
 	module = p_new(auth_userdb->auth->pool, struct static_userdb_module, 1);
-
-	tmp = t_strsplit_spaces(args, " ");
-	p_array_init(&module->template, auth_userdb->auth->pool,
-		     strarray_length(tmp));
-
-	for (; *tmp != NULL; tmp++) {
-		value = strchr(*tmp, '=');
-		if (value == NULL)
-			key = *tmp;
-		else {
-			key = t_strdup_until(*tmp, value);
-			value++;
-		}
-
-		if (strcasecmp(key, "uid") == 0) {
-			uid = userdb_parse_uid(NULL, value);
-			if (uid == (uid_t)-1) {
-				i_fatal("static userdb: Invalid uid: %s",
-					value);
-			}
-			value = dec2str(uid);


More information about the dovecot-cvs mailing list