#include "ostream.h"
#include "hex-binary.h"
#include "str.h"
+#include "strescape.h"
#include "eacces-error.h"
#include "auth-request.h"
#include "auth-worker-client.h"
"Aborting auth request that was queued for %d secs, "
"%d left in queue",
age_secs, aqueue_count(worker_request_queue));
- request->callback(t_strdup_printf(
- "FAIL\t%d", PASSDB_RESULT_INTERNAL_FAILURE),
- request->context);
+ const char *const args[] = {
+ "FAIL",
+ t_strdup_printf("%d", PASSDB_RESULT_INTERNAL_FAILURE),
+ NULL,
+ };
+ request->callback(args, request->context);
return FALSE;
}
if (age_secs >= AUTH_WORKER_DELAY_WARN_SECS &&
e_error(worker->conn.event, "Aborted %s request for %s: %s",
t_strcut(worker->request->data, '\t'),
worker->request->username, reason);
- worker->request->callback(t_strdup_printf(
- "FAIL\t%d", PASSDB_RESULT_INTERNAL_FAILURE),
- worker->request->context);
+ const char *const args[] = {
+ "FAIL",
+ t_strdup_printf("%d", PASSDB_RESULT_INTERNAL_FAILURE),
+ NULL,
+ };
+ worker->request->callback(args, worker->request->context);
}
io_remove(&worker->conn.io);
idle_count++;
}
- if (!request->callback(line, request->context) &&
+ const char *const *args = t_strsplit_tabescaped(line);
+ if (args[0] == NULL) {
+ const char *empty_args[] = { "", NULL };
+ args = empty_args;
+ }
+
+ if (!request->callback(args, request->context) &&
worker->conn.io != NULL) {
worker->timeout_pending_resume = FALSE;
timeout_remove(&worker->to_lookup);
struct auth_request;
struct auth_stream_reply;
-typedef bool auth_worker_callback_t(const char *reply, void *context);
+typedef bool auth_worker_callback_t(const char *const *args, void *context);
struct auth_worker_connection * ATTR_NOWARN_UNUSED_RESULT
auth_worker_call(pool_t pool, const char *username, const char *data,
}
enum passdb_result
-passdb_blocking_auth_worker_reply_parse(struct auth_request *request, const char *reply)
+passdb_blocking_auth_worker_reply_parse(struct auth_request *request,
+ const char *const *args)
{
enum passdb_result ret;
- const char *const *args;
-
- args = t_strsplit_tabescaped(reply);
if (strcmp(*args, "OK") == 0 && args[1] != NULL && args[2] != NULL) {
/* OK \t user \t password [\t extra] */
}
}
- e_error(authdb_event(request),
- "Received invalid reply from worker: %s", reply);
+ e_error(authdb_event(request), "Received invalid reply from worker: %s",
+ t_strarray_join(args, "\t"));
return PASSDB_RESULT_INTERNAL_FAILURE;
}
static bool
-verify_plain_callback(const char *reply, void *context)
+verify_plain_callback(const char *const *args, void *context)
{
struct auth_request *request = context;
enum passdb_result result;
- result = passdb_blocking_auth_worker_reply_parse(request, reply);
+ result = passdb_blocking_auth_worker_reply_parse(request, args);
auth_request_verify_plain_callback(result, request);
auth_request_unref(&request);
return TRUE;
verify_plain_callback, request);
}
-static bool lookup_credentials_callback(const char *reply, void *context)
+static bool lookup_credentials_callback(const char *const *args, void *context)
{
struct auth_request *request = context;
enum passdb_result result;
const char *password = NULL, *scheme = NULL;
- result = passdb_blocking_auth_worker_reply_parse(request, reply);
+ result = passdb_blocking_auth_worker_reply_parse(request, args);
if (result == PASSDB_RESULT_OK && request->passdb_password != NULL) {
password = request->passdb_password;
scheme = password_get_scheme(&password);
}
static bool
-set_credentials_callback(const char *reply, void *context)
+set_credentials_callback(const char *const *args, void *context)
{
struct auth_request *request = context;
bool success;
- success = strcmp(reply, "OK") == 0 ||
- str_begins_with(reply, "OK\t");
+ success = strcmp(args[0], "OK") == 0;
request->private_callback.set_credentials(success, request);
auth_request_unref(&request);
return TRUE;
#define PASSDB_BLOCKING_H
enum passdb_result
-passdb_blocking_auth_worker_reply_parse(struct auth_request *request, const char *reply);
+passdb_blocking_auth_worker_reply_parse(struct auth_request *request,
+ const char *const *args);
void passdb_blocking_verify_plain(struct auth_request *request);
void passdb_blocking_lookup_credentials(struct auth_request *request);
void passdb_blocking_set_credentials(struct auth_request *request,
return TRUE;
}
-static bool passdb_cache_verify_plain_callback(const char *reply, void *context)
+static bool passdb_cache_verify_plain_callback(const char *const *args,
+ void *context)
{
struct auth_request *request = context;
enum passdb_result result;
- result = passdb_blocking_auth_worker_reply_parse(request, reply);
+ result = passdb_blocking_auth_worker_reply_parse(request, args);
if (result != PASSDB_RESULT_OK)
auth_fields_rollback(request->fields.extra_fields);
auth_request_verify_plain_callback_finish(result, request);
bool destroyed;
};
-static bool user_callback(const char *reply, void *context)
+static bool user_callback(const char *const *args, void *context)
{
struct auth_request *request = context;
enum userdb_result result;
- const char *username, *args;
+ const char *username;
- if (str_begins(reply, "FAIL\t", &args)) {
+ if (strcmp(args[0], "FAIL") == 0) {
result = USERDB_RESULT_INTERNAL_FAILURE;
- } else if (str_begins(reply, "NOTFOUND\t", &args)) {
+ args++;
+ } else if (strcmp(args[0], "NOTFOUND") == 0) {
result = USERDB_RESULT_USER_UNKNOWN;
- } else if (str_begins(reply, "OK\t", &username)) {
+ args++;
+ } else if (strcmp(args[0], "OK") == 0) {
result = USERDB_RESULT_OK;
- args = strchr(username, '\t');
- if (args == NULL)
- args = "";
- else
- username = t_strdup_until(username, args++);
+ if (args[1] == NULL) {
+ username = "";
+ args++;
+ } else {
+ username = args[1];
+ args += 2;
+ }
+
if (username[0] != '\0' &&
strcmp(request->fields.user, username) != 0) {
auth_request_set_username_forced(request, username);
result = USERDB_RESULT_INTERNAL_FAILURE;
e_error(authdb_event(request),
"BUG: auth-worker sent invalid user reply");
- args = "";
+ args = NULL;
}
- if (*args != '\0') {
- auth_fields_import(request->fields.userdb_reply, args, 0);
+ if (args != NULL && args[0] != NULL && *args[0] != '\0') {
+ auth_fields_import_args(request->fields.userdb_reply, args, 0);
if (auth_fields_exists(request->fields.userdb_reply, "tempfail"))
request->userdb_lookup_tempfailed = TRUE;
}
str_c(str), user_callback, request);
}
-static bool iter_callback(const char *reply, void *context)
+static bool iter_callback(const char *const *args, void *context)
{
struct blocking_userdb_iterate_context *ctx = context;
- const char *args;
- if (str_begins(reply, "*\t", &args)) {
+ if (strcmp(args[0], "*") == 0 && args[1] != NULL) {
if (ctx->destroyed)
return TRUE;
ctx->next = FALSE;
- ctx->ctx.callback(args, ctx->ctx.context);
+ ctx->ctx.callback(args[1], ctx->ctx.context);
return ctx->next || ctx->destroyed;
}
- if (strcmp(reply, "OK") != 0)
+ if (strcmp(args[0], "OK") != 0)
ctx->ctx.failed = TRUE;
if (!ctx->destroyed)
ctx->ctx.callback(NULL, ctx->ctx.context);