/* Copyright (c) 2009-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "md5.h"
#include "hash.h"
#include "str.h"
#include "strescape.h"
#include "net.h"
#include "istream.h"
#include "write-full.h"
#include "master-service.h"
#include "auth-master.h"
#include "mail-user-hash.h"
#include "doveadm.h"
#include "doveadm-print.h"
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
struct director_context {
const char *socket_path;
const char *users_path;
const char *tag;
const char *user;
const char *host;
const char *ip;
const char *port;
const char *vhost_count;
const char *passdb_field;
bool explicit_socket_path;
};
struct user_list {
const char *name;
};
static void director_cmd_help(const struct doveadm_cmd_ver2 *);
unsigned int *ips_count_r) ATTR_WARN_UNUSED_RESULT;
static void
{
}
{
const char *line;
int fd;
alarm(5);
alarm(0);
} else {
i_fatal("read(%s) timed out (is director configured?)",
ctx->socket_path);
}
}
"%s not a compatible director-doveadm socket",
ctx->socket_path);
}
}
{
}
}
}
static struct director_context *
{
"/director-admin", NULL);
else
ctx->max_parallel = 0;
return ctx;
}
{
} else {
}
}
static void
{
return;
}
i_error("Invalid reply from director");
return;
}
doveadm_print_header_simple("status");
doveadm_print_header_simple("expires");
doveadm_print_header_simple("hashed");
doveadm_print_header_simple("initial-config");
doveadm_print_formatted_set_format("Current: %{status} (expires %{expires})\n" \
"Hashed: %{hashed}\n" \
"Initial config: %{initial-config}\n");
if (args[0][0] != '\0') {
doveadm_print(args[0]);
} else {
doveadm_print("n/a");
doveadm_print("-1");
}
}
{
return;
}
doveadm_print_header_simple("mail server ip");
doveadm_print_header_simple("tag");
doveadm_print_header_simple("vhosts");
doveadm_print_header_simple("state");
doveadm_print_header_simple("users");
if (*line == '\0')
break;
T_BEGIN {
unsigned int arg_count;
if (arg_count >= 6) {
/* ip vhosts users tag updown updown-ts */
doveadm_print(args[0]);
ts <= 0)
doveadm_print("-");
else
}
} T_END;
}
}
{
const char *error;
i_error("Failed to expand director_username_hash=%s: %s",
return FALSE;
}
return TRUE;
}
static void
{
unsigned int user_hash;
return;
}
static void ATTR_NULL(1)
{
const char *username;
if (auth_socket_path == NULL) {
"/auth-userdb", NULL);
}
if (auth_master_user_list_deinit(&ctx) < 0) {
i_error("user listing failed");
}
}
static void
{
const char *username;
}
unsigned int *ips_count_r)
{
int ret = 0;
*ips_count_r = 1;
} else {
if (ret != 0) {
return ret;
}
}
return ret;
}
{
unsigned int i;
for (i = 0; i < ips_count; i++) {
return TRUE;
}
return FALSE;
}
{
return;
}
/* user -> hash mapping */
}
return;
}
ips_count = 0;
return;
}
else
/* hash -> usernames mapping */
goto deinit;
}
doveadm_print_header_simple("hash");
doveadm_print_header_simple("mail server ip");
doveadm_print_header_simple("expire time");
if (ips_count != 1)
else {
}
if (*line == '\0')
break;
T_BEGIN {
} else if (ips_count == 0 ||
doveadm_print("<unknown>");
doveadm_print(args[0]);
}
doveadm_print(args[0]);
}
}
} T_END;
}
pool_unref(&pool);
}
static void
{
return;
}
return;
}
} else if (update) {
return;
}
/* host is a number. this would translate to an IP address,
which is probably a mistake. */
return;
}
}
return;
}
for (i = 0; i < ips_count; i++) {
str_truncate(cmd, 0);
if (vhost_count != UINT_MAX)
}
for (i = 0; i < ips_count; i++) {
"doesn't exist" : line);
} else if (doveadm_verbose) {
}
}
}
{
}
{
}
static void
struct doveadm_cmd_context *cctx)
{
unsigned int i, ips_count;
return;
}
return;
}
for (i = 0; i < ips_count; i++) {
}
for (i = 0; i < ips_count; i++) {
i_error("%s: doesn't exist\n",
net_ip2addr(&ips[i]));
if (doveadm_exit_code == 0)
} else if (doveadm_verbose) {
}
}
}
{
}
{
}
{
}
{
return;
}
return;
}
if (doveadm_verbose)
i_error("User is already being moved, "
"wait a while for it to be finished");
} else {
}
}
{
const char *line;
return;
}
} else {
}
if (doveadm_verbose)
} else {
}
}
{
const char *line;
if (ctx->force_flush)
line = "HOST-FLUSH\n";
else if (ctx->max_parallel > 0) {
(long long)ctx->max_parallel);
} else {
line = "HOST-RESET-USERS\n";
}
} else if (doveadm_verbose)
i_info("flushed");
}
{
unsigned int i, ips_count;
const char *line;
return;
}
return;
}
ips_count = 1;
return;
}
for (i = 0; i < ips_count; i++) {
str_truncate(cmd, 0);
if (ctx->force_flush)
else {
if (ctx->max_parallel > 0) {
(long long)ctx->max_parallel);
}
}
}
for (i = 0; i < ips_count; i++) {
i_warning("%s: doesn't exist",
net_ip2addr(&ips[i]));
if (doveadm_exit_code == 0)
} else if (doveadm_verbose) {
}
}
}
{
if (ctx->explicit_socket_path)
doveadm_print_formatted_set_format("doveadm director %{command} -a %{socket-path} %{host} %{vhost_count}\n");
else
doveadm_print_formatted_set_format("doveadm director %{command} %{host} %{vhost_count}\n");
doveadm_print_header_simple("command");
doveadm_print_header_simple("socket-path");
doveadm_print_header_simple("host");
doveadm_print_header_simple("vhost_count");
if (*line == '\0')
break;
T_BEGIN {
/* this is guaranteed to be at least NULL */
*tag != '\0')
tag);
doveadm_print("add");
}
} T_END;
}
if (*line == '\0')
break;
doveadm_print("remove");
doveadm_print("");
}
}
{
const char *line;
i_error("Not found");
}
}
{
return;
}
if (port != 0)
}
{
return;
}
if (port != 0)
}
{
doveadm_print_header_simple("director ip");
doveadm_print_header_simple("port");
doveadm_print_header_simple("type");
doveadm_print_header_simple("last failed");
doveadm_print_header_simple("status");
doveadm_print_header_simple("ping ms");
doveadm_print_header_simple("input");
doveadm_print_header_simple("output");
doveadm_print_header_simple("buffered");
doveadm_print_header_simple("buffered peak");
doveadm_print_header_simple("last read");
doveadm_print_header_simple("last write");
if (*line == '\0')
break;
T_BEGIN {
unsigned int i;
if ((i == 3 || i == 10 || i == 11) &&
if (ts == 0)
doveadm_print("never");
else
} else {
doveadm_print(args[i]);
}
}
for (; i < 12; i++)
doveadm_print("-");
} T_END;
}
}
{
.name = "director status",
.usage = "[-a <director socket path>] [<user>] [<tag>]",
},
{
.name = "director map",
.cmd = cmd_director_map,
.usage = "[-a <director socket path>] [-f <users file>] [-h | -u] [<host>]",
},
{
.name = "director add",
.cmd = cmd_director_add,
.usage = "[-a <director socket path>] [-t <tag>] <host> [<vhost count>]",
},
{
.name = "director update",
.usage = "[-a <director socket path>] <host> <vhost count>",
},
{
.name = "director up",
.cmd = cmd_director_up,
.usage = "[-a <director socket path>] <host>",
},
{
.name = "director down",
.cmd = cmd_director_down,
.usage = "[-a <director socket path>] <host>",
},
{
.name = "director remove",
.usage = "[-a <director socket path>] <host>",
},
{
.name = "director move",
.cmd = cmd_director_move,
.usage = "[-a <director socket path>] <user> <host>",
},
{
.name = "director kick",
.cmd = cmd_director_kick,
.usage = "[-a <director socket path>] [-f <passdb field>] <user>",
},
{
.name = "director flush",
.usage = "[-a <director socket path>] [-F] [--max-parallel <n>] <host>|all",
},
{
.name = "director dump",
.cmd = cmd_director_dump,
.usage = "[-a <director socket path>]",
},
{
.name = "director ring add",
.usage = "[-a <director socket path>] <ip> [<port>]",
},
{
.name = "director ring remove",
.usage = "[-a <director socket path>] <ip> [<port>]",
},
{
.name = "director ring status",
.usage = "[-a <director socket path>]",
}
};
{
unsigned int i;
for (i = 0; i < N_ELEMENTS(doveadm_cmd_director); i++) {
}
i_unreached();
}
void doveadm_register_director_commands(void)
{
unsigned int i;
for (i = 0; i < N_ELEMENTS(doveadm_cmd_director); i++)
}