Exemple #1
0
static void
solr_lookup_xml_start(void *context, const char *name, const char **attrs)
{
	struct solr_lookup_xml_context *ctx = context;
	const char *name_attr;

	i_assert(ctx->depth >= (int)ctx->state);

	ctx->depth++;
	if (ctx->depth - 1 > (int)ctx->state) {
		/* skipping over unwanted elements */
		return;
	}

	/* response -> result -> doc */
	switch (ctx->state) {
	case SOLR_XML_RESPONSE_STATE_ROOT:
		if (strcmp(name, "response") == 0)
			ctx->state++;
		break;
	case SOLR_XML_RESPONSE_STATE_RESPONSE:
		if (strcmp(name, "result") == 0)
			ctx->state++;
		break;
	case SOLR_XML_RESPONSE_STATE_RESULT:
		if (strcmp(name, "doc") == 0) {
			ctx->state++;
			ctx->uid = 0;
			ctx->score = 0;
			i_free_and_null(ctx->mailbox);
			i_free_and_null(ctx->ns);
			ctx->uidvalidity = 0;
		}
		break;
	case SOLR_XML_RESPONSE_STATE_DOC:
		name_attr = attrs_get_name(attrs);
		if (strcmp(name_attr, "uid") == 0)
			ctx->content_state = SOLR_XML_CONTENT_STATE_UID;
		else if (strcmp(name_attr, "score") == 0)
			ctx->content_state = SOLR_XML_CONTENT_STATE_SCORE;
		else if (strcmp(name_attr, "box") == 0)
			ctx->content_state = SOLR_XML_CONTENT_STATE_MAILBOX;
		else if (strcmp(name_attr, "ns") == 0)
			ctx->content_state = SOLR_XML_CONTENT_STATE_NAMESPACE;
		else if (strcmp(name_attr, "uidv") == 0)
			ctx->content_state = SOLR_XML_CONTENT_STATE_UIDVALIDITY;
		else 
			break;
		ctx->state++;
		break;
	case SOLR_XML_RESPONSE_STATE_CONTENT:
		break;
	}
}
Exemple #2
0
void client_proxy_failed(struct client *client, bool send_line)
{
	if (send_line) {
		client_proxy_error(client, PROXY_FAILURE_MSG);
	}

	login_proxy_free(&client->login_proxy);
	proxy_free_password(client);
	i_free_and_null(client->proxy_user);
	i_free_and_null(client->proxy_master_user);

	/* call this last - it may destroy the client */
	client_auth_failed(client);
}
void message_decoder_decode_reset(struct message_decoder_context *ctx)
{
	i_free_and_null(ctx->content_charset);
	ctx->message_cte = MESSAGE_CTE_78BIT;
	ctx->charset_utf8 = TRUE;
	buffer_set_used_size(ctx->encoding_buf, 0);
}
Exemple #4
0
void index_storage_mailbox_close(struct mailbox *box)
{
	struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box);

	index_mailbox_check_remove_all(box);
	if (box->input != NULL)
		i_stream_unref(&box->input);

	if (box->view_pvt != NULL)
		mail_index_view_close(&box->view_pvt);
	if (box->index_pvt != NULL)
		mail_index_close(box->index_pvt);
	mail_index_view_close(&box->view);
	mail_index_close(box->index);
	box->cache = NULL;

	ibox->keyword_names = NULL;
	i_free_and_null(ibox->cache_fields);

	if (array_is_created(&ibox->recent_flags))
		array_free(&ibox->recent_flags);
	ibox->recent_flags_prev_uid = 0;
	ibox->recent_flags_count = 0;

	ibox->sync_last_check = 0;
}
Exemple #5
0
static int
worker_connection_input_line(struct worker_connection *conn, const char *line)
{
	void *const *contextp, *context;
	int percentage;

	if (aqueue_count(conn->request_queue) == 0) {
		i_error("Input from worker without pending requests: %s", line);
		return -1;
	}

	if (str_to_int(line, &percentage) < 0 ||
	    percentage < -1 || percentage > 100) {
		i_error("Invalid input from worker: %s", line);
		return -1;
	}

	contextp = array_idx(&conn->request_contexts,
			     aqueue_idx(conn->request_queue, 0));
	context = *contextp;
	if (percentage < 0 || percentage == 100) {
		/* the request is finished */
		aqueue_delete_tail(conn->request_queue);
		if (aqueue_count(conn->request_queue) == 0)
			i_free_and_null(conn->request_username);
	}

	conn->callback(percentage, context);
	return 0;
}
Exemple #6
0
static void
message_decode_body_init_charset(struct message_decoder_context *ctx,
				 struct message_part *part)
{
	ctx->binary_input = ctx->content_charset == NULL &&
		(ctx->flags & MESSAGE_DECODER_FLAG_RETURN_BINARY) != 0 &&
		(part->flags & (MESSAGE_PART_FLAG_TEXT |
				MESSAGE_PART_FLAG_MESSAGE_RFC822)) == 0;

