diff --git a/src/mod_configure.erl b/src/mod_configure.erl index b8b8c4b4b..012319368 100644 --- a/src/mod_configure.erl +++ b/src/mod_configure.erl @@ -1593,7 +1593,7 @@ set_form(From, Host, ?NS_ADMINL("add-user"), _Lang, XData) -> AccountJID = exmpp_jid:parse(AccountString), User = exmpp_jid:prep_node_as_list(AccountJID), Server = exmpp_jid:prep_domain_as_list(AccountJID), - true = lists:member(Server, ?MYHOSTS), + true = ?IS_MY_HOST(Server), true = (Server == Host) orelse (get_permission_level(From) == global), ejabberd_auth:try_register(User, Server, Password), {result, []}; diff --git a/src/mod_disco.erl b/src/mod_disco.erl index 01a818866..f2988a2a7 100644 --- a/src/mod_disco.erl +++ b/src/mod_disco.erl @@ -45,11 +45,13 @@ register_feature/2, unregister_feature/2, register_extra_domain/2, - unregister_extra_domain/2]). + unregister_extra_domain/2, + get_vh_services/1]). -include_lib("exmpp/include/exmpp.hrl"). -include("ejabberd.hrl"). +-include_lib("stdlib/include/ms_transform.hrl"). start(Host, Opts) -> HostB = list_to_binary(Host), @@ -192,8 +194,13 @@ get_local_features(Acc, _From, To, <<>>, _Lang) -> empty -> [] end, HostB = exmpp_jid:prep_domain(To), + NHostB = ejabberd:normalize_host(HostB), {result, - ets:select(disco_features, [{{{'_', HostB}}, [], ['$_']}]) ++ Feats}; + ets:select(disco_features, [{{{'_', NHostB}}, [], + ['$_']}]) ++ + ets:select(disco_features, [{{{'_', global}}, [], + ['$_']}]) ++ + Feats}; get_local_features(Acc, _From, _To, _Node, _Lang) -> case Acc of @@ -239,14 +246,18 @@ get_local_services(Acc, _From, To, <<>>, _Lang) -> {result, Its} -> Its; empty -> [] end, - HostB = exmpp_jid:prep_domain(To), - Host = binary_to_list(HostB), + Host = exmpp_jid:prep_domain_as_list(To), + NHost = ejabberd:normalize_host(Host), {result, lists:usort( lists:map(fun domain_to_xml/1, get_vh_services(Host) ++ ets:select(disco_extra_domains, - [{{{'$1', HostB}}, [], ['$1']}])) + ets:fun2ms(fun ({{Service, H}}) + when H =:= NHost; + H =:= global -> + Service + end))) ) ++ Items}; get_local_services({result, _} = Acc, _From, _To, _Node, _Lang) -> @@ -255,19 +266,24 @@ get_local_services({result, _} = Acc, _From, _To, _Node, _Lang) -> get_local_services(empty, _From, _To, _Node, _Lang) -> {error, 'item-not-found'}. +%% Note: only first-order subdomains are returned. +%% For example, if Host = "a", +%% and Routes = ["muc.a", "vjud.a", "private.muc.a", "muc.b"] +%% only returns ["muc.a", "vjud.a"] get_vh_services(Host) -> - Hosts = lists:sort(fun(H1, H2) -> length(H1) >= length(H2) end, ?MYHOSTS), - lists:filter(fun(H) -> - case lists:dropwhile( - fun(VH) -> - not lists:suffix("." ++ VH, H) - end, Hosts) of - [] -> - false; - [VH | _] -> - VH == Host - end - end, ejabberd_router:dirty_get_all_routes()). + Routes = ejabberd_router:dirty_get_all_routes(), + HostTokenized = string:tokens(Host, "."), + VhServices = + lists:filter(fun(H) -> + case string:tokens(H, ".") of + [_ | HostTokenized] -> + true; + _ -> + false + end + end, Routes), + GlobalServices = ejabberd_global_router:expand_routes(Host), + VhServices ++ GlobalServices. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/src/mod_echo.erl b/src/mod_echo.erl index 689285220..31d22ef76 100644 --- a/src/mod_echo.erl +++ b/src/mod_echo.erl @@ -86,7 +86,7 @@ stop(Host) -> %% Description: Initiates the server %%-------------------------------------------------------------------- init([Host, Opts]) -> - MyHost = gen_mod:get_opt_host(Host, Opts, "echo.@HOST@"), + MyHost = gen_mod:expand_host_name(Host, Opts, "echo"), ClientVersion = gen_mod:get_opt(client_version, Opts, false), ejabberd_router:register_route(MyHost), {ok, #state{host = MyHost, client_version = ClientVersion}}. diff --git a/src/mod_muc/mod_muc.erl b/src/mod_muc/mod_muc.erl index 7a0daf23a..57888b161 100644 --- a/src/mod_muc/mod_muc.erl +++ b/src/mod_muc/mod_muc.erl @@ -209,7 +209,7 @@ init([Host, Opts]) -> {attributes, record_info(fields, muc_online_room)}]), mnesia:add_table_copy(muc_online_room, node(), ram_copies), catch ets:new(muc_online_users, [bag, named_table, public, {keypos, 2}]), - MyHost_L = gen_mod:get_opt_host(Host, Opts, "conference.@HOST@"), + MyHost_L = gen_mod:expand_host_name(Host, Opts, "conference"), MyHost = list_to_binary(MyHost_L), update_tables(MyHost), mnesia:add_table_index(muc_registered, nick), diff --git a/src/mod_private.erl b/src/mod_private.erl index 7614c6a8f..6b43d022c 100644 --- a/src/mod_private.erl +++ b/src/mod_private.erl @@ -114,7 +114,7 @@ check_packet(From, To, IQ_Rec, [F | R]) -> check_domain(From, _To, _IQ_Rec) -> LServer = exmpp_jid:prep_domain_as_list(From), - case lists:member(LServer, ?MYHOSTS) of + case ?IS_MY_HOST(LServer) of true -> ok; false -> {error, 'not-allowed'} end. diff --git a/src/mod_proxy65/mod_proxy65_service.erl b/src/mod_proxy65/mod_proxy65_service.erl index 7ccbbb53d..4ef785d07 100644 --- a/src/mod_proxy65/mod_proxy65_service.erl +++ b/src/mod_proxy65/mod_proxy65_service.erl @@ -222,7 +222,7 @@ iq_vcard(Lang) -> "\nCopyright (c) 2003-2010 Alexey Shchepin")}]}]. parse_options(ServerHost, Opts) -> - MyHost = gen_mod:get_opt_host(ServerHost, Opts, "proxy.@HOST@"), + MyHost = gen_mod:expand_host_name(ServerHost, Opts, "proxy"), Port = gen_mod:get_opt(port, Opts, 7777), ACL = gen_mod:get_opt(access, Opts, all), Name = gen_mod:get_opt(name, Opts, "SOCKS5 Bytestreams"), diff --git a/src/mod_pubsub/mod_pubsub.erl b/src/mod_pubsub/mod_pubsub.erl index 14e3af534..73e622757 100644 --- a/src/mod_pubsub/mod_pubsub.erl +++ b/src/mod_pubsub/mod_pubsub.erl @@ -176,7 +176,7 @@ stop(Host) -> %%-------------------------------------------------------------------- init([ServerHost, Opts]) -> ?DEBUG("pubsub init ~p ~p",[ServerHost,Opts]), - Host = gen_mod:get_opt_host(ServerHost, Opts, "pubsub.@HOST@"), + Host = gen_mod:expand_host_name(ServerHost, Opts, "pubsub"), Access = gen_mod:get_opt(access_createnode, Opts, all), PepOffline = gen_mod:get_opt(ignore_pep_from_offline, Opts, true), IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue), @@ -2643,7 +2643,7 @@ set_options_helper(Configuration, JID, NodeID, SubID, Type) -> _ -> invalid end, Subscriber = try exmpp_jid:parse(JID) of - J -> jlib:short_jid(J) + J -> J catch _ -> exmpp_jid:make("", "", "") %% TODO, check if use <<>> instead of "" end, @@ -2770,8 +2770,9 @@ get_subscriptions(Host, Node, JID) -> end end, case transaction(Host, Node, Action, sync_dirty) of - {result, {_, []}} -> - {error, 'item-not-found'}; +%% Fix bug when node owner retrieve an empty subscriptions list +% {result, {_, []}} -> +% {error, 'item-not-found'}; {result, {_, Subscriptions}} -> Entities = lists:flatmap( fun({_, none}) -> []; @@ -3289,7 +3290,7 @@ broadcast_stanza({LUser, LServer, LResource}, Publisher, Node, NodeId, Type, Nod Contacts when is_list(Contacts) -> lists:foreach(fun({U, S, _}) -> spawn(fun() -> - case lists:member(S, ?MYHOSTS) of + case ?IS_MY_HOST(S) of true -> lists:foreach(fun(R) -> ejabberd_router:route(Sender, exmpp_jid:make(U, S, R), StanzaToSend) @@ -3993,8 +3994,8 @@ is_feature_supported(_, []) -> true; is_feature_supported(#xmlel{name = 'presence', children = Els}, Feature) -> case mod_caps:read_caps(Els) of - nothing -> false; - Caps -> lists:member(Feature ++ "+notify", mod_caps:get_features(Caps)) + nothing -> false; + Caps -> lists:member(Feature ++ "+notify", mod_caps:get_features(Caps)) end. on_user_offline(_, JID, _) -> diff --git a/src/mod_roster.erl b/src/mod_roster.erl index b8df1510c..5ed8d92d0 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -154,7 +154,7 @@ stop(Host) when is_list(Host) -> process_iq(From, To, IQ_Rec) when ?IS_JID(From), ?IS_JID(To), ?IS_IQ_RECORD(IQ_Rec) -> LServer = exmpp_jid:prep_domain_as_list(From), - case lists:member(LServer, ?MYHOSTS) of + case ?IS_MY_HOST(LServer) of true -> process_local_iq(From, To, IQ_Rec); _ -> @@ -1323,7 +1323,7 @@ build_contact_jid_td({U, S, R}) -> {CUser, CServer} -> CUser_S = binary_to_list(CUser), CServer_S = binary_to_list(CServer), - case lists:member(CServer_S, ?MYHOSTS) of + case ?IS_MY_HOST(CServer_S) of false -> ""; true -> "/admin/server/" ++ CServer_S ++ "/user/" ++ CUser_S ++ "/" end diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index b6f5bcbc3..f4d4df335 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -101,7 +101,7 @@ start(Host, Opts) -> gen_iq_handler:add_iq_handler(ejabberd_sm, HostB, ?NS_VCARD, ?MODULE, process_sm_iq, IQDisc), ejabberd_hooks:add(disco_sm_features, HostB, ?MODULE, get_sm_features, 50), - MyHost = gen_mod:get_opt_host(Host, Opts, "vjud.@HOST@"), + MyHost = gen_mod:expand_host_name(Host, Opts, "vjud"), Search = gen_mod:get_opt(search, Opts, true), register(gen_mod:get_module_proc(Host, ?PROCNAME), spawn(?MODULE, init, [MyHost, Host, Search])). @@ -209,7 +209,7 @@ process_sm_iq(_From, To, #iq{type = get} = IQ_Rec) -> process_sm_iq(From, _To, #iq{type = set, payload = Request} = IQ_Rec) -> User = exmpp_jid:node_as_list(From), LServer = exmpp_jid:prep_domain_as_list(From), - case lists:member(LServer, ?MYHOSTS) of + case ?IS_MY_HOST(LServer) of true -> set_vcard(User, LServer, Request), exmpp_iq:result(IQ_Rec); @@ -327,8 +327,10 @@ set_vcard(User, LServer, VCARD) -> ]}]). - - +do_route(global, From, To, Packet) -> + Host = exmpp_jid:prep_domain_as_list(To), + ServerHost = ejabberd_global_router:server_host(Host, self()), + do_route(ServerHost, From, To, Packet); do_route(ServerHost, From, To, Packet) -> User = exmpp_jid:node(To), Resource = exmpp_jid:resource(To), diff --git a/src/mod_vcard_ldap.erl b/src/mod_vcard_ldap.erl index c894efe58..3487ad1fc 100644 --- a/src/mod_vcard_ldap.erl +++ b/src/mod_vcard_ldap.erl @@ -646,7 +646,7 @@ find_xdata_el1([_ | Els]) -> find_xdata_el1(Els). parse_options(Host, Opts) -> - MyHost = gen_mod:get_opt_host(Host, Opts, "vjud.@HOST@"), + MyHost = gen_mod:expand_host_name(Host, Opts, "vjud"), Search = gen_mod:get_opt(search, Opts, true), Matches = case gen_mod:get_opt(matches, Opts, 30) of infinity -> 0;