bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2009-2018 Dovecot authors, see the included COPYING file */
a75d470c9223a75801418fcdda258885c36317e0Timo SirainenHASH_TABLE_DEFINE_TYPE(user_list, void *, struct user_list *);
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomistatic void director_cmd_help(const struct doveadm_cmd_ver2 *);
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomistatic int director_get_host(const char *host, struct ip_addr **ips_r,
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomi unsigned int *ips_count_r) ATTR_WARN_UNUSED_RESULT;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainendirector_send(struct director_context *ctx, const char *data)
8338066be35c696b59fa9aefdc07042cb0797197Timo Sirainen if (write_full(i_stream_get_fd(ctx->input), data, strlen(data)) < 0)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen i_fatal("write(%s) failed: %m", ctx->socket_path);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void director_connect(struct director_context *ctx)
f158d9a303bb15a6848ca276c9391c7ca52e452bTimo Sirainen#define DIRECTOR_HANDSHAKE "VERSION\tdirector-doveadm\t1\t0\n"
bace943c67e6cd14ce6c994f533d82a3caad5bf1Timo Sirainen ctx->input = i_stream_create_fd_autoclose(&fd, (size_t)-1);
0f3d4fbcf88e2ffd674893aed8cc1288fe17d290Timo Sirainen i_fatal("read(%s) failed: %s", ctx->socket_path,
224414073c72d77a09a77b4dd71500ada5690802Timo Sirainen i_fatal("read(%s) timed out (is director configured?)",
f158d9a303bb15a6848ca276c9391c7ca52e452bTimo Sirainen if (!version_string_verify(line, "director-doveadm", 1)) {
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen "%s not a compatible director-doveadm socket",
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenstatic void director_disconnect(struct director_context *ctx)
0f3d4fbcf88e2ffd674893aed8cc1288fe17d290Timo Sirainen i_fatal("read(%s) failed: %s", ctx->socket_path,
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomicmd_director_init(struct doveadm_cmd_context *cctx)
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomi if (!doveadm_cmd_param_str(cctx, "socket-path", &(ctx->socket_path)))
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomi ctx->socket_path = t_strconcat(doveadm_settings->base_dir,
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomi if (!doveadm_cmd_param_bool(cctx, "user-map", &(ctx->user_map)))
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomi if (!doveadm_cmd_param_bool(cctx, "hash-map", &(ctx->hash_map)))
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomi if (!doveadm_cmd_param_bool(cctx, "force-flush", &(ctx->force_flush)))
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomi if (!doveadm_cmd_param_istream(cctx, "users-file", &(ctx->users_input)))
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomi if (!doveadm_cmd_param_str(cctx, "tag", &(ctx->tag)))
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomi if (!doveadm_cmd_param_str(cctx, "user", &(ctx->user)))
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomi if (!doveadm_cmd_param_str(cctx, "host", &(ctx->host)))
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomi if (!doveadm_cmd_param_str(cctx, "ip", &(ctx->ip)))
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomi if (!doveadm_cmd_param_str(cctx, "port", &(ctx->port)))
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomi if (!doveadm_cmd_param_str(cctx, "vhost-count", &(ctx->vhost_count)))
bfef6891565ff9018ac92add6eae401e9352c657Timo Sirainen if (!doveadm_cmd_param_str(cctx, "passdb-field", &(ctx->passdb_field)))
b79120aa36d1b7935c9aef8b0a7cf3f1045a36caTimo Sirainen if (!doveadm_cmd_param_int64(cctx, "max-parallel", &(ctx->max_parallel)))
c300d63f279be299ed07d749c4de7a3443278117Timo Sirainenstatic void director_disconnected(struct director_context *ctx)
c300d63f279be299ed07d749c4de7a3443278117Timo Sirainen i_error("read(%s) failed: %s", ctx->socket_path,
c300d63f279be299ed07d749c4de7a3443278117Timo Sirainen i_error("%s unexpectedly disconnected", ctx->socket_path);
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomicmd_director_status_user(struct director_context *ctx)
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomi director_send(ctx, t_strdup_printf("USER-LOOKUP\t%s\t%s\n", ctx->user,
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomi doveadm_print_formatted_set_format("Current: %{status} (expires %{expires})\n" \
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomi "Hashed: %{hashed}\n" \
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomi "Initial config: %{initial-config}\n");
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomistatic void cmd_director_status(struct doveadm_cmd_context *cctx)
68787d48554f497e711ff66a087ab31f990a11e9Timo Sirainen doveadm_print_header_simple("mail server ip");
a5ddfd7a8b473f73135b93d5e081e470a87f0f7eTimo Sirainen doveadm_print_header("state-changed", "state changed", 0);
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen while ((line = i_stream_read_next_line(ctx->input)) != NULL) {
a5ddfd7a8b473f73135b93d5e081e470a87f0f7eTimo Sirainen /* ip vhosts users tag updown updown-ts */
a5ddfd7a8b473f73135b93d5e081e470a87f0f7eTimo Sirainen doveadm_print(args[4][0] == 'D' ? "down" : "up");
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainenstatic bool user_hash_expand(const char *username, unsigned int *hash_r)
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen if (!mail_user_hash(username, doveadm_settings->director_username_hash,
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen i_error("Failed to expand director_username_hash=%s: %s",
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen doveadm_settings->director_username_hash, error);
678d0463849ba777106eb7875f27db07a5d8e3dfTimo Sirainenuser_list_add(const char *username, pool_t pool,
a75d470c9223a75801418fcdda258885c36317e0Timo Sirainen old_user = hash_table_lookup(users, POINTER_CAST(user_hash));
c224fff79d18480a65e9b4504b891b8ea176f5b1Timo Sirainen hash_table_update(users, POINTER_CAST(user_hash), user);
0591dbf3c6edb9ad502df0e57a0a458896e632a1Timo Sirainenuserdb_get_user_list(const char *auth_socket_path, pool_t pool,
caa1fa99c79c568ce2e42477bc169e7024fb220bTimo Sirainen auth_socket_path = t_strconcat(doveadm_settings->base_dir,
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainen ctx = auth_master_user_list_init(conn, "", NULL);
0591dbf3c6edb9ad502df0e57a0a458896e632a1Timo Sirainen while ((username = auth_master_user_list_next(ctx)) != NULL)
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomiuser_file_get_user_list(struct istream *input, pool_t pool,
0591dbf3c6edb9ad502df0e57a0a458896e632a1Timo Sirainen while ((username = i_stream_read_next_line(input)) != NULL)
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomistatic int director_get_host(const char *host, struct ip_addr **ips_r,
2ea9c5da50bbcb67de03c91ef4cf7778d1e57a22Timo Sirainen unsigned int *ips_count_r)
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen ret = net_gethostbyname(host, ips_r, ips_count_r);
2ea9c5da50bbcb67de03c91ef4cf7778d1e57a22Timo Sirainenstatic bool ip_find(const struct ip_addr *ips, unsigned int ips_count,
2ea9c5da50bbcb67de03c91ef4cf7778d1e57a22Timo Sirainen unsigned int i;
2ea9c5da50bbcb67de03c91ef4cf7778d1e57a22Timo Sirainen for (i = 0; i < ips_count; i++) {
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomistatic void cmd_director_map(struct doveadm_cmd_context *cctx)
0896246f4648151fe846215190ee92cefbcfb8b8Timo Sirainen if ((ctx->hash_map || ctx->user_map) && ctx->host == NULL) {
3957200d949c6e96c4184db2395444d723950583Timo Sirainen /* user -> hash mapping */
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen if (user_hash_expand(ctx->host, &user_hash)) {
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen doveadm_print_header("hash", "hash", DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen doveadm_print(t_strdup_printf("%u", user_hash));
ccf5e99d0285da8679dee6e0b68fa9ea99a4ddfaTimo Sirainen else if (director_get_host(ctx->host, &ips, &ips_count) != 0) {
caa1fa99c79c568ce2e42477bc169e7024fb220bTimo Sirainen pool = pool_alloconly_create("director map users", 1024*128);
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomi user_file_get_user_list(ctx->users_input, pool, users);
3957200d949c6e96c4184db2395444d723950583Timo Sirainen /* hash -> usernames mapping */
3957200d949c6e96c4184db2395444d723950583Timo Sirainen doveadm_print_header("user", "user", DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);
3957200d949c6e96c4184db2395444d723950583Timo Sirainen user = hash_table_lookup(users, POINTER_CAST(user_hash));
6176f3618240943f3cb41cb7063ecef56b1dd7dfTimo Sirainen doveadm_print_header("user", "user", DOVEADM_PRINT_HEADER_FLAG_EXPAND);
caa1fa99c79c568ce2e42477bc169e7024fb220bTimo Sirainen doveadm_print_header_simple("mail server ip");
caa1fa99c79c568ce2e42477bc169e7024fb220bTimo Sirainen while ((line = i_stream_read_next_line(ctx->input)) != NULL) {
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen } else if (ips_count == 0 ||
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomicmd_director_add_or_update(struct doveadm_cmd_context *cctx, bool update)
e307e0fcc31ab7b3d062f6ff4b7d48d8b1b2f7b8Timo Sirainen const char *director_cmd = update ? "HOST-UPDATE" : "HOST-SET";
8ae72ad7d0c69e972cfa65d1e2ce4e3e9a8b765cTimo Sirainen unsigned int i, ips_count, vhost_count = UINT_MAX;
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomi if (str_to_uint(ctx->vhost_count, &vhost_count) < 0) {
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomi } else if (update) {
521c0460fe705f32ea6899c8b1f101043fe0898cTimo Sirainen /* host is a number. this would translate to an IP address,
521c0460fe705f32ea6899c8b1f101043fe0898cTimo Sirainen which is probably a mistake. */
ccf5e99d0285da8679dee6e0b68fa9ea99a4ddfaTimo Sirainen if (director_get_host(host, &ips, &ips_count) != 0) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen for (i = 0; i < ips_count; i++) {
a4502a71879d6018bd2c64f13614bb619911dd9fTimo Sirainen str_printfa(cmd, "%s\t%s", director_cmd, net_ip2addr(&ips[i]));
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen for (i = 0; i < ips_count; i++) {
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomistatic void cmd_director_add(struct doveadm_cmd_context *cctx)
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomistatic void cmd_director_update(struct doveadm_cmd_context *cctx)
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomicmd_director_ipcmd(const char *cmd_name, const char *success_result,
ccf5e99d0285da8679dee6e0b68fa9ea99a4ddfaTimo Sirainen if (director_get_host(host, &ips, &ips_count) != 0) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen for (i = 0; i < ips_count; i++) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen for (i = 0; i < ips_count; i++) {
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen if (line != NULL && strcmp(line, "NOTFOUND") == 0) {
c300d63f279be299ed07d749c4de7a3443278117Timo Sirainen i_error("%s: %s\n", net_ip2addr(&ips[i]), line);
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomi i_info("%s: %s\n", net_ip2addr(&ips[i]), success_result);
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomistatic void cmd_director_remove(struct doveadm_cmd_context *cctx)
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomi cmd_director_ipcmd("HOST-REMOVE", "removed", cctx);
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomistatic void cmd_director_up(struct doveadm_cmd_context *cctx)
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomistatic void cmd_director_down(struct doveadm_cmd_context *cctx)
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomistatic void cmd_director_move(struct doveadm_cmd_context *cctx)
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen if (!user_hash_expand(ctx->user, &user_hash) ||
0f5dc4da3982053036be65190e44bf28a67b1ca2Timo Sirainen director_get_host(ctx->host, &ips, &ips_count) != 0) {
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomi i_info("User hash %u moved to %s\n", user_hash, ip_str);
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen "wait a while for it to be finished");
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomistatic void cmd_director_kick(struct doveadm_cmd_context *cctx)
bfef6891565ff9018ac92add6eae401e9352c657Timo Sirainen str_append_tabescaped(cmd, ctx->passdb_field);
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainenstatic void cmd_director_flush_all(struct director_context *ctx)
b79120aa36d1b7935c9aef8b0a7cf3f1045a36caTimo Sirainen line = t_strdup_printf("HOST-RESET-USERS\t\t%lld\n",
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomistatic void cmd_director_flush(struct doveadm_cmd_context *cctx)
ccf5e99d0285da8679dee6e0b68fa9ea99a4ddfaTimo Sirainen } else if (director_get_host(ctx->host, &ips, &ips_count) != 0) {
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen for (i = 0; i < ips_count; i++) {
b79120aa36d1b7935c9aef8b0a7cf3f1045a36caTimo Sirainen str_printfa(cmd, "HOST-FLUSH\t%s\n", net_ip2addr(&ip));
b79120aa36d1b7935c9aef8b0a7cf3f1045a36caTimo Sirainen str_printfa(cmd, "HOST-RESET-USERS\t%s", net_ip2addr(&ip));
5e9bb72de1209cd39fdf3e95bdb26e047cc5594eTimo Sirainen for (i = 0; i < ips_count; i++) {
5fbccc935e3f7b916aa7c6e302a212821072e83aTimo Sirainen if (line != NULL && strcmp(line, "NOTFOUND") == 0) {
c300d63f279be299ed07d749c4de7a3443278117Timo Sirainen i_warning("%s: %s", net_ip2addr(&ips[i]), line);
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomistatic void cmd_director_dump(struct doveadm_cmd_context *cctx)
3cbc0cb7c454ad5132dd335a7ae47bd6f5da2aa6Timo Sirainen doveadm_print_formatted_set_format("doveadm director %{command} -a %{socket-path} %{host} %{vhost_count}\n");
3cbc0cb7c454ad5132dd335a7ae47bd6f5da2aa6Timo Sirainen doveadm_print_formatted_set_format("doveadm director %{command} %{host} %{vhost_count}\n");
8b16d3b00f051401c97568697ccdbba48663759aTimo Sirainen while ((line = i_stream_read_next_line(ctx->input)) != NULL) {
a2532003186d63337e1cbf9ba8f8f7ec401dea58Aki Tuomi /* this is guaranteed to be at least NULL */
8b16d3b00f051401c97568697ccdbba48663759aTimo Sirainen while ((line = i_stream_read_next_line(ctx->input)) != NULL) {
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainenstatic void director_read_ok_reply(struct director_context *ctx)
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomistatic void cmd_director_ring_add(struct doveadm_cmd_context *cctx)
23bdbb7b1831785c6ba6df190f6369da882d2b9dTimo Sirainen (ctx->port != 0 && net_str2port(ctx->port, &port) < 0)) {
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen str_printfa(str, "DIRECTOR-ADD\t%s", net_ip2addr(&ip));
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomistatic void cmd_director_ring_remove(struct doveadm_cmd_context *cctx)
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomi (ctx->port != NULL && net_str2port(ctx->port, &port) < 0)) {
e4194f4703eeec32b432371ae30fc8f25ab720d8Timo Sirainen str_printfa(str, "DIRECTOR-REMOVE\t%s", net_ip2addr(&ip));
5d16ff58f96527093b49597e8d6168f833e0a52eAki Tuomistatic void cmd_director_ring_status(struct doveadm_cmd_context *cctx)
d3af9043837e4bf0e87a9150fedc9e94908e6f82Timo Sirainen while ((line = i_stream_read_next_line(ctx->input)) != NULL) {
cb3f509b91af4e9cb65ce7acbbba8a335494d6d6Timo Sirainen unsigned int i;
cb3f509b91af4e9cb65ce7acbbba8a335494d6d6Timo Sirainen for (; i < 12; i++)
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomi .usage = "[-a <director socket path>] [<user>] [<tag>]",
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('a', "socket-path", CMD_PARAM_STR, 0)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('\0', "user", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('\0', "tag", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomi .usage = "[-a <director socket path>] [-f <users file>] [-h | -u] [<host>]",
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('a', "socket-path", CMD_PARAM_STR, 0)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('f', "users-file", CMD_PARAM_ISTREAM, 0)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('h', "hash-map", CMD_PARAM_BOOL, 0)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('u', "user-map", CMD_PARAM_BOOL, 0)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('\0', "host", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomi .usage = "[-a <director socket path>] [-t <tag>] <host> [<vhost count>]",
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('a', "socket-path", CMD_PARAM_STR, 0)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('\0', "host", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('\0', "vhost-count", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomi .usage = "[-a <director socket path>] <host> <vhost count>",
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('a', "socket-path", CMD_PARAM_STR, 0)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('\0', "host", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('\0', "vhost-count", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('a', "socket-path", CMD_PARAM_STR, 0)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('\0', "host", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('a', "socket-path", CMD_PARAM_STR, 0)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('\0', "host", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('a', "socket-path", CMD_PARAM_STR, 0)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('\0', "host", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomi .usage = "[-a <director socket path>] <user> <host>",
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('a', "socket-path", CMD_PARAM_STR, 0)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('\0', "user", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('\0', "host", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
bfef6891565ff9018ac92add6eae401e9352c657Timo Sirainen .usage = "[-a <director socket path>] [-f <passdb field>] <user>",
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('a', "socket-path", CMD_PARAM_STR, 0)
44a31b74084a66492154dd03f349b73c8aa57c7dTimo SirainenDOVEADM_CMD_PARAM('f', "passdb-field", CMD_PARAM_STR, 0)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('\0', "user", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
b79120aa36d1b7935c9aef8b0a7cf3f1045a36caTimo Sirainen .usage = "[-a <director socket path>] [-F] [--max-parallel <n>] <host>|all",
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('a', "socket-path", CMD_PARAM_STR, 0)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('F', "force-flush", CMD_PARAM_BOOL, 0)
b79120aa36d1b7935c9aef8b0a7cf3f1045a36caTimo SirainenDOVEADM_CMD_PARAM('\0', "max-parallel", CMD_PARAM_INT64, 0)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('\0', "host", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('a', "socket-path", CMD_PARAM_STR, 0)
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomi .usage = "[-a <director socket path>] <ip> [<port>]",
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('a', "socket-path", CMD_PARAM_STR, 0)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('\0', "ip", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('\0', "port", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomi .usage = "[-a <director socket path>] <ip> [<port>]",
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('a', "socket-path", CMD_PARAM_STR, 0)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('\0', "ip", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('\0', "port", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL)
264a0f242067fb14df778d2fef181ad0045ad0eaAki TuomiDOVEADM_CMD_PARAM('a', "socket-path", CMD_PARAM_STR, 0)
264a0f242067fb14df778d2fef181ad0045ad0eaAki Tuomistatic void director_cmd_help(const struct doveadm_cmd_ver2 *cmd)
caa1fa99c79c568ce2e42477bc169e7024fb220bTimo Sirainen unsigned int i;
caa1fa99c79c568ce2e42477bc169e7024fb220bTimo Sirainen for (i = 0; i < N_ELEMENTS(doveadm_cmd_director); i++) {
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen unsigned int i;
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen for (i = 0; i < N_ELEMENTS(doveadm_cmd_director); i++)