Big #jid to binary() conversion.

Internal tables (ejabberd_router, ejabberd_sm, ejabberd_hooks, mod_last, mod_roster) use binary() as storage.
Basic test using the ODBC backend.

SVN Revision: 1770
This commit is contained in:
Pablo Polvorin 2009-01-03 15:15:38 +00:00
parent 1a44fe29b4
commit 4827db4f56
44 changed files with 1129 additions and 881 deletions

View File

@ -1,3 +1,29 @@
2009-01-03 Pablo Polvorin <pablo.polvorin@process-one.net>
* src/mod_pubsub_node_default.erl: Fix typo
* src/mod_vcard.erl, src/mod_vcard_ldap.erl,src/ ejabberd_hooks.erl,
mod_muc/mod_muc_room.erl, src/mod_muc/mod_muc.erl,
src/mod_muc/mod_muc_log.erl, src/mod_shared_roster.erl,
src/ejabberd_auth_odbc.erl, src/mod_offline_odbc.erl,
src/ejabberd_system_monitor.erl, src/ejabberd_s2s_in.erl,
src/mod_configure.erl, src/ejabberd_receiver.erl, src/mod_irc/mod_irc.erl,
src/ejabberd_sm.erl, src/mod_privacy_odbc.erl, src/ejabberd_c2s.erl,
src/mod_announce.erl, src/ejabberd_local.erl, src/mod_privacy.erl,
src/ejabberd_auth_internal.erl, src/mod_adhoc.erl, src/mod_echo.erl,
src/jlib.erl, src/mod_vcard_odbc.erl, src/ejabberd_s2s.erl,
src/mod_stats.erl, src/ejabberd_router.erl, src/mod_last.erl,
src/mod_private.erl, src/mod_roster.erl, src/ejabberd_service.erl,
src/mod_disco.erl, src/mod_private_odbc.erl, src/mod_service_log.erl,
src/mod_configure2.erl, src/mod_roster_odbc.erl, src/mod_offline.erl,
src/mod_register.erl, src/mod_version.erl, src/mod_caps.erl,
src/mod_last_odbc.erl: Use exmpp API to access JID fields. Keep
#jid fields in binary format when possible. Change all 'user' and
'server' arguments in all hooks to binary. Change internal tables of
ejabberd_sm, ejabberd_router, ejabberd_hooks, mod_last, mod_roster
to use binary() storage.
2009-01-03 Christophe Romain <christophe.romain@process-one.net>
* src/mod_pubsub/mod_pubsub.erl: deliver notification depending on

View File

@ -261,7 +261,9 @@ remove_user(User, Server) ->
mnesia:delete({passwd, US})
end,
mnesia:transaction(F),
ejabberd_hooks:run(remove_user, LServer, [User, Server])
ejabberd_hooks:run(remove_user,
list_to_binary(LServer),
[list_to_binary(User), list_to_binary(Server)])
catch
_ ->
ok
@ -285,7 +287,9 @@ remove_user(User, Server, Password) ->
end,
case mnesia:transaction(F) of
{atomic, ok} ->
ejabberd_hooks:run(remove_user, LServer, [User, Server]),
ejabberd_hooks:run(remove_user,
list_to_binary(LServer),
[list_to_binary(User), list_to_binary(Server)]),
ok;
{atomic, Res} ->
Res;

View File

@ -231,8 +231,8 @@ remove_user(User, Server) ->
Username = ejabberd_odbc:escape(LUser),
LServer = exmpp_stringprep:nameprep(Server),
catch odbc_queries:del_user(LServer, Username),
ejabberd_hooks:run(remove_user, exmpp_stringprep:nameprep(Server),
[User, Server])
ejabberd_hooks:run(remove_user, list_to_binary(LServer),
[list_to_binary(User), list_to_binary(Server)])
catch
_ ->
error
@ -249,8 +249,8 @@ remove_user(User, Server, Password) ->
LServer, Username, Pass),
case Result of
{selected, ["password"], [{Password}]} ->
ejabberd_hooks:run(remove_user, exmpp_stringprep:nameprep(Server),
[User, Server]),
ejabberd_hooks:run(remove_user, list_to_binary(LServer),
[list_to_binary(User), list_to_binary(Server)]),
ok;
{selected, ["password"], []} ->
not_exists;

View File

