* src/mod_register.erl: Bugfix

* src/mod_vcard.erl: Bugfix

* src/ejabberd_app.erl: Updated to allow different authentication
methods for different virtual hosts
* src/ejabberd_auth.erl: Likewise
* src/ejabberd_auth_external.erl: Likewise
* src/ejabberd_auth_internal.erl: Likewise
* src/ejabberd_auth_ldap.erl: Likewise
* src/ejabberd_auth_odbc.erl: Likewise
* src/cyrsasl.erl: Likewise
* src/cyrsasl_digest.erl: Likewise
* src/cyrsasl_plain.erl: Likewise
* src/ejabberd_c2s.erl: Likewise
* src/ejabberd_config.erl: Likewise
* src/extauth.erl: Likewise
* src/mod_last_odbc.erl: Likewise
* src/mod_offline_odbc.erl: Likewise
* src/mod_roster_odbc.erl: Likewise
* src/odbc/ejabberd_odbc.erl: Likewise
* src/odbc/ejabberd_odbc_sup.erl: Likewise

SVN Revision: 374
This commit is contained in:
Alexey Shchepin 2005-07-13 03:24:13 +00:00
parent 37bf811f4b
commit 3202705ad6
20 changed files with 326 additions and 177 deletions

View File

@ -1,3 +1,28 @@
2005-07-13 Alexey Shchepin <alexey@sevcom.net>
* src/mod_register.erl: Bugfix
* src/mod_vcard.erl: Bugfix
* src/ejabberd_app.erl: Updated to allow different authentication
methods for different virtual hosts
* src/ejabberd_auth.erl: Likewise
* src/ejabberd_auth_external.erl: Likewise
* src/ejabberd_auth_internal.erl: Likewise
* src/ejabberd_auth_ldap.erl: Likewise
* src/ejabberd_auth_odbc.erl: Likewise
* src/cyrsasl.erl: Likewise
* src/cyrsasl_digest.erl: Likewise
* src/cyrsasl_plain.erl: Likewise
* src/ejabberd_c2s.erl: Likewise
* src/ejabberd_config.erl: Likewise
* src/extauth.erl: Likewise
* src/mod_last_odbc.erl: Likewise
* src/mod_offline_odbc.erl: Likewise
* src/mod_roster_odbc.erl: Likewise
* src/odbc/ejabberd_odbc.erl: Likewise
* src/odbc/ejabberd_odbc_sup.erl: Likewise
2005-07-03 Alexey Shchepin <alexey@sevcom.net>
* src/ejabberd_app.erl: Bugfix

View File

