Ejemplo n.º 1
0
bool_t check_inx_append_mthread(MAGMA_INDEX inx_type, stringer_t *errmsg) {

	void *result;
	inx_t *inx = NULL;
	bool_t outcome = true;
	pthread_t *threads = NULL;

	if (status() && (!(inx = inx_alloc(inx_type | M_INX_LOCK_MANUAL, &ns_free)))) {
		st_sprint(errmsg, "An error occured during initial allocation in the inx check append multi-threaded test.");
		outcome = false;
	}
	else {

		if (!INX_CHECK_MTHREADS || !(threads = mm_alloc(sizeof(pthread_t) * INX_CHECK_MTHREADS))) {
			outcome = false;
		}
		else {

			for (uint64_t counter = 0; counter < INX_CHECK_MTHREADS; counter++) {
				if (thread_launch(threads + counter, &check_inx_append_mthread_test, inx)) {
					st_sprint(errmsg, "An error occured when launching a thread.");
					outcome = false;
				}
			}

			for (uint64_t counter = 0; counter < INX_CHECK_MTHREADS; counter++) {
				if (thread_result(*(threads + counter), &result) || !result || !*(bool_t *)result) {
					if (st_empty(errmsg)) st_sprint(errmsg, "One of the append check threads returned false.");
					outcome = false;
				}

				mm_cleanup(result);
			}

			mm_free(threads);
		}

		if (inx_count(inx) != 0 && st_empty(errmsg)) {
			st_sprint(errmsg, "The index was not properly cleared.");
			outcome = false;
		}

	}

	if (inx) {
		inx_cleanup(inx);
	}

	return outcome;
}
Ejemplo n.º 2
0
bool_t check_inx_append_sthread(MAGMA_INDEX inx_type, stringer_t *errmsg) {

	inx_t *inx = NULL;
	bool_t outcome = true;

	if (status() && (!(inx = inx_alloc(inx_type | M_INX_LOCK_MANUAL, &ns_free)))) {
		st_sprint(errmsg, "An error occured during initial allocation in the inx check append single-threaded test.");
		outcome = false;
	}
	else if(!check_inx_append_helper(inx)) {
		st_sprint(errmsg, "An error occured inside append test helper.");
		outcome = false;
	}

	if (outcome && inx_count(inx) != 0) {
		st_sprint(errmsg, "The index was not properly cleared.");
		outcome = false;
	}

	inx_cleanup(inx);
	return outcome;
}
Ejemplo n.º 3
0
/**
 * @brief	Accept and verify a password for POP3 authentication.
 * @note	This command is only allowed for sessions which have not yet been authenticated, but which have already supplied a username.
 *			If the username/password combo was validated, the account information is retrieved and checked to see if it is locked.
 *			After successful authentication, this function will prohibit insecure connections for any user configured to use SSL only,
 *			and enforce the existence of only one POP3 session at a time.
 *			Finally, the database Log table for this user's POP3 access is updated, and all the user's messages are retrieved.
 * @param	con		the POP3 client connection issuing the command.
 * @return	This function returns no value.
 */
void pop_pass(connection_t *con) {

	int_t state;
	credential_t *cred;
	stringer_t *password, *username;

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

	// The user must come before the PASS command.
	if (st_empty(con->pop.username)) {
		con_write_bl(con, "-ERR You must supply a username first.\r\n", 40);
		return;
	}

	// If they didn't pass in a valid password.
	if (!(password = pop_pass_parse(con))) {
		con_write_bl(con, "-ERR Invalid PASS command.\r\n", 28);
		return;
	}

	// Hash the password.
	// First we need to get the regular username from the fully qualified one.
	if (!(username = credential_username(con->pop.username))) {
		con_write_bl(con, "-ERR Internal server error. Please try again later.\r\n", 53);
		st_wipe(password);
		st_free(password);
	}

	st_free(con->pop.username);
	con->pop.username = username;

	if (!(cred = credential_alloc_auth(con->pop.username, password))) {
		con_write_bl(con, "-ERR Internal server error. Please try again later.\r\n", 53);
		st_wipe(password);
		st_free(password);
		return;
	}

	st_wipe(password);
	st_free(password);

	// Pull the user info out.
	state = meta_get(con->pop.username, cred->auth.domain, cred->auth.password, cred->auth.key, META_PROT_POP, META_GET_MESSAGES, &(con->pop.user));

	// Securely delete this information, as these are the keys to the castle.
	credential_free(cred);

	// Not found, or invalid password.
	if (state == 0) {
		con_write_bl(con,  "-ERR The username and password combination is invalid.\r\n", 56);
		return;
	}
	// Internal error.
	else if (state < 0 || !con->pop.user) {
		con_write_bl(con, "-ERR [SYS/TEMP] Internal server error. Please try again later.\r\n", 64);
		return;
	}

	// Locks
	else if (con->pop.user->lock_status != 0) {
		// What type of lock is it.
		if (con->pop.user->lock_status == 1) {
			con_write_bl(con, "-ERR [SYS/PERM] This account has been administratively locked.\r\n", 64);
		}
		else if (con->pop.user->lock_status == 2) {
			con_write_bl(con, "-ERR [SYS/PERM] This account has been locked for inactivity.\r\n", 62);
		}
		else if (con->pop.user->lock_status == 3) {
			con_write_bl(con, "-ERR [SYS/PERM] This account has been locked on suspicion of abuse.\r\n", 69);
		}
		else if (con->pop.user->lock_status == 4) {
			con_write_bl(con, "-ERR [SYS/PERM] This account has been locked at the request of the user.\r\n", 74);
		}
		else {
			con_write_bl(con, "-ERR [SYS/PERM] This account has been locked.\r\n", 47);
		}

		con->pop.user = NULL;
		meta_remove(con->pop.username, META_PROT_POP);
		return;
	}

	// SSL check.
	else if ((con->pop.user->flags & META_USER_SSL) == META_USER_SSL && con_secure(con) != 1) {
		con->pop.user = NULL;
		meta_remove(con->pop.username, META_PROT_POP);
		con_write_bl(con, "-ERR [SYS/PERM] This user account is configured to require that all POP sessions be connected over SSL.\r\n", 105);
		return;
	}

	// Single session check.
	else if (con->pop.user->refs.pop != 1) {
		con->pop.user = NULL;
		meta_remove(con->pop.username, META_PROT_POP);
		con_write_bl(con, "-ERR [IN-USE] This account is being used by another session. Please try again in a few minutes.\r\n", 97);
		return;
	}

	// Debug logging.
	log_pedantic("User %.*s logged in from %s via POP. {poprefs = %lu, imaprefs = %lu, messages = %lu}",
		st_length_int(con->pop.username), st_char_get(con->pop.username), st_char_get(con_addr_presentation(con, MANAGEDBUF(256))),
		con->pop.user->refs.pop, con->pop.user->refs.imap, con->pop.user->messages ? inx_count(con->pop.user->messages) : 0);

	// Update the log and unlock the session.
	meta_data_update_log(con->pop.user, META_PROT_POP);

	meta_user_wlock(con->pop.user);
	meta_messages_login_update(con->pop.user, META_LOCKED);
	meta_user_unlock(con->pop.user);

	// Update session state.
	con->pop.session_state = 1;

	// Tell the client everything worked.
	con_write_bl(con, "+OK Password accepted.\r\n", 24);

	return;
}