user_directory_deinit(&dir->users);
mail_hosts_deinit(&dir->mail_hosts);
+ mail_hosts_deinit(&dir->orig_config_hosts);
if (dir->to_request != NULL)
timeout_remove(&dir->to_request);
array_foreach(&dir->dir_hosts, hostp)
struct director_host *self_host;
struct director_connection *left, *right;
+ /* current mail hosts */
struct mail_host_list *mail_hosts;
+ /* original mail hosts configured in config file.
+ this is used only for doveadm lookups */
+ struct mail_host_list *orig_config_hosts;
/* temporary user -> host associations */
struct user_directory *users;
doveadm_cmd_user_lookup(struct doveadm_connection *conn, const char *line)
{
struct user *user;
- unsigned int hash;
+ struct mail_host *host;
+ unsigned int username_hash;
+ string_t *str = t_str_new(256);
+
+ username_hash = user_directory_get_username_hash(line);
- hash = user_directory_get_username_hash(line);
- user = user_directory_lookup(conn->dir->users, hash);
+ /* get user's current host */
+ user = user_directory_lookup(conn->dir->users, username_hash);
if (user == NULL)
- o_stream_send_str(conn->output, "NOTFOUND\n");
+ str_append(str, "\t0");
else {
- o_stream_send_str(conn->output, t_strconcat(
- net_ip2addr(&user->host->ip), "\n", NULL));
+ str_printfa(str, "%s\t%u", net_ip2addr(&user->host->ip),
+ user->timestamp +
+ conn->dir->set->director_user_expire);
}
+
+ /* get host if it wasn't in user directory */
+ host = mail_host_get_by_hash(conn->dir->mail_hosts, username_hash);
+ if (host == NULL)
+ str_append(str, "\t");
+ else
+ str_printfa(str, "\t%s", net_ip2addr(&host->ip));
+
+ /* get host with default configuration */
+ host = mail_host_get_by_hash(conn->dir->orig_config_hosts,
+ username_hash);
+ if (host == NULL)
+ str_append(str, "\t");
+ else
+ str_printfa(str, "\t%s\n", net_ip2addr(&host->ip));
+ o_stream_send(conn->output, str_data(str), str_len(str));
return TRUE;
}
array_free(&list->vhosts);
i_free(list);
}
+
+static struct mail_host *mail_host_dup(const struct mail_host *src)
+{
+ struct mail_host *dest;
+
+ dest = i_new(struct mail_host, 1);
+ *dest = *src;
+ return dest;
+}
+
+struct mail_host_list *mail_hosts_dup(const struct mail_host_list *src)
+{
+ struct mail_host_list *dest;
+ struct mail_host *const *hostp, *dest_host;
+
+ dest = mail_hosts_init();
+ array_foreach(&src->hosts, hostp) {
+ dest_host = mail_host_dup(*hostp);
+ array_append(&dest->hosts, &dest_host, 1);
+ }
+ mail_hosts_sort(dest);
+ return dest;
+}
struct mail_host_list *mail_hosts_init(void);
void mail_hosts_deinit(struct mail_host_list **list);
+struct mail_host_list *mail_hosts_dup(const struct mail_host_list *src);
+
#endif
if (mail_hosts_parse_and_add(director->mail_hosts,
set->director_mail_servers) < 0)
i_fatal("Invalid value for director_mail_servers setting");
+ director->orig_config_hosts = mail_hosts_dup(director->mail_hosts);
director_connect(director);
}
static void
cmd_director_status_user(struct director_context *ctx, const char *user)
{
- const char *line;
+ const char *line, *const *args;
+ unsigned int expires;
director_send(ctx, t_strdup_printf("USER-LOOKUP\t%s\n", user));
line = i_stream_read_next_line(ctx->input);
return;
}
- if (strcmp(line, "NOTFOUND") == 0)
- printf("User not assigned to any server\n");
- else
- printf("%s\n", line);
+ args = t_strsplit(line, "\t");
+ if (str_array_length(args) != 4 ||
+ str_to_uint(args[1], &expires) < 0) {
+ printf("Invalid reply from director\n");
+ return;
+ }
+
+ if (args[0][0] != '\0') {
+ printf("Current: %s (expires %s)\n",
+ args[0], unixdate2str(expires));
+ } else {
+ printf("Current: not assigned\n");
+ }
+ printf("Hashed: %s\n", args[2]);
+ printf("Initial config: %s\n", args[3]);
director_disconnect(ctx);
}