Optionally cache extauth users in mnesia (EJAB-641)
This commit is contained in:
parent
6ac46c6171
commit
9476d8a2c3
|
@ -194,6 +194,9 @@ operation are as follows:
|
||||||
auth:User:Server:Password (check if a username/password pair is correct)
|
auth:User:Server:Password (check if a username/password pair is correct)
|
||||||
</LI><LI CLASS="li-itemize">isuser:User:Server (check if it’s a valid user)
|
</LI><LI CLASS="li-itemize">isuser:User:Server (check if it’s a valid user)
|
||||||
</LI><LI CLASS="li-itemize">setpass:User:Server:Password (set user’s password)
|
</LI><LI CLASS="li-itemize">setpass:User:Server:Password (set user’s password)
|
||||||
|
</LI><LI CLASS="li-itemize">tryregister:User:Server:Password (try to register an account)
|
||||||
|
</LI><LI CLASS="li-itemize">removeuser:User:Server (remove this account)
|
||||||
|
</LI><LI CLASS="li-itemize">removeuser3:User:Server:Password (remove this account if the password is correct)
|
||||||
</LI></UL>
|
</LI></UL>
|
||||||
</LI></UL>
|
</LI></UL>
|
||||||
</LI><LI CLASS="li-itemize">write to stdout: AABB
|
</LI><LI CLASS="li-itemize">write to stdout: AABB
|
||||||
|
|
|
@ -176,6 +176,9 @@ That script is supposed to do theses actions, in an infinite loop:
|
||||||
\item auth:User:Server:Password (check if a username/password pair is correct)
|
\item auth:User:Server:Password (check if a username/password pair is correct)
|
||||||
\item isuser:User:Server (check if it's a valid user)
|
\item isuser:User:Server (check if it's a valid user)
|
||||||
\item setpass:User:Server:Password (set user's password)
|
\item setpass:User:Server:Password (set user's password)
|
||||||
|
\item tryregister:User:Server:Password (try to register an account)
|
||||||
|
\item removeuser:User:Server (remove this account)
|
||||||
|
\item removeuser3:User:Server:Password (remove this account if the password is correct)
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
\item write to stdout: AABB
|
\item write to stdout: AABB
|
||||||
|
|
|
@ -1030,14 +1030,13 @@ for user authentication. The syntax is:
|
||||||
</P><DL CLASS="description"><DT CLASS="dt-description"><B><TT>{auth_method, [Method, ...]}.</TT></B></DT></DL><P>The following authentication methods are supported by <TT>ejabberd</TT>:
|
</P><DL CLASS="description"><DT CLASS="dt-description"><B><TT>{auth_method, [Method, ...]}.</TT></B></DT></DL><P>The following authentication methods are supported by <TT>ejabberd</TT>:
|
||||||
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
|
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||||
internal (default) — See section <A HREF="#internalauth">3.1.4</A>.
|
internal (default) — See section <A HREF="#internalauth">3.1.4</A>.
|
||||||
</LI><LI CLASS="li-itemize">external — There are <A HREF="http://www.ejabberd.im/extauth">some
|
</LI><LI CLASS="li-itemize">external — See section <A HREF="#extauth">3.1.4</A>.
|
||||||
example authentication scripts</A>.
|
|
||||||
</LI><LI CLASS="li-itemize">ldap — See section <A HREF="#ldap">3.2.5</A>.
|
</LI><LI CLASS="li-itemize">ldap — See section <A HREF="#ldap">3.2.5</A>.
|
||||||
</LI><LI CLASS="li-itemize">odbc — See section <A HREF="#mysql">3.2.1</A>, <A HREF="#pgsql">3.2.3</A>,
|
</LI><LI CLASS="li-itemize">odbc — See section <A HREF="#mysql">3.2.1</A>, <A HREF="#pgsql">3.2.3</A>,
|
||||||
<A HREF="#mssql">3.2.2</A> and <A HREF="#odbc">3.2.4</A>.
|
<A HREF="#mssql">3.2.2</A> and <A HREF="#odbc">3.2.4</A>.
|
||||||
</LI><LI CLASS="li-itemize">anonymous — See section <A HREF="#saslanonymous">3.1.4</A>.
|
</LI><LI CLASS="li-itemize">anonymous — See section <A HREF="#saslanonymous">3.1.4</A>.
|
||||||
</LI><LI CLASS="li-itemize">pam — See section <A HREF="#pam">3.1.4</A>.
|
</LI><LI CLASS="li-itemize">pam — See section <A HREF="#pam">3.1.4</A>.
|
||||||
</LI></UL><P>Account creation is only supported by internal and odbc methods.</P><P> <A NAME="internalauth"></A> </P><!--TOC subsubsection Internal-->
|
</LI></UL><P>Account creation is only supported by internal, external and odbc methods.</P><P> <A NAME="internalauth"></A> </P><!--TOC subsubsection Internal-->
|
||||||
<H4 CLASS="subsubsection"><!--SEC ANCHOR --><A HREF="#internalauth">Internal</A></H4><!--SEC END --><P> <A NAME="internalauth"></A>
|
<H4 CLASS="subsubsection"><!--SEC ANCHOR --><A HREF="#internalauth">Internal</A></H4><!--SEC END --><P> <A NAME="internalauth"></A>
|
||||||
</P><P><TT>ejabberd</TT> uses its internal Mnesia database as the default authentication method.
|
</P><P><TT>ejabberd</TT> uses its internal Mnesia database as the default authentication method.
|
||||||
The value <TT>internal</TT> will enable the internal authentication method.</P><P>Examples:
|
The value <TT>internal</TT> will enable the internal authentication method.</P><P>Examples:
|
||||||
|
@ -1048,7 +1047,31 @@ authentication on <TT>example.net</TT>:
|
||||||
{host_config, "example.net", [{auth_method, [ldap]}]}.
|
{host_config, "example.net", [{auth_method, [ldap]}]}.
|
||||||
</PRE></LI><LI CLASS="li-itemize">To use internal authentication on all virtual hosts:
|
</PRE></LI><LI CLASS="li-itemize">To use internal authentication on all virtual hosts:
|
||||||
<PRE CLASS="verbatim">{auth_method, internal}.
|
<PRE CLASS="verbatim">{auth_method, internal}.
|
||||||
</PRE></LI></UL><P> <A NAME="saslanonymous"></A> </P><!--TOC subsubsection SASL Anonymous and Anonymous Login-->
|
</PRE></LI></UL><P> <A NAME="extauth"></A> </P><!--TOC subsubsection External Script-->
|
||||||
|
<H4 CLASS="subsubsection"><!--SEC ANCHOR --><A HREF="#extauth">External Script</A></H4><!--SEC END --><P> <A NAME="extauth"></A>
|
||||||
|
</P><P>In this authentication method, when <TT>ejabberd</TT> starts,
|
||||||
|
it start a script, and calls it to perform authentication tasks.</P><P>The server administrator can write the external authentication script
|
||||||
|
in any language.
|
||||||
|
The details on the interface between ejabberd and the script are described
|
||||||
|
in the <TT>ejabberd Developers Guide</TT>.
|
||||||
|
There are also <A HREF="http://www.ejabberd.im/extauth">several example authentication scripts</A>.</P><P>These are the specific options:
|
||||||
|
</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 value <TT>false</TT> disables the caching feature, this is the default.
|
||||||
|
The integer <TT>0</TT> (zero) enables caching for statistics, but doesn’t use that cached information to authenticate users.
|
||||||
|
If another integer value is set, caching is enabled both for statistics and for authentication:
|
||||||
|
the CacheTimeInteger indicates the number of seconds that ejabberd can reuse
|
||||||
|
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:
|
||||||
|
</P><PRE CLASS="verbatim">{auth_method, [external]}.
|
||||||
|
{extauth_program, "/etc/ejabberd/JabberAuth.class.php"}.
|
||||||
|
{extauth_cache, 600}.
|
||||||
|
</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>
|
<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
|
</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
|
||||||
options. Remember that you can use the <TT>host_config</TT> option to set virtual
|
options. Remember that you can use the <TT>host_config</TT> option to set virtual
|
||||||
|
|
|
@ -1187,8 +1187,7 @@ for user authentication. The syntax is:
|
||||||
The following authentication methods are supported by \ejabberd{}:
|
The following authentication methods are supported by \ejabberd{}:
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item internal (default) --- See section~\ref{internalauth}.
|
\item internal (default) --- See section~\ref{internalauth}.
|
||||||
\item external --- There are \footahref{http://www.ejabberd.im/extauth}{some
|
\item external --- See section~\ref{extauth}.
|
||||||
example authentication scripts}.
|
|
||||||
\item ldap --- See section~\ref{ldap}.
|
\item ldap --- See section~\ref{ldap}.
|
||||||
\item odbc --- See section~\ref{mysql}, \ref{pgsql},
|
\item odbc --- See section~\ref{mysql}, \ref{pgsql},
|
||||||
\ref{mssql} and \ref{odbc}.
|
\ref{mssql} and \ref{odbc}.
|
||||||
|
@ -1196,7 +1195,7 @@ The following authentication methods are supported by \ejabberd{}:
|
||||||
\item pam --- See section~\ref{pam}.
|
\item pam --- See section~\ref{pam}.
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
Account creation is only supported by internal and odbc methods.
|
Account creation is only supported by internal, external and odbc methods.
|
||||||
|
|
||||||
\makesubsubsection{internalauth}{Internal}
|
\makesubsubsection{internalauth}{Internal}
|
||||||
\ind{internal authentication}\ind{Mnesia}
|
\ind{internal authentication}\ind{Mnesia}
|
||||||
|
@ -1218,6 +1217,42 @@ Examples:
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
|
\makesubsubsection{extauth}{External Script}
|
||||||
|
\ind{external authentication}
|
||||||
|
|
||||||
|
In this authentication method, when \ejabberd{} starts,
|
||||||
|
it start a script, and calls it to perform authentication tasks.
|
||||||
|
|
||||||
|
The server administrator can write the external authentication script
|
||||||
|
in any language.
|
||||||
|
The details on the interface between ejabberd and the script are described
|
||||||
|
in the \term{ejabberd Developers Guide}.
|
||||||
|
There are also \footahref{http://www.ejabberd.im/extauth}{several example authentication scripts}.
|
||||||
|
|
||||||
|
These are the specific options:
|
||||||
|
\begin{description}
|
||||||
|
\titem{\{extauth\_program, PathToScript\}}
|
||||||
|
Indicate in this option the full path to the external authentication script.
|
||||||
|
The script must be executable by ejabberd.
|
||||||
|
|
||||||
|
\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.
|
||||||
|
If another integer value is set, caching is enabled both for statistics and for authentication:
|
||||||
|
the CacheTimeInteger indicates the number of seconds that ejabberd can reuse
|
||||||
|
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, \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:
|
||||||
|
\begin{verbatim}
|
||||||
|
{auth_method, [external]}.
|
||||||
|
{extauth_program, "/etc/ejabberd/JabberAuth.class.php"}.
|
||||||
|
{extauth_cache, 600}.
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
\makesubsubsection{saslanonymous}{SASL Anonymous and Anonymous Login}
|
\makesubsubsection{saslanonymous}{SASL Anonymous and Anonymous Login}
|
||||||
\ind{sasl anonymous}\ind{anonymous login}
|
\ind{sasl anonymous}\ind{anonymous login}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,9 @@
|
||||||
try_register/3,
|
try_register/3,
|
||||||
dirty_get_registered_users/0,
|
dirty_get_registered_users/0,
|
||||||
get_vh_registered_users/1,
|
get_vh_registered_users/1,
|
||||||
|
get_vh_registered_users/2,
|
||||||
|
get_vh_registered_users_number/1,
|
||||||
|
get_vh_registered_users_number/2,
|
||||||
get_password/2,
|
get_password/2,
|
||||||
get_password_s/2,
|
get_password_s/2,
|
||||||
is_user_exists/2,
|
is_user_exists/2,
|
||||||
|
@ -43,45 +46,87 @@
|
||||||
plain_password_required/0
|
plain_password_required/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
|
-include("ejabberd.hrl").
|
||||||
|
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% API
|
%%% API
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
start(Host) ->
|
start(Host) ->
|
||||||
extauth:start(
|
extauth:start(
|
||||||
Host, ejabberd_config:get_local_option({extauth_program, Host})),
|
Host, ejabberd_config:get_local_option({extauth_program, Host})),
|
||||||
ok.
|
case check_cache_last_options(Host) of
|
||||||
|
cache ->
|
||||||
|
ok = ejabberd_auth_internal:start(Host);
|
||||||
|
no_cache ->
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
|
check_cache_last_options(Server) ->
|
||||||
|
%% if extauth_cache is enabled, then a mod_last module must also be enabled
|
||||||
|
case get_cache_option(Server) of
|
||||||
|
false -> no_cache;
|
||||||
|
{true, _CacheTime} ->
|
||||||
|
case get_mod_last_enabled(Server) of
|
||||||
|
no_mod_last ->
|
||||||
|
?ERROR_MSG("In host ~p extauth is used, extauth_cache is enabled but "
|
||||||
|
"mod_last is not enabled.", [Server]),
|
||||||
|
no_cache;
|
||||||
|
_ -> cache
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
plain_password_required() ->
|
plain_password_required() ->
|
||||||
true.
|
true.
|
||||||
|
|
||||||
check_password(User, Server, Password) ->
|
check_password(User, Server, Password) ->
|
||||||
extauth:check_password(User, Server, Password) andalso Password /= "".
|
case get_cache_option(Server) of
|
||||||
|
false -> check_password_extauth(User, Server, Password);
|
||||||
|
{true, CacheTime} -> check_password_cache(User, Server, Password, CacheTime)
|
||||||
|
end.
|
||||||
|
|
||||||
check_password(User, Server, Password, _Digest, _DigestGen) ->
|
check_password(User, Server, Password, _Digest, _DigestGen) ->
|
||||||
check_password(User, Server, Password).
|
check_password(User, Server, Password).
|
||||||
|
|
||||||
set_password(User, Server, Password) ->
|
set_password(User, Server, Password) ->
|
||||||
case extauth:set_password(User, Server, Password) of
|
case extauth:set_password(User, Server, Password) of
|
||||||
true -> ok;
|
true -> set_password_internal(User, Server, Password),
|
||||||
|
ok;
|
||||||
_ -> {error, unknown_problem}
|
_ -> {error, unknown_problem}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
try_register(_User, _Server, _Password) ->
|
try_register(User, Server, Password) ->
|
||||||
{error, not_allowed}.
|
case get_cache_option(Server) of
|
||||||
|
false -> try_register_extauth(User, Server, Password);
|
||||||
|
{true, _CacheTime} -> try_register_external_cache(User, Server, Password)
|
||||||
|
end.
|
||||||
|
|
||||||
%% TODO
|
|
||||||
%% Return the list of all users handled by external
|
|
||||||
dirty_get_registered_users() ->
|
dirty_get_registered_users() ->
|
||||||
[].
|
ejabberd_auth_internal:dirty_get_registered_users().
|
||||||
|
|
||||||
get_vh_registered_users(_Server) ->
|
get_vh_registered_users(Server) ->
|
||||||
[].
|
ejabberd_auth_internal:get_vh_registered_users(Server).
|
||||||
|
|
||||||
get_password(_User, _Server) ->
|
get_vh_registered_users(Server, Data) ->
|
||||||
false.
|
ejabberd_auth_internal:get_vh_registered_users(Server, Data).
|
||||||
|
|
||||||
get_password_s(_User, _Server) ->
|
get_vh_registered_users_number(Server) ->
|
||||||
"".
|
ejabberd_auth_internal:get_vh_registered_users_number(Server).
|
||||||
|
|
||||||
|
get_vh_registered_users_number(Server, Data) ->
|
||||||
|
ejabberd_auth_internal:get_vh_registered_users_number(Server, Data).
|
||||||
|
|
||||||
|
%% The password can only be returned if cache is enabled, cached info exists and is fresh enough.
|
||||||
|
get_password(User, Server) ->
|
||||||
|
case get_cache_option(Server) of
|
||||||
|
false -> false;
|
||||||
|
{true, CacheTime} -> get_password_cache(User, Server, CacheTime)
|
||||||
|
end.
|
||||||
|
|
||||||
|
get_password_s(User, Server) ->
|
||||||
|
case get_password(User, Server) of
|
||||||
|
false -> [];
|
||||||
|
Other -> Other
|
||||||
|
end.
|
||||||
|
|
||||||
%% @spec (User, Server) -> true | false | {error, Error}
|
%% @spec (User, Server) -> true | false | {error, Error}
|
||||||
is_user_exists(User, Server) ->
|
is_user_exists(User, Server) ->
|
||||||
|
@ -91,9 +136,169 @@ is_user_exists(User, Server) ->
|
||||||
_:Error -> {error, Error}
|
_:Error -> {error, Error}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
remove_user(_User, _Server) ->
|
remove_user(User, Server) ->
|
||||||
{error, not_allowed}.
|
case extauth:remove_user(User, Server) of
|
||||||
|
false -> false;
|
||||||
|
true ->
|
||||||
|
case get_cache_option(Server) of
|
||||||
|
false -> false;
|
||||||
|
{true, _CacheTime} ->
|
||||||
|
ejabberd_auth_internal:remove_user(User, Server)
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
remove_user(_User, _Server, _Password) ->
|
remove_user(User, Server, Password) ->
|
||||||
not_allowed.
|
case extauth:remove_user(User, Server, Password) of
|
||||||
|
false -> false;
|
||||||
|
true ->
|
||||||
|
case get_cache_option(Server) of
|
||||||
|
false -> false;
|
||||||
|
{true, _CacheTime} ->
|
||||||
|
ejabberd_auth_internal:remove_user(User, Server, Password)
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
|
%%%
|
||||||
|
%%% Extauth cache management
|
||||||
|
%%%
|
||||||
|
|
||||||
|
%% @spec (Host::string()) -> false | {true, CacheTime::integer()}
|
||||||
|
get_cache_option(Host) ->
|
||||||
|
case ejabberd_config:get_local_option({extauth_cache, Host}) of
|
||||||
|
CacheTime when is_integer(CacheTime) -> {true, CacheTime};
|
||||||
|
_ -> false
|
||||||
|
end.
|
||||||
|
|
||||||
|
%% @spec (User, Server, Password) -> true | false
|
||||||
|
check_password_extauth(User, Server, Password) ->
|
||||||
|
extauth:check_password(User, Server, Password) andalso Password /= "".
|
||||||
|
|
||||||
|
%% @spec (User, Server, Password) -> true | false
|
||||||
|
try_register_extauth(User, Server, Password) ->
|
||||||
|
extauth:try_register(User, Server, Password).
|
||||||
|
|
||||||
|
check_password_cache(User, Server, Password, CacheTime) ->
|
||||||
|
case get_last_access(User, Server) of
|
||||||
|
online ->
|
||||||
|
check_password_internal(User, Server, Password);
|
||||||
|
never ->
|
||||||
|
check_password_external_cache(User, Server, Password);
|
||||||
|
mod_last_required ->
|
||||||
|
?ERROR_MSG("extauth is used, extauth_cache is enabled but mod_last is not enabled in that host", []),
|
||||||
|
check_password_external_cache(User, Server, Password);
|
||||||
|
TimeStamp ->
|
||||||
|
%% If last access exists, compare last access with cache refresh time
|
||||||
|
case is_fresh_enough(TimeStamp, CacheTime) of
|
||||||
|
%% If no need to refresh, check password against Mnesia
|
||||||
|
true ->
|
||||||
|
case check_password_internal(User, Server, Password) of
|
||||||
|
%% If password valid in Mnesia, accept it
|
||||||
|
true ->
|
||||||
|
true;
|
||||||
|
%% Else (password nonvalid in Mnesia), check in extauth and cache result
|
||||||
|
false ->
|
||||||
|
check_password_external_cache(User, Server, Password)
|
||||||
|
end;
|
||||||
|
%% Else (need to refresh), check in extauth and cache result
|
||||||
|
false ->
|
||||||
|
check_password_external_cache(User, Server, Password)
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
|
get_password_internal(User, Server) ->
|
||||||
|
ejabberd_auth_internal:get_password(User, Server).
|
||||||
|
|
||||||
|
%% @spec (User, Server, CacheTime) -> false | Password::string()
|
||||||
|
get_password_cache(User, Server, CacheTime) ->
|
||||||
|
case get_last_access(User, Server) of
|
||||||
|
online ->
|
||||||
|
get_password_internal(User, Server);
|
||||||
|
never ->
|
||||||
|
false;
|
||||||
|
mod_last_required ->
|
||||||
|
?ERROR_MSG("extauth is used, extauth_cache is enabled but mod_last is not enabled in that host", []),
|
||||||
|
false;
|
||||||
|
TimeStamp ->
|
||||||
|
case is_fresh_enough(TimeStamp, CacheTime) of
|
||||||
|
true ->
|
||||||
|
get_password_internal(User, Server);
|
||||||
|
false ->
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
%% Check the password using extauth; if success then cache it
|
||||||
|
check_password_external_cache(User, Server, Password) ->
|
||||||
|
case check_password_extauth(User, Server, Password) of
|
||||||
|
true ->
|
||||||
|
set_password_internal(User, Server, Password), true;
|
||||||
|
false ->
|
||||||
|
false
|
||||||
|
end.
|
||||||
|
|
||||||
|
%% Try to register using extauth; if success then cache it
|
||||||
|
try_register_external_cache(User, Server, Password) ->
|
||||||
|
case try_register_extauth(User, Server, Password) of
|
||||||
|
{atomic, ok} = R ->
|
||||||
|
set_password_internal(User, Server, Password),
|
||||||
|
R;
|
||||||
|
_ -> {error, not_allowed}
|
||||||
|
end.
|
||||||
|
|
||||||
|
%% @spec (User, Server, Password) -> true | false
|
||||||
|
check_password_internal(User, Server, Password) ->
|
||||||
|
ejabberd_auth_internal:check_password(User, Server, Password).
|
||||||
|
|
||||||
|
%% @spec (User, Server, Password) -> ok | {error, invalid_jid}
|
||||||
|
set_password_internal(User, Server, Password) ->
|
||||||
|
ejabberd_auth_internal:set_password(User, Server, Password).
|
||||||
|
|
||||||
|
%% @spec (TimeLast, CacheTime) -> true | false
|
||||||
|
%% TimeLast = online | never | integer()
|
||||||
|
%% CacheTime = integer() | false
|
||||||
|
is_fresh_enough(online, _CacheTime) ->
|
||||||
|
true;
|
||||||
|
is_fresh_enough(never, _CacheTime) ->
|
||||||
|
false;
|
||||||
|
is_fresh_enough(TimeStampLast, CacheTime) ->
|
||||||
|
{MegaSecs, Secs, _MicroSecs} = now(),
|
||||||
|
Now = MegaSecs * 1000000 + Secs,
|
||||||
|
(TimeStampLast + CacheTime > Now).
|
||||||
|
|
||||||
|
%% @spec (User, Server) -> online | never | mod_last_required | TimeStamp::integer()
|
||||||
|
%% Code copied from mod_configure.erl
|
||||||
|
%% Code copied from web/ejabberd_web_admin.erl
|
||||||
|
%% TODO: Update time format to XEP-0202: Entity Time
|
||||||
|
get_last_access(User, Server) ->
|
||||||
|
case ejabberd_sm:get_user_resources(User, Server) of
|
||||||
|
[] ->
|
||||||
|
_US = {User, Server},
|
||||||
|
case get_last_info(User, Server) of
|
||||||
|
mod_last_required ->
|
||||||
|
mod_last_required;
|
||||||
|
not_found ->
|
||||||
|
never;
|
||||||
|
{ok, Timestamp, _Status} ->
|
||||||
|
Timestamp
|
||||||
|
end;
|
||||||
|
_ ->
|
||||||
|
online
|
||||||
|
end.
|
||||||
|
%% @spec (User, Server) -> {ok, Timestamp, Status} | not_found | mod_last_required
|
||||||
|
get_last_info(User, Server) ->
|
||||||
|
case get_mod_last_enabled(Server) of
|
||||||
|
mod_last -> mod_last:get_last_info(User, Server);
|
||||||
|
mod_last_odbc -> mod_last_odbc:get_last_info(User, Server);
|
||||||
|
mod_mod_last -> mod_last_required
|
||||||
|
end.
|
||||||
|
|
||||||
|
%% @spec (Server) -> mod_last | mod_last_odbc | no_mod_last
|
||||||
|
get_mod_last_enabled(Server) ->
|
||||||
|
ML = lists:member(mod_last, gen_mod:loaded_modules(Server)),
|
||||||
|
MLO = lists:member(mod_last_odbc, gen_mod:loaded_modules(Server)),
|
||||||
|
case {ML, MLO} of
|
||||||
|
{true, _} -> mod_last;
|
||||||
|
{false, true} -> mod_last_odbc;
|
||||||
|
{false, false} -> no_mod_last
|
||||||
|
end.
|
||||||
|
|
|
@ -27,8 +27,15 @@
|
||||||
-module(extauth).
|
-module(extauth).
|
||||||
-author('leifj@it.su.se').
|
-author('leifj@it.su.se').
|
||||||
|
|
||||||
-export([start/2, stop/1, init/2,
|
-export([start/2,
|
||||||
check_password/3, set_password/3, is_user_exists/2]).
|
stop/1,
|
||||||
|
init/2,
|
||||||
|
check_password/3,
|
||||||
|
set_password/3,
|
||||||
|
try_register/3,
|
||||||
|
remove_user/2,
|
||||||
|
remove_user/3,
|
||||||
|
is_user_exists/2]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
|
|
||||||
|
@ -56,6 +63,18 @@ is_user_exists(User, Server) ->
|
||||||
set_password(User, Server, Password) ->
|
set_password(User, Server, Password) ->
|
||||||
call_port(Server, ["setpass", User, Server, Password]).
|
call_port(Server, ["setpass", User, Server, Password]).
|
||||||
|
|
||||||
|
try_register(User, Server, Password) ->
|
||||||
|
case call_port(Server, ["tryregister", User, Server, Password]) of
|
||||||
|
true -> {atomic, ok};
|
||||||
|
false -> {error, not_allowed}
|
||||||
|
end.
|
||||||
|
|
||||||
|
remove_user(User, Server) ->
|
||||||
|
call_port(Server, ["removeuser", User, Server]).
|
||||||
|
|
||||||
|
remove_user(User, Server, Password) ->
|
||||||
|
call_port(Server, ["removeuser3", User, Server, Password]).
|
||||||
|
|
||||||
call_port(Server, Msg) ->
|
call_port(Server, Msg) ->
|
||||||
LServer = jlib:nameprep(Server),
|
LServer = jlib:nameprep(Server),
|
||||||
gen_mod:get_module_proc(LServer, eauth) ! {call, self(), Msg},
|
gen_mod:get_module_proc(LServer, eauth) ! {call, self(), Msg},
|
||||||
|
|
Loading…
Reference in New Issue