"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/doveadm/client-connection-tcp.c" between
dovecot-2.3.16.tar.gz and dovecot-2.3.17.tar.gz

About: Dovecot is an IMAP and POP3 server, written with security primarily in mind.

client-connection-tcp.c  (dovecot-2.3.16):client-connection-tcp.c  (dovecot-2.3.17)
skipping to change at line 73 skipping to change at line 73
if (doveadm_client != NULL && if (doveadm_client != NULL &&
doveadm_client->type == DOVEADM_CONNECTION_TYPE_TCP) doveadm_client->type == DOVEADM_CONNECTION_TYPE_TCP)
conn = (struct client_connection_tcp *)doveadm_client; conn = (struct client_connection_tcp *)doveadm_client;
if (!log_recursing && conn != NULL && if (!log_recursing && conn != NULL &&
conn->log_out != NULL) T_BEGIN { conn->log_out != NULL) T_BEGIN {
struct ioloop *prev_ioloop = current_ioloop; struct ioloop *prev_ioloop = current_ioloop;
struct ostream *log_out = conn->log_out; struct ostream *log_out = conn->log_out;
char c; char c;
const char *ptr, *start; const char *ptr;
bool corked; bool corked;
va_list va; va_list va;
/* prevent re-entering this code if /* prevent re-entering this code if
any of the following code causes logging */ any of the following code causes logging */
log_recursing = TRUE; log_recursing = TRUE;
/* since we can get here from just about anywhere, make sure /* since we can get here from just about anywhere, make sure
the log ostream uses the connection's ioloop. */ the log ostream uses the connection's ioloop. */
if (conn->ioloop != NULL) if (conn->ioloop != NULL)
io_loop_set_current(conn->ioloop); io_loop_set_current(conn->ioloop);
const char *log_prefix =
ctx->log_prefix != NULL ? ctx->log_prefix :
i_get_failure_prefix();
size_t log_prefix_len = strlen(log_prefix);
c = doveadm_log_type_to_char(ctx->type); c = doveadm_log_type_to_char(ctx->type);
corked = o_stream_is_corked(log_out); corked = o_stream_is_corked(log_out);
va_copy(va, args); va_copy(va, args);
string_t *str = t_str_new(128); const char *str = t_strdup_vprintf(format, va);
str_vprintfa(str, format, va);
va_end(va); va_end(va);
start = str_c(str);
if (!corked) if (!corked)
o_stream_cork(log_out); o_stream_cork(log_out);
while((ptr = strchr(start, '\n'))!=NULL) { for (;;) {
o_stream_nsend(log_out, &c, 1); ptr = strchr(str, '\n');
o_stream_nsend(log_out, start, ptr-start+1); size_t len = ptr == NULL ? strlen(str) :
str_delete(str, 0, ptr-start+1); (size_t)(ptr - str);
}
if (str->used > 0) {
o_stream_nsend(log_out, &c, 1); o_stream_nsend(log_out, &c, 1);
o_stream_nsend(log_out, str->data, str->used); o_stream_nsend(log_out, log_prefix, log_prefix_len);
o_stream_nsend(log_out, str, len);
o_stream_nsend(log_out, "\n", 1); o_stream_nsend(log_out, "\n", 1);
if (ptr == NULL)
break;
str = ptr+1;
} }
o_stream_uncork(log_out); o_stream_uncork(log_out);
if (corked) if (corked)
o_stream_cork(log_out); o_stream_cork(log_out);
io_loop_set_current(prev_ioloop); io_loop_set_current(prev_ioloop);
log_recursing = FALSE; log_recursing = FALSE;
} T_END; } T_END;
switch(ctx->type) { switch(ctx->type) {
skipping to change at line 186 skipping to change at line 192
doveadm_cmd_server_run_ver2(struct client_connection_tcp *conn, doveadm_cmd_server_run_ver2(struct client_connection_tcp *conn,
int argc, const char *const argv[], int argc, const char *const argv[],
struct doveadm_cmd_context *cctx) struct doveadm_cmd_context *cctx)
{ {
i_getopt_reset(); i_getopt_reset();
if (doveadm_cmd_run_ver2(argc, argv, cctx) < 0) if (doveadm_cmd_run_ver2(argc, argv, cctx) < 0)
doveadm_exit_code = EX_USAGE; doveadm_exit_code = EX_USAGE;
doveadm_cmd_server_post(conn, cctx->cmd->name); doveadm_cmd_server_post(conn, cctx->cmd->name);
} }
static void
doveadm_cmd_server_run(struct client_connection_tcp *conn,
int argc, const char *const argv[],
const struct doveadm_cmd *cmd)
{
i_getopt_reset();
cmd->cmd(argc, (char **)argv);
doveadm_cmd_server_post(conn, cmd->name);
}
static int
doveadm_mail_cmd_server_parse(const struct doveadm_mail_cmd *cmd,
const struct doveadm_settings *set,
int argc, const char *const argv[],
struct doveadm_cmd_context *cctx,
struct doveadm_mail_cmd_context **mctx_r)
{
struct doveadm_mail_cmd_context *mctx;
const char *getopt_args;
bool add_username_header = FALSE;
int c;
mctx = doveadm_mail_cmd_init(cmd, set);
mctx->cctx = cctx;
mctx->full_args = argv+1;
mctx->proxying = TRUE;
mctx->service_flags |=
MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT |
MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP;
if (doveadm_debug)
mctx->service_flags |= MAIL_STORAGE_SERVICE_FLAG_DEBUG;
i_getopt_reset();
getopt_args = t_strconcat("AF:S:u:", mctx->getopt_args, NULL);
while ((c = getopt(argc, (char **)argv, getopt_args)) > 0) {
switch (c) {
case 'A':
case 'F':
add_username_header = TRUE;
break;
case 'S':
/* ignore */
break;
case 'u':
if (strchr(optarg, '*') != NULL ||
strchr(optarg, '?') != NULL)
add_username_header = TRUE;
break;
default:
if ((mctx->v.parse_arg == NULL ||
!mctx->v.parse_arg(mctx, c))) {
i_error("doveadm %s: "
"Client sent unknown parameter: %c",
cmd->name, c);
mctx->v.deinit(mctx);
pool_unref(&mctx->pool);
return -1;
}
}
}
if (argv[optind] != NULL && cmd->usage_args == NULL) {
i_error("doveadm %s: Client sent unknown parameter: %s",
cmd->name, argv[optind]);
mctx->v.deinit(mctx);
pool_unref(&mctx->pool);
return -1;
}
mctx->args = argv+optind;
if (cctx->username != NULL) {
if (strchr(cctx->username, '*') != NULL ||
strchr(cctx->username, '?') != NULL) {
add_username_header = TRUE;
}
}
if (doveadm_print_is_initialized() && add_username_header) {
doveadm_print_header("username", "Username",
DOVEADM_PRINT_HEADER_FLAG_STICKY |
DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE);
doveadm_print_sticky("username", cctx->username);
}
*mctx_r = mctx;
return 0;
}
static void
doveadm_mail_cmd_server_run(struct client_connection_tcp *conn,
struct doveadm_mail_cmd_context *mctx)
{
const char *error;
int ret;
o_stream_cork(conn->output);
if (mctx->v.preinit != NULL)
mctx->v.preinit(mctx);
ret = doveadm_mail_single_user(mctx, &error);
doveadm_mail_server_flush();
mctx->v.deinit(mctx);
doveadm_print_flush();
mail_storage_service_deinit(&mctx->storage_service);
if (ret < 0) {
i_error("%s: %s", mctx->cmd->name, error);
o_stream_nsend(conn->output, "\n-\n", 3);
} else if (ret == 0) {
o_stream_nsend_str(conn->output, "\n-NOUSER\n");
} else if (mctx->exit_code == DOVEADM_EX_NOREPLICATE) {
o_stream_nsend_str(conn->output, "\n-NOREPLICATE\n");
} else if (mctx->exit_code != 0) {
/* maybe not an error, but not a full success either */
o_stream_nsend_str(conn->output,
t_strdup_printf("\n-%u\n", mctx->exit_code));
} else {
o_stream_nsend(conn->output, "\n+\n", 3);
}
o_stream_uncork(conn->output);
pool_unref(&mctx->pool);
}
static int doveadm_cmd_handle(struct client_connection_tcp *conn, static int doveadm_cmd_handle(struct client_connection_tcp *conn,
const char *cmd_name, const char *cmd_name,
int argc, const char *const argv[], int argc, const char *const argv[],
struct doveadm_cmd_context *cctx) struct doveadm_cmd_context *cctx)
{ {
struct ioloop *prev_ioloop = current_ioloop; struct ioloop *prev_ioloop = current_ioloop;
const struct doveadm_cmd *cmd = NULL;
const struct doveadm_mail_cmd *mail_cmd;
struct doveadm_mail_cmd_context *mctx = NULL;
const struct doveadm_cmd_ver2 *cmd_ver2; const struct doveadm_cmd_ver2 *cmd_ver2;
if ((cmd_ver2 = doveadm_cmd_find_with_args_ver2(cmd_name, &argc, &argv)) == NULL) { if ((cmd_ver2 = doveadm_cmd_find_with_args_ver2(cmd_name, &argc, &argv)) == NULL) {
mail_cmd = doveadm_mail_cmd_find(cmd_name); i_error("doveadm: Client sent unknown command: %s", cmd_name);
if (mail_cmd == NULL) { return -1;
cmd = doveadm_cmd_find_with_args(cmd_name, &argc, &argv);
if (cmd == NULL) {
i_error("doveadm: Client sent unknown command: %s
", cmd_name);
return -1;
}
} else {
if (doveadm_mail_cmd_server_parse(mail_cmd, conn->conn.se
t,
argc, argv,
cctx, &mctx) < 0)
return -1;
}
} else {
cctx->cmd = cmd_ver2;
} }
cctx->cmd = cmd_ver2;
/* some commands will want to call io_loop_run(), but we're already /* some commands will want to call io_loop_run(), but we're already
running one and we can't call the original one recursively, so running one and we can't call the original one recursively, so
create a new ioloop. */ create a new ioloop. */
conn->ioloop = io_loop_create(); conn->ioloop = io_loop_create();
o_stream_switch_ioloop(conn->output); o_stream_switch_ioloop(conn->output);
if (conn->log_out != NULL) if (conn->log_out != NULL)
o_stream_switch_ioloop(conn->log_out); o_stream_switch_ioloop(conn->log_out);
if (cmd_ver2 != NULL) doveadm_cmd_server_run_ver2(conn, argc, argv, cctx);
doveadm_cmd_server_run_ver2(conn, argc, argv, cctx);
else if (cmd != NULL)
doveadm_cmd_server_run(conn, argc, argv, cmd);
else {
i_assert(mctx != NULL);
doveadm_mail_cmd_server_run(conn, mctx);
}
o_stream_switch_ioloop_to(conn->output, prev_ioloop); o_stream_switch_ioloop_to(conn->output, prev_ioloop);
if (conn->log_out != NULL) if (conn->log_out != NULL)
o_stream_switch_ioloop_to(conn->log_out, prev_ioloop); o_stream_switch_ioloop_to(conn->log_out, prev_ioloop);
io_loop_destroy(&conn->ioloop); io_loop_destroy(&conn->ioloop);
/* clear all headers */ /* clear all headers */
doveadm_print_deinit(); doveadm_print_deinit();
doveadm_print_init(DOVEADM_PRINT_TYPE_SERVER); doveadm_print_init(DOVEADM_PRINT_TYPE_SERVER);
return doveadm_exit_code == 0 ? 0 : -1;
/* We already sent the success/failure reply to the client. Return 0
so caller never adds another failure reply. */
return 0;
} }
static bool client_handle_command(struct client_connection_tcp *conn, static bool client_handle_command(struct client_connection_tcp *conn,
const char *const *args) const char *const *args)
{ {
struct doveadm_cmd_context cctx; struct doveadm_cmd_context cctx;
const char *flags, *cmd_name; const char *flags, *cmd_name;
unsigned int argc = str_array_length(args); unsigned int argc = str_array_length(args);
if (argc < 3) { if (argc < 3) {
 End of changes. 13 change blocks. 
163 lines changed or deleted 25 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)