void fs_sis_try_unlink_hash_file(struct fs *sis_fs, struct fs_file *super_file)
{
	struct fs_file *hash_file;
	struct stat st1, st2;
	const char *dir, *hash, *hash_path;

	if (fs_sis_path_parse(sis_fs, super_file->path, &dir, &hash) == 0 &&
	    fs_stat(super_file, &st1) == 0 && st1.st_nlink == 2) {
		/* this may be the last link. if hashes/ file is the same,
		   delete it. */
		hash_path = t_strdup_printf("%s/"HASH_DIR_NAME"/%s", dir, hash);
		hash_file = fs_file_init(super_file->fs, hash_path,
					 FS_OPEN_MODE_READONLY);
		if (fs_stat(hash_file, &st2) == 0 &&
		    st1.st_ino == st2.st_ino &&
		    CMP_DEV_T(st1.st_dev, st2.st_dev)) {
			if (fs_delete(hash_file) < 0)
				i_error("%s", fs_last_error(hash_file->fs));
		}
		fs_file_deinit(&hash_file);
	}
}
int mail_transaction_log_sync_lock(struct mail_transaction_log *log,
				   const char *lock_reason,
				   uint32_t *file_seq_r, uoff_t *file_offset_r)
{
	i_assert(!log->index->log_sync_locked);

	if (mail_transaction_log_lock_head(log, lock_reason) < 0)
		return -1;

	/* update sync_offset */
	if (mail_transaction_log_file_map(log->head, log->head->sync_offset,
					  (uoff_t)-1) <= 0) {
		mail_transaction_log_file_unlock(log->head, t_strdup_printf(
			"%s - map failed", lock_reason));
		return -1;
	}

	log->index->log_sync_locked = TRUE;
	*file_seq_r = log->head->hdr.file_seq;
	*file_offset_r = log->head->sync_offset;
	return 0;
}
Exemple #3
0
void smtp_server_command_finished(struct smtp_server_command *cmd)
{
	struct smtp_server_connection *conn = cmd->context.conn;
	struct smtp_server_reply *reply;

	i_assert(cmd->state < SMTP_SERVER_COMMAND_STATE_FINISHED);
	cmd->state = SMTP_SERVER_COMMAND_STATE_FINISHED;

	DLLIST2_REMOVE(&conn->command_queue_head,
		       &conn->command_queue_tail, cmd);
	conn->command_queue_count--;
	conn->stats.reply_count++;

	i_assert(array_is_created(&cmd->replies));
	reply = array_idx_modifiable(&cmd->replies, 0);
	i_assert(reply->content != NULL);

	if (reply->content->status == 221 || reply->content->status == 421) {
		i_assert(cmd->replies_expected == 1);
		if (reply->content->status == 421) {
			smtp_server_connection_close(&conn, t_strdup_printf(
				"Server closed the connection: %s",
				smtp_server_reply_get_one_line(reply)));

		} else {
			smtp_server_connection_close(&conn,
				"Client has quit the connection");
		}
		smtp_server_command_unref(&cmd);
		return;
	} else if (cmd->input_locked) {
		if (cmd->input_captured)
			smtp_server_connection_input_halt(conn);
		smtp_server_connection_input_resume(conn);
	}

	smtp_server_command_unref(&cmd);
	smtp_server_connection_trigger_output(conn);
}
Exemple #4
0
static bool
master_login_auth_input_notfound(struct master_login_auth *auth,
				 const char *args)
{
	struct master_login_auth_request *request;
	unsigned int id;

	if (str_to_uint(args, &id) < 0) {
		i_error("Auth server sent corrupted NOTFOUND line");
		return FALSE;
	}

	request = master_login_auth_lookup_request(auth, id);
	if (request != NULL) {
		const char *reason = t_strdup_printf(
			"Authenticated user not found from userdb, "
			"auth lookup id=%u", id);
		request_internal_failure(request, reason);
		i_free(request);
	}
	return TRUE;
}
int client_open_save_dest_box(struct client_command_context *cmd,
			      const char *name, struct mailbox **destbox_r)
{
	struct mail_namespace *ns;
	struct mailbox *box;
	const char *error_string;
	enum mail_error error;

	ns = client_find_namespace(cmd, &name);
	if (ns == NULL)
		return -1;

	if (cmd->client->mailbox != NULL &&
	    mailbox_equals(cmd->client->mailbox, ns, name)) {
		*destbox_r = cmd->client->mailbox;
		return 0;
	}
	box = mailbox_alloc(ns->list, name, MAILBOX_FLAG_SAVEONLY);
	if (mailbox_open(box) < 0) {
		error_string = mailbox_get_last_error(box, &error);
		if (error == MAIL_ERROR_NOTFOUND) {
			client_send_tagline(cmd,  t_strdup_printf(
				"NO [TRYCREATE] %s", error_string));
		} else {
			client_send_box_error(cmd, box);
		}
		mailbox_free(&box);
		return -1;
	}
	if (cmd->client->enabled_features != 0) {
		if (mailbox_enable(box, cmd->client->enabled_features) < 0) {
			client_send_box_error(cmd, box);
			mailbox_free(&box);
			return -1;
		}
	}
	*destbox_r = box;
	return 0;
}
Exemple #6
0
static void service_process_log(struct service_process *process,
				bool default_fatal, const char *str)
{
	const char *data;

	if (process->service->log_fd[1] == -1) {
		i_error("%s", str);
		return;
	}

	/* log it via the log process in charge of handling
	   this process's logging */
	data = t_strdup_printf("%d %s %s %s\n",
			       process->service->log_process_internal_fd,
			       dec2str(process->pid),
			       default_fatal ? "DEFAULT-FATAL" : "FATAL", str);
	if (write(process->service->list->master_log_fd[1],
		  data, strlen(data)) < 0) {
		i_error("write(log process) failed: %m");
		i_error("%s", str);
	}
}
static int http_transfer_chunked_parse_size
(struct http_transfer_chunked_istream *tcstream)
{
	uoff_t size = 0, prev;

	/* chunk-size     = 1*HEXDIG */

	while (tcstream->cur < tcstream->end) {
		prev = tcstream->chunk_size;

		if (*tcstream->cur >= '0' && *tcstream->cur <= '9')
			size = *tcstream->cur-'0';
		else if (*tcstream->cur >= 'A' && *tcstream->cur <= 'F')
			size = *tcstream->cur-'A' + 10;
		else if (*tcstream->cur >= 'a' && *tcstream->cur <= 'f')
			size = *tcstream->cur-'a' + 10;
		else {
			if (tcstream->parsed_chars == 0) {
				tcstream->error = t_strdup_printf(
					"Expected chunk size digit, but found %s",
					_chr_sanitize(*tcstream->cur));
				return -1;
			}
			tcstream->parsed_chars = 0;
			return 1;
		}
		tcstream->chunk_size <<= 4;
		tcstream->chunk_size += size;
		if (tcstream->chunk_size < prev) {
			tcstream->error = "Chunk size exceeds integer limit";
			return -1;
		}
		tcstream->parsed_chars++;
		tcstream->cur++;
	}

	return 0;
}
Exemple #8
0
/* <settings checks> */
static bool auth_settings_check(void *_set, pool_t pool,
				const char **error_r)
{
	struct auth_settings *set = _set;
	const char *p;

	if (set->debug_passwords)
		set->debug = TRUE;
	if (set->debug)
		set->verbose = TRUE;

	if (set->cache_size > 0 && set->cache_size < 1024) {
		/* probably a configuration error.
		   older versions used megabyte numbers */
		*error_r = t_strdup_printf("auth_cache_size value is too small "
					   "(%"PRIuUOFF_T" bytes)",
					   set->cache_size);
		return FALSE;
	}

	if (*set->username_chars == '\0') {
		/* all chars are allowed */
		memset(set->username_chars_map, 1,
		       sizeof(set->username_chars_map));
	} else {
		for (p = set->username_chars; *p != '\0'; p++)
			set->username_chars_map[(int)(uint8_t)*p] = 1;
	}

	if (*set->username_translation != '\0') {
		p = set->username_translation;
		for (; *p != '\0' && p[1] != '\0'; p += 2)
			set->username_translation_map[(int)(uint8_t)*p] = p[1];
	}
	set->realms_arr =
		(const char *const *)p_strsplit_spaces(pool, set->realms, " ");
	return TRUE;
}
Exemple #9
0
static void test_net_is_in_network(void)
{
	static struct test_net_is_in_network_input input[] = {
		{ "1.2.3.4", "1.2.3.4", 32, TRUE },
		{ "1.2.3.4", "1.2.3.3", 32, FALSE },
		{ "1.2.3.4", "1.2.3.5", 32, FALSE },
		{ "1.2.3.4", "1.2.2.4", 32, FALSE },
		{ "1.2.3.4", "1.1.3.4", 32, FALSE },
		{ "1.2.3.4", "0.2.3.4", 32, FALSE },
		{ "1.2.3.253", "1.2.3.254", 31, FALSE },
		{ "1.2.3.254", "1.2.3.254", 31, TRUE },
		{ "1.2.3.255", "1.2.3.254", 31, TRUE },
		{ "1.2.3.255", "1.2.3.0", 24, TRUE },
		{ "1.2.255.255", "1.2.254.0", 23, TRUE },
		{ "255.255.255.255", "128.0.0.0", 1, TRUE },
		{ "255.255.255.255", "127.0.0.0", 1, FALSE }
#ifdef HAVE_IPV6
		,
		{ "1234:5678::abcf", "1234:5678::abce", 127, TRUE },
		{ "1234:5678::abcd", "1234:5678::abce", 127, FALSE },
		{ "123e::ffff", "123e::0", 15, TRUE },
		{ "123d::ffff", "123e::0", 15, FALSE }
#endif
	};
	struct ip_addr ip, net_ip;
	unsigned int i;
	bool success;

	test_begin("net_is_in_network()");
	for (i = 0; i < N_ELEMENTS(input); i++) {
		test_assert(net_addr2ip(input[i].ip, &ip) == 0);
		test_assert(net_addr2ip(input[i].net, &net_ip) == 0);
		success = net_is_in_network(&ip, &net_ip, input[i].bits) ==
			input[i].ret;
		test_out(t_strdup_printf("net_is_in_network(%u)", i), success);
	}
	test_end();
}
Exemple #10
0
static struct dbox_file *
mdbox_file_init_full(struct mdbox_storage *storage,
		     uint32_t file_id, bool alt_dir)
{
	struct mdbox_file *file;
	const char *fname;
	unsigned int count;

	file = file_id == 0 ? NULL :
		mdbox_find_and_move_open_file(storage, file_id);
	if (file != NULL) {
		file->file.refcount++;
		return &file->file;
	}

	count = array_count(&storage->open_files);
	if (count > MDBOX_MAX_OPEN_UNUSED_FILES) {
		mdbox_close_open_files(storage,
				       count - MDBOX_MAX_OPEN_UNUSED_FILES);
	}

	file = i_new(struct mdbox_file, 1);
	file->storage = storage;
	file->file.storage = &storage->storage;
	file->file_id = file_id;
	fname = file_id == 0 ? dbox_generate_tmp_filename() :
		t_strdup_printf(MDBOX_MAIL_FILE_FORMAT, file_id);
	mdbox_file_init_paths(file, fname);
	dbox_file_init(&file->file);
	if (alt_dir)
		file->file.cur_path = file->file.alt_path;

	if (file_id != 0)
		array_append(&storage->open_files, &file, 1);
	else
		(void)mdbox_file_create(file);
	return &file->file;
}
static int
client_input_replicate(struct doveadm_connection *client, const char *const *args)
{
	struct replicator_queue_iter *iter;
	struct replicator_user *user;
	const char *usermask;
	enum replication_priority priority;
	unsigned int match_count;

	/* <priority> <username>|<mask> */
	if (str_array_length(args) != 2) {
		i_error("%s: REPLICATE: Invalid parameters", client->conn.name);
		return -1;
	}
	if (replication_priority_parse(args[0], &priority) < 0) {
		o_stream_send_str(client->conn.output, "-Invalid priority\n");
		return 0;
	}
	usermask = args[1];
	if (strchr(usermask, '*') == NULL && strchr(usermask, '?') == NULL) {
		replicator_queue_add(client->queue, usermask, priority);
		o_stream_send_str(client->conn.output, "+1\n");
		return 0;
	}

	match_count = 0;
	iter = replicator_queue_iter_init(client->queue);
	while ((user = replicator_queue_iter_next(iter)) != NULL) {
		if (!wildcard_match(user->username, usermask))
			continue;
		replicator_queue_add(client->queue, user->username, priority);
		match_count++;
	}
	replicator_queue_iter_deinit(&iter);
	o_stream_send_str(client->conn.output,
			  t_strdup_printf("+%u\n", match_count));
	return 0;
}
Exemple #12
0
static int
hardlink_replace(const char *src, const char *dest, ino_t src_inode)
{
	const char *p, *destdir, *tmppath;
	unsigned char randbuf[8];
	struct stat st;

	p = strrchr(dest, '/');
	i_assert(p != NULL);
	destdir = t_strdup_until(dest, p);

	random_fill_weak(randbuf, sizeof(randbuf));
	tmppath = t_strdup_printf("%s/temp.%s.%s.%s",
				  destdir, my_hostname, my_pid,
				  binary_to_hex(randbuf, sizeof(randbuf)));
	if (link(src, tmppath) < 0) {
		if (errno == EMLINK)
			return 0;
		i_error("link(%s, %s) failed: %m", src, tmppath);
		return -1;
	}
	if (stat(tmppath, &st) < 0) {
		i_error("stat(%s) failed: %m", tmppath);
		return -1;
	}
	if (st.st_ino != src_inode) {
		if (unlink(tmppath) < 0)
			i_error("unlink(%s) failed: %m", tmppath);
		return 0;
	}
	if (rename(tmppath, dest) < 0) {
		i_error("rename(%s, %s) failed: %m", src, tmppath);
		if (unlink(tmppath) < 0)
			i_error("unlink(%s) failed: %m", tmppath);
		return -1;
	}
	return 1;
}
static int
sieve_attribute_get_default(struct mail_storage *storage,
			    struct sieve_storage *svstorage,
			    struct mail_attribute_value *value_r)
{
	const char *scriptname;
	int ret;

