dovecot-2.0: master: Give better error messages for unknown user...

dovecot at dovecot.org dovecot at dovecot.org
Mon Aug 16 18:50:01 EEST 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/a2e60bd5d9a7
changeset: 12003:a2e60bd5d9a7
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Aug 16 16:49:29 2010 +0100
description:
master: Give better error messages for unknown users/groups.

diffstat:

 src/lib-master/service-settings.h |   7 +++
 src/master/master-settings.c      |  17 ++++++--
 src/master/service.c              |  87 +++++++++++++++++++++++++++++++++----------
 3 files changed, 85 insertions(+), 26 deletions(-)

diffs (212 lines):

diff -r 2156583b00e2 -r a2e60bd5d9a7 src/lib-master/service-settings.h
--- a/src/lib-master/service-settings.h	Mon Aug 16 16:07:01 2010 +0100
+++ b/src/lib-master/service-settings.h	Mon Aug 16 16:49:29 2010 +0100
@@ -2,6 +2,12 @@
 #define SERVICE_SETTINGS_H
 
 /* <settings checks> */
+enum service_user_default {
+	SERVICE_USER_DEFAULT_NONE = 0,
+	SERVICE_USER_DEFAULT_INTERNAL,
+	SERVICE_USER_DEFAULT_LOGIN
+};
+
 enum service_type {
 	SERVICE_TYPE_UNKNOWN,
 	SERVICE_TYPE_LOG,
@@ -55,6 +61,7 @@
 	/* internal to master: */
 	struct master_settings *master_set;
 	enum service_type parsed_type;
+	enum service_user_default user_default;
 	unsigned int login_dump_core:1;
 };
 ARRAY_DEFINE_TYPE(service_settings, struct service_settings *);
diff -r 2156583b00e2 -r a2e60bd5d9a7 src/master/master-settings.c
--- a/src/master/master-settings.c	Mon Aug 16 16:07:01 2010 +0100
+++ b/src/master/master-settings.c	Mon Aug 16 16:49:29 2010 +0100
@@ -239,15 +239,21 @@
 
 /* <settings checks> */
 static void
-expand_user(const char **user, const struct master_settings *set)
+expand_user(const char **user, enum service_user_default *default_r,
+	    const struct master_settings *set)
 {
 	/* $variable expansion is typically done by doveconf, but these
 	   variables can come from built-in settings, so we need to expand
 	   them here */
-	if (strcmp(*user, "$default_internal_user") == 0)
+	if (strcmp(*user, "$default_internal_user") == 0) {
 		*user = set->default_internal_user;
-	else if (strcmp(*user, "$default_login_user") == 0)
+		*default_r = SERVICE_USER_DEFAULT_INTERNAL;
+	} else if (strcmp(*user, "$default_login_user") == 0) {
 		*user = set->default_login_user;
+		*default_r = SERVICE_USER_DEFAULT_LOGIN;
+	} else {
+		*default_r = SERVICE_USER_DEFAULT_NONE;
+	}
 }
 
 static void
@@ -257,6 +263,7 @@
 {
 	struct file_listener_settings *const *sets;
 	unsigned int base_dir_len = strlen(master_set->base_dir);
+	enum service_user_default user_default;
 
 	if (!array_is_created(l))
 		return;
@@ -264,7 +271,7 @@
 	array_foreach(l, sets) {
 		struct file_listener_settings *set = *sets;
 
-		expand_user(&set->user, master_set);
+		expand_user(&set->user, &user_default, master_set);
 		if (*set->path != '/') {
 			set->path = p_strconcat(pool, master_set->base_dir, "/",
 						set->path, NULL);
@@ -401,7 +408,7 @@
 				return FALSE;
 			}
 		}
-		expand_user(&service->user, set);
+		expand_user(&service->user, &service->user_default, set);
 		service_set_login_dump_core(service);
 	}
 	set->protocols_split = p_strsplit_spaces(pool, set->protocols, " ");
