Beispiel #1
0
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;
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
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);
}
Beispiel #5
0
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);
}
Beispiel #6
0
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);
}
Beispiel #7
0
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;
}
Beispiel #8
0
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);
}
Beispiel #9
0
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;
}
Beispiel #10
0
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);
}
Beispiel #11
0
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);
	}
}
Beispiel #13
0
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);
}
Beispiel #14
0
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;
}