	ret = sieve_storage_active_script_get_name(svstorage, &scriptname);
	if (ret == 0)
		return sieve_attribute_get_active_script(storage, svstorage, value_r);

	if (ret > 0) {
		value_r->value = t_strdup_printf("%c%s",
			MAILBOX_ATTRIBUTE_SIEVE_DEFAULT_LINK, scriptname);
		if (sieve_storage_active_script_get_last_change
				(svstorage, &value_r->last_change) < 0)
			ret = -1;
	}
	if (ret < 0)
		mail_storage_set_internal_error(storage);
	return ret;
}
Exemple #14
0
const char *message_date_create(time_t timestamp)
{
	struct tm *tm;
	int offset;
	bool negative;

	tm = localtime(&timestamp);
	offset = utc_offset(tm, timestamp);
	if (offset >= 0)
		negative = FALSE;
	else {
		negative = TRUE;
		offset = -offset;
	}

	return t_strdup_printf("%s, %02d %s %04d %02d:%02d:%02d %c%02d%02d",
			       weekday_names[tm->tm_wday],
			       tm->tm_mday,
			       month_names[tm->tm_mon],
			       tm->tm_year+1900,
			       tm->tm_hour, tm->tm_min, tm->tm_sec,
			       negative ? '-' : '+', offset / 60, offset % 60);
}
Exemple #15
0
static const char *test_aqueue2(unsigned int initial_size)
{
	ARRAY(unsigned int) aqueue_array;
	unsigned int i, j, k;

	for (i = 0; i < N_ELEMENTS(aqueue_input); i++) {
		for (k = 0; k < N_ELEMENTS(aqueue_input); k++) {
			struct aqueue *aqueue;

			t_array_init(&aqueue_array, initial_size);
			aqueue = aqueue_init(&aqueue_array.arr);
			aqueue->head = aqueue->tail = initial_size - 1;
			for (j = 0; j < k; j++) {
				aqueue_append(aqueue, &aqueue_input[j]);
				if (aqueue_count(aqueue) != j + 1) {
					return t_strdup_printf("Wrong count after append %u vs %u)",
							       aqueue_count(aqueue), j + 1);
				}
				if (!aqueue_is_ok(aqueue, UINT_MAX))
					return "Invalid data after append";
			}

			if (k != 0 && i < k) {
				aqueue_delete(aqueue, i);
				if (aqueue_count(aqueue) != k - 1)
					return "Wrong count after delete";
				if (!aqueue_is_ok(aqueue, i))
					return "Invalid data after delete";
			}
			aqueue_clear(aqueue);
			if (aqueue_count(aqueue) != 0)
				return "aqueue_clear() broken";
			aqueue_deinit(&aqueue);
		}
	}
	return NULL;
}
static int
acllist_append(struct acl_backend_vfile *backend, struct ostream *output,
	       const char *vname)
{
	struct acl_object *aclobj;
	struct acl_object_list_iter *iter;
	struct acl_rights rights;
	struct acl_backend_vfile_acllist acllist;
	const char *name;
	int ret;

	name = mail_namespace_get_storage_name(backend->backend.list->ns,
					       vname);
	acl_cache_flush(backend->backend.cache, name);
	aclobj = acl_object_init_from_name(&backend->backend, name);

	iter = acl_object_list_init(aclobj);
	while ((ret = acl_object_list_next(iter, &rights)) > 0) {
		if (acl_rights_has_nonowner_lookup_changes(&rights))
			break;
	}
	acl_object_list_deinit(&iter);

	if (acl_backend_vfile_object_get_mtime(aclobj, &acllist.mtime) < 0)
		ret = -1;

	if (ret > 0) {
		acllist.name = p_strdup(backend->acllist_pool, name);
		array_append(&backend->acllist, &acllist, 1);

		T_BEGIN {
			const char *line;
			line = t_strdup_printf("%s %s\n",
					       dec2str(acllist.mtime), name);
			o_stream_send_str(output, line);
		} T_END;
	}
Exemple #17
0
void http_server_request_finished(struct http_server_request *req)
{
	struct http_server_connection *conn = req->conn;
	struct http_server_response *resp = req->response;
	http_server_tunnel_callback_t tunnel_callback = resp->tunnel_callback;
	void *tunnel_context = resp->tunnel_context;

	http_server_request_debug(req, "Finished");

	i_assert(req->state < HTTP_SERVER_REQUEST_STATE_FINISHED);
	req->state = HTTP_SERVER_REQUEST_STATE_FINISHED;

	http_server_connection_remove_request(conn, req);
	conn->stats.response_count++;

	if (tunnel_callback == NULL && (req->req.connection_close || resp->close)) {
		if (resp->close) {
			http_server_connection_close(&conn,
				t_strdup_printf("Server closed connection: %u %s",
					resp->status, resp->reason));
			
		} else {
			http_server_connection_close(&conn,
				"Client requested connection close");
		}
		http_server_request_destroy(&req);
		return;
	}

	http_server_request_destroy(&req);
	if (tunnel_callback != NULL) {
		http_server_connection_tunnel(&conn, tunnel_callback, tunnel_context);
		return;
	}
	
	http_server_connection_trigger_responses(conn);
}
Exemple #18
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);
}
struct mail_namespace *
client_find_namespace_full(struct client *client,
			   const char **mailbox, const char **error_r)
{
	struct mail_namespace *namespaces = client->user->namespaces;
	struct mail_namespace *ns;
	string_t *utf8_name;

	utf8_name = t_str_new(64);
	if (imap_utf7_to_utf8(*mailbox, utf8_name) < 0) {
		*error_r = "NO Mailbox name is not valid mUTF-7";
		return NULL;
	}

	ns = mail_namespace_find(namespaces, str_c(utf8_name));
	if ((ns->flags & NAMESPACE_FLAG_AUTOCREATED) != 0 &&
	    ns->prefix_len == 0) {
		/* this matched only the autocreated prefix="" namespace.
		   give a nice human-readable error message */
		*error_r = t_strdup_printf(
			"NO Client tried to access nonexistent namespace. "
			"(Mailbox name should probably be prefixed with: %s)",
			mail_namespace_find_inbox(namespaces)->prefix);
		return NULL;
	}

	if ((client->set->parsed_workarounds &
	     		WORKAROUND_TB_EXTRA_MAILBOX_SEP) != 0 &&
	    str_len(utf8_name) > 0 &&
	    str_c(utf8_name)[str_len(utf8_name)-1] == mail_namespace_get_sep(ns)) {
		/* drop the extra trailing hierarchy separator */
		str_truncate(utf8_name, str_len(utf8_name)-1);
	}

	*mailbox = str_c(utf8_name);
	return ns;
}
Exemple #20
0
static int
openssl_iostream_verify_client_cert(int preverify_ok, X509_STORE_CTX *ctx)
{
	int ssl_extidx = SSL_get_ex_data_X509_STORE_CTX_idx();
	SSL *ssl;
	struct ssl_iostream *ssl_io;
	char certname[1024];
	X509_NAME *subject;

	ssl = X509_STORE_CTX_get_ex_data(ctx, ssl_extidx);
	ssl_io = SSL_get_ex_data(ssl, dovecot_ssl_extdata_index);
	ssl_io->cert_received = TRUE;

	subject = X509_get_subject_name(X509_STORE_CTX_get_current_cert(ctx));
	if (subject == NULL ||
	    X509_NAME_oneline(subject, certname, sizeof(certname)) == NULL)
		certname[0] = '\0';
	else
		certname[sizeof(certname)-1] = '\0'; /* just in case.. */
	if (preverify_ok == 0) {
		openssl_iostream_set_error(ssl_io, t_strdup_printf(
			"Received invalid SSL certificate: %s: %s",
			X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx)), certname));
		if (ssl_io->verbose_invalid_cert)
			i_info("%s", ssl_io->last_error);
	} else if (ssl_io->verbose) {
		i_info("Received valid SSL certificate: %s", certname);
	}
	if (preverify_ok == 0) {
		ssl_io->cert_broken = TRUE;
		if (!ssl_io->allow_invalid_cert) {
			ssl_io->handshake_failed = TRUE;
			return 0;
		}
	}
	return 1;
}
Exemple #21
0
static const char *
imapc_list_get_fs_name(struct imapc_mailbox_list *list, const char *name)
{
	struct mailbox_list *fs_list = imapc_list_get_fs(list);
	struct mail_namespace *ns = list->list.ns;
	const char *vname;
	char ns_sep = mail_namespace_get_sep(ns);

	if (name == NULL)
		return NULL;

	vname = mailbox_list_get_vname(&list->list, name);
	if (list->set->imapc_list_prefix[0] != '\0') {
		/* put back the prefix, so it gets included in the filesystem. */
		unsigned int vname_len = strlen(vname);

		if (ns->prefix_len > 0) {
			/* skip over the namespace prefix */
			i_assert(strncmp(vname, ns->prefix, ns->prefix_len-1) == 0);
			if (vname_len == ns->prefix_len-1)
				vname = "";
			else {
				i_assert(vname[ns->prefix_len-1] == ns_sep);
				vname += ns->prefix_len;
			}
		}
		if (vname[0] == '\0') {
			vname = t_strconcat(ns->prefix,
				list->set->imapc_list_prefix, NULL);
		} else {
			vname = t_strdup_printf("%s%s%c%s", ns->prefix,
						list->set->imapc_list_prefix,
						ns_sep, vname);
		}
	}
	return mailbox_list_get_storage_name(fs_list, vname);
}
Exemple #22
0
static void pop3c_client_authenticate1(struct pop3c_client *client)
{
	const struct pop3c_client_settings *set = &client->set;

	if (client->set.debug) {
		if (set->master_user == NULL) {
			i_debug("pop3c(%s): Authenticating as %s",
				client->set.host, set->username);
		} else {
			i_debug("pop3c(%s): Authenticating as %s for user %s",
				client->set.host, set->master_user,
				set->username);
		}
	}

	if (set->master_user == NULL) {
		o_stream_nsend_str(client->output,
			t_strdup_printf("USER %s\r\n", set->username));
		client->state = POP3C_CLIENT_STATE_USER;
	} else {
		client->state = POP3C_CLIENT_STATE_AUTH;
		o_stream_nsend_str(client->output, "AUTH PLAIN\r\n");
	}
}
Exemple #23
0
static bool
list_parse_directives(struct list_directives_context *ctx,
		      const struct imap_arg *args, const char **error_r)
{
	const char *str;

	while (imap_arg_get_atom(args, &str) &&
	       strncmp(str, "$!", 2) == 0) {
		str += 2;

		if (strncmp(str, "unordered", 9) == 0) {
			if (str[9] == '\0')
				;
			else if (str[9] == '=' &&
				 str_to_uint(str + 10, &ctx->chain_count) == 0)
				;
			else {
				*error_r = "Broken $!unordered directive";
				return FALSE;
			}
		} else if (strcmp(str, "ordered") == 0 ||
			   strcmp(str, "noextra") == 0 ||
			   strcmp(str, "extra") == 0 ||
			   strncmp(str, "ignore=", 7) == 0 ||
			   strncmp(str, "ban=", 4) == 0) {
			/* ok */
		} else {
			*error_r = t_strdup_printf("Unknown directive: %s",
						   str);
			return FALSE;
		}
		ctx->directives = TRUE;
		args++;
	}
	return TRUE;
}
Exemple #24
0
static void
login_host_callback(const struct ip_addr *ip, const char *errormsg,
		    void *context)
{
	struct login_host_request *request = context;
	struct director *dir = request->conn->dir;
	const char *line, *line_params;
	unsigned int secs;

	if (ip == NULL) {
		if (strncmp(request->line, "OK\t", 3) == 0)
			line_params = request->line + 3;
		else if (strncmp(request->line, "PASS\t", 5) == 0)
			line_params = request->line + 5;
		else
			i_panic("BUG: Unexpected line: %s", request->line);

		i_error("director: User %s host lookup failed: %s",
			request->username, errormsg);
		line = t_strconcat("FAIL\t", t_strcut(line_params, '\t'),
				   "\ttemp", NULL);
	} else if (request->director_proxy_maybe &&
		   login_host_request_is_self(request, ip)) {
		line = request->line;
	} else {
		secs = dir->set->director_user_expire / 2;
		line = t_strdup_printf("%s\thost=%s\tproxy_refresh=%u",
				       request->line, net_ip2addr(ip), secs);
	}
	login_connection_send_line(request->conn, line);

	login_connection_unref(&request->conn);
	i_free(request->username);
	i_free(request->line);
	i_free(request);
}
int acl_mailbox_update_acl(struct mailbox_transaction_context *t,
			   const struct acl_rights_update *update)
{
	struct acl_object *aclobj;
	const char *key;
	time_t ts = update->last_change != 0 ?
		update->last_change : ioloop_time;

	key = t_strdup_printf(MAILBOX_ATTRIBUTE_PREFIX_ACL"%s",
			      acl_rights_get_id(&update->rights));
	aclobj = acl_mailbox_get_aclobj(t->box);
	if (acl_object_update(aclobj, update) < 0) {
		mail_storage_set_critical(t->box->storage, "Failed to set ACL");
		return -1;
	}

	/* FIXME: figure out some value lengths, so maybe some day
	   quota could apply to ACLs as well. */
	if (acl_mailbox_update_removed_id(aclobj, update))
		mail_index_attribute_unset(t->itrans, FALSE, key, ts);
	else
		mail_index_attribute_set(t->itrans, FALSE, key, ts, 0);
	return 0;
}
Exemple #26
0
static int mbox_write_content_length(struct mbox_save_context *ctx)
{
	uoff_t end_offset;
	const char *str;
	size_t len;

	i_assert(ctx->eoh_offset != (uoff_t)-1);

	if (ctx->mbox->mbox_writeonly) {
		/* we can't seek, don't set Content-Length */
		return 0;
	}

	end_offset = ctx->output->offset;

	/* write Content-Length headers */
	str = t_strdup_printf("\nContent-Length: %s",
			      dec2str(end_offset - ctx->eoh_offset));
	len = strlen(str);

	/* flush manually here so that we don't confuse seek() errors with
	   buffer flushing errors */
	if (o_stream_flush(ctx->output) < 0)
		return write_error(ctx);
	if (o_stream_seek(ctx->output, ctx->extra_hdr_offset +
			  ctx->space_end_idx - len) < 0)
		return mbox_set_syscall_error(ctx->mbox, "o_stream_seek()");

	if (o_stream_send(ctx->output, str, len) < 0 ||
	    o_stream_flush(ctx->output) < 0)
		return write_error(ctx);

	if (o_stream_seek(ctx->output, end_offset) < 0)
		return mbox_set_syscall_error(ctx->mbox, "o_stream_seek()");
	return 0;
}
Exemple #27
0
int mail_user_init(struct mail_user *user, const char **error_r)
{
	const struct mail_storage_settings *mail_set;
	const char *home, *key, *value;
	bool need_home_dir;

	need_home_dir = user->_home == NULL &&
		settings_vars_have_key(user->set_info, user->set,
				       'h', "home", &key, &value);

	/* expand mail_home setting before calling mail_user_get_home() */
	settings_var_expand(user->set_info, user->set,
			    user->pool, mail_user_var_expand_table(user));

	if (need_home_dir && mail_user_get_home(user, &home) <= 0) {
		*error_r = t_strdup_printf(
			"userdb didn't return a home directory, "
			"but %s used it (%%h): %s", key, value);
		return -1;
	}

	if (mail_user_expand_plugins_envs(user, error_r) < 0)
		return -1;

	mail_set = mail_user_set_get_storage_set(user);
	user->mail_debug = mail_set->mail_debug;

	user->initialized = TRUE;
	hook_mail_user_created(user);

	if (user->error != NULL) {
		*error_r = t_strdup(user->error);
		return -1;
	}
	return 0;
}
/* <settings checks> */
static bool
master_service_ssl_settings_check(void *_set, pool_t pool ATTR_UNUSED,
				  const char **error_r)
{
	struct master_service_ssl_settings *set = _set;

	if (strcmp(set->ssl, "no") == 0) {
		/* disabled */
		return TRUE;
	}
#ifndef HAVE_SSL
	*error_r = t_strdup_printf("SSL support not compiled in but ssl=%s",
				   set->ssl);
	return FALSE;
#else
	/* we get called from many different tools, possibly with -O parameter,
	   and few of those tools care about SSL settings. so don't check
	   ssl_cert/ssl_key/etc validity here except in doveconf, because it
	   usually is just an extra annoyance. */
#ifdef CONFIG
	if (*set->ssl_cert == '\0') {
		*error_r = "ssl enabled, but ssl_cert not set";
		return FALSE;
	}
	if (*set->ssl_key == '\0') {
		*error_r = "ssl enabled, but ssl_key not set";
		return FALSE;
	}
#endif
	if (set->ssl_verify_client_cert && *set->ssl_ca == '\0') {
		*error_r = "ssl_verify_client_cert set, but ssl_ca not";
		return FALSE;
	}
	return TRUE;
#endif
}
Exemple #29
0
static const char *
i_stream_mail_get_cached_mail_id(struct mail_istream *mstream)
{
	static const char *headers[] = {
		"Message-Id",
		"Date",
		"Subject"
	};
	struct mail *mail = mstream->mail;
	enum mail_lookup_abort orig_lookup_abort;
	const char *value, *ret = "";
	unsigned int i;

	orig_lookup_abort = mail->lookup_abort;
	mail->lookup_abort = MAIL_LOOKUP_ABORT_NOT_IN_CACHE;
	for (i = 0; i < N_ELEMENTS(headers); i++) {
		if (mail_get_first_header(mail, headers[i], &value) > 0) {
			ret = t_strdup_printf("%s=%s", headers[i], value);
			break;
		}
	}
	mail->lookup_abort = orig_lookup_abort;
	return ret;
}
Exemple #30
0
static void
imapc_sync_add_missing_deleted_flags(struct imapc_sync_context *ctx,
				     uint32_t seq1, uint32_t seq2)
{
	const struct mail_index_record *rec;
	uint32_t seq, uid1, uid2;
	const char *cmd;

	/* if any of them has a missing \Deleted flag,
	   just add it to all of them. */
	for (seq = seq1; seq <= seq2; seq++) {
		rec = mail_index_lookup(ctx->sync_view, seq);
		if ((rec->flags & MAIL_DELETED) == 0)
			break;
	}

	if (seq <= seq2) {
		mail_index_lookup_uid(ctx->sync_view, seq1, &uid1);
		mail_index_lookup_uid(ctx->sync_view, seq2, &uid2);
		cmd = t_strdup_printf("UID STORE %u:%u +FLAGS \\Deleted",
				      uid1, uid2);
		imapc_sync_cmd(ctx, cmd);
	}
}