struct vqpasswd *vpopmail_lookup_vqp(struct auth_request *request, char vpop_user[VPOPMAIL_LIMIT], char vpop_domain[VPOPMAIL_LIMIT]) { struct vqpasswd *vpw; /* vpop_user must be zero-filled or parse_email() leaves an extra character after the user name. we'll fill vpop_domain as well just to be sure... */ memset(vpop_user, '\0', VPOPMAIL_LIMIT); memset(vpop_domain, '\0', VPOPMAIL_LIMIT); if (parse_email(request->user, vpop_user, vpop_domain, VPOPMAIL_LIMIT-1) < 0) { auth_request_log_info(request, "vpopmail", "parse_email() failed"); return NULL; } auth_request_log_debug(request, "vpopmail", "lookup user=%s domain=%s", vpop_user, vpop_domain); vpw = vauth_getpw(vpop_user, vpop_domain); if (vpw == NULL) { auth_request_log_info(request, "vpopmail", "unknown user"); return NULL; } return vpw; }
static void mech_external_auth_continue(struct auth_request *request, const unsigned char *data, size_t data_size) { const char *authzid, *error; authzid = t_strndup(data, data_size); if (request->user == NULL) { auth_request_log_info(request, AUTH_SUBSYS_MECH, "username not known"); auth_request_fail(request); return; } /* this call is done simply to put the username through translation settings */ if (!auth_request_set_username(request, "", &error)) { auth_request_log_info(request, AUTH_SUBSYS_MECH, "Invalid username"); auth_request_fail(request); return; } if (*authzid != '\0' && !auth_request_set_login_username(request, authzid, &error)) { /* invalid login username */ auth_request_log_info(request, AUTH_SUBSYS_MECH, "login user: %s", error); auth_request_fail(request); } else { auth_request_verify_plain(request, "", plain_verify_callback); } }
static void mech_plain_auth_continue(struct auth_request *request, const unsigned char *data, size_t data_size) { const char *authid, *authenid, *error; char *pass; size_t i, len; int count; /* authorization ID \0 authentication ID \0 pass. */ authid = (const char *) data; authenid = NULL; pass = NULL; count = 0; for (i = 0; i < data_size; i++) { if (data[i] == '\0') { if (++count == 1) authenid = (const char *) data + i+1; else { i++; len = data_size - i; pass = p_strndup(unsafe_data_stack_pool, data+i, len); break; } } } if (authenid != NULL && strcmp(authid, authenid) == 0) { /* the login username isn't different */ authid = ""; } if (count != 2) { /* invalid input */ auth_request_log_info(request, AUTH_SUBSYS_MECH, "invalid input"); auth_request_fail(request); } else if (!auth_request_set_username(request, authenid, &error)) { /* invalid username */ auth_request_log_info(request, AUTH_SUBSYS_MECH, "%s", error); auth_request_fail(request); } else if (*authid != '\0' && !auth_request_set_login_username(request, authid, &error)) { /* invalid login username */ auth_request_log_info(request, AUTH_SUBSYS_MECH, "login user: %s", error); auth_request_fail(request); } else { auth_request_verify_plain(request, pass, plain_verify_callback); } /* make sure it's cleared */ if (pass != NULL) safe_memset(pass, 0, strlen(pass)); }
static void mech_dovecot_token_auth_continue(struct auth_request *request, const unsigned char *data, size_t data_size) { const char *session_id, *username, *pid, *service, *error; char *auth_token; size_t i, len; int count; /* service \0 pid \0 username \0 session_id \0 auth_token */ service = (const char *) data; session_id = username = pid = auth_token = NULL; count = 0; for (i = 0; i < data_size; i++) { if (data[i] == '\0') { count++; i++; if (count == 1) pid = (const char *)data + i; else if (count == 2) username = (const char *)data + i; else if (count == 3) session_id = (const char *)data + i; else { len = data_size - i; auth_token = p_strndup(unsafe_data_stack_pool, data+i, len); break; } } } if (count != 4) { /* invalid input */ auth_request_log_info(request, AUTH_SUBSYS_MECH, "invalid input"); auth_request_fail(request); } else if (!auth_request_set_username(request, username, &error)) { /* invalid username */ auth_request_log_info(request, AUTH_SUBSYS_MECH, "%s", error); auth_request_fail(request); } else { const char *valid_token = auth_token_get(service, pid, request->user, session_id); if (auth_token != NULL && strcmp(auth_token, valid_token) == 0) { request->passdb_success = TRUE; auth_request_success(request, NULL, 0); } else { auth_request_fail(request); } } /* make sure it's cleared */ if (auth_token != NULL) safe_memset(auth_token, 0, strlen(auth_token)); }
static void userdb_nss_lookup(struct auth_request *auth_request, userdb_callback_t *callback) { struct userdb_module *_module = auth_request->userdb->userdb; struct nss_userdb_module *module = (struct nss_userdb_module *)_module; struct passwd pw; enum nss_status status; enum userdb_result result = USERDB_RESULT_INTERNAL_FAILURE; int err; auth_request_log_debug(auth_request, "nss", "lookup"); status = module->getpwnam_r(auth_request->user, &pw, module->buf, module->bufsize, &err); switch (status) { case NSS_STATUS_TRYAGAIN: auth_request_log_error(auth_request, "nss", "returned tryagain (err=%d)", err); break; case NSS_STATUS_UNAVAIL: auth_request_log_error(auth_request, "nss", "unavailable (err=%d)", err); break; case NSS_STATUS_NOTFOUND: auth_request_log_info(auth_request, "nss", "unknown user"); result = USERDB_RESULT_USER_UNKNOWN; break; case NSS_STATUS_SUCCESS: result = USERDB_RESULT_OK; break; default: auth_request_log_info(auth_request, "nss", "returned %d (err=%d)", status, err); break; } if (result != USERDB_RESULT_OK) { callback(result, auth_request); return; } auth_request_set_field(auth_request, "user", pw.pw_name, NULL); auth_request_init_userdb_reply(auth_request); auth_request_set_userdb_field(auth_request, "system_groups_user", pw.pw_name); auth_request_set_userdb_field(auth_request, "uid", dec2str(pw.pw_uid)); auth_request_set_userdb_field(auth_request, "gid", dec2str(pw.pw_gid)); auth_request_set_userdb_field(auth_request, "home", pw.pw_dir); callback(USERDB_RESULT_OK, auth_request); }
static void ldap_lookup_finish(struct auth_request *auth_request, struct passdb_ldap_request *ldap_request, LDAPMessage *res) { enum passdb_result passdb_result; const char *password = NULL, *scheme; int ret; if (res == NULL) { passdb_result = PASSDB_RESULT_INTERNAL_FAILURE; } else if (ldap_request->entries == 0) { passdb_result = PASSDB_RESULT_USER_UNKNOWN; auth_request_log_info(auth_request, "ldap", "unknown user"); } else if (ldap_request->entries > 1) { auth_request_log_error(auth_request, "ldap", "pass_filter matched multiple objects, aborting"); passdb_result = PASSDB_RESULT_INTERNAL_FAILURE; } else if (auth_request->passdb_password == NULL && !auth_fields_exists(auth_request->extra_fields, "nopassword")) { auth_request_log_info(auth_request, "ldap", "No password returned (and no nopassword)"); passdb_result = PASSDB_RESULT_PASSWORD_MISMATCH; } else { /* passdb_password may change on the way, so we'll need to strdup. */ password = t_strdup(auth_request->passdb_password); passdb_result = PASSDB_RESULT_OK; } scheme = password_get_scheme(&password); /* auth_request_set_field() sets scheme */ i_assert(password == NULL || scheme != NULL); if (auth_request->credentials_scheme != NULL) { passdb_handle_credentials(passdb_result, password, scheme, ldap_request->callback.lookup_credentials, auth_request); } else { if (password != NULL) { ret = auth_request_password_verify(auth_request, auth_request->mech_password, password, scheme, "ldap"); passdb_result = ret > 0 ? PASSDB_RESULT_OK : PASSDB_RESULT_PASSWORD_MISMATCH; } ldap_request->callback.verify_plain(passdb_result, auth_request); } }
static enum passdb_result passwd_lookup(struct auth_request *request, struct passwd *pw_r) { auth_request_log_debug(request, AUTH_SUBSYS_DB, "lookup"); switch (i_getpwnam(request->user, pw_r)) { case -1: auth_request_log_error(request, AUTH_SUBSYS_DB, "getpwnam() failed: %m"); return PASSDB_RESULT_INTERNAL_FAILURE; case 0: auth_request_log_unknown_user(request, AUTH_SUBSYS_DB); return PASSDB_RESULT_USER_UNKNOWN; } if (!IS_VALID_PASSWD(pw_r->pw_passwd)) { auth_request_log_info(request, AUTH_SUBSYS_DB, "invalid password field '%s'", pw_r->pw_passwd); return PASSDB_RESULT_USER_DISABLED; } /* save the password so cache can use it */ auth_request_set_field(request, "password", pw_r->pw_passwd, PASSWD_PASS_SCHEME); return PASSDB_RESULT_OK; }
static enum passdb_result passdb_dict_lookup_key(struct auth_request *auth_request, struct dict_passdb_module *module) { struct db_dict_value_iter *iter; int ret; ret = db_dict_value_iter_init(module->conn, auth_request, &module->conn->set.passdb_fields, &module->conn->set.parsed_passdb_objects, &iter); if (ret < 0) return PASSDB_RESULT_INTERNAL_FAILURE; else if (ret == 0) { auth_request_log_unknown_user(auth_request, AUTH_SUBSYS_DB); return PASSDB_RESULT_USER_UNKNOWN; } else { if (dict_query_save_results(auth_request, module->conn, iter) < 0) return PASSDB_RESULT_INTERNAL_FAILURE; if (auth_request->passdb_password == NULL && !auth_fields_exists(auth_request->extra_fields, "nopassword")) { auth_request_log_info(auth_request, AUTH_SUBSYS_DB, "No password returned (and no nopassword)"); return PASSDB_RESULT_PASSWORD_MISMATCH; } else { return PASSDB_RESULT_OK; } } }
static void mech_digest_md5_auth_continue(struct auth_request *auth_request, const unsigned char *data, size_t data_size) { struct digest_auth_request *request = (struct digest_auth_request *)auth_request; const char *username, *error; if (parse_digest_response(request, data, data_size, &error)) { if (auth_request->realm != NULL && strchr(request->username, '@') == NULL) { username = t_strconcat(request->username, "@", auth_request->realm, NULL); auth_request->domain_is_realm = TRUE; } else { username = request->username; } if (auth_request_set_username(auth_request, username, &error) && (request->authzid == NULL || auth_request_set_login_username(auth_request, request->authzid, &error))) { auth_request_lookup_credentials(auth_request, "DIGEST-MD5", credentials_callback); return; } } if (error != NULL) auth_request_log_info(auth_request, AUTH_SUBSYS_MECH, "%s", error); auth_request_fail(auth_request); }
static enum passdb_result passdb_dict_lookup_key(struct auth_request *auth_request, struct dict_passdb_module *module, const char *key) { const char *value; int ret; auth_request_log_debug(auth_request, "dict", "lookup %s", key); ret = dict_lookup(module->conn->dict, pool_datastack_create(), key, &value); if (ret < 0) { auth_request_log_error(auth_request, "dict", "Lookup failed"); return PASSDB_RESULT_INTERNAL_FAILURE; } else if (ret == 0) { auth_request_log_unknown_user(auth_request, "dict"); return PASSDB_RESULT_USER_UNKNOWN; } else { auth_request_log_debug(auth_request, "dict", "result: %s", value); if (dict_query_save_results(auth_request, module->conn, value) < 0) return PASSDB_RESULT_INTERNAL_FAILURE; if (auth_request->passdb_password == NULL && !auth_fields_exists(auth_request->extra_fields, "nopassword")) { auth_request_log_info(auth_request, "dict", "No password returned (and no nopassword)"); return PASSDB_RESULT_PASSWORD_MISMATCH; } else { return PASSDB_RESULT_OK; } } }
static void passdb_imap_login_callback(const struct imapc_command_reply *reply, void *context) { struct imap_auth_request *request = context; struct imapc_client *client = request->client; enum passdb_result result = PASSDB_RESULT_INTERNAL_FAILURE; switch (reply->state) { case IMAPC_COMMAND_STATE_OK: result = PASSDB_RESULT_OK; break; case IMAPC_COMMAND_STATE_NO: result = passdb_imap_get_failure_result(reply); auth_request_log_info(request->auth_request, AUTH_SUBSYS_DB, "%s", reply->text_full); break; case IMAPC_COMMAND_STATE_BAD: case IMAPC_COMMAND_STATE_DISCONNECTED: auth_request_log_error(request->auth_request, AUTH_SUBSYS_DB, "%s", reply->text_full); break; } request->verify_callback(result, request->auth_request); imapc_client_deinit(&client); auth_request_unref(&request->auth_request); }
static void ldap_bind_lookup_dn_fail(struct auth_request *auth_request, struct passdb_ldap_request *request, LDAPMessage *res) { enum passdb_result passdb_result; if (res == NULL) passdb_result = PASSDB_RESULT_INTERNAL_FAILURE; else if (request->entries == 0) { passdb_result = PASSDB_RESULT_USER_UNKNOWN; auth_request_log_info(auth_request, "ldap", "unknown user"); } else { i_assert(request->entries > 1); auth_request_log_error(auth_request, "ldap", "pass_filter matched multiple objects, aborting"); passdb_result = PASSDB_RESULT_INTERNAL_FAILURE; } if (auth_request->credentials_scheme != NULL) { request->callback.lookup_credentials(passdb_result, NULL, 0, auth_request); } else { request->callback.verify_plain(passdb_result, auth_request); } auth_request_unref(&auth_request); }
static enum passdb_result static_save_fields(struct auth_request *request, const char **password_r) { struct static_passdb_module *module = (struct static_passdb_module *)request->passdb->passdb; const struct var_expand_table *table; string_t *str = t_str_new(128); auth_request_log_debug(request, AUTH_SUBSYS_DB, "lookup"); passdb_template_export(module->tmpl, request); if (module->static_password_tmpl != NULL) { table = auth_request_get_var_expand_table(request, NULL); var_expand(str, module->static_password_tmpl, table); *password_r = str_c(str); } else if (auth_fields_exists(request->extra_fields, "nopassword")) { *password_r = ""; } else { auth_request_log_info(request, AUTH_SUBSYS_DB, "No password returned (and no nopassword)"); *password_r = NULL; return PASSDB_RESULT_PASSWORD_MISMATCH; } return PASSDB_RESULT_OK; }
static bool verify_credentials(struct cram_auth_request *request, const unsigned char *credentials, size_t size) { unsigned char digest[MD5_RESULTLEN]; struct hmac_context ctx; const char *response_hex; if (size != CRAM_MD5_CONTEXTLEN) { auth_request_log_error(&request->auth_request, AUTH_SUBSYS_MECH, "invalid credentials length"); return FALSE; } hmac_init(&ctx, NULL, 0, &hash_method_md5); hmac_md5_set_cram_context(&ctx, credentials); hmac_update(&ctx, request->challenge, strlen(request->challenge)); hmac_final(&ctx, digest); response_hex = binary_to_hex(digest, sizeof(digest)); if (memcmp(response_hex, request->response, sizeof(digest)*2) != 0) { auth_request_log_info(&request->auth_request, AUTH_SUBSYS_MECH, "password mismatch"); return FALSE; } return TRUE; }
static void checkpassword_request_half_finish(struct chkpw_auth_request *request) { if (!request->exited || request->fd_in != -1) return; switch (request->exit_status) { case 3: /* User does not exist. */ auth_request_log_info(request->request, "userdb-checkpassword", "User unknown"); checkpassword_request_finish(request, USERDB_RESULT_USER_UNKNOWN); break; case 2: /* This is intentionally not 0. checkpassword-reply exits with 2 on success when AUTHORIZED is set. */ if (request->input_buf != NULL) { checkpassword_request_finish(request, USERDB_RESULT_OK); break; } /* missing input - fall through */ default: /* whatever error... */ auth_request_log_error(request->request, "userdb-checkpassword", "Child %s exited with status %d", dec2str(request->pid), request->exit_status); checkpassword_request_finish(request, USERDB_RESULT_INTERNAL_FAILURE); break; } }
bool passdb_cache_verify_plain(struct auth_request *request, const char *key, const char *password, enum passdb_result *result_r, bool use_expired) { const char *value, *cached_pw, *scheme, *const *list; struct auth_cache_node *node; int ret; bool neg_expired; if (passdb_cache == NULL || key == NULL) return FALSE; if (!passdb_cache_lookup(request, key, use_expired, &node, &value, &neg_expired)) return FALSE; if (*value == '\0') { /* negative cache entry */ auth_request_log_unknown_user(request, AUTH_SUBSYS_DB); *result_r = PASSDB_RESULT_USER_UNKNOWN; return TRUE; } list = t_strsplit_tab(value); cached_pw = list[0]; if (*cached_pw == '\0') { /* NULL password */ auth_request_log_info(request, AUTH_SUBSYS_DB, "Cached NULL password access"); ret = 1; } else { scheme = password_get_scheme(&cached_pw); i_assert(scheme != NULL); ret = auth_request_password_verify(request, password, cached_pw, scheme, AUTH_SUBSYS_DB); if (ret == 0 && (node->last_success || neg_expired)) { /* a) the last authentication was successful. assume that the password was changed and cache is expired. b) negative TTL reached, use it for password mismatches too. */ node->last_success = FALSE; return FALSE; } } node->last_success = ret > 0; /* save the extra_fields only after we know we're using the cached data */ auth_request_set_fields(request, list + 1, NULL); *result_r = ret > 0 ? PASSDB_RESULT_OK : PASSDB_RESULT_PASSWORD_MISMATCH; return TRUE; }
static void ldap_auth_bind_callback(struct ldap_connection *conn, struct ldap_request *ldap_request, LDAPMessage *res) { struct passdb_ldap_request *passdb_ldap_request = (struct passdb_ldap_request *)ldap_request; struct auth_request *auth_request = ldap_request->auth_request; enum passdb_result passdb_result; const char *str; int ret; passdb_result = PASSDB_RESULT_INTERNAL_FAILURE; if (res != NULL) { ret = ldap_result2error(conn->ld, res, 0); if (ret == LDAP_SUCCESS) passdb_result = PASSDB_RESULT_OK; else if (ret == LDAP_INVALID_CREDENTIALS) { str = "invalid credentials"; if (auth_request->set->debug_passwords) { str = t_strconcat(str, " (given password: "******")", NULL); } auth_request_log_info(auth_request, "ldap", "%s", str); passdb_result = PASSDB_RESULT_PASSWORD_MISMATCH; } else if (ret == LDAP_NO_SUCH_OBJECT) { passdb_result = PASSDB_RESULT_USER_UNKNOWN; auth_request_log_info(auth_request, "ldap", "unknown user"); } else { auth_request_log_error(auth_request, "ldap", "ldap_bind() failed: %s", ldap_err2string(ret)); } } passdb_ldap_request->callback. verify_plain(passdb_result, auth_request); auth_request_unref(&auth_request); }
static void auth_request_handler_auth_fail(struct auth_request_handler *handler, struct auth_request *request, const char *reason) { string_t *str = t_str_new(128); auth_request_log_info(request, request->mech->mech_name, "%s", reason); str_printfa(str, "FAIL\t%u\treason=", request->id); str_append_tabescaped(str, reason); handler->callback(str_c(str), handler->context); auth_request_handler_remove(handler, request); }
static void passwd_verify_plain(struct auth_request *request, const char *password, verify_plain_callback_t *callback) { struct passwd pw; int ret; auth_request_log_debug(request, "passwd", "lookup"); switch (i_getpwnam(request->user, &pw)) { case -1: auth_request_log_error(request, "passwd", "getpwnam() failed: %m"); callback(PASSDB_RESULT_INTERNAL_FAILURE, request); return; case 0: auth_request_log_unknown_user(request, "passwd"); callback(PASSDB_RESULT_USER_UNKNOWN, request); return; } if (!IS_VALID_PASSWD(pw.pw_passwd)) { auth_request_log_info(request, "passwd", "invalid password field '%s'", pw.pw_passwd); callback(PASSDB_RESULT_USER_DISABLED, request); return; } /* save the password so cache can use it */ auth_request_set_field(request, "password", pw.pw_passwd, PASSWD_PASS_SCHEME); /* check if the password is valid */ ret = auth_request_password_verify(request, password, pw.pw_passwd, PASSWD_PASS_SCHEME, "passwd"); /* clear the passwords from memory */ safe_memset(pw.pw_passwd, 0, strlen(pw.pw_passwd)); if (ret <= 0) { callback(PASSDB_RESULT_PASSWORD_MISMATCH, request); return; } /* make sure we're using the username exactly as it's in the database */ auth_request_set_field(request, "user", pw.pw_name, NULL); callback(PASSDB_RESULT_OK, request); }
static bool postfix_input_user(struct auth_postfix_connection *conn, const char *username) { struct auth_request *auth_request; const char *error; io_remove(&conn->io); if (!postfix_input_auth_request(conn, username, &auth_request, &error)) { auth_request_log_info(auth_request, "postfix", "%s", error); user_callback(USERDB_RESULT_USER_UNKNOWN, auth_request); } else { auth_request_set_state(auth_request, AUTH_REQUEST_STATE_USERDB); auth_request_lookup_user(auth_request, user_callback); } return TRUE; }
static void auth_request_timeout(struct auth_request *request) { unsigned int secs = (unsigned int)(time(NULL) - request->last_access); if (request->state != AUTH_REQUEST_STATE_MECH_CONTINUE) { /* client's fault */ auth_request_log_error(request, request->mech->mech_name, "Request %u.%u timed out after %u secs, state=%d", request->handler->client_pid, request->id, secs, request->state); } else if (request->set->verbose) { auth_request_log_info(request, request->mech->mech_name, "Request timed out waiting for client to continue authentication " "(%u secs)", secs); } auth_request_handler_remove(request->handler, request); }
static enum passdb_result static_save_fields(struct auth_request *request, const char **password_r, const char **scheme_r) { struct static_passdb_module *module = (struct static_passdb_module *)request->passdb->passdb; const char *error; *password_r = NULL; *scheme_r = NULL; auth_request_log_debug(request, AUTH_SUBSYS_DB, "lookup"); if (passdb_template_export(module->tmpl, request, &error) < 0) { auth_request_log_error(request, AUTH_SUBSYS_DB, "Failed to expand template: %s", error); return PASSDB_RESULT_INTERNAL_FAILURE; } if (module->static_password_tmpl != NULL) { if (t_auth_request_var_expand(module->static_password_tmpl, request, NULL, password_r, &error) <= 0) { auth_request_log_error(request, AUTH_SUBSYS_DB, "Failed to expand password=%s: %s", module->static_password_tmpl, error); return PASSDB_RESULT_INTERNAL_FAILURE; } } else if (auth_fields_exists(request->extra_fields, "nopassword")) { *password_r = ""; } else { auth_request_log_info(request, AUTH_SUBSYS_DB, "No password returned (and no nopassword)"); return PASSDB_RESULT_PASSWORD_MISMATCH; } *scheme_r = password_get_scheme(password_r); if (*scheme_r == NULL) *scheme_r = STATIC_PASS_SCHEME; auth_request_set_field(request, "password", *password_r, *scheme_r); return PASSDB_RESULT_OK; }
static void passwd_lookup(struct auth_request *auth_request, userdb_callback_t *callback) { struct userdb_module *_module = auth_request->userdb->userdb; struct passwd_userdb_module *module = (struct passwd_userdb_module *)_module; struct passwd pw; struct timeval start_tv; int ret; auth_request_log_debug(auth_request, "passwd", "lookup"); if (gettimeofday(&start_tv, NULL) < 0) start_tv.tv_sec = 0; ret = i_getpwnam(auth_request->user, &pw); if (start_tv.tv_sec != 0) passwd_check_warnings(auth_request, module, &start_tv); switch (ret) { case -1: auth_request_log_error(auth_request, "passwd", "getpwnam() failed: %m"); callback(USERDB_RESULT_INTERNAL_FAILURE, auth_request); return; case 0: auth_request_log_info(auth_request, "passwd", "unknown user"); callback(USERDB_RESULT_USER_UNKNOWN, auth_request); return; } auth_request_set_field(auth_request, "user", pw.pw_name, NULL); auth_request_init_userdb_reply(auth_request); auth_request_set_userdb_field(auth_request, "system_groups_user", pw.pw_name); auth_request_set_userdb_field(auth_request, "uid", dec2str(pw.pw_uid)); auth_request_set_userdb_field(auth_request, "gid", dec2str(pw.pw_gid)); auth_request_set_userdb_field(auth_request, "home", pw.pw_dir); userdb_template_export(module->tmpl, auth_request); callback(USERDB_RESULT_OK, auth_request); }
static bool master_input_user(struct auth_master_connection *conn, const char *args) { struct auth_request *auth_request; const char *error; int ret; ret = master_input_auth_request(conn, args, "USER", &auth_request, &error); if (ret <= 0) { if (ret < 0) return FALSE; auth_request_log_info(auth_request, "userdb", "%s", error); user_callback(USERDB_RESULT_USER_UNKNOWN, auth_request); } else { auth_request_set_state(auth_request, AUTH_REQUEST_STATE_USERDB); auth_request_lookup_user(auth_request, user_callback); } return TRUE; }
static void mech_anonymous_auth_continue(struct auth_request *request, const unsigned char *data, size_t data_size) { i_assert(*request->set->anonymous_username != '\0'); if (request->set->verbose) { /* temporarily set the user to the one that was given, so that the log message goes right */ request->user = p_strndup(pool_datastack_create(), data, data_size); auth_request_log_info(request, AUTH_SUBSYS_MECH, "login"); } request->user = p_strdup(request->pool, request->set->anonymous_username); request->passdb_success = TRUE; auth_request_success(request, "", 0); }
static char * vpopmail_password_lookup(struct auth_request *auth_request, bool *cleartext, enum passdb_result *result_r) { char vpop_user[VPOPMAIL_LIMIT], vpop_domain[VPOPMAIL_LIMIT]; struct vqpasswd *vpw; char *password; vpw = vpopmail_lookup_vqp(auth_request, vpop_user, vpop_domain); if (vpw == NULL) { *result_r = PASSDB_RESULT_USER_UNKNOWN; return NULL; } if (vpopmail_is_disabled(auth_request, vpw)) { auth_request_log_info(auth_request, AUTH_SUBSYS_DB, "%s disabled in vpopmail for this user", auth_request->service); password = NULL; *result_r = PASSDB_RESULT_USER_DISABLED; } else { if (vpw->pw_clear_passwd != NULL && *vpw->pw_clear_passwd != '\0') { password = t_strdup_noconst(vpw->pw_clear_passwd); *cleartext = TRUE; } else if (!*cleartext) password = t_strdup_noconst(vpw->pw_passwd); else password = NULL; *result_r = password != NULL ? PASSDB_RESULT_OK : PASSDB_RESULT_SCHEME_NOT_AVAILABLE; } safe_memset(vpw->pw_passwd, 0, strlen(vpw->pw_passwd)); if (vpw->pw_clear_passwd != NULL) { safe_memset(vpw->pw_clear_passwd, 0, strlen(vpw->pw_clear_passwd)); } return password; }
static void ldap_auth_bind(struct ldap_connection *conn, struct ldap_request_bind *brequest) { struct passdb_ldap_request *passdb_ldap_request = (struct passdb_ldap_request *)brequest; struct auth_request *auth_request = brequest->request.auth_request; if (*auth_request->mech_password == '\0') { /* Assume that empty password fails. This is especially important with Windows 2003 AD, which always returns success with empty passwords. */ auth_request_log_info(auth_request, "ldap", "Login attempt with empty password"); passdb_ldap_request->callback. verify_plain(PASSDB_RESULT_PASSWORD_MISMATCH, auth_request); return; } brequest->request.callback = ldap_auth_bind_callback; db_ldap_request(conn, &brequest->request); }
/* return AD realm if it exists */ const char *get_ad_realm ( struct auth_request *auth_request ) { const char *out_realm = NULL; SCDynamicStoreRef store = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("dovecot.digest.auth"), NULL, NULL); if ( store ) { CFDictionaryRef dict = SCDynamicStoreCopyValue(store, CFSTR("com.apple.opendirectoryd.ActiveDirectory")); if (dict) { CFStringRef domain = CFDictionaryGetValue(dict, CFSTR("DomainNameFlat")); if (domain) { const char *ad_realm = CFStringGetCStringPtr(domain, kCFStringEncodingUTF8); if (ad_realm) { auth_request_log_info(auth_request, "digest-md5", "ad realm: %s", ad_realm); out_realm = t_strdup(ad_realm); } } CFRelease(dict); } CFRelease(store); } return( out_realm ); }
static void mech_cram_md5_auth_continue(struct auth_request *auth_request, const unsigned char *data, size_t data_size) { struct cram_auth_request *request = (struct cram_auth_request *)auth_request; const char *error; if (parse_cram_response(request, data, data_size, &error)) { if (auth_request_set_username(auth_request, request->username, &error)) { auth_request_lookup_credentials(auth_request, "CRAM-MD5", credentials_callback); return; } } if (error == NULL) error = "authentication failed"; auth_request_log_info(auth_request, AUTH_SUBSYS_MECH, "%s", error); auth_request_fail(auth_request); }
static void mech_apop_auth_initial(struct auth_request *auth_request, const unsigned char *data, size_t data_size) { struct apop_auth_request *request = (struct apop_auth_request *)auth_request; const unsigned char *tmp, *end, *username = NULL; unsigned long pid, connect_uid, timestamp; const char *error; /* pop3-login handles sending the challenge and getting the response. Our input here is: <challenge> \0 <username> \0 <response> */ if (data_size == 0) { /* Should never happen */ auth_request_log_info(auth_request, "apop", "no initial respone"); auth_request_fail(auth_request); return; } tmp = data; end = data + data_size; /* get the challenge */ while (tmp != end && *tmp != '\0') tmp++; request->challenge = p_strdup_until(request->pool, data, tmp); if (tmp != end) { /* get the username */ username = ++tmp; while (tmp != end && *tmp != '\0') tmp++; } if (tmp + 1 + 16 != end) { /* Should never happen */ auth_request_log_info(auth_request, "apop", "malformed data"); auth_request_fail(auth_request); return; } memcpy(request->response_digest, tmp + 1, sizeof(request->response_digest)); /* the challenge must begin with trusted unique ID. we trust only ourself, so make sure it matches our connection specific UID which we told to client in handshake. Also require a timestamp which is later than this process's start time. */ if (sscanf(request->challenge, "<%lx.%lx.%lx.", &pid, &connect_uid, ×tamp) != 3 || connect_uid != auth_request->connect_uid || pid != (unsigned long)getpid() || (time_t)timestamp < process_start_time) { auth_request_log_info(auth_request, "apop", "invalid challenge"); auth_request_fail(auth_request); return; } if (!auth_request_set_username(auth_request, (const char *)username, &error)) { auth_request_log_info(auth_request, "apop", "%s", error); auth_request_fail(auth_request); return; } auth_request_lookup_credentials(auth_request, "PLAIN", apop_credentials_callback); }