From 6cdead166ba53fc09cee8696b5ff5a85f48fbc84 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Thu, 23 Feb 2017 16:19:22 +0300 Subject: [PATCH] Start/stop auth modules when host is added/deleted --- src/ejabberd_auth.erl | 41 ++++++++++++++++++++++++---------- src/ejabberd_auth_external.erl | 6 ++++- src/ejabberd_auth_ldap.erl | 2 +- src/ejabberd_auth_mnesia.erl | 5 ++++- src/ejabberd_auth_pam.erl | 5 ++++- src/ejabberd_auth_riak.erl | 5 ++++- src/ejabberd_auth_sql.erl | 4 +++- src/gen_mod.erl | 2 +- 8 files changed, 51 insertions(+), 19 deletions(-) diff --git a/src/ejabberd_auth.erl b/src/ejabberd_auth.erl index 88b39f48a..fd5b6b244 100644 --- a/src/ejabberd_auth.erl +++ b/src/ejabberd_auth.erl @@ -32,7 +32,7 @@ -author('alexey@process-one.net'). %% External exports --export([start/0, set_password/3, check_password/4, +-export([start/0, start/1, stop/1, set_password/3, check_password/4, check_password/6, check_password_with_authmodule/4, check_password_with_authmodule/6, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, @@ -61,6 +61,7 @@ {offset, integer()}]. -callback start(binary()) -> any(). +-callback stop(binary()) -> any(). -callback plain_password_required() -> boolean(). -callback store_type() -> plain | external | scram. -callback set_password(binary(), binary(), binary()) -> ok | {error, atom()}. @@ -81,12 +82,20 @@ -callback get_password_s(binary(), binary()) -> password(). start() -> - %% This is only executed by ejabberd_c2s for non-SASL auth client - lists:foreach(fun (Host) -> - lists:foreach(fun (M) -> M:start(Host) end, - auth_modules(Host)) - end, - ?MYHOSTS). + ets:new(ejabberd_auth_modules, [named_table, public]), + ejabberd_hooks:add(host_up, ?MODULE, start, 30), + ejabberd_hooks:add(host_down, ?MODULE, stop, 80), + lists:foreach(fun start/1, ?MYHOSTS). + +start(Host) -> + Modules = auth_modules_from_config(Host), + ets:insert(ejabberd_auth_modules, {Host, Modules}), + lists:foreach(fun(M) -> M:start(Host) end, Modules). + +stop(Host) -> + OldModules = auth_modules(Host), + ets:delete(ejabberd_auth_modules, Host), + lists:foreach(fun(M) -> M:stop(Host) end, OldModules). plain_password_required(Server) -> lists:any(fun (M) -> M:plain_password_required() end, @@ -429,21 +438,29 @@ backend_type(Mod) -> %% Return the lists of all the auth modules actually used in the %% configuration auth_modules() -> - lists:usort(lists:flatmap(fun (Server) -> - auth_modules(Server) - end, - ?MYHOSTS)). + lists:usort(lists:flatmap(fun auth_modules/1, ?MYHOSTS)). -spec auth_modules(binary()) -> [atom()]. %% Return the list of authenticated modules for a given host auth_modules(Server) -> + LServer = jid:nameprep(Server), + try ets:lookup(ejabberd_auth_modules, LServer) of + [{_, Modules}] -> Modules; + _ -> [] + catch error:badarg -> + %% ejabberd_auth is not started yet + auth_modules_from_config(Server) + end. + +-spec auth_modules_from_config(binary()) -> [module()]. +auth_modules_from_config(Server) -> LServer = jid:nameprep(Server), Default = ejabberd_config:default_db(LServer, ?MODULE), Methods = ejabberd_config:get_option( {auth_method, LServer}, opt_type(auth_method), [Default]), [jlib:binary_to_atom(<<"ejabberd_auth_", - (jlib:atom_to_binary(M))/binary>>) + (jlib:atom_to_binary(M))/binary>>) || M <- Methods]. export(Server) -> diff --git a/src/ejabberd_auth_external.erl b/src/ejabberd_auth_external.erl index 333543b0b..4ba76cd99 100644 --- a/src/ejabberd_auth_external.erl +++ b/src/ejabberd_auth_external.erl @@ -31,7 +31,7 @@ -behaviour(ejabberd_auth). --export([start/1, set_password/3, check_password/4, +-export([start/1, stop/1, set_password/3, check_password/4, check_password/6, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, get_vh_registered_users/2, @@ -58,6 +58,10 @@ start(Host) -> check_cache_last_options(Host), ejabberd_auth_mnesia:start(Host). +stop(Host) -> + extauth:stop(Host), + ejabberd_auth_mnesia:stop(Host). + check_cache_last_options(Server) -> case get_cache_option(Server) of false -> no_cache; diff --git a/src/ejabberd_auth_ldap.erl b/src/ejabberd_auth_ldap.erl index 75c6a0f6e..18770a512 100644 --- a/src/ejabberd_auth_ldap.erl +++ b/src/ejabberd_auth_ldap.erl @@ -90,7 +90,6 @@ start(Host) -> stop(Host) -> Proc = gen_mod:get_module_proc(Host, ?MODULE), - gen_server:call(Proc, stop), supervisor:terminate_child(ejabberd_sup, Proc), supervisor:delete_child(ejabberd_sup, Proc). @@ -101,6 +100,7 @@ start_link(Host) -> terminate(_Reason, _State) -> ok. init(Host) -> + process_flag(trap_exit, true), State = parse_options(Host), eldap_pool:start_link(State#state.eldap_id, State#state.servers, State#state.backups, diff --git a/src/ejabberd_auth_mnesia.erl b/src/ejabberd_auth_mnesia.erl index 3145d90ca..9d1632ef8 100644 --- a/src/ejabberd_auth_mnesia.erl +++ b/src/ejabberd_auth_mnesia.erl @@ -33,7 +33,7 @@ -behaviour(ejabberd_auth). --export([start/1, set_password/3, check_password/4, +-export([start/1, stop/1, set_password/3, check_password/4, check_password/6, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, get_vh_registered_users/2, init_db/0, @@ -65,6 +65,9 @@ start(Host) -> maybe_alert_password_scrammed_without_option(), ok. +stop(_Host) -> + ok. + init_db() -> ejabberd_mnesia:create(?MODULE, passwd, [{disc_copies, [node()]}, diff --git a/src/ejabberd_auth_pam.erl b/src/ejabberd_auth_pam.erl index 9e5e63ac1..51ad3a881 100644 --- a/src/ejabberd_auth_pam.erl +++ b/src/ejabberd_auth_pam.erl @@ -30,7 +30,7 @@ -behaviour(ejabberd_auth). --export([start/1, set_password/3, check_password/4, +-export([start/1, stop/1, set_password/3, check_password/4, check_password/6, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, get_vh_registered_users/2, @@ -43,6 +43,9 @@ start(_Host) -> ejabberd:start_app(epam). +stop(_Host) -> + ok. + set_password(_User, _Server, _Password) -> {error, not_allowed}. diff --git a/src/ejabberd_auth_riak.erl b/src/ejabberd_auth_riak.erl index 6067c35ed..69b1862c1 100644 --- a/src/ejabberd_auth_riak.erl +++ b/src/ejabberd_auth_riak.erl @@ -34,7 +34,7 @@ -behaviour(ejabberd_auth). %% External exports --export([start/1, set_password/3, check_password/4, +-export([start/1, stop/1, set_password/3, check_password/4, check_password/6, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, get_vh_registered_users/2, @@ -56,6 +56,9 @@ start(_Host) -> ok. +stop(_Host) -> + ok. + plain_password_required() -> case is_scrammed() of false -> false; diff --git a/src/ejabberd_auth_sql.erl b/src/ejabberd_auth_sql.erl index d8fc61703..2cc7a278a 100644 --- a/src/ejabberd_auth_sql.erl +++ b/src/ejabberd_auth_sql.erl @@ -33,7 +33,7 @@ -behaviour(ejabberd_auth). --export([start/1, set_password/3, check_password/4, +-export([start/1, stop/1, set_password/3, check_password/4, check_password/6, try_register/3, dirty_get_registered_users/0, get_vh_registered_users/1, get_vh_registered_users/2, @@ -54,6 +54,8 @@ %%%---------------------------------------------------------------------- start(_Host) -> ok. +stop(_Host) -> ok. + plain_password_required() -> case is_scrammed() of false -> false; diff --git a/src/gen_mod.erl b/src/gen_mod.erl index 178fccb1f..77edb0e90 100644 --- a/src/gen_mod.erl +++ b/src/gen_mod.erl @@ -81,7 +81,7 @@ start_link() -> init([]) -> ejabberd_hooks:add(config_reloaded, ?MODULE, config_reloaded, 50), ejabberd_hooks:add(host_up, ?MODULE, start_modules, 40), - ejabberd_hooks:add(host_down, ?MODULE, stop_modules, 80), + ejabberd_hooks:add(host_down, ?MODULE, stop_modules, 70), ets:new(ejabberd_modules, [named_table, public, {keypos, #ejabberd_module.module_host}]),