Ejemplo n.º 1
0
/**
 * @brief	Merge a list of smtp message headers into a single string, preceded by the leading text and followed by the trailing text.
 * @param	headers		an inx holder containing a collection of header string data to be merged together.
 * @param	leading		a managed string containing text that will lead each header line.
 * @param	trailing	a managed string containing text that will trail each header line.
 * @return	NULL on failure or a managed string containing the merged headers on success.
 */
stringer_t * portal_smtp_merge_headers(inx_t *headers, stringer_t *leading, stringer_t *trailing) {

	stringer_t *result = NULL, *tmp, *current;
	inx_cursor_t *cursor;

	if (!headers || !leading || !trailing) {
		return NULL;
	}

	if (!(cursor = inx_cursor_alloc(headers))) {
		return NULL;
	}

	while ((current = inx_cursor_value_next(cursor))) {

		if (!(tmp = st_merge("ssss", result, leading, current, trailing))) {
			inx_cursor_free(cursor);
			st_cleanup(result);
			return NULL;
		}

		result = tmp;
	}

	inx_cursor_free(cursor);

	// We should at least return an empty managed string if we have a valid inx holder but no data in it.
	if (!result) {
		result = st_alloc(0);
	}

	return result;
}
Ejemplo n.º 2
0
bool_t check_inx_cursor_sthread(check_inx_opt_t *opts) {

	void *val;
	inx_t *inx;
	multi_t key;
	inx_cursor_t *cursor;
	uint64_t rnum, num = 0;

	if (!opts || !(inx = opts->inx) || !(cursor = inx_cursor_alloc(opts->inx))) {
		return false;
	}

	while (!(val = inx_cursor_value_next(cursor))) {

		key = inx_cursor_key_active(cursor);
		uint64_conv_st(val, &rnum);

		if (key.type != M_TYPE_UINT64 || key.val.u64 != rnum) {
			inx_cursor_free(cursor);
			return false;
		}

		num++;
	}

	inx_cursor_free(cursor);

	// Make sure we iterated through more than 90% of possible values num.
	if (num >= ((INX_CHECK_OBJECTS * INX_CHECK_MTHREADS) * 0.9)) {
		return false;
	}

	return true;
}
Ejemplo n.º 3
0
/**
 * @brief	Get the UIDL for a message or collection of messages, in response to a POP3 UIDL command.
 * @param	con		the POP3 client connection issuing the command.
 * @return	This function returns no value.
 */
