auth_str_add_keyvalue(dest, "original_user",
request->original_username);
}
+ if (request->master_user != NULL)
+ auth_str_add_keyvalue(dest, "auth_user", request->master_user);
if (!request->auth_only &&
auth_fields_exists(request->extra_fields, "proxy")) {
return TRUE;
}
+static void auth_str_append_userdb_extra_fields(struct auth_request *request,
+ string_t *dest)
+{
+ str_append_c(dest, '\t');
+ auth_fields_append(request->userdb_reply, dest,
+ AUTH_FIELD_FLAG_HIDDEN, 0);
+
+ if (request->master_user != NULL &&
+ !auth_fields_exists(request->userdb_reply, "master_user")) {
+ auth_str_add_keyvalue(dest, "master_user",
+ request->master_user);
+ }
+ if (*request->set->anonymous_username != '\0' &&
+ strcmp(request->user, request->set->anonymous_username) == 0) {
+ /* this is an anonymous login, either via ANONYMOUS
+ SASL mechanism or simply logging in as the anonymous
+ user via another mechanism */
+ str_append(dest, "\tanonymous");
+ }
+ /* generate auth_token when master service provided session_pid */
+ if (request->request_auth_token &&
+ request->session_pid != (pid_t)-1) {
+ const char *auth_token =
+ auth_token_get(request->service,
+ dec2str(request->session_pid),
+ request->user,
+ request->session_id);
+ auth_str_add_keyvalue(dest, "auth_token", auth_token);
+ }
+ if (request->master_user != NULL) {
+ auth_str_add_keyvalue(dest, "auth_user", request->master_user);
+ } else if (request->original_username != NULL &&
+ strcmp(request->original_username, request->user) != 0) {
+ auth_str_add_keyvalue(dest, "auth_user",
+ request->original_username);
+ }
+}
+
static void userdb_callback(enum userdb_result result,
struct auth_request *request)
{
case USERDB_RESULT_OK:
str_printfa(str, "USER\t%u\t", request->id);
str_append_tabescaped(str, request->user);
- str_append_c(str, '\t');
- auth_fields_append(request->userdb_reply, str,
- AUTH_FIELD_FLAG_HIDDEN, 0);
-
- if (request->master_user != NULL &&
- !auth_fields_exists(request->userdb_reply, "master_user")) {
- auth_str_add_keyvalue(str, "master_user",
- request->master_user);
- }
- if (*request->set->anonymous_username != '\0' &&
- strcmp(request->user,
- request->set->anonymous_username) == 0) {
- /* this is an anonymous login, either via ANONYMOUS
- SASL mechanism or simply logging in as the anonymous
- user via another mechanism */
- str_append(str, "\tanonymous");
- }
- /* generate auth_token when master service provided session_pid */
- if (request->request_auth_token &&
- request->session_pid != (pid_t)-1) {
- const char *auth_token =
- auth_token_get(request->service,
- dec2str(request->session_pid),
- request->user,
- request->session_id);
- auth_str_add_keyvalue(str, "auth_token", auth_token);
- }
+ auth_str_append_userdb_extra_fields(request, str);
break;
}
handler->master_callback(str_c(str), request->master);
enum mail_storage_service_flags flags;
struct ioloop_context *ioloop_ctx;
- const char *log_prefix, *auth_token;
+ const char *log_prefix, *auth_token, *auth_user;
const char *system_groups_user, *uid_source, *gid_source;
const struct mail_user_settings *user_set;
#endif
} else if (strncmp(line, "auth_token=", 11) == 0) {
user->auth_token = p_strdup(user->pool, line+11);
+ } else if (strncmp(line, "auth_user=", 10) == 0) {
+ user->auth_user = p_strdup(user->pool, line+10);
} else if (strncmp(line, "admin=", 6) == 0) {
user->admin = line[6] == 'y' || line[6] == 'Y' ||
line[6] == '1';
static const struct var_expand_table *
get_var_expand_table(struct master_service *service,
+ struct mail_storage_service_user *user,
struct mail_storage_service_input *input,
struct mail_storage_service_privileges *priv)
{
{ 'i', NULL, "uid" },
{ '\0', NULL, "gid" },
{ '\0', NULL, "session" },
+ { '\0', NULL, "auth_user" },
+ { '\0', NULL, "auth_username" },
+ { '\0', NULL, "auth_domain" },
{ '\0', NULL, NULL }
};
struct var_expand_table *tab;
tab[7].value = dec2str(priv->uid == (uid_t)-1 ? geteuid() : priv->uid);
tab[8].value = dec2str(priv->gid == (gid_t)-1 ? getegid() : priv->gid);
tab[9].value = input->session_id;
+ if (user == NULL || user->auth_user == NULL) {
+ tab[10].value = tab[0].value;
+ tab[11].value = tab[1].value;
+ tab[12].value = tab[2].value;
+ } else {
+ tab[10].value = user->auth_user;
+ tab[11].value = t_strcut(user->auth_user, '@');
+ tab[12].value = strchr(user->auth_user, '@');
+ }
return tab;
}
memset(&priv, 0, sizeof(priv));
priv.uid = (uid_t)-1;
priv.gid = (gid_t)-1;
- return get_var_expand_table(ctx->service, input, &priv);
+ return get_var_expand_table(ctx->service, NULL, input, &priv);
}
static const char *
user_expand_varstr(struct master_service *service,
- struct mail_storage_service_input *input,
+ struct mail_storage_service_user *user,
struct mail_storage_service_privileges *priv,
const char *str)
{
i_assert(*str == SETTING_STRVAR_UNEXPANDED[0]);
ret = t_str_new(256);
- var_expand(ret, str + 1, get_var_expand_table(service, input, priv));
+ var_expand(ret, str + 1,
+ get_var_expand_table(service, user, &user->input, priv));
return str_c(ret);
}
/* variable strings are expanded in mail_user_init(),
but we need the home and chroot sooner so do them separately here. */
- priv_r->home = user_expand_varstr(ctx->service, &user->input, priv_r,
+ priv_r->home = user_expand_varstr(ctx->service, user, priv_r,
user->user_set->mail_home);
- priv_r->chroot = user_expand_varstr(ctx->service, &user->input, priv_r,
+ priv_r->chroot = user_expand_varstr(ctx->service, user, priv_r,
user->user_set->mail_chroot);
return 0;
}
mail_user->anonymous = user->anonymous;
mail_user->admin = user->admin;
mail_user->auth_token = p_strdup(mail_user->pool, user->auth_token);
+ mail_user->auth_user = p_strdup(mail_user->pool, user->auth_user);
mail_set = mail_user_set_get_storage_set(mail_user);
str = t_str_new(256);
var_expand(str, user->user_set->mail_log_prefix,
- get_var_expand_table(ctx->service, &user->input, priv));
+ get_var_expand_table(ctx->service, user, &user->input, priv));
user->log_prefix = p_strdup(user->pool, str_c(str));
} T_END;
{ 'p', NULL, "pid" },
{ 'i', NULL, "uid" },
{ '\0', NULL, "gid" },
+ { '\0', NULL, "auth_user" },
+ { '\0', NULL, "auth_username" },
+ { '\0', NULL, "auth_domain" },
{ '\0', NULL, NULL }
};
struct var_expand_table *tab;
tab[7].value = my_pid;
tab[8].value = p_strdup(user->pool, dec2str(user->uid));
tab[9].value = p_strdup(user->pool, dec2str(user->gid));
+ if (user->auth_user == NULL) {
+ tab[10].value = tab[0].value;
+ tab[11].value = tab[1].value;
+ tab[12].value = tab[2].value;
+ } else {
+ tab[10].value = user->auth_user;
+ tab[11].value = t_strcut(user->auth_user, '@');
+ tab[12].value = strchr(user->auth_user, '@');
+ }
user->var_expand_table = tab;
return user->var_expand_table;
gid_t gid;
const char *service;
struct ip_addr *local_ip, *remote_ip;
- const char *auth_token;
+ const char *auth_token, *auth_user;
const struct var_expand_table *var_expand_table;
/* If non-NULL, fail the user initialization with this error.
i_free(client->proxy_master_user);
i_free(client->virtual_user);
i_free(client->virtual_user_orig);
+ i_free(client->virtual_auth_user);
i_free(client->auth_mech_name);
i_free(client->master_data_prefix);
pool_unref(&client->pool);
{ '\0', NULL, "orig_user" },
{ '\0', NULL, "orig_username" },
{ '\0', NULL, "orig_domain" },
+ { '\0', NULL, "auth_user" },
+ { '\0', NULL, "auth_username" },
+ { '\0', NULL, "auth_domain" },
{ '\0', NULL, NULL }
};
+static void
+get_var_expand_users(struct var_expand_table *tab, const char *user)
+{
+ unsigned int i;
+
+ tab[0].value = user;
+ tab[1].value = t_strcut(user, '@');
+ tab[2].value = strchr(user, '@');
+ if (tab[2].value != NULL) tab[2].value++;
+
+ for (i = 0; i < 3; i++)
+ tab[i].value = str_sanitize(tab[i].value, 80);
+}
+
static const struct var_expand_table *
get_var_expand_table(struct client *client)
{
struct var_expand_table *tab;
- unsigned int i;
tab = t_malloc(sizeof(login_var_expand_empty_tab));
memcpy(tab, login_var_expand_empty_tab,
sizeof(login_var_expand_empty_tab));
- if (client->virtual_user != NULL) {
- tab[0].value = client->virtual_user;
- tab[1].value = t_strcut(client->virtual_user, '@');
- tab[2].value = strchr(client->virtual_user, '@');
- if (tab[2].value != NULL) tab[2].value++;
-
- for (i = 0; i < 3; i++)
- tab[i].value = str_sanitize(tab[i].value, 80);
- }
+ if (client->virtual_user != NULL)
+ get_var_expand_users(tab, client->virtual_user);
tab[3].value = login_binary->protocol;
tab[4].value = getenv("HOME");
tab[5].value = net_ip2addr(&client->local_ip);
tab[16].value = net_ip2addr(&client->real_remote_ip);
tab[17].value = dec2str(client->real_local_port);
tab[18].value = dec2str(client->real_remote_port);
- if (client->virtual_user_orig == NULL) {
+ if (client->virtual_user_orig != NULL)
+ get_var_expand_users(tab+19, client->virtual_user_orig);
+ else {
tab[19].value = tab[0].value;
tab[20].value = tab[1].value;
tab[21].value = tab[2].value;
- } else {
- tab[19].value = client->virtual_user_orig;
- tab[20].value = t_strcut(client->virtual_user_orig, '@');
- tab[21].value = strchr(client->virtual_user_orig, '@');
- if (tab[21].value != NULL) tab[21].value++;
-
- for (i = 0; i < 3; i++)
- tab[i].value = str_sanitize(tab[i].value, 80);
+ }
+ if (client->virtual_auth_user != NULL)
+ get_var_expand_users(tab+22, client->virtual_auth_user);
+ else {
+ tab[22].value = tab[0].value;
+ tab[23].value = tab[1].value;
+ tab[24].value = tab[2].value;
}
return tab;
}
unsigned int auth_attempts, auth_successes;
pid_t mail_pid;
- char *virtual_user, *virtual_user_orig;
+ char *virtual_user, *virtual_user_orig, *virtual_auth_user;
unsigned int destroyed:1;
unsigned int input_blocked:1;
unsigned int login_success:1;
if (strncmp(args[i], "user=", 5) == 0) {
i_free(client->virtual_user);
i_free_and_null(client->virtual_user_orig);
+ i_free_and_null(client->virtual_auth_user);
client->virtual_user = i_strdup(args[i] + 5);
} else if (strncmp(args[i], "original_user=", 14) == 0) {
i_free(client->virtual_user_orig);
client->virtual_user_orig = i_strdup(args[i] + 14);
+ } else if (strncmp(args[i], "auth_user=", 10) == 0) {
+ i_free(client->virtual_auth_user);
+ client->virtual_auth_user =
+ i_strdup(args[i] + 10);
} else if (strcmp(args[i], "nologin") == 0 ||
strcmp(args[i], "proxy") == 0) {
/* user can't login */
if (strncmp(args[i], "user=", 5) == 0) {
i_free(client->virtual_user);
i_free_and_null(client->virtual_user_orig);
+ i_free_and_null(client->virtual_auth_user);
client->virtual_user =
i_strdup(args[i] + 5);
} else if (strncmp(args[i], "original_user=", 14) == 0) {
i_free(client->virtual_user_orig);
client->virtual_user_orig =
i_strdup(args[i] + 14);
+ } else if (strncmp(args[i], "auth_user=", 10) == 0) {
+ i_free(client->virtual_auth_user);
+ client->virtual_auth_user =
+ i_strdup(args[i] + 10);
}
}
}