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; }
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; }
/** * @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; }