24
1
mirror of https://github.com/processone/ejabberd.git synced 2024-06-28 22:52:27 +02:00

Replace more ?ERR_* macros with ?ERRT_*

This commit is contained in:
Evgeniy Khramtsov 2016-04-05 13:09:44 +03:00
parent fced8dc3d9
commit 9ac6e4edf7
10 changed files with 649 additions and 382 deletions

View File

@ -211,15 +211,15 @@ disco_identity(Acc, _From, _To, Node, Lang) ->
%%------------------------------------------------------------------------- %%-------------------------------------------------------------------------
-define(INFO_RESULT(Allow, Feats), -define(INFO_RESULT(Allow, Feats, Lang),
case Allow of case Allow of
deny -> deny ->
{error, ?ERR_FORBIDDEN}; {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
allow -> allow ->
{result, Feats} {result, Feats}
end). end).
disco_features(Acc, From, #jid{lserver = LServer} = _To, <<"announce">>, _Lang) -> disco_features(Acc, From, #jid{lserver = LServer} = _To, <<"announce">>, Lang) ->
case gen_mod:is_loaded(LServer, mod_adhoc) of case gen_mod:is_loaded(LServer, mod_adhoc) of
false -> false ->
Acc; Acc;
@ -229,13 +229,14 @@ disco_features(Acc, From, #jid{lserver = LServer} = _To, <<"announce">>, _Lang)
case {acl:match_rule(LServer, Access1, From), case {acl:match_rule(LServer, Access1, From),
acl:match_rule(global, Access2, From)} of acl:match_rule(global, Access2, From)} of
{deny, deny} -> {deny, deny} ->
{error, ?ERR_FORBIDDEN}; Txt = <<"Denied by ACL">>,
{error, ?ERRT_FORBIDDEN(Lang, Txt)};
_ -> _ ->
{result, []} {result, []}
end end
end; end;
disco_features(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) -> disco_features(Acc, From, #jid{lserver = LServer} = _To, Node, Lang) ->
case gen_mod:is_loaded(LServer, mod_adhoc) of case gen_mod:is_loaded(LServer, mod_adhoc) of
false -> false ->
Acc; Acc;
@ -246,25 +247,25 @@ disco_features(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
AllowGlobal = acl:match_rule(global, AccessGlobal, From), AllowGlobal = acl:match_rule(global, AccessGlobal, From),
case Node of case Node of
?NS_ADMIN_ANNOUNCE -> ?NS_ADMIN_ANNOUNCE ->
?INFO_RESULT(Allow, [?NS_COMMANDS]); ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
?NS_ADMIN_ANNOUNCE_ALL -> ?NS_ADMIN_ANNOUNCE_ALL ->
?INFO_RESULT(Allow, [?NS_COMMANDS]); ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
?NS_ADMIN_SET_MOTD -> ?NS_ADMIN_SET_MOTD ->
?INFO_RESULT(Allow, [?NS_COMMANDS]); ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
?NS_ADMIN_EDIT_MOTD -> ?NS_ADMIN_EDIT_MOTD ->
?INFO_RESULT(Allow, [?NS_COMMANDS]); ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
?NS_ADMIN_DELETE_MOTD -> ?NS_ADMIN_DELETE_MOTD ->
?INFO_RESULT(Allow, [?NS_COMMANDS]); ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
?NS_ADMIN_ANNOUNCE_ALLHOSTS -> ?NS_ADMIN_ANNOUNCE_ALLHOSTS ->
?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]); ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS], Lang);
?NS_ADMIN_ANNOUNCE_ALL_ALLHOSTS -> ?NS_ADMIN_ANNOUNCE_ALL_ALLHOSTS ->
?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]); ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS], Lang);
?NS_ADMIN_SET_MOTD_ALLHOSTS -> ?NS_ADMIN_SET_MOTD_ALLHOSTS ->
?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]); ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS], Lang);
?NS_ADMIN_EDIT_MOTD_ALLHOSTS -> ?NS_ADMIN_EDIT_MOTD_ALLHOSTS ->
?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]); ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS], Lang);
?NS_ADMIN_DELETE_MOTD_ALLHOSTS -> ?NS_ADMIN_DELETE_MOTD_ALLHOSTS ->
?INFO_RESULT(AllowGlobal, [?NS_COMMANDS]); ?INFO_RESULT(AllowGlobal, [?NS_COMMANDS], Lang);
_ -> _ ->
Acc Acc
end end
@ -283,10 +284,10 @@ disco_features(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
} }
)). )).
-define(ITEMS_RESULT(Allow, Items), -define(ITEMS_RESULT(Allow, Items, Lang),
case Allow of case Allow of
deny -> deny ->
{error, ?ERR_FORBIDDEN}; {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
allow -> allow ->
{result, Items} {result, Items}
end). end).
@ -320,7 +321,7 @@ disco_items(Acc, From, #jid{lserver = LServer} = To, <<"announce">>, Lang) ->
announce_items(Acc, From, To, Lang) announce_items(Acc, From, To, Lang)
end; end;
disco_items(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) -> disco_items(Acc, From, #jid{lserver = LServer} = _To, Node, Lang) ->
case gen_mod:is_loaded(LServer, mod_adhoc) of case gen_mod:is_loaded(LServer, mod_adhoc) of
false -> false ->
Acc; Acc;
@ -331,25 +332,25 @@ disco_items(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
AllowGlobal = acl:match_rule(global, AccessGlobal, From), AllowGlobal = acl:match_rule(global, AccessGlobal, From),
case Node of case Node of
?NS_ADMIN_ANNOUNCE -> ?NS_ADMIN_ANNOUNCE ->
?ITEMS_RESULT(Allow, []); ?ITEMS_RESULT(Allow, [], Lang);
?NS_ADMIN_ANNOUNCE_ALL -> ?NS_ADMIN_ANNOUNCE_ALL ->
?ITEMS_RESULT(Allow, []); ?ITEMS_RESULT(Allow, [], Lang);
?NS_ADMIN_SET_MOTD -> ?NS_ADMIN_SET_MOTD ->
?ITEMS_RESULT(Allow, []); ?ITEMS_RESULT(Allow, [], Lang);
?NS_ADMIN_EDIT_MOTD -> ?NS_ADMIN_EDIT_MOTD ->
?ITEMS_RESULT(Allow, []); ?ITEMS_RESULT(Allow, [], Lang);
?NS_ADMIN_DELETE_MOTD -> ?NS_ADMIN_DELETE_MOTD ->
?ITEMS_RESULT(Allow, []); ?ITEMS_RESULT(Allow, [], Lang);
?NS_ADMIN_ANNOUNCE_ALLHOSTS -> ?NS_ADMIN_ANNOUNCE_ALLHOSTS ->
?ITEMS_RESULT(AllowGlobal, []); ?ITEMS_RESULT(AllowGlobal, [], Lang);
?NS_ADMIN_ANNOUNCE_ALL_ALLHOSTS -> ?NS_ADMIN_ANNOUNCE_ALL_ALLHOSTS ->
?ITEMS_RESULT(AllowGlobal, []); ?ITEMS_RESULT(AllowGlobal, [], Lang);
?NS_ADMIN_SET_MOTD_ALLHOSTS -> ?NS_ADMIN_SET_MOTD_ALLHOSTS ->
?ITEMS_RESULT(AllowGlobal, []); ?ITEMS_RESULT(AllowGlobal, [], Lang);
?NS_ADMIN_EDIT_MOTD_ALLHOSTS -> ?NS_ADMIN_EDIT_MOTD_ALLHOSTS ->
?ITEMS_RESULT(AllowGlobal, []); ?ITEMS_RESULT(AllowGlobal, [], Lang);
?NS_ADMIN_DELETE_MOTD_ALLHOSTS -> ?NS_ADMIN_DELETE_MOTD_ALLHOSTS ->
?ITEMS_RESULT(AllowGlobal, []); ?ITEMS_RESULT(AllowGlobal, [], Lang);
_ -> _ ->
Acc Acc
end end
@ -396,7 +397,8 @@ announce_items(Acc, From, #jid{lserver = LServer, server = Server} = _To, Lang)
commands_result(Allow, From, To, Request) -> commands_result(Allow, From, To, Request) ->
case Allow of case Allow of
deny -> deny ->
{error, ?ERR_FORBIDDEN}; Lang = Request#adhoc_request.lang,
{error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
allow -> allow ->
announce_commands(From, To, Request) announce_commands(From, To, Request)
end. end.
@ -463,12 +465,13 @@ announce_commands(From, To,
%% User returns form. %% User returns form.
case jlib:parse_xdata_submit(XData) of case jlib:parse_xdata_submit(XData) of
invalid -> invalid ->
{error, ?ERR_BAD_REQUEST}; {error, ?ERRT_BAD_REQUEST(Lang, <<"Incorrect data form">>)};
Fields -> Fields ->
handle_adhoc_form(From, To, Request, Fields) handle_adhoc_form(From, To, Request, Fields)
end; end;
true -> true ->
{error, ?ERR_BAD_REQUEST} Txt = <<"Incorrect action or data form">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
end. end.
-define(VVALUE(Val), -define(VVALUE(Val),
@ -688,7 +691,9 @@ announce_all(From, To, Packet) ->
Access = get_access(Host), Access = get_access(Host),
case acl:match_rule(Host, Access, From) of case acl:match_rule(Host, Access, From) of
deny -> deny ->
Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
Txt = <<"Denied by ACL">>,
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
ejabberd_router:route(To, From, Err); ejabberd_router:route(To, From, Err);
allow -> allow ->
Local = jid:make(<<>>, To#jid.server, <<>>), Local = jid:make(<<>>, To#jid.server, <<>>),
@ -703,7 +708,9 @@ announce_all_hosts_all(From, To, Packet) ->
Access = get_access(global), Access = get_access(global),
case acl:match_rule(global, Access, From) of case acl:match_rule(global, Access, From) of
deny -> deny ->
Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
Txt = <<"Denied by ACL">>,
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
ejabberd_router:route(To, From, Err); ejabberd_router:route(To, From, Err);
allow -> allow ->
Local = jid:make(<<>>, To#jid.server, <<>>), Local = jid:make(<<>>, To#jid.server, <<>>),
@ -719,7 +726,9 @@ announce_online(From, To, Packet) ->
Access = get_access(Host), Access = get_access(Host),
case acl:match_rule(Host, Access, From) of case acl:match_rule(Host, Access, From) of
deny -> deny ->
Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
Txt = <<"Denied by ACL">>,
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
ejabberd_router:route(To, From, Err); ejabberd_router:route(To, From, Err);
allow -> allow ->
announce_online1(ejabberd_sm:get_vh_session_list(Host), announce_online1(ejabberd_sm:get_vh_session_list(Host),
@ -731,7 +740,9 @@ announce_all_hosts_online(From, To, Packet) ->
Access = get_access(global), Access = get_access(global),
case acl:match_rule(global, Access, From) of case acl:match_rule(global, Access, From) of
deny -> deny ->
Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
Txt = <<"Denied by ACL">>,
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
ejabberd_router:route(To, From, Err); ejabberd_router:route(To, From, Err);
allow -> allow ->
announce_online1(ejabberd_sm:dirty_get_sessions_list(), announce_online1(ejabberd_sm:dirty_get_sessions_list(),
@ -752,7 +763,9 @@ announce_motd(From, To, Packet) ->
Access = get_access(Host), Access = get_access(Host),
case acl:match_rule(Host, Access, From) of case acl:match_rule(Host, Access, From) of
deny -> deny ->
Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
Txt = <<"Denied by ACL">>,
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
ejabberd_router:route(To, From, Err); ejabberd_router:route(To, From, Err);
allow -> allow ->
announce_motd(Host, Packet) announce_motd(Host, Packet)
@ -762,7 +775,9 @@ announce_all_hosts_motd(From, To, Packet) ->
Access = get_access(global), Access = get_access(global),
case acl:match_rule(global, Access, From) of case acl:match_rule(global, Access, From) of
deny -> deny ->
Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
Txt = <<"Denied by ACL">>,
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
ejabberd_router:route(To, From, Err); ejabberd_router:route(To, From, Err);
allow -> allow ->
Hosts = ?MYHOSTS, Hosts = ?MYHOSTS,
@ -815,7 +830,9 @@ announce_motd_update(From, To, Packet) ->
Access = get_access(Host), Access = get_access(Host),
case acl:match_rule(Host, Access, From) of case acl:match_rule(Host, Access, From) of
deny -> deny ->
Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
Txt = <<"Denied by ACL">>,
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
ejabberd_router:route(To, From, Err); ejabberd_router:route(To, From, Err);
allow -> allow ->
announce_motd_update(Host, Packet) announce_motd_update(Host, Packet)
@ -825,7 +842,9 @@ announce_all_hosts_motd_update(From, To, Packet) ->
Access = get_access(global), Access = get_access(global),
case acl:match_rule(global, Access, From) of case acl:match_rule(global, Access, From) of
deny -> deny ->
Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
Txt = <<"Denied by ACL">>,
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
ejabberd_router:route(To, From, Err); ejabberd_router:route(To, From, Err);
allow -> allow ->
Hosts = ?MYHOSTS, Hosts = ?MYHOSTS,
@ -861,7 +880,9 @@ announce_motd_delete(From, To, Packet) ->
Access = get_access(Host), Access = get_access(Host),
case acl:match_rule(Host, Access, From) of case acl:match_rule(Host, Access, From) of
deny -> deny ->
Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
Txt = <<"Denied by ACL">>,
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
ejabberd_router:route(To, From, Err); ejabberd_router:route(To, From, Err);
allow -> allow ->
announce_motd_delete(Host) announce_motd_delete(Host)
@ -871,7 +892,9 @@ announce_all_hosts_motd_delete(From, To, Packet) ->
Access = get_access(global), Access = get_access(global),
case acl:match_rule(global, Access, From) of case acl:match_rule(global, Access, From) of
deny -> deny ->
Err = jlib:make_error_reply(Packet, ?ERR_FORBIDDEN), Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
Txt = <<"Denied by ACL">>,
Err = jlib:make_error_reply(Packet, ?ERRT_FORBIDDEN(Lang, Txt)),
ejabberd_router:route(To, From, Err); ejabberd_router:route(To, From, Err);
allow -> allow ->
Hosts = ?MYHOSTS, Hosts = ?MYHOSTS,

View File

@ -198,81 +198,81 @@ get_local_identity(Acc, _From, _To, Node, Lang) ->
%%%----------------------------------------------------------------------- %%%-----------------------------------------------------------------------
-define(INFO_RESULT(Allow, Feats), -define(INFO_RESULT(Allow, Feats, Lang),
case Allow of case Allow of
deny -> {error, ?ERR_FORBIDDEN}; deny -> {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
allow -> {result, Feats} allow -> {result, Feats}
end). end).
get_sm_features(Acc, From, get_sm_features(Acc, From,
#jid{lserver = LServer} = _To, Node, _Lang) -> #jid{lserver = LServer} = _To, Node, Lang) ->
case gen_mod:is_loaded(LServer, mod_adhoc) of case gen_mod:is_loaded(LServer, mod_adhoc) of
false -> Acc; false -> Acc;
_ -> _ ->
Allow = acl:match_rule(LServer, configure, From), Allow = acl:match_rule(LServer, configure, From),
case Node of case Node of
<<"config">> -> ?INFO_RESULT(Allow, [?NS_COMMANDS]); <<"config">> -> ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
_ -> Acc _ -> Acc
end end
end. end.
get_local_features(Acc, From, get_local_features(Acc, From,
#jid{lserver = LServer} = _To, Node, _Lang) -> #jid{lserver = LServer} = _To, Node, Lang) ->
case gen_mod:is_loaded(LServer, mod_adhoc) of case gen_mod:is_loaded(LServer, mod_adhoc) of
false -> Acc; false -> Acc;
_ -> _ ->
LNode = tokenize(Node), LNode = tokenize(Node),
Allow = acl:match_rule(LServer, configure, From), Allow = acl:match_rule(LServer, configure, From),
case LNode of case LNode of
[<<"config">>] -> ?INFO_RESULT(Allow, []); [<<"config">>] -> ?INFO_RESULT(Allow, [], Lang);
[<<"user">>] -> ?INFO_RESULT(Allow, []); [<<"user">>] -> ?INFO_RESULT(Allow, [], Lang);
[<<"online users">>] -> ?INFO_RESULT(Allow, []); [<<"online users">>] -> ?INFO_RESULT(Allow, [], Lang);
[<<"all users">>] -> ?INFO_RESULT(Allow, []); [<<"all users">>] -> ?INFO_RESULT(Allow, [], Lang);
[<<"all users">>, <<$@, _/binary>>] -> [<<"all users">>, <<$@, _/binary>>] ->
?INFO_RESULT(Allow, []); ?INFO_RESULT(Allow, [], Lang);
[<<"outgoing s2s">> | _] -> ?INFO_RESULT(Allow, []); [<<"outgoing s2s">> | _] -> ?INFO_RESULT(Allow, [], Lang);
[<<"running nodes">>] -> ?INFO_RESULT(Allow, []); [<<"running nodes">>] -> ?INFO_RESULT(Allow, [], Lang);
[<<"stopped nodes">>] -> ?INFO_RESULT(Allow, []); [<<"stopped nodes">>] -> ?INFO_RESULT(Allow, [], Lang);
[<<"running nodes">>, _ENode] -> [<<"running nodes">>, _ENode] ->
?INFO_RESULT(Allow, [?NS_STATS]); ?INFO_RESULT(Allow, [?NS_STATS], Lang);
[<<"running nodes">>, _ENode, <<"DB">>] -> [<<"running nodes">>, _ENode, <<"DB">>] ->
?INFO_RESULT(Allow, [?NS_COMMANDS]); ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
[<<"running nodes">>, _ENode, <<"modules">>] -> [<<"running nodes">>, _ENode, <<"modules">>] ->
?INFO_RESULT(Allow, []); ?INFO_RESULT(Allow, [], Lang);
[<<"running nodes">>, _ENode, <<"modules">>, _] -> [<<"running nodes">>, _ENode, <<"modules">>, _] ->
?INFO_RESULT(Allow, [?NS_COMMANDS]); ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
[<<"running nodes">>, _ENode, <<"backup">>] -> [<<"running nodes">>, _ENode, <<"backup">>] ->
?INFO_RESULT(Allow, []); ?INFO_RESULT(Allow, [], Lang);
[<<"running nodes">>, _ENode, <<"backup">>, _] -> [<<"running nodes">>, _ENode, <<"backup">>, _] ->
?INFO_RESULT(Allow, [?NS_COMMANDS]); ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
[<<"running nodes">>, _ENode, <<"import">>] -> [<<"running nodes">>, _ENode, <<"import">>] ->
?INFO_RESULT(Allow, []); ?INFO_RESULT(Allow, [], Lang);
[<<"running nodes">>, _ENode, <<"import">>, _] -> [<<"running nodes">>, _ENode, <<"import">>, _] ->
?INFO_RESULT(Allow, [?NS_COMMANDS]); ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
[<<"running nodes">>, _ENode, <<"restart">>] -> [<<"running nodes">>, _ENode, <<"restart">>] ->
?INFO_RESULT(Allow, [?NS_COMMANDS]); ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
[<<"running nodes">>, _ENode, <<"shutdown">>] -> [<<"running nodes">>, _ENode, <<"shutdown">>] ->
?INFO_RESULT(Allow, [?NS_COMMANDS]); ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
[<<"config">>, _] -> [<<"config">>, _] ->
?INFO_RESULT(Allow, [?NS_COMMANDS]); ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
?NS_ADMINL(<<"add-user">>) -> ?NS_ADMINL(<<"add-user">>) ->
?INFO_RESULT(Allow, [?NS_COMMANDS]); ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
?NS_ADMINL(<<"delete-user">>) -> ?NS_ADMINL(<<"delete-user">>) ->
?INFO_RESULT(Allow, [?NS_COMMANDS]); ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
?NS_ADMINL(<<"end-user-session">>) -> ?NS_ADMINL(<<"end-user-session">>) ->
?INFO_RESULT(Allow, [?NS_COMMANDS]); ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
?NS_ADMINL(<<"get-user-password">>) -> ?NS_ADMINL(<<"get-user-password">>) ->
?INFO_RESULT(Allow, [?NS_COMMANDS]); ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
?NS_ADMINL(<<"change-user-password">>) -> ?NS_ADMINL(<<"change-user-password">>) ->
?INFO_RESULT(Allow, [?NS_COMMANDS]); ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
?NS_ADMINL(<<"get-user-lastlogin">>) -> ?NS_ADMINL(<<"get-user-lastlogin">>) ->
?INFO_RESULT(Allow, [?NS_COMMANDS]); ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
?NS_ADMINL(<<"user-stats">>) -> ?NS_ADMINL(<<"user-stats">>) ->
?INFO_RESULT(Allow, [?NS_COMMANDS]); ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
?NS_ADMINL(<<"get-registered-users-num">>) -> ?NS_ADMINL(<<"get-registered-users-num">>) ->
?INFO_RESULT(Allow, [?NS_COMMANDS]); ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
?NS_ADMINL(<<"get-online-users-num">>) -> ?NS_ADMINL(<<"get-online-users-num">>) ->
?INFO_RESULT(Allow, [?NS_COMMANDS]); ?INFO_RESULT(Allow, [?NS_COMMANDS], Lang);
_ -> Acc _ -> Acc
end end
end. end.
@ -318,7 +318,8 @@ get_sm_items(Acc, From,
{result, {result,
Items ++ Nodes ++ get_user_resources(User, Server)}; Items ++ Nodes ++ get_user_resources(User, Server)};
{allow, <<"config">>} -> {result, []}; {allow, <<"config">>} -> {result, []};
{_, <<"config">>} -> {error, ?ERR_FORBIDDEN}; {_, <<"config">>} ->
{error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
_ -> Acc _ -> Acc
end end
end. end.
@ -448,63 +449,64 @@ get_local_items(Acc, From, #jid{lserver = LServer} = To,
_ -> _ ->
LNode = tokenize(Node), LNode = tokenize(Node),
Allow = acl:match_rule(LServer, configure, From), Allow = acl:match_rule(LServer, configure, From),
Err = ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>),
case LNode of case LNode of
[<<"config">>] -> [<<"config">>] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
[<<"user">>] -> [<<"user">>] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
[<<"online users">>] -> [<<"online users">>] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
[<<"all users">>] -> [<<"all users">>] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
[<<"all users">>, <<$@, _/binary>>] -> [<<"all users">>, <<$@, _/binary>>] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
[<<"outgoing s2s">> | _] -> [<<"outgoing s2s">> | _] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
[<<"running nodes">>] -> [<<"running nodes">>] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
[<<"stopped nodes">>] -> [<<"stopped nodes">>] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
[<<"running nodes">>, _ENode] -> [<<"running nodes">>, _ENode] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
[<<"running nodes">>, _ENode, <<"DB">>] -> [<<"running nodes">>, _ENode, <<"DB">>] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
[<<"running nodes">>, _ENode, <<"modules">>] -> [<<"running nodes">>, _ENode, <<"modules">>] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
[<<"running nodes">>, _ENode, <<"modules">>, _] -> [<<"running nodes">>, _ENode, <<"modules">>, _] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
[<<"running nodes">>, _ENode, <<"backup">>] -> [<<"running nodes">>, _ENode, <<"backup">>] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
[<<"running nodes">>, _ENode, <<"backup">>, _] -> [<<"running nodes">>, _ENode, <<"backup">>, _] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
[<<"running nodes">>, _ENode, <<"import">>] -> [<<"running nodes">>, _ENode, <<"import">>] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
[<<"running nodes">>, _ENode, <<"import">>, _] -> [<<"running nodes">>, _ENode, <<"import">>, _] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
[<<"running nodes">>, _ENode, <<"restart">>] -> [<<"running nodes">>, _ENode, <<"restart">>] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
[<<"running nodes">>, _ENode, <<"shutdown">>] -> [<<"running nodes">>, _ENode, <<"shutdown">>] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
[<<"config">>, _] -> [<<"config">>, _] ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
?NS_ADMINL(<<"add-user">>) -> ?NS_ADMINL(<<"add-user">>) ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
?NS_ADMINL(<<"delete-user">>) -> ?NS_ADMINL(<<"delete-user">>) ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
?NS_ADMINL(<<"end-user-session">>) -> ?NS_ADMINL(<<"end-user-session">>) ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
?NS_ADMINL(<<"get-user-password">>) -> ?NS_ADMINL(<<"get-user-password">>) ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
?NS_ADMINL(<<"change-user-password">>) -> ?NS_ADMINL(<<"change-user-password">>) ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
?NS_ADMINL(<<"get-user-lastlogin">>) -> ?NS_ADMINL(<<"get-user-lastlogin">>) ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
?NS_ADMINL(<<"user-stats">>) -> ?NS_ADMINL(<<"user-stats">>) ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
?NS_ADMINL(<<"get-registered-users-num">>) -> ?NS_ADMINL(<<"get-registered-users-num">>) ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
?NS_ADMINL(<<"get-online-users-num">>) -> ?NS_ADMINL(<<"get-online-users-num">>) ->
?ITEMS_RESULT(Allow, LNode, {error, ?ERR_FORBIDDEN}); ?ITEMS_RESULT(Allow, LNode, {error, Err});
_ -> Acc _ -> Acc
end end
end. end.
@ -562,33 +564,29 @@ get_local_items({_, Host}, [<<"all users">>], _Server,
get_local_items({_, Host}, get_local_items({_, Host},
[<<"all users">>, <<$@, Diap/binary>>], _Server, [<<"all users">>, <<$@, Diap/binary>>], _Server,
_Lang) -> _Lang) ->
case catch ejabberd_auth:get_vh_registered_users(Host) Users = ejabberd_auth:get_vh_registered_users(Host),
of SUsers = lists:sort([{S, U} || {U, S} <- Users]),
{'EXIT', _Reason} -> ?ERR_INTERNAL_SERVER_ERROR; case catch begin
Users -> [S1, S2] = ejabberd_regexp:split(Diap, <<"-">>),
SUsers = lists:sort([{S, U} || {U, S} <- Users]), N1 = jlib:binary_to_integer(S1),
case catch begin N2 = jlib:binary_to_integer(S2),
[S1, S2] = ejabberd_regexp:split(Diap, <<"-">>), Sub = lists:sublist(SUsers, N1, N2 - N1 + 1),
N1 = jlib:binary_to_integer(S1), lists:map(fun ({S, U}) ->
N2 = jlib:binary_to_integer(S2), #xmlel{name = <<"item">>,
Sub = lists:sublist(SUsers, N1, N2 - N1 + 1), attrs =
lists:map(fun ({S, U}) -> [{<<"jid">>,
#xmlel{name = <<"item">>, <<U/binary, "@",
attrs = S/binary>>},
[{<<"jid">>, {<<"name">>,
<<U/binary, "@", <<U/binary, "@",
S/binary>>}, S/binary>>}],
{<<"name">>, children = []}
<<U/binary, "@", end,
S/binary>>}], Sub)
children = []} end
end, of
Sub) {'EXIT', _Reason} -> ?ERR_NOT_ACCEPTABLE;
end Res -> {result, Res}
of
{'EXIT', _Reason} -> ?ERR_NOT_ACCEPTABLE;
Res -> {result, Res}
end
end; end;
get_local_items({_, Host}, [<<"outgoing s2s">>], get_local_items({_, Host}, [<<"outgoing s2s">>],
_Server, Lang) -> _Server, Lang) ->
@ -826,33 +824,33 @@ get_stopped_nodes(_Lang) ->
%%------------------------------------------------------------------------- %%-------------------------------------------------------------------------
-define(COMMANDS_RESULT(LServerOrGlobal, From, To, -define(COMMANDS_RESULT(LServerOrGlobal, From, To,
Request), Request, Lang),
case acl:match_rule(LServerOrGlobal, configure, From) of case acl:match_rule(LServerOrGlobal, configure, From) of
deny -> {error, ?ERR_FORBIDDEN}; deny -> {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
allow -> adhoc_local_commands(From, To, Request) allow -> adhoc_local_commands(From, To, Request)
end). end).
adhoc_local_commands(Acc, From, adhoc_local_commands(Acc, From,
#jid{lserver = LServer} = To, #jid{lserver = LServer} = To,
#adhoc_request{node = Node} = Request) -> #adhoc_request{node = Node, lang = Lang} = Request) ->
LNode = tokenize(Node), LNode = tokenize(Node),
case LNode of case LNode of
[<<"running nodes">>, _ENode, <<"DB">>] -> [<<"running nodes">>, _ENode, <<"DB">>] ->
?COMMANDS_RESULT(global, From, To, Request); ?COMMANDS_RESULT(global, From, To, Request, Lang);
[<<"running nodes">>, _ENode, <<"modules">>, _] -> [<<"running nodes">>, _ENode, <<"modules">>, _] ->
?COMMANDS_RESULT(LServer, From, To, Request); ?COMMANDS_RESULT(LServer, From, To, Request, Lang);
[<<"running nodes">>, _ENode, <<"backup">>, _] -> [<<"running nodes">>, _ENode, <<"backup">>, _] ->
?COMMANDS_RESULT(global, From, To, Request); ?COMMANDS_RESULT(global, From, To, Request, Lang);
[<<"running nodes">>, _ENode, <<"import">>, _] -> [<<"running nodes">>, _ENode, <<"import">>, _] ->
?COMMANDS_RESULT(global, From, To, Request); ?COMMANDS_RESULT(global, From, To, Request, Lang);
[<<"running nodes">>, _ENode, <<"restart">>] -> [<<"running nodes">>, _ENode, <<"restart">>] ->
?COMMANDS_RESULT(global, From, To, Request); ?COMMANDS_RESULT(global, From, To, Request, Lang);
[<<"running nodes">>, _ENode, <<"shutdown">>] -> [<<"running nodes">>, _ENode, <<"shutdown">>] ->
?COMMANDS_RESULT(global, From, To, Request); ?COMMANDS_RESULT(global, From, To, Request, Lang);
[<<"config">>, _] -> [<<"config">>, _] ->
?COMMANDS_RESULT(LServer, From, To, Request); ?COMMANDS_RESULT(LServer, From, To, Request, Lang);
?NS_ADMINL(_) -> ?NS_ADMINL(_) ->
?COMMANDS_RESULT(LServer, From, To, Request); ?COMMANDS_RESULT(LServer, From, To, Request, Lang);
_ -> Acc _ -> Acc
end. end.
@ -882,7 +880,8 @@ adhoc_local_commands(From,
end; end;
XData /= false, ActionIsExecute -> XData /= false, ActionIsExecute ->
case jlib:parse_xdata_submit(XData) of case jlib:parse_xdata_submit(XData) of
invalid -> {error, ?ERR_BAD_REQUEST}; invalid ->
{error, ?ERRT_BAD_REQUEST(Lang, <<"Incorrect data form">>)};
Fields -> Fields ->
case catch set_form(From, LServer, LNode, Lang, Fields) case catch set_form(From, LServer, LNode, Lang, Fields)
of of
@ -898,7 +897,8 @@ adhoc_local_commands(From,
{error, Error} -> {error, Error} {error, Error} -> {error, Error}
end end
end; end;
true -> {error, ?ERR_BAD_REQUEST} true ->
{error, ?ERRT_BAD_REQUEST(Lang, <<"Incorrect action or data form">>)}
end. end.
-define(TVFIELD(Type, Var, Val), -define(TVFIELD(Type, Var, Val),
@ -980,10 +980,14 @@ adhoc_local_commands(From,
get_form(_Host, [<<"running nodes">>, ENode, <<"DB">>], get_form(_Host, [<<"running nodes">>, ENode, <<"DB">>],
Lang) -> Lang) ->
case search_running_node(ENode) of case search_running_node(ENode) of
false -> {error, ?ERR_ITEM_NOT_FOUND}; false ->
Txt = <<"No running node found">>,
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
Node -> Node ->
case ejabberd_cluster:call(Node, mnesia, system_info, [tables]) of case ejabberd_cluster:call(Node, mnesia, system_info, [tables]) of
{badrpc, _Reason} -> {badrpc, Reason} ->
?ERROR_MSG("RPC call mnesia:system_info(tables) on node "
"~s failed: ~p", [Node, Reason]),
{error, ?ERR_INTERNAL_SERVER_ERROR}; {error, ?ERR_INTERNAL_SERVER_ERROR};
Tables -> Tables ->
STables = lists:sort(Tables), STables = lists:sort(Tables),
@ -1023,10 +1027,14 @@ get_form(Host,
[<<"running nodes">>, ENode, <<"modules">>, <<"stop">>], [<<"running nodes">>, ENode, <<"modules">>, <<"stop">>],
Lang) -> Lang) ->
case search_running_node(ENode) of case search_running_node(ENode) of
false -> {error, ?ERR_ITEM_NOT_FOUND}; false ->
Txt = <<"No running node found">>,
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
Node -> Node ->
case ejabberd_cluster:call(Node, gen_mod, loaded_modules, [Host]) of case ejabberd_cluster:call(Node, gen_mod, loaded_modules, [Host]) of
{badrpc, _Reason} -> {badrpc, Reason} ->
?ERROR_MSG("RPC call gen_mod:loaded_modules(~s) on node "
"~s failed: ~p", [Host, Node, Reason]),
{error, ?ERR_INTERNAL_SERVER_ERROR}; {error, ?ERR_INTERNAL_SERVER_ERROR};
Modules -> Modules ->
SModules = lists:sort(Modules), SModules = lists:sort(Modules),
@ -1562,9 +1570,11 @@ get_form(_Host, _, _Lang) ->
{error, ?ERR_SERVICE_UNAVAILABLE}. {error, ?ERR_SERVICE_UNAVAILABLE}.
set_form(_From, _Host, set_form(_From, _Host,
[<<"running nodes">>, ENode, <<"DB">>], _Lang, XData) -> [<<"running nodes">>, ENode, <<"DB">>], Lang, XData) ->
case search_running_node(ENode) of case search_running_node(ENode) of
false -> {error, ?ERR_ITEM_NOT_FOUND}; false ->
Txt = <<"No running node found">>,
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
Node -> Node ->
lists:foreach(fun ({SVar, SVals}) -> lists:foreach(fun ({SVar, SVals}) ->
Table = jlib:binary_to_atom(SVar), Table = jlib:binary_to_atom(SVar),
@ -1596,9 +1606,11 @@ set_form(_From, _Host,
end; end;
set_form(_From, Host, set_form(_From, Host,
[<<"running nodes">>, ENode, <<"modules">>, <<"stop">>], [<<"running nodes">>, ENode, <<"modules">>, <<"stop">>],
_Lang, XData) -> Lang, XData) ->
case search_running_node(ENode) of case search_running_node(ENode) of
false -> {error, ?ERR_ITEM_NOT_FOUND}; false ->
Txt = <<"No running node found">>,
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
Node -> Node ->
lists:foreach(fun ({Var, Vals}) -> lists:foreach(fun ({Var, Vals}) ->
case Vals of case Vals of
@ -1615,12 +1627,16 @@ set_form(_From, Host,
set_form(_From, Host, set_form(_From, Host,
[<<"running nodes">>, ENode, <<"modules">>, [<<"running nodes">>, ENode, <<"modules">>,
<<"start">>], <<"start">>],
_Lang, XData) -> Lang, XData) ->
case search_running_node(ENode) of case search_running_node(ENode) of
false -> {error, ?ERR_ITEM_NOT_FOUND}; false ->
Txt = <<"No running node found">>,
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
Node -> Node ->
case lists:keysearch(<<"modules">>, 1, XData) of case lists:keysearch(<<"modules">>, 1, XData) of
false -> {error, ?ERR_BAD_REQUEST}; false ->
Txt = <<"No 'modules' found in data form">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
{value, {_, Strings}} -> {value, {_, Strings}} ->
String = lists:foldl(fun (S, Res) -> String = lists:foldl(fun (S, Res) ->
<<Res/binary, S/binary, "\n">> <<Res/binary, S/binary, "\n">>
@ -1637,98 +1653,143 @@ set_form(_From, Host,
end, end,
Modules), Modules),
{result, []}; {result, []};
_ -> {error, ?ERR_BAD_REQUEST} _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Parse failed">>)}
end; end;
_ -> {error, ?ERR_BAD_REQUEST} _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Scan failed">>)}
end end
end end
end; end;
set_form(_From, _Host, set_form(_From, _Host,
[<<"running nodes">>, ENode, <<"backup">>, [<<"running nodes">>, ENode, <<"backup">>,
<<"backup">>], <<"backup">>],
_Lang, XData) -> Lang, XData) ->
case search_running_node(ENode) of case search_running_node(ENode) of
false -> {error, ?ERR_ITEM_NOT_FOUND}; false ->
Txt = <<"No running node found">>,
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
Node -> Node ->
case lists:keysearch(<<"path">>, 1, XData) of case lists:keysearch(<<"path">>, 1, XData) of
false -> {error, ?ERR_BAD_REQUEST}; false ->
Txt = <<"No 'path' found in data form">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
{value, {_, [String]}} -> {value, {_, [String]}} ->
case ejabberd_cluster:call(Node, mnesia, backup, [String]) of case ejabberd_cluster:call(Node, mnesia, backup, [String]) of
{badrpc, _Reason} -> {badrpc, Reason} ->
?ERROR_MSG("RPC call mnesia:backup(~s) to node ~s "
"failed: ~p", [String, Node, Reason]),
{error, ?ERR_INTERNAL_SERVER_ERROR};
{error, Reason} ->
?ERROR_MSG("RPC call mnesia:backup(~s) to node ~s "
"failed: ~p", [String, Node, Reason]),
{error, ?ERR_INTERNAL_SERVER_ERROR}; {error, ?ERR_INTERNAL_SERVER_ERROR};
{error, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR};
_ -> {result, []} _ -> {result, []}
end; end;
_ -> {error, ?ERR_BAD_REQUEST} _ ->
Txt = <<"Incorrect value of 'path' in data form">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
end end
end; end;
set_form(_From, _Host, set_form(_From, _Host,
[<<"running nodes">>, ENode, <<"backup">>, [<<"running nodes">>, ENode, <<"backup">>,
<<"restore">>], <<"restore">>],
_Lang, XData) -> Lang, XData) ->
case search_running_node(ENode) of case search_running_node(ENode) of
false -> {error, ?ERR_ITEM_NOT_FOUND}; false ->
Txt = <<"No running node found">>,
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
Node -> Node ->
case lists:keysearch(<<"path">>, 1, XData) of case lists:keysearch(<<"path">>, 1, XData) of
false -> {error, ?ERR_BAD_REQUEST}; false ->
Txt = <<"No 'path' found in data form">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
{value, {_, [String]}} -> {value, {_, [String]}} ->
case ejabberd_cluster:call(Node, ejabberd_admin, restore, [String]) case ejabberd_cluster:call(Node, ejabberd_admin, restore, [String])
of of
{badrpc, _Reason} -> {badrpc, Reason} ->
?ERROR_MSG("RPC call ejabberd_admin:restore(~s) to node "
"~s failed: ~p", [String, Node, Reason]),
{error, ?ERR_INTERNAL_SERVER_ERROR};
{error, Reason} ->
?ERROR_MSG("RPC call ejabberd_admin:restore(~s) to node "
"~s failed: ~p", [String, Node, Reason]),
{error, ?ERR_INTERNAL_SERVER_ERROR}; {error, ?ERR_INTERNAL_SERVER_ERROR};
{error, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR};
_ -> {result, []} _ -> {result, []}
end; end;
_ -> {error, ?ERR_BAD_REQUEST} _ ->
Txt = <<"Incorrect value of 'path' in data form">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
end end
end; end;
set_form(_From, _Host, set_form(_From, _Host,
[<<"running nodes">>, ENode, <<"backup">>, [<<"running nodes">>, ENode, <<"backup">>,
<<"textfile">>], <<"textfile">>],
_Lang, XData) -> Lang, XData) ->
case search_running_node(ENode) of case search_running_node(ENode) of
false -> {error, ?ERR_ITEM_NOT_FOUND}; false ->
Txt = <<"No running node found">>,
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
Node -> Node ->
case lists:keysearch(<<"path">>, 1, XData) of case lists:keysearch(<<"path">>, 1, XData) of
false -> {error, ?ERR_BAD_REQUEST}; false ->
Txt = <<"No 'path' found in data form">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
{value, {_, [String]}} -> {value, {_, [String]}} ->
case ejabberd_cluster:call(Node, ejabberd_admin, dump_to_textfile, case ejabberd_cluster:call(Node, ejabberd_admin, dump_to_textfile,
[String]) [String])
of of
{badrpc, _Reason} -> {badrpc, Reason} ->
?ERROR_MSG("RPC call ejabberd_admin:dump_to_textfile(~s) "
"to node ~s failed: ~p", [String, Node, Reason]),
{error, ?ERR_INTERNAL_SERVER_ERROR};
{error, Reason} ->
?ERROR_MSG("RPC call ejabberd_admin:dump_to_textfile(~s) "
"to node ~s failed: ~p", [String, Node, Reason]),
{error, ?ERR_INTERNAL_SERVER_ERROR}; {error, ?ERR_INTERNAL_SERVER_ERROR};
{error, _Reason} -> {error, ?ERR_INTERNAL_SERVER_ERROR};
_ -> {result, []} _ -> {result, []}
end; end;
_ -> {error, ?ERR_BAD_REQUEST} _ ->
Txt = <<"Incorrect value of 'path' in data form">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
end end
end; end;
set_form(_From, _Host, set_form(_From, _Host,
[<<"running nodes">>, ENode, <<"import">>, <<"file">>], [<<"running nodes">>, ENode, <<"import">>, <<"file">>],
_Lang, XData) -> Lang, XData) ->
case search_running_node(ENode) of case search_running_node(ENode) of
false -> {error, ?ERR_ITEM_NOT_FOUND}; false ->
Txt = <<"No running node found">>,
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
Node -> Node ->
case lists:keysearch(<<"path">>, 1, XData) of case lists:keysearch(<<"path">>, 1, XData) of
false -> {error, ?ERR_BAD_REQUEST}; false ->
Txt = <<"No 'path' found in data form">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
{value, {_, [String]}} -> {value, {_, [String]}} ->
ejabberd_cluster:call(Node, jd2ejd, import_file, [String]), ejabberd_cluster:call(Node, jd2ejd, import_file, [String]),
{result, []}; {result, []};
_ -> {error, ?ERR_BAD_REQUEST} _ ->
Txt = <<"Incorrect value of 'path' in data form">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
end end
end; end;
set_form(_From, _Host, set_form(_From, _Host,
[<<"running nodes">>, ENode, <<"import">>, <<"dir">>], [<<"running nodes">>, ENode, <<"import">>, <<"dir">>],
_Lang, XData) -> Lang, XData) ->
case search_running_node(ENode) of case search_running_node(ENode) of
false -> {error, ?ERR_ITEM_NOT_FOUND}; false ->
Txt = <<"No running node found">>,
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
Node -> Node ->
case lists:keysearch(<<"path">>, 1, XData) of case lists:keysearch(<<"path">>, 1, XData) of
false -> {error, ?ERR_BAD_REQUEST}; false ->
Txt = <<"No 'path' found in data form">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
{value, {_, [String]}} -> {value, {_, [String]}} ->
ejabberd_cluster:call(Node, jd2ejd, import_dir, [String]), ejabberd_cluster:call(Node, jd2ejd, import_dir, [String]),
{result, []}; {result, []};
_ -> {error, ?ERR_BAD_REQUEST} _ ->
Txt = <<"Incorrect value of 'path' in data form">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
end end
end; end;
set_form(From, Host, set_form(From, Host,
@ -1739,7 +1800,7 @@ set_form(From, Host,
[<<"running nodes">>, ENode, <<"shutdown">>], _Lang, [<<"running nodes">>, ENode, <<"shutdown">>], _Lang,
XData) -> XData) ->
stop_node(From, Host, ENode, stop, XData); stop_node(From, Host, ENode, stop, XData);
set_form(_From, Host, [<<"config">>, <<"acls">>], _Lang, set_form(_From, Host, [<<"config">>, <<"acls">>], Lang,
XData) -> XData) ->
case lists:keysearch(<<"acls">>, 1, XData) of case lists:keysearch(<<"acls">>, 1, XData) of
{value, {_, Strings}} -> {value, {_, Strings}} ->
@ -1753,14 +1814,16 @@ set_form(_From, Host, [<<"config">>, <<"acls">>], _Lang,
{ok, ACLs} -> {ok, ACLs} ->
acl:add_list(Host, ACLs, true), acl:add_list(Host, ACLs, true),
{result, []}; {result, []};
_ -> {error, ?ERR_BAD_REQUEST} _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Parse failed">>)}
end; end;
_ -> {error, ?ERR_BAD_REQUEST} _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Scan failed">>)}
end; end;
_ -> {error, ?ERR_BAD_REQUEST} _ ->
Txt = <<"No 'acls' found in data form">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
end; end;
set_form(_From, Host, [<<"config">>, <<"access">>], set_form(_From, Host, [<<"config">>, <<"access">>],
_Lang, XData) -> Lang, XData) ->
SetAccess = fun (Rs) -> SetAccess = fun (Rs) ->
mnesia:transaction(fun () -> mnesia:transaction(fun () ->
Os = mnesia:select(local_config, Os = mnesia:select(local_config,
@ -1803,11 +1866,13 @@ set_form(_From, Host, [<<"config">>, <<"access">>],
{atomic, _} -> {result, []}; {atomic, _} -> {result, []};
_ -> {error, ?ERR_BAD_REQUEST} _ -> {error, ?ERR_BAD_REQUEST}
end; end;
_ -> {error, ?ERR_BAD_REQUEST} _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Parse failed">>)}
end; end;
_ -> {error, ?ERR_BAD_REQUEST} _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Scan failed">>)}
end; end;
_ -> {error, ?ERR_BAD_REQUEST} _ ->
Txt = <<"No 'access' found in data form">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
end; end;
set_form(From, Host, ?NS_ADMINL(<<"add-user">>), _Lang, set_form(From, Host, ?NS_ADMINL(<<"add-user">>), _Lang,
XData) -> XData) ->
@ -2052,7 +2117,7 @@ adhoc_sm_commands(_Acc, From,
action = Action, xdata = XData} = action = Action, xdata = XData} =
Request) -> Request) ->
case acl:match_rule(LServer, configure, From) of case acl:match_rule(LServer, configure, From) of
deny -> {error, ?ERR_FORBIDDEN}; deny -> {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
allow -> allow ->
ActionIsExecute = lists:member(Action, ActionIsExecute = lists:member(Action,
[<<"">>, <<"execute">>, [<<"">>, <<"execute">>,
@ -2071,11 +2136,15 @@ adhoc_sm_commands(_Acc, From,
end; end;
XData /= false, ActionIsExecute -> XData /= false, ActionIsExecute ->
case jlib:parse_xdata_submit(XData) of case jlib:parse_xdata_submit(XData) of
invalid -> {error, ?ERR_BAD_REQUEST}; invalid ->
Txt = <<"Incorrect data form">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
Fields -> Fields ->
set_sm_form(User, Server, <<"config">>, Request, Fields) set_sm_form(User, Server, <<"config">>, Request, Fields)
end; end;
true -> {error, ?ERR_BAD_REQUEST} true ->
Txt = <<"Incorrect action or data form">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
end end
end; end;
adhoc_sm_commands(Acc, _From, _To, _Request) -> Acc. adhoc_sm_commands(Acc, _From, _To, _Request) -> Acc.
@ -2135,12 +2204,16 @@ set_sm_form(User, Server, <<"config">>,
{value, {_, [Password]}} -> {value, {_, [Password]}} ->
ejabberd_auth:set_password(User, Server, Password), ejabberd_auth:set_password(User, Server, Password),
adhoc:produce_response(Response); adhoc:produce_response(Response);
_ -> {error, ?ERR_NOT_ACCEPTABLE} _ ->
Txt = <<"No 'password' found in data form">>,
{error, ?ERRT_NOT_ACCEPTABLE(Lang, Txt)}
end; end;
{value, {_, [<<"remove">>]}} -> {value, {_, [<<"remove">>]}} ->
catch ejabberd_auth:remove_user(User, Server), catch ejabberd_auth:remove_user(User, Server),
adhoc:produce_response(Response); adhoc:produce_response(Response);
_ -> {error, ?ERR_NOT_ACCEPTABLE} _ ->
Txt = <<"Incorrect value of 'action' in data form">>,
{error, ?ERRT_NOT_ACCEPTABLE(Lang, Txt)}
end; end;
set_sm_form(_User, _Server, _Node, _Request, _Fields) -> set_sm_form(_User, _Server, _Node, _Request, _Fields) ->
{error, ?ERR_SERVICE_UNAVAILABLE}. {error, ?ERR_SERVICE_UNAVAILABLE}.

View File

@ -150,7 +150,8 @@ process_local_iq_items(From, To,
#iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
case Type of case Type of
set -> set ->
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
get -> get ->
Node = fxml:get_tag_attr_s(<<"node">>, SubEl), Node = fxml:get_tag_attr_s(<<"node">>, SubEl),
Host = To#jid.lserver, Host = To#jid.lserver,
@ -177,7 +178,8 @@ process_local_iq_info(From, To,
#iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
case Type of case Type of
set -> set ->
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
get -> get ->
Host = To#jid.lserver, Host = To#jid.lserver,
Node = fxml:get_tag_attr_s(<<"node">>, SubEl), Node = fxml:get_tag_attr_s(<<"node">>, SubEl),
@ -229,10 +231,12 @@ get_local_features(Acc, _From, To, <<>>, _Lang) ->
ets:select(disco_features, ets:select(disco_features,
[{{{'_', Host}}, [], ['$_']}]) [{{{'_', Host}}, [], ['$_']}])
++ Feats}; ++ Feats};
get_local_features(Acc, _From, _To, _Node, _Lang) -> get_local_features(Acc, _From, _To, _Node, Lang) ->
case Acc of case Acc of
{result, _Features} -> Acc; {result, _Features} -> Acc;
empty -> {error, ?ERR_ITEM_NOT_FOUND} empty ->
Txt = <<"No features available">>,
{error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)}
end. end.
features_to_xml(FeatureList) -> features_to_xml(FeatureList) ->
@ -271,8 +275,8 @@ get_local_services(Acc, _From, To, <<>>, _Lang) ->
get_local_services({result, _} = Acc, _From, _To, _Node, get_local_services({result, _} = Acc, _From, _To, _Node,
_Lang) -> _Lang) ->
Acc; Acc;
get_local_services(empty, _From, _To, _Node, _Lang) -> get_local_services(empty, _From, _To, _Node, Lang) ->
{error, ?ERR_ITEM_NOT_FOUND}. {error, ?ERRT_ITEM_NOT_FOUND(Lang, <<"No services available">>)}.
get_vh_services(Host) -> get_vh_services(Host) ->
Hosts = lists:sort(fun (H1, H2) -> Hosts = lists:sort(fun (H1, H2) ->
@ -300,7 +304,8 @@ process_sm_iq_items(From, To,
#iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
case Type of case Type of
set -> set ->
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
get -> get ->
case is_presence_subscribed(From, To) of case is_presence_subscribed(From, To) of
true -> true ->
@ -325,8 +330,9 @@ process_sm_iq_items(From, To,
IQ#iq{type = error, sub_el = [SubEl, Error]} IQ#iq{type = error, sub_el = [SubEl, Error]}
end; end;
false -> false ->
Txt = <<"Not subscribed">>,
IQ#iq{type = error, IQ#iq{type = error,
sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]} sub_el = [SubEl, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)]}
end end
end. end.
@ -347,12 +353,14 @@ get_sm_items(Acc, From,
get_sm_items({result, _} = Acc, _From, _To, _Node, get_sm_items({result, _} = Acc, _From, _To, _Node,
_Lang) -> _Lang) ->
Acc; Acc;
get_sm_items(empty, From, To, _Node, _Lang) -> get_sm_items(empty, From, To, _Node, Lang) ->
#jid{luser = LFrom, lserver = LSFrom} = From, #jid{luser = LFrom, lserver = LSFrom} = From,
#jid{luser = LTo, lserver = LSTo} = To, #jid{luser = LTo, lserver = LSTo} = To,
case {LFrom, LSFrom} of case {LFrom, LSFrom} of
{LTo, LSTo} -> {error, ?ERR_ITEM_NOT_FOUND}; {LTo, LSTo} -> {error, ?ERR_ITEM_NOT_FOUND};
_ -> {error, ?ERR_NOT_ALLOWED} _ ->
Txt = <<"Query to another users is forbidden">>,
{error, ?ERRT_NOT_ALLOWED(Lang, Txt)}
end. end.
is_presence_subscribed(#jid{luser = User, lserver = Server}, is_presence_subscribed(#jid{luser = User, lserver = Server},
@ -373,7 +381,8 @@ process_sm_iq_info(From, To,
#iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) -> #iq{type = Type, lang = Lang, sub_el = SubEl} = IQ) ->
case Type of case Type of
set -> set ->
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
get -> get ->
case is_presence_subscribed(From, To) of case is_presence_subscribed(From, To) of
true -> true ->
@ -405,8 +414,9 @@ process_sm_iq_info(From, To,
IQ#iq{type = error, sub_el = [SubEl, Error]} IQ#iq{type = error, sub_el = [SubEl, Error]}
end; end;
false -> false ->
Txt = <<"Not subscribed">>,
IQ#iq{type = error, IQ#iq{type = error,
sub_el = [SubEl, ?ERR_SERVICE_UNAVAILABLE]} sub_el = [SubEl, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)]}
end end
end. end.
@ -423,12 +433,14 @@ get_sm_identity(Acc, _From,
_ -> [] _ -> []
end. end.
get_sm_features(empty, From, To, _Node, _Lang) -> get_sm_features(empty, From, To, _Node, Lang) ->
#jid{luser = LFrom, lserver = LSFrom} = From, #jid{luser = LFrom, lserver = LSFrom} = From,
#jid{luser = LTo, lserver = LSTo} = To, #jid{luser = LTo, lserver = LSTo} = To,
case {LFrom, LSFrom} of case {LFrom, LSFrom} of
{LTo, LSTo} -> {error, ?ERR_ITEM_NOT_FOUND}; {LTo, LSTo} -> {error, ?ERR_ITEM_NOT_FOUND};
_ -> {error, ?ERR_NOT_ALLOWED} _ ->
Txt = <<"Query to another users is forbidden">>,
{error, ?ERRT_NOT_ALLOWED(Lang, Txt)}
end; end;
get_sm_features(Acc, _From, _To, _Node, _Lang) -> Acc. get_sm_features(Acc, _From, _To, _Node, _Lang) -> Acc.

View File

@ -304,8 +304,9 @@ do_route1(Host, ServerHost, From, To, Packet) ->
Lang)}]}, Lang)}]},
Res = jlib:iq_to_xml(ResIQ); Res = jlib:iq_to_xml(ResIQ);
_ -> _ ->
Res = jlib:make_error_reply(Packet, Txt = <<"Node not found">>,
?ERR_ITEM_NOT_FOUND) Res = jlib:make_error_reply(
Packet, ?ERRT_ITEM_NOT_FOUND(Lang, Txt))
end, end,
ejabberd_router:route(To, From, Res); ejabberd_router:route(To, From, Res);
#iq{xmlns = ?NS_REGISTER} = IQ -> #iq{xmlns = ?NS_REGISTER} = IQ ->
@ -319,7 +320,7 @@ do_route1(Host, ServerHost, From, To, Packet) ->
attrs = [{<<"xmlns">>, XMLNS}], attrs = [{<<"xmlns">>, XMLNS}],
children = iq_get_vcard(Lang)}]}, children = iq_get_vcard(Lang)}]},
ejabberd_router:route(To, From, jlib:iq_to_xml(Res)); ejabberd_router:route(To, From, jlib:iq_to_xml(Res));
#iq{type = set, xmlns = ?NS_COMMANDS, lang = _Lang, #iq{type = set, xmlns = ?NS_COMMANDS, lang = Lang,
sub_el = SubEl} = sub_el = SubEl} =
IQ -> IQ ->
Request = adhoc:parse_request(IQ), Request = adhoc:parse_request(IQ),
@ -348,8 +349,9 @@ do_route1(Host, ServerHost, From, To, Packet) ->
true -> ok true -> ok
end; end;
_ -> _ ->
Err = jlib:make_error_reply(Packet, Txt = <<"Node not found">>,
?ERR_ITEM_NOT_FOUND), Err = jlib:make_error_reply(
Packet, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)),
ejabberd_router:route(To, From, Err) ejabberd_router:route(To, From, Err)
end; end;
#iq{} = _IQ -> #iq{} = _IQ ->
@ -407,12 +409,14 @@ do_route1(Host, ServerHost, From, To, Packet) ->
ok ok
end; end;
_ -> _ ->
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
case str:tokens(ChanServ, <<"!">>) of case str:tokens(ChanServ, <<"!">>) of
[<<_, _/binary>> = Nick, <<_, _/binary>> = Server] -> [<<_, _/binary>> = Nick, <<_, _/binary>> = Server] ->
case ets:lookup(irc_connection, {From, Server, Host}) of case ets:lookup(irc_connection, {From, Server, Host}) of
[] -> [] ->
Err = jlib:make_error_reply(Packet, Txt = <<"IRC connection not found">>,
?ERR_SERVICE_UNAVAILABLE), Err = jlib:make_error_reply(
Packet, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)),
ejabberd_router:route(To, From, Err); ejabberd_router:route(To, From, Err);
[R] -> [R] ->
Pid = R#irc_connection.pid, Pid = R#irc_connection.pid,
@ -421,7 +425,9 @@ do_route1(Host, ServerHost, From, To, Packet) ->
ok ok
end; end;
_ -> _ ->
Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST), Txt = <<"Failed to parse chanserv">>,
Err = jlib:make_error_reply(
Packet, ?ERRT_BAD_REQUEST(Lang, Txt)),
ejabberd_router:route(To, From, Err) ejabberd_router:route(To, From, Err)
end end
end end
@ -532,8 +538,9 @@ process_irc_register(ServerHost, Host, From, _To,
XDataEl = find_xdata_el(SubEl), XDataEl = find_xdata_el(SubEl),
case XDataEl of case XDataEl of
false -> false ->
Txt1 = <<"No data form found">>,
IQ#iq{type = error, IQ#iq{type = error,
sub_el = [SubEl, ?ERR_NOT_ACCEPTABLE]}; sub_el = [SubEl, ?ERRT_NOT_ACCEPTABLE(Lang, Txt1)]};
#xmlel{attrs = Attrs} -> #xmlel{attrs = Attrs} ->
case fxml:get_attr_s(<<"type">>, Attrs) of case fxml:get_attr_s(<<"type">>, Attrs) of
<<"cancel">> -> <<"cancel">> ->
@ -546,8 +553,9 @@ process_irc_register(ServerHost, Host, From, _To,
XData = jlib:parse_xdata_submit(XDataEl), XData = jlib:parse_xdata_submit(XDataEl),
case XData of case XData of
invalid -> invalid ->
Txt2 = <<"Incorrect data form">>,
IQ#iq{type = error, IQ#iq{type = error,
sub_el = [SubEl, ?ERR_BAD_REQUEST]}; sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt2)]};
_ -> _ ->
Node = str:tokens(fxml:get_tag_attr_s(<<"node">>, Node = str:tokens(fxml:get_tag_attr_s(<<"node">>,
SubEl), SubEl),
@ -567,7 +575,9 @@ process_irc_register(ServerHost, Host, From, _To,
end end
end; end;
_ -> _ ->
IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]} Txt3 = <<"Incorrect value of 'type' attribute">>,
IQ#iq{type = error,
sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt3)]}
end end
end; end;
get -> get ->
@ -629,7 +639,9 @@ get_form(ServerHost, Host, From, [], Lang) ->
#jid{user = User, server = Server} = From, #jid{user = User, server = Server} = From,
DefaultEncoding = get_default_encoding(Host), DefaultEncoding = get_default_encoding(Host),
Customs = case get_data(ServerHost, Host, From) of Customs = case get_data(ServerHost, Host, From) of
error -> {error, ?ERR_INTERNAL_SERVER_ERROR}; error ->
Txt1 = <<"Database failure">>,
{error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt1)};
empty -> {User, []}; empty -> {User, []};
Data -> get_username_and_connection_params(Data) Data -> get_username_and_connection_params(Data)
end, end,
@ -763,7 +775,7 @@ set_data(LServer, Host, From, Data, odbc) ->
end, end,
ejabberd_odbc:sql_transaction(LServer, F). ejabberd_odbc:sql_transaction(LServer, F).
set_form(ServerHost, Host, From, [], _Lang, XData) -> set_form(ServerHost, Host, From, [], Lang, XData) ->
case {lists:keysearch(<<"username">>, 1, XData), case {lists:keysearch(<<"username">>, 1, XData),
lists:keysearch(<<"connections_params">>, 1, XData)} lists:keysearch(<<"connections_params">>, 1, XData)}
of of
@ -781,11 +793,11 @@ set_form(ServerHost, Host, From, [], _Lang, XData) ->
{connections_params, ConnectionsParams}]) {connections_params, ConnectionsParams}])
of of
{atomic, _} -> {result, []}; {atomic, _} -> {result, []};
_ -> {error, ?ERR_NOT_ACCEPTABLE} _ -> {error, ?ERRT_NOT_ACCEPTABLE(Lang, <<"Database failure">>)}
end; end;
_ -> {error, ?ERR_NOT_ACCEPTABLE} _ -> {error, ?ERRT_NOT_ACCEPTABLE(Lang, <<"Parse error">>)}
end; end;
_ -> {error, ?ERR_NOT_ACCEPTABLE} _ -> {error, ?ERRT_NOT_ACCEPTABLE(Lang, <<"Scan error">>)}
end; end;
_ -> {error, ?ERR_NOT_ACCEPTABLE} _ -> {error, ?ERR_NOT_ACCEPTABLE}
end; end;
@ -909,7 +921,9 @@ adhoc_join(From, To,
elements = [Form]}); elements = [Form]});
true -> true ->
case jlib:parse_xdata_submit(XData) of case jlib:parse_xdata_submit(XData) of
invalid -> {error, ?ERR_BAD_REQUEST}; invalid ->
Txt1 = <<"Incorrect data form">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt1)};
Fields -> Fields ->
Channel = case lists:keysearch(<<"channel">>, 1, Fields) Channel = case lists:keysearch(<<"channel">>, 1, Fields)
of of
@ -998,7 +1012,8 @@ adhoc_register(ServerHost, From, To,
true -> true ->
case jlib:parse_xdata_submit(XData) of case jlib:parse_xdata_submit(XData) of
invalid -> invalid ->
Error = {error, ?ERR_BAD_REQUEST}, Txt1 = <<"Incorrect data form">>,
Error = {error, ?ERRT_BAD_REQUEST(Lang, Txt1)},
Username = false, Username = false,
ConnectionsParams = false; ConnectionsParams = false;
Fields -> Fields ->
@ -1021,7 +1036,9 @@ adhoc_register(ServerHost, From, To,
{atomic, _} -> {atomic, _} ->
adhoc:produce_response(Request, adhoc:produce_response(Request,
#adhoc_response{status = completed}); #adhoc_response{status = completed});
_ -> {error, ?ERR_INTERNAL_SERVER_ERROR} _ ->
Txt2 = <<"Database failure">>,
{error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt2)}
end; end;
true -> true ->
Form = generate_adhoc_register_form(Lang, Username, Form = generate_adhoc_register_form(Lang, Username,

View File

@ -152,8 +152,7 @@ process_sm_iq(From, To,
of of
allow -> get_last_iq(IQ, SubEl, User, Server); allow -> get_last_iq(IQ, SubEl, User, Server);
deny -> deny ->
Txt = <<"Denied by privacy lists">>, IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]}
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_FORBIDDEN(Lang, Txt)]}
end; end;
true -> true ->
Txt = <<"Not subscribed">>, Txt = <<"Not subscribed">>,

View File

@ -252,7 +252,7 @@ normal_state({route, From, <<"">>,
IsVoiceApprovement = is_voice_approvement(Els) and IsVoiceApprovement = is_voice_approvement(Els) and
not is_visitor(From, StateData), not is_visitor(From, StateData),
if IsInvitation -> if IsInvitation ->
case catch check_invitation(From, Els, Lang, StateData) case catch check_invitation(From, Packet, Lang, StateData)
of of
{error, Error} -> {error, Error} ->
Err = jlib:make_error_reply(Packet, Error), Err = jlib:make_error_reply(Packet, Error),
@ -433,9 +433,11 @@ normal_state({route, From, <<"">>,
process_iq_owner(From, Type, Lang, SubEl, StateData); process_iq_owner(From, Type, Lang, SubEl, StateData);
?NS_DISCO_INFO -> ?NS_DISCO_INFO ->
case fxml:get_attr(<<"node">>, Attrs) of case fxml:get_attr(<<"node">>, Attrs) of
false -> process_iq_disco_info(From, Type, Lang, StateData); false -> process_iq_disco_info(From, Type, Lang, StateData);
{value, _} -> {error, ?ERR_SERVICE_UNAVAILABLE} {value, _} ->
end; Txt = <<"Disco info is not available for this node">>,
{error, ?ERRT_SERVICE_UNAVAILABLE(Lang, Txt)}
end;
?NS_DISCO_ITEMS -> ?NS_DISCO_ITEMS ->
process_iq_disco_items(From, Type, Lang, StateData); process_iq_disco_items(From, Type, Lang, StateData);
?NS_VCARD -> ?NS_VCARD ->
@ -817,8 +819,9 @@ handle_info({captcha_failed, From}, normal_state,
of of
{ok, {Nick, Packet}} -> {ok, {Nick, Packet}} ->
Robots = (?DICT):erase(From, StateData#state.robots), Robots = (?DICT):erase(From, StateData#state.robots),
Err = jlib:make_error_reply(Packet, Txt = <<"The CAPTCHA verification has failed">>,
?ERR_NOT_AUTHORIZED), Err = jlib:make_error_reply(
Packet, ?ERRT_NOT_AUTHORIZED(?MYLANG, Txt)),
ejabberd_router:route % TODO: s/Nick/""/ ejabberd_router:route % TODO: s/Nick/""/
(jid:replace_resource(StateData#state.jid, (jid:replace_resource(StateData#state.jid,
Nick), Nick),
@ -1807,6 +1810,22 @@ add_new_user(From, Nick,
StateData#state.host, From, Nick), StateData#state.host, From, Nick),
get_default_role(Affiliation, StateData)} get_default_role(Affiliation, StateData)}
of of
{false, _, _, _} when NUsers >= MaxUsers orelse NUsers >= MaxAdminUsers ->
Txt = <<"Too many users in this conference">>,
Err = jlib:make_error_reply(Packet,
?ERRT_RESOURCE_CONSTRAINT(Lang, Txt)),
ejabberd_router:route % TODO: s/Nick/""/
(jid:replace_resource(StateData#state.jid, Nick),
From, Err),
StateData;
{false, _, _, _} when NConferences >= MaxConferences ->
Txt = <<"You have joined too many conferences">>,
Err = jlib:make_error_reply(Packet,
?ERRT_RESOURCE_CONSTRAINT(Lang, Txt)),
ejabberd_router:route % TODO: s/Nick/""/
(jid:replace_resource(StateData#state.jid, Nick),
From, Err),
StateData;
{false, _, _, _} -> {false, _, _, _} ->
Err = jlib:make_error_reply(Packet, Err = jlib:make_error_reply(Packet,
?ERR_SERVICE_UNAVAILABLE), ?ERR_SERVICE_UNAVAILABLE),
@ -2555,14 +2574,18 @@ process_iq_admin(From, set, Lang, SubEl, StateData) ->
process_admin_items_set(From, Items, Lang, StateData); process_admin_items_set(From, Items, Lang, StateData);
process_iq_admin(From, get, Lang, SubEl, StateData) -> process_iq_admin(From, get, Lang, SubEl, StateData) ->
case fxml:get_subtag(SubEl, <<"item">>) of case fxml:get_subtag(SubEl, <<"item">>) of
false -> {error, ?ERR_BAD_REQUEST}; false ->
Txt = <<"No 'item' element found">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
Item -> Item ->
FAffiliation = get_affiliation(From, StateData), FAffiliation = get_affiliation(From, StateData),
FRole = get_role(From, StateData), FRole = get_role(From, StateData),
case fxml:get_tag_attr(<<"role">>, Item) of case fxml:get_tag_attr(<<"role">>, Item) of
false -> false ->
case fxml:get_tag_attr(<<"affiliation">>, Item) of case fxml:get_tag_attr(<<"affiliation">>, Item) of
false -> {error, ?ERR_BAD_REQUEST}; false ->
Txt = <<"No 'affiliation' attribute found">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
{value, StrAffiliation} -> {value, StrAffiliation} ->
case catch list_to_affiliation(StrAffiliation) of case catch list_to_affiliation(StrAffiliation) of
{'EXIT', _} -> {error, ?ERR_BAD_REQUEST}; {'EXIT', _} -> {error, ?ERR_BAD_REQUEST};
@ -2583,7 +2606,9 @@ process_iq_admin(From, get, Lang, SubEl, StateData) ->
end; end;
{value, StrRole} -> {value, StrRole} ->
case catch list_to_role(StrRole) of case catch list_to_role(StrRole) of
{'EXIT', _} -> {error, ?ERR_BAD_REQUEST}; {'EXIT', _} ->
Txt = <<"Incorrect value of 'role' attribute">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
SRole -> SRole ->
if FRole == moderator -> if FRole == moderator ->
Items = items_with_role(SRole, StateData), Items = items_with_role(SRole, StateData),
@ -2780,7 +2805,9 @@ find_changed_items(UJID, UAffiliation, URole,
{error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)}; {error, ?ERRT_NOT_ACCEPTABLE(Lang, ErrText)};
J -> {value, J} J -> {value, J}
end; end;
_ -> {error, ?ERR_BAD_REQUEST} _ ->
Txt1 = <<"No 'nick' attribute found">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt1)}
end end
end, end,
case TJID of case TJID of
@ -2790,7 +2817,9 @@ find_changed_items(UJID, UAffiliation, URole,
case fxml:get_attr(<<"role">>, Attrs) of case fxml:get_attr(<<"role">>, Attrs) of
false -> false ->
case fxml:get_attr(<<"affiliation">>, Attrs) of case fxml:get_attr(<<"affiliation">>, Attrs) of
false -> {error, ?ERR_BAD_REQUEST}; false ->
Txt2 = <<"No 'affiliation' attribute found">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt2)};
{value, StrAffiliation} -> {value, StrAffiliation} ->
case catch list_to_affiliation(StrAffiliation) of case catch list_to_affiliation(StrAffiliation) of
{'EXIT', _} -> {'EXIT', _} ->
@ -2839,7 +2868,9 @@ find_changed_items(UJID, UAffiliation, URole,
find_changed_items(UJID, UAffiliation, URole, find_changed_items(UJID, UAffiliation, URole,
Items, Lang, StateData, Items, Lang, StateData,
[MoreRes | Res]); [MoreRes | Res]);
false -> {error, ?ERR_NOT_ALLOWED} false ->
Txt3 = <<"Changing role/affiliation is not allowed">>,
{error, ?ERRT_NOT_ALLOWED(Lang, Txt3)}
end end
end end
end; end;
@ -2885,7 +2916,9 @@ find_changed_items(UJID, UAffiliation, URole,
find_changed_items(UJID, UAffiliation, URole, Items, find_changed_items(UJID, UAffiliation, URole, Items,
Lang, StateData, Lang, StateData,
[MoreRes | Res]); [MoreRes | Res]);
_ -> {error, ?ERR_NOT_ALLOWED} _ ->
Txt4 = <<"Changing role/affiliation is not allowed">>,
{error, ?ERRT_NOT_ALLOWED(Lang, Txt4)}
end end
end end
end; end;
@ -3143,10 +3176,12 @@ process_iq_owner(From, set, Lang, SubEl, StateData) ->
andalso andalso
is_password_settings_correct(XEl, StateData) is_password_settings_correct(XEl, StateData)
of of
true -> set_config(XEl, StateData); true -> set_config(XEl, StateData, Lang);
false -> {error, ?ERR_NOT_ACCEPTABLE} false -> {error, ?ERR_NOT_ACCEPTABLE}
end; end;
_ -> {error, ?ERR_BAD_REQUEST} _ ->
Txt = <<"Incorrect data form">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
end; end;
[#xmlel{name = <<"destroy">>} = SubEl1] -> [#xmlel{name = <<"destroy">>} = SubEl1] ->
?INFO_MSG("Destroyed MUC room ~s by the owner ~s", ?INFO_MSG("Destroyed MUC room ~s by the owner ~s",
@ -3170,7 +3205,9 @@ process_iq_owner(From, get, Lang, SubEl, StateData) ->
[] -> get_config(Lang, StateData, From); [] -> get_config(Lang, StateData, From);
[Item] -> [Item] ->
case fxml:get_tag_attr(<<"affiliation">>, Item) of case fxml:get_tag_attr(<<"affiliation">>, Item) of
false -> {error, ?ERR_BAD_REQUEST}; false ->
Txt = <<"No 'affiliation' attribute found">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
{value, StrAffiliation} -> {value, StrAffiliation} ->
case catch list_to_affiliation(StrAffiliation) of case catch list_to_affiliation(StrAffiliation) of
{'EXIT', _} -> {'EXIT', _} ->
@ -3642,10 +3679,10 @@ get_config(Lang, StateData, From) ->
children = Res}], children = Res}],
StateData}. StateData}.
set_config(XEl, StateData) -> set_config(XEl, StateData, Lang) ->
XData = jlib:parse_xdata_submit(XEl), XData = jlib:parse_xdata_submit(XEl),
case XData of case XData of
invalid -> {error, ?ERR_BAD_REQUEST}; invalid -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Incorrect data form">>)};
_ -> _ ->
case set_xoption(XData, StateData#state.config) of case set_xoption(XData, StateData#state.config) of
#config{} = Config -> #config{} = Config ->
@ -3675,14 +3712,20 @@ set_config(XEl, StateData) ->
<<"1">> -> set_xoption(Opts, Config#config{Opt = true}); <<"1">> -> set_xoption(Opts, Config#config{Opt = true});
<<"true">> -> <<"true">> ->
set_xoption(Opts, Config#config{Opt = true}); set_xoption(Opts, Config#config{Opt = true});
_ -> {error, ?ERR_BAD_REQUEST} _ ->
Txt = <<"Value of '~s' should be boolean">>,
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
{error, ?ERRT_BAD_REQUEST(?MYLANG, ErrTxt)}
end). end).
-define(SET_NAT_XOPT(Opt, Val), -define(SET_NAT_XOPT(Opt, Val),
case catch jlib:binary_to_integer(Val) of case catch jlib:binary_to_integer(Val) of
I when is_integer(I), I > 0 -> I when is_integer(I), I > 0 ->
set_xoption(Opts, Config#config{Opt = I}); set_xoption(Opts, Config#config{Opt = I});
_ -> {error, ?ERR_BAD_REQUEST} _ ->
Txt = <<"Value of '~s' should be integer">>,
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
{error, ?ERRT_BAD_REQUEST(?MYLANG, ErrTxt)}
end). end).
-define(SET_STRING_XOPT(Opt, Val), -define(SET_STRING_XOPT(Opt, Val),
@ -3735,7 +3778,10 @@ set_xoption([{<<"allow_private_messages_from_visitors">>,
<<"nobody">> -> <<"nobody">> ->
?SET_STRING_XOPT(allow_private_messages_from_visitors, ?SET_STRING_XOPT(allow_private_messages_from_visitors,
nobody); nobody);
_ -> {error, ?ERR_BAD_REQUEST} _ ->
Txt = <<"Value of 'allow_private_messages_from_visitors' "
"should be anyone|moderators|nobody">>,
{error, ?ERRT_BAD_REQUEST(?MYLANG, Txt)}
end; end;
set_xoption([{<<"muc#roomconfig_allowvisitorstatus">>, set_xoption([{<<"muc#roomconfig_allowvisitorstatus">>,
[Val]} [Val]}
@ -3803,7 +3849,10 @@ set_xoption([{<<"muc#roomconfig_presencebroadcast">>, Vals} | Opts],
end end
end, {false, false, false}, Vals), end, {false, false, false}, Vals),
case Roles of case Roles of
error -> {error, ?ERR_BAD_REQUEST}; error ->
Txt = <<"Value of 'muc#roomconfig_presencebroadcast' should "
"be moderator|participant|visitor">>,
{error, ?ERRT_BAD_REQUEST(?MYLANG, Txt)};
{M, P, V} -> {M, P, V} ->
Res = Res =
if M -> [moderator]; true -> [] end ++ if M -> [moderator]; true -> [] end ++
@ -3831,7 +3880,10 @@ set_xoption([{<<"muc#roomconfig_whois">>, [Val]}
<<"anyone">> -> <<"anyone">> ->
?SET_BOOL_XOPT(anonymous, ?SET_BOOL_XOPT(anonymous,
(iolist_to_binary(integer_to_list(0)))); (iolist_to_binary(integer_to_list(0))));
_ -> {error, ?ERR_BAD_REQUEST} _ ->
Txt = <<"Value of 'muc#roomconfig_whois' should be "
"moderators|anyone">>,
{error, ?ERRT_BAD_REQUEST(?MYLANG, Txt)}
end; end;
set_xoption([{<<"muc#roomconfig_maxusers">>, [Val]} set_xoption([{<<"muc#roomconfig_maxusers">>, [Val]}
| Opts], | Opts],
@ -3854,8 +3906,10 @@ set_xoption([{<<"muc#roomconfig_captcha_whitelist">>,
?SET_JIDMULTI_XOPT(captcha_whitelist, JIDs); ?SET_JIDMULTI_XOPT(captcha_whitelist, JIDs);
set_xoption([{<<"FORM_TYPE">>, _} | Opts], Config) -> set_xoption([{<<"FORM_TYPE">>, _} | Opts], Config) ->
set_xoption(Opts, Config); set_xoption(Opts, Config);
set_xoption([_ | _Opts], _Config) -> set_xoption([{Opt, _Vals} | _Opts], _Config) ->
{error, ?ERR_BAD_REQUEST}. Txt = <<"Unknown option '~s'">>,
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
{error, ?ERRT_BAD_REQUEST(?MYLANG, ErrTxt)}.
change_config(Config, StateData) -> change_config(Config, StateData) ->
send_config_change_info(Config, StateData), send_config_change_info(Config, StateData),
@ -4128,8 +4182,9 @@ destroy_room(DEl, StateData) ->
false -> ?FEATURE(Fiffalse) false -> ?FEATURE(Fiffalse)
end). end).
process_iq_disco_info(_From, set, _Lang, _StateData) -> process_iq_disco_info(_From, set, Lang, _StateData) ->
{error, ?ERR_NOT_ALLOWED}; Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
{error, ?ERRT_NOT_ALLOWED(Lang, Txt)};
process_iq_disco_info(_From, get, Lang, StateData) -> process_iq_disco_info(_From, get, Lang, StateData) ->
Config = StateData#state.config, Config = StateData#state.config,
{result, {result,
@ -4199,9 +4254,10 @@ iq_disco_info_extras(Lang, StateData) ->
<<"muc#roominfo_occupants">>, <<"muc#roominfo_occupants">>,
(iolist_to_binary(integer_to_list(Len))))]}]. (iolist_to_binary(integer_to_list(Len))))]}].
process_iq_disco_items(_From, set, _Lang, _StateData) -> process_iq_disco_items(_From, set, Lang, _StateData) ->
{error, ?ERR_NOT_ALLOWED}; Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
process_iq_disco_items(From, get, _Lang, StateData) -> {error, ?ERRT_NOT_ALLOWED(Lang, Txt)};
process_iq_disco_items(From, get, Lang, StateData) ->
case (StateData#state.config)#config.public_list of case (StateData#state.config)#config.public_list of
true -> true ->
{result, get_mucroom_disco_items(StateData), StateData}; {result, get_mucroom_disco_items(StateData), StateData};
@ -4209,18 +4265,26 @@ process_iq_disco_items(From, get, _Lang, StateData) ->
case is_occupant_or_admin(From, StateData) of case is_occupant_or_admin(From, StateData) of
true -> true ->
{result, get_mucroom_disco_items(StateData), StateData}; {result, get_mucroom_disco_items(StateData), StateData};
_ -> {error, ?ERR_FORBIDDEN} _ ->
Txt = <<"Only occupants or administrators can perform this query">>,
{error, ?ERRT_FORBIDDEN(Lang, Txt)}
end end
end. end.
process_iq_captcha(_From, get, _Lang, _SubEl, process_iq_captcha(_From, get, Lang, _SubEl,
_StateData) -> _StateData) ->
{error, ?ERR_NOT_ALLOWED}; Txt = <<"Value 'get' of 'type' attribute is not allowed">>,
process_iq_captcha(_From, set, _Lang, SubEl, {error, ?ERRT_NOT_ALLOWED(Lang, Txt)};
process_iq_captcha(_From, set, Lang, SubEl,
StateData) -> StateData) ->
case ejabberd_captcha:process_reply(SubEl) of case ejabberd_captcha:process_reply(SubEl) of
ok -> {result, [], StateData}; ok -> {result, [], StateData};
_ -> {error, ?ERR_NOT_ACCEPTABLE} {error, malformed} ->
Txt = <<"Incorrect CAPTCHA submit">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
_ ->
Txt = <<"The CAPTCHA verification has failed">>,
{error, ?ERRT_NOT_ALLOWED(Lang, Txt)}
end. end.
process_iq_vcard(_From, get, _Lang, _SubEl, StateData) -> process_iq_vcard(_From, get, _Lang, _SubEl, StateData) ->
@ -4442,33 +4506,38 @@ is_invitation(Els) ->
end, end,
false, Els). false, Els).
check_invitation(From, Els, Lang, StateData) -> check_invitation(From, Packet, Lang, StateData) ->
FAffiliation = get_affiliation(From, StateData), FAffiliation = get_affiliation(From, StateData),
CanInvite = CanInvite =
(StateData#state.config)#config.allow_user_invites (StateData#state.config)#config.allow_user_invites
orelse orelse
FAffiliation == admin orelse FAffiliation == owner, FAffiliation == admin orelse FAffiliation == owner,
InviteEl = case fxml:remove_cdata(Els) of InviteEl = case fxml:get_subtag_with_xmlns(Packet, <<"x">>, ?NS_MUC_USER) of
[#xmlel{name = <<"x">>, children = Els1} = XEl] -> false ->
case fxml:get_tag_attr_s(<<"xmlns">>, XEl) of Txt1 = <<"No 'x' element found">>,
?NS_MUC_USER -> ok; throw({error, ?ERRT_BAD_REQUEST(Lang, Txt1)});
_ -> throw({error, ?ERR_BAD_REQUEST}) XEl ->
end, case fxml:get_subtag(XEl, <<"invite">>) of
case fxml:remove_cdata(Els1) of false ->
[#xmlel{name = <<"invite">>} = InviteEl1] -> InviteEl1; Txt2 = <<"No 'invite' element found">>,
_ -> throw({error, ?ERR_BAD_REQUEST}) throw({error, ?ERRT_BAD_REQUEST(Lang, Txt2)});
end; InviteEl1 ->
_ -> throw({error, ?ERR_BAD_REQUEST}) InviteEl1
end
end, end,
JID = case JID = case
jid:from_string(fxml:get_tag_attr_s(<<"to">>, jid:from_string(fxml:get_tag_attr_s(<<"to">>,
InviteEl)) InviteEl))
of of
error -> throw({error, ?ERR_JID_MALFORMED}); error ->
Txt = <<"Incorrect value of 'to' attribute">>,
throw({error, ?ERRT_JID_MALFORMED(Lang, Txt)});
JID1 -> JID1 JID1 -> JID1
end, end,
case CanInvite of case CanInvite of
false -> throw({error, ?ERR_NOT_ALLOWED}); false ->
Txt3 = <<"Invitations are not allowed in this conference">>,
throw({error, ?ERRT_NOT_ALLOWED(Lang, Txt3)});
true -> true ->
Reason = fxml:get_path_s(InviteEl, Reason = fxml:get_path_s(InviteEl,
[{elem, <<"reason">>}, cdata]), [{elem, <<"reason">>}, cdata]),

View File

@ -105,27 +105,29 @@ process_iq(_From, _To, IQ) ->
SubEl = IQ#iq.sub_el, SubEl = IQ#iq.sub_el,
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}. IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}.
process_iq_get(_, From, _To, #iq{sub_el = SubEl}, process_iq_get(_, From, _To, #iq{lang = Lang, sub_el = SubEl},
#userlist{name = Active}) -> #userlist{name = Active}) ->
#jid{luser = LUser, lserver = LServer} = From, #jid{luser = LUser, lserver = LServer} = From,
#xmlel{children = Els} = SubEl, #xmlel{children = Els} = SubEl,
case fxml:remove_cdata(Els) of case fxml:remove_cdata(Els) of
[] -> process_lists_get(LUser, LServer, Active); [] -> process_lists_get(LUser, LServer, Active, Lang);
[#xmlel{name = Name, attrs = Attrs}] -> [#xmlel{name = Name, attrs = Attrs}] ->
case Name of case Name of
<<"list">> -> <<"list">> ->
ListName = fxml:get_attr(<<"name">>, Attrs), ListName = fxml:get_attr(<<"name">>, Attrs),
process_list_get(LUser, LServer, ListName); process_list_get(LUser, LServer, ListName, Lang);
_ -> {error, ?ERR_BAD_REQUEST} _ ->
Txt = <<"Unsupported tag name">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
end; end;
_ -> {error, ?ERR_BAD_REQUEST} _ -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Too many elements">>)}
end. end.
process_lists_get(LUser, LServer, Active) -> process_lists_get(LUser, LServer, Active, Lang) ->
case process_lists_get(LUser, LServer, Active, case process_lists_get_db(LUser, LServer, Active,
gen_mod:db_type(LServer, ?MODULE)) gen_mod:db_type(LServer, ?MODULE))
of of
error -> {error, ?ERR_INTERNAL_SERVER_ERROR}; error -> {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)};
{_Default, []} -> {_Default, []} ->
{result, {result,
[#xmlel{name = <<"query">>, [#xmlel{name = <<"query">>,
@ -151,7 +153,7 @@ process_lists_get(LUser, LServer, Active) ->
children = ADItems}]} children = ADItems}]}
end. end.
process_lists_get(LUser, LServer, _Active, mnesia) -> process_lists_get_db(LUser, LServer, _Active, mnesia) ->
case catch mnesia:dirty_read(privacy, {LUser, LServer}) case catch mnesia:dirty_read(privacy, {LUser, LServer})
of of
{'EXIT', _Reason} -> error; {'EXIT', _Reason} -> error;
@ -165,7 +167,7 @@ process_lists_get(LUser, LServer, _Active, mnesia) ->
Lists), Lists),
{Default, LItems} {Default, LItems}
end; end;
process_lists_get(LUser, LServer, _Active, riak) -> process_lists_get_db(LUser, LServer, _Active, riak) ->
case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of
{ok, #privacy{default = Default, lists = Lists}} -> {ok, #privacy{default = Default, lists = Lists}} ->
LItems = lists:map(fun ({N, _}) -> LItems = lists:map(fun ({N, _}) ->
@ -180,7 +182,7 @@ process_lists_get(LUser, LServer, _Active, riak) ->
{error, _} -> {error, _} ->
error error
end; end;
process_lists_get(LUser, LServer, _Active, odbc) -> process_lists_get_db(LUser, LServer, _Active, odbc) ->
Default = case catch sql_get_default_privacy_list(LUser, LServer) of Default = case catch sql_get_default_privacy_list(LUser, LServer) of
{selected, []} -> none; {selected, []} -> none;
{selected, [{DefName}]} -> DefName; {selected, [{DefName}]} -> DefName;
@ -198,11 +200,11 @@ process_lists_get(LUser, LServer, _Active, odbc) ->
_ -> error _ -> error
end. end.
process_list_get(LUser, LServer, {value, Name}) -> process_list_get(LUser, LServer, {value, Name}, Lang) ->
case process_list_get(LUser, LServer, Name, case process_list_get_db(LUser, LServer, Name,
gen_mod:db_type(LServer, ?MODULE)) gen_mod:db_type(LServer, ?MODULE))
of of
error -> {error, ?ERR_INTERNAL_SERVER_ERROR}; error -> {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)};
not_found -> {error, ?ERR_ITEM_NOT_FOUND}; not_found -> {error, ?ERR_ITEM_NOT_FOUND};
Items -> Items ->
LItems = lists:map(fun item_to_xml/1, Items), LItems = lists:map(fun item_to_xml/1, Items),
@ -213,10 +215,10 @@ process_list_get(LUser, LServer, {value, Name}) ->
[#xmlel{name = <<"list">>, attrs = [{<<"name">>, Name}], [#xmlel{name = <<"list">>, attrs = [{<<"name">>, Name}],
children = LItems}]}]} children = LItems}]}]}
end; end;
process_list_get(_LUser, _LServer, false) -> process_list_get(_LUser, _LServer, false, _Lang) ->
{error, ?ERR_BAD_REQUEST}. {error, ?ERR_BAD_REQUEST}.
process_list_get(LUser, LServer, Name, mnesia) -> process_list_get_db(LUser, LServer, Name, mnesia) ->
case catch mnesia:dirty_read(privacy, {LUser, LServer}) case catch mnesia:dirty_read(privacy, {LUser, LServer})
of of
{'EXIT', _Reason} -> error; {'EXIT', _Reason} -> error;
@ -227,7 +229,7 @@ process_list_get(LUser, LServer, Name, mnesia) ->
_ -> not_found _ -> not_found
end end
end; end;
process_list_get(LUser, LServer, Name, riak) -> process_list_get_db(LUser, LServer, Name, riak) ->
case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of
{ok, #privacy{lists = Lists}} -> {ok, #privacy{lists = Lists}} ->
case lists:keysearch(Name, 1, Lists) of case lists:keysearch(Name, 1, Lists) of
@ -239,7 +241,7 @@ process_list_get(LUser, LServer, Name, riak) ->
{error, _} -> {error, _} ->
error error
end; end;
process_list_get(LUser, LServer, Name, odbc) -> process_list_get_db(LUser, LServer, Name, odbc) ->
case catch sql_get_privacy_list_id(LUser, LServer, Name) of case catch sql_get_privacy_list_id(LUser, LServer, Name) of
{selected, []} -> not_found; {selected, []} -> not_found;
{selected, [{ID}]} -> {selected, [{ID}]} ->
@ -332,7 +334,7 @@ list_to_action(S) ->
<<"deny">> -> deny <<"deny">> -> deny
end. end.
process_iq_set(_, From, _To, #iq{sub_el = SubEl}) -> process_iq_set(_, From, _To, #iq{lang = Lang, sub_el = SubEl}) ->
#jid{luser = LUser, lserver = LServer} = From, #jid{luser = LUser, lserver = LServer} = From,
#xmlel{children = Els} = SubEl, #xmlel{children = Els} = SubEl,
case fxml:remove_cdata(Els) of case fxml:remove_cdata(Els) of
@ -342,27 +344,30 @@ process_iq_set(_, From, _To, #iq{sub_el = SubEl}) ->
case Name of case Name of
<<"list">> -> <<"list">> ->
process_list_set(LUser, LServer, ListName, process_list_set(LUser, LServer, ListName,
fxml:remove_cdata(SubEls)); fxml:remove_cdata(SubEls), Lang);
<<"active">> -> <<"active">> ->
process_active_set(LUser, LServer, ListName); process_active_set(LUser, LServer, ListName);
<<"default">> -> <<"default">> ->
process_default_set(LUser, LServer, ListName); process_default_set(LUser, LServer, ListName, Lang);
_ -> {error, ?ERR_BAD_REQUEST} _ ->
Txt = <<"Unsupported tag name">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
end; end;
_ -> {error, ?ERR_BAD_REQUEST} _ -> {error, ?ERR_BAD_REQUEST}
end. end.
process_default_set(LUser, LServer, Value) -> process_default_set(LUser, LServer, Value, Lang) ->
case process_default_set(LUser, LServer, Value, case process_default_set_db(LUser, LServer, Value,
gen_mod:db_type(LServer, ?MODULE)) gen_mod:db_type(LServer, ?MODULE))
of of
{atomic, error} -> {error, ?ERR_INTERNAL_SERVER_ERROR}; {atomic, error} ->
{error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)};
{atomic, not_found} -> {error, ?ERR_ITEM_NOT_FOUND}; {atomic, not_found} -> {error, ?ERR_ITEM_NOT_FOUND};
{atomic, ok} -> {result, []}; {atomic, ok} -> {result, []};
_ -> {error, ?ERR_INTERNAL_SERVER_ERROR} _ -> {error, ?ERR_INTERNAL_SERVER_ERROR}
end. end.
process_default_set(LUser, LServer, {value, Name}, process_default_set_db(LUser, LServer, {value, Name},
mnesia) -> mnesia) ->
F = fun () -> F = fun () ->
case mnesia:read({privacy, {LUser, LServer}}) of case mnesia:read({privacy, {LUser, LServer}}) of
@ -378,7 +383,7 @@ process_default_set(LUser, LServer, {value, Name},
end end
end, end,
mnesia:transaction(F); mnesia:transaction(F);
process_default_set(LUser, LServer, {value, Name}, riak) -> process_default_set_db(LUser, LServer, {value, Name}, riak) ->
{atomic, {atomic,
case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of
{ok, #privacy{lists = Lists} = P} -> {ok, #privacy{lists = Lists} = P} ->
@ -393,7 +398,7 @@ process_default_set(LUser, LServer, {value, Name}, riak) ->
{error, _} -> {error, _} ->
not_found not_found
end}; end};
process_default_set(LUser, LServer, {value, Name}, process_default_set_db(LUser, LServer, {value, Name},
odbc) -> odbc) ->
F = fun () -> F = fun () ->
case sql_get_privacy_list_names_t(LUser) of case sql_get_privacy_list_names_t(LUser) of
@ -406,7 +411,7 @@ process_default_set(LUser, LServer, {value, Name},
end end
end, end,
odbc_queries:sql_transaction(LServer, F); odbc_queries:sql_transaction(LServer, F);
process_default_set(LUser, LServer, false, mnesia) -> process_default_set_db(LUser, LServer, false, mnesia) ->
F = fun () -> F = fun () ->
case mnesia:read({privacy, {LUser, LServer}}) of case mnesia:read({privacy, {LUser, LServer}}) of
[] -> ok; [] -> ok;
@ -414,7 +419,7 @@ process_default_set(LUser, LServer, false, mnesia) ->
end end
end, end,
mnesia:transaction(F); mnesia:transaction(F);
process_default_set(LUser, LServer, false, riak) -> process_default_set_db(LUser, LServer, false, riak) ->
{atomic, {atomic,
case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of case ejabberd_riak:get(privacy, privacy_schema(), {LUser, LServer}) of
{ok, R} -> {ok, R} ->
@ -422,7 +427,7 @@ process_default_set(LUser, LServer, false, riak) ->
{error, _} -> {error, _} ->
ok ok
end}; end};
process_default_set(LUser, LServer, false, odbc) -> process_default_set_db(LUser, LServer, false, odbc) ->
case catch sql_unset_default_privacy_list(LUser, case catch sql_unset_default_privacy_list(LUser,
LServer) LServer)
of of
@ -588,14 +593,16 @@ set_privacy_list(LUser, LServer, Name, List, odbc) ->
end, end,
odbc_queries:sql_transaction(LServer, F). odbc_queries:sql_transaction(LServer, F).
process_list_set(LUser, LServer, {value, Name}, Els) -> process_list_set(LUser, LServer, {value, Name}, Els, Lang) ->
case parse_items(Els) of case parse_items(Els) of
false -> {error, ?ERR_BAD_REQUEST}; false -> {error, ?ERR_BAD_REQUEST};
remove -> remove ->
case remove_privacy_list(LUser, LServer, Name, case remove_privacy_list(LUser, LServer, Name,
gen_mod:db_type(LServer, ?MODULE)) gen_mod:db_type(LServer, ?MODULE))
of of
{atomic, conflict} -> {error, ?ERR_CONFLICT}; {atomic, conflict} ->
Txt = <<"Cannot remove default list">>,
{error, ?ERRT_CONFLICT(Lang, Txt)};
{atomic, ok} -> {atomic, ok} ->
ejabberd_sm:route(jid:make(LUser, LServer, ejabberd_sm:route(jid:make(LUser, LServer,
<<"">>), <<"">>),
@ -605,7 +612,7 @@ process_list_set(LUser, LServer, {value, Name}, Els) ->
list = []}, list = []},
Name}}), Name}}),
{result, []}; {result, []};
_ -> {error, ?ERR_INTERNAL_SERVER_ERROR} _ -> {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)}
end; end;
List -> List ->
case set_privacy_list(LUser, LServer, Name, List, case set_privacy_list(LUser, LServer, Name, List,
@ -622,10 +629,10 @@ process_list_set(LUser, LServer, {value, Name}, Els) ->
needdb = NeedDb}, needdb = NeedDb},
Name}}), Name}}),
{result, []}; {result, []};
_ -> {error, ?ERR_INTERNAL_SERVER_ERROR} _ -> {error, ?ERRT_INTERNAL_SERVER_ERROR(Lang, <<"Database failure">>)}
end end
end; end;
process_list_set(_LUser, _LServer, false, _Els) -> process_list_set(_LUser, _LServer, false, _Els, _Lang) ->
{error, ?ERR_BAD_REQUEST}. {error, ?ERR_BAD_REQUEST}.
parse_items([]) -> remove; parse_items([]) -> remove;

View File

@ -1034,7 +1034,10 @@ do_route(ServerHost, Access, Plugins, Host, From, To, Packet) ->
none -> none ->
ok; ok;
invalid -> invalid ->
Err = jlib:make_error_reply(Packet, ?ERR_BAD_REQUEST), Lang = fxml:get_attr_s(<<"xml:lang">>, Attrs),
Txt = <<"Incorrect authorization response">>,
Err = jlib:make_error_reply(
Packet, ?ERRT_BAD_REQUEST(Lang, Txt)),
ejabberd_router:route(To, From, Err); ejabberd_router:route(To, From, Err);
XFields -> XFields ->
handle_authorization_response(Host, From, To, Packet, XFields) handle_authorization_response(Host, From, To, Packet, XFields)
@ -1418,13 +1421,14 @@ adhoc_request(Host, _ServerHost, Owner,
send_pending_node_form(Host, Owner, Lang, Plugins); send_pending_node_form(Host, Owner, Lang, Plugins);
adhoc_request(Host, _ServerHost, Owner, adhoc_request(Host, _ServerHost, Owner,
#adhoc_request{node = ?NS_PUBSUB_GET_PENDING, #adhoc_request{node = ?NS_PUBSUB_GET_PENDING,
action = <<"execute">>, xdata = XData}, action = <<"execute">>, xdata = XData, lang = Lang},
_Access, _Plugins) -> _Access, _Plugins) ->
ParseOptions = case XData of ParseOptions = case XData of
#xmlel{name = <<"x">>} = XEl -> #xmlel{name = <<"x">>} = XEl ->
case jlib:parse_xdata_submit(XEl) of case jlib:parse_xdata_submit(XEl) of
invalid -> invalid ->
{error, ?ERR_BAD_REQUEST}; Txt = <<"Incorrect data form">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
XData2 -> XData2 ->
case set_xoption(Host, XData2, []) of case set_xoption(Host, XData2, []) of
NewOpts when is_list(NewOpts) -> {result, NewOpts}; NewOpts when is_list(NewOpts) -> {result, NewOpts};
@ -1432,8 +1436,8 @@ adhoc_request(Host, _ServerHost, Owner,
end end
end; end;
_ -> _ ->
?INFO_MSG("Bad XForm: ~p", [XData]), Txt = <<"No data form found">>,
{error, ?ERR_BAD_REQUEST} {error, ?ERRT_BAD_REQUEST(Lang, Txt)}
end, end,
case ParseOptions of case ParseOptions of
{result, XForm} -> {result, XForm} ->
@ -1463,7 +1467,9 @@ send_pending_node_form(Host, Owner, _Lang, Plugins) ->
end, end,
case lists:filter(Filter, Plugins) of case lists:filter(Filter, Plugins) of
[] -> [] ->
{error, ?ERR_FEATURE_NOT_IMPLEMENTED}; Err = extended_error(?ERR_FEATURE_NOT_IMPLEMENTED,
unsupported, <<"get-pending">>),
{error, Err};
Ps -> Ps ->
XOpts = [#xmlel{name = <<"option">>, attrs = [], XOpts = [#xmlel{name = <<"option">>, attrs = [],
children = [#xmlel{name = <<"value">>, children = [#xmlel{name = <<"value">>,
@ -1504,10 +1510,11 @@ send_pending_auth_events(Host, Node, Owner) ->
true -> true ->
case node_call(Host, Type, get_affiliation, [Nidx, Owner]) of case node_call(Host, Type, get_affiliation, [Nidx, Owner]) of
{result, owner} -> node_call(Host, Type, get_node_subscriptions, [Nidx]); {result, owner} -> node_call(Host, Type, get_node_subscriptions, [Nidx]);
_ -> {error, ?ERR_FORBIDDEN} _ -> {error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)}
end; end;
false -> false ->
{error, ?ERR_FEATURE_NOT_IMPLEMENTED} {error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED,
unsupported, <<"get-pending">>)}
end end
end, end,
case transaction(Host, Node, Action, sync_dirty) of case transaction(Host, Node, Action, sync_dirty) of
@ -1644,6 +1651,7 @@ send_authorization_approval(Host, JID, SNode, Subscription) ->
ejabberd_router:route(service_jid(Host), JID, Stanza). ejabberd_router:route(service_jid(Host), JID, Stanza).
handle_authorization_response(Host, From, To, Packet, XFields) -> handle_authorization_response(Host, From, To, Packet, XFields) ->
Lang = fxml:get_tag_attr_s(<<"xml:lang">>, Packet),
case {lists:keysearch(<<"pubsub#node">>, 1, XFields), case {lists:keysearch(<<"pubsub#node">>, 1, XFields),
lists:keysearch(<<"pubsub#subscriber_jid">>, 1, XFields), lists:keysearch(<<"pubsub#subscriber_jid">>, 1, XFields),
lists:keysearch(<<"pubsub#allow">>, 1, XFields)} lists:keysearch(<<"pubsub#allow">>, 1, XFields)}
@ -1665,7 +1673,7 @@ handle_authorization_response(Host, From, To, Packet, XFields) ->
{result, Subs} = node_call(Host, Type, get_subscriptions, [Nidx, Subscriber]), {result, Subs} = node_call(Host, Type, get_subscriptions, [Nidx, Subscriber]),
update_auth(Host, Node, Type, Nidx, Subscriber, Allow, Subs); update_auth(Host, Node, Type, Nidx, Subscriber, Allow, Subs);
false -> false ->
{error, ?ERR_FORBIDDEN} {error, ?ERRT_FORBIDDEN(Lang, <<"You're not an owner">>)}
end end
end, end,
case transaction(Host, Node, Action, sync_dirty) of case transaction(Host, Node, Action, sync_dirty) of
@ -1680,7 +1688,8 @@ handle_authorization_response(Host, From, To, Packet, XFields) ->
ejabberd_router:route(To, From, Err) ejabberd_router:route(To, From, Err)
end; end;
_ -> _ ->
Err = jlib:make_error_reply(Packet, ?ERR_NOT_ACCEPTABLE), Txt = <<"Incorrect data form">>,
Err = jlib:make_error_reply(Packet, ?ERRT_NOT_ACCEPTABLE(Lang, Txt)),
ejabberd_router:route(To, From, Err) ejabberd_router:route(To, From, Err)
end. end.
@ -1691,7 +1700,7 @@ update_auth(Host, Node, Type, Nidx, Subscriber, Allow, Subs) ->
end, end,
Subs), Subs),
case Sub of case Sub of
[{pending, SubId}] -> [{pending, SubId}|_] ->
NewSub = case Allow of NewSub = case Allow of
true -> subscribed; true -> subscribed;
false -> none false -> none
@ -1700,7 +1709,8 @@ update_auth(Host, Node, Type, Nidx, Subscriber, Allow, Subs) ->
send_authorization_approval(Host, Subscriber, Node, NewSub), send_authorization_approval(Host, Subscriber, Node, NewSub),
{result, ok}; {result, ok};
_ -> _ ->
{error, ?ERR_UNEXPECTED_REQUEST} Txt = <<"No pending subscriptions found">>,
{error, ?ERRT_UNEXPECTED_REQUEST(?MYLANG, Txt)}
end. end.
-define(XFIELD(Type, Label, Var, Val), -define(XFIELD(Type, Label, Var, Val),
@ -1830,7 +1840,8 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
[#xmlel{name = <<"x">>} = XEl] -> [#xmlel{name = <<"x">>} = XEl] ->
case jlib:parse_xdata_submit(XEl) of case jlib:parse_xdata_submit(XEl) of
invalid -> invalid ->
{error, ?ERR_BAD_REQUEST}; Txt = <<"Incorrect data form">>,
{error, ?ERRT_BAD_REQUEST(?MYLANG, Txt)};
XData -> XData ->
case set_xoption(Host, XData, node_options(Host, Type)) of case set_xoption(Host, XData, node_options(Host, Type)) of
NewOpts when is_list(NewOpts) -> {result, NewOpts}; NewOpts when is_list(NewOpts) -> {result, NewOpts};
@ -1839,7 +1850,8 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
end; end;
_ -> _ ->
?INFO_MSG("Node ~p; bad configuration: ~p", [Node, Configuration]), ?INFO_MSG("Node ~p; bad configuration: ~p", [Node, Configuration]),
{error, ?ERR_BAD_REQUEST} Txt = <<"No data form found">>,
{error, ?ERRT_BAD_REQUEST(?MYLANG, Txt)}
end, end,
case ParseOptions of case ParseOptions of
{result, NodeOptions} -> {result, NodeOptions} ->
@ -1876,7 +1888,8 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
Error Error
end; end;
_ -> _ ->
{error, ?ERR_FORBIDDEN} Txt1 = <<"You're not allowed to create nodes">>,
{error, ?ERRT_FORBIDDEN(?MYLANG, Txt1)}
end end
end, end,
Reply = [#xmlel{name = <<"pubsub">>, Reply = [#xmlel{name = <<"pubsub">>,
@ -1926,7 +1939,7 @@ create_node(Host, ServerHost, Node, Owner, GivenType, Access, Configuration) ->
| {error, xmlel()} | {error, xmlel()}
). ).
delete_node(_Host, <<>>, _Owner) -> delete_node(_Host, <<>>, _Owner) ->
{error, ?ERR_NOT_ALLOWED}; {error, ?ERRT_NOT_ALLOWED(?MYLANG, <<"No node specified">>)};
delete_node(Host, Node, Owner) -> delete_node(Host, Node, Owner) ->
Action = fun (#pubsub_node{type = Type, id = Nidx}) -> Action = fun (#pubsub_node{type = Type, id = Nidx}) ->
case node_call(Host, Type, get_affiliation, [Nidx, Owner]) of case node_call(Host, Type, get_affiliation, [Nidx, Owner]) of
@ -1938,7 +1951,7 @@ delete_node(Host, Node, Owner) ->
Error -> Error Error -> Error
end; end;
_ -> _ ->
{error, ?ERR_FORBIDDEN} {error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)}
end end
end, end,
Reply = [], Reply = [],
@ -2247,22 +2260,28 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload, Access) ->
{result, Reply}; {result, Reply};
{result, {_, Result}} -> {result, {_, Result}} ->
{result, Result}; {result, Result};
{error, ?ERR_ITEM_NOT_FOUND} -> {error, _} = Error ->
Type = select_type(ServerHost, Host, Node), case is_item_not_found(Error) of
case lists:member(<<"auto-create">>, plugin_features(Host, Type)) of
true -> true ->
case create_node(Host, ServerHost, Node, Publisher, Type, Access, []) of Type = select_type(ServerHost, Host, Node),
{result, case lists:member(<<"auto-create">>, plugin_features(Host, Type)) of
[#xmlel{name = <<"pubsub">>, true ->
attrs = [{<<"xmlns">>, ?NS_PUBSUB}], case create_node(Host, ServerHost, Node, Publisher, Type, Access, []) of
children = [#xmlel{name = <<"create">>, {result,
attrs = [{<<"node">>, NewNode}]}]}]} -> [#xmlel{name = <<"pubsub">>,
publish_item(Host, ServerHost, NewNode, Publisher, ItemId, Payload); attrs = [{<<"xmlns">>, ?NS_PUBSUB}],
_ -> children = [#xmlel{name = <<"create">>,
{error, ?ERR_ITEM_NOT_FOUND} attrs = [{<<"node">>, NewNode}]}]}]} ->
publish_item(Host, ServerHost, NewNode, Publisher, ItemId, Payload);
_ ->
{error, ?ERR_ITEM_NOT_FOUND}
end;
false ->
Txt = <<"Automatic node creation is not enabled">>,
{error, ?ERRT_ITEM_NOT_FOUND(?MYLANG, Txt)}
end; end;
false -> false ->
{error, ?ERR_ITEM_NOT_FOUND} Error
end; end;
Error -> Error ->
Error Error
@ -2416,7 +2435,9 @@ get_items(Host, Node, From, SubId, SMaxItems, ItemIds, RSM) ->
end; end;
true -> true ->
case catch jlib:binary_to_integer(SMaxItems) of case catch jlib:binary_to_integer(SMaxItems) of
{'EXIT', _} -> {error, ?ERR_BAD_REQUEST}; {'EXIT', _} ->
Txt = <<"Value of 'max_items' should be integer">>,
{error, ?ERRT_BAD_REQUEST(?MYLANG, Txt)};
Val -> Val Val -> Val
end end
end, end,
@ -2639,7 +2660,7 @@ get_affiliations(Host, Node, JID) ->
{error, {error,
extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"modify-affiliations">>)}; extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"modify-affiliations">>)};
Affiliation /= owner -> Affiliation /= owner ->
{error, ?ERR_FORBIDDEN}; {error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)};
true -> true ->
node_call(Host, Type, get_node_affiliations, [Nidx]) node_call(Host, Type, get_node_affiliations, [Nidx])
end end
@ -2732,7 +2753,7 @@ set_affiliations(Host, Node, From, EntitiesEls) ->
FilteredEntities), FilteredEntities),
{result, []}; {result, []};
_ -> _ ->
{error, ?ERR_FORBIDDEN} {error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)}
end end
end, end,
case transaction(Host, Node, Action, sync_dirty) of case transaction(Host, Node, Action, sync_dirty) of
@ -2948,7 +2969,7 @@ get_subscriptions(Host, Node, JID) ->
{error, {error,
extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"manage-subscriptions">>)}; extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, <<"manage-subscriptions">>)};
Affiliation /= owner -> Affiliation /= owner ->
{error, ?ERR_FORBIDDEN}; {error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)};
true -> true ->
node_call(Host, Type, get_node_subscriptions, [Nidx]) node_call(Host, Type, get_node_subscriptions, [Nidx])
end end
@ -3059,10 +3080,10 @@ set_subscriptions(Host, Node, From, EntitiesEls) ->
[], Entities), [], Entities),
case Result of case Result of
[] -> {result, []}; [] -> {result, []};
_ -> {error, ?ERR_NOT_ACCEPTABLE} [{error, E}|_] -> {error, E}
end; end;
_ -> _ ->
{error, ?ERR_FORBIDDEN} {error, ?ERRT_FORBIDDEN(?MYLANG, <<"You're not an owner">>)}
end end
end, end,
case transaction(Host, Node, Action, sync_dirty) of case transaction(Host, Node, Action, sync_dirty) of
@ -3606,7 +3627,7 @@ get_configure(Host, ServerHost, Node, From, Lang) ->
children = children =
get_configure_xfields(Type, Options, Lang, Groups)}]}]}]}; get_configure_xfields(Type, Options, Lang, Groups)}]}]}]};
_ -> _ ->
{error, ?ERR_FORBIDDEN} {error, ?ERRT_FORBIDDEN(Lang, <<"You're not an owner">>)}
end end
end, end,
case transaction(Host, Node, Action, sync_dirty) of case transaction(Host, Node, Action, sync_dirty) of
@ -3820,7 +3841,8 @@ set_configure(Host, Node, From, Els, Lang) ->
{result, owner} -> {result, owner} ->
case jlib:parse_xdata_submit(XEl) of case jlib:parse_xdata_submit(XEl) of
invalid -> invalid ->
{error, ?ERR_BAD_REQUEST}; Txt = <<"Incorrect data form">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)};
XData -> XData ->
OldOpts = case Options of OldOpts = case Options of
[] -> node_options(Host, Type); [] -> node_options(Host, Type);
@ -3840,7 +3862,8 @@ set_configure(Host, Node, From, Els, Lang) ->
end end
end; end;
_ -> _ ->
{error, ?ERR_FORBIDDEN} Txt = <<"You're not an owner">>,
{error, ?ERRT_FORBIDDEN(Lang, Txt)}
end end
end, end,
case transaction(Host, Node, Action, transaction) of case transaction(Host, Node, Action, transaction) of
@ -3854,10 +3877,12 @@ set_configure(Host, Node, From, Els, Lang) ->
Other Other
end; end;
_ -> _ ->
{error, ?ERR_BAD_REQUEST} Txt = <<"Incorrect data form">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
end; end;
_ -> _ ->
{error, ?ERR_BAD_REQUEST} Txt = <<"No data form found">>,
{error, ?ERRT_BAD_REQUEST(Lang, Txt)}
end. end.
add_opt(Key, Value, Opts) -> add_opt(Key, Value, Opts) ->
@ -3872,7 +3897,10 @@ add_opt(Key, Value, Opts) ->
_ -> error _ -> error
end, end,
case BoolVal of case BoolVal of
error -> {error, ?ERR_NOT_ACCEPTABLE}; error ->
Txt = <<"Value of '~s' should be boolean">>,
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
{error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)};
_ -> set_xoption(Host, Opts, add_opt(Opt, BoolVal, NewOpts)) _ -> set_xoption(Host, Opts, add_opt(Opt, BoolVal, NewOpts))
end). end).
@ -3885,10 +3913,14 @@ add_opt(Key, Value, Opts) ->
if (Max =:= undefined) orelse (IVal =< Max) -> if (Max =:= undefined) orelse (IVal =< Max) ->
set_xoption(Host, Opts, add_opt(Opt, IVal, NewOpts)); set_xoption(Host, Opts, add_opt(Opt, IVal, NewOpts));
true -> true ->
{error, ?ERR_NOT_ACCEPTABLE} Txt = <<"Incorrect value of '~s'">>,
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
{error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)}
end; end;
_ -> _ ->
{error, ?ERR_NOT_ACCEPTABLE} Txt = <<"Value of '~s' should be integer">>,
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
{error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)}
end). end).
-define(SET_ALIST_XOPT(Opt, Val, Vals), -define(SET_ALIST_XOPT(Opt, Val, Vals),
@ -3896,7 +3928,9 @@ add_opt(Key, Value, Opts) ->
true -> true ->
set_xoption(Host, Opts, add_opt(Opt, jlib:binary_to_atom(Val), NewOpts)); set_xoption(Host, Opts, add_opt(Opt, jlib:binary_to_atom(Val), NewOpts));
false -> false ->
{error, ?ERR_NOT_ACCEPTABLE} Txt = <<"Incorrect value of '~s'">>,
ErrTxt = iolist_to_binary(io_lib:format(Txt, [Opt])),
{error, ?ERRT_NOT_ACCEPTABLE(?MYLANG, ErrTxt)}
end). end).
-define(SET_LIST_XOPT(Opt, Val), -define(SET_LIST_XOPT(Opt, Val),
@ -4139,8 +4173,9 @@ features(Host, Node) when is_binary(Node) ->
tree_call({_User, Server, _Resource}, Function, Args) -> tree_call({_User, Server, _Resource}, Function, Args) ->
tree_call(Server, Function, Args); tree_call(Server, Function, Args);
tree_call(Host, Function, Args) -> tree_call(Host, Function, Args) ->
?DEBUG("tree_call ~p ~p ~p", [Host, Function, Args]), Tree = tree(Host),
catch apply(tree(Host), Function, Args). ?DEBUG("tree_call apply(~s, ~s, ~p) @ ~s", [Tree, Function, Args, Host]),
catch apply(Tree, Function, Args).
tree_action(Host, Function, Args) -> tree_action(Host, Function, Args) ->
?DEBUG("tree_action ~p ~p ~p", [Host, Function, Args]), ?DEBUG("tree_action ~p ~p ~p", [Host, Function, Args]),
@ -4267,6 +4302,13 @@ extended_error(#xmlel{name = Error, attrs = Attrs, children = SubEls}, Ext, ExtA
#xmlel{name = Error, attrs = Attrs, #xmlel{name = Error, attrs = Attrs,
children = lists:reverse([#xmlel{name = Ext, attrs = ExtAttrs} | SubEls])}. children = lists:reverse([#xmlel{name = Ext, attrs = ExtAttrs} | SubEls])}.
is_item_not_found({error, ErrEl}) ->
case fxml:get_subtag_with_xmlns(
ErrEl, <<"item-not-found">>, ?NS_STANZAS) of
#xmlel{} -> true;
_ -> false
end.
string_to_ljid(JID) -> string_to_ljid(JID) ->
case jid:from_string(JID) of case jid:from_string(JID) of
error -> error ->

View File

@ -151,21 +151,28 @@ process_iq(From, To,
%% modules. lists:foreach can %% modules. lists:foreach can
%% only return ok: %% only return ok:
not_allowed -> not_allowed ->
Txt = <<"Removal is not allowed">>,
IQ#iq{type = error, IQ#iq{type = error,
sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; sub_el = [SubEl,
?ERRT_NOT_ALLOWED(Lang, Txt)]};
not_exists -> not_exists ->
Txt = <<"No such user">>,
IQ#iq{type = error, IQ#iq{type = error,
sub_el = sub_el =
[SubEl, ?ERR_ITEM_NOT_FOUND]}; [SubEl,
_ -> ?ERRT_ITEM_NOT_FOUND(Lang, Txt)]};
Err ->
?ERROR_MSG("failed to remove user ~s@~s: ~p",
[User, Server, Err]),
IQ#iq{type = error, IQ#iq{type = error,
sub_el = sub_el =
[SubEl, [SubEl,
?ERR_INTERNAL_SERVER_ERROR]} ?ERR_INTERNAL_SERVER_ERROR]}
end; end;
true -> true ->
Txt = <<"No password in this query">>,
IQ#iq{type = error, IQ#iq{type = error,
sub_el = [SubEl, ?ERR_BAD_REQUEST]} sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]}
end end
end; end;
(UTag == false) and (RTag /= false) and AllowRemove -> (UTag == false) and (RTag /= false) and AllowRemove ->
@ -182,7 +189,9 @@ process_iq(From, To,
ejabberd_auth:remove_user(User, Server), ejabberd_auth:remove_user(User, Server),
ignore; ignore;
_ -> _ ->
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]} Txt = <<"The query is only allowed from local users">>,
IQ#iq{type = error,
sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]}
end; end;
(UTag /= false) and (PTag /= false) -> (UTag /= false) and (PTag /= false) ->
User = fxml:get_tag_cdata(UTag), User = fxml:get_tag_cdata(UTag),
@ -200,11 +209,14 @@ process_iq(From, To,
SubEl, Source, Lang, SubEl, Source, Lang,
true); true);
_ -> _ ->
Txt = <<"Incorrect data form">>,
IQ#iq{type = error, IQ#iq{type = error,
sub_el = [SubEl, ?ERR_BAD_REQUEST]} sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]}
end; end;
{error, malformed} -> {error, malformed} ->
IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]}; Txt = <<"Incorrect CAPTCHA submit">>,
IQ#iq{type = error,
sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]};
_ -> _ ->
ErrText = <<"The CAPTCHA verification has failed">>, ErrText = <<"The CAPTCHA verification has failed">>,
IQ#iq{type = error, IQ#iq{type = error,
@ -344,7 +356,8 @@ try_register_or_set_password(User, Server, Password,
IQ#iq{type = error, sub_el = [SubEl, Error]} IQ#iq{type = error, sub_el = [SubEl, Error]}
end; end;
deny -> deny ->
IQ#iq{type = error, sub_el = [SubEl, ?ERR_FORBIDDEN]} Txt = <<"Denied by ACL">>,
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_FORBIDDEN(Lang, Txt)]}
end; end;
_ -> _ ->
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]} IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}
@ -359,13 +372,17 @@ try_set_password(User, Server, Password, IQ, SubEl,
of of
ok -> IQ#iq{type = result, sub_el = []}; ok -> IQ#iq{type = result, sub_el = []};
{error, empty_password} -> {error, empty_password} ->
IQ#iq{type = error, sub_el = [SubEl, ?ERR_BAD_REQUEST]}; Txt = <<"Empty password">>,
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]};
{error, not_allowed} -> {error, not_allowed} ->
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]}; Txt = <<"Chaning password is not allowed">>,
IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
{error, invalid_jid} -> {error, invalid_jid} ->
IQ#iq{type = error, IQ#iq{type = error,
sub_el = [SubEl, ?ERR_ITEM_NOT_FOUND]}; sub_el = [SubEl, ?ERR_JID_MALFORMED]};
_ -> Err ->
?ERROR_MSG("failed to register user ~s@~s: ~p",
[User, Server, Err]),
IQ#iq{type = error, IQ#iq{type = error,
sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]} sub_el = [SubEl, ?ERR_INTERNAL_SERVER_ERROR]}
end; end;
@ -377,7 +394,7 @@ try_set_password(User, Server, Password, IQ, SubEl,
try_register(User, Server, Password, SourceRaw, Lang) -> try_register(User, Server, Password, SourceRaw, Lang) ->
case jid:is_nodename(User) of case jid:is_nodename(User) of
false -> {error, ?ERR_BAD_REQUEST}; false -> {error, ?ERRT_BAD_REQUEST(Lang, <<"Malformed username">>)};
_ -> _ ->
JID = jid:make(User, Server, <<"">>), JID = jid:make(User, Server, <<"">>),
Access = gen_mod:get_module_opt(Server, ?MODULE, access, Access = gen_mod:get_module_opt(Server, ?MODULE, access,
@ -387,8 +404,8 @@ try_register(User, Server, Password, SourceRaw, Lang) ->
case {acl:match_rule(Server, Access, JID), case {acl:match_rule(Server, Access, JID),
check_ip_access(SourceRaw, IPAccess)} check_ip_access(SourceRaw, IPAccess)}
of of
{deny, _} -> {error, ?ERR_FORBIDDEN}; {deny, _} -> {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
{_, deny} -> {error, ?ERR_FORBIDDEN}; {_, deny} -> {error, ?ERRT_FORBIDDEN(Lang, <<"Denied by ACL">>)};
{allow, allow} -> {allow, allow} ->
Source = may_remove_resource(SourceRaw), Source = may_remove_resource(SourceRaw),
case check_timeout(Source) of case check_timeout(Source) of
@ -406,14 +423,20 @@ try_register(User, Server, Password, SourceRaw, Lang) ->
Error -> Error ->
remove_timeout(Source), remove_timeout(Source),
case Error of case Error of
{atomic, exists} -> {error, ?ERR_CONFLICT}; {atomic, exists} ->
Txt = <<"User already exists">>,
{error, ?ERRT_CONFLICT(Lang, Txt)};
{error, invalid_jid} -> {error, invalid_jid} ->
{error, ?ERR_JID_MALFORMED}; {error, ?ERR_JID_MALFORMED};
{error, not_allowed} -> {error, not_allowed} ->
{error, ?ERR_NOT_ALLOWED}; {error, ?ERR_NOT_ALLOWED};
{error, too_many_users} -> {error, too_many_users} ->
{error, ?ERR_NOT_ALLOWED}; Txt = <<"Too many users registered">>,
{error, _Reason} -> {error, ?ERRT_RESOURCE_CONSTRAINT(Lang, Txt)};
{error, _} ->
?ERROR_MSG("failed to register user "
"~s@~s: ~p",
[User, Server, Error]),
{error, ?ERR_INTERNAL_SERVER_ERROR} {error, ?ERR_INTERNAL_SERVER_ERROR}
end end
end; end;

View File

@ -800,8 +800,10 @@ get_item(Nidx, ItemId) ->
{selected, {selected,
[<<"itemid">>, <<"publisher">>, <<"creation">>, <<"modification">>, <<"payload">>], [RItem]} -> [<<"itemid">>, <<"publisher">>, <<"creation">>, <<"modification">>, <<"payload">>], [RItem]} ->
{result, raw_to_item(Nidx, RItem)}; {result, raw_to_item(Nidx, RItem)};
_ -> {selected, _, []} ->
{error, ?ERR_ITEM_NOT_FOUND} {error, ?ERR_ITEM_NOT_FOUND};
{'EXIT', _} ->
{error, ?ERRT_INTERNAL_SERVER_ERROR(?MYLANG, <<"Database failure">>)}
end. end.
get_item(Nidx, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) -> get_item(Nidx, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) ->