aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/guide.html8
-rw-r--r--doc/guide.tex8
-rw-r--r--src/extauth.erl37
3 files changed, 44 insertions, 9 deletions
diff --git a/doc/guide.html b/doc/guide.html
index 3b78cba9e..57873a873 100644
--- a/doc/guide.html
+++ b/doc/guide.html
@@ -1060,7 +1060,9 @@ There are also <A HREF="http://www.ejabberd.im/extauth">several example authenti
</P><DL CLASS="description"><DT CLASS="dt-description">
<B><TT>{extauth_program, PathToScript}</TT></B></DT><DD CLASS="dd-description">
Indicate in this option the full path to the external authentication script.
-The script must be executable by ejabberd.</DD><DT CLASS="dt-description"><B><TT>{extauth_cache, false|CacheTimeInteger}</TT></B></DT><DD CLASS="dd-description">
+The script must be executable by ejabberd.</DD><DT CLASS="dt-description"><B><TT>{extauth_instances, Integer}</TT></B></DT><DD CLASS="dd-description">
+Indicate how many instances of the script to run simultaneously to serve authentication in the virtual host.
+The default value is the minimum number: 1.</DD><DT CLASS="dt-description"><B><TT>{extauth_cache, false|CacheTimeInteger}</TT></B></DT><DD CLASS="dd-description">
The value <TT>false</TT> disables the caching feature, this is the default.
The integer <TT>0</TT> (zero) enables caching for statistics, but doesn&#X2019;t use that cached information to authenticate users.
If another integer value is set, caching is enabled both for statistics and for authentication:
@@ -1069,10 +1071,12 @@ the authentication information since the user last disconnected,
to verify again the user authentication without querying again the extauth script.
Note: caching should not be enabled in a host if internal auth is also enabled.
If caching is enabled, <TT>mod_last</TT> or <TT>mod_last_odbc</TT> must be enabled also in that vhost.
-</DD></DL><P>This example sets external authentication, the extauth script, and enables caching for 10 minutes:
+</DD></DL><P>This example sets external authentication, the extauth script, enables caching for 10 minutes,
+and starts three instances of the script for each virtual host defined in ejabberd:
</P><PRE CLASS="verbatim">{auth_method, [external]}.
{extauth_program, "/etc/ejabberd/JabberAuth.class.php"}.
{extauth_cache, 600}.
+{extauth_instances, 3}.
</PRE><P> <A NAME="saslanonymous"></A> </P><!--TOC subsubsection SASL Anonymous and Anonymous Login-->
<H4 CLASS="subsubsection"><!--SEC ANCHOR --><A HREF="#saslanonymous">SASL Anonymous and Anonymous Login</A></H4><!--SEC END --><P> <A NAME="saslanonymous"></A>
</P><P>The value <TT>anonymous</TT> will enable the internal authentication method.</P><P>The anonymous authentication method can be configured with the following
diff --git a/doc/guide.tex b/doc/guide.tex
index ecd4815c6..044fab829 100644
--- a/doc/guide.tex
+++ b/doc/guide.tex
@@ -1239,6 +1239,10 @@ These are the specific options:
Indicate in this option the full path to the external authentication script.
The script must be executable by ejabberd.
+ \titem{\{extauth\_instances, Integer\}}
+ Indicate how many instances of the script to run simultaneously to serve authentication in the virtual host.
+ The default value is the minimum number: 1.
+
\titem{\{extauth\_cache, false|CacheTimeInteger\}}
The value \term{false} disables the caching feature, this is the default.
The integer \term{0} (zero) enables caching for statistics, but doesn't use that cached information to authenticate users.
@@ -1250,11 +1254,13 @@ These are the specific options:
If caching is enabled, \term{mod\_last} or \term{mod\_last\_odbc} must be enabled also in that vhost.
\end{description}
-This example sets external authentication, the extauth script, and enables caching for 10 minutes:
+This example sets external authentication, the extauth script, enables caching for 10 minutes,
+and starts three instances of the script for each virtual host defined in ejabberd:
\begin{verbatim}
{auth_method, [external]}.
{extauth_program, "/etc/ejabberd/JabberAuth.class.php"}.
{extauth_cache, 600}.
+{extauth_instances, 3}.
\end{verbatim}
\makesubsubsection{saslanonymous}{SASL Anonymous and Anonymous Login}
diff --git a/src/extauth.erl b/src/extauth.erl
index 1cbd33126..3f96c9ab2 100644
--- a/src/extauth.erl
+++ b/src/extauth.erl
@@ -43,16 +43,29 @@
-define(CALL_TIMEOUT, 10000). % Timeout is in milliseconds: 10 seconds == 10000
start(Host, ExtPrg) ->
- spawn(?MODULE, init, [Host, ExtPrg]).
-
-init(Host, ExtPrg) ->
- register(gen_mod:get_module_proc(Host, eauth), self()),
+ lists:foreach(
+ fun(This) ->
+ spawn(?MODULE, init, [get_process_name(Host, This), ExtPrg])
+ end,
+ lists:seq(0, get_instances(Host)-1)
+ ).
+
+init(ProcessName, ExtPrg) ->
+ register(ProcessName, self()),
process_flag(trap_exit,true),
Port = open_port({spawn, ExtPrg}, [{packet,2}]),
loop(Port, ?INIT_TIMEOUT).
stop(Host) ->
- gen_mod:get_module_proc(Host, eauth) ! stop.
+ lists:foreach(
+ fun(This) ->
+ get_process_name(Host, This) ! stop
+ end,
+ lists:seq(0, get_instances(Host)-1)
+ ).
+
+get_process_name(Host, Integer) ->
+ gen_mod:get_module_proc(lists:append([Host, integer_to_list(Integer)]), eauth).
check_password(User, Server, Password) ->
call_port(Server, ["auth", User, Server, Password]).
@@ -77,12 +90,24 @@ remove_user(User, Server, Password) ->
call_port(Server, Msg) ->
LServer = jlib:nameprep(Server),
- gen_mod:get_module_proc(LServer, eauth) ! {call, self(), Msg},
+ ProcessName = get_process_name(LServer, random_instance(get_instances(LServer))),
+ ProcessName ! {call, self(), Msg},
receive
{eauth,Result} ->
Result
end.
+random_instance(MaxNum) ->
+ {A1,A2,A3} = now(),
+ random:seed(A1, A2, A3),
+ random:uniform(MaxNum) - 1.
+
+get_instances(Server) ->
+ case ejabberd_config:get_local_option({extauth_instances, Server}) of
+ Num when is_integer(Num) -> Num;
+ _ -> 1
+ end.
+
loop(Port, Timeout) ->
receive
{call, Caller, Msg} ->