Exemplo n.º 1
0
struct mail_index *mail_index_alloc(const char *dir, const char *prefix)
{
	struct mail_index *index;

	index = i_new(struct mail_index, 1);
	index->dir = i_strdup(dir);
	index->prefix = i_strdup(prefix);
	index->fd = -1;

	index->extension_pool =
		pool_alloconly_create(MEMPOOL_GROWING"index extension", 1024);
	p_array_init(&index->extensions, index->extension_pool, 5);
	i_array_init(&index->sync_lost_handlers, 4);
	i_array_init(&index->module_contexts,
		     I_MIN(5, mail_index_module_register.id));

	index->mode = 0600;
	index->gid = (gid_t)-1;
	index->lock_method = FILE_LOCK_METHOD_FCNTL;
	index->max_lock_timeout_secs = UINT_MAX;

	index->keywords_ext_id =
		mail_index_ext_register(index, MAIL_INDEX_EXT_KEYWORDS,
					128, 2, 1);
	index->keywords_pool = pool_alloconly_create("keywords", 512);
	i_array_init(&index->keywords, 16);
	hash_table_create(&index->keywords_hash, index->keywords_pool, 0,
			  strcase_hash, strcasecmp);
	index->log = mail_transaction_log_alloc(index);
	mail_index_modseq_init(index);
	return index;
}
Exemplo n.º 2
0
static void
parse_content_type(struct message_decoder_context *ctx,
		   struct message_header_line *hdr)
{
	struct rfc822_parser_context parser;
	const char *const *results;
	string_t *str;

	if (ctx->content_type != NULL)
		return;

	rfc822_parser_init(&parser, hdr->full_value, hdr->full_value_len, NULL);
	rfc822_skip_lwsp(&parser);
	str = t_str_new(64);
	if (rfc822_parse_content_type(&parser, str) < 0)
		return;
	ctx->content_type = i_strdup(str_c(str));

