Beispiel #1
0
static void fts_queue_index(struct mailbox *box)
{
	struct mail_user *user = box->storage->user;
	string_t *str = t_str_new(256);
	const char *path, *value;
	unsigned int max_recent_msgs;
	int fd;

	path = t_strconcat(user->set->base_dir, "/"INDEXER_SOCKET_NAME, NULL);
	fd = net_connect_unix(path);
	if (fd == -1) {
		i_error("net_connect_unix(%s) failed: %m", path);
		return;
	}

	value = mail_user_plugin_getenv(user, "fts_autoindex_max_recent_msgs");
	if (value == NULL || str_to_uint(value, &max_recent_msgs) < 0)
		max_recent_msgs = 0;

	str_append(str, INDEXER_HANDSHAKE);
	str_append(str, "APPEND\t0\t");
	str_append_tabescaped(str, user->username);
	str_append_c(str, '\t');
	str_append_tabescaped(str, box->vname);
	str_printfa(str, "\t%u", max_recent_msgs);
	str_append_c(str, '\t');
	str_append_tabescaped(str, box->storage->user->session_id);
	str_append_c(str, '\n');
	if (write_full(fd, str_data(str), str_len(str)) < 0)
		i_error("write(%s) failed: %m", path);
	i_close_fd(&fd);
}
Beispiel #2
0
static void server_real_connect(SERVER_REC *server, IPADDR *ip,
				const char *unix_socket)
{
	GIOChannel *handle;
	IPADDR *own_ip = NULL;
	const char *errmsg;
	char *errmsg2;
	char ipaddr[MAX_IP_LEN];
        int port, protonum;

	g_return_if_fail(ip != NULL || unix_socket != NULL);

	signal_emit("server connecting", 2, server, ip);

	if (server->connrec->no_connect)
		return;

	if (ip != NULL) {
		own_ip = IPADDR_IS_V6(ip) ? server->connrec->own_ip6 : server->connrec->own_ip4;
		port = server->connrec->proxy != NULL ?
			server->connrec->proxy_port : server->connrec->port;
		protonum = server->connrec->use_sctp ? 132 : 0;
		handle = server->connrec->use_ssl ?
			net_connect_ip_ssl(ip, port, own_ip, server, protonum) : net_connect_ip(ip, port, own_ip, protonum);
	} else {
		handle = net_connect_unix(unix_socket);
	}

	if (handle == NULL) {
		/* failed */
		errmsg = g_strerror(errno);
		errmsg2 = NULL;
		if (errno == EADDRNOTAVAIL) {
			if (own_ip != NULL) {
				/* show the IP which is causing the error */
				net_ip2host(own_ip, ipaddr);
				errmsg2 = g_strconcat(errmsg, ": ", ipaddr, NULL);
			}
			server->no_reconnect = TRUE;
		}
		if (server->connrec->use_ssl && errno == ENOSYS)
			server->no_reconnect = TRUE;

		server->connection_lost = TRUE;
		server_connect_failed(server, errmsg2 ? errmsg2 : errmsg);
		g_free(errmsg2);
	} else {
		server->handle = net_sendbuffer_create(handle, 0);
#ifdef HAVE_OPENSSL
		if (server->connrec->use_ssl)
			server_connect_callback_init_ssl(server, handle);
		else
#endif
		server->connect_tag =
			g_input_add(handle, G_INPUT_WRITE | G_INPUT_READ,
				    (GInputFunction)
				    server_connect_callback_init,
				    server);
	}
}
Beispiel #3
0
int connection_client_connect(struct connection *conn)
{
	const struct connection_settings *set = &conn->list->set;
	int fd;

	i_assert(conn->list->set.client);
	i_assert(conn->fd_in == -1);

	if (conn->port != 0)
		fd = net_connect_ip(&conn->ip, conn->port, NULL);
	else
		fd = net_connect_unix(conn->name);
	if (fd == -1)
		return -1;
	conn->fd_in = conn->fd_out = fd;

	if (conn->port != 0) {
		conn->io = io_add(conn->fd_out, IO_WRITE,
				  connection_ip_connected, conn);
		if (set->client_connect_timeout_msecs != 0) {
			conn->to = timeout_add(set->client_connect_timeout_msecs,
					       connection_connect_timeout, conn);
		}
	} else {
		connection_client_connected(conn, TRUE);
	}
	return 0;
}
Beispiel #4
0
static int replication_notify_sync(struct mail_user *user)
{
	struct replication_user *ruser = REPLICATION_USER_CONTEXT(user);
	string_t *str;
	char buf[1024];
	int fd;
	ssize_t ret;

	fd = net_connect_unix(ruser->socket_path);
	if (fd == -1) {
		i_error("net_connect_unix(%s) failed: %m", ruser->socket_path);
		return -1;
	}
	net_set_nonblock(fd, FALSE);

	/* <username> \t "sync" */
	str = t_str_new(256);
	str_append_tabescaped(str, user->username);
	str_append(str, "\tsync\n");
	alarm(ruser->sync_secs);
	if (write_full(fd, str_data(str), str_len(str)) < 0) {
		i_error("write(%s) failed: %m", ruser->socket_path);
		ret = -1;
	} else {
		/* + | - */
		ret = read(fd, buf, sizeof(buf));
		if (ret < 0) {
			if (errno != EINTR) {
				i_error("read(%s) failed: %m",
					ruser->socket_path);
			} else {
				i_warning("replication(%s): Sync failure: "
					  "Timeout in %u secs",
					  user->username, ruser->sync_secs);
			}
		} else if (ret == 0) {
			i_error("read(%s) failed: EOF", ruser->socket_path);
			ret = -1;
		} else if (buf[0] == '+') {
			/* success */
			ret = 0;
		} else if (buf[0] == '-') {
			/* failure */
			if (buf[ret-1] == '\n') ret--;
			i_warning("replication(%s): Sync failure: %s",
				  user->username, t_strndup(buf+1, ret-1));
			ret = -1;
		} else {
			i_warning("replication(%s): "
				  "Remote sent invalid input: %s",
				  user->username, t_strndup(buf, ret));
		}
	}
	alarm(0);
	if (close(fd) < 0)
		i_error("close(%s) failed: %m", ruser->socket_path);
	return ret;
}
static int
master_service_open_config(struct master_service *service,
			   const struct master_service_settings_input *input,
			   const char **path_r, const char **error_r)
{
	struct stat st;
	const char *path;
	int fd;

	*path_r = path = input->config_path != NULL ? input->config_path :
		master_service_get_config_path(service);

	if (service->config_fd != -1 && input->config_path == NULL &&
	    !service->config_path_changed_with_param) {
		/* use the already opened config socket */
		fd = service->config_fd;
		service->config_fd = -1;
		return fd;
	}

	if (!service->config_path_from_master &&
	    !service->config_path_changed_with_param &&
	    input->config_path == NULL) {
		/* first try to connect to the default config socket.
		   configuration may contain secrets, so in default config
		   this fails because the socket is 0600. it's useful for
		   developers though. :) */
		fd = net_connect_unix(DOVECOT_CONFIG_SOCKET_PATH);
		if (fd >= 0) {
			*path_r = DOVECOT_CONFIG_SOCKET_PATH;
			net_set_nonblock(fd, FALSE);
			return fd;
		}
		/* fallback to executing doveconf */
	}

	if (stat(path, &st) < 0) {
		*error_r = errno == EACCES ? eacces_error_get("stat", path) :
			t_strdup_printf("stat(%s) failed: %m", path);
		return -1;
	}

	if (!S_ISSOCK(st.st_mode) && !S_ISFIFO(st.st_mode)) {
		/* it's not an UNIX socket, don't even try to connect */
		fd = -1;
		errno = ENOTSOCK;
	} else {
		fd = net_connect_unix_with_retries(path, 1000);
	}
	if (fd < 0) {
		*error_r = t_strdup_printf("net_connect_unix(%s) failed: %m",
					   path);
		config_exec_fallback(service, input);
		return -1;
	}
	net_set_nonblock(fd, FALSE);
	return fd;
}
Beispiel #6
0
int doveadm_connect_with_default_port(const char *path,
				      in_port_t default_port)
{
	int fd;

	/* we'll assume UNIX sockets typically have an absolute path,
	   or at the very least '/' somewhere. */
	if (strchr(path, '/') == NULL)
		fd = doveadm_tcp_connect(path, default_port);
	else {
		fd = net_connect_unix(path);
		if (fd == -1)
			i_fatal("net_connect_unix(%s) failed: %m", path);
	}
	return fd;
}
Beispiel #7
0
int worker_connection_connect(struct worker_connection *conn)
{
	i_assert(conn->fd == -1);

	conn->fd = net_connect_unix(conn->socket_path);
	if (conn->fd == -1) {
		i_error("connect(%s) failed: %m", conn->socket_path);
		return -1;
	}
	conn->io = io_add(conn->fd, IO_READ, worker_connection_input, conn);
	conn->input = i_stream_create_fd(conn->fd, (size_t)-1);
	conn->output = o_stream_create_fd(conn->fd, (size_t)-1);
	o_stream_set_no_error_handling(conn->output, TRUE);
	o_stream_nsend_str(conn->output, INDEXER_MASTER_HANDSHAKE);
	return 0;
}
Beispiel #8
0
static void server_real_connect(SERVER_REC *server, IPADDR *ip,
				const char *unix_socket)
{
	GIOChannel *handle;
        IPADDR *own_ip;
        int port;

	g_return_if_fail(ip != NULL || unix_socket != NULL);

	signal_emit("server connecting", 2, server, ip);

	if (server->connrec->no_connect)
		return;

	if (ip != NULL) {
		own_ip = ip == NULL ? NULL :
			(IPADDR_IS_V6(ip) ? server->connrec->own_ip6 :
			 server->connrec->own_ip4);
		port = server->connrec->proxy != NULL ?
			server->connrec->proxy_port : server->connrec->port;
		handle = server->connrec->use_ssl ?
			net_connect_ip_ssl(ip, port, own_ip, server->connrec->ssl_cert, server->connrec->ssl_pkey,
server->connrec->ssl_cafile, server->connrec->ssl_capath, server->connrec->ssl_verify) :
			net_connect_ip(ip, port, own_ip);
	} else {
		handle = net_connect_unix(unix_socket);
	}

	if (handle == NULL) {
		/* failed */
		if (errno == EADDRNOTAVAIL ||
		    (server->connrec->use_ssl && errno == ENOSYS))
			server->no_reconnect = TRUE;

		server->connection_lost = TRUE;
		server_connect_failed(server, g_strerror(errno));
	} else {
		server->handle = net_sendbuffer_create(handle, 0);
		server->connect_tag =
			g_input_add(handle, G_INPUT_WRITE | G_INPUT_READ,
				    (GInputFunction)
				    server_connect_callback_init,
				    server);
	}
}
static void replicator_connection_connect(struct replicator_connection *conn)
{
	unsigned int n;
	int fd = -1;

	if (conn->fd != -1)
		return;

	if (conn->port == 0) {
		fd = net_connect_unix(conn->path);
		if (fd == -1)
			i_error("net_connect_unix(%s) failed: %m", conn->path);
	} else {
		for (n = 0; n < conn->ips_count; n++) {
			unsigned int idx = conn->ip_idx;

			conn->ip_idx = (conn->ip_idx + 1) % conn->ips_count;
			fd = net_connect_ip(&conn->ips[idx], conn->port, NULL);
			if (fd != -1)
				break;
			i_error("connect(%s, %u) failed: %m",
				net_ip2addr(&conn->ips[idx]), conn->port);
		}
	}

	if (fd == -1) {
		if (conn->to == NULL) {
			conn->to = timeout_add(REPLICATOR_RECONNECT_MSECS,
					       replicator_connection_connect,
					       conn);
		}
		return;
	}

	if (conn->to != NULL)
		timeout_remove(&conn->to);
	conn->fd = fd;
	conn->io = io_add(fd, IO_READ, replicator_input, conn);
	conn->input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE);
	conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE);
	o_stream_set_no_error_handling(conn->output, TRUE);
	o_stream_nsend_str(conn->output, REPLICATOR_HANDSHAKE);
	o_stream_set_flush_callback(conn->output, replicator_output, conn);
}
Beispiel #10
0
static int ssl_refresh_parameters(struct master_service *service)
{
#define BUF_APPEND_SIZE 1024
	const char *path;
	buffer_t *buf;
	void *data;
	ssize_t ret;
	int fd;

	if (ioloop_time == 0 ||
	    service->ssl_params_last_refresh > ioloop_time - SSL_PARAMS_CHECK_INTERVAL)
		return 0;
	service->ssl_params_last_refresh = ioloop_time;

	path = t_strdup_printf("%s/"SSL_PARAMETERS_PATH, service->set->base_dir);
	fd = net_connect_unix(path);
	if (fd == -1) {
		i_error("connect(%s) failed: %m", path);
		return -1;
	}
	net_set_nonblock(fd, FALSE);

	buf = buffer_create_dynamic(default_pool, BUF_APPEND_SIZE*2);
	for (;;) {
		data = buffer_append_space_unsafe(buf, BUF_APPEND_SIZE);
		ret = read(fd, data, BUF_APPEND_SIZE);
		buffer_set_used_size(buf, buf->used - BUF_APPEND_SIZE +
				     (ret < 0 ? 0 : ret));
		if (ret <= 0)
			break;
	}
	if (ret < 0)
		i_error("read(%s) failed: %m", path);
	else if (ssl_iostream_context_import_params(service->ssl_ctx, buf) < 0) {
		i_error("Corrupted SSL parameters file in state_dir: "
			"ssl-parameters.dat - disabling SSL %u", (int)buf->used);
		ret = -1;
	}
	i_close_fd(&fd);
	buffer_free(&buf);
	return ret < 0 ? -1 : 0;
}
Beispiel #11
0
struct access_lookup *
access_lookup(const char *path, int client_fd, const char *daemon_name,
	      access_lookup_callback_t *callback, void *context)
{
	struct access_lookup *lookup;
	const char *cmd;
	ssize_t ret;
	int fd;

	fd = net_connect_unix(path);
	if (fd == -1) {
		i_error("connect(%s) failed: %m", path);
		return NULL;
	}

	cmd = t_strconcat(daemon_name, "\n", NULL);
	ret = fd_send(fd, client_fd, cmd, strlen(cmd));
	if (ret != (ssize_t)strlen(cmd)) {
		if (ret < 0)
			i_error("fd_send(%s) failed: %m", path);
		else
			i_error("fd_send(%s) didn't write enough bytes", path);
		i_close_fd(&fd);
		return NULL;
	}

	lookup = i_new(struct access_lookup, 1);
	lookup->refcount = 1;
	lookup->fd = fd;
	lookup->path = i_strdup(path);
	lookup->io = io_add(fd, IO_READ, access_lookup_input, lookup);
	lookup->to = timeout_add(ACCESS_LOOKUP_TIMEOUT_MSECS,
				 access_lookup_timeout, lookup);
	lookup->callback = callback;
	lookup->context = context;
	return lookup;
}
Beispiel #12
0
static void
dsync_replicator_notify(struct dsync_cmd_context *ctx,
			enum dsync_brain_sync_type sync_type,
			const char *state_str)
{
#define REPLICATOR_HANDSHAKE "VERSION\treplicator-doveadm-client\t1\t0\n"
	const char *path;
	string_t *str;
	int fd;

	path = t_strdup_printf("%s/replicator-doveadm",
			       ctx->ctx.cur_mail_user->set->base_dir);
	fd = net_connect_unix(path);
	if (fd == -1) {
		if (errno == ECONNREFUSED || errno == ENOENT) {
			/* replicator not running on this server. ignore. */
			return;
		}
		i_error("net_connect_unix(%s) failed: %m", path);
		return;
	}
	str = t_str_new(128);
	str_append(str, REPLICATOR_HANDSHAKE"NOTIFY\t");
	str_append_tabescaped(str, ctx->ctx.cur_mail_user->username);
	str_append_c(str, '\t');
	if (sync_type == DSYNC_BRAIN_SYNC_TYPE_FULL)
		str_append_c(str, 'f');
	str_append_c(str, '\t');
	str_append_tabescaped(str, state_str);
	str_append_c(str, '\n');
	if (write_full(fd, str_data(str), str_len(str)) < 0)
		i_error("write(%s) failed: %m", path);
	/* we only wanted to notify replicator. we don't care enough about the
	   answer to wait for it. */
	if (close(fd) < 0)
		i_error("close(%s) failed: %m", path);
}