userdb-blocking.c revision 91e2dc36b9c0c91f0af716be81dc2aa6cbbed6c2
0N/A/* Copyright (c) 2005-2010 Dovecot authors, see the included COPYING file */
2362N/A
0N/A#include "auth-common.h"
0N/A#include "str.h"
0N/A#include "auth-worker-server.h"
0N/A#include "userdb.h"
2362N/A#include "userdb-blocking.h"
0N/A
2362N/A#include <stdlib.h>
0N/A
0N/Astruct blocking_userdb_iterate_context {
0N/A struct userdb_iterate_context ctx;
0N/A pool_t pool;
0N/A struct auth_worker_connection *conn;
0N/A bool next;
0N/A bool destroyed;
0N/A};
0N/A
0N/Astatic bool user_callback(const char *reply, void *context)
0N/A{
2362N/A struct auth_request *request = context;
2362N/A enum userdb_result result;
2362N/A const char *args;
0N/A
0N/A if (strncmp(reply, "FAIL\t", 5) == 0) {
0N/A result = USERDB_RESULT_INTERNAL_FAILURE;
0N/A args = reply + 5;
0N/A } else if (strncmp(reply, "NOTFOUND\t", 9) == 0) {
0N/A result = USERDB_RESULT_USER_UNKNOWN;
0N/A args = reply + 9;
0N/A } else if (strncmp(reply, "OK\t", 3) == 0) {
0N/A result = USERDB_RESULT_OK;
0N/A args = reply + 3;
0N/A } else {
0N/A result = USERDB_RESULT_INTERNAL_FAILURE;
0N/A i_error("BUG: auth-worker sent invalid user reply");
0N/A args = "";
0N/A }
0N/A
0N/A if (*args != '\0') {
0N/A request->userdb_reply = auth_stream_reply_init(request->pool);
0N/A auth_stream_reply_import(request->userdb_reply, args);
0N/A if (auth_stream_reply_find(request->userdb_reply,
0N/A "tempfail") != NULL)
0N/A request->userdb_lookup_failed = TRUE;
0N/A }
0N/A
0N/A auth_request_userdb_callback(result, request);
0N/A auth_request_unref(&request);
0N/A return TRUE;
0N/A}
0N/A
0N/Avoid userdb_blocking_lookup(struct auth_request *request)
0N/A{
0N/A struct auth_stream_reply *reply;
0N/A
0N/A reply = auth_stream_reply_init(pool_datastack_create());
0N/A auth_stream_reply_add(reply, "USER", NULL);
0N/A auth_stream_reply_add(reply, NULL, dec2str(request->userdb->userdb->id));
0N/A auth_request_export(request, reply);
0N/A
0N/A auth_request_ref(request);
0N/A auth_worker_call(request->pool, reply, user_callback, request);
0N/A}
0N/A
0N/Astatic bool iter_callback(const char *reply, void *context)
0N/A{
0N/A struct blocking_userdb_iterate_context *ctx = context;
0N/A pool_t pool = ctx->pool;
0N/A
0N/A if (strncmp(reply, "*\t", 2) == 0) {
0N/A ctx->next = FALSE;
0N/A ctx->ctx.callback(reply + 2, ctx->ctx.context);
return ctx->next;
}
if (strcmp(reply, "OK") != 0)
ctx->ctx.failed = TRUE;
if (!ctx->destroyed)
ctx->ctx.callback(NULL, ctx->ctx.context);
pool_unref(&pool);
return TRUE;
}
struct userdb_iterate_context *
userdb_blocking_iter_init(struct userdb_module *userdb,
userdb_iter_callback_t *callback, void *context)
{
struct blocking_userdb_iterate_context *ctx;
struct auth_stream_reply *reply;
pool_t pool;
reply = auth_stream_reply_init(pool_datastack_create());
auth_stream_reply_add(reply, "LIST", NULL);
auth_stream_reply_add(reply, NULL, dec2str(userdb->id));
pool = pool_alloconly_create("userdb iter", 512);
ctx = p_new(pool, struct blocking_userdb_iterate_context, 1);
ctx->ctx.userdb = userdb;
ctx->ctx.callback = callback;
ctx->ctx.context = context;
ctx->pool = pool;
pool_ref(pool);
ctx->conn = auth_worker_call(pool, reply, iter_callback, ctx);
return &ctx->ctx;
}
void userdb_blocking_iter_next(struct userdb_iterate_context *_ctx)
{
struct blocking_userdb_iterate_context *ctx =
(struct blocking_userdb_iterate_context *)_ctx;
ctx->next = TRUE;
auth_worker_server_resume_input(ctx->conn);
}
int userdb_blocking_iter_deinit(struct userdb_iterate_context **_ctx)
{
struct blocking_userdb_iterate_context *ctx =
(struct blocking_userdb_iterate_context *)*_ctx;
int ret = ctx->ctx.failed ? -1 : 0;
*_ctx = NULL;
ctx->destroyed = TRUE;
pool_unref(&ctx->pool);
return ret;
}