doveadm-dsync.c (dovecot-2.3.16) | : | doveadm-dsync.c (dovecot-2.3.17) | ||
---|---|---|---|---|
skipping to change at line 222 | skipping to change at line 222 | |||
t_array_init(&cmd_args, 16); | t_array_init(&cmd_args, 16); | |||
for (i = 0; argv[i] != NULL; i++) { | for (i = 0; argv[i] != NULL; i++) { | |||
p = argv[i]; | p = argv[i]; | |||
array_push_back(&cmd_args, &p); | array_push_back(&cmd_args, &p); | |||
} | } | |||
if (legacy_dsync) { | if (legacy_dsync) { | |||
/* we're executing dsync */ | /* we're executing dsync */ | |||
p = "server"; | p = "server"; | |||
} else if (i > 0 && strcmp(argv[i-1], "dsync-server") == 0) { | ||||
/* Caller already specified dsync-server in parameters. | ||||
This is a common misconfiguration, so just allow it. */ | ||||
p = NULL; | ||||
} else { | } else { | |||
/* we're executing doveadm */ | /* we're executing doveadm */ | |||
p = "dsync-server"; | p = "dsync-server"; | |||
} | } | |||
array_push_back(&cmd_args, &p); | if (p != NULL) | |||
array_push_back(&cmd_args, &p); | ||||
array_append_zero(&cmd_args); | array_append_zero(&cmd_args); | |||
*cmd_args_r = array_front(&cmd_args); | *cmd_args_r = array_front(&cmd_args); | |||
} | } | |||
static const char *const * | static const char *const * | |||
get_ssh_cmd_args(const char *host, const char *login, const char *mail_user) | get_ssh_cmd_args(const char *host, const char *login, const char *mail_user) | |||
{ | { | |||
static struct var_expand_table static_tab[] = { | static struct var_expand_table static_tab[] = { | |||
{ 'u', NULL, "user" }, | { 'u', NULL, "user" }, | |||
{ '\0', NULL, "login" }, | { '\0', NULL, "login" }, | |||
skipping to change at line 810 | skipping to change at line 815 | |||
ctx->error = p_strdup_printf(ctx->ctx.pool, | ctx->error = p_strdup_printf(ctx->ctx.pool, | |||
"Failed to start remote dsync-server command: " | "Failed to start remote dsync-server command: " | |||
"Remote exit_code=%u %s", | "Remote exit_code=%u %s", | |||
exit_code, error == NULL ? "" : error); | exit_code, error == NULL ? "" : error); | |||
break; | break; | |||
} | } | |||
io_loop_stop(current_ioloop); | io_loop_stop(current_ioloop); | |||
} | } | |||
static int dsync_init_ssl_ctx(struct dsync_cmd_context *ctx, | static int dsync_init_ssl_ctx(struct dsync_cmd_context *ctx, | |||
const struct mail_storage_settings *mail_set, | const struct master_service_ssl_settings *ssl_set, | |||
const char **error_r) | const char **error_r) | |||
{ | { | |||
struct ssl_iostream_settings ssl_set; | struct ssl_iostream_settings ssl_ctx_set; | |||
if (ctx->ssl_ctx != NULL) | if (ctx->ssl_ctx != NULL) | |||
return 0; | return 0; | |||
mail_storage_settings_init_ssl_client_settings(mail_set, &ssl_set); | master_service_ssl_client_settings_to_iostream_set(ssl_set, | |||
pool_datastack_create(), &ssl_ctx_set); | ||||
return ssl_iostream_client_context_cache_get(&ssl_set, &ctx->ssl_ctx, err | return ssl_iostream_client_context_cache_get(&ssl_ctx_set, | |||
or_r); | &ctx->ssl_ctx, error_r); | |||
} | } | |||
static void dsync_server_run_command(struct dsync_cmd_context *ctx, | static void dsync_server_run_command(struct dsync_cmd_context *ctx, | |||
struct server_connection *conn) | struct server_connection *conn) | |||
{ | { | |||
struct doveadm_cmd_context *cctx = ctx->ctx.cctx; | struct doveadm_cmd_context *cctx = ctx->ctx.cctx; | |||
/* <flags> <username> <command> [<args>] */ | /* <flags> <username> <command> [<args>] */ | |||
string_t *cmd = t_str_new(256); | string_t *cmd = t_str_new(256); | |||
if (doveadm_debug) | if (doveadm_debug) | |||
str_append_c(cmd, 'D'); | str_append_c(cmd, 'D'); | |||
skipping to change at line 848 | skipping to change at line 854 | |||
ctx->tcp_conn = conn; | ctx->tcp_conn = conn; | |||
server_connection_cmd(conn, str_c(cmd), NULL, | server_connection_cmd(conn, str_c(cmd), NULL, | |||
dsync_connected_callback, ctx); | dsync_connected_callback, ctx); | |||
io_loop_run(current_ioloop); | io_loop_run(current_ioloop); | |||
ctx->tcp_conn = NULL; | ctx->tcp_conn = NULL; | |||
} | } | |||
static int | static int | |||
dsync_connect_tcp(struct dsync_cmd_context *ctx, | dsync_connect_tcp(struct dsync_cmd_context *ctx, | |||
const struct mail_storage_settings *mail_set, | const struct master_service_ssl_settings *ssl_set, | |||
const char *target, bool ssl, const char **error_r) | const char *target, bool ssl, const char **error_r) | |||
{ | { | |||
struct doveadm_server *server; | struct doveadm_server *server; | |||
struct server_connection *conn; | struct server_connection *conn; | |||
struct ioloop *prev_ioloop, *ioloop; | struct ioloop *prev_ioloop, *ioloop; | |||
const char *p, *error; | const char *p, *error; | |||
server = p_new(ctx->ctx.pool, struct doveadm_server, 1); | server = p_new(ctx->ctx.pool, struct doveadm_server, 1); | |||
server->name = p_strdup(ctx->ctx.pool, target); | server->name = p_strdup(ctx->ctx.pool, target); | |||
p = strrchr(server->name, ':'); | p = strrchr(server->name, ':'); | |||
server->hostname = p == NULL ? server->name : | server->hostname = p == NULL ? server->name : | |||
p_strdup_until(ctx->ctx.pool, server->name, p); | p_strdup_until(ctx->ctx.pool, server->name, p); | |||
if (ssl) { | if (ssl) { | |||
if (dsync_init_ssl_ctx(ctx, mail_set, &error) < 0) { | if (dsync_init_ssl_ctx(ctx, ssl_set, &error) < 0) { | |||
*error_r = t_strdup_printf( | *error_r = t_strdup_printf( | |||
"Couldn't initialize SSL context: %s", error); | "Couldn't initialize SSL context: %s", error); | |||
return -1; | return -1; | |||
} | } | |||
server->ssl_flags = PROXY_SSL_FLAG_YES; | server->ssl_flags = PROXY_SSL_FLAG_YES; | |||
server->ssl_ctx = ctx->ssl_ctx; | server->ssl_ctx = ctx->ssl_ctx; | |||
} | } | |||
p_array_init(&server->connections, ctx->ctx.pool, 1); | p_array_init(&server->connections, ctx->ctx.pool, 1); | |||
p_array_init(&server->queue, ctx->ctx.pool, 1); | p_array_init(&server->queue, ctx->ctx.pool, 1); | |||
skipping to change at line 900 | skipping to change at line 906 | |||
dsync_server_run_command(ctx, conn); | dsync_server_run_command(ctx, conn); | |||
} | } | |||
if (array_count(&server->connections) > 0) | if (array_count(&server->connections) > 0) | |||
server_connection_destroy(&conn); | server_connection_destroy(&conn); | |||
dsync_cmd_switch_ioloop_to(ctx, prev_ioloop); | dsync_cmd_switch_ioloop_to(ctx, prev_ioloop); | |||
io_loop_destroy(&ioloop); | io_loop_destroy(&ioloop); | |||
if (ctx->error != NULL) { | if (ctx->error != NULL) { | |||
ssl_iostream_context_unref(&ctx->ssl_ctx); | ||||
*error_r = ctx->error; | *error_r = ctx->error; | |||
ctx->error = NULL; | ctx->error = NULL; | |||
return -1; | return -1; | |||
} | } | |||
ctx->run_type = DSYNC_RUN_TYPE_STREAM; | ctx->run_type = DSYNC_RUN_TYPE_STREAM; | |||
return 0; | return 0; | |||
} | } | |||
static int | static int | |||
parse_location(struct dsync_cmd_context *ctx, | parse_location(struct dsync_cmd_context *ctx, | |||
const struct mail_storage_settings *mail_set, | const struct master_service_ssl_settings *ssl_set, | |||
const char *location, | const char *location, | |||
const char *const **remote_cmd_args_r, const char **error_r) | const char *const **remote_cmd_args_r, const char **error_r) | |||
{ | { | |||
struct doveadm_cmd_context *cctx = ctx->ctx.cctx; | struct doveadm_cmd_context *cctx = ctx->ctx.cctx; | |||
if (str_begins(location, "tcp:")) { | if (str_begins(location, "tcp:")) { | |||
/* TCP connection to remote dsync */ | /* TCP connection to remote dsync */ | |||
ctx->remote_name = location+4; | ctx->remote_name = location+4; | |||
return dsync_connect_tcp(ctx, mail_set, ctx->remote_name, | return dsync_connect_tcp(ctx, ssl_set, ctx->remote_name, | |||
FALSE, error_r); | FALSE, error_r); | |||
} | } | |||
if (str_begins(location, "tcps:")) { | if (str_begins(location, "tcps:")) { | |||
/* TCP+SSL connection to remote dsync */ | /* TCP+SSL connection to remote dsync */ | |||
ctx->remote_name = location+5; | ctx->remote_name = location+5; | |||
return dsync_connect_tcp(ctx, mail_set, ctx->remote_name, | return dsync_connect_tcp(ctx, ssl_set, ctx->remote_name, | |||
TRUE, error_r); | TRUE, error_r); | |||
} | } | |||
if (str_begins(location, "remote:")) { | if (str_begins(location, "remote:")) { | |||
/* this is a remote (ssh) command */ | /* this is a remote (ssh) command */ | |||
ctx->remote_name = location+7; | ctx->remote_name = location+7; | |||
} else if (str_begins(location, "remoteprefix:")) { | } else if (str_begins(location, "remoteprefix:")) { | |||
/* this is a remote (ssh) command with a "user\n" | /* this is a remote (ssh) command with a "user\n" | |||
prefix sent before dsync actually starts */ | prefix sent before dsync actually starts */ | |||
ctx->remote_name = location+13; | ctx->remote_name = location+13; | |||
skipping to change at line 955 | skipping to change at line 962 | |||
} | } | |||
static int cmd_dsync_prerun(struct doveadm_mail_cmd_context *_ctx, | static int cmd_dsync_prerun(struct doveadm_mail_cmd_context *_ctx, | |||
struct mail_storage_service_user *service_user, | struct mail_storage_service_user *service_user, | |||
const char **error_r) | const char **error_r) | |||
{ | { | |||
struct dsync_cmd_context *ctx = (struct dsync_cmd_context *)_ctx; | struct dsync_cmd_context *ctx = (struct dsync_cmd_context *)_ctx; | |||
struct doveadm_cmd_context *cctx = _ctx->cctx; | struct doveadm_cmd_context *cctx = _ctx->cctx; | |||
const char *const *remote_cmd_args = NULL; | const char *const *remote_cmd_args = NULL; | |||
const struct mail_user_settings *user_set; | const struct mail_user_settings *user_set; | |||
const struct mail_storage_settings *mail_set; | const struct master_service_ssl_settings *ssl_set; | |||
const char *username = ""; | const char *username = ""; | |||
user_set = mail_storage_service_user_get_set(service_user)[0]; | user_set = mail_storage_service_user_get_set(service_user)[0]; | |||
mail_set = mail_storage_service_user_get_mail_set(service_user); | ssl_set = mail_storage_service_user_get_ssl_settings(service_user); | |||
ctx->fd_in = -1; | ctx->fd_in = -1; | |||
ctx->fd_out = -1; | ctx->fd_out = -1; | |||
ctx->fd_err = -1; | ctx->fd_err = -1; | |||
ctx->run_type = DSYNC_RUN_TYPE_LOCAL; | ctx->run_type = DSYNC_RUN_TYPE_LOCAL; | |||
ctx->remote_name = "remote"; | ctx->remote_name = "remote"; | |||
if (ctx->default_replica_location) { | if (ctx->default_replica_location) { | |||
ctx->local_location = | ctx->local_location = | |||
mail_user_set_plugin_getenv(user_set, "mail_replica"); | mail_user_set_plugin_getenv(user_set, "mail_replica"); | |||
skipping to change at line 992 | skipping to change at line 999 | |||
if (!mirror_get_remote_cmd(ctx, username, &remote_cmd_args)) { | if (!mirror_get_remote_cmd(ctx, username, &remote_cmd_args)) { | |||
/* it's a mail_location */ | /* it's a mail_location */ | |||
if (_ctx->args[1] != NULL) | if (_ctx->args[1] != NULL) | |||
doveadm_mail_help_name(_ctx->cmd->name); | doveadm_mail_help_name(_ctx->cmd->name); | |||
ctx->local_location = _ctx->args[0]; | ctx->local_location = _ctx->args[0]; | |||
ctx->local_location_from_arg = TRUE; | ctx->local_location_from_arg = TRUE; | |||
} | } | |||
} | } | |||
if (remote_cmd_args == NULL && ctx->local_location != NULL) { | if (remote_cmd_args == NULL && ctx->local_location != NULL) { | |||
if (parse_location(ctx, mail_set, ctx->local_location, | if (parse_location(ctx, ssl_set, ctx->local_location, | |||
&remote_cmd_args, error_r) < 0) | &remote_cmd_args, error_r) < 0) | |||
return -1; | return -1; | |||
} | } | |||
if (remote_cmd_args != NULL) { | if (remote_cmd_args != NULL) { | |||
/* do this before mail_storage_service_next() in case it | /* do this before mail_storage_service_next() in case it | |||
drops process privileges */ | drops process privileges */ | |||
run_cmd(ctx, remote_cmd_args); | run_cmd(ctx, remote_cmd_args); | |||
ctx->run_type = DSYNC_RUN_TYPE_CMD; | ctx->run_type = DSYNC_RUN_TYPE_CMD; | |||
} | } | |||
skipping to change at line 1301 | skipping to change at line 1308 | |||
ctx->ctx.getopt_args = "Er:T:U"; | ctx->ctx.getopt_args = "Er:T:U"; | |||
ctx->ctx.v.parse_arg = cmd_mailbox_dsync_server_parse_arg; | ctx->ctx.v.parse_arg = cmd_mailbox_dsync_server_parse_arg; | |||
ctx->ctx.v.run = cmd_dsync_server_run; | ctx->ctx.v.run = cmd_dsync_server_run; | |||
ctx->sync_type = DSYNC_BRAIN_SYNC_TYPE_CHANGED; | ctx->sync_type = DSYNC_BRAIN_SYNC_TYPE_CHANGED; | |||
ctx->fd_in = STDIN_FILENO; | ctx->fd_in = STDIN_FILENO; | |||
ctx->fd_out = STDOUT_FILENO; | ctx->fd_out = STDOUT_FILENO; | |||
return &ctx->ctx; | return &ctx->ctx; | |||
} | } | |||
struct doveadm_mail_cmd cmd_dsync_mirror = { | #define DSYNC_COMMON_PARAMS \ | |||
cmd_dsync_alloc, "sync", | DOVEADM_CMD_MAIL_COMMON \ | |||
"[-1fPRU] [-l <secs>] [-r <rawlog path>] [-m <mailbox>] [-g <mailbox_guid | DOVEADM_CMD_PARAM('f', "full-sync", CMD_PARAM_BOOL, 0) \ | |||
>] [-n <namespace> | -N] [-x <exclude>] [-s <state>] [-t <start date>] -d|<dest> | DOVEADM_CMD_PARAM('P', "purge-remote", CMD_PARAM_BOOL, 0) \ | |||
" | DOVEADM_CMD_PARAM('R', "reverse-sync", CMD_PARAM_BOOL, 0) \ | |||
DOVEADM_CMD_PARAM('U', "replicator-notify", CMD_PARAM_BOOL, 0) \ | ||||
DOVEADM_CMD_PARAM('l', "lock-timeout", CMD_PARAM_INT64, 0) \ | ||||
DOVEADM_CMD_PARAM('r', "rawlog", CMD_PARAM_STR, 0) \ | ||||
DOVEADM_CMD_PARAM('m', "mailbox", CMD_PARAM_STR, 0) \ | ||||
DOVEADM_CMD_PARAM('g', "mailbox-guid", CMD_PARAM_STR, 0) \ | ||||
DOVEADM_CMD_PARAM('n', "namespace", CMD_PARAM_ARRAY, 0) \ | ||||
DOVEADM_CMD_PARAM('N', "all-namespaces", CMD_PARAM_BOOL, 0) \ | ||||
DOVEADM_CMD_PARAM('x', "exclude-mailbox", CMD_PARAM_ARRAY, 0) \ | ||||
DOVEADM_CMD_PARAM('s', "state", CMD_PARAM_STR, 0) \ | ||||
DOVEADM_CMD_PARAM('t', "sync-since-time", CMD_PARAM_STR, 0) \ | ||||
DOVEADM_CMD_PARAM('d', "default-destination", CMD_PARAM_BOOL, 0) \ | ||||
DOVEADM_CMD_PARAM('\0', "destination", CMD_PARAM_ARRAY, CMD_PARAM_FLAG_POSITIONA | ||||
L) | ||||
struct doveadm_cmd_ver2 doveadm_cmd_dsync_mirror = { | ||||
.mail_cmd = cmd_dsync_alloc, | ||||
.name = "sync", | ||||
.usage = "[-1fPRU] [-l <secs>] [-r <rawlog path>] [-m <mailbox>] [-g <mai | ||||
lbox_guid>] [-n <namespace> | -N] [-x <exclude>] [-s <state>] [-t <start date>] | ||||
-d|<dest>", | ||||
.flags = CMD_FLAG_NO_UNORDERED_OPTIONS, | ||||
DOVEADM_CMD_PARAMS_START | ||||
DSYNC_COMMON_PARAMS | ||||
DOVEADM_CMD_PARAM('1', "oneway-sync", CMD_PARAM_BOOL, 0) | ||||
DOVEADM_CMD_PARAMS_END | ||||
}; | }; | |||
struct doveadm_mail_cmd cmd_dsync_backup = { | struct doveadm_cmd_ver2 doveadm_cmd_dsync_backup = { | |||
cmd_dsync_backup_alloc, "backup", | .mail_cmd = cmd_dsync_backup_alloc, | |||
"[-fPRU] [-l <secs>] [-r <rawlog path>] [-m <mailbox>] [-g <mailbox_guid> | .name = "backup", | |||
] [-n <namespace> | -N] [-x <exclude>] [-s <state>] [-t <start date>] -d|<dest>" | .usage = "[-fPRU] [-l <secs>] [-r <rawlog path>] [-m <mailbox>] [-g <mail | |||
box_guid>] [-n <namespace> | -N] [-x <exclude>] [-s <state>] [-t <start date>] - | ||||
d|<dest>", | ||||
.flags = CMD_FLAG_NO_UNORDERED_OPTIONS, | ||||
DOVEADM_CMD_PARAMS_START | ||||
DSYNC_COMMON_PARAMS | ||||
DOVEADM_CMD_PARAMS_END | ||||
}; | }; | |||
struct doveadm_mail_cmd cmd_dsync_server = { | struct doveadm_cmd_ver2 doveadm_cmd_dsync_server = { | |||
cmd_dsync_server_alloc, "dsync-server", &doveadm_mail_cmd_hide | .mail_cmd = cmd_dsync_server_alloc, | |||
.name = "dsync-server", | ||||
.usage = "[-E] [-r <rawlog path>] [-T <timeout secs>] [-U]", | ||||
DOVEADM_CMD_PARAMS_START | ||||
DOVEADM_CMD_MAIL_COMMON | ||||
DOVEADM_CMD_PARAM('E', "legacy-dsync", CMD_PARAM_BOOL, 0) | ||||
DOVEADM_CMD_PARAM('r', "rawlog", CMD_PARAM_STR, 0) | ||||
DOVEADM_CMD_PARAM('T', "timeout", CMD_PARAM_INT64, 0) | ||||
DOVEADM_CMD_PARAM('U', "replicator-notify", CMD_PARAM_BOOL, 0) | ||||
/* previously dsync-server could have been added twice to the parameters */ | ||||
DOVEADM_CMD_PARAM('\0', "ignore-arg", CMD_PARAM_STR, CMD_PARAM_FLAG_POSITIONAL) | ||||
DOVEADM_CMD_PARAMS_END | ||||
}; | }; | |||
void doveadm_dsync_main(int *_argc, char **_argv[]) | void doveadm_dsync_main(int *_argc, char **_argv[]) | |||
{ | { | |||
int argc = *_argc; | int argc = *_argc; | |||
const char *getopt_str; | const char *getopt_str; | |||
char **argv = *_argv; | char **argv = *_argv; | |||
char **new_argv, *mailbox = NULL, *alt_char = NULL, *username = NULL; | char **new_argv, *mailbox = NULL, *alt_char = NULL, *username = NULL; | |||
char *p, *dup, new_flags[6]; | char *p, *dup, new_flags[6]; | |||
int max_argc, src, dest, i, j; | int max_argc, src, dest, i, j; | |||
End of changes. 17 change blocks. | ||||
26 lines changed or deleted | 74 lines changed or added |