diff -r 2156583b00e2 -r a2e60bd5d9a7 src/master/service.c
--- a/src/master/service.c	Mon Aug 16 16:07:01 2010 +0100
+++ b/src/master/service.c	Mon Aug 16 16:49:29 2010 +0100
@@ -38,6 +38,7 @@
 			     const char **error_r)
 {
 	struct service_listener *l;
+	const char *set_name;
 	gid_t gid;
 
 	l = p_new(service->list->pool, struct service_listener, 1);
@@ -47,10 +48,18 @@
 	l->set.fileset.set = set;
 
 	if (get_uidgid(set->user, &l->set.fileset.uid, &gid, error_r) < 0)
-		return NULL;
-	if (get_gid(set->group, &l->set.fileset.gid, error_r) < 0)
-		return NULL;
-	return l;
+		set_name = "user";
+	else if (get_gid(set->group, &l->set.fileset.gid, error_r) < 0)
+		set_name = "group";
+	else
+		return l;
+
+	*error_r = t_strdup_printf(
+		"%s (See service %s { %s_listener %s { %s } } setting)",
+		*error_r, service->set->name,
+		type == SERVICE_LISTENER_UNIX ? "unix" : "fifo",
+		set->path, set_name);
+	return NULL;
 }
 
 static int
@@ -169,6 +178,26 @@
 	return 0;
 }
 
+static int service_get_groups(const char *groups, pool_t pool,
+			      const char **gids_r, const char **error_r)
+{
+	const char *const *tmp;
+	string_t *str;
+	gid_t gid;
+
+	str = t_str_new(64);
+	for (tmp = t_strsplit(groups, ","); *tmp != NULL; tmp++) {
+		if (get_gid(*tmp, &gid, error_r) < 0)
+			return -1;
+
+		if (str_len(str) > 0)
+			str_append_c(str, ',');
+		str_append(str, dec2str(gid));
+	}
+	*gids_r = p_strdup(pool, str_c(str));
+	return 0;
+}
+
 static struct service *
 service_create(pool_t pool, const struct service_settings *set,
 	       struct service_list *service_list, const char **error_r)
@@ -178,8 +207,6 @@
 	struct inet_listener_settings *const *inet_listeners;
 	struct service *service;
         struct service_listener *l;
-	const char *const *tmp;
-	string_t *str;
 	unsigned int i, unix_count, fifo_count, inet_count;
 
 	service = p_new(pool, struct service, 1);
@@ -215,30 +242,48 @@
 	}
 
 	/* default gid to user's primary group */
-	if (get_uidgid(set->user, &service->uid, &service->gid, error_r) < 0)
+	if (get_uidgid(set->user, &service->uid, &service->gid, error_r) < 0) {
+		switch (set->user_default) {
+		case SERVICE_USER_DEFAULT_NONE:
+			*error_r = t_strdup_printf(
+				"%s (See service %s { user } setting)",
+				*error_r, set->name);
+			break;
+		case SERVICE_USER_DEFAULT_INTERNAL:
+			*error_r = t_strconcat(*error_r,
+				" (See default_internal_user setting)", NULL);
+			break;
+		case SERVICE_USER_DEFAULT_LOGIN:
+			*error_r = t_strconcat(*error_r,
+				" (See default_login_user setting)", NULL);
+			break;
+		}
 		return NULL;
+	}
 	if (*set->group != '\0') {
-		if (get_gid(set->group, &service->gid, error_r) < 0)
+		if (get_gid(set->group, &service->gid, error_r) < 0) {
+			*error_r = t_strdup_printf(
+				"%s (See service %s { group } setting)",
+				*error_r, set->name);
 			return NULL;
+		}
 	}
 	if (get_gid(set->privileged_group, &service->privileged_gid,
-		    error_r) < 0)
+		    error_r) < 0) {
+		*error_r = t_strdup_printf(
+			"%s (See service %s { privileged_group } setting)",
+			*error_r, set->name);
 		return NULL;
+	}
 
 	if (*set->extra_groups != '\0') {
-		str = t_str_new(64);
-		tmp = t_strsplit(set->extra_groups, ",");
-		for (; *tmp != NULL; tmp++) {
-			gid_t gid;
-
-			if (get_gid(*tmp, &gid, error_r) < 0)
-				return NULL;
-
-			if (str_len(str) > 0)
-				str_append_c(str, ',');
-			str_append(str, dec2str(gid));
+		if (service_get_groups(set->extra_groups, pool,
+				       &service->extra_gids, error_r) < 0) {
+			*error_r = t_strdup_printf(
+				"%s (See service %s { extra_groups } setting)",
+				*error_r, set->name);
+			return NULL;
 		}
-		service->extra_gids = p_strdup(pool, str_c(str));
 	}
 
 	if (*set->executable == '/')


More information about the dovecot-cvs mailing list