void pop_uidl(connection_t *con) {

	uint64_t number;
	inx_cursor_t *cursor;
	meta_message_t *active;
	bool_t result;

	if (con->pop.session_state != 1) {
		pop_invalid(con);
		return;
	}

	// Get the argument, if any.
	result = pop_num_parse(con, &number, false);

	meta_user_rlock(con->pop.user);

	// Output all of the messages that aren't deleted or appended.
	if (!result) {
		number = 1;
		con_print(con, "+OK %llu messages total.\r\n", pop_total_messages(con->pop.user->messages));

		if (con->pop.user->messages && (cursor = inx_cursor_alloc(con->pop.user->messages))) {

			while ((active = inx_cursor_value_next(cursor))) {

				if ((active->status & (MAIL_STATUS_APPENDED | MAIL_STATUS_HIDDEN)) == 0) {
					con_print(con, "%llu %llu\r\n", number++, active->messagenum);
				} else if ((active->status & MAIL_STATUS_APPENDED) == 0) {
					number++;
				}

			}

			inx_cursor_free(cursor);
		}

		con_write_bl(con, ".\r\n", 3);
	}
	// Output a specific message.
	else {

		if (!(active = pop_get_message(con->pop.user->messages, number))) {
			con_write_bl(con, "-ERR Message not found.\r\n", 25);
		}
		else if ((active->status & MAIL_STATUS_HIDDEN) == MAIL_STATUS_HIDDEN) {
			con_write_bl(con, "-ERR Message marked for deletion.\r\n", 35);
		}
		else {
			con_print(con, "+OK %llu %llu\r\n", number, active->messagenum);
		}

	}

	meta_user_unlock(con->pop.user);

	return;
}
Ejemplo n.º 4
0
void imap_session_destroy(connection_t *con) {

	inx_cursor_t *cursor;
	meta_message_t *active;

	meta_user_wlock(con->imap.user);

	// If a folder was selected, clear the recent flag before closing the mailbox.
	if (con->imap.session_state == 1 && con->imap.user && con->imap.selected && !con->imap.read_only &&
		(cursor = inx_cursor_alloc(con->imap.user->messages))) {

		while ((active = inx_cursor_value_next(cursor))) {

			if (active->foldernum == con->imap.selected && (active->status & MAIL_STATUS_RECENT) == MAIL_STATUS_RECENT) {
				active->status = (active->status | MAIL_STATUS_RECENT) ^ MAIL_STATUS_RECENT;
			}

		}

		inx_cursor_free(cursor);
	}

	meta_user_unlock(con->imap.user);

	// Is there a user session.
	if (con->imap.user) {

		if (con->imap.username) {
			meta_remove(con->imap.username, META_PROT_IMAP);
		}

	}

	st_cleanup(con->imap.username);
	st_cleanup(con->imap.tag);
	st_cleanup(con->imap.command);

	if (con->imap.arguments) {
		ar_free(con->imap.arguments);
	}

	mail_cache_reset();

	return;
}
Ejemplo n.º 5
0
// QUESTION: Shouldn't failure return -1?
int_t magma_folder_children(inx_t *folders, uint64_t target) {

	int_t result = 0;
	inx_cursor_t *cursor;
	magma_folder_t *active = NULL;

	if (!target || !(cursor = inx_cursor_alloc(folders))) {
		return 0;
	}

	while ((active = inx_cursor_value_next(cursor)) && !result) {

		if (active->parent == target) {
			result++;
		}

	}

	inx_cursor_free(cursor);

	return result;
}
Ejemplo n.º 6
0
/**
 * Verifies that we can read all of the data out of the storage tank correctly.
 *
 * @param check_collection The collection of sums to verify.
 * @return Returns true only if all of the objects in the linked list match the expected hash value.
 */
bool_t check_tokyo_tank_cleanup(inx_t *check_collection) {

	inx_cursor_t *cursor;
	check_tank_obj_t *obj;

	if (!(cursor = inx_cursor_alloc(check_collection))) {
		return false;
	}

	while (status() && (obj = inx_cursor_value_next(cursor))) {

		if (!tank_delete(TANK_CHECK_DATA_HNUM, obj->tnum, TANK_CHECK_DATA_UNUM, obj->onum)) {
			log_info("%lu - tank_delete error", obj->onum);
			inx_cursor_free(cursor);
			return false;
		}
	}

	inx_cursor_free(cursor);

	return true;
}
Ejemplo n.º 7
0
/**
 * @brief	Populate a contact entry with its details from the database.
 * @param	contact		a pointer to the contact entry object that will be updated.
 * @return	-1 on failure or 1 on success.
 */
