};
enum master_service_flags service_flags = 0;
enum mail_storage_service_flags storage_service_flags = 0;
+ struct mail_storage_service_input input;
struct mail_user *mail_user;
const struct imap_settings *set;
- const char *user;
bool dump_capability;
+ const char *value;
int c;
#ifdef DEBUG
i_fatal("Unknown argument: %c", c);
}
- user = getenv("USER");
- if (user == NULL) {
+ memset(&input, 0, sizeof(input));
+ input.username = getenv("USER");
+ if (input.username == NULL) {
if (IS_STANDALONE())
- user = getlogin();
- if (user == NULL)
+ input.username = getlogin();
+ if (input.username == NULL)
i_fatal("USER environment missing");
}
+ if ((value = getenv("IP")) != NULL)
+ net_addr2ip(value, &input.remote_ip);
+ if ((value = getenv("LOCAL_IP")) != NULL)
+ net_addr2ip(value, &input.local_ip);
/* plugins may want to add commands, so this needs to be called early */
commands_init();
- mail_user = mail_storage_service_init_user(service, user, set_roots,
+ mail_user = mail_storage_service_init_user(service, &input, set_roots,
storage_service_flags);
set = mail_storage_service_get_settings(service);
restrict_access_allow_coredumps(TRUE);
struct mail_deliver_context ctx;
enum mail_storage_service_flags service_flags = 0;
const char *user, *errstr, *path, *getopt_str;
+ struct mail_storage_service_input service_input;
struct mail_user *raw_mail_user;
struct mail_namespace *raw_ns;
struct mail_namespace_settings raw_ns_set;
"destination user parameter (-d user) not given");
}
+ memset(&service_input, 0, sizeof(service_input));
+ service_input.username = user;
+
service_flags |= MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT;
- ctx.dest_user = mail_storage_service_init_user(service, user, set_roots,
+ ctx.dest_user = mail_storage_service_init_user(service, &service_input,
+ set_roots,
service_flags);
ctx.set = mail_storage_service_get_settings(service);
duplicate_init(mail_user_set_get_storage_set(ctx.dest_user->set));
struct mail_storage_service_multi_user {
pool_t pool;
- const char *user;
+ struct mail_storage_service_input input;
+
const char *system_groups_user;
const struct mail_user_settings *user_set;
struct setting_parser_context *set_parser;
if (ret > 0 && strcmp(*user, orig_user) != 0) {
if (mail_user_set_get_storage_set(user_set)->mail_debug)
i_info("changed username to %s", *user);
- i_set_failure_prefix(t_strdup_printf("%s(%s): ", name, *user));
}
auth_master_deinit(&conn);
static int
mail_storage_service_init_post(struct master_service *service,
- const char *user, const char *home,
+ const struct mail_storage_service_input *input,
+ const char *home,
const struct mail_user_settings *user_set,
bool setuid_root, struct mail_user **mail_user_r,
const char **error_r)
}
}
- mail_user = mail_user_alloc(user, user_set);
+ mail_user = mail_user_alloc(input->username, user_set);
mail_user_set_home(mail_user, *home == '\0' ? NULL : home);
- mail_user_set_vars(mail_user, geteuid(), service->name, NULL, NULL);
+ mail_user_set_vars(mail_user, geteuid(), service->name,
+ &input->local_ip, &input->remote_ip);
if (mail_user_init(mail_user, error_r) < 0) {
mail_user_unref(&mail_user);
return -1;
}
static const struct var_expand_table *
-get_var_expand_table(struct master_service *service, const char *user)
+get_var_expand_table(struct master_service *service,
+ struct mail_storage_service_input *input)
{
static struct var_expand_table static_tab[] = {
{ 'u', NULL, "user" },
{ 'n', NULL, "username" },
{ 'd', NULL, "domain" },
{ 's', NULL, "service" },
+ { 'l', NULL, "lip" },
+ { 'r', NULL, "rip" },
{ 'p', NULL, "pid" },
{ 'i', NULL, "uid" },
{ '\0', NULL, NULL }
tab = t_malloc(sizeof(static_tab));
memcpy(tab, static_tab, sizeof(static_tab));
- tab[0].value = user;
- tab[1].value = t_strcut(user, '@');
- tab[2].value = strchr(user, '@');
+ tab[0].value = input->username;
+ tab[1].value = t_strcut(input->username, '@');
+ tab[2].value = strchr(input->username, '@');
if (tab[2].value != NULL) tab[2].value++;
tab[3].value = service->name;
- tab[4].value = my_pid;
- tab[5].value = dec2str(geteuid());
+ tab[4].value = net_ip2addr(&input->local_ip);
+ tab[5].value = net_ip2addr(&input->remote_ip);
+ tab[6].value = my_pid;
+ tab[7].value = dec2str(geteuid());
return tab;
}
static const char *
-user_expand_varstr(struct master_service *service, const char *user,
- const char *str)
+user_expand_varstr(struct master_service *service,
+ struct mail_storage_service_input *input, const char *str)
{
string_t *ret;
i_assert(*str == SETTING_STRVAR_UNEXPANDED[0]);
ret = t_str_new(256);
- var_expand(ret, str + 1, get_var_expand_table(service, user));
+ var_expand(ret, str + 1, get_var_expand_table(service, input));
return str_c(ret);
}
+static void
+mail_storage_service_init_log(struct master_service *service,
+ struct mail_storage_service_input *input)
+{
+ const struct mail_user_settings *user_set;
+ void **sets;
+
+ sets = master_service_settings_get_others(service);
+ user_set = sets[0];
+
+ T_BEGIN {
+ string_t *str;
+
+ str = t_str_new(256);
+ var_expand(str, user_set->mail_log_prefix,
+ get_var_expand_table(service, input));
+ master_service_init_log(service, str_c(str));
+ } T_END;
+}
+
struct mail_user *
-mail_storage_service_init_user(struct master_service *service, const char *user,
+mail_storage_service_init_user(struct master_service *service,
+ const struct mail_storage_service_input *_input,
const struct setting_parser_info *set_roots[],
enum mail_storage_service_flags flags)
{
+ struct mail_storage_service_input input = *_input;
const struct master_service_settings *set;
const struct mail_user_settings *user_set;
const struct mail_storage_settings *mail_set;
struct mail_user *mail_user;
void **sets;
- const char *orig_user, *home, *system_groups_user, *error;
+ const char *user, *orig_user, *home, *system_groups_user, *error;
unsigned int len;
bool userdb_lookup;
set_keyval(service->set_parser, "mail_debug", "yes");
/* now that we've read settings, we can set up logging */
- master_service_init_log(service,
- t_strdup_printf("%s(%s): ", service->name, user));
+ mail_storage_service_init_log(service, &input);
set = master_service_settings_get(service);
sets = master_service_settings_get_others(service);
if (userdb_lookup) {
/* userdb lookup may change settings, do it as soon as
possible. */
- orig_user = user;
+ orig_user = user = input.username;
if (service_auth_userdb_lookup(service->set_parser,
service->name, user_set, &user,
&system_groups_user,
&error) <= 0)
i_fatal("%s", error);
+ input.username = user;
+
+ /* set up logging again in case username changed */
+ mail_storage_service_init_log(service, &input);
}
/* variable strings are expanded in mail_user_init(),
but we need the home sooner so do it separately here. */
- home = user_expand_varstr(service, user, user_set->mail_home);
+ home = user_expand_varstr(service, &input, user_set->mail_home);
if (!userdb_lookup) {
system_groups_user = NULL;
dict_drivers_register_builtin();
module_dir_init(modules);
mail_users_init(user_set->auth_socket_path, mail_set->mail_debug);
- if (mail_storage_service_init_post(service, user, home, user_set, FALSE,
- &mail_user, &error) < 0)
+ if (mail_storage_service_init_post(service, &input, home, user_set,
+ FALSE, &mail_user, &error) < 0)
i_fatal("%s", error);
return mail_user;
}
}
int mail_storage_service_multi_lookup(struct mail_storage_service_multi_ctx *ctx,
- const char *username, pool_t pool,
+ const struct mail_storage_service_input *input,
+ pool_t pool,
struct mail_storage_service_multi_user **user_r,
const char **error_r)
{
struct mail_storage_service_multi_user *user;
- const char *orig_user;
+ const char *orig_user, *username;
void **sets;
int ret;
user = p_new(pool, struct mail_storage_service_multi_user, 1);
memset(user_r, 0, sizeof(user_r));
user->pool = pool;
- user->user = username;
+ user->input = *input;
+ user->input.username = p_strdup(pool, input->username);
user->set_parser = settings_parser_dup(ctx->service->set_parser, pool);
sets = settings_parser_get_list(user->set_parser);
user->user_set = sets[1];
if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP) != 0) {
- orig_user = user->user;
+ orig_user = username = user->input.username;
ret = service_auth_userdb_lookup(user->set_parser,
ctx->service->name,
- user->user_set,
- &user->user,
+ user->user_set, &username,
&user->system_groups_user,
error_r);
if (ret <= 0)
return ret;
+ user->input.username = p_strdup(pool, username);
}
- user->user = p_strdup(pool, user->user);
*user_r = user;
return 1;
}
/* variable strings are expanded in mail_user_init(),
but we need the home sooner so do it separately here. */
- home = user_expand_varstr(ctx->service, user->user,
+ home = user_expand_varstr(ctx->service, &user->input,
user_set->mail_home);
+ mail_storage_service_init_log(ctx->service, &user->input);
+
if ((ctx->flags & MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS) == 0) {
service_drop_privileges(user_set, user->system_groups_user, home,
(ctx->flags & MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT) != 0,
set_keyval(user->set_parser, "mail_home",
t_strconcat(user_set->mail_chroot, "/", home, NULL));
}
- if (mail_storage_service_init_post(ctx->service, user->user, home,
- user_set, TRUE,
+ if (mail_storage_service_init_post(ctx->service, &user->input,
+ home, user_set, TRUE,
mail_user_r, error_r) < 0)
return -1;
return 0;
#ifndef MAIL_STORAGE_SERVICE_H
#define MAIL_STORAGE_SERVICE_H
+#include "network.h"
+
struct master_service;
enum mail_storage_service_flags {
MAIL_STORAGE_SERVICE_FLAG_NO_RESTRICT_ACCESS = 0x08
};
+struct mail_storage_service_input {
+ const char *username;
+ struct ip_addr local_ip, remote_ip;
+};
+
struct setting_parser_info;
struct mail_storage_service_multi_user;
struct mail_user *
-mail_storage_service_init_user(struct master_service *service, const char *user,
+mail_storage_service_init_user(struct master_service *service,
+ const struct mail_storage_service_input *input,
const struct setting_parser_info *set_roots[],
enum mail_storage_service_flags flags);
void mail_storage_service_deinit_user(void);
enum mail_storage_service_flags flags);
/* Returns 1 if ok, 0 if user wasn't found, -1 if error. */
int mail_storage_service_multi_lookup(struct mail_storage_service_multi_ctx *ctx,
- const char *username, pool_t pool,
+ const struct mail_storage_service_input *input,
+ pool_t pool,
struct mail_storage_service_multi_user **user_r,
const char **error_r);
int mail_storage_service_multi_next(struct mail_storage_service_multi_ctx *ctx,
DEF(SET_STR, mail_plugins),
DEF(SET_STR, mail_plugin_dir),
+ DEF(SET_STR, mail_log_prefix),
+
DEFLIST(namespaces, "namespace", &mail_namespace_setting_parser_info),
{ SET_STRLIST, "plugin", offsetof(struct mail_user_settings, plugin_envs), NULL },
MEMBER(mail_plugins) "",
MEMBER(mail_plugin_dir) MODULEDIR,
+ MEMBER(mail_log_prefix) "%Us(%u): ",
+
MEMBER(namespaces) ARRAY_INIT,
MEMBER(plugin_envs) ARRAY_INIT
};
const char *mail_plugins;
const char *mail_plugin_dir;
+ const char *mail_log_prefix;
+
ARRAY_DEFINE(namespaces, struct mail_namespace_settings *);
ARRAY_DEFINE(plugin_envs, const char *);
};
{
user->uid = uid;
user->service = p_strdup(user->pool, service);
- if (local_ip != NULL) {
+ if (local_ip != NULL && local_ip->family != 0) {
user->local_ip = p_new(user->pool, struct ip_addr, 1);
*user->local_ip = *local_ip;
}
- if (remote_ip != NULL) {
+ if (remote_ip != NULL && remote_ip->family != 0) {
user->remote_ip = p_new(user->pool, struct ip_addr, 1);
*user->remote_ip = *remote_ip;
}
{
i_free(log_prefix);
log_prefix = i_strdup(prefix);
+ i_warning("new prefix=%s", prefix);
}
static int ATTR_FORMAT(2, 0)
int cmd_rcpt(struct client *client, const char *args)
{
struct mail_recipient rcpt;
+ struct mail_storage_service_input input;
const char *name, *error;
unsigned int len;
int ret;
return 0;
}
- ret = mail_storage_service_multi_lookup(multi_service, name,
+ memset(&input, 0, sizeof(input));
+ input.username = name;
+ input.local_ip = client->local_ip;
+ input.remote_ip = client->remote_ip;
+
+ ret = mail_storage_service_multi_lookup(multi_service, &input,
client->state_pool,
&rcpt.multi_user, &error);
if (ret < 0) {
int main(int argc, char *argv[])
{
struct master_service *service;
+ struct mail_storage_service_input input;
struct mail_user *user;
struct convert_plugin_settings set;
struct mail_namespace *dest_ns;
i_fatal(USAGE_STRING);
}
+ memset(&input, 0, sizeof(input));
+ input.username = argv[optind];
+
master_service_init_log(service,
- t_strdup_printf("convert-tool(%s): ", argv[optind]));
- user = mail_storage_service_init_user(service, argv[optind], NULL, 0);
+ t_strdup_printf("convert-tool(%s): ", input.username));
+ user = mail_storage_service_init_user(service, &input, NULL, 0);
memset(&ns_set, 0, sizeof(ns_set));
ns_set.location = argv[4];
unsigned int expunge_secs, unsigned int altmove_secs,
time_t *oldest_r)
{
+ struct mail_storage_service_input input;
struct mail_storage_service_multi_user *multi_user;
struct mail_namespace *ns;
struct mail_storage *storage;
enum mail_flags flags;
int ret;
+ memset(&input, 0, sizeof(input));
+ input.username = user;
+
*oldest_r = 0;
if (ctx->mail_user != NULL &&
i_set_failure_prefix(t_strdup_printf("expire-tool(%s): ",
user));
p_clear(ctx->multi_user_pool);
- ret = mail_storage_service_multi_lookup(ctx->multi, user,
+ ret = mail_storage_service_multi_lookup(ctx->multi, &input,
ctx->multi_user_pool,
&multi_user, &errstr);
if (ret <= 0) {
enum master_service_flags service_flags = 0;
enum mail_storage_service_flags storage_service_flags =
MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT;
+ struct mail_storage_service_input input;
struct mail_user *mail_user;
const struct pop3_settings *set;
- const char *user;
+ const char *value;
int c;
#ifdef DEBUG
if (!master_service_parse_option(service, c, optarg))
i_fatal("Unknown argument: %c", c);
}
- user = getenv("USER");
- if (user == NULL) {
+
+ memset(&input, 0, sizeof(input));
+ input.username = getenv("USER");
+ if (input.username == NULL) {
if (IS_STANDALONE())
- user = getlogin();
- if (user == NULL)
+ input.username = getlogin();
+ if (input.username == NULL)
i_fatal("USER environment missing");
}
+ if ((value = getenv("IP")) != NULL)
+ net_addr2ip(value, &input.remote_ip);
+ if ((value = getenv("LOCAL_IP")) != NULL)
+ net_addr2ip(value, &input.local_ip);
- mail_user = mail_storage_service_init_user(service, user, set_roots,
+ mail_user = mail_storage_service_init_user(service, &input, set_roots,
storage_service_flags);
set = mail_storage_service_get_settings(service);
restrict_access_allow_coredumps(TRUE);
{
enum mail_storage_service_flags service_flags = 0;
struct master_service *service;
- const char *getopt_str, *user;
+ struct mail_storage_service_input input;
+ const char *getopt_str;
int c;
service = master_service_init("doveadm",
MASTER_SERVICE_FLAG_LOG_TO_STDERR,
argc, argv);
- user = getenv("USER");
+ memset(&input, 0, sizeof(input));
+ input.username = getenv("USER");
getopt_str = t_strconcat("u:v", master_service_getopt_string(), NULL);
while ((c = getopt(argc, argv, getopt_str)) > 0) {
switch (c) {
case 'u':
- user = optarg;
+ input.username = optarg;
service_flags |= MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
break;
case 'v':
if (optind == argc)
usage();
- if (user == NULL)
+ if (input.username == NULL)
i_fatal("USER environment is missing and -u option not used");
- mail_user = mail_storage_service_init_user(service, user, NULL,
+ mail_user = mail_storage_service_init_user(service, &input, NULL,
service_flags);
if (strcmp(argv[optind], "purge") == 0)