	if (ctx->binary_input)
		return;

	if (ctx->charset_trans != NULL && ctx->content_charset != NULL &&
	    strcasecmp(ctx->content_charset, ctx->charset_trans_charset) == 0) {
		/* already have the correct translation selected */
		charset_to_utf8_reset(ctx->charset_trans);
		return;
	}

	if (ctx->charset_trans != NULL)
		charset_to_utf8_end(&ctx->charset_trans);
	i_free_and_null(ctx->charset_trans_charset);

	ctx->charset_trans_charset = i_strdup(ctx->content_charset != NULL ?
					      ctx->content_charset : "UTF-8");
	if (charset_to_utf8_begin(ctx->charset_trans_charset, ctx->normalizer,
				  &ctx->charset_trans) < 0)
		ctx->charset_trans = charset_utf8_to_utf8_begin(ctx->normalizer);
}
Exemple #7
0
static void worker_connection_disconnect(struct worker_connection *conn)
{
	unsigned int i, count = aqueue_count(conn->request_queue);

	if (conn->fd != -1) {
		io_remove(&conn->io);
		i_stream_destroy(&conn->input);
		o_stream_destroy(&conn->output);

		if (close(conn->fd) < 0)
			i_error("close(%s) failed: %m", conn->socket_path);
		conn->fd = -1;
	}

	/* cancel any pending requests */
	if (count > 0) {
		i_error("Indexer worker disconnected, "
			"discarding %u requests for %s",
			count, conn->request_username);
	}

	/* conn->callback() can try to destroy us */
	conn->refcount++;
	for (i = 0; i < count; i++) {
		void *const *contextp =
			array_idx(&conn->request_contexts,
				  aqueue_idx(conn->request_queue, 0));
		void *context = *contextp;

		aqueue_delete_tail(conn->request_queue);
		conn->callback(-1, context);
	}
	i_free_and_null(conn->request_username);
	worker_connection_unref(conn);
}
Exemple #8
0
static
int o_stream_encrypt_send_header_v2(struct encrypt_ostream *stream)
{
	unsigned char c;
	unsigned int i;

	i_assert(!stream->prefix_written);
	stream->prefix_written = TRUE;

	buffer_t *values = buffer_create_dynamic(pool_datastack_create(), 256);
	buffer_append(values, IOSTREAM_CRYPT_MAGIC, sizeof(IOSTREAM_CRYPT_MAGIC));
	c = 2;
	buffer_append(values, &c, 1);
	i = htonl(stream->flags);
	buffer_append(values, &i, 4);
	/* store total length of header
	   9 = version + flags + length
	   8 = rounds + key data length
	   */
	i = htonl(sizeof(IOSTREAM_CRYPT_MAGIC) + 9 + stream->cipher_oid->used + stream->mac_oid->used + 8 + stream->key_data_len);
	buffer_append(values, &i, 4);

	buffer_append_buf(values, stream->cipher_oid, 0, (size_t)-1);
	buffer_append_buf(values, stream->mac_oid, 0, (size_t)-1);
	i = htonl(IO_STREAM_ENCRYPT_ROUNDS);
	buffer_append(values, &i, 4);
	i = htonl(stream->key_data_len);
	buffer_append(values, &i, 4);
	buffer_append(values, stream->key_data, stream->key_data_len);
	i_free_and_null(stream->key_data);

	return o_stream_encrypt_send(stream, values->data, values->used);
}
Exemple #9
0
void i_stream_skip(struct istream *stream, uoff_t count)
{
	struct istream_private *_stream = stream->real_stream;
	size_t data_size;

	data_size = _stream->pos - _stream->skip;
	if (count <= data_size) {
		/* within buffer */
		stream->v_offset += count;
		_stream->skip += count;
		if (_stream->nonpersistent_buffers &&
		    _stream->skip == _stream->pos) {
			_stream->skip = _stream->pos = 0;
			_stream->buffer_size = 0;
			i_free_and_null(_stream->w_buffer);
		}
		return;
	}

	/* have to seek forward */
	count -= data_size;
	_stream->skip = _stream->pos;
	stream->v_offset += data_size;

	if (unlikely(stream->closed || stream->stream_errno != 0))
		return;

	_stream->seek(_stream, stream->v_offset + count, FALSE);
}
static void
fts_backend_solr_update_set_mailbox(struct fts_backend_update_context *_ctx,
				    struct mailbox *box)
{
	struct solr_fts_backend_update_context *ctx =
		(struct solr_fts_backend_update_context *)_ctx;
	struct mailbox_status status;
	struct mail_namespace *ns;

