static struct userdb_iterate_context * userdb_sql_iterate_init(struct auth_request *auth_request, userdb_iter_callback_t *callback, void *context) { struct userdb_module *_module = auth_request->userdb->userdb; struct sql_userdb_module *module = (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, auth_request_get_var_expand_table(auth_request, userdb_sql_escape)); ctx = i_new(struct sql_userdb_iterate_context, 1); 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, AUTH_SUBSYS_DB, "%s", str_c(query)); return &ctx->ctx; }
static void sql_lookup_pass(struct passdb_sql_request *sql_request) { struct passdb_module *_module = sql_request->auth_request->passdb->passdb; struct sql_passdb_module *module = (struct sql_passdb_module *)_module; const char *query, *error; if (t_auth_request_var_expand(module->conn->set.password_query, sql_request->auth_request, passdb_sql_escape, &query, &error) <= 0) { auth_request_log_debug(sql_request->auth_request, AUTH_SUBSYS_DB, "Failed to expand password_query=%s: %s", module->conn->set.password_query, error); sql_request->callback.verify_plain(PASSDB_RESULT_INTERNAL_FAILURE, sql_request->auth_request); return; } auth_request_log_debug(sql_request->auth_request, AUTH_SUBSYS_DB, "query: %s", query); auth_request_ref(sql_request->auth_request); sql_query(module->conn->db, query, sql_query_callback, sql_request); }
void userdb_blocking_lookup(struct auth_request *request) { string_t *str; str = t_str_new(128); str_printfa(str, "USER\t%u\t", request->userdb->userdb->id); auth_request_export(request, str); auth_request_ref(request); auth_worker_call(request->pool, request->user, str_c(str), user_callback, request); }
void passdb_blocking_verify_plain(struct auth_request *request) { string_t *str; str = t_str_new(128); str_printfa(str, "PASSV\t%u\t", request->passdb->passdb->id); str_append_tabescaped(str, request->mech_password); str_append_c(str, '\t'); auth_request_export(request, str); auth_request_ref(request); auth_worker_call(request->pool, request->user, str_c(str), verify_plain_callback, request); }
void passdb_blocking_lookup_credentials(struct auth_request *request) { string_t *str; str = t_str_new(128); str_printfa(str, "PASSL\t%u\t", request->passdb->passdb->id); str_append_tabescaped(str, request->credentials_scheme); str_append_c(str, '\t'); auth_request_export(request, str); auth_request_ref(request); auth_worker_call(request->pool, request->user, str_c(str), lookup_credentials_callback, request); }
void passdb_blocking_set_credentials(struct auth_request *request, const char *new_credentials) { string_t *str; str = t_str_new(128); str_printfa(str, "SETCRED\t%u\t", request->passdb->passdb->id); str_append_tabescaped(str, new_credentials); str_append_c(str, '\t'); auth_request_export(request, str); auth_request_ref(request); auth_worker_call(request->pool, request->user, str_c(str), set_credentials_callback, request); }
static struct userdb_iterate_context * userdb_ldap_iterate_init(struct auth_request *auth_request, userdb_iter_callback_t *callback, void *context) { struct userdb_module *_module = auth_request->userdb->userdb; struct ldap_userdb_module *module = (struct ldap_userdb_module *)_module; struct ldap_connection *conn = module->conn; struct ldap_userdb_iterate_context *ctx; struct userdb_iter_ldap_request *request; const char **attr_names = (const char **)conn->iterate_attr_names; string_t *str; ctx = i_new(struct ldap_userdb_iterate_context, 1); ctx->ctx.auth_request = auth_request; ctx->ctx.callback = callback; ctx->ctx.context = context; ctx->conn = conn; request = &ctx->request; request->ctx = ctx; auth_request_ref(auth_request); request->request.request.auth_request = auth_request; str = t_str_new(512); auth_request_var_expand(str, conn->set.base, auth_request, ldap_escape); request->request.base = p_strdup(auth_request->pool, str_c(str)); str_truncate(str, 0); auth_request_var_expand(str, conn->set.iterate_filter, auth_request, ldap_escape); request->request.filter = p_strdup(auth_request->pool, str_c(str)); request->request.attr_map = &conn->iterate_attr_map; request->request.attributes = conn->iterate_attr_names; request->request.multi_entry = TRUE; if (global_auth_settings->debug) { i_debug("ldap: iterate: base=%s scope=%s filter=%s fields=%s", request->request.base, conn->set.scope, request->request.filter, attr_names == NULL ? "(all)" : t_strarray_join(attr_names, ",")); } request->request.request.callback = userdb_ldap_iterate_callback; db_ldap_request(conn, &request->request.request); return &ctx->ctx; }
static void sql_lookup_pass(struct passdb_sql_request *sql_request) { struct passdb_module *_module = sql_request->auth_request->passdb->passdb; struct sql_passdb_module *module = (struct sql_passdb_module *)_module; const char *query; query = t_auth_request_var_expand(module->conn->set.password_query, sql_request->auth_request, passdb_sql_escape); auth_request_log_debug(sql_request->auth_request, AUTH_SUBSYS_DB, "query: %s", query); auth_request_ref(sql_request->auth_request); sql_query(module->conn->db, query, sql_query_callback, sql_request); }
static struct userdb_iterate_context * userdb_dict_iterate_init(struct auth_request *auth_request, userdb_iter_callback_t *callback, void *context) { struct userdb_module *_module = auth_request->userdb->userdb; struct dict_userdb_module *module = (struct dict_userdb_module *)_module; struct dict_userdb_iterate_context *ctx; string_t *path; const char *error; ctx = i_new(struct dict_userdb_iterate_context, 1); ctx->ctx.auth_request = auth_request; ctx->ctx.callback = callback; ctx->ctx.context = context; auth_request_ref(auth_request); if (*module->conn->set.iterate_prefix == '\0') { if (!module->conn->set.iterate_disable) { auth_request_log_error(auth_request, AUTH_SUBSYS_DB, "iterate: iterate_prefix not set"); ctx->ctx.failed = TRUE; } return &ctx->ctx; } path = t_str_new(128); str_append(path, DICT_PATH_SHARED); if (auth_request_var_expand(path, module->conn->set.iterate_prefix, auth_request, NULL, &error) <= 0) { auth_request_log_error(auth_request, AUTH_SUBSYS_DB, "Failed to expand iterate_prefix=%s: %s", module->conn->set.iterate_prefix, error); ctx->ctx.failed = TRUE; return &ctx->ctx; } ctx->key_prefix = p_strdup(auth_request->pool, str_c(path)); ctx->key_prefix_len = strlen(ctx->key_prefix); ctx->iter = dict_iterate_init(module->conn->dict, ctx->key_prefix, 0); auth_request_log_debug(auth_request, AUTH_SUBSYS_DB, "iterate: prefix=%s", ctx->key_prefix); return &ctx->ctx; }
static void passdb_imap_verify_plain(struct auth_request *auth_request, const char *password, verify_plain_callback_t *callback) { struct passdb_module *_module = auth_request->passdb->passdb; struct imap_passdb_module *module = (struct imap_passdb_module *)_module; struct imap_auth_request *request; struct imapc_client_settings set; const struct var_expand_table *table; string_t *str; set = module->set; set.debug = auth_request->set->debug; set.dns_client_socket_path = t_strconcat(auth_request->set->base_dir, "/", DNS_CLIENT_SOCKET_NAME, NULL); set.password = password; set.max_idle_time = IMAPC_DEFAULT_MAX_IDLE_TIME; if (module->set_have_vars) { str = t_str_new(128); table = auth_request_get_var_expand_table(auth_request, NULL); var_expand(str, set.username, table); set.username = t_strdup(str_c(str)); str_truncate(str, 0); var_expand(str, set.host, table); set.host = t_strdup(str_c(str)); } auth_request_log_debug(auth_request, AUTH_SUBSYS_DB, "lookup host=%s port=%d", set.host, set.port); request = p_new(auth_request->pool, struct imap_auth_request, 1); request->client = imapc_client_init(&set); request->auth_request = auth_request; request->verify_callback = callback; auth_request_ref(auth_request); imapc_client_login(request->client, passdb_imap_login_callback, request); }
struct userdb_iterate_context * userdb_blocking_iter_init(struct auth_request *request, userdb_iter_callback_t *callback, void *context) { struct blocking_userdb_iterate_context *ctx; string_t *str; str = t_str_new(128); str_printfa(str, "LIST\t%u\t", request->userdb->userdb->id); auth_request_export(request, str); ctx = p_new(request->pool, struct blocking_userdb_iterate_context, 1); ctx->ctx.auth_request = request; ctx->ctx.callback = callback; ctx->ctx.context = context; auth_request_ref(request); ctx->conn = auth_worker_call(request->pool, "*", str_c(str), iter_callback, ctx); return &ctx->ctx; }
static void auth_request_handle_failure(struct auth_request *request, const char *reply) { struct auth_request_handler *handler = request->handler; if (request->in_delayed_failure_queue) { /* we came here from flush_failures() */ handler->callback(reply, handler->context); return; } /* remove the request from requests-list */ auth_request_ref(request); auth_request_handler_remove(handler, request); if (auth_fields_exists(request->extra_fields, "nodelay")) { /* passdb specifically requested not to delay the reply. */ handler->callback(reply, handler->context); auth_request_unref(&request); return; } /* failure. don't announce it immediately to avoid a) timing attacks, b) flooding */ request->in_delayed_failure_queue = TRUE; handler->refcount++; if (auth_penalty != NULL) { auth_penalty_update(auth_penalty, request, request->last_penalty + 1); } auth_request_refresh_last_access(request); aqueue_append(auth_failures, &request); if (to_auth_failures == NULL) { to_auth_failures = timeout_add_short(AUTH_FAILURE_DELAY_CHECK_MSECS, auth_failure_timeout, (void *)NULL); } }
static void userdb_ldap_lookup(struct auth_request *auth_request, userdb_callback_t *callback) { struct userdb_module *_module = auth_request->userdb->userdb; struct ldap_userdb_module *module = (struct ldap_userdb_module *)_module; struct ldap_connection *conn = module->conn; const char **attr_names = (const char **)conn->user_attr_names; struct userdb_ldap_request *request; string_t *str; auth_request_ref(auth_request); request = p_new(auth_request->pool, struct userdb_ldap_request, 1); request->userdb_callback = callback; str = t_str_new(512); auth_request_var_expand(str, conn->set.base, auth_request, ldap_escape); request->request.base = p_strdup(auth_request->pool, str_c(str)); str_truncate(str, 0); auth_request_var_expand(str, conn->set.user_filter, auth_request, ldap_escape); request->request.filter = p_strdup(auth_request->pool, str_c(str)); request->request.attr_map = &conn->user_attr_map; request->request.attributes = conn->user_attr_names; auth_request_log_debug(auth_request, AUTH_SUBSYS_DB, "user search: " "base=%s scope=%s filter=%s fields=%s", request->request.base, conn->set.scope, request->request.filter, attr_names == NULL ? "(all)" : t_strarray_join(attr_names, ",")); request->request.request.auth_request = auth_request; request->request.request.callback = userdb_ldap_lookup_callback; db_ldap_request(conn, &request->request.request); }
static void userdb_sql_lookup(struct auth_request *auth_request, userdb_callback_t *callback) { struct userdb_module *_module = auth_request->userdb->userdb; struct sql_userdb_module *module = (struct sql_userdb_module *)_module; struct userdb_sql_request *sql_request; string_t *query; query = t_str_new(512); var_expand(query, module->conn->set.user_query, auth_request_get_var_expand_table(auth_request, userdb_sql_escape)); auth_request_ref(auth_request); sql_request = i_new(struct userdb_sql_request, 1); sql_request->callback = callback; sql_request->auth_request = auth_request; auth_request_log_debug(auth_request, AUTH_SUBSYS_DB, "%s", str_c(query)); sql_query(module->conn->db, str_c(query), sql_query_callback, sql_request); }
static void checkpassword_lookup(struct auth_request *request, userdb_callback_t *callback) { struct userdb_module *_module = request->userdb->userdb; struct checkpassword_userdb_module *module = (struct checkpassword_userdb_module *)_module; struct chkpw_auth_request *chkpw_auth_request; int fd_in[2], fd_out[2]; pid_t pid; fd_in[0] = -1; if (pipe(fd_in) < 0 || pipe(fd_out) < 0) { auth_request_log_error(request, "userdb-checkpassword", "pipe() failed: %m"); callback(USERDB_RESULT_INTERNAL_FAILURE, request); if (fd_in[0] != -1) { (void)close(fd_in[0]); (void)close(fd_in[1]); } return; } pid = fork(); if (pid == -1) { auth_request_log_error(request, "userdb-checkpassword", "fork() failed: %m"); callback(USERDB_RESULT_INTERNAL_FAILURE, request); (void)close(fd_in[0]); (void)close(fd_in[1]); (void)close(fd_out[0]); (void)close(fd_out[1]); return; } if (pid == 0) { (void)close(fd_in[0]); (void)close(fd_out[1]); checkpassword_lookup_child(request, module, fd_in[1], fd_out[0]); /* not reached */ } if (close(fd_in[1]) < 0) { auth_request_log_error(request, "userdb-checkpassword", "close(fd_in[1]) failed: %m"); } if (close(fd_out[0]) < 0) { auth_request_log_error(request, "userdb-checkpassword", "close(fd_out[0]) failed: %m"); } auth_request_ref(request); chkpw_auth_request = i_new(struct chkpw_auth_request, 1); chkpw_auth_request->fd_in = fd_in[0]; chkpw_auth_request->fd_out = fd_out[1]; chkpw_auth_request->pid = pid; chkpw_auth_request->request = request; chkpw_auth_request->callback = callback; chkpw_auth_request->half_finish_callback = checkpassword_request_half_finish; chkpw_auth_request->finish_callback = checkpassword_request_finish; chkpw_auth_request->internal_failure_code = USERDB_RESULT_INTERNAL_FAILURE; chkpw_auth_request->io_in = io_add(fd_in[0], IO_READ, checkpassword_child_input, chkpw_auth_request); chkpw_auth_request->io_out = io_add(fd_out[1], IO_WRITE, checkpassword_child_output, chkpw_auth_request); hash_table_insert(module->clients, POINTER_CAST(pid), chkpw_auth_request); if (checkpassword_userdb_children != NULL) child_wait_add_pid(checkpassword_userdb_children, pid); else { checkpassword_userdb_children = child_wait_new_with_pid(pid, sigchld_handler, module); } }
bool auth_request_handler_master_request(struct auth_request_handler *handler, struct auth_master_connection *master, unsigned int id, unsigned int client_id, const char *const *params) { struct auth_request *request; struct net_unix_cred cred; request = hash_table_lookup(handler->requests, POINTER_CAST(client_id)); if (request == NULL) { i_error("Master request %u.%u not found", handler->client_pid, client_id); return auth_master_request_failed(handler, master, id); } auth_request_ref(request); auth_request_handler_remove(handler, request); for (; *params != NULL; params++) { const char *name, *param = strchr(*params, '='); if (param == NULL) { name = *params; param = ""; } else { name = t_strdup_until(*params, param); param++; } (void)auth_request_import_master(request, name, param); } /* verify session pid if specified and possible */ if (request->session_pid != (pid_t)-1 && net_getunixcred(master->fd, &cred) == 0 && cred.pid != (pid_t)-1 && request->session_pid != cred.pid) { i_error("Session pid %ld provided by master for request %u.%u " "did not match peer credentials (pid=%ld, uid=%ld)", (long)request->session_pid, handler->client_pid, client_id, (long)cred.pid, (long)cred.uid); return auth_master_request_failed(handler, master, id); } if (request->state != AUTH_REQUEST_STATE_FINISHED || !request->successful) { i_error("Master requested unfinished authentication request " "%u.%u", handler->client_pid, client_id); handler->master_callback(t_strdup_printf("FAIL\t%u", id), master); auth_request_unref(&request); } else { /* the request isn't being referenced anywhere anymore, so we can do a bit of kludging.. replace the request's old client_id with master's id. */ auth_request_set_state(request, AUTH_REQUEST_STATE_USERDB); request->id = id; request->master = master; /* master and handler are referenced until userdb_callback i s called. */ auth_master_connection_ref(master); handler->refcount++; auth_request_lookup_user(request, userdb_callback); } return TRUE; }