	rfc2231_parse(&parser, &results);
	for (; *results != NULL; results += 2) {
		if (strcasecmp(results[0], "charset") == 0) {
			ctx->content_charset = i_strdup(results[1]);
			break;
		}
	}
}
Exemplo n.º 3
0
int imap_msgpart_url_create(struct mail_user *user, const struct imap_url *url,
			    struct imap_msgpart_url **mpurl_r,
			    const char **error_r)
{
	const char *section = url->section == NULL ? "" : url->section;
	struct imap_msgpart_url *mpurl;
	struct imap_msgpart *msgpart;

	i_assert(url->mailbox != NULL && url->uid != 0 &&
		 url->search_program == NULL);

	if (imap_msgpart_parse(section, &msgpart) < 0) {
		*error_r = "Invalid section";
		return -1;
	}

	mpurl = i_new(struct imap_msgpart_url, 1);
	mpurl->part = msgpart;
	mpurl->user = user;
	mpurl->mailbox = i_strdup(url->mailbox);
	mpurl->uidvalidity = url->uidvalidity;
	mpurl->uid = url->uid;
	if (url->section != NULL)
		mpurl->section = i_strdup(url->section);
	mpurl->partial_offset = url->partial_offset;
	mpurl->partial_size = url->partial_size;

	imap_msgpart_set_partial(msgpart, url->partial_offset,
				 url->partial_size == 0 ?
				 (uoff_t)-1 : url->partial_size);

	*mpurl_r = mpurl;
	return 0;
}
Exemplo n.º 4
0
struct imap_urlauth_context *
imap_urlauth_init(struct mail_user *user,
		  const struct imap_urlauth_config *config)
{
	struct imap_urlauth_context *uctx;
	unsigned int timeout;

	i_assert(*config->url_host != '\0');

	uctx = i_new(struct imap_urlauth_context, 1);
	uctx->user = user;
	uctx->url_host = i_strdup(config->url_host);
	uctx->url_port = config->url_port;

	if (config->access_anonymous)
		uctx->access_user = i_strdup("anonymous");
	else
		uctx->access_user = i_strdup(config->access_user);
	uctx->access_anonymous = config->access_anonymous;
	if (config->access_applications != NULL &&
	    *config->access_applications != NULL) {
		uctx->access_applications =
			p_strarray_dup(default_pool,
				       config->access_applications);
		timeout = IMAP_URLAUTH_SPECIAL_TIMEOUT_MSECS;
	} else {
		timeout = IMAP_URLAUTH_NORMAL_TIMEOUT_MSECS;
	}

	if (config->socket_path != NULL) {
		uctx->conn = imap_urlauth_connection_init(config->socket_path,
					user, config->session_id, timeout);
	}
	return uctx;
}
Exemplo n.º 5
0
/*
* 合并路径,如果filename传入的是绝对路径,则直接返回filename的拷贝。
*   base     - 基目录
*   basesz   - base的字节长度,传入-1的话,将使用strlen()函数读取。
*   filename - 文件名字
* 使用完后,需调用pcs_free来释放返回值
*/
char *combin_path(const char *base, int basesz, const char *filename)
{
	char *result = NULL;
#ifdef WIN32
	char buf[MAX_PATH] = "";
	char *p = i_strdup(base, basesz),
		*f = i_strdup(filename, -1);
	p = fix_win_path(p);
	f = fix_win_path(f);
	if (PathCombine(buf, p, f)) {
		result = i_strdup(buf, -1);
	}
	pcs_free(p);
	pcs_free(f);
#else
	if (basesz == -1) {
		result = combin_net_disk_path(base, filename);
	}
	else {
		char *p = i_strdup(base, basesz);
		result = combin_net_disk_path(p, filename);
		pcs_free(p);
	}
#endif
	return result;
}
Exemplo n.º 6
0
struct ostream *iostream_temp_create_sized(const char *temp_path_prefix,
					   enum iostream_temp_flags flags,
					   const char *name,
					   size_t max_mem_size)
{
	struct temp_ostream *tstream;
	struct ostream *output;

	tstream = i_new(struct temp_ostream, 1);
	tstream->ostream.ostream.blocking = TRUE;
	tstream->ostream.sendv = o_stream_temp_sendv;
	tstream->ostream.send_istream = o_stream_temp_send_istream;
	tstream->ostream.write_at = o_stream_temp_write_at;
	tstream->ostream.seek = o_stream_temp_seek;
	tstream->ostream.iostream.close = o_stream_temp_close;
	tstream->temp_path_prefix = i_strdup(temp_path_prefix);
	tstream->flags = flags;
	tstream->max_mem_size = max_mem_size;
	tstream->buf = buffer_create_dynamic(default_pool, 8192);
	tstream->fd = -1;

	output = o_stream_create(&tstream->ostream, NULL, -1);
	tstream->name = i_strdup(name);
	if (name[0] == '\0') {
		o_stream_set_name(output, t_strdup_printf(
			"(temp iostream in %s)", temp_path_prefix));
	} else {
		o_stream_set_name(output, t_strdup_printf(
			"(temp iostream in %s for %s)", temp_path_prefix, name));
	}
	return output;
}
Exemplo n.º 7
0
static int proxy_start(struct client *client,
		       const struct client_auth_reply *reply)
{
	struct login_proxy_settings proxy_set;

	i_assert(reply->destuser != NULL);
	i_assert(!client->destroyed);

	client->v.proxy_reset(client);

	if (reply->password == NULL) {
		client_log_err(client, "proxy: password not given");
		client_proxy_error(client, PROXY_FAILURE_MSG);
		return -1;
	}
	if (reply->host == NULL || *reply->host == '\0') {
		client_log_err(client, "proxy: host not given");
		client_proxy_error(client, PROXY_FAILURE_MSG);
		return -1;
	}

	i_assert(client->refcount > 1);

	if (client->destroyed) {
		/* connection_queue_add() decided that we were the oldest
		   connection and killed us. */
		return -1;
	}
	if (login_proxy_is_ourself(client, reply->host, reply->port,
				   reply->destuser)) {
		client_log_err(client, "Proxying loops to itself");
		client_proxy_error(client, PROXY_FAILURE_MSG);
		return -1;
	}

	memset(&proxy_set, 0, sizeof(proxy_set));
	proxy_set.host = reply->host;
	if (reply->hostip != NULL &&
	    net_addr2ip(reply->hostip, &proxy_set.ip) < 0)
		proxy_set.ip.family = 0;
	proxy_set.port = reply->port;
	proxy_set.connect_timeout_msecs = reply->proxy_timeout_msecs;
	proxy_set.notify_refresh_secs = reply->proxy_refresh_secs;
	proxy_set.ssl_flags = reply->ssl_flags;

	if (login_proxy_new(client, &proxy_set, proxy_input) < 0) {
		client_proxy_error(client, PROXY_FAILURE_MSG);
		return -1;
	}

	client->proxy_user = i_strdup(reply->destuser);
	client->proxy_master_user = i_strdup(reply->master_user);
	client->proxy_password = i_strdup(reply->password);

	/* disable input until authentication is finished */
	if (client->io != NULL)
		io_remove(&client->io);
	return 0;
}
Exemplo n.º 8
0
static int
fs_sis_open(struct fs *_fs, const char *path, enum fs_open_mode mode,
	    enum fs_open_flags flags, struct fs_file **file_r)
{
	struct sis_fs *fs = (struct sis_fs *)_fs;
	struct sis_fs_file *file;
	struct fs_file *super;
	const char *dir, *hash;

