passdb-blocking.c revision 2e29e4797a48d78d669821722bdb54fd0a1d3b94
6781N/A/* Copyright (C) 2005 Timo Sirainen */
6781N/A
6781N/A#include "common.h"
6781N/A#include "str.h"
6781N/A#include "auth-worker-server.h"
6781N/A#include "password-scheme.h"
6781N/A#include "passdb.h"
6781N/A#include "passdb-blocking.h"
6781N/A
6781N/A#include <stdlib.h>
6781N/A
6781N/Astatic enum passdb_result
6781N/Acheck_failure(struct auth_request *request, const char **reply)
6781N/A{
6781N/A /* OK / FAIL */
6781N/A if (strncmp(*reply, "OK\t", 3) == 0) {
6781N/A *reply += 3;
6781N/A return PASSDB_RESULT_OK;
6781N/A }
6781N/A
6781N/A /* FAIL \t result */
6781N/A if (strncmp(*reply, "FAIL\t", 5) != 0) {
6781N/A auth_request_log_error(request, "blocking",
6781N/A "Received unknown reply from worker: %s", *reply);
6781N/A return PASSDB_RESULT_INTERNAL_FAILURE;
6781N/A } else {
6781N/A return atoi(*reply + 5);
6781N/A }
6781N/A}
6781N/A
6781N/Astatic int get_pass_reply(struct auth_request *request, const char *reply,
6781N/A const char **password_r, const char **scheme_r)
6781N/A{
6781N/A const char *p;
6781N/A
6781N/A p = strchr(reply, '\t');
6781N/A if (p == NULL) {
6781N/A *password_r = NULL;
6781N/A *scheme_r = NULL;
6781N/A return 0;
6781N/A }
6781N/A
6781N/A *password_r = t_strdup_until(reply, p);
6781N/A reply = p + 1;
6781N/A
6781N/A if (**password_r == '\0') {
6781N/A *password_r = NULL;
6781N/A *scheme_r = NULL;
6781N/A } else {
6781N/A request->passdb_password =
6781N/A p_strdup(request->pool, *password_r);
6781N/A
6781N/A *scheme_r = password_get_scheme(password_r);
6781N/A if (*scheme_r == NULL) {
6781N/A auth_request_log_error(request, "blocking",
6781N/A "Received reply from worker without "
6781N/A "password scheme");
6781N/A return -1;
6781N/A }
6781N/A }
6781N/A
6781N/A if (*reply != '\0') {
6781N/A i_assert(request->extra_fields == NULL);
6781N/A
6781N/A request->extra_fields = str_new(request->pool, 128);
6781N/A str_append(request->extra_fields, reply);
6781N/A }
6781N/A return 0;
6781N/A}
6781N/A
6781N/Astatic void
6781N/Averify_plain_callback(struct auth_request *request, const char *reply)
6781N/A{
6781N/A enum passdb_result result;
6781N/A const char *password, *scheme;
6781N/A
6781N/A result = check_failure(request, &reply);
6781N/A if (result >= 0) {
6781N/A if (get_pass_reply(request, reply, &password, &scheme) < 0)
6781N/A result = PASSDB_RESULT_INTERNAL_FAILURE;
6781N/A }
6781N/A
6781N/A auth_request_verify_plain_callback(result, request);
6781N/A}
6781N/A
6781N/Avoid passdb_blocking_verify_plain(struct auth_request *request)
6781N/A{
6781N/A string_t *str;
6781N/A
6781N/A str = t_str_new(64);
6781N/A str_append(str, "PASSV\t");
6781N/A str_append(str, request->mech_password);
6781N/A str_append_c(str, '\t');
6781N/A auth_request_export(request, str);
6781N/A
6781N/A auth_worker_call(request, str_c(str), verify_plain_callback);
6781N/A}
6781N/A
6781N/Astatic void
6781N/Alookup_credentials_callback(struct auth_request *request, const char *reply)
6781N/A{
6781N/A enum passdb_result result;
6781N/A const char *password, *scheme;
6781N/A
6781N/A result = check_failure(request, &reply);
6781N/A if (result >= 0) {
6781N/A if (get_pass_reply(request, reply, &password, &scheme) < 0)
6781N/A result = PASSDB_RESULT_INTERNAL_FAILURE;
6781N/A }
6781N/A
6781N/A passdb_handle_credentials(result, request->credentials,
6781N/A password, scheme,
6781N/A auth_request_lookup_credentials_callback,
6781N/A request);
6781N/A}
6781N/A
6781N/Avoid passdb_blocking_lookup_credentials(struct auth_request *request)
6781N/A{
6781N/A string_t *str;
6781N/A
6781N/A str = t_str_new(64);
6781N/A str_printfa(str, "PASSL\t%d\t", request->credentials);
6781N/A auth_request_export(request, str);
6781N/A
6781N/A auth_worker_call(request, str_c(str), lookup_credentials_callback);
6781N/A}
6781N/A