struct master_userdb_request {
struct auth_master_connection *conn;
- unsigned int id;
struct auth_request *auth_request;
};
struct master_list_iter_ctx {
struct auth_master_connection *conn;
- struct auth_userdb *userdb;
struct userdb_iterate_context *iter;
- unsigned int id;
+ struct auth_request *auth_request;
bool failed;
};
if (ctx->iter != NULL)
(void)userdb_blocking_iter_deinit(&ctx->iter);
o_stream_unset_flush_callback(ctx->conn->output);
+ auth_request_unref(&ctx->auth_request);
+ auth_master_connection_unref(&ctx->conn);
i_free(ctx);
}
static void master_input_list_callback(const char *user, void *context)
{
struct master_list_iter_ctx *ctx = context;
+ struct auth_userdb *userdb = ctx->auth_request->userdb;
int ret;
if (user == NULL) {
ctx->failed = TRUE;
do {
- ctx->userdb = ctx->userdb->next;
- } while (ctx->userdb != NULL &&
- ctx->userdb->userdb->iface->iterate_init == NULL);
- if (ctx->userdb == NULL) {
+ userdb = userdb->next;
+ } while (userdb != NULL &&
+ userdb->userdb->iface->iterate_init == NULL);
+ if (userdb == NULL) {
/* iteration is finished */
const char *str;
- str = t_strdup_printf("DONE\t%u\t%s\n", ctx->id,
+ str = t_strdup_printf("DONE\t%u\t%s\n",
+ ctx->auth_request->id,
ctx->failed ? "fail" : "");
(void)o_stream_send_str(ctx->conn->output, str);
master_input_list_finish(ctx);
}
/* continue iterating next userdb */
- ctx->iter = userdb_blocking_iter_init(ctx->userdb->userdb,
+ ctx->auth_request->userdb = userdb;
+ ctx->iter = userdb_blocking_iter_init(ctx->auth_request,
master_input_list_callback, ctx);
userdb_blocking_iter_next(ctx->iter);
return;
T_BEGIN {
const char *str;
- str = t_strdup_printf("LIST\t%u\t%s\n", ctx->id,
+ str = t_strdup_printf("LIST\t%u\t%s\n", ctx->auth_request->id,
str_tabescape(user));
ret = o_stream_send_str(ctx->conn->output, str);
} T_END;
master_input_list(struct auth_master_connection *conn, const char *args)
{
struct auth_userdb *userdb = conn->auth->userdbs;
+ struct auth_request *auth_request;
struct master_list_iter_ctx *ctx;
- const char *str;
+ const char *str, *name, *arg, *const *list;
unsigned int id;
- /* <id> */
- if (str_to_uint(args, &id) < 0) {
+ /* <id> [<parameters>] */
+ list = t_strsplit(args, "\t");
+ if (list[0] == NULL || str_to_uint(list[0], &id) < 0) {
i_error("BUG: Master sent broken LIST");
- return FALSE;
+ return -1;
}
+ list++;
if (conn->userdb_restricted_uid != 0) {
i_error("Auth client doesn't have permissions to list users: %s",
return TRUE;
}
+ auth_request = auth_request_new_dummy();
+ auth_request->id = id;
+ auth_request->master = conn;
+ auth_master_connection_ref(conn);
+
+ for (; *list != NULL; list++) {
+ arg = strchr(*list, '=');
+ if (arg == NULL) {
+ name = *list;
+ arg = "";
+ } else {
+ name = t_strdup_until(*list, arg);
+ arg++;
+ }
+
+ if (!auth_request_import_info(auth_request, name, arg) &&
+ strcmp(name, "user") == 0) {
+ /* username mask */
+ auth_request->user = p_strdup(auth_request->pool, arg);
+ }
+ }
+
+ /* rest of the code doesn't like NULL user or service */
+ if (auth_request->user == NULL)
+ auth_request->user = "";
+ if (auth_request->service == NULL)
+ auth_request->service = "";
+
ctx = i_new(struct master_list_iter_ctx, 1);
ctx->conn = conn;
- ctx->userdb = userdb;
- ctx->id = id;
+ ctx->auth_request = auth_request;
+ ctx->auth_request->userdb = userdb;
io_remove(&conn->io);
o_stream_set_flush_callback(conn->output, master_output_list, ctx);
- ctx->iter = userdb_blocking_iter_init(ctx->userdb->userdb,
+ ctx->iter = userdb_blocking_iter_init(auth_request,
master_input_list_callback, ctx);
return TRUE;
}
};
struct master_service_settings_input input;
struct setting_parser_context *set_parser;
+ struct auth_settings *set;
const char *error;
memset(&input, 0, sizeof(input));
output_r, &error) < 0)
i_fatal("Error reading configuration: %s", error);
+ pool_ref(pool);
set_parser = settings_parser_dup(master_service->set_parser, pool);
if (!settings_parser_check(set_parser, pool, &error))
i_unreached();
- return settings_parser_get_list(set_parser)[1];
+ set = settings_parser_get_list(set_parser)[1];
+ settings_parser_deinit(&set_parser);
+ return set;
}
struct auth_worker_list_context {
struct auth_worker_client *client;
- struct userdb_module *userdb;
+ struct auth_request *auth_request;
struct userdb_iterate_context *iter;
- unsigned int id;
bool sending, sent, done;
};
i_assert(client->io == NULL);
str = t_str_new(32);
- if (ctx->userdb->iface->iterate_deinit(ctx->iter) < 0)
- str_printfa(str, "%u\tFAIL\n", ctx->id);
+ if (ctx->auth_request->userdb->userdb->iface->
+ iterate_deinit(ctx->iter) < 0)
+ str_printfa(str, "%u\tFAIL\n", ctx->auth_request->id);
else
- str_printfa(str, "%u\tOK\n", ctx->id);
+ str_printfa(str, "%u\tOK\n", ctx->auth_request->id);
auth_worker_send_reply(client, str);
client->io = io_add(client->fd, IO_READ, auth_worker_input, client);
o_stream_set_flush_callback(client->output, auth_worker_output, client);
+ auth_request_unref(&ctx->auth_request);
auth_worker_client_unref(&client);
i_free(ctx);
}
T_BEGIN {
str = t_str_new(128);
- str_printfa(str, "%u\t*\t%s\n", ctx->id, user);
+ str_printfa(str, "%u\t*\t%s\n", ctx->auth_request->id, user);
o_stream_send(ctx->client->output, str_data(str), str_len(str));
} T_END;
do {
ctx->sending = TRUE;
ctx->sent = FALSE;
- ctx->userdb->iface->iterate_next(ctx->iter);
+ ctx->auth_request->userdb->userdb->iface->
+ iterate_next(ctx->iter);
} while (ctx->sent &&
o_stream_get_buffer_used_size(ctx->client->output) == 0);
ctx->sending = FALSE;
list_iter_deinit(ctx);
return 1;
}
- if (ret > 0)
- ctx->userdb->iface->iterate_next(ctx->iter);
+ if (ret > 0) {
+ ctx->auth_request->userdb->userdb->iface->
+ iterate_next(ctx->iter);
+ }
return 1;
}
ctx = i_new(struct auth_worker_list_context, 1);
ctx->client = client;
- ctx->id = id;
- ctx->userdb = userdb->userdb;
+ ctx->auth_request = worker_auth_request_new(client, id, args + 1);
+ ctx->auth_request->userdb = userdb;
+ if (ctx->auth_request->user == NULL ||
+ ctx->auth_request->service == NULL) {
+ i_error("BUG: LIST had missing parameters");
+ auth_request_unref(&ctx->auth_request);
+ i_free(ctx);
+ return FALSE;
+ }
io_remove(&ctx->client->io);
o_stream_set_flush_callback(ctx->client->output,
auth_worker_list_output, ctx);
- client->refcount++;
- ctx->iter = ctx->userdb->iface->
- iterate_init(userdb->userdb, list_iter_callback, ctx);
- ctx->userdb->iface->iterate_next(ctx->iter);
+ ctx->iter = ctx->auth_request->userdb->userdb->iface->
+ iterate_init(ctx->auth_request, list_iter_callback, ctx);
+ ctx->auth_request->userdb->userdb->iface->iterate_next(ctx->iter);
return TRUE;
}
struct blocking_userdb_iterate_context {
struct userdb_iterate_context ctx;
- pool_t pool;
struct auth_worker_connection *conn;
bool next;
bool destroyed;
static bool iter_callback(const char *reply, void *context)
{
struct blocking_userdb_iterate_context *ctx = context;
- pool_t pool = ctx->pool;
if (strncmp(reply, "*\t", 2) == 0) {
ctx->next = FALSE;
ctx->ctx.failed = TRUE;
if (!ctx->destroyed)
ctx->ctx.callback(NULL, ctx->ctx.context);
- pool_unref(&pool);
+ auth_request_unref(&ctx->ctx.auth_request);
return TRUE;
}
struct userdb_iterate_context *
-userdb_blocking_iter_init(struct userdb_module *userdb,
+userdb_blocking_iter_init(struct auth_request *request,
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));
+ auth_stream_reply_add(reply, NULL,
+ dec2str(request->userdb->userdb->id));
+ auth_request_export(request, reply);
- pool = pool_alloconly_create("userdb iter", 512);
- ctx = p_new(pool, struct blocking_userdb_iterate_context, 1);
- ctx->ctx.userdb = userdb;
+ ctx = p_new(request->pool, struct blocking_userdb_iterate_context, 1);
+ ctx->ctx.auth_request = request;
ctx->ctx.callback = callback;
ctx->ctx.context = context;
- ctx->pool = pool;
- pool_ref(pool);
- ctx->conn = auth_worker_call(pool, reply, iter_callback, ctx);
+ auth_request_ref(request);
+ ctx->conn = auth_worker_call(request->pool, reply, iter_callback, ctx);
return &ctx->ctx;
}
*_ctx = NULL;
+ /* iter_callback() may still be called */
ctx->destroyed = TRUE;
- pool_unref(&ctx->pool);
return ret;
}
void userdb_blocking_lookup(struct auth_request *request);
struct userdb_iterate_context *
-userdb_blocking_iter_init(struct userdb_module *userdb,
+userdb_blocking_iter_init(struct auth_request *request,
userdb_iter_callback_t *callback, void *context);
void userdb_blocking_iter_next(struct userdb_iterate_context *ctx);
int userdb_blocking_iter_deinit(struct userdb_iterate_context **ctx);
}
static struct userdb_iterate_context *
-userdb_ldap_iterate_init(struct userdb_module *userdb,
+userdb_ldap_iterate_init(struct auth_request *auth_request,
userdb_iter_callback_t *callback, void *context)
{
- static struct var_expand_table static_tab[] = {
- /* nothing for now, but e.g. %{hostname} can be used */
- { '\0', NULL, NULL }
- };
+ struct userdb_module *_module = auth_request->userdb->userdb;
struct ldap_userdb_module *module =
- (struct ldap_userdb_module *)userdb;
+ (struct ldap_userdb_module *)_module;
struct ldap_connection *conn = module->conn;
struct ldap_userdb_iterate_context *ctx;
struct userdb_iter_ldap_request *request;
+ const struct var_expand_table *vars;
const char **attr_names = (const char **)conn->iterate_attr_names;
string_t *str;
ctx = i_new(struct ldap_userdb_iterate_context, 1);
- ctx->ctx.userdb = userdb;
+ ctx->ctx.auth_request = auth_request;
ctx->ctx.callback = callback;
ctx->ctx.context = context;
ctx->conn = conn;
request = &ctx->request;
request->ctx = ctx;
- request->request.request.auth_request = auth_request_new_dummy();
- request->request.base = conn->set.base;
+ auth_request_ref(auth_request);
+ request->request.request.auth_request = auth_request;
+
+ vars = auth_request_get_var_expand_table(auth_request, ldap_escape);
str = t_str_new(512);
- var_expand(str, conn->set.iterate_filter, static_tab);
- request->request.filter =
- p_strdup(request->request.request.auth_request->pool,
- str_c(str));
+ var_expand(str, conn->set.base, vars);
+ request->request.base = p_strdup(auth_request->pool, str_c(str));
+
+ str_truncate(str, 0);
+ var_expand(str, conn->set.iterate_filter, vars);
+ request->request.filter = p_strdup(auth_request->pool, str_c(str));
request->request.attributes = conn->iterate_attr_names;
if (global_auth_settings->debug) {
}
static struct userdb_iterate_context *
-passwd_file_iterate_init(struct userdb_module *userdb,
+passwd_file_iterate_init(struct auth_request *auth_request,
userdb_iter_callback_t *callback, void *context)
{
+ struct userdb_module *_module = auth_request->userdb->userdb;
struct passwd_file_userdb_module *module =
- (struct passwd_file_userdb_module *)userdb;
+ (struct passwd_file_userdb_module *)_module;
struct passwd_file_userdb_iterate_context *ctx;
int fd;
ctx = i_new(struct passwd_file_userdb_iterate_context, 1);
- ctx->ctx.userdb = userdb;
+ ctx->ctx.auth_request = auth_request;
ctx->ctx.callback = callback;
ctx->ctx.context = context;
if (module->pwf->default_file == NULL) {
struct passwd_userdb_iterate_context {
struct userdb_iterate_context ctx;
struct passwd_userdb_iterate_context *next_waiting;
- const struct auth_settings *set;
};
static struct passwd_userdb_iterate_context *cur_userdb_iter = NULL;
}
static struct userdb_iterate_context *
-passwd_iterate_init(struct userdb_module *userdb,
+passwd_iterate_init(struct auth_request *auth_request,
userdb_iter_callback_t *callback, void *context)
{
struct passwd_userdb_iterate_context *ctx;
ctx = i_new(struct passwd_userdb_iterate_context, 1);
- ctx->ctx.userdb = userdb;
+ ctx->ctx.auth_request = auth_request;
ctx->ctx.callback = callback;
ctx->ctx.context = context;
- ctx->set = auth_find_service("")->set;
setpwent();
if (cur_userdb_iter == NULL)
{
struct passwd_userdb_iterate_context *ctx =
(struct passwd_userdb_iterate_context *)_ctx;
+ const struct auth_settings *set = _ctx->auth_request->set;
struct passwd *pw;
if (cur_userdb_iter != NULL && cur_userdb_iter != ctx) {
while ((pw = getpwent()) != NULL) {
/* skip entries not in valid UID range.
they're users for daemons and such. */
- if (pw->pw_uid >= (uid_t)ctx->set->first_valid_uid &&
- (ctx->set->last_valid_uid == 0 ||
- pw->pw_uid <= (uid_t)ctx->set->last_valid_uid)) {
+ if (pw->pw_uid >= (uid_t)set->first_valid_uid &&
+ (set->last_valid_uid == 0 ||
+ pw->pw_uid <= (uid_t)set->last_valid_uid)) {
_ctx->callback(pw->pw_name, _ctx->context);
return;
}
}
static struct userdb_iterate_context *
-userdb_sql_iterate_init(struct userdb_module *userdb,
+userdb_sql_iterate_init(struct auth_request *auth_request,
userdb_iter_callback_t *callback, void *context)
{
- static struct var_expand_table static_tab[] = {
- /* nothing for now, but e.g. %{hostname} can be used */
- { '\0', NULL, NULL }
- };
+ struct userdb_module *_module = auth_request->userdb->userdb;
struct sql_userdb_module *module =
- (struct sql_userdb_module *)userdb;
+ (struct sql_userdb_module *)_module;
struct sql_userdb_iterate_context *ctx;
string_t *query;
query = t_str_new(512);
- var_expand(query, module->conn->set.iterate_query, static_tab);
+ var_expand(query, module->conn->set.iterate_query,
+ auth_request_get_var_expand_table(auth_request,
+ userdb_sql_escape));
ctx = i_new(struct sql_userdb_iterate_context, 1);
- ctx->ctx.userdb = userdb;
+ ctx->ctx.auth_request = auth_request;
ctx->ctx.callback = callback;
ctx->ctx.context = context;
+ auth_request_ref(auth_request);
sql_query(module->conn->db, str_c(query),
sql_iter_query_callback, ctx);
+ auth_request_log_debug(auth_request, "sql", "%s", str_c(query));
return &ctx->ctx;
}
{
struct sql_userdb_iterate_context *ctx =
(struct sql_userdb_iterate_context *)_ctx;
- struct userdb_module *_module = _ctx->userdb;
+ struct userdb_module *_module = _ctx->auth_request->userdb->userdb;
struct sql_userdb_module *module = (struct sql_userdb_module *)_module;
const char *user;
int ret;
(struct sql_userdb_iterate_context *)_ctx;
int ret = _ctx->failed ? -1 : 0;
+ auth_request_unref(&_ctx->auth_request);
if (ctx->result == NULL) {
/* sql query hasn't finished yet */
ctx->freed = TRUE;
};
struct userdb_iterate_context {
- struct userdb_module *userdb;
+ struct auth_request *auth_request;
userdb_iter_callback_t *callback;
void *context;
bool failed;
userdb_callback_t *callback);
struct userdb_iterate_context *
- (*iterate_init)(struct userdb_module *userdb,
+ (*iterate_init)(struct auth_request *auth_request,
userdb_iter_callback_t *callback,
void *context);
void (*iterate_next)(struct userdb_iterate_context *ctx);