	if (mode == FS_OPEN_MODE_APPEND) {
		fs_set_error(_fs, "APPEND mode not supported");
		return -1;
	}

	if (fs_open(fs->super, path, mode | flags, &super) < 0) {
		fs_sis_copy_error(fs);
		return -1;
	}

	switch (mode) {
	case FS_OPEN_MODE_RDONLY:
		*file_r = super;
		return 0;
	case FS_OPEN_MODE_CREATE:
	case FS_OPEN_MODE_REPLACE:
		break;
	case FS_OPEN_MODE_APPEND:
		i_unreached();
	}

	if (fs_sis_path_parse(_fs, path, &dir, &hash) < 0)
		return -1;

	file = i_new(struct sis_fs_file, 1);
	file->file.fs = _fs;
	file->file.path = i_strdup(fs_file_path(super));
	file->super = super;
	file->open_mode = mode;
	file->hash = i_strdup(hash);

	/* if hashes/<hash> already exists, open it */
	file->hash_path = i_strdup_printf("%s/"HASH_DIR_NAME"/%s", dir, hash);
	if (fs_open(fs->super, file->hash_path, FS_OPEN_MODE_RDONLY,
		    &file->hash_file) < 0 && errno != ENOENT) {
		i_error("fs-sis: Couldn't open hash file: %s",
			fs_last_error(fs->super));
	}
	if (file->hash_file != NULL) {
		file->hash_input =
			fs_read_stream(file->hash_file, IO_BLOCK_SIZE);
	}