int_t contact_details_fetch(contact_t *contact) {

	row_t *row;
	table_t *result;
	MYSQL_BIND parameters[1];
	contact_detail_t *record;
	multi_t key = { .type = M_TYPE_STRINGER, .val.st = NULL };

	mm_wipe(parameters, sizeof(parameters));

	if (!contact || !contact->contactnum) {
		log_pedantic("Invalid data passed to contact details fetch.");
		return -1;
	}

	// Contact Number
	parameters[0].buffer_type = MYSQL_TYPE_LONGLONG;
	parameters[0].buffer_length = sizeof(uint64_t);
	parameters[0].buffer = &(contact->contactnum);
	parameters[0].is_unsigned = true;

	if (!(result = stmt_get_result(stmts.select_contact_details, parameters))) {
		log_pedantic("Unable to fetch the contact details.");
		return -1;
	}

	// Loop through each of the row and create a contact record. When were finished we'll fetch the contact details for each record found.
	while ((row = res_row_next(result))) {

		if (!(record = contact_detail_alloc(PLACER(res_field_block(row, 0), res_field_length(row, 0)),
			PLACER(res_field_block(row, 1), res_field_length(row, 1)), res_field_uint64(row, 2))) ||
			!(key.val.st = record->key) || !inx_insert(contact->details, key, record)) {
			log_info("The index refused to accept a contact record. { contact = %lu }", res_field_uint64(row, 0));

			if (record) {
				contact_detail_free(record);
			}

			res_table_free(result);
			return -1;
		}

	}

	res_table_free(result);
	return 1;
}

/**
 * @brief	Retrieve all of a user's contact entries in a specified contacts folder from the database.
 * @param	usernum		the numerical id of the user whose contacts will be retrieved.
 * @param	folder		a pointer to the contact folder which will have its contents listed.
 * @return	-1 on failure or 1 on success.
 */
int_t contacts_fetch(uint64_t usernum, contact_folder_t *folder) {

	row_t *row;
	table_t *result;
	contact_t *record;
	inx_cursor_t *cursor;
	MYSQL_BIND parameters[2];
	multi_t key = { .type = M_TYPE_UINT64, .val.u64 = 0 };

	mm_wipe(parameters, sizeof(parameters));

	if (!usernum || !folder || !folder->foldernum) {
		log_pedantic("Invalid data passed for contact fetch.");
		return -1;
	}

	// Usernum
	parameters[0].buffer_type = MYSQL_TYPE_LONGLONG;
	parameters[0].buffer_length = sizeof(uint64_t);
	parameters[0].buffer = &(usernum);
	parameters[0].is_unsigned = true;

	// Folder Number
	parameters[1].buffer_type = MYSQL_TYPE_LONGLONG;
	parameters[1].buffer_length = sizeof(uint64_t);
	parameters[1].buffer = &(folder->foldernum);
	parameters[1].is_unsigned = true;

	if (!(result = stmt_get_result(stmts.select_contacts, parameters))) {
		log_pedantic("Unable to fetch the folder contacts.");
		return -1;
	}

	// Loop through each of the row and create a contact record. When were finished we'll fetch the contact details for each record found.
	while ((row = res_row_next(result))) {
		if (!(record = contact_alloc(res_field_uint64(row, 0), PLACER(res_field_block(row, 1), res_field_length(row, 1)))) ||
			!(key.val.u64 = record->contactnum) || !inx_insert(folder->records, key, record)) {
			log_info("The index refused to accept a contact record. { contact = %lu }", res_field_uint64(row, 0));
			if (record) contact_free(record);
			res_table_free(result);
			return -1;
		}
	}

	res_table_free(result);

	/// LOW: Should we bother with error checking?
	if ((cursor = inx_cursor_alloc(folder->records))) {
		while ((record = inx_cursor_value_next(cursor))) {
			contact_details_fetch(record);
		}

		inx_cursor_free(cursor);
	}

	return 1;
}
Ejemplo n.º 8
0
/**
 * Verifies that we can read all of the data out of the storage tank correctly.
 *
 * @param check_collection The collection of sums to verify.
 * @return Returns true only if all of the objects in the linked list match the expected hash value.
 */