@ -11,13 +11,13 @@
-vsn('$Revision$ ').
-export([start/0,
register_mechanism/2,
listmech/0,
register_mechanism/3,
listmech/1,
server_new/6,
server_start/3,
server_step/2]).
-record(sasl_mechanism, {mechanism, module}).
-record(sasl_mechanism, {mechanism, module, require_plain_password}).
-record(sasl_state, {service, myname, realm,
get_password, check_password,
mech_mod, mech_state}).
@ -38,9 +38,11 @@ start() ->
cyrsasl_digest:start([]),
ok.
register_mechanism(Mechanism, Module) ->
ets:insert(sasl_mechanism, #sasl_mechanism{mechanism = Mechanism,
module = Module}).
register_mechanism(Mechanism, Module, RequirePlainPassword) ->
ets:insert(sasl_mechanism,
#sasl_mechanism{mechanism = Mechanism,
module = Module,
require_plain_password = RequirePlainPassword}).
% TODO: use callbacks
-include("ejabberd.hrl").
@ -77,9 +79,19 @@ check_credentials(State, Props) ->
ok
end.
listmech() ->
listmech(Host) ->
RequirePlainPassword = ejabberd_auth:plain_password_required(Host),
ets:select(sasl_mechanism,
[{#sasl_mechanism{mechanism = '$1', _ = '_'}, [], ['$1']}]).
[{#sasl_mechanism{mechanism = '$1',
require_plain_password = '$2',
_ = '_'},
if
RequirePlainPassword ->
[{'==', '$2', false}];
true ->
[]
end,
['$1']}]).
server_new(Service, ServerFQDN, UserRealm, SecFlags,

View File

@ -20,13 +20,7 @@
-record(state, {step, nonce, username, authzid, get_password}).
start(_Opts) ->
case ejabberd_auth:plain_password_required() of
true ->
ok;
false ->
cyrsasl:register_mechanism("DIGEST-MD5", ?MODULE),
ok
end.
cyrsasl:register_mechanism("DIGEST-MD5", ?MODULE, true).
stop() ->
ok.

View File

@ -17,7 +17,7 @@
-record(state, {check_password}).
start(_Opts) ->
cyrsasl:register_mechanism("PLAIN", ?MODULE),
cyrsasl:register_mechanism("PLAIN", ?MODULE, false),
ok.
stop() ->

View File

@ -28,13 +28,13 @@ start(normal, _Args) ->
acl:start(),
gen_mod:start(),
ejabberd_config:start(),
Sup = ejabberd_sup:start_link(),
ejabberd_auth:start(),
cyrsasl:start(),
% Profiling
%eprof:start(),
%eprof:profile([self()]),
%fprof:trace(start, "/tmp/fprof"),
Sup = ejabberd_sup:start_link(),
start(),
load_modules(),
Sup;

View File

@ -23,7 +23,7 @@
is_user_exists/2,
remove_user/2,
remove_user/3,
plain_password_required/0
plain_password_required/1
]).
-include("ejabberd.hrl").
@ -32,55 +32,58 @@
%%% API
%%%----------------------------------------------------------------------
start() ->
(auth_module()):start().
lists:foreach(fun(Host) ->
(auth_module(Host)):start(Host)
end, ?MYHOSTS).
plain_password_required() ->
(auth_module()):plain_password_required().
plain_password_required(Server) ->
(auth_module(Server)):plain_password_required().
check_password(User, Server, Password) ->
(auth_module()):check_password(User, Server, Password).
(auth_module(Server)):check_password(User, Server, Password).
check_password(User, Server, Password, StreamID, Digest) ->
(auth_module()):check_password(User, Server, Password, StreamID, Digest).
(auth_module(Server)):check_password(User, Server, Password, StreamID, Digest).
set_password(User, Server, Password) ->
(auth_module()):set_password(User, Server, Password).
(auth_module(Server)):set_password(User, Server, Password).
try_register(User, Server, Password) ->
case lists:member(jlib:nameprep(Server), ?MYHOSTS) of
true ->
(auth_module()):try_register(User, Server, Password);
(auth_module(Server)):try_register(User, Server, Password);
false ->
{error, not_allowed}
end.
dirty_get_registered_users() ->
(auth_module()):dirty_get_registered_users().
(auth_module(?MYNAME)):dirty_get_registered_users().
get_vh_registered_users(Server) ->
(auth_module()):get_vh_registered_users(Server).
(auth_module(Server)):get_vh_registered_users(Server).
get_password(User, Server) ->
(auth_module()):get_password(User, Server).
(auth_module(Server)):get_password(User, Server).
get_password_s(User, Server) ->
(auth_module()):get_password_s(User, Server).
(auth_module(Server)):get_password_s(User, Server).
is_user_exists(User, Server) ->
(auth_module()):is_user_exists(User, Server).
(auth_module(Server)):is_user_exists(User, Server).
remove_user(User, Server) ->
(auth_module()):remove_user(User, Server).
(auth_module(Server)):remove_user(User, Server).
remove_user(User, Server, Password) ->
(auth_module()):remove_user(User, Server, Password).
(auth_module(Server)):remove_user(User, Server, Password).
%%%----------------------------------------------------------------------
%%% Internal functions
%%%----------------------------------------------------------------------
auth_module() ->
case ejabberd_config:get_local_option(auth_method) of
auth_module(Server) ->
LServer = jlib:nameprep(Server),
case ejabberd_config:get_local_option({auth_method, LServer}) of
external ->
ejabberd_auth_external;
ldap ->

View File