	if (ctx->prev_uid != 0) {
		fts_index_set_last_uid(ctx->cur_box, ctx->prev_uid);
		ctx->prev_uid = 0;
	}

	ctx->cur_box = box;
	ctx->uid_validity = 0;
	i_free_and_null(ctx->id_box_name);

	if (box != NULL) {
		ctx->id_box_name = i_strdup(fts_box_get_root(box, &ns));

		mailbox_get_open_status(box, STATUS_UIDVALIDITY, &status);
		ctx->uid_validity = status.uidvalidity;
	}
}
static void proxy_free_password(struct client *client)
{
	if (client->proxy_password == NULL)
		return;

	safe_memset(client->proxy_password, 0, strlen(client->proxy_password));
	i_free_and_null(client->proxy_password);
}
Exemple #12
0
void test_end(void)
{
	i_assert(test_prefix != NULL);

	test_out("", test_success);
	i_free_and_null(test_prefix);
	test_success = FALSE;
}
Exemple #13
0
int pop3c_sync_get_sizes(struct pop3c_mailbox *mbox)
{
	struct istream *input;
	const char *error;
	char *line, *p;
	unsigned int seq, line_seq;

	i_assert(mbox->msg_sizes == NULL);

	if (mbox->msg_uidls == NULL) {
		if (pop3c_sync_get_uidls(mbox) < 0)
			return -1;
	}
	if (mbox->msg_count == 0) {
		mbox->msg_sizes = i_new(uoff_t, 1);
		return 0;
	}

	if (pop3c_client_cmd_stream(mbox->client, "LIST\r\n",
				    &input, &error) < 0) {
		mail_storage_set_critical(mbox->box.storage,
					  "LIST failed: %s", error);
		return -1;
	}

	mbox->msg_sizes = i_new(uoff_t, mbox->msg_count); seq = 0;
	while ((line = i_stream_read_next_line(input)) != NULL) {
		if (++seq > mbox->msg_count) {
			mail_storage_set_critical(mbox->box.storage,
				"Too much data in LIST: %s", line);
			break;
		}
		p = strchr(line, ' ');
		if (p == NULL) {
			mail_storage_set_critical(mbox->box.storage,
				"Invalid LIST line: %s", line);
			break;
		}
		*p++ = '\0';
		if (str_to_uint(line, &line_seq) < 0 || line_seq != seq) {
			mail_storage_set_critical(mbox->box.storage,
				"Unexpected LIST seq: %s != %u", line, seq);
			break;
		}
		if (str_to_uoff(p, &mbox->msg_sizes[seq-1]) < 0) {
			mail_storage_set_critical(mbox->box.storage,
				"Invalid LIST size: %s", p);
			break;
		}
	}
	i_stream_destroy(&input);
	if (line != NULL) {
		i_free_and_null(mbox->msg_sizes);
		return -1;
	}
	return 0;
}
static void astream_part_reset(struct attachment_istream *astream)
{
	struct attachment_istream_part *part = &astream->part;

	if (part->temp_output != NULL)
		o_stream_destroy(&part->temp_output);
	if (part->temp_fd != -1)
		i_close_fd(&part->temp_fd);

	i_free_and_null(part->content_type);
	i_free_and_null(part->content_disposition);
	if (part->part_buf != NULL)
		buffer_free(&part->part_buf);

	memset(part, 0, sizeof(*part));
	part->temp_fd = -1;
	hash_format_reset(astream->set.hash_format);
}
Exemple #15
0
static void cmd_id_free(struct imap_client *client)
{
	struct imap_client_cmd_id *id = client->cmd_id;

	if (id->log_reply != NULL)
		str_free(&id->log_reply);
	if (id->log_keys != NULL)
		p_strsplit_free(default_pool, id->log_keys);
	imap_parser_unref(&id->parser);

	i_free_and_null(client->cmd_id);
	client->skip_line = TRUE;
}
Exemple #16
0
int istream_raw_mbox_seek(struct istream *stream, uoff_t offset)
{
	struct raw_mbox_istream *rstream =
		(struct raw_mbox_istream *)stream->real_stream;
	bool check;

	i_assert(rstream->locked);

	/* reset any (corruption) errors */
	stream->stream_errno = 0;
	i_free_and_null(stream->real_stream->iostream.error);
	rstream->corrupted = FALSE;
	rstream->eof = FALSE;
	rstream->istream.istream.eof = FALSE;

	/* if seeked is FALSE, we unlocked in the middle. don't try to use
	   any cached state then. */
	if (rstream->mail_size != (uoff_t)-1 && rstream->seeked &&
	    rstream->hdr_offset + rstream->mail_size == offset)
		return istream_raw_mbox_next(stream, (uoff_t)-1);

	if (offset == rstream->from_offset && rstream->seeked) {
		/* back to beginning of current message */
		offset = rstream->hdr_offset;
		check = offset == 0;
	} else {
		rstream->body_offset = (uoff_t)-1;
		rstream->mail_size = (uoff_t)-1;
		rstream->received_time = (time_t)-1;
		rstream->next_received_time = (time_t)-1;
		rstream->header_missing_eoh = FALSE;

		i_free(rstream->sender);
		rstream->sender = NULL;
		i_free(rstream->next_sender);
		rstream->next_sender = NULL;

                rstream->from_offset = offset;
		rstream->hdr_offset = offset;
		check = TRUE;
	}
	rstream->seeked = TRUE;

	i_stream_seek_mark(stream, offset);
	i_stream_seek_mark(rstream->istream.parent, offset);

	if (check)
		(void)i_stream_read(stream);
	return rstream->corrupted ? -1 : 0;
}
static bool stats_top_round(struct top_context *ctx)
{
#define TOP_CMD "EXPORT\tsession\tconnected\n"
	const char *const *args;
	pool_t tmp_pool;

	if (write_full(ctx->fd, TOP_CMD, strlen(TOP_CMD)) < 0)
		i_fatal("write(%s) failed: %m", ctx->path);

	/* read header */
	if (ctx->headers != NULL) {
		args = read_next_line(ctx->input);
		if (args == NULL)
			i_fatal("read(%s) unexpectedly disconnected", ctx->path);
		if (*args == NULL)
			return TRUE;
		if (str_array_length(args) != ctx->headers_count)
			i_fatal("headers changed");
	} else {
		ctx->headers = p_read_next_line(default_pool, ctx->input);
		if (ctx->headers == NULL)
			i_fatal("read(%s) unexpectedly disconnected", ctx->path);
		if (*ctx->headers == NULL) {
			i_free_and_null(ctx->headers);
			return FALSE;
		}
		ctx->headers_count = str_array_length((void *)ctx->headers);
		if (!stats_header_find(ctx, "last_update", &ctx->last_update_idx))
			i_fatal("last_update header missing");
		if (!stats_header_find(ctx, "user", &ctx->user_idx))
			i_fatal("user header missing");
		stats_top_get_sorting(ctx);
	}

	array_clear(&ctx->lines);
	p_clear(ctx->prev_pool);
	tmp_pool = ctx->prev_pool;
	ctx->prev_pool = ctx->cur_pool;
	ctx->cur_pool = tmp_pool;

	ctx->flip = !ctx->flip;
	stats_read(ctx);
	stats_drop_stale(ctx);

	sort_ctx = ctx;
	array_sort(&ctx->lines, *ctx->lines_sort);
	sort_ctx = NULL;
	return TRUE;
}
static void imap_urlauth_fetch_abort_local(struct imap_urlauth_fetch *ufetch)
{
	struct imap_urlauth_fetch_url *url, *url_next;

	if (ufetch->local_url != NULL) {
		ufetch->pending_requests--;
		imap_msgpart_url_free(&ufetch->local_url);
	}

	i_free_and_null(ufetch->pending_reply.url);
	i_free_and_null(ufetch->pending_reply.bodypartstruct);
	i_free_and_null(ufetch->pending_reply.error);
	if (ufetch->pending_reply.input != NULL)
		i_stream_unref(&ufetch->pending_reply.input);

	url = ufetch->local_urls_head;
	for (; url != NULL; url = url_next) {
		url_next = url->next;
		i_free(url->url);
		i_free(url);
		ufetch->pending_requests--;
	}
	ufetch->local_urls_head = ufetch->local_urls_tail = NULL;
}
static void client_auth_failed(struct client *client)
{
	i_free_and_null(client->master_data_prefix);
	if (client->auth_response != NULL)
		str_truncate(client->auth_response, 0);

	if (client->auth_initializing || client->destroyed)
		return;

	if (client->io != NULL)
		io_remove(&client->io);

	client->io = io_add(client->fd, IO_READ, client_input, client);
	client_input(client);
}
Exemple #20
0
void hostpid_init(void)
{
	static char hostname[256], pid[MAX_INT_STRLEN];

	if (gethostname(hostname, sizeof(hostname)-1) == -1)
		i_strocpy(hostname, "unknown", sizeof(hostname));
	hostname[sizeof(hostname)-1] = '\0';
	my_hostname = hostname;

	if (strchr(hostname, '/') != NULL)
		i_fatal("Invalid system hostname: %s", hostname);

	/* allow calling hostpid_init() multiple times to reset hostname */
	i_free_and_null(my_domain);

	i_strocpy(pid, dec2str(getpid()), sizeof(pid));
	my_pid = pid;
}
Exemple #21
0
static
void i_stream_decrypt_destroy(struct iostream_private *stream)
{
	struct decrypt_istream *dstream =
		(struct decrypt_istream *)stream;

	if (dstream->buf != NULL)
		buffer_free(&dstream->buf);
	if (dstream->iv != NULL)
		i_free_and_null(dstream->iv);
	if (dstream->ctx_sym != NULL)
		dcrypt_ctx_sym_destroy(&(dstream->ctx_sym));
	if (dstream->ctx_mac != NULL)
		dcrypt_ctx_hmac_destroy(&(dstream->ctx_mac));
	if (dstream->priv_key != NULL)
		dcrypt_key_unref_private(&(dstream->priv_key));

	i_stream_unref(&(dstream->istream.parent));
}
Exemple #22
0
static int openssl_iostream_handshake(struct ssl_iostream *ssl_io)
{
	const char *error = NULL;
	int ret;

	i_assert(!ssl_io->handshaked);

	if (ssl_io->ctx->client_ctx) {
		while ((ret = SSL_connect(ssl_io->ssl)) <= 0) {
			ret = openssl_iostream_handle_error(ssl_io, ret,
							    "SSL_connect()");
			if (ret <= 0)
				return ret;
		}
	} else {
		while ((ret = SSL_accept(ssl_io->ssl)) <= 0) {
			ret = openssl_iostream_handle_error(ssl_io, ret,
							    "SSL_accept()");
			if (ret <= 0)
				return ret;
		}
	}
	/* handshake finished */
	(void)openssl_iostream_bio_sync(ssl_io);

	if (ssl_io->handshake_callback != NULL) {
		if (ssl_io->handshake_callback(&error, ssl_io->handshake_context) < 0) {
			i_assert(error != NULL);
			i_stream_close(ssl_io->plain_input);
			o_stream_close(ssl_io->plain_output);
			openssl_iostream_set_error(ssl_io, error);
			ssl_io->handshake_failed = TRUE;
			errno = EINVAL;
			return -1;
		}
	}
	i_free_and_null(ssl_io->last_error);
	ssl_io->handshaked = TRUE;

	if (ssl_io->ssl_output != NULL)
		(void)o_stream_flush(ssl_io->ssl_output);
	return 1;
}
Exemple #23
0
static int i_stream_seekable_write_failed(struct seekable_istream *sstream)
{
	struct istream_private *stream = &sstream->istream;
	void *data;

	i_assert(sstream->fd != -1);

	stream->max_buffer_size = (size_t)-1;
	data = i_stream_alloc(stream, sstream->write_peak);

	if (pread_full(sstream->fd, data, sstream->write_peak, 0) < 0) {
		i_error("istream-seekable: read(%s) failed: %m", sstream->temp_path);
		memarea_unref(&stream->memarea);
		return -1;
	}
	i_stream_destroy(&sstream->fd_input);
	i_close_fd(&sstream->fd);

	i_free_and_null(sstream->temp_path);
	return 0;
}
Exemple #24
0
void index_storage_mailbox_close(struct mailbox *box)
{
	struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box);

	mailbox_watch_remove_all(box);
	if (box->input != NULL)
		i_stream_unref(&box->input);

	if (box->view_pvt != NULL)
		mail_index_view_close(&box->view_pvt);
	if (box->index_pvt != NULL)
		mail_index_close(box->index_pvt);
	if (box->view != NULL) {
		mail_index_view_close(&box->view);
		mail_index_close(box->index);
	}
	box->cache = NULL;

	ibox->keyword_names = NULL;
	i_free_and_null(ibox->cache_fields);

	ibox->sync_last_check = 0;
}
static int i_stream_seekable_write_failed(struct seekable_istream *sstream)
{
    struct istream_private *stream = &sstream->istream;
    void *data;

    i_assert(sstream->membuf == NULL);

    sstream->membuf =
        buffer_create_dynamic(default_pool, sstream->write_peak);
    data = buffer_append_space_unsafe(sstream->membuf, sstream->write_peak);

    if (pread_full(sstream->fd, data, sstream->write_peak, 0) < 0) {
        i_error("istream-seekable: read(%s) failed: %m", sstream->temp_path);
        buffer_free(&sstream->membuf);
        return -1;
    }
    i_stream_destroy(&sstream->fd_input);
    i_close_fd(&sstream->fd);

    stream->max_buffer_size = (size_t)-1;
    i_free_and_null(sstream->temp_path);
    return 0;
}
Exemple #26
0
static
int o_stream_encrypt_send_header_v1(struct encrypt_ostream *stream)
{
	unsigned char c;
	unsigned short s;

	i_assert(!stream->prefix_written);
	stream->prefix_written = TRUE;

	buffer_t *values = buffer_create_dynamic(pool_datastack_create(), 256);
	buffer_append(values, IOSTREAM_CRYPT_MAGIC, sizeof(IOSTREAM_CRYPT_MAGIC));
	/* version */
	c = 1;
	buffer_append(values, &c, 1);
	/* key data length */
	s = htons(stream->key_data_len);
	buffer_append(values, &s, 2);
	/* then write key data */
	buffer_append(values, stream->key_data, stream->key_data_len);
	i_free_and_null(stream->key_data);

	/* then send it to stream */
	return o_stream_encrypt_send(stream, values->data, values->used);
}
void client_destroy(struct client *client, const char *reason)
{
	if (client->destroyed)
		return;
	client->destroyed = TRUE;

	if (!client->login_success && reason != NULL) {
		reason = t_strconcat(reason, " ",
			client_get_extra_disconnect_reason(client), NULL);
	}
	if (reason != NULL)
		client_log(client, reason);

	if (last_client == client)
		last_client = client->prev;
	DLLIST_REMOVE(&clients, client);

	if (client->input != NULL)
		i_stream_close(client->input);
	if (client->output != NULL)
		o_stream_close(client->output);

	if (client->master_tag != 0) {
		i_assert(client->auth_request == NULL);
		i_assert(client->authenticating);
		i_assert(client->refcount > 1);
		client->authenticating = FALSE;
		master_auth_request_abort(master_auth, client->master_tag);
		client->refcount--;
	} else if (client->auth_request != NULL) {
		i_assert(client->authenticating);
		sasl_server_auth_abort(client);
	} else {
		i_assert(!client->authenticating);
	}

	if (client->io != NULL)
		io_remove(&client->io);
	if (client->to_disconnect != NULL)
		timeout_remove(&client->to_disconnect);
	if (client->to_auth_waiting != NULL)
		timeout_remove(&client->to_auth_waiting);
	if (client->auth_response != NULL)
		str_free(&client->auth_response);

	if (client->fd != -1) {
		net_disconnect(client->fd);
		client->fd = -1;
	}

	if (client->proxy_password != NULL) {
		safe_memset(client->proxy_password, 0,
			    strlen(client->proxy_password));
		i_free_and_null(client->proxy_password);
	}

	if (client->proxy_sasl_client != NULL)
		dsasl_client_free(&client->proxy_sasl_client);
	if (client->login_proxy != NULL)
		login_proxy_free(&client->login_proxy);
	if (client->v.destroy != NULL)
		client->v.destroy(client);
	if (client_unref(&client) && initial_service_count == 1) {
		/* as soon as this connection is done with proxying
		   (or whatever), the process will die. there's no need for
		   authentication anymore, so close the connection.
		   do this only with initial service_count=1, in case there
		   are other clients with pending authentications */
		auth_client_disconnect(auth_client, "unnecessary connection");
	}
	login_client_destroyed();
	login_refresh_proctitle();
}
Exemple #28
0
int mdbox_sync_begin(struct mdbox_mailbox *mbox, enum mdbox_sync_flags flags,
		     struct mdbox_map_atomic_context *atomic,
		     struct mdbox_sync_context **ctx_r)
{
	struct mail_storage *storage = mbox->box.storage;
	struct mdbox_sync_context *ctx;
	enum mail_index_sync_flags sync_flags;
	int ret;
	bool rebuild, storage_rebuilt = FALSE;