	*file_r = &file->file;
	return 0;
}
struct sieve_extprograms_config *sieve_extprograms_config_init
(const struct sieve_extension *ext)
{
	struct sieve_instance *svinst = ext->svinst;
	struct sieve_extprograms_config *ext_config;
	const char *extname = sieve_extension_name(ext);
	const char *bin_dir, *socket_dir, *input_eol;
	sieve_number_t execute_timeout;

	extname = strrchr(extname, '.');
	i_assert(extname != NULL);
	extname++;

	bin_dir = sieve_setting_get
		(svinst, t_strdup_printf("sieve_%s_bin_dir", extname));
	socket_dir = sieve_setting_get
		(svinst, t_strdup_printf("sieve_%s_socket_dir", extname));
	input_eol = sieve_setting_get
		(svinst, t_strdup_printf("sieve_%s_input_eol", extname));
	
	ext_config = i_new(struct sieve_extprograms_config, 1);
	ext_config->execute_timeout = 
		SIEVE_EXTPROGRAMS_DEFAULT_EXEC_TIMEOUT_SECS;

	if ( bin_dir == NULL && socket_dir == NULL ) {
		if ( svinst->debug ) {
			sieve_sys_debug(svinst, "%s extension: "
				"no bin or socket directory specified; extension is unconfigured "
				"(both sieve_%s_bin_dir and sieve_%s_socket_dir are not set)",
				sieve_extension_name(ext), extname, extname);
		}
	} else {
		ext_config->bin_dir = i_strdup(bin_dir);
		ext_config->socket_dir = i_strdup(socket_dir);

		if (sieve_setting_get_duration_value
			(svinst, t_strdup_printf("sieve_%s_exec_timeout", extname),
				&execute_timeout)) {
			ext_config->execute_timeout = execute_timeout;
		}

		ext_config->default_input_eol = SIEVE_EXTPROGRAMS_EOL_CRLF;
		if (input_eol != NULL && strcasecmp(input_eol, "lf") == 0)
			ext_config->default_input_eol = SIEVE_EXTPROGRAMS_EOL_LF;
	}

	if ( sieve_extension_is(ext, vnd_pipe_extension) ) 
		ext_config->copy_ext = sieve_ext_copy_get_extension(ext->svinst);
	if ( sieve_extension_is(ext, vnd_execute_extension) ) 
		ext_config->var_ext = sieve_ext_variables_get_extension(ext->svinst);
	return ext_config;
}
Exemplo n.º 10
0
static int
imap_urlauth_fetch_request_callback(struct imap_urlauth_fetch_reply *reply,
				    void *context)
{
	struct imap_urlauth_fetch *ufetch =
		(struct imap_urlauth_fetch *)context;
	int ret = 1;

	if (ufetch->waiting_local && reply != NULL) {
		i_assert(ufetch->pending_reply.url == NULL);
		ufetch->pending_reply.url = i_strdup(reply->url);
		ufetch->pending_reply.flags = reply->flags;
		ufetch->pending_reply.bodypartstruct =
			i_strdup(reply->bodypartstruct);
		ufetch->pending_reply.error = i_strdup(reply->error);
		if (reply->input != NULL) {
			ufetch->pending_reply.input = reply->input;
			i_stream_ref(ufetch->pending_reply.input);
		}
		ufetch->pending_reply.size = reply->size;
		ufetch->pending_reply.succeeded = reply->succeeded;
		ufetch->pending_reply.binary_has_nuls = reply->binary_has_nuls;
		ufetch->waiting_service = TRUE;
		return 0;
	}

	ufetch->waiting_local = FALSE;
	ufetch->pending_requests--;

	imap_urlauth_fetch_ref(ufetch);

	if (!ufetch->failed) {
		bool last = ufetch->pending_requests == 0 || reply == NULL;
		ret = ufetch->callback(reply, last, ufetch->context);
	}

	/* report failure only once */
	if (ret < 0 || reply == NULL) {
		if (!ufetch->failed)
			imap_urlauth_fetch_abort_local(ufetch);
		ufetch->failed = TRUE;
	} else if (ret == 0) {
		ufetch->waiting_service = TRUE;
		ufetch->pending_requests++;
	}
	
	imap_urlauth_fetch_unref(&ufetch);
	return ret;
}
Exemplo n.º 11
0
int imap_urlauth_fetch_url_parsed(struct imap_urlauth_fetch *ufetch,
			   const char *url, struct imap_url *imap_url,
			   enum imap_urlauth_fetch_flags url_flags)
{
	struct imap_urlauth_context *uctx = ufetch->uctx;
	struct mail_user *mail_user = uctx->user;
	const char *error, *errormsg;
	int ret = 0;

	ufetch->failed = FALSE;
	ufetch->pending_requests++;

	imap_urlauth_fetch_ref(ufetch);

	/* if access user and target user match, handle fetch request locally */
	if (imap_url->userid != NULL &&
		strcmp(mail_user->username, imap_url->userid) == 0) {

		if (ufetch->waiting_local) {
			struct imap_urlauth_fetch_url *url_local;

			url_local = i_new(struct imap_urlauth_fetch_url, 1);
			url_local->url = i_strdup(url);
			url_local->flags = url_flags;

			DLLIST2_APPEND(&ufetch->local_urls_head,
				       &ufetch->local_urls_tail, url_local);
		} else T_BEGIN {
			imap_urlauth_fetch_local(ufetch, url,
						 url_flags, imap_url);
		} T_END;
		imap_url = NULL;
	/* don't try to fetch remote URLs that are already known to fail access */
	} else if (!imap_urlauth_check(uctx, imap_url, TRUE, &error)) {
Exemplo n.º 12
0
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;
	}
}
Exemplo n.º 13
0
struct subsfile_list_context *
subsfile_list_init(struct mailbox_list *list, const char *path)
{
	struct subsfile_list_context *ctx;
	int fd;

	ctx = i_new(struct subsfile_list_context, 1);
	ctx->list = list;

	fd = nfs_safe_open(path, O_RDONLY);
	if (fd == -1) {
		if (errno != ENOENT) {
			subsread_set_syscall_error(list, "open()", path);
			ctx->failed = TRUE;
		}
	} else {
		ctx->input = i_stream_create_fd_autoclose(&fd,
					list->mailbox_name_max_length+1);
		i_stream_set_return_partial_line(ctx->input, TRUE);
		subsfile_list_read_header(ctx->list, ctx->input, &ctx->version);
	}
	ctx->path = i_strdup(path);
	ctx->name = str_new(default_pool, 128);
	return ctx;
}
Exemplo n.º 14
0
void connection_init_from_streams(struct connection_list *list,
			    struct connection *conn, const char *name,
			    struct istream *input, struct ostream *output)
{
	i_assert(name != NULL);