@ -11,7 +11,7 @@
-vsn('$Revision$ ').
%% External exports
-export([start/0,
-export([start/1,
set_password/3,
check_password/3,
check_password/5,
@ -29,21 +29,22 @@
%%%----------------------------------------------------------------------
%%% API
%%%----------------------------------------------------------------------
start() ->
extauth:start(ejabberd_config:get_local_option(extauth_program)),
start(Host) ->
extauth:start(
Host, ejabberd_config:get_local_option({extauth_program, Host})),
ok.
plain_password_required() ->
true.
check_password(User, _Server, Password) ->
extauth:check_password(User, Password).
check_password(User, Server, Password) ->
extauth:check_password(User, Server, Password).
check_password(User, Server, Password, _StreamID, _Digest) ->
check_password(User, Server, Password).
set_password(User, _Server, Password) ->
extauth:set_password(User, Password).
set_password(User, Server, Password) ->
extauth:set_password(User, Server, Password).
try_register(_User, _Server, _Password) ->
{error, not_allowed}.
@ -60,8 +61,8 @@ get_password(_User, _Server) ->
get_password_s(_User, _Server) ->
"".
is_user_exists(User, _Server) ->
extauth:is_user_exists(User).
is_user_exists(User, Server) ->
extauth:is_user_exists(User, Server).
remove_user(_User, _Server) ->
{error, not_allowed}.

View File

@ -11,7 +11,7 @@
-vsn('$Revision$ ').
%% External exports
-export([start/0,
-export([start/1,
set_password/3,
check_password/3,
check_password/5,
@ -33,7 +33,7 @@
%%%----------------------------------------------------------------------
%%% API
%%%----------------------------------------------------------------------
start() ->
start(_Host) ->
mnesia:create_table(passwd, [{disc_copies, [node()]},
{attributes, record_info(fields, passwd)}]),
update_table(),

View File

@ -11,7 +11,7 @@
-vsn('$Revision$ ').
%% External exports
-export([start/0,
-export([start/1,
set_password/3,
check_password/3,
check_password/5,
@ -32,23 +32,27 @@
%%%----------------------------------------------------------------------
%%% 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),
start(Host) ->
LDAPServers = ejabberd_config:get_local_option({ldap_servers, Host}),
RootDN = ejabberd_config:get_local_option({ldap_rootdn, Host}),
Password = ejabberd_config:get_local_option({ldap_password, Host}),
eldap:start_link(gen_mod:get_module_proc(Host, ejabberd),
LDAPServers, 389, RootDN, Password),
eldap:start_link(gen_mod:get_module_proc(Host, ejabberd_bind),
LDAPServers, 389, RootDN, Password),
ok.
plain_password_required() ->
true.
check_password(User, _Server, Password) ->
case find_user_dn(User) of
check_password(User, Server, Password) ->
case find_user_dn(User, Server) of
false ->
false;
DN ->
case eldap:bind("ejabberd_bind", DN, Password) of
LServer = jlib:nameprep(Server),
case eldap:bind(gen_mod:get_module_proc(LServer, ejabberd_bind),
DN, Password) of
ok ->
true;
_ ->
@ -70,12 +74,13 @@ dirty_get_registered_users() ->
get_vh_registered_users(Server) ->
LServer = jlib:nameprep(Server),
Attr = ejabberd_config:get_local_option(ldap_uidattr),
Attr = ejabberd_config:get_local_option({ldap_uidattr, LServer}),
Filter = eldap:present(Attr),
Base = ejabberd_config:get_local_option(ldap_base),
case eldap:search("ejabberd", [{base, Base},
{filter, Filter},
{attributes, [Attr]}]) of
Base = ejabberd_config:get_local_option({ldap_base, LServer}),
case eldap:search(gen_mod:get_module_proc(LServer, ejabberd),
[{base, Base},
{filter, Filter},
{attributes, [Attr]}]) of
#eldap_search_result{entries = Es} ->
lists:flatmap(
fun(E) ->
@ -101,8 +106,8 @@ get_password(_User, _Server) ->
get_password_s(_User, _Server) ->
"".
is_user_exists(User, _Server) ->
case find_user_dn(User) of
is_user_exists(User, Server) ->
case find_user_dn(User, Server) of
false ->
false;
_DN ->
@ -120,13 +125,15 @@ remove_user(_User, _Server, _Password) ->
%%% Internal functions
%%%----------------------------------------------------------------------
find_user_dn(User) ->
Attr = ejabberd_config:get_local_option(ldap_uidattr),
find_user_dn(User, Server) ->
LServer = jlib:nameprep(Server),
Attr = ejabberd_config:get_local_option({ldap_uidattr, LServer}),
Filter = eldap:equalityMatch(Attr, User),
Base = ejabberd_config:get_local_option(ldap_base),
case eldap:search("ejabberd", [{base, Base},
{filter, Filter},
{attributes, []}]) of
Base = ejabberd_config:get_local_option({ldap_base, LServer}),
case eldap:search(gen_mod:get_module_proc(LServer, ejabberd),
[{base, Base},
{filter, Filter},
{attributes, []}]) of
#eldap_search_result{entries = [E | _]} ->
E#eldap_entry.object_name;
_ ->

View File

@ -11,7 +11,7 @@
-vsn('$Revision$ ').
%% External exports
-export([start/0,
-export([start/1,
set_password/3,
check_password/3,
check_password/5,
@ -26,24 +26,28 @@
plain_password_required/0
]).
-include("ejabberd.hrl").
-record(passwd, {user, password}).
%%%----------------------------------------------------------------------
%%% API
%%%----------------------------------------------------------------------
start() ->
start(Host) ->
ejabberd_odbc_sup:start_link(Host),
ok.
plain_password_required() ->
false.
check_password(User, _Server, Password) ->
check_password(User, Server, Password) ->
case jlib:nodeprep(User) of
error ->
false;
LUser ->
Username = ejabberd_odbc:escape(LUser),
case catch ejabberd_odbc:sql_query(
jlib:nameprep(Server),
["select password from users "
"where username='", Username, "'"]) of
{selected, ["password"], [{Password}]} ->
@ -53,13 +57,14 @@ check_password(User, _Server, Password) ->
end
end.
check_password(User, _Server, Password, StreamID, Digest) ->
check_password(User, Server, Password, StreamID, Digest) ->
case jlib:nodeprep(User) of
error ->
false;
LUser ->
Username = ejabberd_odbc:escape(LUser),
case catch ejabberd_odbc:sql_query(
jlib:nameprep(Server),
["select password from users "
"where username='", Username, "'"]) of
{selected, ["password"], [{Passwd}]} ->
@ -79,7 +84,7 @@ check_password(User, _Server, Password, StreamID, Digest) ->
end
end.
set_password(User, _Server, Password) ->
set_password(User, Server, Password) ->
case jlib:nodeprep(User) of
error ->
{error, invalid_jid};
@ -87,6 +92,7 @@ set_password(User, _Server, Password) ->
Username = ejabberd_odbc:escape(LUser),
Pass = ejabberd_odbc:escape(Password),
catch ejabberd_odbc:sql_query(
jlib:nameprep(Server),
["begin;"
"delete from users where username='", Username ,"';"
"insert into users(username, password) "
@ -94,7 +100,7 @@ set_password(User, _Server, Password) ->
end.
try_register(User, _Server, Password) ->
try_register(User, Server, Password) ->
case jlib:nodeprep(User) of
error ->
{error, invalid_jid};
@ -102,6 +108,7 @@ try_register(User, _Server, Password) ->
Username = ejabberd_odbc:escape(LUser),
Pass = ejabberd_odbc:escape(Password),
case catch ejabberd_odbc:sql_query(
jlib:nameprep(Server),
["insert into users(username, password) "
"values ('", Username, "', '", Pass, "')"]) of
{updated, _} ->
@ -112,23 +119,26 @@ try_register(User, _Server, Password) ->
end.
dirty_get_registered_users() ->
case catch ejabberd_odbc:sql_query("select username from users") of
get_vh_registered_users(?MYNAME).
get_vh_registered_users(Server) ->
case catch ejabberd_odbc:sql_query(
jlib:nameprep(Server),
"select username from users") of
{selected, ["username"], Res} ->
[U || {U} <- Res];
_ ->
[]
end.
get_vh_registered_users(Server) ->
dirty_get_registered_users().
get_password(User, _Server) ->
get_password(User, Server) ->
case jlib:nodeprep(User) of
error ->
false;
LUser ->
Username = ejabberd_odbc:escape(LUser),
case catch ejabberd_odbc:sql_query(
jlib:nameprep(Server),
["select password from users "
"where username='", Username, "'"]) of
{selected, ["password"], [{Password}]} ->
@ -138,13 +148,14 @@ get_password(User, _Server) ->
end
end.
get_password_s(User, _Server) ->
get_password_s(User, Server) ->
case jlib:nodeprep(User) of
error ->
"";
LUser ->
Username = ejabberd_odbc:escape(LUser),
case catch ejabberd_odbc:sql_query(
jlib:nameprep(Server),
["select password from users "
"where username='", Username, "'"]) of
{selected, ["password"], [{Password}]} ->
@ -154,13 +165,14 @@ get_password_s(User, _Server) ->
end
end.
is_user_exists(User, _Server) ->
is_user_exists(User, Server) ->
case jlib:nodeprep(User) of
error ->
false;
LUser ->
Username = ejabberd_odbc:escape(LUser),
case catch ejabberd_odbc:sql_query(
jlib:nameprep(Server),
["select password from users "
"where username='", Username, "'"]) of
{selected, ["password"], [{_Password}]} ->
@ -177,6 +189,7 @@ remove_user(User, Server) ->
LUser ->
Username = ejabberd_odbc:escape(LUser),
catch ejabberd_odbc:sql_query(
jlib:nameprep(Server),
["delete from users where username='", Username ,"'"]),
ejabberd_hooks:run(remove_user, jlib:nameprep(Server), [User])
end.
@ -190,6 +203,7 @@ remove_user(User, Server, Password) ->
Pass = ejabberd_odbc:escape(Password),
case catch
ejabberd_odbc:sql_query(
jlib:nameprep(Server),
["begin;"
"select password from users where username='", Username, "';"
"delete from users "

View File

@ -195,7 +195,7 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
fun(S) ->
{xmlelement, "mechanism", [],
[{xmlcdata, S}]}
end, cyrsasl:listmech()),
end, cyrsasl:listmech(Server)),
TLS = StateData#state.tls,
TLSEnabled = StateData#state.tls_enabled,
TLSRequired = StateData#state.tls_required,
@ -312,7 +312,8 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
{next_state, wait_for_auth, StateData};
{auth, _ID, get, {U, _, _, _}} ->
{xmlelement, Name, Attrs, _Els} = jlib:make_result_iq_reply(El),
Res = case ejabberd_auth:plain_password_required() of
Res = case ejabberd_auth:plain_password_required(
StateData#state.server) of
false ->
{xmlelement, Name, Attrs,
[{xmlelement, "query", [{"xmlns", ?NS_AUTH}],

View File

@ -103,6 +103,8 @@ process_term(Term, State) ->
State;
{listen, Val} ->
add_option(listen, Val, State);
{outgoing_s2s_port, Port} ->
add_option(outgoing_s2s_port, Port, State);
{Opt, Val} ->
lists:foldl(fun(Host, S) -> process_host_term(Term, Host, S) end,
State, State#state.hosts)

View File

@ -9,35 +9,36 @@
-module(extauth).
-author('leifj@it.su.se').
-export([start/1, stop/0, init/1,
check_password/2, set_password/2, is_user_exists/1 ]).
-export([start/2, stop/1, init/2,
check_password/3, set_password/3, is_user_exists/2]).
start(ExtPrg) ->
spawn(?MODULE, init, [ExtPrg]).
start(Host, ExtPrg) ->
spawn(?MODULE, init, [Host, ExtPrg]).
init(ExtPrg) ->
register(eauth,self()),
init(Host, ExtPrg) ->
register(gen_mod:get_module_proc(Host, eauth), self()),
process_flag(trap_exit,true),
Port = open_port({spawn, ExtPrg}, [{packet,2}]),
loop(Port).
stop() ->
eauth ! stop.
stop(Host) ->
gen_mod:get_module_proc(Host, eauth) ! stop.
check_password(User,Password) ->
call_port(["auth",User,Password]).
check_password(User, Server, Password) ->
call_port(Server, ["auth", User, Server, Password]).
is_user_exists(User) ->
call_port(["isuser",User]).
is_user_exists(User, Server) ->
call_port(Server, ["isuser", User, Server]).
set_password(User,Password) ->
call_port(["setpass",User,Password]).
set_password(User, Server, Password) ->
call_port(Server, ["setpass", User, Server, Password]).
call_port(Msg) ->
eauth ! {call, self(), Msg},
call_port(Server, Msg) ->
LServer = jlib:nameprep(Server),
gen_mod:get_module_proc(LServer, eauth) ! {call, self(), Msg},
receive
{eauth,Result}->
{eauth,Result} ->
Result
end.

View File

@ -18,7 +18,7 @@
process_sm_iq/3,
on_presence_update/4,
store_last_info/4,
remove_user/1]).
remove_user/2]).
-include("ejabberd.hrl").
-include("jlib.hrl").
@ -72,17 +72,17 @@ process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
(Subscription == both) or (Subscription == from) ->
case catch mod_privacy:get_user_list(User, Server) of
{'EXIT', _Reason} ->
get_last(IQ, SubEl, User);
get_last(IQ, SubEl, User, Server);
List ->
case catch mod_privacy:check_packet(
User, ?MYNAME, List, % TODO
User, Server, List,
{From, To,
{xmlelement, "presence", [], []}},
out) of
{'EXIT', _Reason} ->
get_last(IQ, SubEl, User);
get_last(IQ, SubEl, User, Server);
allow ->
get_last(IQ, SubEl, User);
get_last(IQ, SubEl, User, Server);
deny ->
IQ#iq{type = error,
sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
@ -94,9 +94,10 @@ process_sm_iq(From, To, #iq{type = Type, sub_el = SubEl} = IQ) ->
end
end.
get_last(IQ, SubEl, LUser) ->
get_last(IQ, SubEl, LUser, LServer) ->
Username = ejabberd_odbc:escape(LUser),
case catch ejabberd_odbc:sql_query(
LServer,
["select seconds, state from last "
"where username='", Username, "'"]) of
{'EXIT', _Reason} ->
@ -129,10 +130,12 @@ on_presence_update(User, Server, _Resource, Status) ->
store_last_info(User, Server, TimeStamp, Status) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(User),
Username = ejabberd_odbc:escape(LUser),
Seconds = ejabberd_odbc:escape(integer_to_list(TimeStamp)),
State = ejabberd_odbc:escape(Status),
ejabberd_odbc:sql_query(
LServer,
["begin;"
"delete from last where username='", Username, "';"
"insert into last(username, seconds, state) "
@ -140,9 +143,11 @@ store_last_info(User, Server, TimeStamp, Status) ->
"commit"]).
remove_user(User) ->
remove_user(User, Server) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
Username = ejabberd_odbc:escape(LUser),
ejabberd_odbc:sql_query(
LServer,
["delete from last where username='", Username, "'"]).

View File

@ -12,11 +12,11 @@
-behaviour(gen_mod).
-export([start/2,
init/0,
init/1,
stop/1,
store_packet/3,
pop_offline_messages/2,
remove_user/1]).
pop_offline_messages/3,
remove_user/2]).
-include("ejabberd.hrl").
-include("jlib.hrl").
@ -27,8 +27,6 @@
-define(OFFLINE_TABLE_LOCK_THRESHOLD, 1000).
start(Host, _Opts) ->
% TODO: remove
ejabberd_odbc:start(),
ejabberd_hooks:add(offline_message_hook, Host,
?MODULE, store_packet, 50),
ejabberd_hooks:add(offline_subscription_hook, Host,
@ -37,12 +35,13 @@ start(Host, _Opts) ->
?MODULE, pop_offline_messages, 50),
ejabberd_hooks:add(remove_user, Host,
?MODULE, remove_user, 50),
register(?PROCNAME, spawn(?MODULE, init, [])).
register(gen_mod:get_module_proc(Host, ?PROCNAME),
spawn(?MODULE, init, [Host])).
init() ->
loop().
init(Host) ->
loop(Host).
loop() ->
loop(Host) ->
receive
#offline_msg{} = Msg ->
Msgs = receive_all([Msg]),
@ -75,15 +74,16 @@ loop() ->
"');"]
end, Msgs),
case catch ejabberd_odbc:sql_query(
Host,
["begin; ", Query, " commit"]) of
{'EXIT', Reason} ->
?ERROR_MSG("~p~n", [Reason]);
_ ->
ok
end,
loop();
loop(Host);
_ ->
loop()
loop(Host)
end.
receive_all(Msgs) ->
@ -104,7 +104,8 @@ stop(Host) ->
?MODULE, pop_offline_messages, 50),
ejabberd_hooks:delete(remove_user, Host,
?MODULE, remove_user, 50),
exit(whereis(?PROCNAME), stop),
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
exit(whereis(Proc), stop),
ok.
store_packet(From, To, Packet) ->
@ -117,12 +118,13 @@ store_packet(From, To, Packet) ->
TimeStamp = now(),
{xmlelement, _Name, _Attrs, Els} = Packet,
Expire = find_x_expire(TimeStamp, Els),
?PROCNAME ! #offline_msg{user = LUser,
timestamp = TimeStamp,
expire = Expire,
from = From,
to = To,
packet = Packet},
gen_mod:get_module_proc(To#jid.lserver, ?PROCNAME) !
#offline_msg{user = LUser,
timestamp = TimeStamp,
expire = Expire,
from = From,
to = To,
packet = Packet},
stop;
_ ->
ok
@ -205,10 +207,12 @@ find_x_expire(TimeStamp, [El | Els]) ->
end.
pop_offline_messages(Ls, User) ->
pop_offline_messages(Ls, User, Server) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
EUser = ejabberd_odbc:escape(LUser),
case ejabberd_odbc:sql_query(
LServer,
["begin;"
"select * from spool where username='", EUser, "';"
"delete from spool where username='", EUser, "';"
@ -238,9 +242,11 @@ pop_offline_messages(Ls, User) ->
end.
remove_user(User) ->
remove_user(User, Server) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
Username = ejabberd_odbc:escape(LUser),
ejabberd_odbc:sql_query(
LServer,
["delete from spool where username='", Username, "'"]).

View File

@ -150,12 +150,13 @@ try_register(User, Server, Password) ->
send_welcome_message(JID) ->
case ejabberd_config:get_local_option(welcome_message) of
Host = JID#jid.lserver,
case ejabberd_config:get_local_option({welcome_message, Host}) of
{"", ""} ->
ok;
{Subj, Body} ->
ejabberd_router:route(
jlib:make_jid("", ?MYNAME, ""),
jlib:make_jid("", Host, ""),
JID,
{xmlelement, "message", [{"type", "normal"}],
[{xmlelement, "subject", [], [{xmlcdata, Subj}]},
@ -165,7 +166,8 @@ send_welcome_message(JID) ->
end.
send_registration_notifications(UJID) ->
case ejabberd_config:get_local_option(registration_watchers) of
Host = UJID#jid.lserver,
case ejabberd_config:get_local_option({registration_watchers, Host}) of
[] -> ok;
JIDs when is_list(JIDs) ->
Body = lists:flatten(
@ -178,7 +180,7 @@ send_registration_notifications(UJID) ->
error -> ok;
JID ->
ejabberd_router:route(
jlib:make_jid("", ?MYNAME, ""),
jlib:make_jid("", Host, ""),
JID,
{xmlelement, "message", [{"type", "chat"}],
[{xmlelement, "body", [],

View File

@ -15,12 +15,13 @@
-export([start/2, stop/1,
process_iq/3,
process_local_iq/3,
get_subscription_lists/2,
in_subscription/4,
out_subscription/3,
set_items/2,
remove_user/1,
get_jid_info/3]).
get_user_roster/2,
get_subscription_lists/3,
in_subscription/5,
out_subscription/4,
set_items/3,
remove_user/2,
get_jid_info/4]).
-include("ejabberd.hrl").
-include("jlib.hrl").
@ -33,8 +34,8 @@
start(Host, Opts) ->
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
ejabberd_hooks:add(roster_out_subscription, Host,
?MODULE, out_subscription, 50),
ejabberd_hooks:add(roster_get, Host,
?MODULE, get_user_roster, 50),
ejabberd_hooks:add(roster_in_subscription, Host,
?MODULE, in_subscription, 50),
ejabberd_hooks:add(roster_out_subscription, Host,
@ -49,6 +50,8 @@ start(Host, Opts) ->
?MODULE, process_iq, IQDisc).
stop(Host) ->
ejabberd_hooks:delete(roster_get, Host,
?MODULE, get_user_roster, 50),
ejabberd_hooks:delete(roster_in_subscription, Host,
?MODULE, in_subscription, 50),
ejabberd_hooks:delete(roster_out_subscription, Host,
@ -105,8 +108,10 @@ process_local_iq(From, To, #iq{type = Type} = IQ) ->
process_iq_get(From, _To, #iq{sub_el = SubEl} = IQ) ->
LUser = From#jid.luser,
LServer = From#jid.lserver,
Username = ejabberd_odbc:escape(LUser),
case catch ejabberd_odbc:sql_query(
LServer,
["select username, jid, nick, subscription, ask, "
"server, subscribe, type from rosterusers "
"where username='", Username, "'"]) of
@ -130,6 +135,31 @@ process_iq_get(From, _To, #iq{sub_el = SubEl} = IQ) ->
IQ#iq{type = error, sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}
end.
get_user_roster(Acc, {LUser, LServer}) ->
Username = ejabberd_odbc:escape(LUser),
case catch ejabberd_odbc:sql_query(
LServer,
["select username, jid, nick, subscription, ask, "
"server, subscribe, type from rosterusers "
"where username='", Username, "'"]) of
{selected, ["username", "jid", "nick", "subscription", "ask",
"server", "subscribe", "type"],
Items} when is_list(Items) ->
RItems = lists:flatmap(
fun(I) ->
case raw_to_record(I) of
error ->
[];
R ->
[R]
end
end, Items),
RItems ++ Acc;
_ ->
Acc
end.
item_to_xml(Item) ->
Attrs1 = [{"jid", jlib:jid_to_string(Item#roster.jid)}],
Attrs2 = case Item#roster.name of
@ -173,7 +203,7 @@ process_iq_set(From, To, #iq{sub_el = SubEl} = IQ) ->
process_item_set(From, To, {xmlelement, _Name, Attrs, Els}) ->
JID1 = jlib:string_to_jid(xml:get_attr_s("jid", Attrs)),
#jid{user = User, luser = LUser} = From,
#jid{user = User, luser = LUser, lserver = LServer} = From,
case JID1 of
error ->
ok;
@ -183,6 +213,7 @@ process_item_set(From, To, {xmlelement, _Name, Attrs, Els}) ->
Username = ejabberd_odbc:escape(LUser),
SJID = ejabberd_odbc:escape(jlib:jid_to_string(LJID)),
case catch ejabberd_odbc:sql_query(
LServer,
["select username, jid, nick, subscription, ask, "
"server, subscribe, type from rosterusers "
"where username='", Username, "' "
@ -203,6 +234,7 @@ process_item_set(From, To, {xmlelement, _Name, Attrs, Els}) ->
case Item1#roster.subscription of
remove ->
catch ejabberd_odbc:sql_query(
LServer,
["begin;"
"delete from rosterusers "
" where username='", Username, "' "
@ -214,6 +246,7 @@ process_item_set(From, To, {xmlelement, _Name, Attrs, Els}) ->
_ ->
ItemVals = record_to_string(Item1),
catch ejabberd_odbc:sql_query(
LServer,
["begin;"
"delete from rosterusers "
" where username='", Username, "' "
@ -228,8 +261,6 @@ process_item_set(From, To, {xmlelement, _Name, Attrs, Els}) ->
" and jid='", SJID, "';"
% TODO
"commit"])
%mnesia:write(Item1)
end,
push_item(User, To, Item1),
case Item1#roster.subscription of
@ -362,10 +393,12 @@ push_item(User, Resource, From, Item) ->
-endif.
get_subscription_lists(_, User) ->
get_subscription_lists(_, User, Server) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
Username = ejabberd_odbc:escape(LUser),
case catch ejabberd_odbc:sql_query(
LServer,
["select username, jid, nick, subscription, ask, "
"server, subscribe, type from rosterusers "
"where username='", Username, "'"]) of
@ -398,18 +431,20 @@ ask_to_pending(Ask) -> Ask.
in_subscription(_, User, JID, Type) ->
process_subscription(in, User, JID, Type).
in_subscription(_, User, Server, JID, Type) ->
process_subscription(in, User, Server, JID, Type).
out_subscription(User, JID, Type) ->
process_subscription(out, User, JID, Type).
out_subscription(User, Server, JID, Type) ->
process_subscription(out, User, Server, JID, Type).
process_subscription(Direction, User, JID1, Type) ->
process_subscription(Direction, User, Server, JID1, Type) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
LJID = jlib:jid_tolower(JID1),
Username = ejabberd_odbc:escape(LUser),
SJID = ejabberd_odbc:escape(jlib:jid_to_string(LJID)),
Item = case catch ejabberd_odbc:sql_query(
LServer,
["select username, jid, nick, subscription, ask, "
"server, subscribe, type from rosterusers "
"where username='", Username, "' "
@ -448,6 +483,7 @@ process_subscription(Direction, User, JID1, Type) ->
ask = Pending},
ItemVals = record_to_string(NewItem),
catch ejabberd_odbc:sql_query(
LServer,
["begin;"
"delete from rosterusers "
" where username='", Username, "' "
@ -572,10 +608,12 @@ in_auto_reply(both, none, unsubscribe) -> unsubscribed;
in_auto_reply(_, _, _) -> none.
remove_user(User) ->
remove_user(User, Server) ->
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
Username = ejabberd_odbc:escape(LUser),
catch ejabberd_odbc:sql_query(
LServer,
["begin;"
"delete from rosterusers "
" where username='", Username, "';"
@ -586,15 +624,18 @@ remove_user(User) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
set_items(User, SubEl) ->
set_items(User, Server, SubEl) ->
{xmlelement, _Name, _Attrs, Els} = SubEl,
LUser = jlib:nodeprep(User),
LServer = jlib:nameprep(Server),
F = fun() ->
lists:foreach(fun(El) -> process_item_set_t(LUser, El) end, Els)
lists:foreach(fun(El) ->
process_item_set_t(LUser, LServer, El)
end, Els)
end,
mnesia:transaction(F).
process_item_set_t(LUser, {xmlelement, _Name, Attrs, Els}) ->
process_item_set_t(LUser, LServer, {xmlelement, _Name, Attrs, Els}) ->
JID1 = jlib:string_to_jid(xml:get_attr_s("jid", Attrs)),
case JID1 of
error ->
@ -612,8 +653,40 @@ process_item_set_t(LUser, {xmlelement, _Name, Attrs, Els}) ->
_ ->
mnesia:write(Item2)
end
% TODO
%case Item2#roster.subscription of
% remove ->
% catch ejabberd_odbc:sql_query(
% LServer,
% ["begin;"
% "delete from rosterusers "
% " where username='", Username, "' "
% " and jid='", SJID, "';"
% "delete from rostergroups "
% " where username='", Username, "' "
% " and jid='", SJID, "';"
% "commit"]);
% _ ->
% ItemVals = record_to_string(Item1),
% catch ejabberd_odbc:sql_query(
% LServer,
% ["begin;"
% "delete from rosterusers "
% " where username='", Username, "' "
% " and jid='", SJID, "';"
% "insert into rosterusers("
% " username, jid, nick, "
% " subscription, ask, "
% " server, subscribe, type) "
% " values ", ItemVals, ";"
% "delete from rostergroups "
% " where username='", Username, "' "
% " and jid='", SJID, "';"
% % TODO
% "commit"])
%end
end;
process_item_set_t(_LUser, _) ->
process_item_set_t(_LUser, _LServer, _) ->
ok.
process_item_attrs_ws(Item, [{Attr, Val} | Attrs]) ->
@ -659,7 +732,7 @@ process_item_attrs_ws(Item, []) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
get_jid_info(_, User, JID) ->
get_jid_info(_, User, Server, JID) ->
% TODO
% LUser = jlib:nodeprep(User),
% LJID = jlib:jid_tolower(JID),
@ -681,7 +754,7 @@ get_jid_info(_, User, JID) ->
% end
% end
% end.
{none, []}.
{none, []}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

View File

@ -69,7 +69,7 @@ start(Host, Opts) ->
?MODULE, process_local_iq, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_VCARD,
?MODULE, process_sm_iq, IQDisc),
catch mod_disco:register_sm_feature(?NS_VCARD),
catch mod_disco:register_sm_feature(Host, ?NS_VCARD),
Hosts = gen_mod:get_hosts(Opts, "vjud."),
Search = gen_mod:get_opt(search, Opts, true),
register(gen_mod:get_module_proc(Host, ?PROCNAME),

View File

@ -13,8 +13,8 @@
-behaviour(gen_server).
%% External exports
-export([start/0, start_link/0,
sql_query/1,
-export([start/1, start_link/1,
sql_query/2,
escape/1]).
%% gen_server callbacks
@ -30,14 +30,14 @@
%%%----------------------------------------------------------------------
%%% API
%%%----------------------------------------------------------------------
start() ->
gen_server:start(ejabberd_odbc, [], []).
start(Host) ->
gen_server:start(ejabberd_odbc, [Host], []).
start_link() ->
gen_server:start_link(ejabberd_odbc, [], []).
start_link(Host) ->
gen_server:start_link(ejabberd_odbc, [Host], []).
sql_query(Query) ->
gen_server:call(ejabberd_odbc_sup:get_random_pid(),
sql_query(Host, Query) ->
gen_server:call(ejabberd_odbc_sup:get_random_pid(Host),
{sql_query, Query}, 60000).
escape(S) ->
@ -67,8 +67,9 @@ escape(S) ->
%% ignore |
%% {stop, Reason}
%%----------------------------------------------------------------------
init([]) ->
{ok, Ref} = odbc:connect(ejabberd_config:get_local_option(odbc_server),
init([Host]) ->
{ok, Ref} = odbc:connect(ejabberd_config:get_local_option(
{odbc_server, Host}),
[{scrollable_cursors, off}]),
{ok, #state{odbc_ref = Ref}}.

View File

@ -10,37 +10,39 @@
-author('alexey@sevcom.net').
-vsn('$Revision$ ').
-export([start_link/0,
-export([start_link/1,
init/1,
get_pids/0,
get_random_pid/0
get_pids/1,
get_random_pid/1
]).
-include("ejabberd.hrl").
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
start_link(Host) ->
supervisor:start_link({local, gen_mod:get_module_proc(Host, ?MODULE)},
?MODULE, [Host]).
init(_) ->
init([Host]) ->
% TODO
N = 10,
{ok, {{one_for_one, 10, 1},
lists:map(
fun(I) ->
{I,
{ejabberd_odbc, start_link, []},
{ejabberd_odbc, start_link, [Host]},
transient,
brutal_kill,
worker,
[?MODULE]}
end, lists:seq(1, N))}}.
get_pids() ->
get_pids(Host) ->
Proc = gen_mod:get_module_proc(Host, ?MODULE),
[Child ||
{_Id, Child, _Type, _Modules} <- supervisor:which_children(?MODULE),
{_Id, Child, _Type, _Modules} <- supervisor:which_children(Proc),
Child /= undefined].
get_random_pid() ->
Pids = get_pids(),
get_random_pid(Host) ->
Pids = get_pids(Host),
lists:nth(erlang:phash(now(), length(Pids)), Pids).