	*ctx_r = NULL;

	/* avoid race conditions with mailbox creation, don't check for dbox
	   headers until syncing has locked the mailbox */
	rebuild = mbox->storage->corrupted ||
		(flags & MDBOX_SYNC_FLAG_FORCE_REBUILD) != 0;
	if (rebuild && (flags & MDBOX_SYNC_FLAG_NO_REBUILD) == 0) {
		if (mdbox_storage_rebuild_in_context(mbox->storage, atomic) < 0)
			return -1;
		index_mailbox_reset_uidvalidity(&mbox->box);
		storage_rebuilt = TRUE;
	}

	ctx = i_new(struct mdbox_sync_context, 1);
	ctx->mbox = mbox;
	ctx->flags = flags;
	ctx->atomic = atomic;

	sync_flags = index_storage_get_sync_flags(&mbox->box);
	if (!rebuild && (flags & MDBOX_SYNC_FLAG_FORCE) == 0)
		sync_flags |= MAIL_INDEX_SYNC_FLAG_REQUIRE_CHANGES;
	if ((flags & MDBOX_SYNC_FLAG_FSYNC) != 0)
		sync_flags |= MAIL_INDEX_SYNC_FLAG_FSYNC;
	/* don't write unnecessary dirty flag updates */
	sync_flags |= MAIL_INDEX_SYNC_FLAG_AVOID_FLAG_UPDATES;