	conn->list = list;
	conn->name = i_strdup(name);
	conn->fd_in = i_stream_get_fd(input);
	conn->fd_out = o_stream_get_fd(output);

	i_assert(conn->fd_in >= 0);
	i_assert(conn->fd_out >= 0);
	i_assert(conn->io == NULL);
	i_assert(conn->input == NULL);
	i_assert(conn->output == NULL);
	i_assert(conn->to == NULL);

	conn->input = input;
	i_stream_ref(conn->input);
	i_stream_set_name(conn->input, conn->name);

	conn->output = output;
	o_stream_ref(conn->output);
	o_stream_set_no_error_handling(conn->output, TRUE);
	o_stream_set_name(conn->output, conn->name);

	conn->io = io_add_istream(conn->input, *list->v.input, conn);
	
	DLLIST_PREPEND(&list->connections, conn);
	list->connections_count++;

	if (list->v.client_connected != NULL)
		list->v.client_connected(conn, TRUE);
}
Exemplo n.º 15
0
static void fts_solr_set_default_ns(struct solr_fts_backend *backend)
{
	struct mail_namespace *ns = backend->backend.ns;
	struct fts_solr_user *fuser = FTS_SOLR_USER_CONTEXT(ns->user);
	const struct fts_solr_settings *set = &fuser->set;
	const char *str;

	if (backend->default_ns != NULL)
		return;

	if (set->default_ns_prefix != NULL) {
		backend->default_ns =
			mail_namespace_find_prefix(ns->user->namespaces,
						   set->default_ns_prefix);
		if (backend->default_ns == NULL) {
			i_error("fts_solr: default_ns setting points to "
				"nonexistent namespace");
		}
	}
	if (backend->default_ns == NULL) {
		backend->default_ns =
			mail_namespace_find_inbox(ns->user->namespaces);
	}
	while (backend->default_ns->alias_for != NULL)
		backend->default_ns = backend->default_ns->alias_for;

	if (ns != backend->default_ns) {
		str = solr_escape_id_str(ns->prefix);
		backend->id_namespace = i_strdup(str);
	}
}
Exemplo n.º 16
0
int cmd_login(struct imap_client *imap_client, const struct imap_arg *args)
{
	struct client *client = &imap_client->common;
	const char *user, *pass;
	string_t *plain_login, *base64;

	/* two arguments: username and password */
	if (!imap_arg_get_astring(&args[0], &user) ||
	    !imap_arg_get_astring(&args[1], &pass) ||
	    !IMAP_ARG_IS_EOL(&args[2]))
		return -1;

	if (!client_check_plaintext_auth(client, TRUE)) {
		if (client->virtual_user == NULL)
			client->virtual_user = i_strdup(user);
		return 1;
	}

	/* authorization ID \0 authentication ID \0 pass */
	plain_login = t_buffer_create(64);
	buffer_append_c(plain_login, '\0');
	buffer_append(plain_login, user, strlen(user));
	buffer_append_c(plain_login, '\0');
	buffer_append(plain_login, pass, strlen(pass));

	base64 = t_buffer_create(MAX_BASE64_ENCODED_SIZE(plain_login->used));
	base64_encode(plain_login->data, plain_login->used, base64);
	return imap_client_auth_begin(imap_client, "PLAIN", str_c(base64));
}
Exemplo n.º 17
0
struct istream *
i_stream_create_rawlog(struct istream *input, const char *rawlog_path,
		       int rawlog_fd, enum iostream_rawlog_flags flags)
{
	struct rawlog_istream *rstream;

	i_assert(rawlog_path != NULL);
	i_assert(rawlog_fd != -1);

	rstream = i_new(struct rawlog_istream, 1);
	rstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
	rstream->istream.stream_size_passthrough = TRUE;

	rstream->riostream.rawlog_path = i_strdup(rawlog_path);
	rstream->riostream.rawlog_fd = rawlog_fd;
	iostream_rawlog_init(&rstream->riostream, flags, TRUE);

	rstream->istream.read = i_stream_rawlog_read;
	rstream->istream.iostream.close = i_stream_rawlog_close;
	rstream->istream.iostream.destroy = i_stream_rawlog_destroy;

	rstream->istream.istream.readable_fd = input->readable_fd;
	rstream->istream.istream.blocking = input->blocking;
	rstream->istream.istream.seekable = input->seekable;
	return i_stream_create(&rstream->istream, input,
			       i_stream_get_fd(input));
}
Exemplo n.º 18
0
void worker_connection_request(struct worker_connection *conn,
			       const struct indexer_request *request,
			       void *context)
{
	i_assert(worker_connection_is_connected(conn));
	i_assert(context != NULL);
	i_assert(request->index || request->optimize);

	if (conn->request_username == NULL)
		conn->request_username = i_strdup(request->username);
	else {
		i_assert(strcmp(conn->request_username,
				request->username) == 0);
	}

	aqueue_append(conn->request_queue, &context);

	T_BEGIN {
		string_t *str = t_str_new(128);

		str_append_tabescaped(str, request->username);
		str_append_c(str, '\t');
		str_append_tabescaped(str, request->mailbox);
		str_append_c(str, '\t');
		if (request->session_id != NULL)
			str_append_tabescaped(str, request->session_id);
		str_printfa(str, "\t%u\t", request->max_recent_msgs);
		if (request->index)
			str_append_c(str, 'i');
		if (request->optimize)
			str_append_c(str, 'o');
		str_append_c(str, '\n');
		o_stream_nsend(conn->output, str_data(str), str_len(str));
	} T_END;
}
Exemplo n.º 19
0
int mail_session_connect_parse(const char *const *args, const char **error_r)
{
	struct mail_session *session;
	const char *session_id;
	pid_t pid;
	struct ip_addr ip;
	unsigned int i;

	/* <session id> <username> <service> <pid> [key=value ..] */
	if (str_array_length(args) < 4) {
		*error_r = "CONNECT: Too few parameters";
		return -1;
	}
	session_id = args[0];
	if (str_to_pid(args[3], &pid) < 0) {
		*error_r = t_strdup_printf("CONNECT: Invalid pid %s for session ID %s",
					   args[3], session_id);
		return -1;
	}

	session = hash_table_lookup(mail_sessions_hash, session_id);
	if (session != NULL) {
		*error_r = t_strdup_printf(
			"CONNECT: Duplicate session ID %s for user %s service %s",
			session_id, args[1], args[2]);
		return -1;
	}
	session = i_malloc(sizeof(struct mail_session) + stats_alloc_size());
	session->stats = (void *)(session + 1);
	session->refcount = 1; /* unrefed at disconnect */
	session->id = i_strdup(session_id);
	session->service = str_table_ref(services, args[2]);
	session->pid = pid;
	session->last_update = ioloop_timeval;
	session->to_idle = timeout_add(MAIL_SESSION_IDLE_TIMEOUT_MSECS,
				       mail_session_idle_timeout, session);

	session->user = mail_user_login(args[1]);
	for (i = 3; args[i] != NULL; i++) {
		if (strncmp(args[i], "rip=", 4) == 0 &&
		    net_addr2ip(args[i] + 4, &ip) == 0)
			session->ip = mail_ip_login(&ip);
	}

	hash_table_insert(mail_sessions_hash, session->id, session);
	DLLIST_PREPEND_FULL(&stable_mail_sessions, session,
			    stable_prev, stable_next);
	DLLIST2_APPEND_FULL(&mail_sessions_head, &mail_sessions_tail, session,
			    sorted_prev, sorted_next);
	DLLIST_PREPEND_FULL(&session->user->sessions, session,
			    user_prev, user_next);
	mail_user_ref(session->user);
	if (session->ip != NULL) {
		DLLIST_PREPEND_FULL(&session->ip->sessions, session,
				    ip_prev, ip_next);
		mail_ip_ref(session->ip);
	}
	global_memory_alloc(mail_session_memsize(session));
	return 0;
}
Exemplo n.º 20
0
void mail_transaction_log_file_move_to_memory(struct mail_transaction_log_file
					      *file)
{
	buffer_t *buf;

	if (MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file))
		return;

	if (file->mmap_base != NULL) {
		/* just copy to memory */
		i_assert(file->buffer_offset == 0);

		buf = buffer_create_dynamic(default_pool, file->mmap_size);
		buffer_append(buf, file->mmap_base, file->mmap_size);
		buffer_free(&file->buffer);
		file->buffer = buf;

		/* and lose the mmap */
		if (munmap(file->mmap_base, file->mmap_size) < 0)
			log_file_set_syscall_error(file, "munmap()");
		file->mmap_base = NULL;
	} else if (file->buffer_offset != 0) {
		/* we don't have the full log in the memory. read it. */
		(void)mail_transaction_log_file_read(file, 0, FALSE);
	}
	file->last_size = 0;

	if (close(file->fd) < 0)
		log_file_set_syscall_error(file, "close()");
	file->fd = -1;

	i_free(file->filepath);
	file->filepath = i_strdup(file->log->filepath);
}
Exemplo n.º 21
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);
}
Exemplo n.º 22
0
static struct userdb_iterate_context *
passwd_file_iterate_init(struct auth_request *auth_request,
                         userdb_iter_callback_t *callback, void *context)
{
    struct userdb_module *_module = auth_request->userdb->userdb;
    struct passwd_file_userdb_module *module =
        (struct passwd_file_userdb_module *)_module;
    struct passwd_file_userdb_iterate_context *ctx;
    int fd;

    ctx = i_new(struct passwd_file_userdb_iterate_context, 1);
    ctx->ctx.auth_request = auth_request;
    ctx->ctx.callback = callback;
    ctx->ctx.context = context;
    ctx->skip_passdb_entries = !module->pwf->userdb_warn_missing;
    if (module->pwf->default_file == NULL) {
        i_error("passwd-file: User iteration isn't currently supported "
                "with %%variable paths");
        ctx->ctx.failed = TRUE;
        return &ctx->ctx;
    }
    ctx->path = i_strdup(module->pwf->default_file->path);

    /* for now we support only a single passwd-file */
    fd = open(ctx->path, O_RDONLY);
    if (fd == -1) {
        i_error("open(%s) failed: %m", ctx->path);
        ctx->ctx.failed = TRUE;
    } else {
        ctx->input = i_stream_create_fd(fd, (size_t)-1, TRUE);
    }
    return &ctx->ctx;
}
Exemplo n.º 23
0
static int
client_input_notify(struct doveadm_connection *client, const char *const *args)
{
	struct replicator_user *user;

	/* <username> <flags> <state> */
	if (str_array_length(args) < 3) {
		i_error("%s: NOTIFY: Invalid parameters", client->conn.name);
		return -1;
	}

	user = replicator_queue_add(client->queue, args[0],
				    REPLICATION_PRIORITY_NONE);
	if (args[1][0] == 'f')
		user->last_full_sync = ioloop_time;
	user->last_fast_sync = ioloop_time;
	user->last_update = ioloop_time;

	if (args[2][0] != '\0') {
		i_free(user->state);
		user->state = i_strdup(args[2]);
	}
	o_stream_send_str(client->conn.output, "+\n");
	return 0;
}
Exemplo n.º 24
0
static struct fs_file *
fs_compress_file_init(struct fs *_fs, const char *path,
		      enum fs_open_mode mode, enum fs_open_flags flags)
{
	struct compress_fs *fs = (struct compress_fs *)_fs;
	struct compress_fs_file *file;

