diff options
author | Evgeniy Khramtsov <ekhramtsov@process-one.net> | 2018-05-07 19:27:18 +0300 |
---|---|---|
committer | Evgeniy Khramtsov <ekhramtsov@process-one.net> | 2018-05-07 19:27:18 +0300 |
commit | b23d5754e81fe27de16e57c28644d83c43dc169d (patch) | |
tree | 6753338d1afa48fb47226ba40bc0c9ef4a5d0407 /src/ejabberd_auth.erl | |
parent | Make trusted_proxied ejabberd_http option accept ip masks (diff) |
Improve robustness of external authentication backends
Now all external ports are attached to supervising processes
and requests are balanced in round-robin manner until the pool
is exhausted.
The commit also deprecates `extauth_instances` option and introduces
`extauth_pool_size` option instead, with the default value of a number
of logical processors (i.e. CPU cores).
Fixes #2403
Diffstat (limited to 'src/ejabberd_auth.erl')
-rw-r--r-- | src/ejabberd_auth.erl | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/src/ejabberd_auth.erl b/src/ejabberd_auth.erl index 585b4a9b..847549c7 100644 --- a/src/ejabberd_auth.erl +++ b/src/ejabberd_auth.erl @@ -69,6 +69,7 @@ -callback start(binary()) -> any(). -callback stop(binary()) -> any(). +-callback reload(binary()) -> any(). -callback plain_password_required(binary()) -> boolean(). -callback store_type(binary()) -> plain | external | scram. -callback set_password(binary(), binary(), binary()) -> ok | {error, atom()}. @@ -82,7 +83,8 @@ -callback use_cache(binary()) -> boolean(). -callback cache_nodes(binary()) -> boolean(). --optional_callbacks([set_password/3, +-optional_callbacks([reload/1, + set_password/3, remove_user/2, user_exists/2, check_password/4, @@ -130,14 +132,16 @@ handle_cast({host_down, Host}, #state{host_modules = HostModules} = State) -> init_cache(NewHostModules), {noreply, State#state{host_modules = NewHostModules}}; handle_cast(config_reloaded, #state{host_modules = HostModules} = State) -> - NewHostModules = lists:foldl( - fun(Host, Acc) -> - OldModules = maps:get(Host, HostModules, []), - NewModules = auth_modules(Host), - start(Host, NewModules -- OldModules), - stop(Host, OldModules -- NewModules), - maps:put(Host, NewModules, Acc) - end, HostModules, ?MYHOSTS), + NewHostModules = + lists:foldl( + fun(Host, Acc) -> + OldModules = maps:get(Host, HostModules, []), + NewModules = auth_modules(Host), + start(Host, NewModules -- OldModules), + stop(Host, OldModules -- NewModules), + reload(Host, lists_intersection(OldModules, NewModules)), + maps:put(Host, NewModules, Acc) + end, HostModules, ?MYHOSTS), init_cache(NewHostModules), {noreply, State#state{host_modules = NewHostModules}}; handle_cast(Msg, State) -> @@ -165,6 +169,15 @@ start(Host, Modules) -> stop(Host, Modules) -> lists:foreach(fun(M) -> M:stop(Host) end, Modules). +reload(Host, Modules) -> + lists:foreach( + fun(M) -> + case erlang:function_exported(M, reload, 1) of + true -> M:reload(Host); + false -> ok + end + end, Modules). + host_up(Host) -> gen_server:cast(?MODULE, {host_up, Host}). @@ -559,7 +572,9 @@ db_user_exists(User, Server, Mod) -> {ok, _} -> true; error -> - false + false; + {error, _} = Err -> + Err end; {external, false} -> Mod:user_exists(User, Server); @@ -816,6 +831,12 @@ validate_credentials(User, Server, Password) -> end end. +lists_intersection(L1, L2) -> + lists:filter( + fun(E) -> + lists:member(E, L2) + end, L1). + import_info() -> [{<<"users">>, 3}]. |