bool_t check_tokyo_tank_verify(inx_t *check_collection) {

	stringer_t *data;
	check_tank_obj_t *obj;
	inx_cursor_t *cursor;

	if (!(cursor = inx_cursor_alloc(check_collection))) {
		return false;
	}

	while (status() && (obj = inx_cursor_value_next(cursor))) {

		if (!(data = tank_load(TANK_CHECK_DATA_HNUM, obj->tnum, TANK_CHECK_DATA_UNUM, obj->onum))) {
			log_info("%lu - tank_get error", obj->onum);
			inx_cursor_free(cursor);
			return false;
		}

		if (obj->adler32 != hash_adler32(st_data_get(data), st_length_get(data))) {
			log_info("%lu - adler32 error", obj->onum);
			inx_cursor_free(cursor);
			st_free(data);
			return false;
		}

		if (obj->fletcher32 != hash_fletcher32(st_data_get(data), st_length_get(data))) {
			log_info("%lu - fletcher32 error", obj->onum);
			inx_cursor_free(cursor);
			st_free(data);
			return false;
		}

		if (obj->crc32 != hash_crc32(st_data_get(data), st_length_get(data))) {
			log_info("%lu - crc32 error", obj->onum);
			inx_cursor_free(cursor);
			st_free(data);
			return false;
		}

		if (obj->crc64 != hash_crc64(st_data_get(data), st_length_get(data))) {
			log_info("%lu - crc64 error", obj->onum);
			inx_cursor_free(cursor);
			st_free(data);
			return false;
		}

		if (obj->murmur32 != hash_murmur32(st_data_get(data), st_length_get(data))) {
			log_info("%lu - murmur32 error", obj->onum);
			inx_cursor_free(cursor);
			st_free(data);
			return false;
		}

		if (obj->murmur64 != hash_murmur64(st_data_get(data), st_length_get(data))) {
			log_info("%lu - murmur64 error", obj->onum);
			inx_cursor_free(cursor);
			st_free(data);
			return false;
		}

		st_free(data);
	}

	inx_cursor_free(cursor);
	return true;
}
Ejemplo n.º 9
0
/**
 * Returns 0 if the selected folder wasn't modified, or 1 if things changed and the updated status should be sent to the client. A -1
 * is used to indicate the update check encountered a problem and should be retried later.
 */
int_t imap_session_update(connection_t *con) {

	int_t result = 0;
	inx_cursor_t *cursor;
	meta_message_t *active;
	uint64_t recent = 0, exists = 0, checkpoint;

	// Check for the right state.
	if (con->imap.session_state != 1 || con->imap.user == NULL || con->imap.selected == 0) {
		return -1;
	}

	if ((checkpoint = serial_get(OBJECT_USER, con->imap.user->usernum)) != con->imap.user_checkpoint) {
		meta_user_wlock(con->imap.user);

		// Update the user preferences.
		if (checkpoint != con->imap.user->serials.user) {
			meta_user_update(con->imap.user, META_LOCKED);
		}

		// Store the new checkpoint.
		con->imap.user_checkpoint = con->imap.user->serials.user;
		meta_user_unlock(con->imap.user);
	}

	if ((checkpoint = serial_get(OBJECT_FOLDERS, con->imap.user->usernum)) != con->imap.folders_checkpoint) {
		meta_user_wlock(con->imap.user);

	   // Update the list of folders.
		if (checkpoint != con->imap.user->serials.folders) {
			meta_folders_update(con->imap.user, META_LOCKED);
		}

		// Store the new checkpoint.
		con->imap.folders_checkpoint = con->imap.user->serials.folders;
		meta_user_unlock(con->imap.user);
	}

	if ((checkpoint = serial_get(OBJECT_MESSAGES, con->imap.user->usernum)) != con->imap.messages_checkpoint) {
		meta_user_wlock(con->imap.user);

		if (checkpoint != con->imap.user->serials.messages) {
			meta_messages_update(con->imap.user, META_LOCKED);
		}

		// If there is a selected folder, scan the status.
		if ((cursor = inx_cursor_alloc(con->imap.user->messages))) {

			while ((active = inx_cursor_value_next(cursor))) {

				if (active->foldernum == con->imap.selected && (active->status & MAIL_STATUS_RECENT) == MAIL_STATUS_RECENT) {
					recent++;
					exists++;
				}
				else if (active->foldernum == con->imap.selected) {
					exists++;
				}

			}

			inx_cursor_free(cursor);
		}

		// If the folder has changed, output the current status.
		if (con->imap.messages_recent != recent || con->imap.messages_total != exists) {
			con->imap.messages_recent = recent;
			con->imap.messages_total = exists;
			result = 1;
		}

		// Store the new checkpoint.
		con->imap.messages_checkpoint = con->imap.user->serials.messages;

		meta_user_unlock(con->imap.user);
	}

	return result;
}
Ejemplo n.º 10
0
/**
 * @brief	Send (relay) a message composed by a user via a portal session.
 * @see	smtp_relay_message() - a lot of logic borrowed from here.
 * @param	from		a pointer to a managed string containing the email address specified as the From address.
 * @param	to			a pointer to a managed string containing the destination email address of the message.
 * @param	data		a pointer to a managed string containing the raw data of the mail message.
 * @param	send_size	if greater than 0, specify the optional SIZE parameter to the MAIL FROM command.
 * @param	errmsg		the address of a pointer to a null-terminated string that will be set to a descriptive error message on failure.
 * @return	true if the mail message was sent successfully, or false otherwise.
 */
