static void login_client_connected(const struct master_login_client *client, const char *username, const char *const *extra_fields) { struct mail_storage_service_input input; const char *error; buffer_t input_buf; memset(&input, 0, sizeof(input)); input.module = input.service = "pop3"; input.local_ip = client->auth_req.local_ip; input.remote_ip = client->auth_req.remote_ip; input.username = username; input.userdb_fields = extra_fields; input.session_id = client->session_id; buffer_create_from_const_data(&input_buf, client->data, client->auth_req.data_size); if (client_create_from_input(&input, client->fd, client->fd, &input_buf, &error) < 0) { int fd = client->fd; i_error("%s", error); i_close_fd(&fd); master_service_client_connection_destroyed(master_service); } }
static void login_client_connected(const struct master_login_client *client, const char *username, const char *const *extra_fields) { #define MSG_BYE_INTERNAL_ERROR "* BYE "MAIL_ERRSTR_CRITICAL_MSG"\r\n" struct mail_storage_service_input input; const char *error; buffer_t input_buf; memset(&input, 0, sizeof(input)); input.module = input.service = "imap"; input.local_ip = client->auth_req.local_ip; input.remote_ip = client->auth_req.remote_ip; input.username = username; input.userdb_fields = extra_fields; input.session_id = client->session_id; buffer_create_from_const_data(&input_buf, client->data, client->auth_req.data_size); if (client_create_from_input(&input, client, client->fd, client->fd, &input_buf, &error) < 0) { int fd = client->fd; if (write(fd, MSG_BYE_INTERNAL_ERROR, strlen(MSG_BYE_INTERNAL_ERROR)) < 0) { if (errno != EAGAIN && errno != EPIPE) i_error("write(client) failed: %m"); } i_error("%s", error); i_close_fd(&fd); master_service_client_connection_destroyed(master_service); } }
static void main_stdio_run(const char *username) { struct mail_storage_service_input input; buffer_t *input_buf; const char *value, *error, *input_base64; memset(&input, 0, sizeof(input)); input.module = input.service = "pop3"; input.username = username != NULL ? username : getenv("USER"); if (input.username == NULL && IS_STANDALONE()) input.username = getlogin(); if (input.username == NULL) i_fatal("USER environment missing"); if ((value = getenv("IP")) != NULL) (void)net_addr2ip(value, &input.remote_ip); if ((value = getenv("LOCAL_IP")) != NULL) (void)net_addr2ip(value, &input.local_ip); input_base64 = getenv("CLIENT_INPUT"); input_buf = input_base64 == NULL ? NULL : t_base64_decode_str(input_base64); if (client_create_from_input(&input, STDIN_FILENO, STDOUT_FILENO, input_buf, &error) < 0) i_fatal("%s", error); }
static int imap_master_client_input_args(struct connection *conn, const char *const *args, int fd_client, pool_t pool) { struct imap_master_client *client = (struct imap_master_client *)conn; struct client *imap_client; struct mail_storage_service_input input; struct imap_master_input master_input; const char *error; int ret; if (imap_master_client_parse_input(args, pool, &input, &master_input, &error) < 0) { i_error("imap-master: Failed to parse client input: %s", error); o_stream_nsend_str(conn->output, t_strdup_printf( "-Failed to parse client input: %s\n", error)); i_close_fd(&fd_client); return -1; } if (imap_master_client_verify(&master_input, fd_client, &error) < 0) { i_error("imap-master: Failed to verify client input: %s", error); o_stream_nsend_str(conn->output, t_strdup_printf( "-Failed to verify client input: %s\n", error)); i_close_fd(&fd_client); return -1; } /* Send a success notification before we start anything that lasts potentially a long time. imap-hibernate process is waiting for us to answer. Even if we fail later, we log the error anyway. */ o_stream_nsend_str(conn->output, "+\n"); (void)o_stream_flush(conn->output); /* NOTE: before client_create_from_input() on failures we need to close fd_client, but afterward it gets closed by client_destroy() */ ret = client_create_from_input(&input, fd_client, fd_client, &imap_client, &error); if (ret < 0) { i_error("imap-master(%s): Failed to create client: %s", input.username, error); i_close_fd(&fd_client); return -1; } client->imap_client_created = TRUE; if (client_create_finish(imap_client, &error) < 0) { i_error("imap-master(%s): %s", input.username, error); client_destroy(imap_client, error); return -1; } /* log prefix is set at this point, so we don't need to add the username anymore to the log messages */ o_stream_nsend(imap_client->output, master_input.client_output->data, master_input.client_output->used); if (master_input.client_input->used > 0 && !i_stream_add_data(imap_client->input, master_input.client_input->data, master_input.client_input->used)) { i_error("imap-master: Couldn't add %"PRIuSIZE_T " bytes to client's input stream", master_input.client_input->used); client_destroy(imap_client, "Client initialization failed"); return -1; } imap_client->state_import_bad_idle_done = master_input.state_import_bad_idle_done; imap_client->state_import_idle_continue = master_input.state_import_idle_continue; if (imap_client->user->mail_debug) { if (imap_client->state_import_bad_idle_done) i_debug("imap-master: Unhibernated because IDLE was stopped with BAD command"); else if (imap_client->state_import_idle_continue) i_debug("imap-master: Unhibernated to send mailbox changes"); else i_debug("imap-master: Unhibernated because IDLE was stopped with DONE"); } ret = imap_state_import_internal(imap_client, master_input.state->data, master_input.state->used, &error); if (ret <= 0) { i_error("imap-master: Failed to import client state: %s", error); client_destroy(imap_client, "Client state initialization failed"); return -1; } if (master_input.tag != NULL) imap_state_import_idle_cmd_tag(imap_client, master_input.tag); /* make sure all pending input gets handled */ i_assert(imap_client->to_delayed_input == NULL); if (master_input.client_input->used > 0) { if (imap_client->user->mail_debug) { i_debug("imap-master: Pending client input: '%s'", str_sanitize(str_c(master_input.client_input), 128)); } imap_client->to_delayed_input = timeout_add(0, client_input, imap_client); } imap_refresh_proctitle(); /* we'll always disconnect the client afterwards */ return -1; }