Mercurial > dovecot > core-2.2
changeset 12003:a2e60bd5d9a7
master: Give better error messages for unknown users/groups.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 16 Aug 2010 16:49:29 +0100 |
parents | 2156583b00e2 |
children | 4f90b4114450 |
files | src/lib-master/service-settings.h src/master/master-settings.c src/master/service.c |
diffstat | 3 files changed, 85 insertions(+), 26 deletions(-) [+] |
line wrap: on
line diff
--- 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 *);
--- 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, " ");
--- 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 == '/')