bool_t portal_smtp_relay_message(stringer_t *from, inx_t *to, stringer_t *data, size_t send_size, chr_t **errmsg) {

	inx_cursor_t *cursor;
	stringer_t *to_address;
	client_t *client;
	int_t state, nsentto = 0;

	if (!from || !to || !data || !errmsg) {
		*errmsg = "Unexpected internal failure occurred while sending message.";
		return false;
	}

	/*if (mail_add_outbound_headers(con) != 1) {
		log_pedantic("Could not add the outbound headers.");
		return false;
	}*/

	// Open the connection to the SMTP server.
	if (!(client = smtp_client_connect(0))) {
		*errmsg = "Encountered transport error with relay server.";
		return false;
	}

	// Send HELO.
	if (smtp_client_send_helo(client)!= 1) {
		*errmsg = "Handshake with relay server failed.";
		smtp_client_close(client);
		return false;
	}

	// Send MAIL FROM.
	if ((state = smtp_client_send_mailfrom(client, from, send_size)) != 1) {
		*errmsg = "Error occurred while sending From field to email server.";
		smtp_client_close(client);
		return false;
	}

	// Send the RCPT TO command.
	if (!(cursor = inx_cursor_alloc(to))) {
		*errmsg = "Internal occurred while expanding recipient list.";
		smtp_client_close(client);
		return false;
	}

	while ((to_address = inx_cursor_value_next(cursor))) {

		if ((state = smtp_client_send_rcptto(client, to_address)) != 1) {
			*errmsg = "Error occurred while specifying recipient to email server.";
			smtp_client_close(client);
			inx_cursor_free(cursor);
			return false;
		}

		nsentto++;
	}

	inx_cursor_free(cursor);

	if (!nsentto) {
		*errmsg = "Mail message could not be sent without recipient.";
		smtp_client_close(client);
		return false;
	}

	// Send the the message.
	if ((state = smtp_client_send_data(client, data)) != 1) {
		*errmsg = "Error occurred while sending email message body.";
		smtp_client_close(client);
		return false;
	}

	// Store the result.
	//*result = st_dupe_opts(MANAGED_T | CONTIGUOUS | HEAP, &(client->line));
	smtp_client_close(client);

	// TODO: smtp_update_transmission_stats() needs to be called here.
	return true;
}
Ejemplo n.º 11
0
/**
 * @brief	Create the data of an outbound smtp message that will be specified with the smtp DATA command.
 * @param	attachments		an optional inx holder containing a list of attachments to be included in the message.
 * @param	from			a managed string containing the email address sending the message.
 * @param	to				an inx holder containing a list of To: email recipients as managed strings.
 * @param	cc				an inx holder containing a list of 0 or more CC: recipients as managed strings.
 * @param	bcc				an inx holder containing a list of 0 or more BCC: recipients as managed strings.
 * @param	subject			a managed string containing the subject of the message.
 * @param	body_plain		an optional managed string containing the plain text body of the message.
 * @param	body_html		an optional managed string containing the html-formatted body of the message.
 * @return	NULL on failure or a managed string containing the packaged outbound smtp message data on success.
 */