@ -37,7 +37,8 @@
send_element/2,
socket_type/0,
get_presence/1,
get_subscribed/1]).
get_subscribed/1,
get_subscribed_and_online/1]).
%% gen_fsm callbacks
-export([init/1,
@ -54,6 +55,9 @@
handle_info/3,
terminate/3]).
-export([get_state/1]).
-include_lib("exmpp/include/exmpp.hrl").
-include("ejabberd.hrl").
@ -78,12 +82,13 @@
tls_options = [],
authenticated = false,
jid,
user = undefined, server = ?MYNAME, resource = undefined,
user = undefined, server = list_to_binary(?MYNAME), resource = undefined,
sid,
pres_t = ?SETS:new(),
pres_f = ?SETS:new(),
pres_a = ?SETS:new(),
pres_i = ?SETS:new(),
pres_available = ?DICT:new(),
pres_last, pres_pri,
pres_timestamp,
pres_invis = false,
@ -98,7 +103,7 @@
-ifdef(DBGFSM).
-define(FSMOPTS, [{debug, [trace]}]).
-else.
-define(FSMOPTS, []).
-define(FSMOPTS, [{spawn_opt,[{fullsweep_after,10}]}]).
-endif.
%% Module start with or without supervisor:
@ -142,6 +147,11 @@ socket_type() ->
get_presence(FsmRef) ->
gen_fsm:sync_send_all_state_event(FsmRef, {get_presence}, 1000).
%%TODO: for debug only
get_state(FsmRef) ->
gen_fsm:sync_send_all_state_event(FsmRef, get_state, 1000).
%%%----------------------------------------------------------------------
%%% Callback functions from gen_fsm
%%%----------------------------------------------------------------------
@ -170,7 +180,6 @@ init([{SockMod, Socket}, Opts]) ->
TLSOpts = lists:filter(fun({certfile, _}) -> true;
(_) -> false
end, Opts),
Zlib = lists:member(zlib, Opts) andalso (not StartTLSRequired),
IP = peerip(SockMod, Socket),
%% Check if IP is blacklisted:
case is_ip_blacklisted(IP) of
@ -203,8 +212,14 @@ init([{SockMod, Socket}, Opts]) ->
end.
%% Return list of all available resources of contacts,
%% in form [{JID, Caps}].
get_subscribed(FsmRef) ->
gen_fsm:sync_send_all_state_event(FsmRef, get_subscribed, 1000).
gen_fsm:sync_send_all_state_event(
FsmRef, get_subscribed, 1000).
get_subscribed_and_online(FsmRef) ->
gen_fsm:sync_send_all_state_event(
FsmRef, get_subscribed_and_online, 1000).
%%----------------------------------------------------------------------
%% Func: StateName/2
@ -226,6 +241,7 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
?NS_XMPP ->
Server = exmpp_stringprep:nameprep(
exmpp_stream:get_receiving_entity(Opening)),
ServerB = list_to_binary(Server),
case lists:member(Server, ?MYHOSTS) of
true ->
Lang = exmpp_stream:get_lang(Opening),
@ -275,7 +291,7 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
end,
Other_Feats = ejabberd_hooks:run_fold(
c2s_stream_features,
Server,
ServerB,
[], []),
send_element(StateData,
exmpp_stream:features(
@ -285,7 +301,7 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
Other_Feats)),
fsm_next_state(wait_for_feature_request,
StateData#state{
server = Server,
server = ServerB,
sasl_state = SASLState,
lang = Lang});
_ ->
@ -299,7 +315,7 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
])),
fsm_next_state(wait_for_bind,
StateData#state{
server = Server,
server = ServerB,
lang = Lang});
_ ->
send_element(
@ -307,7 +323,7 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
exmpp_stream:features([])),
fsm_next_state(wait_for_session,
StateData#state{
server = Server,
server = ServerB,
lang = Lang})
end
end;
@ -324,7 +340,7 @@ wait_for_stream({xmlstreamstart, #xmlel{ns = NS} = Opening}, StateData) ->
send_element(StateData, Header),
fsm_next_state(wait_for_auth,
StateData#state{
server = Server,
server = ServerB,
lang = Lang})
end
end;
@ -368,10 +384,11 @@ wait_for_stream(closed, StateData) ->
wait_for_auth({xmlstreamelement, El}, StateData) ->
ServerString = binary_to_list(StateData#state.server),
case is_auth_packet(El) of
{auth, _ID, get, {_U, _, _, _}} ->
Fields = case ejabberd_auth:plain_password_required(
StateData#state.server) of
ServerString) of
false -> both;
true -> plain
end,
@ -386,11 +403,12 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
{auth, _ID, set, {U, P, D, R}} ->
try
JID = exmpp_jid:make_jid(U, StateData#state.server, R),
case acl:match_rule(StateData#state.server,
UBinary = exmpp_jid:lnode(JID),
case acl:match_rule(ServerString,
StateData#state.access, JID) of
allow ->
case ejabberd_auth:check_password_with_authmodule(
U, StateData#state.server, P,
U, ServerString, P,
StateData#state.streamid, D) of
{true, AuthModule} ->
?INFO_MSG(
@ -402,7 +420,7 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
Info = [{ip, StateData#state.ip}, {conn, Conn},
{auth_module, AuthModule}],
ejabberd_sm:open_session(
SID, U, StateData#state.server, R, Info),
SID, exmpp_jid:make_jid(U, StateData#state.server, R), Info),
Res = exmpp_server_legacy_auth:success(El),
send_element(StateData, Res),
change_shaper(StateData, JID),
@ -410,18 +428,20 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
roster_get_subscription_lists,
StateData#state.server,
{[], []},
[U, StateData#state.server]),
[UBinary, StateData#state.server]),
LJID = jlib:short_prepd_bare_jid(JID),
Fs1 = [LJID | Fs],
Ts1 = [LJID | Ts],
PrivList = ejabberd_hooks:run_fold(
privacy_get_user_list, StateData#state.server,
#userlist{},
[U, StateData#state.server]),
[UBinary, StateData#state.server]),
fsm_next_state(session_established,
StateData#state{
user = U,
resource = R,
sasl_state = 'undefined',
%not used anymore, let the GC work.
user = list_to_binary(U),
resource = list_to_binary(R),
jid = JID,
sid = SID,
conn = Conn,
@ -504,7 +524,7 @@ wait_for_feature_request({xmlstreamelement, #xmlel{ns = NS, name = Name} = El},
StateData#state{
streamid = new_id(),
authenticated = true,
user = U });
user = list_to_binary(U) });
{continue, ServerOut, NewSASLState} ->
send_element(StateData,
exmpp_server_sasl:challenge(ServerOut)),
@ -528,8 +548,9 @@ wait_for_feature_request({xmlstreamelement, #xmlel{ns = NS, name = Name} = El},
{?NS_TLS, 'starttls'} when TLS == true,
TLSEnabled == false,
SockMod == gen_tcp ->
ServerString = binary_to_list(StateData#state.server),
TLSOpts = case ejabberd_config:get_local_option(
{domain_certfile, StateData#state.server}) of
{domain_certfile, ServerString}) of
undefined ->
StateData#state.tls_options;
CertFile ->
@ -619,7 +640,7 @@ wait_for_sasl_response({xmlstreamelement, #xmlel{ns = NS, name = Name} = El},
streamid = new_id(),
authenticated = true,
auth_module = AuthModule,
user = U});
user = list_to_binary(U)});
{continue, ServerOut, NewSASLState} ->
send_element(StateData,
exmpp_server_sasl:challenge(ServerOut)),
@ -662,18 +683,17 @@ wait_for_sasl_response(closed, StateData) ->
wait_for_bind({xmlstreamelement, El}, StateData) ->
try
U = StateData#state.user,
R = case exmpp_server_binding:wished_resource(El) of
undefined ->
lists:concat([randoms:get_string() | tuple_to_list(now())]);
Resource ->
Resource
end,
JID = exmpp_jid:make_jid(U, StateData#state.server, R),
JID = exmpp_jid:make_jid(StateData#state.user, StateData#state.server, R),
Res = exmpp_server_binding:bind(El, JID),
send_element(StateData, Res),
fsm_next_state(wait_for_session,
StateData#state{resource = R, jid = JID})
StateData#state{resource = exmpp_jid:resource(JID), jid = JID})
catch
throw:{stringprep, resourceprep, _, _} ->
Err = exmpp_server_binding:error(El, 'bad-request'),
@ -702,11 +722,10 @@ wait_for_bind(closed, StateData) ->
wait_for_session({xmlstreamelement, El}, StateData) ->
try
U = StateData#state.user,
R = StateData#state.resource,
ServerString = binary_to_list(StateData#state.server),
JID = StateData#state.jid,
true = exmpp_server_session:want_establishment(El),
case acl:match_rule(StateData#state.server,
case acl:match_rule(ServerString,
StateData#state.access, JID) of
allow ->
?INFO_MSG("(~w) Opened session for ~s",
@ -717,7 +736,7 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
Info = [{ip, StateData#state.ip}, {conn, Conn},
{auth_module, StateData#state.auth_module}],
ejabberd_sm:open_session(
SID, U, StateData#state.server, R, Info),
SID, JID, Info),
Res = exmpp_server_session:establish(El),
send_element(StateData, Res),
change_shaper(StateData, JID),
@ -725,7 +744,7 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
roster_get_subscription_lists,
StateData#state.server,
{[], []},
[U, StateData#state.server]),
[StateData#state.user, StateData#state.server]),
LJID = jlib:short_prepd_bare_jid(JID),
Fs1 = [LJID | Fs],
Ts1 = [LJID | Ts],
@ -733,9 +752,11 @@ wait_for_session({xmlstreamelement, El}, StateData) ->
ejabberd_hooks:run_fold(
privacy_get_user_list, StateData#state.server,
#userlist{},
[U, StateData#state.server]),
[StateData#state.user, StateData#state.server]),
fsm_next_state(session_established,
StateData#state{
sasl_state = 'undefined',
%not used anymore, let the GC work.
sid = SID,
conn = Conn,
pres_f = ?SETS:from_list(Fs1),
@ -773,15 +794,13 @@ wait_for_session(closed, StateData) ->
session_established({xmlstreamelement, El}, StateData) ->
FromJID = StateData#state.jid,
% Check 'from' attribute in stanza RFC 3920 Section 9.1.2
case check_from(El, FromJID) of
'invalid-from' ->
send_element(StateData, exmpp_stream:error('invalid-from')),
send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
_NewEl ->
session_established2(El, StateData)
case check_from(El, StateData#state.jid) of
'invalid-from' ->
send_element(StateData, exmpp_stream:error('invalid-from')),
send_element(StateData, exmpp_stream:closing()),
{stop, normal, StateData};
_ ->
session_established2(El, StateData)
end;
%% We hibernate the process to reduce memory consumption after a
@ -810,11 +829,13 @@ session_established2(El, StateData) ->
try
User = StateData#state.user,
Server = StateData#state.server,
% TODO: check 'from' attribute in stanza
FromJID = StateData#state.jid,
To = exmpp_stanza:get_recipient(El),
ToJID = case To of
undefined ->
exmpp_jid:make_bare_jid(User, Server);
exmpp_jid:jid_to_bare_jid(StateData#state.jid);
_ ->
exmpp_jid:list_to_jid(To)
end,
@ -839,10 +860,10 @@ session_established2(El, StateData) ->
user_send_packet,
Server,
[FromJID, ToJID, PresenceEl]),
case ToJID of
#jid{node = User,
domain = Server,
resource = undefined} ->
case {exmpp_jid:node(ToJID),
exmpp_jid:domain(ToJID),
exmpp_jid:resource(ToJID)} of
{User, Server,undefined} ->
?DEBUG("presence_update(~p,~n\t~p,~n\t~p)",
[FromJID, PresenceEl, StateData]),
presence_update(FromJID, PresenceEl,
@ -894,6 +915,7 @@ session_established2(El, StateData) ->
fsm_next_state(session_established, StateData)
end.
%%----------------------------------------------------------------------
%% Func: StateName/3
%% Returns: {next_state, NextStateName, NextStateData} |
@ -925,8 +947,12 @@ handle_event(_Event, StateName, StateData) ->
%% {stop, Reason, NewStateData} |
%% {stop, Reason, Reply, NewStateData}
%%----------------------------------------------------------------------
%TODO: for debug only
handle_sync_event(get_state,_From,StateName,StateData) ->
{reply,{StateName, StateData}, StateName, StateData};
handle_sync_event({get_presence}, _From, StateName, StateData) ->
User = StateData#state.user,
User = binary_to_list(StateData#state.user),
PresLast = StateData#state.pres_last,
Show = case PresLast of
@ -937,14 +963,35 @@ handle_sync_event({get_presence}, _From, StateName, StateData) ->
undefined -> "";
_ -> exmpp_presence:get_status(PresLast)
end,
Resource = StateData#state.resource,
Resource = binary_to_list(StateData#state.resource),
Reply = {User, Resource, atom_to_list(Show), Status},
fsm_reply(Reply, StateName, StateData);
handle_sync_event(get_subscribed, _From, StateName, StateData) ->
Subscribed = ?SETS:to_list(StateData#state.pres_f),
{reply, Subscribed, StateName, StateData};
Subscribed = StateData#state.pres_f,
Online = StateData#state.pres_available,
Pred = fun({U, S, _} = User, _Caps) ->
?SETS:is_element({U, S, undefined},
Subscribed) orelse
?SETS:is_element(User, Subscribed)
end,
SubscribedAndOnline = ?DICT:filter(Pred, Online),
SubscribedWithCaps = ?SETS:fold(fun(User, Acc) ->
[{User, undefined}|Acc]
end, ?DICT:to_list(SubscribedAndOnline), Subscribed),
{reply, SubscribedWithCaps, StateName, StateData};
handle_sync_event(get_subscribed_and_online, _From, StateName, StateData) ->
Subscribed = StateData#state.pres_f,
Online = StateData#state.pres_available,
Pred = fun({U, S, _R} = User, _Caps) ->
?SETS:is_element({U, S, undefined},
Subscribed) orelse
?SETS:is_element(User, Subscribed)
end,
SubscribedAndOnline = ?DICT:filter(Pred, Online),
{reply, ?DICT:to_list(SubscribedAndOnline), StateName, StateData};
handle_sync_event(_Event, _From, StateName, StateData) ->
Reply = ok,
@ -1036,39 +1083,44 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
LFrom = jlib:short_prepd_jid(From),
LBFrom = jlib:short_prepd_bare_jid(From),
%% Note contact availability
case exmpp_presence:get_type(Packet) of
'unavailable' ->
mod_caps:clear_caps(From);
_ ->
Caps = mod_caps:read_caps(Packet#xmlel.children),
mod_caps:note_caps(StateData#state.server, From, Caps)
end,
Els = Packet#xmlel.children,
Caps = mod_caps:read_caps(Els),
ServerString = binary_to_list(StateData#state.server),
mod_caps:note_caps(ServerString, From, Caps),
NewAvailable = case exmpp_presence:get_type(Packet) of
'unavailable' ->
?DICT:erase(LFrom, StateData#state.pres_available);
_ ->
%?DICT:store(LFrom, Caps, StateData#state.pres_available)
StateData#state.pres_available
end,
NewStateData = StateData#state{pres_available = NewAvailable},
case ?SETS:is_element(
LFrom, StateData#state.pres_a) orelse
LFrom, NewStateData#state.pres_a) orelse
?SETS:is_element(
LBFrom, StateData#state.pres_a) of
LBFrom, NewStateData#state.pres_a) of
true ->
{true, Attrs, StateData};
{true, Attrs, NewStateData};
false ->
case ?SETS:is_element(
LFrom, StateData#state.pres_f) of
LFrom, NewStateData#state.pres_f) of
true ->
A = ?SETS:add_element(
LFrom,
StateData#state.pres_a),
NewStateData#state.pres_a),
{true, Attrs,
StateData#state{pres_a = A}};
NewStateData#state{pres_a = A}};
false ->
case ?SETS:is_element(
LBFrom, StateData#state.pres_f) of
LBFrom, NewStateData#state.pres_f) of
true ->
A = ?SETS:add_element(
LBFrom,
StateData#state.pres_a),
NewStateData#state.pres_a),
{true, Attrs,
StateData#state{pres_a = A}};
NewStateData#state{pres_a = A}};
false ->
{true, Attrs, StateData}
{true, Attrs, NewStateData}
end
end
end;
@ -1080,7 +1132,9 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
?DEBUG("broadcast~n~p~n", [Packet#xmlel.children]),
case Packet#xmlel.children of
[{item, {U, S, R} = _IJIDShort, ISubscription}] ->
IJID = exmpp_jid:make_jid(U, S, R),
IJID = exmpp_jid:make_jid(U,
S,
R),
{false, Attrs,
roster_change(IJID, ISubscription,
StateData)};
@ -1108,7 +1162,7 @@ handle_info({route, From, To, Packet}, StateName, StateData) ->
true ->
case exmpp_iq:get_request(Packet) of
#xmlel{ns = ?NS_VCARD} ->
Host = StateData#state.server,
Host = binary_to_list(StateData#state.server),
case ets:lookup(sm_iqtable, {?NS_VCARD, Host}) of
[{_, Module, Function, Opts}] ->
gen_iq_handler:handle(Host, Module, Function, Opts,
@ -1186,6 +1240,7 @@ handle_info(Info, StateName, StateData) ->
%% Returns: any
%%----------------------------------------------------------------------
terminate(_Reason, StateName, StateData) ->
%%TODO: resource could be 'undefined' if terminate before bind?
case StateName of
session_established ->
case StateData#state.authenticated of
@ -1199,9 +1254,7 @@ terminate(_Reason, StateName, StateData) ->
"Replaced by new connection"),
ejabberd_sm:close_session_unset_presence(
StateData#state.sid,
StateData#state.user,
StateData#state.server,
StateData#state.resource,
StateData#state.jid,
"Replaced by new connection"),
presence_broadcast(
StateData, From, StateData#state.pres_a, Packet1),
@ -1219,17 +1272,13 @@ terminate(_Reason, StateName, StateData) ->
pres_i = EmptySet,
pres_invis = false} ->
ejabberd_sm:close_session(StateData#state.sid,
StateData#state.user,
StateData#state.server,
StateData#state.resource);
StateData#state.jid);
_ ->
From = StateData#state.jid,
Packet = exmpp_presence:unavailable(),
ejabberd_sm:close_session_unset_presence(
StateData#state.sid,
StateData#state.user,
StateData#state.server,
StateData#state.resource,
StateData#state.jid,
""),
presence_broadcast(
StateData, From, StateData#state.pres_a, Packet),
@ -1248,7 +1297,7 @@ terminate(_Reason, StateName, StateData) ->
%%%----------------------------------------------------------------------
change_shaper(StateData, JID) ->
Shaper = acl:match_rule(StateData#state.server,
Shaper = acl:match_rule(binary_to_list(StateData#state.server),
StateData#state.shaper, JID),
(StateData#state.sockmod):change_shaper(StateData#state.socket, Shaper).
@ -1257,9 +1306,9 @@ send_text(StateData, Text) ->
(StateData#state.sockmod):send(StateData#state.socket, Text).
send_element(StateData, #xmlel{ns = ?NS_XMPP, name = 'stream'} = El) ->
send_text(StateData, exmpp_stream:to_list(El));
send_text(StateData, exmpp_stream:to_iolist(El));
send_element(StateData, El) ->
send_text(StateData, exmpp_stanza:to_list(El)).
send_text(StateData, exmpp_stanza:to_iolist(El)).
new_id() ->
@ -1372,9 +1421,7 @@ presence_update(From, Packet, StateData) ->
Info = [{ip, StateData#state.ip}, {conn, StateData#state.conn},
{auth_module, StateData#state.auth_module}],
ejabberd_sm:unset_presence(StateData#state.sid,
StateData#state.user,
StateData#state.server,
StateData#state.resource,
StateData#state.jid,
Status,
Info),
presence_broadcast(StateData, From, StateData#state.pres_a, Packet),
@ -1476,8 +1523,6 @@ presence_update(From, Packet, StateData) ->
presence_track(From, To, Packet, StateData) ->
LTo = jlib:short_prepd_jid(To),
User = StateData#state.user,
Server = StateData#state.server,
BFrom = exmpp_jid:jid_to_bare_jid(From),
case exmpp_presence:get_type(Packet) of
'unavailable' ->
@ -1494,26 +1539,26 @@ presence_track(From, To, Packet, StateData) ->
pres_a = A};
'subscribe' ->
ejabberd_hooks:run(roster_out_subscription,
Server,
[User, Server, To, subscribe]),
StateData#state.server,
[StateData#state.user, StateData#state.server, To, subscribe]),
ejabberd_router:route(BFrom, To, Packet),
StateData;
'subscribed' ->
ejabberd_hooks:run(roster_out_subscription,
Server,
[User, Server, To, subscribed]),
StateData#state.server,
[StateData#state.user, StateData#state.server, To, subscribed]),
ejabberd_router:route(BFrom, To, Packet),
StateData;
'unsubscribe' ->
ejabberd_hooks:run(roster_out_subscription,
Server,
[User, Server, To, unsubscribe]),
StateData#state.server,
[StateData#state.user, StateData#state.server, To, unsubscribe]),
ejabberd_router:route(BFrom, To, Packet),
StateData;
'unsubscribed' ->
ejabberd_hooks:run(roster_out_subscription,
Server,
[User, Server, To, unsubscribed]),
StateData#state.server,
[StateData#state.user, StateData#state.server, To, unsubscribed]),
ejabberd_router:route(BFrom, To, Packet),
StateData;
'error' ->
@ -1718,9 +1763,7 @@ update_priority(Priority, Packet, StateData) ->
Info = [{ip, StateData#state.ip}, {conn, StateData#state.conn},
{auth_module, StateData#state.auth_module}],
ejabberd_sm:set_presence(StateData#state.sid,
StateData#state.user,
StateData#state.server,
StateData#state.resource,
StateData#state.jid,
Priority,
Packet,
Info).
@ -1732,7 +1775,7 @@ process_privacy_iq(From, To,
case Type of
get ->
R = ejabberd_hooks:run_fold(
privacy_iq_get, StateData#state.server,
privacy_iq_get, StateData#state.server ,
{error, ?ERR_FEATURE_NOT_IMPLEMENTED(IQ_NS)},
[From, To, IQ_Rec, StateData#state.privacy_list]),
{R, StateData};
@ -1761,22 +1804,23 @@ process_privacy_iq(From, To,
NewStateData.
resend_offline_messages(#state{user = User,
server = Server,
resend_offline_messages(#state{user = UserB,
server = ServerB,
privacy_list = PrivList} = StateData) ->
case ejabberd_hooks:run_fold(resend_offline_messages_hook,
Server,
StateData#state.server,
[],
[User, Server]) of
[UserB, ServerB]) of
Rs when list(Rs) ->
lists:foreach(
fun({route,
From, To, Packet}) ->
Pass = case ejabberd_hooks:run_fold(
privacy_check_packet, Server,
privacy_check_packet, StateData#state.server,
allow,
[User,
Server,
[StateData#state.user,
StateData#state.server,
PrivList,
{From, To, Packet},
in]) of
@ -1799,13 +1843,13 @@ resend_offline_messages(#state{user = User,
end, Rs)
end.
resend_subscription_requests(#state{user = User,
server = Server} = StateData) ->
resend_subscription_requests(#state{user = UserB,
server = ServerB} = StateData) ->
PendingSubscriptions = ejabberd_hooks:run_fold(
resend_subscription_requests_hook,
Server,
StateData#state.server,
[],
[User, Server]),
[UserB, ServerB]),
lists:foreach(fun(XMLPacket) ->
send_element(StateData,
XMLPacket)
@ -1813,6 +1857,7 @@ resend_subscription_requests(#state{user = User,
PendingSubscriptions).
process_unauthenticated_stanza(StateData, El) when ?IS_IQ(El) ->
ServerString = binary_to_list(StateData#state.server),
case exmpp_iq:get_kind(El) of
request ->
IQ_Rec = exmpp_iq:xmlel_to_iq(El),
@ -1828,7 +1873,7 @@ process_unauthenticated_stanza(StateData, El) when ?IS_IQ(El) ->
ResIQ = exmpp_iq:error_without_original(El,
'service-unavailable'),
Res1 = exmpp_stanza:set_sender(ResIQ,
exmpp_jid:make_bare_jid(StateData#state.server)),
exmpp_jid:make_bare_jid(ServerString)),
Res2 = exmpp_stanza:remove_recipient(Res1),
send_element(StateData, Res2);
_ ->

View File

@ -61,19 +61,21 @@ start_link() ->
add(Hook, Module, Function, Seq) ->
add(Hook, global, Module, Function, Seq).
add(Hook, Host, Module, Function, Seq) ->
add(Hook, Host, Module, Function, Seq)
when is_binary(Host) orelse is_atom(Host) ->
gen_server:call(ejabberd_hooks, {add, Hook, Host, Module, Function, Seq}).
delete(Hook, Module, Function, Seq) ->
delete(Hook, global, Module, Function, Seq).
delete(Hook, Host, Module, Function, Seq) ->
delete(Hook, Host, Module, Function, Seq)
when is_binary(Host) orelse is_atom(Host) ->
gen_server:call(ejabberd_hooks, {delete, Hook, Host, Module, Function, Seq}).
run(Hook, Args) ->
run(Hook, global, Args).
run(Hook, Host, Args) ->
run(Hook, Host, Args) when is_binary(Host) orelse is_atom(Host) ->
case ets:lookup(hooks, {Hook, Host}) of
[{_, Ls}] ->
run1(Ls, Hook, Args);
@ -84,7 +86,7 @@ run(Hook, Host, Args) ->
run_fold(Hook, Val, Args) ->
run_fold(Hook, global, Val, Args).
run_fold(Hook, Host, Val, Args) ->
run_fold(Hook, Host, Val, Args) when is_binary(Host) orelse is_atom(Host) ->
case ets:lookup(hooks, {Hook, Host}) of
[{_, Ls}] ->
run_fold1(Ls, Hook, Val, Args);

View File

@ -76,7 +76,7 @@ start_link() ->
process_iq(From, To, Packet) ->
case exmpp_iq:xmlel_to_iq(Packet) of
#iq{kind = request, ns = XMLNS} = IQ_Rec ->
Host = To#jid.ldomain,
Host = exmpp_jid:ldomain_as_list(To),
case ets:lookup(?IQTABLE, {XMLNS, Host}) of
[{_, Module, Function}] ->
ResIQ = Module:Function(From, To, IQ_Rec),
@ -182,7 +182,7 @@ init([]) ->
lists:foreach(
fun(Host) ->
ejabberd_router:register_route(Host, {apply, ?MODULE, route}),
ejabberd_hooks:add(local_send_to_resource_hook, Host,
ejabberd_hooks:add(local_send_to_resource_hook, list_to_binary(Host),
?MODULE, bounce_resource_packet, 100)
end, ?MYHOSTS),
catch ets:new(?IQTABLE, [named_table, public]),
@ -302,10 +302,13 @@ code_change(_OldVsn, State, _Extra) ->
do_route(From, To, Packet) ->
?DEBUG("local route~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
[From, To, Packet, 8]),
LNode = exmpp_jid:lnode(To),
LResource = exmpp_jid:lresource(To),
if
To#jid.lnode /= undefined ->
LNode /= undefined ->
ejabberd_sm:route(From, To, Packet);
To#jid.lresource == undefined ->
LResource == undefined ->
case Packet of
_ when ?IS_IQ(Packet) ->
process_iq(From, To, Packet);
@ -322,7 +325,7 @@ do_route(From, To, Packet) ->
"result" -> ok;
_ ->
ejabberd_hooks:run(local_send_to_resource_hook,
To#jid.ldomain,
exmpp_jid:ldomain(To),
[From, To, Packet])
end
end.

View File

@ -134,13 +134,14 @@ init([Socket, SockMod, Shaper, MaxStanzaSize]) ->
%%--------------------------------------------------------------------
handle_call({starttls, TLSSocket}, _From,
#state{xml_stream_state = XMLStreamState} = State) ->
NewXMLStreamState = exmpp_xmlstream:reset(XMLStreamState),
NewXMLStreamState = do_reset_stream(XMLStreamState),
NewState = State#state{socket = TLSSocket,
sock_mod = tls,
xml_stream_state = NewXMLStreamState},
case tls:recv_data(TLSSocket, "") of
{ok, TLSData} ->
{reply, ok, process_data(TLSData, NewState), ?HIBERNATE_TIMEOUT};
{NextState, Hib} = process_data(TLSData, NewState),
{reply, ok, NextState, Hib};
{error, _Reason} ->
{stop, normal, ok, NewState}
end;
@ -152,7 +153,8 @@ handle_call({compress, ZlibSocket}, _From,
xml_stream_state = NewXMLStreamState},
case ejabberd_zlib:recv_data(ZlibSocket, "") of
{ok, ZlibData} ->
{reply, ok, process_data(ZlibData, NewState), ?HIBERNATE_TIMEOUT};
{NextState, Hib} = process_data(ZlibData, NewState),
{reply, ok, NextState, Hib};
{error, _Reason} ->
{stop, normal, ok, NewState}
end;
@ -164,7 +166,10 @@ handle_call(reset_stream, _From,
?HIBERNATE_TIMEOUT};
handle_call({become_controller, C2SPid}, _From, State) ->
Parser = exmpp_xml:start_parser([
names_as_atom,
{names_as_atom, true},
{check_nss, xmpp},
{check_elems, xmpp},
{check_attrs, xmpp},
{max_size, State#state.max_stanza_size}
]),
XMLStreamState = exmpp_xmlstream:start(
@ -208,21 +213,22 @@ handle_info({Tag, _TCPSocket, Data},
tls ->
case tls:recv_data(Socket, Data) of
{ok, TLSData} ->
{noreply, process_data(TLSData, State),
?HIBERNATE_TIMEOUT};
{NextState, Hib} = process_data(TLSData, State),
{noreply, NextState, Hib};
{error, _Reason} ->
{stop, normal, State}
end;
ejabberd_zlib ->
case ejabberd_zlib:recv_data(Socket, Data) of
{ok, ZlibData} ->
{noreply, process_data(ZlibData, State),
?HIBERNATE_TIMEOUT};
{NextState, Hib} = process_data(ZlibData, State),
{noreply, NextState, Hib};
{error, _Reason} ->
{stop, normal, State}
end;
_ ->
{noreply, process_data(Data, State), ?HIBERNATE_TIMEOUT}
{NextState, Hib} = process_data(Data, State),
{noreply, NextState, Hib}
end;
handle_info({Tag, _TCPSocket}, State)
when (Tag == tcp_closed) or (Tag == ssl_closed) ->
@ -239,8 +245,8 @@ handle_info({timeout, _Ref, activate}, State) ->
activate_socket(State),
{noreply, State, ?HIBERNATE_TIMEOUT};
handle_info(timeout, State) ->
proc_lib:hibernate(gen_server, enter_loop, [?MODULE, [], State]),
{noreply, State, ?HIBERNATE_TIMEOUT};
{noreply, State, hibernate};
handle_info(_Info, State) ->
{noreply, State, ?HIBERNATE_TIMEOUT}.
@ -299,19 +305,30 @@ process_data(Data,
?DEBUG("Received XML on stream = ~p", [binary_to_list(Data)]),
{ok, XMLStreamState1} = exmpp_xmlstream:parse(XMLStreamState, Data),
{NewShaperState, Pause} = shaper:update(ShaperState, size(Data)),
if
C2SPid == undefined ->
ok;
Pause > 0 ->
erlang:start_timer(Pause, self(), activate);
true ->
activate_socket(State)
end,
State#state{xml_stream_state = XMLStreamState1,
shaper_state = NewShaperState}.
HibTimeout =
if
C2SPid == undefined ->
infinity;
Pause > 0 ->
erlang:start_timer(Pause, self(), activate),
hibernate;
true ->
activate_socket(State),
?HIBERNATE_TIMEOUT
end,
{State#state{xml_stream_state = XMLStreamState1,
shaper_state = NewShaperState}, HibTimeout}.
close_stream(undefined) ->
ok;
close_stream(XMLStreamState) ->
exmpp_xml:stop_parser(exmpp_xmlstream:get_parser(XMLStreamState)),
exmpp_xmlstream:stop(XMLStreamState).
do_reset_stream(undefined) ->
undefined;
do_reset_stream(XMLStreamState) ->
exmpp_xmlstream:reset(XMLStreamState).

View File

@ -89,27 +89,28 @@ register_route(Domain) ->
register_route(Domain, LocalHint) ->
try
LDomain = exmpp_stringprep:nameprep(Domain),
LDomainB = list_to_binary(LDomain),
Pid = self(),
case get_component_number(LDomain) of
undefined ->
F = fun() ->
mnesia:write(#route{domain = LDomain,
mnesia:write(#route{domain = LDomainB,
pid = Pid,
local_hint = LocalHint})
end,
mnesia:transaction(F);
N ->
F = fun() ->
case mnesia:read({route, LDomain}) of
case mnesia:read({route, LDomainB}) of
[] ->
mnesia:write(
#route{domain = LDomain,
#route{domain = LDomainB,
pid = Pid,
local_hint = 1}),
lists:foreach(
fun(I) ->
mnesia:write(
#route{domain = LDomain,
#route{domain = LDomainB,
pid = undefined,
local_hint = I})
end, lists:seq(2, N));
@ -118,7 +119,7 @@ register_route(Domain, LocalHint) ->
fun(#route{pid = undefined,
local_hint = I} = R) ->
mnesia:write(
#route{domain = LDomain,
#route{domain = LDomainB,
pid = Pid,
local_hint = I}),
mnesia:delete_object(R),
@ -143,12 +144,13 @@ register_routes(Domains) ->
unregister_route(Domain) ->
try
LDomain = exmpp_stringprep:nameprep(Domain),
LDomainB = list_to_binary(LDomain),
Pid = self(),
case get_component_number(LDomain) of
undefined ->
F = fun() ->
case mnesia:match_object(
#route{domain = LDomain,
#route{domain = LDomainB,
pid = Pid,
_ = '_'}) of
[R] ->
@ -160,13 +162,13 @@ unregister_route(Domain) ->
mnesia:transaction(F);
_ ->
F = fun() ->
case mnesia:match_object(#route{domain=LDomain,
case mnesia:match_object(#route{domain=LDomainB,
pid = Pid,
_ = '_'}) of
[R] ->
I = R#route.local_hint,
mnesia:write(
#route{domain = LDomain,
#route{domain = LDomainB,
pid = undefined,
local_hint = I}),
mnesia:delete_object(R);
@ -188,10 +190,14 @@ unregister_routes(Domains) ->
dirty_get_all_routes() ->
lists:usort(mnesia:dirty_all_keys(route)) -- ?MYHOSTS.
lists:usort(
lists:map(fun erlang:binary_to_list/1,
mnesia:dirty_all_keys(route))) -- ?MYHOSTS.
dirty_get_all_domains() ->
lists:usort(mnesia:dirty_all_keys(route)).
lists:usort(
lists:map(fun erlang:binary_to_list/1,
mnesia:dirty_all_keys(route))).
%%====================================================================
@ -326,8 +332,8 @@ do_route(OrigFrom, OrigTo, OrigPacket) ->
case ejabberd_hooks:run_fold(filter_packet,
{OrigFrom, OrigTo, OrigPacket}, []) of
{From, To, Packet} ->
LDstDomain = To#jid.ldomain,
case mnesia:dirty_read(route, LDstDomain) of
LDomain = exmpp_jid:ldomain(To),
case mnesia:dirty_read(route, LDomain) of
[] ->
ejabberd_s2s:route(From, To, Packet);
[R] ->
@ -346,6 +352,7 @@ do_route(OrigFrom, OrigTo, OrigPacket) ->
drop
end;
Rs ->
LDstDomain = exmpp_jid:ldomain_as_list(To),
Value = case ejabberd_config:get_local_option(
{domain_balancing, LDstDomain}) of
undefined -> now();

View File

@ -281,7 +281,7 @@ do_route(From, To, Packet) ->
?DEBUG("sending to process ~p~n", [Pid]),
NewPacket1 = exmpp_stanza:set_sender(Packet, From),
NewPacket = exmpp_stanza:set_recipient(NewPacket1, To),
#jid{ldomain = MyServer} = From,
MyServer = exmpp_jid:ldomain(From),
ejabberd_hooks:run(
s2s_send_packet,
MyServer,
@ -301,8 +301,8 @@ do_route(From, To, Packet) ->
end.
find_connection(From, To) ->
#jid{ldomain = MyServer} = From,
#jid{ldomain = Server} = To,
MyServer = exmpp_jid:ldomain_as_list(From),
Server = exmpp_jid:ldomain_as_list(To),
FromTo = {MyServer, Server},
MaxS2SConnectionsNumber = max_s2s_connections_number(FromTo),
MaxS2SConnectionsNumberPerNode =
@ -430,12 +430,12 @@ needed_connections_number(Ls, MaxS2SConnectionsNumber,
%% service.
%% --------------------------------------------------------------------
is_service(From, To) ->
LFromDomain = From#jid.ldomain,
LFromDomain = exmpp_jid:ldomain_as_list(From),
case ejabberd_config:get_local_option({route_subdomains, LFromDomain}) of
s2s -> % bypass RFC 3920 10.3
false;
_ ->
LDstDomain = To#jid.ldomain,
LDstDomain = exmpp_jid:ldomain_as_list(To),
P = fun(Domain) -> is_subdomain(LDstDomain, Domain) end,
lists:any(P, ?MYHOSTS)
end.

View File

@ -390,8 +390,8 @@ stream_established({xmlstreamelement, El}, StateData) ->
% This is handled by C2S and S2S send_element functions.
if
(To /= error) and (From /= error) ->
LFrom = From#jid.ldomain,
LTo = To#jid.ldomain,
LFrom = exmpp_jid:ldomain_as_list(From),
LTo = exmpp_jid:ldomain_as_list(To),
if
StateData#state.authenticated ->
case (LFrom == StateData#state.auth_domain)
@ -406,7 +406,7 @@ stream_established({xmlstreamelement, El}, StateData) ->
(Name == 'presence')) ->
ejabberd_hooks:run(
s2s_receive_packet,
LFrom,
exmpp_jid:ldomain(From),
[From, To, El]),
ejabberd_router:route(
From, To, El);
@ -426,7 +426,7 @@ stream_established({xmlstreamelement, El}, StateData) ->
(Name == 'presence')) ->
ejabberd_hooks:run(
s2s_receive_packet,
LFrom,
exmpp_jid:ldomain(From),
[From, To, El]),
ejabberd_router:route(
From, To, El);
@ -612,10 +612,11 @@ get_cert_domains(Cert) ->
end,
if
D /= error ->
case exmpp_jid:list_to_jid(D) of
#jid{lnode = undefined,
ldomain = LD,
lresource = undefined} ->
JID = exmpp_jid:list_to_jid(D),
case {exmpp_jid:lnode_as_list(JID),
exmpp_jid:ldomain_as_list(JID),
exmpp_jid:lresource_as_list(JID)} of
{undefined, LD, undefined} ->
[LD];
_ ->
[]
@ -647,11 +648,11 @@ get_cert_domains(Cert) ->
case 'XmppAddr':decode(
'XmppAddr', XmppAddr) of
{ok, D} when is_binary(D) ->
case exmpp_jid:list_to_jid(
binary_to_list(D)) of
#jid{lnode = undefined,
ldomain = LD,
lresource = undefined} ->
JID2 = exmpp_jid:list_to_jid(binary_to_list(D)),
case {exmpp_jid:lnode_as_list(JID2),
exmpp_jid:ldomain_as_list(JID2),
exmpp_jid:lresource_as_list(JID2)} of
{ undefined, LD, undefined} ->
case idna:domain_utf8_to_ascii(LD) of
false ->
[];
@ -665,10 +666,11 @@ get_cert_domains(Cert) ->
[]
end;
({dNSName, D}) when is_list(D) ->
case exmpp_jid:list_to_jid(D) of
#jid{lnode = undefined,
ldomain = LD,
lresource = undefined} ->
JID3 = exmpp_jid:list_to_jid(D),
case {exmpp_jid:lnode_as_list(JID3),
exmpp_jid:ldomain_as_list(JID3),
exmpp_jid:lresource_as_list(JID3)} of
{undefined, LD, undefined} ->
[LD];
_ ->
[]

View File

@ -231,14 +231,11 @@ stream_established({xmlstreamelement, El}, StateData) ->
%% The default is the standard behaviour in XEP-0114
_ ->
FromJID1 = exmpp_jib:string_to_jid(From),
case FromJID1 of
#jid{ldomain = Server} ->
case lists:member(Server, StateData#state.hosts) of
Server = exmpp_jid:ldomain_as_list(FromJID1),
case lists:member(Server, StateData#state.hosts) of
true -> FromJID1;
false -> error
end;
_ -> error
end
end
end,
To = exmpp_stanza:get_recipient(El),
ToJID = case To of

View File

@ -32,14 +32,14 @@
%% API
-export([start_link/0,
route/3,
open_session/5, close_session/4,
open_session/3, close_session/2,
check_in_subscription/6,
bounce_offline_message/3,
disconnect_removed_user/2,
get_user_resources/2,
set_presence/7,
unset_presence/6,
close_session_unset_presence/5,
set_presence/5,
unset_presence/4,
close_session_unset_presence/3,
dirty_get_sessions_list/0,
dirty_get_my_sessions_list/0,
get_vh_session_list/1,
@ -49,9 +49,9 @@
connected_users/0,
connected_users_number/0,
user_resources/2,
get_session_pid/3,
get_session_pid/1,
get_user_info/3,
get_user_ip/3
get_user_ip/1
]).
%% gen_server callbacks
@ -76,6 +76,9 @@
{?NS_XMPP, ?NS_XMPP_pfx}, {?NS_DIALBACK, ?NS_DIALBACK_pfx}
]).
-define(IS_BINARY_OR_UNDEF(X),
(is_binary(X) orelse X == 'undefined')).
%%====================================================================
%% API
%%====================================================================
@ -105,14 +108,13 @@ route(From, To, Packet) ->
ok
end.
open_session(SID, User, Server, Resource, Info) ->
set_session(SID, User, Server, Resource, undefined, Info),
check_for_sessions_to_replace(User, Server, Resource),
JID = exmpp_jid:make_jid(User, Server, Resource),
ejabberd_hooks:run(sm_register_connection_hook, JID#jid.ldomain,
open_session(SID, JID, Info) when ?IS_JID(JID) ->
set_session(SID, JID, undefined, Info),
check_for_sessions_to_replace(JID),
ejabberd_hooks:run(sm_register_connection_hook, exmpp_jid:ldomain(JID),
[SID, JID, Info]).
close_session(SID, User, Server, Resource) ->
close_session(SID, JID ) when ?IS_JID(JID)->
Info = case mnesia:dirty_read({session, SID}) of
[] -> [];
[#session{info=I}] -> I
@ -121,12 +123,12 @@ close_session(SID, User, Server, Resource) ->
mnesia:delete({session, SID})
end,
mnesia:sync_dirty(F),
JID = exmpp_jid:make_jid(User, Server, Resource),
ejabberd_hooks:run(sm_remove_connection_hook, JID#jid.ldomain,
ejabberd_hooks:run(sm_remove_connection_hook, exmpp_jid:ldomain(JID),
[SID, JID, Info]).
check_in_subscription(Acc, User, Server, _JID, _Type, _Reason) ->
case ejabberd_auth:is_user_exists(User, Server) of
check_in_subscription(Acc, User, Server, _JID, _Type, _Reason)
when is_binary(User), is_binary(Server)->
case ejabberd_auth:is_user_exists(binary_to_list(User), binary_to_list(Server)) of
true ->
Acc;
false ->
@ -139,27 +141,26 @@ bounce_offline_message(From, To, Packet) ->
stop.
disconnect_removed_user(User, Server) ->
ejabberd_sm:route(#jid{},
exmpp_jid:make_bare_jid(User, Server),
ejabberd_sm:route(exmpp_jid:make_jid(),
exmpp_jid:make_bare_jid(User,
Server),
#xmlel{name = 'broadcast',
children = [{exit, "User removed"}]}).
get_user_resources(User, Server) ->
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
US = {LUser, LServer},
get_user_resources(User, Server)
when is_binary(User), is_binary(Server) ->
US = {User, Server},
case catch mnesia:dirty_index_read(session, US, #session.us) of
{'EXIT', _Reason} ->
[];
Ss ->
[element(3, S#session.usr) || S <- clean_session_list(Ss)]
[binary_to_list(element(3, S#session.usr)) || S <- clean_session_list(Ss)]
end.
get_user_ip(User, Server, Resource) ->
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
LResource = exmpp_stringprep:resourceprep(Resource),
USR = {LUser, LServer, LResource},
get_user_ip(JID) when ?IS_JID(JID) ->
USR = {exmpp_jid:lnode(JID),
exmpp_jid:ldomain(JID),
exmpp_jid:lresource(JID)},
case mnesia:dirty_index_read(session, USR, #session.usr) of
[] ->
undefined;
@ -168,11 +169,16 @@ get_user_ip(User, Server, Resource) ->
proplists:get_value(ip, Session#session.info)
end.
get_user_info(User, Server, Resource) ->
get_user_info(User, Server, Resource)
when is_binary(User),
is_binary(Server),
is_binary(Resource) ->
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
LResource = exmpp_stringprep:resourceprep(Resource),
USR = {LUser, LServer, LResource},
USR = {list_to_binary(LUser),
list_to_binary(LServer),
list_to_binary(LResource)},
case mnesia:dirty_index_read(session, USR, #session.usr) of
[] ->
offline;
@ -184,26 +190,37 @@ get_user_info(User, Server, Resource) ->
[{node, Node}, {conn, Conn}, {ip, IP}]
end.
set_presence(SID, User, Server, Resource, Priority, Presence, Info) ->
set_session(SID, User, Server, Resource, Priority, Info),
ejabberd_hooks:run(set_presence_hook, exmpp_stringprep:nameprep(Server),
[User, Server, Resource, Presence]).
set_presence(SID, JID, Priority, Presence, Info) when ?IS_JID(JID) ->
set_session(SID, JID, Priority, Info),
ejabberd_hooks:run(set_presence_hook,
exmpp_jid:ldomain(JID),
[exmpp_jid:lnode(JID),
exmpp_jid:ldomain(JID),
exmpp_jid:lresource(JID),
Presence]).
unset_presence(SID, User, Server, Resource, Status, Info) ->
set_session(SID, User, Server, Resource, undefined, Info),
ejabberd_hooks:run(unset_presence_hook, exmpp_stringprep:nameprep(Server),
[User, Server, Resource, Status]).
unset_presence(SID, JID, Status, Info) when ?IS_JID(JID)->
set_session(SID, JID, undefined, Info),
ejabberd_hooks:run(unset_presence_hook,
exmpp_jid:ldomain(JID),
[exmpp_jid:lnode(JID),
exmpp_jid:ldomain(JID),
exmpp_jid:lresource(JID),
Status]).
close_session_unset_presence(SID, User, Server, Resource, Status) ->
close_session(SID, User, Server, Resource),
ejabberd_hooks:run(unset_presence_hook, exmpp_stringprep:nameprep(Server),
[User, Server, Resource, Status]).
close_session_unset_presence(SID, JID, Status) when ?IS_JID(JID) ->
close_session(SID, JID),
ejabberd_hooks:run(unset_presence_hook,
exmpp_jid:ldomain(JID),
[exmpp_jid:lnode(JID),
exmpp_jid:ldomain(JID),
exmpp_jid:lresource(JID),
Status]).
get_session_pid(User, Server, Resource) ->
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
LResource = exmpp_stringprep:resourceprep(Resource),
USR = {LUser, LServer, LResource},
get_session_pid(JID) when ?IS_JID(JID) ->
USR = {exmpp_jid:lnode(JID),
exmpp_jid:ldomain(JID),
exmpp_jid:lresource(JID)},
case catch mnesia:dirty_index_read(session, USR, #session.usr) of
[#session{sid = {_, Pid}}] -> Pid;
_ -> none
@ -223,8 +240,9 @@ dirty_get_my_sessions_list() ->
[{'==', {node, '$1'}, node()}],
['$_']}]).
get_vh_session_list(Server) ->
LServer = exmpp_stringprep:nameprep(Server),
get_vh_session_list(Server) when is_binary(Server) ->
LServer = list_to_binary(
exmpp_stringprep:nameprep(Server)),
mnesia:dirty_select(
session,
[{#session{usr = '$1', _ = '_'},
@ -264,11 +282,12 @@ init([]) ->
ets:new(sm_iqtable, [named_table]),
lists:foreach(
fun(Host) ->
ejabberd_hooks:add(roster_in_subscription, Host,
HostB = list_to_binary(Host),
ejabberd_hooks:add(roster_in_subscription, HostB,
ejabberd_sm, check_in_subscription, 20),
ejabberd_hooks:add(offline_message_hook, Host,
ejabberd_hooks:add(offline_message_hook, HostB,
ejabberd_sm, bounce_offline_message, 100),
ejabberd_hooks:add(remove_user, Host,
ejabberd_hooks:add(remove_user, HostB,
ejabberd_sm, disconnect_removed_user, 100)
end, ?MYHOSTS),
ejabberd_commands:register_commands(commands()),
@ -365,12 +384,11 @@ code_change(_OldVsn, State, _Extra) ->
%%% Internal functions
%%--------------------------------------------------------------------
set_session(SID, User, Server, Resource, Priority, Info) ->
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
LResource = exmpp_stringprep:resourceprep(Resource),
US = {LUser, LServer},
USR = {LUser, LServer, LResource},
set_session(SID, JID, Priority, Info) ->
US = {exmpp_jid:node(JID), exmpp_jid:ldomain(JID)},
USR = {exmpp_jid:node(JID),
exmpp_jid:ldomain(JID),
exmpp_jid:lresource(JID)},
F = fun() ->
mnesia:write(#session{sid = SID,
usr = USR,
@ -398,9 +416,7 @@ clean_table_from_bad_node(Node) ->
do_route(From, To, Packet) ->
?DEBUG("session manager~n\tfrom ~p~n\tto ~p~n\tpacket ~P~n",
[From, To, Packet, 8]),
#jid{node = User, domain = Server,
lnode = LUser, ldomain = LServer, lresource = LResource} = To,
case LResource of
case exmpp_jid:lresource(To) of
undefined ->
case Packet of
_ when ?IS_PRESENCE(Packet) ->
@ -410,37 +426,37 @@ do_route(From, To, Packet) ->
Reason = exmpp_presence:get_status(Packet),
{ejabberd_hooks:run_fold(
roster_in_subscription,
LServer,
exmpp_jid:ldomain(To),
false,
[User, Server, From, subscribe, Reason]),
[exmpp_jid:lnode(To), exmpp_jid:ldomain(To), From, subscribe, Reason]),
true};
'subscribed' ->
{ejabberd_hooks:run_fold(
roster_in_subscription,
LServer,
exmpp_jid:ldomain(To),
false,
[User, Server, From, subscribed, <<>>]),
[exmpp_jid:lnode(To), exmpp_jid:ldomain(To), From, subscribed, <<>>]),
true};
'unsubscribe' ->
{ejabberd_hooks:run_fold(
roster_in_subscription,
LServer,
exmpp_jid:ldomain(To),
false,
[User, Server, From, unsubscribe, <<>>]),
[exmpp_jid:lnode(To), exmpp_jid:ldomain(To), From, unsubscribe, <<>>]),
true};
'unsubscribed' ->
{ejabberd_hooks:run_fold(
roster_in_subscription,
LServer,
exmpp_jid:ldomain(To),
false,
[User, Server, From, unsubscribed, <<>>]),
[exmpp_jid:lnode(To), exmpp_jid:ldomain(To), From, unsubscribed, <<>>]),
true};
_ ->
{true, false}
end,
if Pass ->
PResources = get_user_present_resources(
LUser, LServer),
exmpp_jid:lnode(To), exmpp_jid:ldomain(To)),
lists:foreach(
fun({_, R}) ->
do_route(
@ -461,12 +477,15 @@ do_route(From, To, Packet) ->
do_route(From,
exmpp_jid:bare_jid_to_jid(To, R),
Packet)
end, get_user_resources(User, Server));
end, get_user_resources(exmpp_jid:lnode(To),
exmpp_jid:ldomain(To)));
_ ->
ok
end;
_ ->
USR = {LUser, LServer, LResource},
USR = {exmpp_jid:lnode(To),
exmpp_jid:ldomain(To),
exmpp_jid:lresource(To)},
case mnesia:dirty_index_read(session, USR, #session.usr) of
[] ->
case Packet of
@ -494,8 +513,8 @@ do_route(From, To, Packet) ->
end.
route_message(From, To, Packet) ->
LUser = To#jid.lnode,
LServer = To#jid.ldomain,
LUser = exmpp_jid:lnode(To),
LServer = exmpp_jid:ldomain(To),
PrioRes = get_user_present_resources(LUser, LServer),
case catch lists:max(PrioRes) of
{Priority, _R} when is_integer(Priority), Priority >= 0 ->
@ -503,8 +522,7 @@ route_message(From, To, Packet) ->
%% Route messages to all priority that equals the max, if
%% positive
fun({P, R}) when P == Priority ->
LResource = exmpp_stringprep:resourceprep(R),
USR = {LUser, LServer, LResource},
USR = {LUser, LServer, R},
case mnesia:dirty_index_read(session, USR, #session.usr) of
[] ->
ok; % Race condition
@ -528,10 +546,11 @@ route_message(From, To, Packet) ->
'headline' ->
bounce_offline_message(From, To, Packet);
_ ->
case ejabberd_auth:is_user_exists(LUser, LServer) of
case ejabberd_auth:is_user_exists(exmpp_jid:lnode_as_list(To),
exmpp_jid:ldomain_as_list(To)) of
true ->
ejabberd_hooks:run(offline_message_hook,
LServer,
exmpp_jid:ldomain(To),
[From, To, Packet]);
_ ->
Err = exmpp_stanza:reply_with_error(
@ -580,18 +599,16 @@ get_user_present_resources(LUser, LServer) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% On new session, check if some existing connections need to be replace
check_for_sessions_to_replace(User, Server, Resource) ->
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
LResource = exmpp_stringprep:resourceprep(Resource),
check_for_sessions_to_replace(JID) ->
%% TODO: Depending on how this is executed, there could be an unneeded
%% replacement for max_sessions. We need to check this at some point.
check_existing_resources(LUser, LServer, LResource),
check_max_sessions(LUser, LServer).
check_existing_resources(JID),
check_max_sessions(JID).
check_existing_resources(LUser, LServer, LResource) ->
USR = {LUser, LServer, LResource},
check_existing_resources(JID) ->
USR = {exmpp_jid:lnode(JID),
exmpp_jid:ldomain(JID),
exmpp_jid:lresource(JID)},
%% A connection exist with the same resource. We replace it:
SIDs = mnesia:dirty_select(
session,
@ -607,14 +624,16 @@ check_existing_resources(LUser, LServer, LResource) ->
end, SIDs)
end.
check_max_sessions(LUser, LServer) ->
check_max_sessions(JID) ->
%% If the max number of sessions for a given is reached, we replace the
%% first one
SIDs = mnesia:dirty_select(
session,
[{#session{sid = '$1', us = {LUser, LServer}, _ = '_'}, [],
[{#session{sid = '$1',
us = {exmpp_jid:lnode(JID), exmpp_jid:ldomain(JID)},
_ = '_'}, [],
['$1']}]),
MaxSessions = get_max_user_sessions(LUser, LServer),
MaxSessions = get_max_user_sessions(JID),
if
length(SIDs) =< MaxSessions ->
ok;
@ -628,9 +647,9 @@ check_max_sessions(LUser, LServer) ->
%% This option defines the max number of time a given users are allowed to
%% log in
%% Defaults to infinity
get_max_user_sessions(LUser, Host) ->
get_max_user_sessions(JID) ->
case acl:match_rule(
Host, max_user_sessions, exmpp_jid:make_bare_jid(LUser, Host)) of
exmpp_jid:ldomain_as_list(JID), max_user_sessions, exmpp_jid:jid_to_bare_jid(JID)) of
Max when is_integer(Max) -> Max;
infinity -> infinity;
_ -> ?MAX_USER_SESSIONS
@ -642,8 +661,8 @@ get_max_user_sessions(LUser, Host) ->
process_iq(From, To, Packet) ->
case exmpp_iq:xmlel_to_iq(Packet) of
#iq{kind = request, ns = XMLNS} = IQ_Rec ->
Host = To#jid.ldomain,
case ets:lookup(sm_iqtable, {XMLNS, Host}) of
LServer = exmpp_jid:ldomain_as_list(To),
case ets:lookup(sm_iqtable, {XMLNS, LServer}) of
[{_, Module, Function}] ->
ResIQ = Module:Function(From, To, IQ_Rec),
if
@ -654,8 +673,8 @@ process_iq(From, To, Packet) ->
ok
end;
[{_, Module, Function, Opts}] ->
gen_iq_handler:handle(Host, Module, Function, Opts,
From, To, IQ_Rec);
gen_iq_handler:handle(LServer,
Module, Function, Opts, From, To, IQ_Rec);
[] ->
Err = exmpp_iq:error(Packet, 'service-unavailable'),
ejabberd_router:route(To, From, Err)
@ -703,7 +722,8 @@ connected_users_number() ->
length(dirty_get_sessions_list()).
user_resources(User, Server) ->
Resources = get_user_resources(User, Server),
Resources = get_user_resources(list_to_binary(User),
list_to_binary(Server)),
lists:sort(Resources).

View File

@ -55,12 +55,13 @@ start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
process_command(From, To, Packet) ->
case To of
#jid{lnode = undefined, lresource = "watchdog"} ->
case {exmpp_jid:lnode(To), exmpp_jid:lresource(To) } of
{undefined, <<"watchdog">>} ->
case Packet#xmlel.name of
'message' ->
LFrom = jlib:short_prepd_bare_jid(From),
case lists:member(LFrom, get_admin_jids()) of
case lists:any(fun(J) ->
exmpp_jid:compare_jids(J,From)
end, get_admin_jids()) of
true ->
Body = exmpp_xml:get_path(
Packet, [{element, 'body'}, cdata_as_list]),
@ -95,7 +96,8 @@ init([]) ->
erlang:system_monitor(self(), [{large_heap, 1000000}]),
lists:foreach(
fun(Host) ->
ejabberd_hooks:add(local_send_to_resource_hook, Host,
ejabberd_hooks:add(local_send_to_resource_hook,
list_to_binary(Host),
?MODULE, process_command, 50)
end, ?MYHOSTS),
{ok, #state{}}.
@ -168,7 +170,7 @@ process_large_heap(Pid, Info) ->
"(~w) The process ~w is consuming too much memory: ~w.~n"
"~s",
[node(), Pid, Info, DetailedInfo]),
From = exmpp_jid:make_jid(undefined, Host, "watchdog"),
From = exmpp_jid:make_jid(undefined, Host, <<"watchdog">>),
lists:foreach(
fun(S) ->
try
@ -195,7 +197,9 @@ get_admin_jids() ->
fun(S) ->
try
JID = exmpp_jid:list_to_jid(S),
[jlib:short_prepd_jid(JID)]
[{exmpp_jid:lnode(JID),
exmpp_jid:ldomain(JID),
exmpp_jid:lresource(JID)}]
catch
_ ->
[]

View File

@ -37,7 +37,6 @@
encode_base64/1,
ip_to_list/1,
from_old_jid/1,
to_old_jid/1,
short_jid/1,
short_bare_jid/1,
short_prepd_jid/1,
@ -295,49 +294,26 @@ ip_to_list({A,B,C,D}) ->
%%
%% Empty fields are set to `undefined', not the empty string.
from_old_jid(#jid{node = Node, resource = Resource,
lnode = LNode, lresource = LResource} = JID) ->
{Node1, LNode1} = case Node of
"" -> {undefined, undefined};
_ -> {Node, LNode}
end,
{Resource1, LResource1} = case Resource of
"" -> {undefined, undefined};
_ -> {Resource, LResource}
end,
JID#jid{node = Node1, resource = Resource1,
lnode = LNode1, lresource = LResource1}.
%%TODO: this doesn't make sence!, it is still used?.
from_old_jid(JID) ->
Node = exmpp_jid:node(JID),
Resource = exmpp_jid:resource(JID),
Domain = exmpp_jid:domain(JID),
exmpp_jid:make_jid(Node,Domain,Resource).
%% @spec (JID) -> New_JID
%% JID = jid()
%% New_JID = jid()
%% @doc Convert a JID from its exmpp form to its ejabberd form.
%%
%% Empty fields are set to the empty string, not `undefined'.
to_old_jid(#jid{node = Node, resource = Resource,
lnode = LNode, lresource = LResource} = JID) ->
{Node1, LNode1} = case Node of
undefined -> {"", ""};
_ -> {Node, LNode}
end,
{Resource1, LResource1} = case Resource of
undefined -> {"", ""};
_ -> {Resource, LResource}
end,
JID#jid{node = Node1, resource = Resource1,
lnode = LNode1, lresource = LResource1}.
short_jid(JID) ->
{JID#jid.node, JID#jid.domain, JID#jid.resource}.
{exmpp_jid:node(JID), exmpp_jid:domain(JID), exmpp_jid:resource(JID)}.
short_bare_jid(JID) ->
Bare_JID = exmpp_jid:jid_to_bare_jid(JID),
{Bare_JID#jid.node, Bare_JID#jid.domain, Bare_JID#jid.resource}.
short_jid(exmpp_jid:jid_to_bare_jid(JID)).
short_prepd_jid(JID) ->
{JID#jid.lnode, JID#jid.ldomain, JID#jid.lresource}.
{exmpp_jid:lnode(JID),
exmpp_jid:ldomain(JID),
exmpp_jid:lresource(JID)}.
short_prepd_bare_jid(JID) ->
Bare_JID = exmpp_jid:jid_to_bare_jid(JID),
{Bare_JID#jid.lnode, Bare_JID#jid.ldomain, Bare_JID#jid.lresource}.
short_prepd_jid(exmpp_jid:jid_to_bare_jid(JID)).

View File

@ -48,6 +48,7 @@
-include("adhoc.hrl").
start(Host, Opts) ->
HostB = list_to_binary(Host),
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_ADHOC,
@ -55,31 +56,34 @@ start(Host, Opts) ->
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ADHOC,
?MODULE, process_sm_iq, IQDisc),
ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, get_local_identity, 99),
ejabberd_hooks:add(disco_local_features, Host, ?MODULE, get_local_features, 99),
ejabberd_hooks:add(disco_local_items, Host, ?MODULE, get_local_commands, 99),
ejabberd_hooks:add(disco_sm_identity, Host, ?MODULE, get_sm_identity, 99),
ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 99),
ejabberd_hooks:add(disco_sm_items, Host, ?MODULE, get_sm_commands, 99),
ejabberd_hooks:add(adhoc_local_items, Host, ?MODULE, ping_item, 100),
ejabberd_hooks:add(adhoc_local_commands, Host, ?MODULE, ping_command, 100).
ejabberd_hooks:add(disco_local_identity, HostB, ?MODULE, get_local_identity, 99),
ejabberd_hooks:add(disco_local_features, HostB, ?MODULE, get_local_features, 99),
ejabberd_hooks:add(disco_local_items, HostB, ?MODULE, get_local_commands, 99),
ejabberd_hooks:add(disco_sm_identity, HostB, ?MODULE, get_sm_identity, 99),
ejabberd_hooks:add(disco_sm_features, HostB, ?MODULE, get_sm_features, 99),
ejabberd_hooks:add(disco_sm_items, HostB, ?MODULE, get_sm_commands, 99),
ejabberd_hooks:add(adhoc_local_items, HostB, ?MODULE, ping_item, 100),
ejabberd_hooks:add(adhoc_local_commands, HostB, ?MODULE, ping_command, 100).
stop(Host) ->
ejabberd_hooks:delete(adhoc_local_commands, Host, ?MODULE, ping_command, 100),
ejabberd_hooks:delete(adhoc_local_items, Host, ?MODULE, ping_item, 100),
ejabberd_hooks:delete(disco_sm_items, Host, ?MODULE, get_sm_commands, 99),
ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 99),
ejabberd_hooks:delete(disco_sm_identity, Host, ?MODULE, get_sm_identity, 99),
ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, get_local_commands, 99),
ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_local_features, 99),
ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, get_local_identity, 99),
HostB = list_to_binary(Host),
ejabberd_hooks:delete(adhoc_local_commands, HostB, ?MODULE, ping_command, 100),
ejabberd_hooks:delete(adhoc_local_items, HostB, ?MODULE, ping_item, 100),
ejabberd_hooks:delete(disco_sm_items, HostB, ?MODULE, get_sm_commands, 99),
ejabberd_hooks:delete(disco_sm_features, HostB, ?MODULE, get_sm_features, 99),
ejabberd_hooks:delete(disco_sm_identity, HostB, ?MODULE, get_sm_identity, 99),
ejabberd_hooks:delete(disco_local_items, HostB, ?MODULE, get_local_commands, 99),
ejabberd_hooks:delete(disco_local_features, HostB, ?MODULE, get_local_features, 99),
ejabberd_hooks:delete(disco_local_identity, HostB, ?MODULE, get_local_identity, 99),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_ADHOC),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_ADHOC).
%-------------------------------------------------------------------------
get_local_commands(Acc, _From, #jid{domain = Server, ldomain = LServer} = _To, "", Lang) ->
get_local_commands(Acc, _From, To, "", Lang) ->
Server = exmpp_jid:domain_as_list(To),
LServer = exmpp_jid:ldomain_as_list(To),
Display = gen_mod:get_module_opt(LServer, ?MODULE, report_commands_node, false),
case Display of
false ->
@ -98,8 +102,8 @@ get_local_commands(Acc, _From, #jid{domain = Server, ldomain = LServer} = _To, "
{result, Items ++ Nodes}
end;
get_local_commands(_Acc, From, #jid{ldomain = LServer} = To, ?NS_ADHOC_s, Lang) ->
ejabberd_hooks:run_fold(adhoc_local_items, LServer, {result, []}, [From, To, Lang]);
get_local_commands(_Acc, From, To, ?NS_ADHOC_s, Lang) ->
ejabberd_hooks:run_fold(adhoc_local_items, exmpp_jid:ldomain(To), {result, []}, [From, To, Lang]);
get_local_commands(_Acc, _From, _To, "ping", _Lang) ->
{result, []};
@ -109,7 +113,8 @@ get_local_commands(Acc, _From, _To, _Node, _Lang) ->
%-------------------------------------------------------------------------
get_sm_commands(Acc, _From, #jid{ldomain = LServer} = To, "", Lang) ->
get_sm_commands(Acc, _From, To, "", Lang) ->
LServer = exmpp_jid:ldomain_as_list(To),
Display = gen_mod:get_module_opt(LServer, ?MODULE, report_commands_node, false),
case Display of
false ->
@ -128,8 +133,8 @@ get_sm_commands(Acc, _From, #jid{ldomain = LServer} = To, "", Lang) ->
{result, Items ++ Nodes}
end;
get_sm_commands(_Acc, From, #jid{ldomain = LServer} = To, ?NS_ADHOC_s, Lang) ->
ejabberd_hooks:run_fold(adhoc_sm_items, LServer, {result, []}, [From, To, Lang]);
get_sm_commands(_Acc, From, To, ?NS_ADHOC_s, Lang) ->
ejabberd_hooks:run_fold(adhoc_sm_items, exmpp_jid:ldomain(To), {result, []}, [From, To, Lang]);
get_sm_commands(Acc, _From, _To, _Node, _Lang) ->
Acc.
@ -216,8 +221,7 @@ process_adhoc_request(From, To, IQ_Rec, Hook) ->
{error, Error} ->
exmpp_iq:error(IQ_Rec, Error);
#adhoc_request{} = AdhocRequest ->
Host = To#jid.ldomain,
case ejabberd_hooks:run_fold(Hook, Host, empty,
case ejabberd_hooks:run_fold(Hook, exmpp_jid:ldomain(To), empty,
[From, To, AdhocRequest]) of
ignore ->
ignore;
@ -231,7 +235,8 @@ process_adhoc_request(From, To, IQ_Rec, Hook) ->
end.
ping_item(Acc, _From, #jid{domain = Server} = _To, Lang) ->
ping_item(Acc, _From, To, Lang) ->
Server = exmpp_jid:domain_as_list(To),
Items = case Acc of
{result, I} ->
I;

View File

@ -59,19 +59,20 @@
tokenize(Node) -> string:tokens(Node, "/#").
start(Host, _Opts) ->
HostB = list_to_binary(Host),
mnesia:create_table(motd, [{disc_copies, [node()]},
{attributes, record_info(fields, motd)}]),
mnesia:create_table(motd_users, [{disc_copies, [node()]},
{attributes, record_info(fields, motd_users)}]),
update_tables(),
ejabberd_hooks:add(local_send_to_resource_hook, Host,
ejabberd_hooks:add(local_send_to_resource_hook, HostB,
?MODULE, announce, 50),
ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, disco_identity, 50),
ejabberd_hooks:add(disco_local_features, Host, ?MODULE, disco_features, 50),
ejabberd_hooks:add(disco_local_items, Host, ?MODULE, disco_items, 50),
ejabberd_hooks:add(adhoc_local_items, Host, ?MODULE, announce_items, 50),
ejabberd_hooks:add(adhoc_local_commands, Host, ?MODULE, announce_commands, 50),
ejabberd_hooks:add(user_available_hook, Host,
ejabberd_hooks:add(disco_local_identity, HostB, ?MODULE, disco_identity, 50),
ejabberd_hooks:add(disco_local_features, HostB, ?MODULE, disco_features, 50),
ejabberd_hooks:add(disco_local_items, HostB, ?MODULE, disco_items, 50),
ejabberd_hooks:add(adhoc_local_items, HostB, ?MODULE, announce_items, 50),
ejabberd_hooks:add(adhoc_local_commands, HostB, ?MODULE, announce_commands, 50),
ejabberd_hooks:add(user_available_hook, HostB,
?MODULE, send_motd, 50),
register(gen_mod:get_module_proc(Host, ?PROCNAME),
proc_lib:spawn(?MODULE, init, [])).
@ -116,14 +117,15 @@ loop() ->
end.
stop(Host) ->
ejabberd_hooks:delete(adhoc_local_commands, Host, ?MODULE, announce_commands, 50),
ejabberd_hooks:delete(adhoc_local_items, Host, ?MODULE, announce_items, 50),
ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, disco_identity, 50),
ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, disco_features, 50),
ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, disco_items, 50),
ejabberd_hooks:delete(local_send_to_resource_hook, Host,
HostB = list_to_binary(Host),
ejabberd_hooks:delete(adhoc_local_commands, HostB, ?MODULE, announce_commands, 50),
ejabberd_hooks:delete(adhoc_local_items, HostB, ?MODULE, announce_items, 50),
ejabberd_hooks:delete(disco_local_identity, HostB, ?MODULE, disco_identity, 50),
ejabberd_hooks:delete(disco_local_features, HostB, ?MODULE, disco_features, 50),
ejabberd_hooks:delete(disco_local_items, HostB, ?MODULE, disco_items, 50),
ejabberd_hooks:delete(local_send_to_resource_hook, HostB,
?MODULE, announce, 50),
ejabberd_hooks:delete(user_available_hook, Host,
ejabberd_hooks:delete(user_available_hook, HostB,
?MODULE, send_motd, 50),
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
exit(whereis(Proc), stop),
@ -131,39 +133,39 @@ stop(Host) ->
%% Announcing via messages to a custom resource
announce(From, To, Packet) ->
case To of
#jid{lnode = undefined, lresource = Res} ->
case {exmpp_jid:lnode(To), exmpp_jid:lresource(To)} of
{undefined, Res} ->
Name = Packet#xmlel.name,
Proc = gen_mod:get_module_proc(To#jid.ldomain, ?PROCNAME),
Proc = gen_mod:get_module_proc(exmpp_jid:ldomain_as_list(To), ?PROCNAME),
case {Res, Name} of
{"announce/all", 'message'} ->
{<<"announce/all">>, 'message'} ->
Proc ! {announce_all, From, To, Packet},
stop;
{"announce/all-hosts/all", 'message'} ->
{<<"announce/all-hosts/all">>, 'message'} ->
Proc ! {announce_all_hosts_all, From, To, Packet},
stop;
{"announce/online", 'message'} ->
{<<"announce/online">>, 'message'} ->
Proc ! {announce_online, From, To, Packet},
stop;
{"announce/all-hosts/online", 'message'} ->
{<<"announce/all-hosts/online">>, 'message'} ->
Proc ! {announce_all_hosts_online, From, To, Packet},
stop;
{"announce/motd", 'message'} ->
{<<"announce/motd">>, 'message'} ->
Proc ! {announce_motd, From, To, Packet},
stop;
{"announce/all-hosts/motd", 'message'} ->
{<<"announce/all-hosts/motd">>, 'message'} ->
Proc ! {announce_all_hosts_motd, From, To, Packet},
stop;
{"announce/motd/update", 'message'} ->
{<<"announce/motd/update">>, 'message'} ->
Proc ! {announce_motd_update, From, To, Packet},
stop;
{"announce/all-hosts/motd/update", 'message'} ->
{<<"announce/all-hosts/motd/update">>, 'message'} ->
Proc ! {announce_all_hosts_motd_update, From, To, Packet},
stop;
{"announce/motd/delete", 'message'} ->
{<<"announce/motd/delete">>, 'message'} ->
Proc ! {announce_motd_delete, From, To, Packet},
stop;
{"announce/all-hosts/motd/delete", 'message'} ->
{<<"announce/all-hosts/motd/delete">>, 'message'} ->
Proc ! {announce_all_hosts_motd_delete, From, To, Packet},
stop;
_ ->
@ -218,8 +220,8 @@ disco_identity(Acc, _From, _To, Node, Lang) ->
{result, Feats}
end).
disco_features(Acc, From, #jid{ldomain = LServer} = _To,
"announce", _Lang) ->
disco_features(Acc, From, To, "announce", _Lang) ->
LServer = exmpp_jid:ldomain_as_list(To),
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
Acc;
@ -235,8 +237,8 @@ disco_features(Acc, From, #jid{ldomain = LServer} = _To,
end
end;
disco_features(Acc, From, #jid{ldomain = LServer} = _To,
Node, _Lang) ->
disco_features(Acc, From, To, Node, _Lang) ->
LServer = exmpp_jid:ldomain_as_list(To),
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
Acc;
@ -287,8 +289,10 @@ disco_features(Acc, From, #jid{ldomain = LServer} = _To,
{result, Items}
end).
disco_items(Acc, From, #jid{ldomain = LServer, domain = Server} = _To,
"", Lang) ->
disco_items(Acc, From, To, "", Lang) ->
LServer = exmpp_jid:ldomain_as_list(To),
Server = exmpp_jid:domain_as_list(To),
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
Acc;
@ -309,7 +313,8 @@ disco_items(Acc, From, #jid{ldomain = LServer, domain = Server} = _To,
end
end;
disco_items(Acc, From, #jid{ldomain = LServer} = To, "announce", Lang) ->
disco_items(Acc, From, To, "announce", Lang) ->
LServer = exmpp_jid:ldomain_as_list(To),
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
Acc;
@ -317,7 +322,8 @@ disco_items(Acc, From, #jid{ldomain = LServer} = To, "announce", Lang) ->
announce_items(Acc, From, To, Lang)
end;
disco_items(Acc, From, #jid{ldomain = LServer} = _To, Node, _Lang) ->
disco_items(Acc, From, To, Node, _Lang) ->
LServer = exmpp_jid:ldomain_as_list(To),
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
Acc;
@ -354,7 +360,9 @@ disco_items(Acc, From, #jid{ldomain = LServer} = _To, Node, _Lang) ->
%%-------------------------------------------------------------------------
announce_items(Acc, From, #jid{ldomain = LServer, domain = Server} = _To, Lang) ->
announce_items(Acc, From, To, Lang) ->
LServer = exmpp_jid:ldomain_as_list(To),
Server = exmpp_jid:domain_as_list(To),
Access1 = gen_mod:get_module_opt(LServer, ?MODULE, access, none),
Nodes1 = case acl:match_rule(LServer, Access1, From) of
allow ->
@ -399,8 +407,8 @@ commands_result(Allow, From, To, Request) ->
end.
announce_commands(Acc, From, #jid{ldomain = LServer} = To,
#adhoc_request{ node = Node} = Request) ->
announce_commands(Acc, From, To, #adhoc_request{ node = Node} = Request) ->
LServer = exmpp_jid:ldomain_as_list(To),
LNode = tokenize(Node),
F = fun() ->
Access = gen_mod:get_module_opt(global, ?MODULE, access, none),
@ -455,7 +463,7 @@ announce_commands(From, To,
#adhoc_response{status = canceled});
XData == false, ActionIsExecute ->
%% User requests form
Elements = generate_adhoc_form(Lang, Node, To#jid.ldomain),
Elements = generate_adhoc_form(Lang, Node, exmpp_jid:ldomain_as_list(To)),
adhoc:produce_response(
Request,
#adhoc_response{status = executing,
@ -529,11 +537,12 @@ join_lines([], Acc) ->
%% Remove last newline
lists:flatten(lists:reverse(tl(Acc))).
handle_adhoc_form(From, #jid{ldomain = LServer} = To,
handle_adhoc_form(From, To,
#adhoc_request{lang = Lang,
node = Node,
sessionid = SessionID},
Fields) ->
LServer = exmpp_jid:ldomain_as_list(To),
Confirm = case lists:keysearch("confirm", 1, Fields) of
{value, {"confirm", ["true"]}} ->
true;
@ -654,14 +663,14 @@ get_title(Lang, ?NS_ADMIN_s ++ "#delete-motd-allhosts") ->
%%-------------------------------------------------------------------------
announce_all(From, To, Packet) ->
Host = To#jid.ldomain,
Host = exmpp_jid:ldomain_as_list(To),
Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
case acl:match_rule(Host, Access, From) of
deny ->
Err = exmpp_stanza:reply_with_error(Packet, 'forbidden'),
ejabberd_router:route(To, From, Err);
allow ->
Local = exmpp_jid:make_jid(To#jid.domain),
Local = exmpp_jid:make_jid(exmpp_jid:domain(To)),
lists:foreach(
fun({User, Server}) ->
Dest = exmpp_jid:make_jid(User, Server),
@ -676,7 +685,7 @@ announce_all_hosts_all(From, To, Packet) ->
Err = exmpp_stanza:reply_with_error(Packet, 'forbidden'),
ejabberd_router:route(To, From, Err);
allow ->
Local = exmpp_jid:make_jid(To#jid.domain),
Local = exmpp_jid:make_jid(exmpp_jid:domain(To)),
lists:foreach(
fun({User, Server}) ->
Dest = exmpp_jid:make_jid(User, Server),
@ -685,15 +694,15 @@ announce_all_hosts_all(From, To, Packet) ->
end.
announce_online(From, To, Packet) ->
Host = To#jid.ldomain,
Host = exmpp_jid:ldomain_as_list(To),
Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
case acl:match_rule(Host, Access, From) of
deny ->
Err = exmpp_stanza:reply_with_error(Packet, 'forbidden'),
ejabberd_router:route(To, From, Err);
allow ->
announce_online1(ejabberd_sm:get_vh_session_list(Host),
To#jid.domain,
announce_online1(ejabberd_sm:get_vh_session_list(exmpp_jid:ldomain(To)),
exmpp_jid:domain_as_list(To),
Packet)
end.
@ -705,7 +714,7 @@ announce_all_hosts_online(From, To, Packet) ->
ejabberd_router:route(To, From, Err);
allow ->
announce_online1(ejabberd_sm:dirty_get_sessions_list(),
To#jid.domain,
exmpp_jid:domain_as_list(To),
Packet)
end.
@ -718,7 +727,7 @@ announce_online1(Sessions, Server, Packet) ->
end, Sessions).
announce_motd(From, To, Packet) ->
Host = To#jid.ldomain,
Host = exmpp_jid:ldomain_as_list(To),
Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
case acl:match_rule(Host, Access, From) of
deny ->
@ -741,7 +750,7 @@ announce_all_hosts_motd(From, To, Packet) ->
announce_motd(Host, Packet) ->
announce_motd_update(Host, Packet),
Sessions = ejabberd_sm:get_vh_session_list(Host),
Sessions = ejabberd_sm:get_vh_session_list(list_to_binary(Host)),
announce_online1(Sessions, Host, Packet),
F = fun() ->
lists:foreach(
@ -752,7 +761,7 @@ announce_motd(Host, Packet) ->
mnesia:transaction(F).
announce_motd_update(From, To, Packet) ->
Host = To#jid.ldomain,
Host = exmpp_jid:ldomain_as_list(To),
Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
case acl:match_rule(Host, Access, From) of
deny ->
@ -781,7 +790,7 @@ announce_motd_update(LServer, Packet) ->
mnesia:transaction(F).
announce_motd_delete(From, To, Packet) ->
Host = To#jid.ldomain,
Host = exmpp_jid:ldomain_as_list(To),
Access = gen_mod:get_module_opt(Host, ?MODULE, access, none),
case acl:match_rule(Host, Access, From) of
deny ->
@ -817,7 +826,9 @@ announce_motd_delete(LServer) ->
end,
mnesia:transaction(F).
send_motd(#jid{lnode = LUser, ldomain = LServer} = JID) ->
send_motd(JID) ->
LServer = exmpp_jid:ldomain_as_list(JID),
LUser = exmpp_jid:lnode_as_list(JID),
case catch mnesia:dirty_read({motd, LServer}) of
[#motd{packet = Packet}] ->
US = {LUser, LServer},
@ -825,7 +836,7 @@ send_motd(#jid{lnode = LUser, ldomain = LServer} = JID) ->
[#motd_users{}] ->
ok;
_ ->
Local = exmpp_jid:make_jid(LServer),
Local = exmpp_jid:make_jid(exmpp_jid:ldomain(JID)),
ejabberd_router:route(Local, JID, Packet),
F = fun() ->
mnesia:write(#motd_users{us = US})

View File

@ -87,7 +87,7 @@ read_caps([], Result) ->
%% get_caps reads user caps from database
get_caps({U, S, R}) ->
BJID = exmpp_jlib:jid_to_binary(U, S, R),
BJID = exmpp_jid:jid_to_binary(U, S, R),
case catch mnesia:dirty_read({user_caps, BJID}) of
[#user_caps{caps=Caps}] ->
Caps;
@ -97,8 +97,8 @@ get_caps({U, S, R}) ->
%% clear_caps removes user caps from database
clear_caps({U, S, R}) ->
BJID = exmpp_jlib:jid_to_binary(U, S, R),
BUID = exmpp_jlib:jid_to_binary(U, S),
BJID = exmpp_jid:jid_to_binary(U, S, R),
BUID = exmpp_jid:jid_to_binary(U, S),
catch mnesia:dirty_delete({user_caps, BJID}),
case catch mnesia:dirty_read({user_caps_default, BUID}) of
[#user_caps_default{resource=R}] ->
@ -109,7 +109,7 @@ clear_caps({U, S, R}) ->
%% give default user resource
get_user_resource(U, S) ->
BUID = exmpp_jlib:bare_jid_to_binary(U, S),
BUID = exmpp_jid:bare_jid_to_binary(U, S),
case catch mnesia:dirty_read({user_caps_default, BUID}) of
[#user_caps_default{resource=R}] ->
R;
@ -225,15 +225,18 @@ handle_cast({note_caps, From,
#state{host = Host, disco_requests = Requests} = State) ->
%% XXX: this leads to race conditions where ejabberd will send
%% lots of caps disco requests.
#jid{node = U, domain = S, resource = R} = From,
BJID = exmpp_jlib:jid_to_binary(From),
%#jid{node = U, domain = S, resource = R} = From,
U = exmpp_jid:lnode(From),
S = exmpp_jid:ldomain(From),
R = exmpp_jid:resource(From),
BJID = exmpp_jid:jid_to_binary(From),
mnesia:dirty_write(#user_caps{jid = BJID, caps = Caps}),
case ejabberd_sm:get_user_resources(U, S) of
[] ->
ok;
_ ->
% only store default resource of external contacts
BUID = exmpp_jlib:bare_jid_to_binary(From),
BUID = exmpp_jid:bare_jid_to_binary(From),
mnesia:dirty_write(#user_caps_default{uid = BUID, resource = R})
end,
SubNodes = [Version | Exts],
@ -340,7 +343,7 @@ handle_cast(visit_feature_queries, #state{feature_queries = FeatureQueries} = St
{noreply, State#state{feature_queries = NewFeatureQueries}}.
handle_disco_response(From, To, IQ_Rec) ->
#jid{ldomain = Host} = To,
Host = exmpp_jid:ldomain_as_list(To),
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
gen_server:cast(Proc, {disco_response, From, To, IQ_Rec}).

View File

@ -59,29 +59,31 @@
-define(NS_ADMIN_s, "http://jabber.org/protocol/admin").
start(Host, _Opts) ->
ejabberd_hooks:add(disco_local_items, Host, ?MODULE, get_local_items, 50),
ejabberd_hooks:add(disco_local_features, Host, ?MODULE, get_local_features, 50),
ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, get_local_identity, 50),
ejabberd_hooks:add(disco_sm_items, Host, ?MODULE, get_sm_items, 50),
ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
ejabberd_hooks:add(disco_sm_identity, Host, ?MODULE, get_sm_identity, 50),
ejabberd_hooks:add(adhoc_local_items, Host, ?MODULE, adhoc_local_items, 50),
ejabberd_hooks:add(adhoc_local_commands, Host, ?MODULE, adhoc_local_commands, 50),
ejabberd_hooks:add(adhoc_sm_items, Host, ?MODULE, adhoc_sm_items, 50),
ejabberd_hooks:add(adhoc_sm_commands, Host, ?MODULE, adhoc_sm_commands, 50),
HostB = list_to_binary(Host),
ejabberd_hooks:add(disco_local_items, HostB, ?MODULE, get_local_items, 50),
ejabberd_hooks:add(disco_local_features, HostB, ?MODULE, get_local_features, 50),
ejabberd_hooks:add(disco_local_identity, HostB, ?MODULE, get_local_identity, 50),
ejabberd_hooks:add(disco_sm_items, HostB, ?MODULE, get_sm_items, 50),
ejabberd_hooks:add(disco_sm_features, HostB, ?MODULE, get_sm_features, 50),
ejabberd_hooks:add(disco_sm_identity, HostB, ?MODULE, get_sm_identity, 50),
ejabberd_hooks:add(adhoc_local_items, HostB, ?MODULE, adhoc_local_items, 50),
ejabberd_hooks:add(adhoc_local_commands, HostB, ?MODULE, adhoc_local_commands, 50),
ejabberd_hooks:add(adhoc_sm_items, HostB, ?MODULE, adhoc_sm_items, 50),
ejabberd_hooks:add(adhoc_sm_commands, HostB, ?MODULE, adhoc_sm_commands, 50),
ok.
stop(Host) ->
ejabberd_hooks:delete(adhoc_sm_commands, Host, ?MODULE, adhoc_sm_commands, 50),
ejabberd_hooks:delete(adhoc_sm_items, Host, ?MODULE, adhoc_sm_items, 50),
ejabberd_hooks:delete(adhoc_local_commands, Host, ?MODULE, adhoc_local_commands, 50),
ejabberd_hooks:delete(adhoc_local_items, Host, ?MODULE, adhoc_local_items, 50),
ejabberd_hooks:delete(disco_sm_identity, Host, ?MODULE, get_sm_identity, 50),
ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
ejabberd_hooks:delete(disco_sm_items, Host, ?MODULE, get_sm_items, 50),
ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, get_local_identity, 50),
ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_local_features, 50),
ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, get_local_items, 50),
HostB = list_to_binary(Host),
ejabberd_hooks:delete(adhoc_sm_commands, HostB, ?MODULE, adhoc_sm_commands, 50),
ejabberd_hooks:delete(adhoc_sm_items, HostB, ?MODULE, adhoc_sm_items, 50),
ejabberd_hooks:delete(adhoc_local_commands, HostB, ?MODULE, adhoc_local_commands, 50),
ejabberd_hooks:delete(adhoc_local_items, HostB, ?MODULE, adhoc_local_items, 50),
ejabberd_hooks:delete(disco_sm_identity, HostB, ?MODULE, get_sm_identity, 50),
ejabberd_hooks:delete(disco_sm_features, HostB, ?MODULE, get_sm_features, 50),
ejabberd_hooks:delete(disco_sm_items, HostB, ?MODULE, get_sm_items, 50),
ejabberd_hooks:delete(disco_local_identity, HostB, ?MODULE, get_local_identity, 50),
ejabberd_hooks:delete(disco_local_features, HostB, ?MODULE, get_local_features, 50),
ejabberd_hooks:delete(disco_local_items, HostB, ?MODULE, get_local_items, 50),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_ADHOC),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_ADHOC).
@ -181,7 +183,8 @@ get_local_identity(Acc, _From, _To, Node, Lang) ->
{result, Feats}
end).
get_sm_features(Acc, From, #jid{ldomain = LServer} = _To, Node, _Lang) ->
get_sm_features(Acc, From, To, Node, _Lang) ->
LServer = exmpp_jid:ldomain_as_list(To),
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
Acc;
@ -195,7 +198,8 @@ get_sm_features(Acc, From, #jid{ldomain = LServer} = _To, Node, _Lang) ->
end
end.
get_local_features(Acc, From, #jid{ldomain = LServer} = _To, Node, _Lang) ->
get_local_features(Acc, From, To, Node, _Lang) ->
LServer = exmpp_jid:ldomain_as_list(To),
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
Acc;
@ -250,7 +254,8 @@ get_local_features(Acc, From, #jid{ldomain = LServer} = _To, Node, _Lang) ->
%%%-----------------------------------------------------------------------
adhoc_sm_items(Acc, From, #jid{ldomain = LServer} = To, Lang) ->
adhoc_sm_items(Acc, From, To, Lang) ->
LServer = exmpp_jid:ldomain_as_list(To),
case acl:match_rule(LServer, configure, From) of
allow ->
Items = case Acc of
@ -268,9 +273,8 @@ adhoc_sm_items(Acc, From, #jid{ldomain = LServer} = To, Lang) ->
%%%-----------------------------------------------------------------------
get_sm_items(Acc, From,
#jid{node = User, domain = Server, ldomain = LServer} = To,
Node, Lang) ->
get_sm_items(Acc, From, To, Node, Lang) ->
LServer = exmpp_jid:ldomain_as_list(To),
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
Acc;
@ -283,7 +287,7 @@ get_sm_items(Acc, From,
{allow, ""} ->
Nodes = [?NODEJID(To, "Configuration", "config"),
?NODEJID(To, "User Management", "user")],
{result, Items ++ Nodes ++ get_user_resources(User, Server)};
{result, Items ++ Nodes ++ get_user_resources(To)};
{allow, "config"} ->
{result, []};
{_, "config"} ->
@ -293,18 +297,23 @@ get_sm_items(Acc, From,
end
end.
get_user_resources(User, Server) ->
Rs = ejabberd_sm:get_user_resources(User, Server),
get_user_resources(BareJID) ->
Rs = ejabberd_sm:get_user_resources(exmpp_jid:lnode(BareJID),
exmpp_jid:ldomain(BareJID)),
lists:map(fun(R) ->
#xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs =
[#xmlattr{name = 'jid', value = exmpp_jid:jid_to_list(User, Server, R)},
#xmlattr{name = 'name', value = User}]}
[#xmlattr{name = 'jid',
value = exmpp_jid:jid_to_list(
exmpp_jid:bare_jid_to_jid(BareJID, R))},
#xmlattr{name = 'name',
value = exmpp_jid:lnode_as_list(BareJID)}]}
end, lists:sort(Rs)).
%%%-----------------------------------------------------------------------
adhoc_local_items(Acc, From, #jid{ldomain = LServer, domain = Server} = To,
Lang) ->
adhoc_local_items(Acc, From, To, Lang) ->
LServer = exmpp_jid:ldomain_as_list(To),
Server = exmpp_jid:domain_as_list(To),
case acl:match_rule(LServer, configure, From) of
allow ->
Items = case Acc of
@ -373,7 +382,8 @@ recursively_get_local_items(LServer, Node, Server, Lang) ->
end
end).
get_local_items(Acc, From, #jid{ldomain = LServer} = To, "", Lang) ->
get_local_items(Acc, From, To, "", Lang) ->
LServer = exmpp_jid:ldomain_as_list(To),
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
Acc;
@ -397,7 +407,8 @@ get_local_items(Acc, From, #jid{ldomain = LServer} = To, "", Lang) ->
end
end;
get_local_items(Acc, From, #jid{ldomain = LServer} = To, Node, Lang) ->
get_local_items(Acc, From, To, Node, Lang) ->
LServer = exmpp_jid:ldomain_as_list(To),
case gen_mod:is_loaded(LServer, mod_adhoc) of
false ->
Acc;
@ -584,7 +595,7 @@ get_local_items(_Host, _, _Server, _Lang) ->
get_online_vh_users(Host) ->
case catch ejabberd_sm:get_vh_session_list(Host) of
case catch ejabberd_sm:get_vh_session_list(list_to_binary(Host)) of
{'EXIT', _Reason} ->
[];
USRs ->
@ -716,8 +727,8 @@ get_stopped_nodes(_Lang) ->
adhoc_local_commands(From, To, Request)
end).
adhoc_local_commands(Acc, From, #jid{ldomain = LServer} = To,
#adhoc_request{node = Node} = Request) ->
adhoc_local_commands(Acc, From, To, #adhoc_request{node = Node} = Request) ->
LServer = exmpp_jid:ldomain_as_list(To),
LNode = tokenize(Node),
Allow = acl:match_rule(LServer, configure, From),
case LNode of
@ -741,12 +752,13 @@ adhoc_local_commands(Acc, From, #jid{ldomain = LServer} = To,
Acc
end.
adhoc_local_commands(From, #jid{ldomain = LServer} = _To,
adhoc_local_commands(From, To,
#adhoc_request{lang = Lang,
node = Node,
sessionid = SessionID,
action = Action,
xdata = XData} = Request) ->
LServer = exmpp_jid:ldomain_as_list(To),
LNode = tokenize(Node),
%% If the "action" attribute is not present, it is
%% understood as "execute". If there was no <actions/>
@ -1247,7 +1259,7 @@ get_form(Host, ?NS_ADMINL("get-registered-users-num"), Lang) ->
}]}]};
get_form(Host, ?NS_ADMINL("get-online-users-num"), Lang) ->
Num = io_lib:format("~p", [length(ejabberd_sm:get_vh_session_list(Host))]),
Num = io_lib:format("~p", [length(ejabberd_sm:get_vh_session_list(list_to_binary(Host)))]),
{result, completed,
[#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
[?HFIELD(),
@ -1535,8 +1547,8 @@ set_form(_From, _Host, ?NS_ADMINL("add-user"), _Lang, XData) ->
Password = get_value("password", XData),
Password = get_value("password-verify", XData),
AccountJID = exmpp_jid:list_to_jid(AccountString),
User = AccountJID#jid.lnode,
Server = AccountJID#jid.ldomain,
User = exmpp_jid:lnode_as_list(AccountJID),
Server = exmpp_jid:ldomain_as_list(AccountJID),
true = lists:member(Server, ?MYHOSTS),
ejabberd_auth:try_register(User, Server, Password),
{result, []};
@ -1547,9 +1559,8 @@ set_form(_From, _Host, ?NS_ADMINL("delete-user"), _Lang, XData) ->
ASL2 = lists:map(
fun(AccountString) ->
JID = exmpp_jid:list_to_jid(AccountString),
[_|_] = JID#jid.lnode,
User = JID#jid.lnode,
Server = JID#jid.ldomain,
User = [_|_] = exmpp_jid:lnode_as_list(JID),
Server = exmpp_jid:ldomain_as_list(JID),
true = ejabberd_auth:is_user_exists(User, Server),
{User, Server}
end,
@ -1560,11 +1571,10 @@ set_form(_From, _Host, ?NS_ADMINL("delete-user"), _Lang, XData) ->
set_form(_From, _Host, ?NS_ADMINL("end-user-session"), _Lang, XData) ->
AccountString = get_value("accountjid", XData),
JID = exmpp_jid:list_to_jid(AccountString),
[_|_] = JID#jid.lnode,
LUser = JID#jid.lnode,
LServer = JID#jid.ldomain,
LUser = [_|_] = exmpp_jid:lnode_as_list(JID),
LServer = exmpp_jid:ldomain_as_list(JID),
%% Code copied from ejabberd_sm.erl
case JID#jid.lresource of
case exmpp_jid:lresource_as_list(JID) of
undefined ->
SIDs = mnesia:dirty_select(session,
[{#session{sid = '$1', usr = {LUser, LServer, '_'}, _ = '_'}, [], ['$1']}]),
@ -1579,9 +1589,8 @@ set_form(_From, _Host, ?NS_ADMINL("end-user-session"), _Lang, XData) ->
set_form(_From, _Host, ?NS_ADMINL("get-user-password"), Lang, XData) ->
AccountString = get_value("accountjid", XData),
JID = exmpp_jid:list_to_jid(AccountString),
[_|_] = JID#jid.lnode,
User = JID#jid.lnode,
Server = JID#jid.ldomain,
User = [_|_] = exmpp_jid:lnode_as_list(JID),
Server = exmpp_jid:ldomain_as_list(JID),
Password = ejabberd_auth:get_password(User, Server),
true = is_list(Password),
{result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
@ -1594,9 +1603,8 @@ set_form(_From, _Host, ?NS_ADMINL("change-user-password"), _Lang, XData) ->
AccountString = get_value("accountjid", XData),
Password = get_value("password", XData),
JID = exmpp_jid:list_to_jid(AccountString),
[_|_] = JID#jid.lnode,
User = JID#jid.lnode,
Server = JID#jid.ldomain,
User = [_|_] = exmpp_jid:lnode_as_list(JID),
Server = exmpp_jid:ldomain_as_list(JID),
true = ejabberd_auth:is_user_exists(User, Server),
ejabberd_auth:set_password(User, Server, Password),
{result, []};
@ -1604,14 +1612,14 @@ set_form(_From, _Host, ?NS_ADMINL("change-user-password"), _Lang, XData) ->
set_form(_From, _Host, ?NS_ADMINL("get-user-lastlogin"), Lang, XData) ->
AccountString = get_value("accountjid", XData),
JID = exmpp_jid:list_to_jid(AccountString),
[_|_] = JID#jid.lnode,
User = JID#jid.lnode,
Server = JID#jid.ldomain,
User = [_|_] = exmpp_jid:lnode_as_list(JID),
Server = exmpp_jid:ldomain_as_list(JID),
%% Code copied from web/ejabberd_web_admin.erl
%% TODO: Update time format to XEP-0202: Entity Time
FLast =
case ejabberd_sm:get_user_resources(User, Server) of
case ejabberd_sm:get_user_resources(exmpp_jid:lnode(User),
exmpp_jid:ldomain(Server)) of
[] ->
_US = {User, Server},
case get_last_info(User, Server) of
@ -1641,15 +1649,19 @@ set_form(_From, _Host, ?NS_ADMINL("get-user-lastlogin"), Lang, XData) ->
set_form(_From, _Host, ?NS_ADMINL("user-stats"), Lang, XData) ->
AccountString = get_value("accountjid", XData),
JID = exmpp_jid:list_to_jid(AccountString),
[_|_] = JID#jid.lnode,
User = JID#jid.lnode,
Server = JID#jid.ldomain,
User = [_|_] = exmpp_jid:lnode_as_list(JID),
Server = exmpp_jid:ldomain_as_list(JID),
Resources = ejabberd_sm:get_user_resources(User, Server),
IPs1 = [ejabberd_sm:get_user_ip(User, Server, Resource) || Resource <- Resources],
Resources = ejabberd_sm:get_user_resources(exmpp_jid:lnode(JID),
exmpp_jid:ldomain(JID)),
IPs1 = [ejabberd_sm:get_user_ip(exmpp_jid:bare_jid_to_jid(JID,Resource))
|| Resource <- Resources],
IPs = [inet_parse:ntoa(IP)++":"++integer_to_list(Port) || {IP, Port} <- IPs1],
Items = ejabberd_hooks:run_fold(roster_get, Server, [], [{User, Server}]),
Items = ejabberd_hooks:run_fold(roster_get,
exmpp_jid:ldomain(JID),
[],
[{list_to_binary(User), list_to_binary(Server)}]),
Rostersize = integer_to_list(erlang:length(Items)),
{result, [#xmlel{ns = ?NS_DATA_FORMS, name = 'x', children =
@ -1729,12 +1741,14 @@ get_last_info(User, Server) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
adhoc_sm_commands(_Acc, From,
#jid{node = User, domain = Server, ldomain = LServer} = _To,
adhoc_sm_commands(_Acc, From, To,
#adhoc_request{lang = Lang,
node = "config",
action = Action,
xdata = XData} = Request) ->
User = exmpp_jid:node_as_list(To),
Server = exmpp_jid:domain_as_list(To),
LServer = exmpp_jid:ldomain_as_list(To),
case acl:match_rule(LServer, configure, From) of
deny ->
{error, 'forbidden'};

View File

@ -71,7 +71,7 @@ stop(Host) ->
process_local_iq(From, To, #iq{type = Type, payload = Request} = IQ_Rec) ->
case acl:match_rule(To#jid.ldomain, configure, From) of
case acl:match_rule(exmpp_jid:ldomain_as_list(To), configure, From) of
deny ->
exmpp_iq:error(IQ_Rec, 'not-allowed');
allow ->

View File

@ -54,6 +54,7 @@
-record(disco_publish, {owner_node, jid, name, node}).
start(Host, Opts) ->
HostB = list_to_binary(Host),
mnesia:create_table(disco_publish,
[{disc_only_copies, [node()]},
{attributes, record_info(fields, disco_publish)},
@ -84,23 +85,24 @@ start(Host, Opts) ->
ExtraDomains),
catch ets:new(disco_sm_features, [named_table, ordered_set, public]),
catch ets:new(disco_sm_nodes, [named_table, ordered_set, public]),
ejabberd_hooks:add(disco_local_items, Host, ?MODULE, get_local_services, 100),
ejabberd_hooks:add(disco_local_features, Host, ?MODULE, get_local_features, 100),
ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, get_local_identity, 100),
ejabberd_hooks:add(disco_sm_items, Host, ?MODULE, get_sm_items, 100),
ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 100),
ejabberd_hooks:add(disco_sm_identity, Host, ?MODULE, get_sm_identity, 100),
ejabberd_hooks:add(disco_sm_items, Host, ?MODULE, get_publish_items, 75),
ejabberd_hooks:add(disco_local_items, HostB, ?MODULE, get_local_services, 100),
ejabberd_hooks:add(disco_local_features, HostB, ?MODULE, get_local_features, 100),
ejabberd_hooks:add(disco_local_identity, HostB, ?MODULE, get_local_identity, 100),
ejabberd_hooks:add(disco_sm_items, HostB, ?MODULE, get_sm_items, 100),
ejabberd_hooks:add(disco_sm_features, HostB, ?MODULE, get_sm_features, 100),
ejabberd_hooks:add(disco_sm_identity, HostB, ?MODULE, get_sm_identity, 100),
ejabberd_hooks:add(disco_sm_items, HostB, ?MODULE, get_publish_items, 75),
ok.
stop(Host) ->
ejabberd_hooks:delete(disco_sm_items, Host, ?MODULE, get_publish_items, 75),
ejabberd_hooks:delete(disco_sm_identity, Host, ?MODULE, get_sm_identity, 100),
ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 100),
ejabberd_hooks:delete(disco_sm_items, Host, ?MODULE, get_sm_items, 100),
ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, get_local_identity, 100),
ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_local_features, 100),
ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, get_local_services, 100),
HostB = list_to_binary(Host),
ejabberd_hooks:delete(disco_sm_items, HostB, ?MODULE, get_publish_items, 75),
ejabberd_hooks:delete(disco_sm_identity, HostB, ?MODULE, get_sm_identity, 100),
ejabberd_hooks:delete(disco_sm_features, HostB, ?MODULE, get_sm_features, 100),
ejabberd_hooks:delete(disco_sm_items, HostB, ?MODULE, get_sm_items, 100),
ejabberd_hooks:delete(disco_local_identity, HostB, ?MODULE, get_local_identity, 100),
ejabberd_hooks:delete(disco_local_features, HostB, ?MODULE, get_local_features, 100),
ejabberd_hooks:delete(disco_local_items, HostB, ?MODULE, get_local_services, 100),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_ITEMS),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_DISCO_INFO),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_DISCO_ITEMS),
@ -128,11 +130,10 @@ unregister_extra_domain(Host, Domain) ->
process_local_iq_items(From, To, #iq{type = get, payload = SubEl,
lang = Lang} = IQ_Rec) ->
Host = To#jid.ldomain,
Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
case ejabberd_hooks:run_fold(disco_local_items,
Host,
exmpp_jid:ldomain(To),
empty,
[From, To, Node, Lang]) of
{result, Items} ->
@ -152,14 +153,13 @@ process_local_iq_items(_From, _To, #iq{type = set} = IQ_Rec) ->
process_local_iq_info(From, To, #iq{type = get, payload = SubEl,
lang = Lang} = IQ_Rec) ->
Host = To#jid.ldomain,
Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
Identity = ejabberd_hooks:run_fold(disco_local_identity,
Host,
exmpp_jid:ldomain(To),
[],
[From, To, Node, Lang]),
case ejabberd_hooks:run_fold(disco_local_features,
Host,
exmpp_jid:ldomain(To),
empty,
[From, To, Node, Lang]) of
{result, Features} ->
@ -196,7 +196,7 @@ get_local_features(Acc, _From, To, [], _Lang) ->
{result, Features} -> Features;
empty -> []
end,
Host = To#jid.ldomain,
Host = exmpp_jid:ldomain_as_list(To),
{result,
ets:select(disco_features, [{{{'_', Host}}, [], ['$_']}]) ++ Feats};
@ -237,7 +237,7 @@ get_local_services(Acc, _From, To, [], _Lang) ->
{result, Its} -> Its;
empty -> []
end,
Host = To#jid.ldomain,
Host = exmpp_jid:ldomain_as_list(To),
{result,
lists:usort(
lists:map(fun domain_to_xml/1,
@ -270,10 +270,9 @@ get_vh_services(Host) ->
process_sm_iq_items(From, To, #iq{type = get, payload = SubEl,
lang = Lang} = IQ_Rec) ->
Host = To#jid.ldomain,
Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
case ejabberd_hooks:run_fold(disco_sm_items,
Host,
exmpp_jid:ldomain(To),
empty,
[From, To, Node, Lang]) of
{result, Items} ->
@ -288,8 +287,10 @@ process_sm_iq_items(From, To, #iq{type = get, payload = SubEl,
exmpp_iq:error(IQ_Rec, Error)
end;
process_sm_iq_items(From, To, #iq{type = set, payload = SubEl} = IQ_Rec) ->
#jid{lnode = LTo, ldomain = ToServer} = To,
#jid{lnode = LFrom, ldomain = LServer} = From,
LTo = exmpp_jid:lnode_as_list(To),
ToServer = exmpp_jid:ldomain_as_list(To),
LFrom = exmpp_jid:lnode_as_list(From),
LServer = exmpp_jid:ldomain_as_list(From),
Self = (LTo == LFrom) andalso (ToServer == LServer),
Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
if
@ -310,16 +311,18 @@ process_sm_iq_items(From, To, #iq{type = set, payload = SubEl} = IQ_Rec) ->
get_sm_items({error, _Error} = Acc, _From, _To, _Node, _Lang) ->
Acc;
get_sm_items(Acc,
#jid{lnode = LFrom, ldomain = LSFrom},
#jid{node = User, domain = Server, lnode = LTo, ldomain = LSTo} = _To,
[], _Lang) ->
get_sm_items(Acc, From, To, [], _Lang) ->
LFrom = exmpp_jid:lnode_as_list(From),
LSFrom = exmpp_jid:ldomain_as_list(From),
LTo = exmpp_jid:lnode_as_list(To),
LSTo = exmpp_jid:ldomain_as_list(To),
Items = case Acc of
{result, Its} -> Its;
empty -> []
end,
Items1 = case {LFrom, LSFrom} of
{LTo, LSTo} -> get_user_resources(User, Server);
{LTo, LSTo} -> get_user_resources(To);
_ -> []
end,
{result, Items ++ Items1};
@ -328,8 +331,10 @@ get_sm_items({result, _} = Acc, _From, _To, _Node, _Lang) ->
Acc;
get_sm_items(empty, From, To, _Node, _Lang) ->
#jid{lnode = LFrom, ldomain = LSFrom} = From,
#jid{lnode = LTo, ldomain = LSTo} = To,
LFrom = exmpp_jid:lnode_as_list(From),
LSFrom = exmpp_jid:ldomain_as_list(From),
LTo = exmpp_jid:lnode_as_list(To),
LSTo = exmpp_jid:ldomain_as_list(To),
case {LFrom, LSFrom} of
{LTo, LSTo} ->
{error, 'item-not-found'};
@ -339,14 +344,13 @@ get_sm_items(empty, From, To, _Node, _Lang) ->
process_sm_iq_info(From, To, #iq{type = get, payload = SubEl,
lang = Lang} = IQ_Rec) ->
Host = To#jid.ldomain,
Node = exmpp_xml:get_attribute(SubEl, 'node', ""),
Identity = ejabberd_hooks:run_fold(disco_sm_identity,
Host,
exmpp_jid:ldomain(To),
[],
[From, To, Node, Lang]),
case ejabberd_hooks:run_fold(disco_sm_features,
Host,
exmpp_jid:ldomain(To),
empty,
[From, To, Node, Lang]) of
{result, Features} ->
@ -369,8 +373,10 @@ get_sm_identity(Acc, _From, _To, _Node, _Lang) ->
Acc.
get_sm_features(empty, From, To, _Node, _Lang) ->
#jid{lnode = LFrom, ldomain = LSFrom} = From,
#jid{lnode = LTo, ldomain = LSTo} = To,
LFrom = exmpp_jid:lnode_as_list(From),
LSFrom = exmpp_jid:ldomain_as_list(From),
LTo = exmpp_jid:lnode_as_list(To),
LSTo = exmpp_jid:ldomain_as_list(To),
case {LFrom, LSFrom} of
{LTo, LSTo} ->
{error, 'item-not-found'};
@ -383,21 +389,23 @@ get_sm_features(Acc, _From, _To, _Node, _Lang) ->
get_user_resources(User, Server) ->
Rs = ejabberd_sm:get_user_resources(User, Server),
get_user_resources(JID) ->
Rs = ejabberd_sm:get_user_resources(exmpp_jid:lnode(JID),
exmpp_jid:ldomain(JID)),
lists:map(fun(R) ->
#xmlel{ns = ?NS_DISCO_ITEMS, name = 'item', attrs = [
#xmlattr{name = 'jid', value =
exmpp_jid:jid_to_list(User, Server, R)},
#xmlattr{name = 'name', value = User}
exmpp_jid:jid_to_list(exmpp_jid:bare_jid_to_jid(JID, R))},
#xmlattr{name = 'name', value = exmpp_jid:lnode_as_list(JID)}
]}
end, lists:sort(Rs)).
get_publish_items(empty,
#jid{lnode = LFrom, ldomain = LSFrom},
#jid{lnode = LTo, ldomain = LSTo} = _To,
Node, _Lang) ->
get_publish_items(empty, From, To, Node, _Lang) ->
LFrom = exmpp_jid:lnode_as_list(From),
LSFrom = exmpp_jid:ldomain_as_list(From),
LTo = exmpp_jid:lnode_as_list(To),
LSTo = exmpp_jid:ldomain_as_list(To),
if
(LFrom == LTo) and (LSFrom == LSTo) ->
retrieve_disco_publish({LTo, LSTo}, Node);

View File

@ -118,7 +118,7 @@ handle_cast(_Msg, State) ->
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
handle_info({route, From, To, Packet}, State) ->
Packet2 = case From#jid.node of
Packet2 = case exmpp_jid:node(From) of
undefined -> exmpp_stanza:reply_with_error(Packet, 'bad-request');
_ -> Packet
end,
@ -174,8 +174,7 @@ do_client_version(disabled, _From, _To) ->
do_client_version(enabled, From, To) ->
%% It is important to identify this process and packet
Random_resource = integer_to_list(random:uniform(100000)),
From2 = From#jid{resource = Random_resource,
lresource = Random_resource},
From2 = exmpp_jid:bare_jid_to_jid(From,Random_resource),
%% Build an iq:query request
Request = #xmlel{ns = ?NS_SOFT_VERSION, name = 'query'},

View File

@ -204,7 +204,8 @@ do_route(Host, ServerHost, Access, From, To, Packet, DefEnc) ->
end.
do_route1(Host, ServerHost, From, To, Packet, DefEnc) ->
#jid{node = ChanServ, resource = Resource} = To,
ChanServ = exmpp_jid:node_as_list(To),
Resource = exmpp_jid:resource_as_list(To),
case ChanServ of
undefined ->
case Resource of
@ -400,8 +401,10 @@ process_irc_register(Host, From, _To, _DefEnc,
get_form(Host, From, [], Lang, DefEnc) ->
#jid{node = User, domain = Server,
lnode = LUser, ldomain = LServer} = From,
User = exmpp_jid:node_as_list(From),
Server = exmpp_jid:domain_as_list(From),
LUser = exmpp_jid:lnode_as_list(From),
LServer = exmpp_jid:ldomain_as_list(From),
US = {LUser, LServer},
Customs =
case catch mnesia:dirty_read({irc_custom, {US, Host}}) of
@ -485,7 +488,8 @@ get_form(_Host, _, _, _Lang, _) ->
set_form(Host, From, [], _Lang, XData) ->
{LUser, LServer, _} = jlib:short_prepd_jid(From),
LUser = exmpp_jid:lnode_as_list(From),
LServer = exmpp_jid:ldomain_as_list(From),
US = {LUser, LServer},
case {lists:keysearch("username", 1, XData),
lists:keysearch("encodings", 1, XData)} of
@ -529,8 +533,9 @@ set_form(_Host, _, _, _Lang, _XData) ->
get_user_and_encoding(Host, From, IRCServer, DefEnc) ->
#jid{node = User, domain = _Server,
lnode = LUser, ldomain = LServer} = From,
User = exmpp_jid:node_as_list(From),
LUser = exmpp_jid:lnode_as_list(From),
LServer = exmpp_jid:ldomain_as_list(From),
US = {LUser, LServer},
case catch mnesia:dirty_read({irc_custom, {US, Host}}) of
{'EXIT', _Reason} ->

View File

@ -47,6 +47,7 @@
start(Host, Opts) ->
HostB = list_to_binary(Host),
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
mnesia:create_table(last_activity,
[{disc_copies, [node()]},
@ -56,15 +57,16 @@ start(Host, Opts) ->
?MODULE, process_local_iq, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_LAST_ACTIVITY,
?MODULE, process_sm_iq, IQDisc),
ejabberd_hooks:add(remove_user, Host,
ejabberd_hooks:add(remove_user, HostB,
?MODULE, remove_user, 50),
ejabberd_hooks:add(unset_presence_hook, Host,
ejabberd_hooks:add(unset_presence_hook, HostB,
?MODULE, on_presence_update, 50).
stop(Host) ->
ejabberd_hooks:delete(remove_user, Host,
HostB = list_to_binary(Host),
ejabberd_hooks:delete(remove_user, HostB,
?MODULE, remove_user, 50),
ejabberd_hooks:delete(unset_presence_hook, Host,
ejabberd_hooks:delete(unset_presence_hook, HostB,
?MODULE, on_presence_update, 50),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_LAST_ACTIVITY),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_LAST_ACTIVITY).
@ -79,27 +81,25 @@ process_local_iq(_From, _To, #iq{type = set} = IQ_Rec) ->
process_sm_iq(From, To, #iq{type = get} = IQ_Rec) ->
User = To#jid.lnode,
Server = To#jid.ldomain,
{Subscription, _Groups} =
ejabberd_hooks:run_fold(
roster_get_jid_info, Server,
{none, []}, [User, Server, From]),
roster_get_jid_info, exmpp_jid:ldomain(To),
{none, []}, [exmpp_jid:lnode(To), exmpp_jid:ldomain(To), From]),
if
(Subscription == both) or (Subscription == from) ->
UserListRecord = ejabberd_hooks:run_fold(
privacy_get_user_list, Server,
privacy_get_user_list, exmpp_jid:ldomain(To),
#userlist{},
[User, Server]),
[exmpp_jid:lnode(To), exmpp_jid:ldomain(To)]),
case ejabberd_hooks:run_fold(
privacy_check_packet, Server,
privacy_check_packet, exmpp_jid:ldomain(To),
allow,
[User, Server, UserListRecord,
[exmpp_jid:lnode(To), exmpp_jid:ldomain(To), UserListRecord,
{From, To,
exmpp_presence:available()},
out]) of
allow ->
get_last(IQ_Rec, User, Server);
get_last(IQ_Rec, exmpp_jid:lnode(To), exmpp_jid:ldomain(To));
deny ->
exmpp_iq:error(IQ_Rec, 'not-allowed')
end;
@ -133,11 +133,10 @@ on_presence_update(User, Server, _Resource, Status) ->
TimeStamp = MegaSecs * 1000000 + Secs,
store_last_info(User, Server, TimeStamp, Status).
store_last_info(User, Server, TimeStamp, Status) ->
store_last_info(User, Server, TimeStamp, Status)
when is_binary(User), is_binary(Server) ->
try
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
US = {LUser, LServer},
US = {User, Server},
F = fun() ->
mnesia:write(#last_activity{us = US,
timestamp = TimeStamp,
@ -150,7 +149,7 @@ store_last_info(User, Server, TimeStamp, Status) ->
end.
%% Returns: {ok, Timestamp, Status} | not_found
get_last_info(LUser, LServer) ->
get_last_info(LUser, LServer) when is_binary(LUser), is_binary(LServer) ->
case catch mnesia:dirty_read(last_activity, {LUser, LServer}) of
{'EXIT', _Reason} ->
not_found;
@ -160,7 +159,7 @@ get_last_info(LUser, LServer) ->
{ok, TimeStamp, Status}
end.
remove_user(User, Server) ->
remove_user(User, Server) when is_binary(User), is_binary(Server) ->
try
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
@ -250,7 +249,8 @@ convert_to_exmpp2(#last_activity{us = {U, S} = Key, status = Status} = LA,
% Convert status.
Status1 = list_to_binary(Status),
% Prepare the new record.
New_LA = LA#last_activity{us = {U1, S}, status = Status1},
New_LA = LA#last_activity{us = {list_to_binary(U1), list_to_binary(S)},
status = Status1},
% Write the new record.
mnesia:write(New_LA),
Acc.

View File

@ -44,20 +44,22 @@
-include("mod_privacy.hrl").
start(Host, Opts) ->
HostB = list_to_binary(Host),
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_LAST_ACTIVITY,
?MODULE, process_local_iq, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_LAST_ACTIVITY,
?MODULE, process_sm_iq, IQDisc),
ejabberd_hooks:add(remove_user, Host,
ejabberd_hooks:add(remove_user, HostB,
?MODULE, remove_user, 50),
ejabberd_hooks:add(unset_presence_hook, Host,
ejabberd_hooks:add(unset_presence_hook, HostB,
?MODULE, on_presence_update, 50).
stop(Host) ->
ejabberd_hooks:delete(remove_user, Host,
HostB = list_to_binary(Host),
ejabberd_hooks:delete(remove_user, HostB,
?MODULE, remove_user, 50),
ejabberd_hooks:delete(unset_presence_hook, Host,
ejabberd_hooks:delete(unset_presence_hook, HostB,
?MODULE, on_presence_update, 50),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_LAST_ACTIVITY),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_LAST_ACTIVITY).
@ -71,22 +73,22 @@ process_local_iq(_From, _To, #iq{type = set} = IQ_Rec) ->
exmpp_iq:error(IQ_Rec, 'not-allowed').
process_sm_iq(From, To, #iq{type = get} = IQ_Rec) ->
User = To#jid.lnode,
Server = To#jid.ldomain,
User = exmpp_jid:lnode_as_list(To),
Server = exmpp_jid:ldomain_as_list(To),
{Subscription, _Groups} =
ejabberd_hooks:run_fold(
roster_get_jid_info, Server,
{none, []}, [User, Server, From]),
roster_get_jid_info, exmpp_jid:ldomain(To),
{none, []}, [exmpp_jid:lnode(To), exmpp_jid:ldomain(To), From]),
if
(Subscription == both) or (Subscription == from) ->
UserListRecord = ejabberd_hooks:run_fold(
privacy_get_user_list, Server,
privacy_get_user_list, exmpp_jid:ldomain(To),
#userlist{},
[User, Server]),
[exmpp_jid:lnode(To), exmpp_jid:ldomain(To)]),
case ejabberd_hooks:run_fold(
privacy_check_packet, Server,
privacy_check_packet, exmpp_jid:ldomain(To),
allow,
[User, Server, UserListRecord,
[exmpp_jid:lnode(To), exmpp_jid:ldomain(To), UserListRecord,
{From, To,
exmpp_presence:available()},
out]) of
@ -129,13 +131,17 @@ on_presence_update(User, Server, _Resource, Status) ->
TimeStamp = MegaSecs * 1000000 + Secs,
store_last_info(User, Server, TimeStamp, Status).
store_last_info(User, Server, TimeStamp, Status) ->
store_last_info(User, Server, TimeStamp, Status)
when is_binary(User), is_binary(Server) ->
try
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
%LUser = exmpp_stringprep:nodeprep(User),
%LServer = exmpp_stringprep:nameprep(Server),
LUser = binary_to_list(User),
LServer = binary_to_list(Server),
Username = ejabberd_odbc:escape(LUser),
Seconds = ejabberd_odbc:escape(integer_to_list(TimeStamp)),
State = ejabberd_odbc:escape(binary_to_list(Status)),
State = ejabberd_odbc:escape(Status),
odbc_queries:set_last_t(LServer, Username, Seconds, State)
catch
_ ->
@ -151,7 +157,7 @@ get_last_info(LUser, LServer) ->
{selected, ["seconds","state"], [{STimeStamp, Status}]} ->
case catch list_to_integer(STimeStamp) of
TimeStamp when is_integer(TimeStamp) ->
{ok, TimeStamp, list_to_binary(Status)};
{ok, TimeStamp, Status};
_ ->
not_found
end;

View File

@ -136,7 +136,7 @@ process_iq_disco_items(Host, From, To, #iq{} = IQ) ->
can_use_nick(_Host, _JID, "") ->
false;
can_use_nick(Host, JID, Nick) ->
LUS = {JID#jid.lnode, JID#jid.ldomain},
LUS = {exmpp_jid:lnode_as_list(JID), exmpp_jid:ldomain_as_list(JID)},
case catch mnesia:dirty_select(
muc_registered,
[{#muc_registered{us_host = '$1',
@ -312,8 +312,8 @@ do_route(Host, ServerHost, Access, HistorySize, RoomShaper,
do_route1(Host, ServerHost, Access, HistorySize, RoomShaper,
From, To, Packet, DefRoomOpts) ->
{_AccessRoute, AccessCreate, AccessAdmin, _AccessPersistent} = Access,
Room = To#jid.lnode,
Nick = To#jid.lresource,
Room = exmpp_jid:lnode_as_list(To),
Nick = exmpp_jid:lresource_as_list(To),
#xmlel{name = Name} = Packet,
case Room of
'undefined' ->
@ -554,8 +554,8 @@ flush() ->
children = [#xmlcdata{cdata = Val}]}]}).
iq_get_register_info(Host, From, Lang) ->
LUser = From#jid.lnode,
LServer = From#jid.ldomain,
LUser = exmpp_jid:lnode_as_list(From),
LServer = exmpp_jid:ldomain_as_list(From),
LUS = {LUser, LServer},
{Nick, Registered} =
case catch mnesia:dirty_read(muc_registered, {LUS, Host}) of
@ -584,8 +584,8 @@ iq_get_register_info(Host, From, Lang) ->
iq_set_register_info(Host, From, Nick, Lang) ->
LUser = From#jid.lnode,
LServer = From#jid.ldomain,
LUser = exmpp_jid:lnode_as_list(From),
LServer = exmpp_jid:ldomain_as_list(From),
LUS = {LUser, LServer},
F = fun() ->
case Nick of

View File

@ -272,7 +272,7 @@ build_filename_string(TimeStamp, OutDir, RoomJID, DirType, DirName, FileFormat)
get_room_name(RoomJID) ->
JID = exmpp_jid:list_to_jid(RoomJID),
JID#jid.node.
exmpp_jid:node_as_list(JID).
%% calculate day before
get_timestamp_daydiff(TimeStamp, Daydiff) ->

View File

@ -261,6 +261,7 @@ normal_state({route, From, undefined,
StateData#state.jid,
From, exmpp_stanza:reply_with_error(Packet, Err)),
{next_state, normal_state, StateData};
%%TODO: currently exmpp_message:get_type/1 never returns 'undefined'
Type when (Type == 'normal') orelse (Type == 'undefined') ->
case catch check_invitation(From,
exmpp_xml:get_child_elements(Packet),
@ -2139,11 +2140,16 @@ process_admin_items_set(UJID, Items, Lang, StateData) ->
fun(E, SD) ->
case catch (
case E of
{JID, affiliation, owner, _}
when (JID#jid.lnode == "") ->
{JID, affiliation, owner, _} ->
case exmpp_jid:lnode(JID) of
<<>> ->
SD;
%% TODO: <<>> or 'undefined' ?
%% TODO: double case on the E var, because
%% exmpp_jid:lnode/1 can't be used in guards
%% If the provided JID does not have username,
%% forget the affiliation completely
SD;
_ -> case E of
{JID, role, none, Reason} ->
catch send_kickban_presence(
JID, Reason, "307", SD),
@ -2187,6 +2193,8 @@ process_admin_items_set(UJID, Items, Lang, StateData) ->
send_update_presence(JID, SD1),
SD1
end
end
end
) of
{'EXIT', ErrReason} ->
?ERROR_MSG("MUC ITEMS SET ERR: ~p~n",
@ -3285,7 +3293,7 @@ check_invitation(From, Els, Lang, StateData) ->
_ -> [" (", Reason, ") "]
end
])}]},
%%TODO: always NS_JABER_CLIENT?
%%TODO: always NS_JABBER_CLIENT?
Msg =
#xmlel{ns = ?NS_JABBER_CLIENT, name = 'message',
attrs = [#xmlattr{name = 'type', value = "normal"}],
@ -3370,8 +3378,8 @@ add_to_log(Type, Data, StateData) ->
%% Users number checking
tab_add_online_user(JID, StateData) ->
LUser = JID#jid.lnode,
LServer = JID#jid.ldomain,
LUser = exmpp_jid:lnode(JID),
LServer = exmpp_jid:ldomain(JID),
US = {LUser, LServer},
Room = StateData#state.room,
Host = StateData#state.host,
@ -3381,7 +3389,9 @@ tab_add_online_user(JID, StateData) ->
tab_remove_online_user(#jid{lnode = LUser, ldomain = LServer}, StateData) ->
tab_remove_online_user(JID, StateData) when ?IS_JID(JID) ->
LUser = exmpp_jid:lnode(JID),
LServer = exmpp_jid:ldomain(JID),
tab_remove_online_user({LUser, LServer, none},StateData);
tab_remove_online_user({LUser, LServer,_}, StateData) ->
@ -3393,8 +3403,8 @@ tab_remove_online_user({LUser, LServer,_}, StateData) ->
#muc_online_users{us = US, room = Room, host = Host}).
tab_count_user(JID) ->
LUser = JID#jid.lnode,
LServer = JID#jid.ldomain,
LUser = exmpp_jid:lnode(JID),
LServer = exmpp_jid:ldomain(JID),
US = {LUser, LServer},
case catch ets:select(
muc_online_users,
@ -3407,11 +3417,7 @@ tab_count_user(JID) ->
jid_replace_resource(JID, Resource) ->
case exmpp_stringprep:resourceprep(Resource) of
error -> error;
LResource ->
JID#jid{resource = Resource, lresource = LResource}
end.
exmpp_jid:bare_jid_to_jid(JID, Resource).

View File

@ -59,24 +59,25 @@
-define(PREFIXED_NS, [{?NS_XMPP, ?NS_XMPP_pfx}]).
start(Host, Opts) ->
HostB = list_to_binary(Host),
mnesia:create_table(offline_msg,
[{disc_only_copies, [node()]},
{type, bag},
{attributes, record_info(fields, offline_msg)}]),
update_table(),
ejabberd_hooks:add(offline_message_hook, Host,
ejabberd_hooks:add(offline_message_hook, HostB,
?MODULE, store_packet, 50),
ejabberd_hooks:add(resend_offline_messages_hook, Host,
ejabberd_hooks:add(resend_offline_messages_hook, HostB,
?MODULE, pop_offline_messages, 50),
ejabberd_hooks:add(remove_user, Host,
ejabberd_hooks:add(remove_user, HostB,
?MODULE, remove_user, 50),
ejabberd_hooks:add(anonymous_purge_hook, Host,
ejabberd_hooks:add(anonymous_purge_hook, HostB,
?MODULE, remove_user, 50),
ejabberd_hooks:add(webadmin_page_host, Host,
ejabberd_hooks:add(webadmin_page_host, HostB,
?MODULE, webadmin_page, 50),
ejabberd_hooks:add(webadmin_user, Host,
ejabberd_hooks:add(webadmin_user, HostB,
?MODULE, webadmin_user, 50),
ejabberd_hooks:add(webadmin_user_parse_query, Host,
ejabberd_hooks:add(webadmin_user_parse_query, HostB,
?MODULE, webadmin_user_parse_query, 50),
MaxOfflineMsgs = gen_mod:get_opt(user_max_messages, Opts, infinity),
register(gen_mod:get_module_proc(Host, ?PROCNAME),
@ -134,19 +135,20 @@ receive_all(US, Msgs) ->
stop(Host) ->
ejabberd_hooks:delete(offline_message_hook, Host,
HostB = list_to_binary(Host),
ejabberd_hooks:delete(offline_message_hook, HostB,
?MODULE, store_packet, 50),
ejabberd_hooks:delete(resend_offline_messages_hook, Host,
ejabberd_hooks:delete(resend_offline_messages_hook, HostB,
?MODULE, pop_offline_messages, 50),
ejabberd_hooks:delete(remove_user, Host,
ejabberd_hooks:delete(remove_user, HostB,
?MODULE, remove_user, 50),
ejabberd_hooks:delete(anonymous_purge_hook, Host,
ejabberd_hooks:delete(anonymous_purge_hook, HostB,
?MODULE, remove_user, 50),
ejabberd_hooks:delete(webadmin_page_host, Host,
ejabberd_hooks:delete(webadmin_page_host, HostB,
?MODULE, webadmin_page, 50),
ejabberd_hooks:delete(webadmin_user, Host,
ejabberd_hooks:delete(webadmin_user, HostB,
?MODULE, webadmin_user, 50),
ejabberd_hooks:delete(webadmin_user_parse_query, Host,
ejabberd_hooks:delete(webadmin_user_parse_query, HostB,
?MODULE, webadmin_user_parse_query, 50),
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
exit(whereis(Proc), stop),
@ -159,10 +161,11 @@ store_packet(From, To, Packet) ->
(Type /= "headline") ->
case check_event(From, To, Packet) of
true ->
#jid{lnode = LUser, ldomain = LServer} = To,
LUser = exmpp_jid:lnode_as_list(To),
LServer = exmpp_jid:ldomain_as_list(To),
TimeStamp = now(),
Expire = find_x_expire(TimeStamp, Packet#xmlel.children),
gen_mod:get_module_proc(To#jid.ldomain, ?PROCNAME) !
gen_mod:get_module_proc(LServer, ?PROCNAME) !
#offline_msg{us = {LUser, LServer},
timestamp = TimeStamp,
expire = Expire,
@ -267,10 +270,11 @@ resend_offline_messages(User, Server) ->
ok
end.
pop_offline_messages(Ls, User, Server) ->
pop_offline_messages(Ls, User, Server)
when is_binary(User), is_binary(Server) ->
try
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
LUser = binary_to_list(User),
LServer = binary_to_list(Server),
US = {LUser, LServer},
F = fun() ->
Rs = mnesia:wread({offline_msg, US}),
@ -347,7 +351,7 @@ remove_old_messages(Days) ->
end,
mnesia:transaction(F).
remove_user(User, Server) ->
remove_user(User, Server) when is_binary(User), is_binary(Server) ->
try
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),

View File

@ -58,19 +58,20 @@
-define(PREFIXED_NS, [{?NS_XMPP, ?NS_XMPP_pfx}]).
start(Host, Opts) ->
ejabberd_hooks:add(offline_message_hook, Host,
HostB = list_to_binary(Host),
ejabberd_hooks:add(offline_message_hook, HostB,
?MODULE, store_packet, 50),
ejabberd_hooks:add(resend_offline_messages_hook, Host,
ejabberd_hooks:add(resend_offline_messages_hook, HostB,
?MODULE, pop_offline_messages, 50),
ejabberd_hooks:add(remove_user, Host,
ejabberd_hooks:add(remove_user, HostB,
?MODULE, remove_user, 50),
ejabberd_hooks:add(anonymous_purge_hook, Host,
ejabberd_hooks:add(anonymous_purge_hook, HostB,
?MODULE, remove_user, 50),
ejabberd_hooks:add(webadmin_page_host, Host,
ejabberd_hooks:add(webadmin_page_host, HostB,
?MODULE, webadmin_page, 50),
ejabberd_hooks:add(webadmin_user, Host,
ejabberd_hooks:add(webadmin_user, HostB,
?MODULE, webadmin_user, 50),
ejabberd_hooks:add(webadmin_user_parse_query, Host,
ejabberd_hooks:add(webadmin_user_parse_query, HostB,
?MODULE, webadmin_user_parse_query, 50),
MaxOfflineMsgs = gen_mod:get_opt(user_max_messages, Opts, infinity),
register(gen_mod:get_module_proc(Host, ?PROCNAME),
@ -102,7 +103,7 @@ loop(Host, MaxOfflineMsgs) ->
fun(M) ->
Username =
ejabberd_odbc:escape(
(M#offline_msg.to)#jid.lnode),
exmpp_jid:lnode_as_list(M#offline_msg.to)),
From = M#offline_msg.from,
To = M#offline_msg.to,
Packet0 = exmpp_stanza:set_jids(
@ -142,19 +143,20 @@ receive_all(Username, Msgs) ->
stop(Host) ->
ejabberd_hooks:delete(offline_message_hook, Host,
HostB = list_to_binary(Host),
ejabberd_hooks:delete(offline_message_hook, HostB,
?MODULE, store_packet, 50),
ejabberd_hooks:delete(resend_offline_messages_hook, Host,
ejabberd_hooks:delete(resend_offline_messages_hook, HostB,
?MODULE, pop_offline_messages, 50),
ejabberd_hooks:delete(remove_user, Host,
ejabberd_hooks:delete(remove_user, HostB,
?MODULE, remove_user, 50),
ejabberd_hooks:delete(anonymous_purge_hook, Host,
ejabberd_hooks:delete(anonymous_purge_hook, HostB,
?MODULE, remove_user, 50),
ejabberd_hooks:delete(webadmin_page_host, Host,
ejabberd_hooks:delete(webadmin_page_host, HostB,
?MODULE, webadmin_page, 50),
ejabberd_hooks:delete(webadmin_user, Host,
ejabberd_hooks:delete(webadmin_user, HostB,
?MODULE, webadmin_user, 50),
ejabberd_hooks:delete(webadmin_user_parse_query, Host,
ejabberd_hooks:delete(webadmin_user_parse_query, HostB,
?MODULE, webadmin_user_parse_query, 50),
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
exit(whereis(Proc), stop),
@ -167,10 +169,10 @@ store_packet(From, To, Packet) ->
(Type /= "headline") ->
case check_event(From, To, Packet) of
true ->
#jid{lnode = LUser} = To,
LUser = exmpp_jid:lnode_as_list(To),
TimeStamp = now(),
Expire = find_x_expire(TimeStamp, Packet#xmlel.children),
gen_mod:get_module_proc(To#jid.ldomain, ?PROCNAME) !
gen_mod:get_module_proc(exmpp_jid:ldomain_as_list(To), ?PROCNAME) !
#offline_msg{user = LUser,
timestamp = TimeStamp,
expire = Expire,
@ -241,17 +243,20 @@ find_x_expire(TimeStamp, [_ | Els]) ->
find_x_expire(TimeStamp, Els).
pop_offline_messages(Ls, User, Server) ->
pop_offline_messages(Ls, User, Server)
when is_binary(User), is_binary(Server) ->
try
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
LUser = binary_to_list(User),
LServer = binary_to_list(Server),
EUser = ejabberd_odbc:escape(LUser),
case odbc_queries:get_and_del_spool_msg_t(LServer, EUser) of
{atomic, {selected, ["username","xml"], Rs}} ->
Ls ++ lists:flatmap(
fun({_, XML}) ->
try
[El] = exmpp_xml:parse_document(XML, [names_as_atom]),
[El] = exmpp_xml:parse_document(XML,
[names_as_atom, {check_elems, xmpp},
{check_nss,xmpp}, {check_attrs,xmpp}]),
To = exmpp_jid:list_to_jid(
exmpp_stanza:get_recipient(El)),
From = exmpp_jid:list_to_jid(
@ -271,7 +276,8 @@ pop_offline_messages(Ls, User, Server) ->
end.
remove_user(User, Server) ->
remove_user(User, Server)
when is_binary(User), is_binary(Server) ->
try
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
@ -327,7 +333,9 @@ user_queue(User, Server, Query, Lang) ->
{selected, ["username", "xml"], Rs} ->
lists:flatmap(
fun({_, XML}) ->
try exmpp_xml:parse_document(XML, [names_as_atom]) of
try exmpp_xml:parse_document(XML,
[names_as_atom, {check_elems, xmpp},
{check_nss,xmpp}, {check_attrs,xmpp}]) of
[El] ->
[El]
catch
@ -394,7 +402,9 @@ user_queue_parse_query(Username, LServer, Query) ->
{selected, ["xml", "seq"], Rs} ->
lists:flatmap(
fun({XML, Seq}) ->
try exmpp_xml:parse_document(XML, [names_as_atom]) of
try exmpp_xml:parse_document(XML,
[names_as_atom, {check_elems, xmpp},
{check_nss,xmpp}, {check_attrs,xmpp}]) of
[El] ->
[{El, Seq}]
catch

View File

@ -44,33 +44,35 @@
start(Host, Opts) ->
HostB = list_to_binary(Host),
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
mnesia:create_table(privacy, [{disc_copies, [node()]},
{attributes, record_info(fields, privacy)}]),
update_table(),
ejabberd_hooks:add(privacy_iq_get, Host,
ejabberd_hooks:add(privacy_iq_get, HostB,
?MODULE, process_iq_get, 50),
ejabberd_hooks:add(privacy_iq_set, Host,
ejabberd_hooks:add(privacy_iq_set, HostB,
?MODULE, process_iq_set, 50),
ejabberd_hooks:add(privacy_get_user_list, Host,
ejabberd_hooks:add(privacy_get_user_list, HostB,
?MODULE, get_user_list, 50),
ejabberd_hooks:add(privacy_check_packet, Host,
ejabberd_hooks:add(privacy_check_packet, HostB,
?MODULE, check_packet, 50),
ejabberd_hooks:add(privacy_updated_list, Host,
ejabberd_hooks:add(privacy_updated_list, HostB,
?MODULE, updated_list, 50),
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY,
?MODULE, process_iq, IQDisc).
stop(Host) ->
ejabberd_hooks:delete(privacy_iq_get, Host,
HostB = list_to_binary(Host),
ejabberd_hooks:delete(privacy_iq_get, HostB,
?MODULE, process_iq_get, 50),
ejabberd_hooks:delete(privacy_iq_set, Host,
ejabberd_hooks:delete(privacy_iq_set, HostB,
?MODULE, process_iq_set, 50),
ejabberd_hooks:delete(privacy_get_user_list, Host,
ejabberd_hooks:delete(privacy_get_user_list, HostB,
?MODULE, get_user_list, 50),
ejabberd_hooks:delete(privacy_check_packet, Host,
ejabberd_hooks:delete(privacy_check_packet, HostB,
?MODULE, check_packet, 50),
ejabberd_hooks:delete(privacy_updated_list, Host,
ejabberd_hooks:delete(privacy_updated_list, HostB,
?MODULE, updated_list, 50),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY).
@ -80,7 +82,8 @@ process_iq(_From, _To, IQ_Rec) ->
process_iq_get(_, From, _To, #iq{payload = SubEl},
#userlist{name = Active}) ->
#jid{lnode = LUser, ldomain = LServer} = From,
LUser = exmpp_jid:lnode_as_list(From),
LServer = exmpp_jid:ldomain_as_list(From),
case exmpp_xml:get_child_elements(SubEl) of
[] ->
process_lists_get(LUser, LServer, Active);
@ -238,7 +241,8 @@ list_to_action(S) ->
process_iq_set(_, From, _To, #iq{payload = SubEl}) ->
#jid{lnode = LUser, ldomain = LServer} = From,
LUser = exmpp_jid:lnode_as_list(From),
LServer = exmpp_jid:ldomain_as_list(From),
case exmpp_xml:get_child_elements(SubEl) of
[#xmlel{name = Name} = Child] ->
ListName = exmpp_xml:get_attribute(Child, 'name', false),
@ -510,10 +514,11 @@ parse_matches1(_Item, [#xmlel{} | _Els]) ->
get_user_list(_, User, Server) ->
get_user_list(_, User, Server)
when is_binary(User), is_binary(Server) ->
try
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
LUser = binary_to_list(User),
LServer = binary_to_list(Server),
case catch mnesia:dirty_read(privacy, {LUser, LServer}) of
[] ->
#userlist{};
@ -542,7 +547,8 @@ get_user_list(_, User, Server) ->
check_packet(_, User, Server,
#userlist{list = List},
{From, To, #xmlel{name = PName}},
Dir) when PName =:= message ;
Dir) when
PName =:= message ;
PName =:= iq ;
PName =:= presence ->
case List of
@ -554,7 +560,8 @@ check_packet(_, User, Server,
LJID = jlib:short_prepd_jid(From),
{Subscription, Groups} =
ejabberd_hooks:run_fold(
roster_get_jid_info, exmpp_stringprep:nameprep(Server),
roster_get_jid_info,
Server,
{none, []}, [User, Server, From]),
check_packet_aux(List, message,
LJID, Subscription, Groups);
@ -562,7 +569,8 @@ check_packet(_, User, Server,
LJID = jlib:short_prepd_jid(From),
{Subscription, Groups} =
ejabberd_hooks:run_fold(
roster_get_jid_info, exmpp_stringprep:nameprep(Server),
roster_get_jid_info,
Server,
{none, []}, [User, Server, From]),
check_packet_aux(List, iq,
LJID, Subscription, Groups);
@ -570,7 +578,8 @@ check_packet(_, User, Server,
LJID = jlib:short_prepd_jid(From),
{Subscription, Groups} =
ejabberd_hooks:run_fold(
roster_get_jid_info, exmpp_stringprep:nameprep(Server),
roster_get_jid_info,
Server,
{none, []}, [User, Server, From]),
check_packet_aux(List, presence_in,
LJID, Subscription, Groups);
@ -578,7 +587,8 @@ check_packet(_, User, Server,
LJID = jlib:short_prepd_jid(To),
{Subscription, Groups} =
ejabberd_hooks:run_fold(
roster_get_jid_info, exmpp_stringprep:nameprep(Server),
roster_get_jid_info,
Server,
{none, []}, [User, Server, To]),
check_packet_aux(List, presence_out,
LJID, Subscription, Groups);

View File

@ -43,30 +43,32 @@
-include("mod_privacy.hrl").
start(Host, Opts) ->
HostB = list_to_binary(Host),
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
ejabberd_hooks:add(privacy_iq_get, Host,
ejabberd_hooks:add(privacy_iq_get, HostB,
?MODULE, process_iq_get, 50),
ejabberd_hooks:add(privacy_iq_set, Host,
ejabberd_hooks:add(privacy_iq_set, HostB,
?MODULE, process_iq_set, 50),
ejabberd_hooks:add(privacy_get_user_list, Host,
ejabberd_hooks:add(privacy_get_user_list, HostB,
?MODULE, get_user_list, 50),
ejabberd_hooks:add(privacy_check_packet, Host,
ejabberd_hooks:add(privacy_check_packet, HostB,
?MODULE, check_packet, 50),
ejabberd_hooks:add(privacy_updated_list, Host,
ejabberd_hooks:add(privacy_updated_list, HostB,
?MODULE, updated_list, 50),
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY,
?MODULE, process_iq, IQDisc).
stop(Host) ->
ejabberd_hooks:delete(privacy_iq_get, Host,
HostB = list_to_binary(Host),
ejabberd_hooks:delete(privacy_iq_get, HostB,
?MODULE, process_iq_get, 50),
ejabberd_hooks:delete(privacy_iq_set, Host,
ejabberd_hooks:delete(privacy_iq_set, HostB,
?MODULE, process_iq_set, 50),
ejabberd_hooks:delete(privacy_get_user_list, Host,
ejabberd_hooks:delete(privacy_get_user_list, HostB,
?MODULE, get_user_list, 50),
ejabberd_hooks:delete(privacy_check_packet, Host,
ejabberd_hooks:delete(privacy_check_packet, HostB,
?MODULE, check_packet, 50),
ejabberd_hooks:delete(privacy_updated_list, Host,
ejabberd_hooks:delete(privacy_updated_list, HostB,
?MODULE, updated_list, 50),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PRIVACY).
@ -76,7 +78,8 @@ process_iq(_From, _To, IQ_Rec) ->
process_iq_get(_, From, _To, #iq{payload = SubEl},
#userlist{name = Active}) ->
#jid{lnode = LUser, ldomain = LServer} = From,
LUser = exmpp_jid:lnode_as_list(From),
LServer = exmpp_jid:ldomain_as_list(From),
case exmpp_xml:get_child_elements(SubEl) of
[] ->
process_lists_get(LUser, LServer, Active);
@ -244,7 +247,8 @@ list_to_action(S) ->
process_iq_set(_, From, _To, #iq{payload = SubEl}) ->
#jid{lnode = LUser, ldomain = LServer} = From,
LUser = exmpp_jid:lnode_as_list(From),
LServer = exmpp_jid:ldomain_as_list(From),
case exmpp_xml:get_child_elements(SubEl) of
[#xmlel{name = Name} = Child] ->
ListName = exmpp_xml:get_attribute(Child, 'name', false),
@ -511,10 +515,11 @@ parse_matches1(_Item, [#xmlel{} | _Els]) ->
get_user_list(_, User, Server) ->
get_user_list(_, User, Server)
when is_binary(User), is_binary(Server) ->
try
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
LUser = binary_to_list(User),
LServer = binary_to_list(Server),
case catch sql_get_default_privacy_list(LUser, LServer) of
{selected, ["name"], []} ->
#userlist{};
@ -541,7 +546,8 @@ get_user_list(_, User, Server) ->
check_packet(_, User, Server,
#userlist{list = List},
{From, To, #xmlel{name = PName}},
Dir) when PName =:= message ;
Dir) when
PName =:= message ;
PName =:= iq ;
PName =:= presence ->
case List of
@ -553,7 +559,8 @@ check_packet(_, User, Server,
LJID = jlib:short_prepd_jid(From),
{Subscription, Groups} =
ejabberd_hooks:run_fold(
roster_get_jid_info, exmpp_stringprep:nameprep(Server),
roster_get_jid_info,
Server,
{none, []}, [User, Server, From]),
check_packet_aux(List, message,
LJID, Subscription, Groups);
@ -561,7 +568,8 @@ check_packet(_, User, Server,
LJID = jlib:short_prepd_jid(From),
{Subscription, Groups} =
ejabberd_hooks:run_fold(
roster_get_jid_info, exmpp_stringprep:nameprep(Server),
roster_get_jid_info,
Server,
{none, []}, [User, Server, From]),
check_packet_aux(List, iq,
LJID, Subscription, Groups);
@ -569,7 +577,8 @@ check_packet(_, User, Server,
LJID = jlib:short_prepd_jid(From),
{Subscription, Groups} =
ejabberd_hooks:run_fold(
roster_get_jid_info, exmpp_stringprep:nameprep(Server),
roster_get_jid_info,
Server,
{none, []}, [User, Server, From]),
check_packet_aux(List, presence_in,
LJID, Subscription, Groups);
@ -577,7 +586,8 @@ check_packet(_, User, Server,
LJID = jlib:short_prepd_jid(To),
{Subscription, Groups} =
ejabberd_hooks:run_fold(
roster_get_jid_info, exmpp_stringprep:nameprep(Server),
roster_get_jid_info,
Server,
{none, []}, [User, Server, To]),
check_packet_aux(List, presence_out,
LJID, Subscription, Groups);

View File

@ -41,18 +41,20 @@
-record(private_storage, {usns, xml}).
start(Host, Opts) ->
HostB = list_to_binary(Host),
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
mnesia:create_table(private_storage,
[{disc_only_copies, [node()]},
{attributes, record_info(fields, private_storage)}]),
update_table(),
ejabberd_hooks:add(remove_user, Host,
ejabberd_hooks:add(remove_user, HostB,
?MODULE, remove_user, 50),
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE,
?MODULE, process_sm_iq, IQDisc).
stop(Host) ->
ejabberd_hooks:delete(remove_user, Host,
HostB = list_to_binary(Host),
ejabberd_hooks:delete(remove_user, HostB,
?MODULE, remove_user, 50),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE).
@ -71,7 +73,8 @@ process_sm_iq(From, To, #iq{type = Type} = IQ_Rec) ->
end.
process_iq_get(From, _To, #iq{payload = SubEl} = IQ_Rec) ->
#jid{lnode = LUser, ldomain = LServer} = From,
LUser = exmpp_jid:lnode_as_list(From),
LServer = exmpp_jid:ldomain_as_list(From),
case catch get_data(LUser,
LServer,
exmpp_xml:get_child_elements(SubEl)) of
@ -85,7 +88,8 @@ process_iq_get(From, _To, #iq{payload = SubEl} = IQ_Rec) ->
process_iq_set(From, _To, #iq{payload = SubEl} = IQ_Rec) ->
#jid{lnode = LUser, ldomain = LServer} = From,
LUser = exmpp_jid:lnode_as_list(From),
LServer = exmpp_jid:ldomain_as_list(From),
F = fun() ->
lists:foreach(
fun(El) ->
@ -108,7 +112,8 @@ check_packet(From, To, IQ_Rec, [F | R]) ->
ok -> check_packet(From, To, IQ_Rec, R)
end.
check_domain(#jid{ldomain = LServer}, _To, _IQ_Rec) ->
check_domain(From, _To, _IQ_Rec) ->
LServer = exmpp_jid:ldomain_as_list(From),
case lists:member(LServer, ?MYHOSTS) of
true -> ok;
false -> {error, 'not-allowed'}
@ -158,7 +163,8 @@ get_data(LUser, LServer, [El | Els], Res) ->
[El | Res])
end.
remove_user(User, Server) ->
remove_user(User, Server)
when is_binary(User), is_binary(Server) ->
try
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),

View File

@ -39,14 +39,16 @@
-include("ejabberd.hrl").
start(Host, Opts) ->
HostB = list_to_binary(Host),
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
ejabberd_hooks:add(remove_user, Host,
ejabberd_hooks:add(remove_user, HostB,
?MODULE, remove_user, 50),
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE,
?MODULE, process_sm_iq, IQDisc).
stop(Host) ->
ejabberd_hooks:delete(remove_user, Host,
HostB = list_to_binary(Host),
ejabberd_hooks:delete(remove_user, HostB,
?MODULE, remove_user, 50),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_PRIVATE).
@ -65,7 +67,8 @@ process_sm_iq(From, To, #iq{type = Type} = IQ_Rec) ->
end.
process_iq_get(From, _To, #iq{payload = SubEl} = IQ_Rec) ->
#jid{lnode = LUser, ldomain = LServer} = From,
LUser = exmpp_jid:lnode_as_list(From),
LServer = exmpp_jid:ldomain_as_list(From),
case catch get_data(LUser,
LServer,
exmpp_xml:get_child_elements(SubEl)) of
@ -79,7 +82,8 @@ process_iq_get(From, _To, #iq{payload = SubEl} = IQ_Rec) ->
process_iq_set(From, _To, #iq{payload = SubEl} = IQ_Rec) ->
#jid{lnode = LUser, ldomain = LServer} = From,
LUser = exmpp_jid:lnode_as_list(From),
LServer = exmpp_jid:ldomain_as_list(From),
F = fun() ->
lists:foreach(
fun(El) ->
@ -102,7 +106,8 @@ check_packet(From, To, IQ_Rec, [F | R]) ->
ok -> check_packet(From, To, IQ_Rec, R)
end.
check_domain(#jid{ldomain = LServer}, _To, _IQ_Rec) ->
check_domain(From, _To, _IQ_Rec) ->
LServer = exmpp_jid:ldomain_as_list(From),
case lists:member(LServer, ?MYHOSTS) of
true -> ok;
false -> {error, 'not-allowed'}
@ -151,7 +156,9 @@ get_data(LUser, LServer, [El | Els], Res) ->
LXMLNS = ejabberd_odbc:escape(XMLNS),
case catch odbc_queries:get_private_data(LServer, Username, LXMLNS) of
{selected, ["data"], [{SData}]} ->
[Data] = exmpp_xml:parse_document(SData,[names_as_atom]),
[Data] = exmpp_xml:parse_document(SData,
[names_as_atom, {check_elems, xmpp},
{check_nss,xmpp}, {check_attrs,xmpp}]),
get_data(LUser, LServer, Els, [Data | Res]);
%% MREMOND: I wonder when the query could return a vcard ?
{selected, ["vcard"], []} ->
@ -162,7 +169,7 @@ get_data(LUser, LServer, [El | Els], Res) ->
end.
remove_user(User, Server) ->
remove_user(User, Server) when is_binary(User), is_binary(Server) ->
try
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),

View File

@ -631,7 +631,7 @@ get_states(Host, Node) ->
get_state(Host, Node, JID) ->
StateId = {JID, {Host, Node}},
case mnesia:read({pubsub_state, StateId}) of
[State] when is_record(State, pubsub_state) -> State
[State] when is_record(State, pubsub_state) -> State;
_ -> #pubsub_state{stateid=StateId}
end.

View File

@ -40,14 +40,15 @@
-include("ejabberd.hrl").
start(Host, Opts) ->
HostB = list_to_binary(Host),
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_INBAND_REGISTER,
?MODULE, process_iq, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_INBAND_REGISTER,
?MODULE, process_iq, IQDisc),
ejabberd_hooks:add(c2s_stream_features, Host,
ejabberd_hooks:add(c2s_stream_features, HostB,
?MODULE, stream_feature_register, 50),
ejabberd_hooks:add(c2s_unauthenticated_iq, Host,
ejabberd_hooks:add(c2s_unauthenticated_iq, HostB,
?MODULE, unauthenticated_iq_register, 50),
mnesia:create_table(mod_register_ip,
[{ram_copies, [node()]},
@ -57,9 +58,10 @@ start(Host, Opts) ->
ok.
stop(Host) ->
ejabberd_hooks:delete(c2s_stream_features, Host,
HostB = list_to_binary(Host),
ejabberd_hooks:delete(c2s_stream_features, HostB,
?MODULE, stream_feature_register, 50),
ejabberd_hooks:delete(c2s_unauthenticated_iq, Host,
ejabberd_hooks:delete(c2s_unauthenticated_iq, HostB,
?MODULE, unauthenticated_iq_register, 50),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_INBAND_REGISTER),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_INBAND_REGISTER).
@ -74,17 +76,20 @@ unauthenticated_iq_register(_Acc,
{A, _Port} -> A;
_ -> undefined
end,
ResIQ = process_iq(#jid{},
exmpp_jid:make_bare_jid(Server),
BareJID = exmpp_jid:make_bare_jid(Server),
ResIQ = process_iq(exmpp_jid:make_jid(),
BareJID,
IQ_Rec,
Address),
exmpp_iq:iq_to_xmlel(ResIQ, exmpp_jid:make_bare_jid(Server), undefined);
exmpp_iq:iq_to_xmlel(ResIQ, BareJID, undefined);
unauthenticated_iq_register(Acc, _Server, _IQ, _IP) ->
Acc.
process_iq(From, To, IQ) ->
process_iq(From, To, IQ, jlib:short_prepd_bare_jid(From)).
process_iq(From, To, IQ, {exmpp_jid:lnode_as_list(From),
exmpp_jid:ldomain_as_list(From),
exmpp_jid:lresource_as_list(From)}).
process_iq(From, To,
#iq{type = Type, lang = Lang, payload = SubEl} = IQ_Rec,
@ -94,12 +99,12 @@ process_iq(From, To,
UTag = exmpp_xml:get_element(SubEl, 'username'),
PTag = exmpp_xml:get_element(SubEl, 'password'),
RTag = exmpp_xml:get_element(SubEl, 'remove'),
Server = To#jid.ldomain,
Server = exmpp_jid:ldomain_as_list(To),
if
(UTag /= undefined) and (RTag /= undefined) ->
User = exmpp_xml:get_cdata_as_list(UTag),
case From of
#jid{node = User, ldomain = Server} ->
case {exmpp_jid:node_as_list(From), exmpp_jid:ldomain_as_list(From)} of
{User, Server} ->
ejabberd_auth:remove_user(User, Server),
exmpp_iq:result(IQ_Rec, SubEl);
_ ->
@ -132,14 +137,18 @@ process_iq(From, To,
end
end;
(UTag == undefined) and (RTag /= undefined) ->
case From of
#jid{node = User,
ldomain = Server,
resource = Resource} ->
case {exmpp_jid:node_as_list(From),
exmpp_jid:ldomain_as_list(From),
exmpp_jid:resource_as_list(From)}of
{User, Server, Resource} ->
ResIQ = exmpp_iq:result(IQ_Rec, SubEl),
ejabberd_router:route(
exmpp_jid:make_jid(User, Server, Resource),
exmpp_jid:make_jid(User, Server, Resource),
exmpp_jid:make_jid(User,
Server,
Resource),
exmpp_jid:make_jid(User,
Server,
Resource),
exmpp_iq:iq_to_xmlel(ResIQ)),
ejabberd_auth:remove_user(User, Server),
ignore;
@ -149,8 +158,8 @@ process_iq(From, To,
(UTag /= undefined) and (PTag /= undefined) ->
User = exmpp_xml:get_cdata_as_list(UTag),
Password = exmpp_xml:get_cdata_as_list(PTag),
case From of
#jid{node = User, ldomain = Server} ->
case {exmpp_jid:node_as_list(From), exmpp_jid:ldomain_as_list(From)} of
{User, Server} ->
try_set_password(User, Server, Password, IQ_Rec, SubEl);
_ ->
case try_register(User, Server, Password,
@ -195,7 +204,8 @@ try_register(User, Server, Password, Source, Lang) ->
false ->
{error, 'bad-request'};
_ ->
JID = exmpp_jid:make_bare_jid(User, Server),
JID = exmpp_jid:make_bare_jid(User,
Server),
Access = gen_mod:get_module_opt(Server, ?MODULE, access, all),
case acl:match_rule(Server, Access, JID) of
deny ->
@ -205,8 +215,8 @@ try_register(User, Server, Password, Source, Lang) ->
true ->
case ejabberd_auth:try_register(User, Server, Password) of
{atomic, ok} ->
ejabberd_hooks:run(user_registered, Server,
[User, Server]),
ejabberd_hooks:run(user_registered, exmpp_jid:domain(JID),
[exmpp_jid:node(JID), exmpp_jid:domain(JID)]),
send_welcome_message(JID),
send_registration_notifications(JID),
ok;
@ -233,7 +243,7 @@ try_register(User, Server, Password, Source, Lang) ->
send_welcome_message(JID) ->
Host = JID#jid.ldomain,
Host = exmpp_jid:ldomain_as_list(JID),
case gen_mod:get_module_opt(Host, ?MODULE, welcome_message, {"", ""}) of
{"", ""} ->
ok;
@ -247,7 +257,7 @@ send_welcome_message(JID) ->
end.
send_registration_notifications(UJID) ->
Host = UJID#jid.ldomain,
Host = exmpp_jid:ldomain_as_list(UJID),
case gen_mod:get_module_opt(Host, ?MODULE, registration_watchers, []) of
[] -> ok;
JIDs when is_list(JIDs) ->

View File

@ -53,61 +53,63 @@
start(Host, Opts) ->
HostB = list_to_binary(Host),
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
mnesia:create_table(roster,[{disc_copies, [node()]},
{attributes, record_info(fields, roster)}]),
update_table(),
mnesia:add_table_index(roster, us),
ejabberd_hooks:add(roster_get, Host,
ejabberd_hooks:add(roster_get, HostB,
?MODULE, get_user_roster, 50),
ejabberd_hooks:add(roster_in_subscription, Host,
ejabberd_hooks:add(roster_in_subscription, HostB,
?MODULE, in_subscription, 50),
ejabberd_hooks:add(roster_out_subscription, Host,
ejabberd_hooks:add(roster_out_subscription, HostB,
?MODULE, out_subscription, 50),
ejabberd_hooks:add(roster_get_subscription_lists, Host,
ejabberd_hooks:add(roster_get_subscription_lists, HostB,
?MODULE, get_subscription_lists, 50),
ejabberd_hooks:add(roster_get_jid_info, Host,
ejabberd_hooks:add(roster_get_jid_info, HostB,
?MODULE, get_jid_info, 50),
ejabberd_hooks:add(remove_user, Host,
ejabberd_hooks:add(remove_user, HostB,
?MODULE, remove_user, 50),
ejabberd_hooks:add(anonymous_purge_hook, Host,
ejabberd_hooks:add(anonymous_purge_hook, HostB,
?MODULE, remove_user, 50),
ejabberd_hooks:add(resend_subscription_requests_hook, Host,
ejabberd_hooks:add(resend_subscription_requests_hook, HostB,
?MODULE, get_in_pending_subscriptions, 50),
ejabberd_hooks:add(webadmin_page_host, Host,
ejabberd_hooks:add(webadmin_page_host, HostB,
?MODULE, webadmin_page, 50),
ejabberd_hooks:add(webadmin_user, Host,
ejabberd_hooks:add(webadmin_user, HostB,
?MODULE, webadmin_user, 50),
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ROSTER,
?MODULE, process_iq, IQDisc).
stop(Host) ->
ejabberd_hooks:delete(roster_get, Host,
HostB = list_to_binary(Host),
ejabberd_hooks:delete(roster_get, HostB,
?MODULE, get_user_roster, 50),
ejabberd_hooks:delete(roster_in_subscription, Host,
ejabberd_hooks:delete(roster_in_subscription, HostB,
?MODULE, in_subscription, 50),
ejabberd_hooks:delete(roster_out_subscription, Host,
ejabberd_hooks:delete(roster_out_subscription, HostB,
?MODULE, out_subscription, 50),
ejabberd_hooks:delete(roster_get_subscription_lists, Host,
ejabberd_hooks:delete(roster_get_subscription_lists, HostB,
?MODULE, get_subscription_lists, 50),
ejabberd_hooks:delete(roster_get_jid_info, Host,
ejabberd_hooks:delete(roster_get_jid_info, HostB,
?MODULE, get_jid_info, 50),
ejabberd_hooks:delete(remove_user, Host,
ejabberd_hooks:delete(remove_user, HostB,
?MODULE, remove_user, 50),
ejabberd_hooks:delete(anonymous_purge_hook, Host,
ejabberd_hooks:delete(anonymous_purge_hook, HostB,
?MODULE, remove_user, 50),
ejabberd_hooks:delete(resend_subscription_requests_hook, Host,
ejabberd_hooks:delete(resend_subscription_requests_hook, HostB,
?MODULE, get_in_pending_subscriptions, 50),
ejabberd_hooks:delete(webadmin_page_host, Host,
ejabberd_hooks:delete(webadmin_page_host, HostB,
?MODULE, webadmin_page, 50),
ejabberd_hooks:delete(webadmin_user, Host,
ejabberd_hooks:delete(webadmin_user, HostB,
?MODULE, webadmin_user, 50),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
?NS_ROSTER).
process_iq(From, To, IQ_Rec) ->
#jid{ldomain = LServer} = From,
LServer = exmpp_jid:ldomain_as_list(From),
case lists:member(LServer, ?MYHOSTS) of
true ->
process_local_iq(From, To, IQ_Rec);
@ -123,8 +125,8 @@ process_local_iq(From, To, #iq{type = set} = IQ_Rec) ->
process_iq_get(From, To, IQ_Rec) ->
US = {From#jid.lnode, From#jid.ldomain},
case catch ejabberd_hooks:run_fold(roster_get, To#jid.ldomain, [], [US]) of
US = {exmpp_jid:lnode(From), exmpp_jid:ldomain_(From)},
case catch ejabberd_hooks:run_fold(roster_get, exmpp_jid:ldomain(To), [], [US]) of
Items when is_list(Items) ->
XItems = lists:map(fun item_to_xml/1, Items),
Result = #xmlel{ns = ?NS_ROSTER, name = 'query',
@ -189,7 +191,9 @@ process_iq_set(From, To, #iq{payload = Request} = IQ_Rec) ->
process_item_set(From, To, #xmlel{} = El) ->
try
JID1 = exmpp_jid:list_to_jid(exmpp_xml:get_attribute(El, 'jid', "")),
#jid{node = User, lnode = LUser, ldomain = LServer} = From,
User = exmpp_jid:node(From),
LUser = exmpp_jid:lnode(From),
LServer = exmpp_jid:ldomain(From),
JID = jlib:short_jid(JID1),
LJID = jlib:short_prepd_jid(JID1),
F = fun() ->
@ -216,7 +220,7 @@ process_item_set(From, To, #xmlel{} = El) ->
%% If the item exist in shared roster, take the
%% subscription information from there:
Item3 = ejabberd_hooks:run_fold(roster_process_item,
LServer, Item2, [LServer]),
exmpp_jid:ldomain(From), Item2, [exmpp_jid:ldomain(From)]),
{Item, Item3}
end,
case mnesia:transaction(F) of
@ -305,8 +309,8 @@ process_item_els(Item, []) ->
Item.
push_item(User, Server, From, Item) ->
ejabberd_sm:route(#jid{},
push_item(User, Server, From, Item) when is_binary(User), is_binary(Server) ->
ejabberd_sm:route(exmpp_jid:make_jid(),
exmpp_jid:make_bare_jid(User, Server),
#xmlel{name = 'broadcast', children =
[{item,
@ -317,7 +321,8 @@ push_item(User, Server, From, Item) ->
end, ejabberd_sm:get_user_resources(User, Server)).
% TODO: don't push to those who didn't load roster
push_item(User, Server, Resource, From, Item) ->
push_item(User, Server, Resource, From, Item) when is_binary(User),
is_binary(Server) ->
Request = #xmlel{ns = ?NS_ROSTER, name = 'query',
children = [item_to_xml(Item)]},
ResIQ = exmpp_iq:set(?NS_JABBER_CLIENT, Request,
@ -327,11 +332,10 @@ push_item(User, Server, Resource, From, Item) ->
exmpp_jid:make_jid(User, Server, Resource),
ResIQ).
get_subscription_lists(_, User, Server) ->
get_subscription_lists(_, User, Server)
when is_binary(User), is_binary(Server) ->
try
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
US = {LUser, LServer},
US = {User,Server},
case mnesia:dirty_index_read(roster, US, #roster.us) of
Items when is_list(Items) ->
fill_subscription_lists(Items, [], []);
@ -370,17 +374,16 @@ in_subscription(_, User, Server, JID, Type, Reason) ->
out_subscription(User, Server, JID, Type) ->
process_subscription(out, User, Server, JID, Type, <<>>).
process_subscription(Direction, User, Server, JID1, Type, Reason) ->
process_subscription(Direction, User, Server, JID1, Type, Reason)
when is_binary(User), is_binary(Server) ->
try
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
US = {LUser, LServer},
US = {User, Server},
LJID = jlib:short_prepd_jid(JID1),
F = fun() ->
Item = case mnesia:read({roster, {LUser, LServer, LJID}}) of
Item = case mnesia:read({roster, {User, Server, LJID}}) of
[] ->
JID = jlib:short_jid(JID1),
#roster{usj = {LUser, LServer, LJID},
#roster{usj = {User, Server, LJID},
us = US,
jid = JID};
[I] ->
@ -414,7 +417,7 @@ process_subscription(Direction, User, Server, JID1, Type, Reason) ->
{none, AutoReply};
{none, none} when Item#roster.subscription == none,
Item#roster.ask == in ->
mnesia:delete({roster, {LUser, LServer, LJID}}),
mnesia:delete({roster, {User, Server, LJID}}),
{none, AutoReply};
{Subscription, Pending} ->
AskBinary = case AskMessage of
@ -556,10 +559,11 @@ in_auto_reply(both, none, unsubscribe) -> unsubscribed;
in_auto_reply(_, _, _) -> none.
remove_user(User, Server) ->
remove_user(User, Server)
when is_binary(User), is_binary(Server) ->
try
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
LUser = list_to_binary(exmpp_stringprep:nodeprep(User)),
LServer = list_to_binary(exmpp_stringprep:nameprep(Server)),
US = {LUser, LServer},
F = fun() ->
lists:foreach(fun(R) ->
@ -645,9 +649,10 @@ process_item_attrs_ws(Item, [#xmlattr{name = Attr, value = Val} | Attrs]) ->
process_item_attrs_ws(Item, []) ->
Item.
get_in_pending_subscriptions(Ls, User, Server) ->
get_in_pending_subscriptions(Ls, User, Server)
when is_binary(User), is_binary(Server) ->
JID = exmpp_jid:make_bare_jid(User, Server),
US = {JID#jid.lnode, JID#jid.ldomain},
US = {exmpp_jid:lnode(JID), exmpp_jid:ldomain(JID)},
case mnesia:dirty_index_read(roster, US, #roster.us) of
Result when list(Result) ->
Ls ++ lists:map(
@ -676,12 +681,10 @@ get_in_pending_subscriptions(Ls, User, Server) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
get_jid_info(_, User, Server, JID) ->
get_jid_info(_, User, Server, JID) when is_binary(User), is_binary(Server) ->
try
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
LJID = jlib:short_prepd_jid(JID),
case catch mnesia:dirty_read(roster, {LUser, LServer, LJID}) of
case catch mnesia:dirty_read(roster, {User, Server, LJID}) of
[#roster{subscription = Subscription, groups = Groups}] ->
{Subscription, Groups};
_ ->
@ -691,7 +694,7 @@ get_jid_info(_, User, Server, JID) ->
{none, []};
true ->
case catch mnesia:dirty_read(
roster, {LUser, LServer, LRJID}) of
roster, {User, Server, LRJID}) of
[#roster{subscription = Subscription,
groups = Groups}] ->
{Subscription, Groups};

View File

@ -52,56 +52,58 @@
start(Host, Opts) ->
HostB = list_to_binary(Host),
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
ejabberd_hooks:add(roster_get, Host,
ejabberd_hooks:add(roster_get, HostB,
?MODULE, get_user_roster, 50),
ejabberd_hooks:add(roster_in_subscription, Host,
ejabberd_hooks:add(roster_in_subscription, HostB,
?MODULE, in_subscription, 50),
ejabberd_hooks:add(roster_out_subscription, Host,
ejabberd_hooks:add(roster_out_subscription, HostB,
?MODULE, out_subscription, 50),
ejabberd_hooks:add(roster_get_subscription_lists, Host,
ejabberd_hooks:add(roster_get_subscription_lists, HostB,
?MODULE, get_subscription_lists, 50),
ejabberd_hooks:add(roster_get_jid_info, Host,
ejabberd_hooks:add(roster_get_jid_info, HostB,
?MODULE, get_jid_info, 50),
ejabberd_hooks:add(remove_user, Host,
ejabberd_hooks:add(remove_user, HostB,
?MODULE, remove_user, 50),
ejabberd_hooks:add(anonymous_purge_hook, Host,
ejabberd_hooks:add(anonymous_purge_hook, HostB,
?MODULE, remove_user, 50),
ejabberd_hooks:add(resend_subscription_requests_hook, Host,
ejabberd_hooks:add(resend_subscription_requests_hook, HostB,
?MODULE, get_in_pending_subscriptions, 50),
ejabberd_hooks:add(webadmin_page_host, Host,
ejabberd_hooks:add(webadmin_page_host, HostB,
?MODULE, webadmin_page, 50),
ejabberd_hooks:add(webadmin_user, Host,
ejabberd_hooks:add(webadmin_user, HostB,
?MODULE, webadmin_user, 50),
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_ROSTER,
?MODULE, process_iq, IQDisc).
stop(Host) ->
ejabberd_hooks:delete(roster_get, Host,
HostB = list_to_binary(Host),
ejabberd_hooks:delete(roster_get, HostB,
?MODULE, get_user_roster, 50),
ejabberd_hooks:delete(roster_in_subscription, Host,
ejabberd_hooks:delete(roster_in_subscription, HostB,
?MODULE, in_subscription, 50),
ejabberd_hooks:delete(roster_out_subscription, Host,
ejabberd_hooks:delete(roster_out_subscription, HostB,
?MODULE, out_subscription, 50),
ejabberd_hooks:delete(roster_get_subscription_lists, Host,
ejabberd_hooks:delete(roster_get_subscription_lists, HostB,
?MODULE, get_subscription_lists, 50),
ejabberd_hooks:delete(roster_get_jid_info, Host,
ejabberd_hooks:delete(roster_get_jid_info, HostB,
?MODULE, get_jid_info, 50),
ejabberd_hooks:delete(remove_user, Host,
ejabberd_hooks:delete(remove_user, HostB,
?MODULE, remove_user, 50),
ejabberd_hooks:delete(anonymous_purge_hook, Host,
ejabberd_hooks:delete(anonymous_purge_hook, HostB,
?MODULE, remove_user, 50),
ejabberd_hooks:delete(resend_subscription_requests_hook, Host,
ejabberd_hooks:delete(resend_subscription_requests_hook, HostB,
?MODULE, get_in_pending_subscriptions, 50),
ejabberd_hooks:delete(webadmin_page_host, Host,
ejabberd_hooks:delete(webadmin_page_host, HostB,
?MODULE, webadmin_page, 50),
ejabberd_hooks:delete(webadmin_user, Host,
ejabberd_hooks:delete(webadmin_user, HostB,
?MODULE, webadmin_user, 50),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_ROSTER).
process_iq(From, To, IQ_Rec) ->
#jid{ldomain = LServer} = From,
LServer = exmpp_jid:ldomain_as_list(From),
case lists:member(LServer, ?MYHOSTS) of
true ->
process_local_iq(From, To, IQ_Rec);
@ -117,8 +119,8 @@ process_local_iq(From, To, #iq{type = set} = IQ_Rec) ->
process_iq_get(From, To, IQ_Rec) ->
US = {From#jid.lnode, From#jid.ldomain},
case catch ejabberd_hooks:run_fold(roster_get, To#jid.ldomain, [], [US]) of
US = {exmpp_jid:lnode(From), exmpp_jid:ldomain(From)},
case catch ejabberd_hooks:run_fold(roster_get, exmpp_jid:ldomain(To), [], [US]) of
Items when is_list(Items) ->
XItems = lists:map(fun item_to_xml/1, Items),
Result = #xmlel{ns = ?NS_ROSTER, name = 'query',
@ -136,13 +138,14 @@ get_user_roster(Acc, {LUser, LServer}) ->
true
end, Items) ++ Acc.
get_roster(LUser, LServer) ->
Username = ejabberd_odbc:escape(LUser),
case catch odbc_queries:get_roster(LServer, Username) of
get_roster(LUser, LServer) when is_binary(LUser), is_binary(LServer)->
Username = ejabberd_odbc:escape(binary_to_list(LUser)),
DomainString = binary_to_list(LServer),
case catch odbc_queries:get_roster(DomainString, Username) of
{selected, ["username", "jid", "nick", "subscription", "ask",
"askmessage", "server", "subscribe", "type"],
Items} when is_list(Items) ->
JIDGroups = case catch odbc_queries:get_roster_jid_groups(LServer, Username) of
JIDGroups = case catch odbc_queries:get_roster_jid_groups(DomainString, Username) of
{selected, ["jid","grp"], JGrps}
when is_list(JGrps) ->
JGrps;
@ -214,7 +217,8 @@ process_iq_set(From, To, #iq{payload = Request} = IQ_Rec) ->
process_item_set(From, To, #xmlel{} = El) ->
try
JID1 = exmpp_jid:list_to_jid(exmpp_xml:get_attribute(El, 'jid', "")),
#jid{node = User, lnode = LUser, ldomain = LServer} = From,
LUser = exmpp_jid:lnode_as_list(From),
LServer = exmpp_jid:ldomain_as_list(From),
{U0, S0, R0} = LJID = jlib:short_prepd_jid(JID1),
Username = ejabberd_odbc:escape(LUser),
SJID = ejabberd_odbc:escape(exmpp_jid:jid_to_list(U0, S0, R0)),
@ -229,7 +233,7 @@ process_item_set(From, To, #xmlel{} = El) ->
us = {LUser, LServer},
jid = LJID};
[I] ->
R = raw_to_record(LServer, I),
R = raw_to_record(exmpp_jid:ldomain(From), I),
case R of
%% Bad JID in database:
error ->
@ -257,12 +261,12 @@ process_item_set(From, To, #xmlel{} = El) ->
%% If the item exist in shared roster, take the
%% subscription information from there:
Item3 = ejabberd_hooks:run_fold(roster_process_item,
LServer, Item2, [LServer]),
exmpp_jid:ldomain(From), Item2, [exmpp_jid:ldomain(From)]),
{Item, Item3}
end,
case odbc_queries:sql_transaction(LServer, F) of
{atomic, {OldItem, Item}} ->
push_item(User, LServer, To, Item),
push_item(exmpp_jid:node(From), exmpp_jid:ldomain(From), To, Item),
case Item#roster.subscription of
remove ->
IsTo = case OldItem#roster.subscription of
@ -340,8 +344,8 @@ process_item_els(Item, []) ->
Item.
push_item(User, Server, From, Item) ->
ejabberd_sm:route(#jid{},
push_item(User, Server, From, Item) when is_binary(User), is_binary(Server) ->
ejabberd_sm:route(exmpp_jid:make_jid(),
exmpp_jid:make_bare_jid(User, Server),
#xmlel{name = 'broadcast', children =
[{item,
@ -362,16 +366,17 @@ push_item(User, Server, Resource, From, Item) ->
exmpp_jid:make_jid(User, Server, Resource),
ResIQ).
get_subscription_lists(_, User, Server) ->
get_subscription_lists(_, User, Server)
when is_binary(User), is_binary(Server) ->
try
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
LUser = binary_to_list(User),
LServer = binary_to_list(Server),
Username = ejabberd_odbc:escape(LUser),
case catch odbc_queries:get_roster(LServer, Username) of
{selected, ["username", "jid", "nick", "subscription", "ask",
"askmessage", "server", "subscribe", "type"],
Items} when is_list(Items) ->
fill_subscription_lists(LServer, Items, [], []);
fill_subscription_lists(Server, Items, [], []);
_ ->
{[], []}
end
@ -414,10 +419,11 @@ in_subscription(_, User, Server, JID, Type, Reason) ->
out_subscription(User, Server, JID, Type) ->
process_subscription(out, User, Server, JID, Type, <<>>).
process_subscription(Direction, User, Server, JID1, Type, Reason) ->
process_subscription(Direction, User, Server, JID1, Type, Reason)
when is_binary(User), is_binary(Server) ->
try
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
LUser = binary_to_list(User),
LServer = binary_to_list(Server),
{N0,D0,R0} = LJID = jlib:short_prepd_jid(JID1),
Username = ejabberd_odbc:escape(LUser),
SJID = ejabberd_odbc:escape(exmpp_jid:jid_to_list(N0,D0,R0)),
@ -430,7 +436,7 @@ process_subscription(Direction, User, Server, JID1, Type, Reason) ->
[I]} ->
%% raw_to_record can return error, but
%% jlib_to_string would fail before this point
R = raw_to_record(LServer, I),
R = raw_to_record(list_to_binary(LServer), I),
Groups =
case odbc_queries:get_roster_groups(LServer, Username, SJID) of
{selected, ["grp"], JGrps} when is_list(JGrps) ->
@ -443,8 +449,8 @@ process_subscription(Direction, User, Server, JID1, Type, Reason) ->
["username", "jid", "nick", "subscription", "ask",
"askmessage", "server", "subscribe", "type"],
[]} ->
#roster{usj = {LUser, LServer, LJID},
us = {LUser, LServer},
#roster{usj = {list_to_binary(LUser), list_to_binary(LServer), LJID},
us = {list_to_binary(LUser), list_to_binary(LServer)},
jid = LJID}
end,
NewState = case Direction of
@ -619,7 +625,7 @@ in_auto_reply(both, none, unsubscribe) -> unsubscribed;
in_auto_reply(_, _, _) -> none.
remove_user(User, Server) ->
remove_user(User, Server) when is_binary(User), is_binary(Server) ->
try
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
@ -705,10 +711,11 @@ process_item_attrs_ws(Item, [#xmlattr{name = Attr, value = Val} | Attrs]) ->
process_item_attrs_ws(Item, []) ->
Item.
get_in_pending_subscriptions(Ls, User, Server) ->
get_in_pending_subscriptions(Ls, User, Server)
when is_binary(User), is_binary(Server) ->
JID = exmpp_jid:make_bare_jid(User, Server),
LUser = JID#jid.lnode,
LServer = JID#jid.ldomain,
LUser = exmpp_jid:lnode_as_list(JID),
LServer = exmpp_jid:ldomain_as_list(JID),
Username = ejabberd_odbc:escape(LUser),
case catch odbc_queries:get_roster(LServer, Username) of
{selected, ["username", "jid", "nick", "subscription", "ask",
@ -726,7 +733,7 @@ get_in_pending_subscriptions(Ls, User, Server) ->
end,
lists:flatmap(
fun(I) ->
case raw_to_record(LServer, I) of
case raw_to_record(exmpp_jid:ldomain(JID), I) of
%% Bad JID in database:
error ->
[];
@ -745,12 +752,12 @@ get_in_pending_subscriptions(Ls, User, Server) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% JID is #jid record, because it's used latter on for both short_prepd_jid
%% JID is jid() record, because it's used latter on for both short_prepd_jid
%% and short_prepd_bare_jid
get_jid_info(_, User, Server, JID) ->
get_jid_info(_, User, Server, JID) when is_binary(User), is_binary(Server) ->
try
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
LUser = binary_to_list(User),
LServer = binary_to_list(Server),
LJID = {N, D, R} = jlib:short_prepd_jid(JID),
Username = ejabberd_odbc:escape(LUser),
SJID = ejabberd_odbc:escape(exmpp_jid:jid_to_list(N, D, R)),
@ -805,7 +812,7 @@ get_jid_info(_, User, Server, JID) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
raw_to_record(LServer, {User, SJID, Nick, SSubscription, SAsk, SAskMessage,
_SServer, _SSubscribe, _SType}) ->
_SServer, _SSubscribe, _SType}) when is_binary(LServer) ->
try
JID = exmpp_jid:list_to_jid(SJID),
LJID = jlib:short_prepd_jid(JID),
@ -823,8 +830,9 @@ raw_to_record(LServer, {User, SJID, Nick, SSubscription, SAsk, SAskMessage,
"I" -> in;
_ -> none
end,
#roster{usj = {User, LServer, LJID},
us = {User, LServer},
UserB = list_to_binary(User),
#roster{usj = {UserB, LServer, LJID},
us = {UserB, LServer},
jid = LJID,
name = Nick,
subscription = Subscription,
@ -841,7 +849,7 @@ record_to_string(#roster{us = {User, _Server},
subscription = Subscription,
ask = Ask,
askmessage = AskMessage}) ->
Username = ejabberd_odbc:escape(User),
Username = ejabberd_odbc:escape(binary_to_list(User)),
{U, S, R} = JID,
SJID = ejabberd_odbc:escape(exmpp_jid:jid_to_list(U, S, R)),
Nick = ejabberd_odbc:escape(Name),

View File

@ -39,35 +39,37 @@
-include("ejabberd.hrl").
start(Host, _Opts) ->
ejabberd_hooks:add(user_send_packet, Host,
HostB = list_to_binary(Host),
ejabberd_hooks:add(user_send_packet, HostB,
?MODULE, log_user_send, 50),
ejabberd_hooks:add(user_receive_packet, Host,
ejabberd_hooks:add(user_receive_packet, HostB,
?MODULE, log_user_receive, 50),
ok.
stop(Host) ->
ejabberd_hooks:delete(user_send_packet, Host,
HostB = list_to_binary(Host),
ejabberd_hooks:delete(user_send_packet, HostB,
?MODULE, log_user_send, 50),
ejabberd_hooks:delete(user_receive_packet, Host,
ejabberd_hooks:delete(user_receive_packet, HostB,
?MODULE, log_user_receive, 50),
ok.
log_user_send(From, To, Packet) ->
log_packet(From, To, Packet, From#jid.ldomain).
log_packet(From, To, Packet, exmpp_jid:ldomain_as_list(From)).
log_user_receive(_JID, From, To, Packet) ->
log_packet(From, To, Packet, To#jid.ldomain).
log_packet(From, To, Packet, exmpp_jid:ldomain_as_list(To)).
log_packet(From, To, Packet, Host) ->
Loggers = gen_mod:get_module_opt(Host, ?MODULE, loggers, []),
ServerJID = #jid{domain = Host, ldomain = Host},
ServerJID = exmpp_jid:make_bare_jid(Host),
FixedPacket = exmpp_stanza:set_jids(Packet, From, To),
lists:foreach(
fun(Logger) ->
ejabberd_router:route(
ServerJID,
#jid{domain = Logger, ldomain = Logger},
exmpp_jid:make_bare_jid(Logger),
#xmlel{name = 'route', children = [FixedPacket]})
end, Loggers).

View File

@ -60,6 +60,7 @@
-record(sr_user, {us, group_host}).
start(Host, _Opts) ->
HostB = list_to_binary(Host),
mnesia:create_table(sr_group,
[{disc_copies, [node()]},
{attributes, record_info(fields, sr_group)}]),
@ -68,47 +69,48 @@ start(Host, _Opts) ->
{type, bag},
{attributes, record_info(fields, sr_user)}]),
mnesia:add_table_index(sr_user, group_host),
ejabberd_hooks:add(webadmin_menu_host, Host,
ejabberd_hooks:add(webadmin_menu_host, HostB,
?MODULE, webadmin_menu, 70),
ejabberd_hooks:add(webadmin_page_host, Host,
ejabberd_hooks:add(webadmin_page_host, HostB,
?MODULE, webadmin_page, 50),
ejabberd_hooks:add(roster_get, Host,
ejabberd_hooks:add(roster_get, HostB,
?MODULE, get_user_roster, 70),
ejabberd_hooks:add(roster_in_subscription, Host,
ejabberd_hooks:add(roster_in_subscription, HostB,
?MODULE, in_subscription, 30),
ejabberd_hooks:add(roster_out_subscription, Host,
ejabberd_hooks:add(roster_out_subscription, HostB,
?MODULE, out_subscription, 30),
ejabberd_hooks:add(roster_get_subscription_lists, Host,
ejabberd_hooks:add(roster_get_subscription_lists, HostB,
?MODULE, get_subscription_lists, 70),
ejabberd_hooks:add(roster_get_jid_info, Host,
ejabberd_hooks:add(roster_get_jid_info, HostB,
?MODULE, get_jid_info, 70),
ejabberd_hooks:add(roster_process_item, Host,
ejabberd_hooks:add(roster_process_item, HostB,
?MODULE, process_item, 50),
ejabberd_hooks:add(user_registered, Host,
ejabberd_hooks:add(user_registered, HostB,
?MODULE, user_registered, 50).
%%ejabberd_hooks:add(remove_user, Host,
%%ejabberd_hooks:add(remove_user, HostB,
%% ?MODULE, remove_user, 50),
stop(Host) ->
ejabberd_hooks:delete(webadmin_menu_host, Host,
HostB = list_to_binary(Host),
ejabberd_hooks:delete(webadmin_menu_host, HostB,
?MODULE, webadmin_menu, 70),
ejabberd_hooks:delete(webadmin_page_host, Host,
ejabberd_hooks:delete(webadmin_page_host, HostB,
?MODULE, webadmin_page, 50),
ejabberd_hooks:delete(roster_get, Host,
ejabberd_hooks:delete(roster_get, HostB,
?MODULE, get_user_roster, 70),
ejabberd_hooks:delete(roster_in_subscription, Host,
ejabberd_hooks:delete(roster_in_subscription, HostB,
?MODULE, in_subscription, 30),
ejabberd_hooks:delete(roster_out_subscription, Host,
ejabberd_hooks:delete(roster_out_subscription, HostB,
?MODULE, out_subscription, 30),
ejabberd_hooks:delete(roster_get_subscription_lists, Host,
ejabberd_hooks:delete(roster_get_subscription_lists, HostB,
?MODULE, get_subscription_lists, 70),
ejabberd_hooks:delete(roster_get_jid_info, Host,
ejabberd_hooks:delete(roster_get_jid_info, HostB,
?MODULE, get_jid_info, 70),
ejabberd_hooks:delete(roster_process_item, Host,
ejabberd_hooks:delete(roster_process_item, HostB,
?MODULE, process_item, 50),
ejabberd_hooks:delete(user_registered, Host,
ejabberd_hooks:delete(user_registered, HostB,
?MODULE, user_registered, 50).
%%ejabberd_hooks:delete(remove_user, Host,
%%ejabberd_hooks:delete(remove_user, HostB,
%% ?MODULE, remove_user, 50),
@ -252,10 +254,11 @@ set_item(User, Server, Resource, Item) ->
ResIQ).
get_subscription_lists({F, T}, User, Server) ->
get_subscription_lists({F, T}, User, Server)
when is_binary(User), is_binary(Server) ->
try
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
LUser = binary_to_list(User),
LServer = binary_to_list(Server),
US = {LUser, LServer},
DisplayedGroups = get_user_displayed_groups(US),
SRUsers =
@ -271,10 +274,11 @@ get_subscription_lists({F, T}, User, Server) ->
{[], []}
end.
get_jid_info({Subscription, Groups}, User, Server, JID) ->
get_jid_info({Subscription, Groups}, User, Server, JID)
when is_binary(User), is_binary(Server) ->
try
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
LUser = binary_to_list(User),
LServer = binary_to_list(Server),
US = {LUser, LServer},
{U1, S1, _} = jlib:short_prepd_jid(JID),
US1 = {U1, S1},
@ -574,7 +578,7 @@ push_item(User, Server, From, Item) ->
fun(Resource) ->
JID = exmpp_jid:make_jid(User, Server, Resource),
ejabberd_router:route(JID, JID, Stanza)
end, ejabberd_sm:get_user_resources(User, Server)).
end, ejabberd_sm:get_user_resources(list_to_binary(User), list_to_binary(Server))).
item_to_xml(Item) ->
{U, S, R} = Item#roster.jid,
@ -807,7 +811,7 @@ shared_roster_group_parse_query(Host, Group, Query) ->
_ ->
try
JID = exmpp_jid:list_to_jid(SJID),
[{JID#jid.lnode, JID#jid.ldomain} | USs]
[{exmpp_jid:lnode_as_list(JID), exmpp_jid:ldomain_as_list(JID)} | USs]
catch
_ ->
error

View File

@ -49,7 +49,7 @@ process_local_iq(_From, To, #iq{type = get,
Node = string:tokens(exmpp_xml:get_attribute(SubEl, 'node', ""), "/"),
Names = get_names(exmpp_xml:get_child_elements(SubEl), []),
case get_local_stats(To#jid.domain, Node, Names) of
case get_local_stats(exmpp_jid:domain_as_list(To), Node, Names) of
{result, Res} ->
Result = #xmlel{ns = XMLNS, name = 'query', children = Res},
exmpp_iq:result(IQ_Rec, Result);
@ -130,7 +130,7 @@ get_local_stats(_Server, _, _) ->
get_local_stat(Server, [], Name) when Name == "users/online" ->
case catch ejabberd_sm:get_vh_session_list(Server) of
case catch ejabberd_sm:get_vh_session_list(list_to_binary(Server)) of
{'EXIT', _Reason} ->
?STATERR("500", "Internal Server Error");
Users ->

View File

@ -62,6 +62,7 @@
-define(PROCNAME, ejabberd_mod_vcard).
start(Host, Opts) ->
HostB = list_to_binary(Host),
mnesia:create_table(vcard, [{disc_only_copies, [node()]},
{attributes, record_info(fields, vcard)}]),
mnesia:create_table(vcard_search,
@ -81,14 +82,14 @@ start(Host, Opts) ->
mnesia:add_table_index(vcard_search, lorgname),
mnesia:add_table_index(vcard_search, lorgunit),
ejabberd_hooks:add(remove_user, Host,
ejabberd_hooks:add(remove_user, HostB,
?MODULE, remove_user, 50),
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD,
?MODULE, process_local_iq, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_VCARD,
?MODULE, process_sm_iq, IQDisc),
ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
ejabberd_hooks:add(disco_sm_features, HostB, ?MODULE, get_sm_features, 50),
MyHost = gen_mod:get_opt_host(Host, Opts, "vjud.@HOST@"),
Search = gen_mod:get_opt(search, Opts, true),
register(gen_mod:get_module_proc(Host, ?PROCNAME),
@ -122,13 +123,14 @@ loop(Host, ServerHost) ->
end.
stop(Host) ->
ejabberd_hooks:delete(remove_user, Host,
HostB = list_to_binary(Host),
ejabberd_hooks:delete(remove_user, HostB,
?MODULE, remove_user, 50),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host,
?NS_VCARD),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host,
?NS_VCARD),
ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
ejabberd_hooks:delete(disco_sm_features, HostB, ?MODULE, get_sm_features, 50),
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
Proc ! stop,
{wait, Proc}.
@ -167,7 +169,8 @@ process_local_iq(_From, _To, #iq{type = set} = IQ_Rec) ->
process_sm_iq(_From, To, #iq{type = get} = IQ_Rec) ->
#jid{lnode = LUser, ldomain = LServer} = To,
LUser = exmpp_jid:lnode_as_list(To),
LServer = exmpp_jid:ldomain_as_list(To),
US = {LUser, LServer},
F = fun() ->
mnesia:read({vcard, US})
@ -187,7 +190,8 @@ process_sm_iq(_From, To, #iq{type = get} = IQ_Rec) ->
exmpp_iq:result(IQ_Rec)
end;
process_sm_iq(From, _To, #iq{type = set, payload = Request} = IQ_Rec) ->
#jid{node = User, ldomain = LServer} = From,
User = exmpp_jid:node_as_list(From),
LServer = exmpp_jid:ldomain_as_list(From),
case lists:member(LServer, ?MYHOSTS) of
true ->
set_vcard(User, LServer, Request),
@ -307,7 +311,8 @@ set_vcard(User, LServer, VCARD) ->
do_route(ServerHost, From, To, Packet) ->
#jid{node = User, resource = Resource} = To,
User = exmpp_jid:node(To),
Resource = exmpp_jid:resource(To),
if
(User /= undefined) or (Resource /= undefined) ->
Err = exmpp_stanza:reply_with_error(Packet, 'service-unavailable'),
@ -651,7 +656,7 @@ reindex_vcards() ->
mnesia:transaction(F).
remove_user(User, Server) ->
remove_user(User, Server) when is_binary(User), is_binary(Server) ->
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
US = {LUser, LServer},

View File

@ -155,7 +155,7 @@ terminate(_Reason, State) ->
Host = State#state.serverhost,
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_VCARD),
ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
ejabberd_hooks:delete(disco_sm_features, list_to_binary(Host), ?MODULE, get_sm_features, 50),
case State#state.search of
true ->
ejabberd_router:unregister_route(State#state.myhost);
@ -174,7 +174,8 @@ init([Host, Opts]) ->
?MODULE, process_local_iq, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_VCARD,
?MODULE, process_sm_iq, IQDisc),
ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
ejabberd_hooks:add(disco_sm_features,
list_to_binary(Host), ?MODULE, get_sm_features, 50),
eldap_pool:start_link(State#state.eldap_id,
State#state.servers,
State#state.backups,
@ -234,7 +235,8 @@ process_local_iq(_From, _To, #iq{type = get, lang = Lang} = IQ_Rec) ->
process_local_iq(_From, _To, #iq{type = set} = IQ_Rec) ->
exmpp_iq:error(IQ_Rec, 'not-allowed').
process_sm_iq(_From, #jid{ldomain=LServer} = To, #iq{} = IQ_Rec) ->
process_sm_iq(_From, To, #iq{} = IQ_Rec) ->
LServer = exmpp_jid:ldomain_as_list(To),
case catch process_vcard_ldap(To, IQ_Rec, LServer) of
{'EXIT', _} ->
exmpp_iq:error(IQ_Rec, 'internal-server-error');
@ -248,7 +250,7 @@ process_vcard_ldap(To, IQ_Rec, Server) ->
set ->
exmpp_iq:error(IQ_Rec, 'not-allowed');
get ->
#jid{lnode = LUser} = To,
LUser = exmpp_jid:lnode_as_list(To),
LServer = State#state.serverhost,
case ejabberd_auth:is_user_exists(LUser, LServer) of
true ->
@ -402,7 +404,8 @@ do_route(State, From, To, Packet) ->
spawn(?MODULE, route, [State, From, To, Packet]).
route(State, From, To, Packet) ->
#jid{node = User, resource = Resource} = To,
User = exmpp_jid:node(To),
Resource = exmpp_jid:resource(To),
if
(User /= undefined) or (Resource /= undefined) ->
Err = exmpp_stanza:reply_with_error(Packet, 'service-unavailable'),

View File

@ -45,14 +45,15 @@
-define(PROCNAME, ejabberd_mod_vcard).
start(Host, Opts) ->
ejabberd_hooks:add(remove_user, Host,
HostB = list_to_binary(Host),
ejabberd_hooks:add(remove_user, HostB,
?MODULE, remove_user, 50),
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_VCARD,
?MODULE, process_local_iq, IQDisc),
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_VCARD,
?MODULE, process_sm_iq, IQDisc),
ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
ejabberd_hooks:add(disco_sm_features, HostB, ?MODULE, get_sm_features, 50),
MyHost = gen_mod:get_opt_host(Host, Opts, "vjud.@HOST@"),
Search = gen_mod:get_opt(search, Opts, true),
register(gen_mod:get_module_proc(Host, ?PROCNAME),
@ -86,11 +87,12 @@ loop(Host, ServerHost) ->
end.
stop(Host) ->
ejabberd_hooks:delete(remove_user, Host,
HostB = list_to_binary(Host),
ejabberd_hooks:delete(remove_user, HostB,
?MODULE, remove_user, 50),
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_VCARD),
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_VCARD),
ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
ejabberd_hooks:delete(disco_sm_features, HostB, ?MODULE, get_sm_features, 50),
Proc = gen_mod:get_module_proc(Host, ?PROCNAME),
Proc ! stop,
{wait, Proc}.
@ -129,12 +131,14 @@ process_local_iq(_From, _To, #iq{type = set} = IQ_Rec) ->
process_sm_iq(_From, To, #iq{type = get} = IQ_Rec) ->
#jid{lnode = LUser, ldomain = LServer} = To,
LUser = exmpp_jid:lnode_as_list(To),
LServer = exmpp_jid:ldomain_as_list(To),
Username = ejabberd_odbc:escape(LUser),
case catch odbc_queries:get_vcard(LServer, Username) of
{selected, ["vcard"], [{SVCARD}]} ->
try exmpp_xml:parse_document(SVCARD,
[names_as_atom]) of
[names_as_atom, {check_elems, xmpp},
{check_nss,xmpp}, {check_attrs,xmpp}]) of
[VCARD] ->
exmpp_iq:result(IQ_Rec, VCARD)
catch
@ -148,7 +152,8 @@ process_sm_iq(_From, To, #iq{type = get} = IQ_Rec) ->
exmpp_iq:error(IQ_Rec, 'internal-server-error')
end;
process_sm_iq(From, _To, #iq{type = set, payload = Request} = IQ_Rec) ->
#jid{node = User, ldomain = LServer} = From,
User = exmpp_jid:node_as_list(From),
LServer = exmpp_jid:ldomain_as_list(From),
case lists:member(LServer, ?MYHOSTS) of
true ->
set_vcard(User, LServer, Request),
@ -277,7 +282,8 @@ set_vcard(User, LServer, VCARD) ->
]}]).
do_route(ServerHost, From, To, Packet) ->
#jid{node = User, resource = Resource} = To,
User = exmpp_jid:node(To),
Resource = exmpp_jid:resource(To),
if
(User /= undefined) or (Resource /= undefined) ->
Err = exmpp_stanza:reply_with_error(Packet, 'service-unavailable'),
@ -615,7 +621,7 @@ make_val(Match, Field, Val) ->
% mnesia:transaction(F).
remove_user(User, Server) ->
remove_user(User, Server) when is_binary(User), is_binary(server) ->
LUser = exmpp_stringprep:nodeprep(User),
LServer = exmpp_stringprep:nameprep(Server),
Username = ejabberd_odbc:escape(LUser),

View File

@ -53,7 +53,7 @@ process_local_iq(_From, To, #iq{type = Type} = IQ_Rec) ->
set ->
exmpp_iq:error(IQ_Rec, 'not-allowed');
get ->
Host = To#jid.domain,
Host = exmpp_jid:domain_as_list(To),
OS = case gen_mod:get_module_opt(Host, ?MODULE, show_os, true) of
true -> [get_os()];
false -> []