	file = i_new(struct compress_fs_file, 1);
	file->file.fs = _fs;
	file->file.path = i_strdup(path);
	file->fs = fs;
	file->open_mode = mode;

	/* avoid unnecessarily creating two seekable streams */
	flags &= ~FS_OPEN_FLAG_SEEKABLE;

	file->file.parent = fs_file_init(_fs->parent, path, mode | flags);
	if (mode == FS_OPEN_MODE_READONLY &&
	    (flags & FS_OPEN_FLAG_ASYNC) == 0) {
		/* use async stream for parent, so fs_read_stream() won't create
		   another seekable stream unneededly */
		file->super_read = fs_file_init(_fs->parent, path, mode | flags |
						FS_OPEN_FLAG_ASYNC);
	} else {
		file->super_read = file->file.parent;
	}
	return &file->file;
}
static struct acl_object *
acl_backend_vfile_object_init(struct acl_backend *_backend,
			      const char *name)
{
	struct acl_backend_vfile *backend =
		(struct acl_backend_vfile *)_backend;
	struct acl_object_vfile *aclobj;
	const char *dir, *vname, *error;

	aclobj = i_new(struct acl_object_vfile, 1);
	aclobj->aclobj.backend = _backend;
	aclobj->aclobj.name = i_strdup(name);

	T_BEGIN {
		if (*name == '\0' ||
		    mailbox_list_is_valid_name(_backend->list, name, &error)) {
			vname = *name == '\0' ? "" :
				mailbox_list_get_vname(_backend->list, name);

			dir = acl_backend_vfile_get_local_dir(_backend, name, vname);
			aclobj->local_path = dir == NULL ? NULL :
				i_strconcat(dir, "/"ACL_FILENAME, NULL);
			if (backend->global_path != NULL &&
			    _backend->global_file == NULL) {
				aclobj->global_path =
					i_strconcat(backend->global_path, "/", vname, NULL);
			}
		} else {
			/* Invalid mailbox name, just use the default
			   global ACL files */
		}
	} T_END;
	return &aclobj->aclobj;
}
Exemplo n.º 26
0
static int fs_quota_init(struct quota_root *_root, const char *args,
			 const char **error_r)
{
	struct fs_quota_root *root = (struct fs_quota_root *)_root;
	const char *const *tmp;

	if (args == NULL)
		return 0;

	for (tmp = t_strsplit(args, ":"); *tmp != NULL; tmp++) {
		if (strcmp(*tmp, "user") == 0)
			root->group_disabled = TRUE;
		else if (strcmp(*tmp, "group") == 0)
			root->user_disabled = TRUE;
		else if (strcmp(*tmp, "inode_per_mail") == 0)
			root->inode_per_mail = TRUE;
		else if (strcmp(*tmp, "noenforcing") == 0)
			_root->no_enforcing = TRUE;
		else if (strcmp(*tmp, "hidden") == 0)
			_root->hidden = TRUE;
		else if (strncmp(*tmp, "mount=", 6) == 0) {
			i_free(root->storage_mount_path);
			root->storage_mount_path = i_strdup(*tmp + 6);
		} else {
			*error_r = t_strdup_printf("Invalid parameter: %s", *tmp);
			return -1;
		}
	}
	_root->auto_updating = TRUE;
	return 0;
}
Exemplo n.º 27
0
static void
imap_metadata_transaction_set_error(struct imap_metadata_transaction *imtrans,
				    enum mail_error error, const char *string)
{
	i_free(imtrans->error_string);
	imtrans->error_string = i_strdup(string);
	imtrans->error = error;
}
Exemplo n.º 28
0
void program_client_set_output_seekable
(struct program_client *pclient, const char *temp_prefix)
{
	if ( pclient->output != NULL )
		o_stream_unref(&pclient->output);
	pclient->temp_prefix = i_strdup(temp_prefix);
	pclient->output_seekable = TRUE;
}
Exemplo n.º 29
0
static struct client *
client_create_standalone(const char *access_user,
			 const char *const *access_applications,
			 int fd_in, int fd_out, bool debug)
{
	struct client *client;

	/* always use nonblocking I/O */
	net_set_nonblock(fd_in, TRUE);
	net_set_nonblock(fd_out, TRUE);

	client = i_new(struct client, 1);
	i_array_init(&client->access_apps, 16);
	client->fd_in = fd_in;
	client->fd_out = fd_out;
	client->fd_ctrl = -1;

	if (access_user != NULL && *access_user != '\0')
		client->access_user = i_strdup(access_user);
	else {
		client->access_user = i_strdup("anonymous");
		client->access_anonymous = TRUE;
	}
	if (access_applications != NULL) {
		const char *const *apps = access_applications;
		for (; *apps != NULL; apps++) {
			char *app = i_strdup(*apps);
			array_append(&client->access_apps, &app, 1);
		}
	}
	client->debug = debug;

	client->input = i_stream_create_fd(fd_in, MAX_INBUF_SIZE, FALSE);
	client->output = o_stream_create_fd(fd_out, (size_t)-1, FALSE);
	client->io = io_add(fd_in, IO_READ, client_input, client);
	client->to_idle = timeout_add(CLIENT_IDLE_TIMEOUT_MSECS,
				      client_idle_timeout, client);
	o_stream_set_flush_callback(client->output, client_output, client);

	imap_urlauth_worker_client_count++;
	DLLIST_PREPEND(&imap_urlauth_worker_clients, client);

	i_set_failure_prefix("imap-urlauth[%s](%s): ",
			     my_pid, client->access_user);
	return client;
}
Exemplo n.º 30
0
void mail_index_set_permissions(struct mail_index *index,
				mode_t mode, gid_t gid, const char *gid_origin)
{
	index->mode = mode & 0666;
	index->gid = gid;

	i_free(index->gid_origin);
	index->gid_origin = i_strdup(gid_origin);
}