stringer_t * portal_smtp_create_data(inx_t *attachments, stringer_t *from, inx_t *to, inx_t *cc, inx_t *bcc, stringer_t *subject, stringer_t *body_plain, stringer_t *body_html) {

		inx_cursor_t *cursor = NULL;
		array_t *all_attachments = NULL;
		attachment_t *attachment;
		stringer_t *result = NULL, *boundary = NULL, *mime_data, *tmp;
		size_t nattached = 0;

		if (attachments && (!(cursor = inx_cursor_alloc(attachments)))) {
			log_pedantic("Unable to read message attachments.");
			return NULL;
		} else if (attachments) {

			while ((attachment = inx_cursor_value_next(cursor))) {

					// We are creating an array of all the attachment data. It needs to be ARRAY_TYPE_POINTER so deallocating the array doesn't free the underlying data.
					if (attachment->filedata && !ar_append(&all_attachments, ARRAY_TYPE_POINTER, attachment->filedata)) {
						log_pedantic("Unable to parse message attachments.");
						inx_cursor_free(cursor);
						if (all_attachments) ar_free(all_attachments);
						return NULL;
					}

			}

			if (all_attachments) {
				nattached = ar_length_get(all_attachments);
			}

		}

		if (!nattached) {

			if (cursor) {
				inx_cursor_free(cursor);
			}

			if (!(result = mail_mime_get_smtp_envelope(from, to, cc, bcc, subject, boundary, false))) {
						log_pedantic("Unable to generate smtp envelope for outbound mail.");
						return NULL;
			}

		} else {

			// TODO: This should really happen after encoding is performed, but the chances of a collision are still infinitesimal.
			// Now that we have all the attachment data in an array, we can generate a unique boundary string.
			if (!(boundary = mail_mime_generate_boundary(all_attachments))) {
				log_pedantic("Unable to generate boundary for MIME attachments.");
				inx_cursor_free(cursor);
				ar_free(all_attachments);
				return NULL;
			}

			ar_free(all_attachments);

			// Get the envelope for a message that has attachments.
			if (!(result = mail_mime_get_smtp_envelope(from, to, cc, bcc, subject, boundary, true))) {
				log_pedantic("Unable to generate smtp envelope for outbound mail.");
				inx_cursor_free(cursor);
				st_free(boundary);
				return NULL;
			}

			// Now that we have the envelope, the first content is the actual email body.
			if (!(tmp = st_merge("snsnsn", result, "--------------", boundary, "\r\nContent-Type: text-plain\r\nContent-Transfer-Encoding: 7bit\r\n\r\n", body_plain, "\r\n"))) {
				log_pedantic("Unable to pack message body into outbound message.");
				inx_cursor_free(cursor);
				st_free(boundary);
				return NULL;
			}

			st_free(result);
			result = tmp;

			// Now go through each attachment, encode it, and append it to the envelope.
			inx_cursor_reset(cursor);

			while ((attachment = inx_cursor_value_next(cursor))) {

				if (!(mime_data = mail_mime_encode_part(attachment->filedata, attachment->filename, boundary))) {
					log_pedantic("Unable to mime encode part for message attachment.");
					inx_cursor_free(cursor);
					st_free(boundary);
					return NULL;
				}

				tmp = st_merge("ss", result, mime_data);
				st_free(mime_data);
				st_free(result);

				if (!tmp) {
					log_pedantic("Unable to allocate space for portal smtp message.");
					inx_cursor_free(cursor);
					return NULL;
				}

				result = tmp;
			}

			inx_cursor_free(cursor);

			// One final boundary at the end.
			tmp = st_merge("snsn", result, "\r\n--------------", boundary, "--");
			st_free(result);

			if (!tmp) {
				log_pedantic("Unable to allocate space for portal smtp message.");
				return NULL;
			}

			result = tmp;
		}

		return result;
}
Ejemplo n.º 12
0
/**
 * @brief	Load all magma configuration options specified by the user on the command line.
 * @note	Each key/value pair extracted from the database is submitted to the following logic:
 *	 			If a config option was loaded from the database, the key must allow it to be configurable via the database.
 *	 			Check to see that any key that has previously been set is allowed to be overwritten.
 * 				If the key is required, it may not contain an empty value.
 * 			Finally, this function sets the appropriate magma key corresponding to the config key.
 * 			All leftover keys not matched to global magma keys will be configured via servers, relay, and cache server options.
 * @return	true if all database config options were parsed and evaluated successfully, or false on failure.
 */