	ret = mdbox_sync_try_begin(ctx, sync_flags);
	if (ret <= 0) {
		/* failed / nothing to do */
		i_free(ctx);
		return ret;
	}

	if ((ret = mdbox_sync_index(ctx)) <= 0) {
		mail_index_sync_rollback(&ctx->index_sync_ctx);
		i_free_and_null(ctx);

		if (ret < 0)
			return -1;

		/* corrupted */
		if (storage_rebuilt) {
			mail_storage_set_critical(storage,
				"mdbox %s: Storage keeps breaking",
				mailbox_get_path(&mbox->box));
			return -1;
		}

		/* we'll need to rebuild storage.
		   try again from the beginning. */
		mdbox_storage_set_corrupted(mbox->storage);
		if ((flags & MDBOX_SYNC_FLAG_NO_REBUILD) != 0) {
			mail_storage_set_critical(storage,
				"mdbox %s: Can't rebuild storage",
				mailbox_get_path(&mbox->box));
			return -1;
		}
		return mdbox_sync_begin(mbox, flags, atomic, ctx_r);
	}

	*ctx_r = ctx;
	return 0;
}
Exemple #29
0
void ipwd_deinit(void)
{
	i_free_and_null(pwbuf);
	i_free_and_null(grbuf);
}
Exemple #30
0
static int
openssl_iostream_handle_error_full(struct ssl_iostream *ssl_io, int ret,
				   const char *func_name, bool write_error)
{
	const char *errstr = NULL;
	int err;

	err = SSL_get_error(ssl_io->ssl, ret);
	switch (err) {
	case SSL_ERROR_WANT_WRITE:
		if (!openssl_iostream_bio_sync(ssl_io)) {
			if (!write_error)
				i_panic("SSL ostream buffer size not unlimited");
			return 0;
		}
		if (ssl_io->closed) {
			if (ssl_io->plain_stream_errstr != NULL)
				openssl_iostream_set_error(ssl_io, ssl_io->plain_stream_errstr);
			errno = ssl_io->plain_stream_errno != 0 ?
				ssl_io->plain_stream_errno : EPIPE;
			return -1;
		}
		return 1;
	case SSL_ERROR_WANT_READ:
		ssl_io->want_read = TRUE;
		(void)openssl_iostream_bio_sync(ssl_io);
		if (ssl_io->closed) {
			if (ssl_io->plain_stream_errstr != NULL)
				openssl_iostream_set_error(ssl_io, ssl_io->plain_stream_errstr);
			errno = ssl_io->plain_stream_errno != 0 ?
				ssl_io->plain_stream_errno : EPIPE;
			return -1;
		}
		return ssl_io->want_read ? 0 : 1;
	case SSL_ERROR_SYSCALL:
		/* eat up the error queue */
		if (ERR_peek_error() != 0) {
			errstr = openssl_iostream_error();
			errno = EINVAL;
		} else if (ret != 0) {
			i_assert(errno != 0);
			errstr = strerror(errno);
		} else {
			/* EOF. */
			errno = EPIPE;
			errstr = "Disconnected";
			break;
		}
		errstr = t_strdup_printf("%s syscall failed: %s",
					 func_name, errstr);
		break;
	case SSL_ERROR_ZERO_RETURN:
		/* clean connection closing */
		errno = EPIPE;
		i_free_and_null(ssl_io->last_error);
		return -1;
	case SSL_ERROR_SSL:
		errstr = t_strdup_printf("%s failed: %s",
					 func_name, openssl_iostream_error());
		errno = EINVAL;
		break;
	default:
		errstr = t_strdup_printf("%s failed: unknown failure %d (%s)",
					 func_name, err,
					 openssl_iostream_error());
		errno = EINVAL;
		break;
	}

	openssl_iostream_set_error(ssl_io, errstr);
	return -1;
}