* src/ejabberd_sm.erl: Added unset_presence_hook
* src/mod_last.erl: Use unset_presence_hook instead of direct call * src/ejabberd_auth.erl: Splitted into ejabberd_auth_internal.erl, ejabberd_auth_ldap.erl, and ejabberd_auth_external.erl, * src/ejabberd_auth_internal.erl: Likewise * src/ejabberd_auth_ldap.erl: Likewise * src/ejabberd_auth_external.erl: Likewise SVN Revision: 290
This commit is contained in:
parent
da58d568b1
commit
591bc42669
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
||||||
|
2004-12-12 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
|
* src/ejabberd_sm.erl: Added unset_presence_hook
|
||||||
|
* src/mod_last.erl: Use unset_presence_hook instead of direct call
|
||||||
|
|
||||||
|
* src/ejabberd_auth.erl: Splitted into ejabberd_auth_internal.erl,
|
||||||
|
ejabberd_auth_ldap.erl, and ejabberd_auth_external.erl,
|
||||||
|
* src/ejabberd_auth_internal.erl: Likewise
|
||||||
|
* src/ejabberd_auth_ldap.erl: Likewise
|
||||||
|
* src/ejabberd_auth_external.erl: Likewise
|
||||||
|
|
||||||
2004-12-05 Alexey Shchepin <alexey@sevcom.net>
|
2004-12-05 Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
|
||||||
* src/web/ejabberd_web_admin.erl: Changed type of password field
|
* src/web/ejabberd_web_admin.erl: Changed type of password field
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% File : ejabberd_auth.erl
|
%%% File : ejabberd_auth.erl
|
||||||
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||||
%%% Purpose :
|
%%% Purpose : Authentification
|
||||||
%%% Created : 23 Nov 2002 by Alexey Shchepin <alexey@sevcom.net>
|
%%% Created : 23 Nov 2002 by Alexey Shchepin <alexey@sevcom.net>
|
||||||
%%% Id : $Id$
|
%%% Id : $Id$
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
|
@ -10,10 +10,8 @@
|
||||||
-author('alexey@sevcom.net').
|
-author('alexey@sevcom.net').
|
||||||
-vsn('$Revision$ ').
|
-vsn('$Revision$ ').
|
||||||
|
|
||||||
-behaviour(gen_server).
|
|
||||||
|
|
||||||
%% External exports
|
%% External exports
|
||||||
-export([start/0, start_link/0,
|
-export([start/0,
|
||||||
set_password/2,
|
set_password/2,
|
||||||
check_password/2,
|
check_password/2,
|
||||||
check_password/4,
|
check_password/4,
|
||||||
|
@ -24,387 +22,59 @@
|
||||||
is_user_exists/1,
|
is_user_exists/1,
|
||||||
remove_user/1,
|
remove_user/1,
|
||||||
remove_user/2,
|
remove_user/2,
|
||||||
plain_password_required/0,
|
plain_password_required/0
|
||||||
check_password_ldap/2, % TODO: remove
|
|
||||||
is_user_exists_ldap/1 % TODO: remove
|
|
||||||
]).
|
]).
|
||||||
|
|
||||||
%% gen_server callbacks
|
|
||||||
-export([init/1,
|
|
||||||
handle_call/3,
|
|
||||||
handle_cast/2,
|
|
||||||
code_change/3,
|
|
||||||
handle_info/2,
|
|
||||||
terminate/2]).
|
|
||||||
|
|
||||||
-include("eldap/eldap.hrl").
|
|
||||||
|
|
||||||
-record(state, {}).
|
|
||||||
|
|
||||||
-record(passwd, {user, password}).
|
|
||||||
|
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% API
|
%%% API
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
start() ->
|
start() ->
|
||||||
case auth_method() of
|
(auth_module()):start().
|
||||||
external ->
|
|
||||||
extauth:start(ejabberd_config:get_local_option(extauth_program));
|
|
||||||
_ ->
|
|
||||||
ok
|
|
||||||
end,
|
|
||||||
gen_server:start({local, ejabberd_auth}, ejabberd_auth, [], []).
|
|
||||||
|
|
||||||
start_link() ->
|
plain_password_required() ->
|
||||||
gen_server:start_link({local, ejabberd_auth}, ejabberd_auth, [], []).
|
(auth_module()):plain_password_required().
|
||||||
|
|
||||||
%%%----------------------------------------------------------------------
|
check_password(User, Password) ->
|
||||||
%%% Callback functions from gen_server
|
(auth_module()):check_password(User, Password).
|
||||||
%%%----------------------------------------------------------------------
|
|
||||||
|
|
||||||
%%----------------------------------------------------------------------
|
check_password(User, Password, StreamID, Digest) ->
|
||||||
%% Func: init/1
|
(auth_module()):check_password(User, Password, StreamID, Digest).
|
||||||
%% Returns: {ok, State} |
|
|
||||||
%% {ok, State, Timeout} |
|
|
||||||
%% ignore |
|
|
||||||
%% {stop, Reason}
|
|
||||||
%%----------------------------------------------------------------------
|
|
||||||
init([]) ->
|
|
||||||
mnesia:create_table(passwd,[{disc_copies, [node()]},
|
|
||||||
{attributes, record_info(fields, passwd)}]),
|
|
||||||
case auth_method() of
|
|
||||||
internal ->
|
|
||||||
ok;
|
|
||||||
external ->
|
|
||||||
ok;
|
|
||||||
ldap ->
|
|
||||||
LDAPServers = ejabberd_config:get_local_option(ldap_servers),
|
|
||||||
RootDN = ejabberd_config:get_local_option(ldap_rootdn),
|
|
||||||
Password = ejabberd_config:get_local_option(ldap_password),
|
|
||||||
eldap:start_link("ejabberd", LDAPServers, 389, RootDN, Password),
|
|
||||||
eldap:start_link("ejabberd_bind", LDAPServers, 389, RootDN, Password)
|
|
||||||
end,
|
|
||||||
{ok, #state{}}.
|
|
||||||
|
|
||||||
%%----------------------------------------------------------------------
|
set_password(User, Password) ->
|
||||||
%% Func: handle_call/3
|
(auth_module()):set_password(User, Password).
|
||||||
%% Returns: {reply, Reply, State} |
|
|
||||||
%% {reply, Reply, State, Timeout} |
|
|
||||||
%% {noreply, State} |
|
|
||||||
%% {noreply, State, Timeout} |
|
|
||||||
%% {stop, Reason, Reply, State} | (terminate/2 is called)
|
|
||||||
%% {stop, Reason, State} (terminate/2 is called)
|
|
||||||
%%----------------------------------------------------------------------
|
|
||||||
handle_call(_Request, _From, State) ->
|
|
||||||
Reply = ok,
|
|
||||||
{reply, Reply, State}.
|
|
||||||
|
|
||||||
%%----------------------------------------------------------------------
|
try_register(User, Password) ->
|
||||||
%% Func: handle_cast/2
|
(auth_module()):try_register(User, Password).
|
||||||
%% Returns: {noreply, State} |
|
|
||||||
%% {noreply, State, Timeout} |
|
|
||||||
%% {stop, Reason, State} (terminate/2 is called)
|
|
||||||
%%----------------------------------------------------------------------
|
|
||||||
handle_cast(_Msg, State) ->
|
|
||||||
{noreply, State}.
|
|
||||||
|
|
||||||
|
dirty_get_registered_users() ->
|
||||||
|
(auth_module()):dirty_get_registered_users().
|
||||||
|
|
||||||
code_change(_OldVsn, State, _Extra) ->
|
get_password(User) ->
|
||||||
{ok, State}.
|
(auth_module()):get_password(User).
|
||||||
|
|
||||||
%%----------------------------------------------------------------------
|
get_password_s(User) ->
|
||||||
%% Func: handle_info/2
|
(auth_module()):get_password_s(User).
|
||||||
%% Returns: {noreply, State} |
|
|
||||||
%% {noreply, State, Timeout} |
|
|
||||||
%% {stop, Reason, State} (terminate/2 is called)
|
|
||||||
%%----------------------------------------------------------------------
|
|
||||||
handle_info(_Info, State) ->
|
|
||||||
{noreply, State}.
|
|
||||||
|
|
||||||
%%----------------------------------------------------------------------
|
is_user_exists(User) ->
|
||||||
%% Func: terminate/2
|
(auth_module()):is_user_exists(User).
|
||||||
%% Purpose: Shutdown the server
|
|
||||||
%% Returns: any (ignored by gen_server)
|
remove_user(User) ->
|
||||||
%%----------------------------------------------------------------------
|
(auth_module()):remove_user(User).
|
||||||
terminate(_Reason, _State) ->
|
|
||||||
ok.
|
remove_user(User, Password) ->
|
||||||
|
(auth_module()):remove_user(User, Password).
|
||||||
|
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
%%% Internal functions
|
%%% Internal functions
|
||||||
%%%----------------------------------------------------------------------
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
auth_method() ->
|
auth_module() ->
|
||||||
case ejabberd_config:get_local_option(auth_method) of
|
case ejabberd_config:get_local_option(auth_method) of
|
||||||
external ->
|
external ->
|
||||||
external;
|
ejabberd_auth_external;
|
||||||
ldap ->
|
ldap ->
|
||||||
ldap;
|
ejabberd_auth_ldap;
|
||||||
_ ->
|
_ ->
|
||||||
internal
|
ejabberd_auth_internal
|
||||||
end.
|
end.
|
||||||
|
|
||||||
user_method() ->
|
|
||||||
case ejabberd_config:get_local_option(user_method) of
|
|
||||||
ldap ->
|
|
||||||
ldap;
|
|
||||||
_ ->
|
|
||||||
internal
|
|
||||||
end.
|
|
||||||
|
|
||||||
plain_password_required() ->
|
|
||||||
case auth_method() of
|
|
||||||
internal ->
|
|
||||||
false;
|
|
||||||
external ->
|
|
||||||
true;
|
|
||||||
ldap ->
|
|
||||||
true
|
|
||||||
end.
|
|
||||||
|
|
||||||
check_password(User, Password) ->
|
|
||||||
case auth_method() of
|
|
||||||
internal ->
|
|
||||||
check_password_internal(User, Password);
|
|
||||||
external ->
|
|
||||||
check_password_external(User, Password);
|
|
||||||
ldap ->
|
|
||||||
check_password_ldap(User, Password)
|
|
||||||
end.
|
|
||||||
|
|
||||||
check_password_external(User, Password) ->
|
|
||||||
extauth:check_password(User, Password).
|
|
||||||
|
|
||||||
set_password_external(User, Password) ->
|
|
||||||
extauth:set_password(User, Password).
|
|
||||||
|
|
||||||
is_user_exists_external(User) ->
|
|
||||||
extauth:is_user_exists(User).
|
|
||||||
|
|
||||||
check_password_internal(User, Password) ->
|
|
||||||
LUser = jlib:nodeprep(User),
|
|
||||||
case catch mnesia:dirty_read({passwd, LUser}) of
|
|
||||||
[#passwd{password = Password}] ->
|
|
||||||
true;
|
|
||||||
_ ->
|
|
||||||
false
|
|
||||||
end.
|
|
||||||
|
|
||||||
check_password(User, Password, StreamID, Digest) ->
|
|
||||||
case auth_method() of
|
|
||||||
internal ->
|
|
||||||
check_password_internal(User, Password, StreamID, Digest);
|
|
||||||
external ->
|
|
||||||
check_password_external(User, Password, StreamID, Digest);
|
|
||||||
ldap ->
|
|
||||||
check_password_ldap(User, Password, StreamID, Digest)
|
|
||||||
end.
|
|
||||||
|
|
||||||
check_password_internal(User, Password, StreamID, Digest) ->
|
|
||||||
LUser = jlib:nodeprep(User),
|
|
||||||
case catch mnesia:dirty_read({passwd, LUser}) of
|
|
||||||
[#passwd{password = Passwd}] ->
|
|
||||||
DigRes = if
|
|
||||||
Digest /= "" ->
|
|
||||||
Digest == sha:sha(StreamID ++ Passwd);
|
|
||||||
true ->
|
|
||||||
false
|
|
||||||
end,
|
|
||||||
if DigRes ->
|
|
||||||
true;
|
|
||||||
true ->
|
|
||||||
(Passwd == Password) and (Password /= "")
|
|
||||||
end;
|
|
||||||
_ ->
|
|
||||||
false
|
|
||||||
end.
|
|
||||||
|
|
||||||
set_password(User, Password) ->
|
|
||||||
case auth_method() of
|
|
||||||
internal ->
|
|
||||||
set_password_internal(User,Password);
|
|
||||||
external ->
|
|
||||||
set_password_external(User,Password);
|
|
||||||
ldap -> {error, not_allowed}
|
|
||||||
end.
|
|
||||||
|
|
||||||
set_password_internal(User, Password) ->
|
|
||||||
case jlib:nodeprep(User) of
|
|
||||||
error -> {error, invalid_jid};
|
|
||||||
LUser ->
|
|
||||||
F = fun() ->
|
|
||||||
mnesia:write(#passwd{user = LUser,
|
|
||||||
password = Password})
|
|
||||||
end,
|
|
||||||
mnesia:transaction(F)
|
|
||||||
end.
|
|
||||||
|
|
||||||
|
|
||||||
try_register(User, Password) ->
|
|
||||||
case auth_method() of
|
|
||||||
internal ->
|
|
||||||
try_register_internal(User, Password);
|
|
||||||
external ->
|
|
||||||
{error, not_allowed};
|
|
||||||
ldap ->
|
|
||||||
{error, not_allowed}
|
|
||||||
end.
|
|
||||||
|
|
||||||
try_register_internal(User, Password) ->
|
|
||||||
case jlib:nodeprep(User) of
|
|
||||||
error -> {error, invalid_jid};
|
|
||||||
LUser ->
|
|
||||||
F = fun() ->
|
|
||||||
case mnesia:read({passwd, LUser}) of
|
|
||||||
[] ->
|
|
||||||
mnesia:write(#passwd{user = LUser,
|
|
||||||
password = Password}),
|
|
||||||
ok;
|
|
||||||
[_E] ->
|
|
||||||
exists
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
mnesia:transaction(F)
|
|
||||||
end.
|
|
||||||
|
|
||||||
dirty_get_registered_users() ->
|
|
||||||
mnesia:dirty_all_keys(passwd).
|
|
||||||
|
|
||||||
get_password(User) ->
|
|
||||||
LUser = jlib:nodeprep(User),
|
|
||||||
case catch mnesia:dirty_read(passwd, LUser) of
|
|
||||||
[#passwd{password = Password}] ->
|
|
||||||
Password;
|
|
||||||
_ ->
|
|
||||||
false
|
|
||||||
end.
|
|
||||||
|
|
||||||
get_password_s(User) ->
|
|
||||||
LUser = jlib:nodeprep(User),
|
|
||||||
case catch mnesia:dirty_read(passwd, LUser) of
|
|
||||||
[#passwd{password = Password}] ->
|
|
||||||
Password;
|
|
||||||
_ ->
|
|
||||||
[]
|
|
||||||
end.
|
|
||||||
|
|
||||||
is_user_exists(User) ->
|
|
||||||
case auth_method() of
|
|
||||||
internal ->
|
|
||||||
is_user_exists_internal(User);
|
|
||||||
external ->
|
|
||||||
is_user_exists_external(User);
|
|
||||||
ldap ->
|
|
||||||
is_user_exists_ldap(User)
|
|
||||||
end.
|
|
||||||
|
|
||||||
is_user_exists_internal(User) ->
|
|
||||||
LUser = jlib:nodeprep(User),
|
|
||||||
case catch mnesia:dirty_read({passwd, LUser}) of
|
|
||||||
[] ->
|
|
||||||
false;
|
|
||||||
[_] ->
|
|
||||||
true;
|
|
||||||
_ ->
|
|
||||||
false
|
|
||||||
end.
|
|
||||||
|
|
||||||
remove_user(User) ->
|
|
||||||
case user_method() of
|
|
||||||
internal ->
|
|
||||||
remove_user_internal(User);
|
|
||||||
ldap ->
|
|
||||||
{error, not_allowed}
|
|
||||||
end.
|
|
||||||
|
|
||||||
remove_user_internal(User) ->
|
|
||||||
LUser = jlib:nodeprep(User),
|
|
||||||
F = fun() ->
|
|
||||||
mnesia:delete({passwd, LUser})
|
|
||||||
end,
|
|
||||||
mnesia:transaction(F),
|
|
||||||
catch mod_roster:remove_user(User),
|
|
||||||
catch mod_offline:remove_user(User),
|
|
||||||
catch mod_last:remove_user(User),
|
|
||||||
catch mod_vcard:remove_user(User),
|
|
||||||
catch mod_private:remove_user(User).
|
|
||||||
|
|
||||||
remove_user(User, Password) ->
|
|
||||||
case user_method() of
|
|
||||||
internal ->
|
|
||||||
remove_user_internal(User, Password);
|
|
||||||
ldap ->
|
|
||||||
not_allowed
|
|
||||||
end.
|
|
||||||
|
|
||||||
remove_user_internal(User, Password) ->
|
|
||||||
LUser = jlib:nodeprep(User),
|
|
||||||
F = fun() ->
|
|
||||||
case mnesia:read({passwd, LUser}) of
|
|
||||||
[#passwd{password = Password}] ->
|
|
||||||
mnesia:delete({passwd, LUser}),
|
|
||||||
ok;
|
|
||||||
[_] ->
|
|
||||||
not_allowed;
|
|
||||||
_ ->
|
|
||||||
not_exists
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
case mnesia:transaction(F) of
|
|
||||||
{atomic, ok} ->
|
|
||||||
catch mod_roster:remove_user(User),
|
|
||||||
catch mod_offline:remove_user(User),
|
|
||||||
catch mod_last:remove_user(User),
|
|
||||||
catch mod_vcard:remove_user(User),
|
|
||||||
catch mod_private:remove_user(User),
|
|
||||||
ok;
|
|
||||||
{atomic, Res} ->
|
|
||||||
Res;
|
|
||||||
_ ->
|
|
||||||
bad_request
|
|
||||||
end.
|
|
||||||
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
||||||
|
|
||||||
check_password_ldap(User, Password, StreamID, Digest) ->
|
|
||||||
check_password_ldap(User, Password).
|
|
||||||
|
|
||||||
check_password_external(User, Password, StreamID, Digest) ->
|
|
||||||
check_password_external(User, Password).
|
|
||||||
|
|
||||||
check_password_ldap(User, Password) ->
|
|
||||||
case find_user_dn(User) of
|
|
||||||
false ->
|
|
||||||
false;
|
|
||||||
DN ->
|
|
||||||
case eldap:bind("ejabberd_bind", DN, Password) of
|
|
||||||
ok ->
|
|
||||||
true;
|
|
||||||
_ ->
|
|
||||||
false
|
|
||||||
end
|
|
||||||
end.
|
|
||||||
|
|
||||||
is_user_exists_ldap(User) ->
|
|
||||||
case find_user_dn(User) of
|
|
||||||
false ->
|
|
||||||
false;
|
|
||||||
_DN ->
|
|
||||||
true
|
|
||||||
end.
|
|
||||||
|
|
||||||
find_user_dn(User) ->
|
|
||||||
Attr = ejabberd_config:get_local_option(ldap_uidattr),
|
|
||||||
Filter = eldap:equalityMatch(Attr, User),
|
|
||||||
Base = ejabberd_config:get_local_option(ldap_base),
|
|
||||||
case eldap:search("ejabberd", [{base, Base},
|
|
||||||
{filter, Filter},
|
|
||||||
{attributes, []}]) of
|
|
||||||
#eldap_search_result{entries = [E | _]} ->
|
|
||||||
E#eldap_entry.object_name;
|
|
||||||
_ ->
|
|
||||||
false
|
|
||||||
end.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% File : ejabberd_auth_external.erl
|
||||||
|
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
%%% Purpose : Authentification via LDAP external script
|
||||||
|
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
%%% Id : $Id$
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(ejabberd_auth_external).
|
||||||
|
-author('alexey@sevcom.net').
|
||||||
|
-vsn('$Revision$ ').
|
||||||
|
|
||||||
|
%% External exports
|
||||||
|
-export([start/0,
|
||||||
|
set_password/2,
|
||||||
|
check_password/2,
|
||||||
|
check_password/4,
|
||||||
|
try_register/2,
|
||||||
|
dirty_get_registered_users/0,
|
||||||
|
get_password/1,
|
||||||
|
get_password_s/1,
|
||||||
|
is_user_exists/1,
|
||||||
|
remove_user/1,
|
||||||
|
remove_user/2,
|
||||||
|
plain_password_required/0
|
||||||
|
]).
|
||||||
|
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% API
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
start() ->
|
||||||
|
extauth:start(ejabberd_config:get_local_option(extauth_program)),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
plain_password_required() ->
|
||||||
|
true.
|
||||||
|
|
||||||
|
check_password(User, Password) ->
|
||||||
|
extauth:check_password(User, Password).
|
||||||
|
|
||||||
|
check_password(User, Password, _StreamID, _Digest) ->
|
||||||
|
check_password(User, Password).
|
||||||
|
|
||||||
|
set_password(User, Password) ->
|
||||||
|
extauth:set_password(User, Password).
|
||||||
|
|
||||||
|
try_register(_User, _Password) ->
|
||||||
|
{error, not_allowed}.
|
||||||
|
|
||||||
|
dirty_get_registered_users() ->
|
||||||
|
[].
|
||||||
|
|
||||||
|
get_password(_User) ->
|
||||||
|
false.
|
||||||
|
|
||||||
|
get_password_s(_User) ->
|
||||||
|
"".
|
||||||
|
|
||||||
|
is_user_exists(User) ->
|
||||||
|
extauth:is_user_exists(User).
|
||||||
|
|
||||||
|
remove_user(_User) ->
|
||||||
|
{error, not_allowed}.
|
||||||
|
|
||||||
|
remove_user(_User, _Password) ->
|
||||||
|
not_allowed.
|
||||||
|
|
|
@ -0,0 +1,167 @@
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% File : ejabberd_auth_internal.erl
|
||||||
|
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
%%% Purpose : Authentification via mnesia
|
||||||
|
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
%%% Id : $Id$
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(ejabberd_auth_internal).
|
||||||
|
-author('alexey@sevcom.net').
|
||||||
|
-vsn('$Revision$ ').
|
||||||
|
|
||||||
|
%% External exports
|
||||||
|
-export([start/0,
|
||||||
|
set_password/2,
|
||||||
|
check_password/2,
|
||||||
|
check_password/4,
|
||||||
|
try_register/2,
|
||||||
|
dirty_get_registered_users/0,
|
||||||
|
get_password/1,
|
||||||
|
get_password_s/1,
|
||||||
|
is_user_exists/1,
|
||||||
|
remove_user/1,
|
||||||
|
remove_user/2,
|
||||||
|
plain_password_required/0
|
||||||
|
]).
|
||||||
|
|
||||||
|
-record(passwd, {user, password}).
|
||||||
|
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% API
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
start() ->
|
||||||
|
mnesia:create_table(passwd,[{disc_copies, [node()]},
|
||||||
|
{attributes, record_info(fields, passwd)}]),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
plain_password_required() ->
|
||||||
|
false.
|
||||||
|
|
||||||
|
check_password(User, Password) ->
|
||||||
|
LUser = jlib:nodeprep(User),
|
||||||
|
case catch mnesia:dirty_read({passwd, LUser}) of
|
||||||
|
[#passwd{password = Password}] ->
|
||||||
|
true;
|
||||||
|
_ ->
|
||||||
|
false
|
||||||
|
end.
|
||||||
|
|
||||||
|
check_password(User, Password, StreamID, Digest) ->
|
||||||
|
LUser = jlib:nodeprep(User),
|
||||||
|
case catch mnesia:dirty_read({passwd, LUser}) of
|
||||||
|
[#passwd{password = Passwd}] ->
|
||||||
|
DigRes = if
|
||||||
|
Digest /= "" ->
|
||||||
|
Digest == sha:sha(StreamID ++ Passwd);
|
||||||
|
true ->
|
||||||
|
false
|
||||||
|
end,
|
||||||
|
if DigRes ->
|
||||||
|
true;
|
||||||
|
true ->
|
||||||
|
(Passwd == Password) and (Password /= "")
|
||||||
|
end;
|
||||||
|
_ ->
|
||||||
|
false
|
||||||
|
end.
|
||||||
|
|
||||||
|
set_password(User, Password) ->
|
||||||
|
case jlib:nodeprep(User) of
|
||||||
|
error -> {error, invalid_jid};
|
||||||
|
LUser ->
|
||||||
|
F = fun() ->
|
||||||
|
mnesia:write(#passwd{user = LUser,
|
||||||
|
password = Password})
|
||||||
|
end,
|
||||||
|
mnesia:transaction(F)
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
try_register(User, Password) ->
|
||||||
|
case jlib:nodeprep(User) of
|
||||||
|
error -> {error, invalid_jid};
|
||||||
|
LUser ->
|
||||||
|
F = fun() ->
|
||||||
|
case mnesia:read({passwd, LUser}) of
|
||||||
|
[] ->
|
||||||
|
mnesia:write(#passwd{user = LUser,
|
||||||
|
password = Password}),
|
||||||
|
ok;
|
||||||
|
[_E] ->
|
||||||
|
exists
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
mnesia:transaction(F)
|
||||||
|
end.
|
||||||
|
|
||||||
|
dirty_get_registered_users() ->
|
||||||
|
mnesia:dirty_all_keys(passwd).
|
||||||
|
|
||||||
|
get_password(User) ->
|
||||||
|
LUser = jlib:nodeprep(User),
|
||||||
|
case catch mnesia:dirty_read(passwd, LUser) of
|
||||||
|
[#passwd{password = Password}] ->
|
||||||
|
Password;
|
||||||
|
_ ->
|
||||||
|
false
|
||||||
|
end.
|
||||||
|
|
||||||
|
get_password_s(User) ->
|
||||||
|
LUser = jlib:nodeprep(User),
|
||||||
|
case catch mnesia:dirty_read(passwd, LUser) of
|
||||||
|
[#passwd{password = Password}] ->
|
||||||
|
Password;
|
||||||
|
_ ->
|
||||||
|
[]
|
||||||
|
end.
|
||||||
|
|
||||||
|
is_user_exists(User) ->
|
||||||
|
LUser = jlib:nodeprep(User),
|
||||||
|
case catch mnesia:dirty_read({passwd, LUser}) of
|
||||||
|
[] ->
|
||||||
|
false;
|
||||||
|
[_] ->
|
||||||
|
true;
|
||||||
|
_ ->
|
||||||
|
false
|
||||||
|
end.
|
||||||
|
|
||||||
|
remove_user(User) ->
|
||||||
|
LUser = jlib:nodeprep(User),
|
||||||
|
F = fun() ->
|
||||||
|
mnesia:delete({passwd, LUser})
|
||||||
|
end,
|
||||||
|
mnesia:transaction(F),
|
||||||
|
catch mod_roster:remove_user(User),
|
||||||
|
catch mod_offline:remove_user(User),
|
||||||
|
catch mod_last:remove_user(User),
|
||||||
|
catch mod_vcard:remove_user(User),
|
||||||
|
catch mod_private:remove_user(User).
|
||||||
|
|
||||||
|
remove_user(User, Password) ->
|
||||||
|
LUser = jlib:nodeprep(User),
|
||||||
|
F = fun() ->
|
||||||
|
case mnesia:read({passwd, LUser}) of
|
||||||
|
[#passwd{password = Password}] ->
|
||||||
|
mnesia:delete({passwd, LUser}),
|
||||||
|
ok;
|
||||||
|
[_] ->
|
||||||
|
not_allowed;
|
||||||
|
_ ->
|
||||||
|
not_exists
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
case mnesia:transaction(F) of
|
||||||
|
{atomic, ok} ->
|
||||||
|
catch mod_roster:remove_user(User),
|
||||||
|
catch mod_offline:remove_user(User),
|
||||||
|
catch mod_last:remove_user(User),
|
||||||
|
catch mod_vcard:remove_user(User),
|
||||||
|
catch mod_private:remove_user(User),
|
||||||
|
ok;
|
||||||
|
{atomic, Res} ->
|
||||||
|
Res;
|
||||||
|
_ ->
|
||||||
|
bad_request
|
||||||
|
end.
|
|
@ -0,0 +1,106 @@
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% File : ejabberd_auth_ldap.erl
|
||||||
|
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
%%% Purpose : Authentification via LDAP
|
||||||
|
%%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@sevcom.net>
|
||||||
|
%%% Id : $Id$
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(ejabberd_auth_ldap).
|
||||||
|
-author('alexey@sevcom.net').
|
||||||
|
-vsn('$Revision$ ').
|
||||||
|
|
||||||
|
%% External exports
|
||||||
|
-export([start/0,
|
||||||
|
set_password/2,
|
||||||
|
check_password/2,
|
||||||
|
check_password/4,
|
||||||
|
try_register/2,
|
||||||
|
dirty_get_registered_users/0,
|
||||||
|
get_password/1,
|
||||||
|
get_password_s/1,
|
||||||
|
is_user_exists/1,
|
||||||
|
remove_user/1,
|
||||||
|
remove_user/2,
|
||||||
|
plain_password_required/0
|
||||||
|
]).
|
||||||
|
|
||||||
|
-include("eldap/eldap.hrl").
|
||||||
|
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% API
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
start() ->
|
||||||
|
LDAPServers = ejabberd_config:get_local_option(ldap_servers),
|
||||||
|
RootDN = ejabberd_config:get_local_option(ldap_rootdn),
|
||||||
|
Password = ejabberd_config:get_local_option(ldap_password),
|
||||||
|
eldap:start_link("ejabberd", LDAPServers, 389, RootDN, Password),
|
||||||
|
eldap:start_link("ejabberd_bind", LDAPServers, 389, RootDN, Password),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
plain_password_required() ->
|
||||||
|
true.
|
||||||
|
|
||||||
|
check_password(User, Password) ->
|
||||||
|
case find_user_dn(User) of
|
||||||
|
false ->
|
||||||
|
false;
|
||||||
|
DN ->
|
||||||
|
case eldap:bind("ejabberd_bind", DN, Password) of
|
||||||
|
ok ->
|
||||||
|
true;
|
||||||
|
_ ->
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
|
check_password(User, Password, _StreamID, _Digest) ->
|
||||||
|
check_password(User, Password).
|
||||||
|
|
||||||
|
set_password(_User, _Password) ->
|
||||||
|
{error, not_allowed}.
|
||||||
|
|
||||||
|
try_register(_User, _Password) ->
|
||||||
|
{error, not_allowed}.
|
||||||
|
|
||||||
|
dirty_get_registered_users() ->
|
||||||
|
[].
|
||||||
|
|
||||||
|
get_password(_User) ->
|
||||||
|
false.
|
||||||
|
|
||||||
|
get_password_s(_User) ->
|
||||||
|
"".
|
||||||
|
|
||||||
|
is_user_exists(User) ->
|
||||||
|
case find_user_dn(User) of
|
||||||
|
false ->
|
||||||
|
false;
|
||||||
|
_DN ->
|
||||||
|
true
|
||||||
|
end.
|
||||||
|
|
||||||
|
remove_user(_User) ->
|
||||||
|
{error, not_allowed}.
|
||||||
|
|
||||||
|
remove_user(_User, _Password) ->
|
||||||
|
not_allowed.
|
||||||
|
|
||||||
|
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
%%% Internal functions
|
||||||
|
%%%----------------------------------------------------------------------
|
||||||
|
|
||||||
|
find_user_dn(User) ->
|
||||||
|
Attr = ejabberd_config:get_local_option(ldap_uidattr),
|
||||||
|
Filter = eldap:equalityMatch(Attr, User),
|
||||||
|
Base = ejabberd_config:get_local_option(ldap_base),
|
||||||
|
case eldap:search("ejabberd", [{base, Base},
|
||||||
|
{filter, Filter},
|
||||||
|
{attributes, []}]) of
|
||||||
|
#eldap_search_result{entries = [E | _]} ->
|
||||||
|
E#eldap_entry.object_name;
|
||||||
|
_ ->
|
||||||
|
false
|
||||||
|
end.
|
||||||
|
|
|
@ -331,13 +331,12 @@ set_presence(User, Resource, Priority) ->
|
||||||
mnesia:transaction(F).
|
mnesia:transaction(F).
|
||||||
|
|
||||||
unset_presence(User, Resource, Status) ->
|
unset_presence(User, Resource, Status) ->
|
||||||
LUser = jlib:nodeprep(User),
|
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
UR = {User, Resource},
|
UR = {User, Resource},
|
||||||
mnesia:delete({presence, UR})
|
mnesia:delete({presence, UR})
|
||||||
end,
|
end,
|
||||||
mnesia:transaction(F),
|
mnesia:transaction(F),
|
||||||
catch mod_last:on_presence_update(LUser, Status).
|
ejabberd_hooks:run(unset_presence_hook, [User, Resource, Status]).
|
||||||
|
|
||||||
get_user_present_resources(LUser) ->
|
get_user_present_resources(LUser) ->
|
||||||
case catch mnesia:dirty_index_read(presence, LUser, #presence.user) of
|
case catch mnesia:dirty_index_read(presence, LUser, #presence.user) of
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
stop/0,
|
stop/0,
|
||||||
process_local_iq/3,
|
process_local_iq/3,
|
||||||
process_sm_iq/3,
|
process_sm_iq/3,
|
||||||
on_presence_update/2,
|
on_presence_update/3,
|
||||||
remove_user/1]).
|
remove_user/1]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
|
@ -34,7 +34,9 @@ start(Opts) ->
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_LAST,
|
gen_iq_handler:add_iq_handler(ejabberd_local, ?NS_LAST,
|
||||||
?MODULE, process_local_iq, IQDisc),
|
?MODULE, process_local_iq, IQDisc),
|
||||||
gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_LAST,
|
gen_iq_handler:add_iq_handler(ejabberd_sm, ?NS_LAST,
|
||||||
?MODULE, process_sm_iq, IQDisc).
|
?MODULE, process_sm_iq, IQDisc),
|
||||||
|
ejabberd_hooks:add(unset_presence_hook,
|
||||||
|
?MODULE, on_presence_update, 50).
|
||||||
|
|
||||||
stop() ->
|
stop() ->
|
||||||
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_LAST),
|
gen_iq_handler:remove_iq_handler(ejabberd_local, ?NS_LAST),
|
||||||
|
@ -107,7 +109,8 @@ get_last(IQ, SubEl, LUser) ->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
on_presence_update(LUser, Status) ->
|
on_presence_update(User, _Resource, Status) ->
|
||||||
|
LUser = jlib:nodeprep(User),
|
||||||
{MegaSecs, Secs, _MicroSecs} = now(),
|
{MegaSecs, Secs, _MicroSecs} = now(),
|
||||||
TimeStamp = MegaSecs * 1000000 + Secs,
|
TimeStamp = MegaSecs * 1000000 + Secs,
|
||||||
F = fun() ->
|
F = fun() ->
|
||||||
|
|
Loading…
Reference in New Issue