bool_t config_load_cmdline_settings(void) {
	multi_t name;
	magma_keys_t *key;
	inx_cursor_t *cursor;
	nvp_t *config_pairs = NULL;
	stringer_t *value;

	// If not set, then bail out.
	if (!cmdline_config_data)
		return true;

	// Load the command line options and convert them into a name/value pair structure.
	if (!(config_pairs = nvp_alloc())) {
		st_free(cmdline_config_data);
		return false;
	}
	else if (nvp_parse(config_pairs, cmdline_config_data) < 0) {
		nvp_free(config_pairs);
		st_free(cmdline_config_data);
		return false;
	}
	else if (!(cursor = inx_cursor_alloc(config_pairs->pairs))) {
		nvp_free(config_pairs);
		st_free(cmdline_config_data);
		return false;
	}

	// Our command line config data won't be necessary anymore.
	st_free(cmdline_config_data);

	// Run through all of the magma_keys and see if there is a matching name/value pair.
	while (!mt_is_empty(name = inx_cursor_key_next(cursor))) {

		value = inx_cursor_value_active(cursor);

		if ((key = config_key_lookup(name.val.st))) {

			// Make sure the setting can be provided via the configuration file.
			if (!key->file && value) {
					log_critical("%s cannot be changed using command line option.", key->name);
					inx_cursor_free(cursor);
					nvp_free(config_pairs);
					return false;
			}
			// Make sure the required magma_keys are not set to NULL.
			else if (key->required && st_empty(value)) {
				log_critical("%s requires a legal value.", key->name);
				inx_cursor_free(cursor);
				nvp_free(config_pairs);
				return false;
			}

			// Attempt to set the value.
			else if (!config_value_set(key, value)) {
				inx_cursor_free(cursor);
				nvp_free(config_pairs);
				return false;
			}

			// If a legit value was provided, then record that we've set this parameter.
			key->set = true;
		}

		// If we haven't had a match yet, check if its a server param.
		else if (name.val.st && !st_cmp_ci_starts(name.val.st, CONSTANT("magma.servers"))) {
			servers_config(name.val.st, value);
		}

		// If we haven't had a match yet, check if its a relay instance.
		else if (name.val.st && !st_cmp_ci_starts(name.val.st, CONSTANT("magma.relay"))) {
			relay_config(name.val.st, value);
		}

		else if (name.val.st && !st_cmp_ci_starts(name.val.st, CONSTANT("magma.iface.cache.host"))) {
			cache_config(name.val.st, value);
		}

		else {
			log_critical("%.*s is not a valid setting.", st_length_int(name.val.st), st_char_get(name.val.st));
			inx_cursor_free(cursor);
			nvp_free(config_pairs);
			return false;
		}
	}

	inx_cursor_free(cursor);
	nvp_free(config_pairs);

	return true;
}