2003-01-19 21:17:56 +01:00
|
|
|
%%%----------------------------------------------------------------------
|
|
|
|
%%% File : mod_configure.erl
|
|
|
|
%%% Author : Alexey Shchepin <alexey@sevcom.net>
|
2003-02-23 21:13:39 +01:00
|
|
|
%%% Purpose : Support for online configuration of ejabberd
|
2003-01-19 21:17:56 +01:00
|
|
|
%%% Created : 19 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
|
|
|
|
%%% Id : $Id$
|
|
|
|
%%%----------------------------------------------------------------------
|
|
|
|
|
|
|
|
-module(mod_configure).
|
|
|
|
-author('alexey@sevcom.net').
|
|
|
|
-vsn('$Revision$ ').
|
|
|
|
|
2003-01-24 21:18:33 +01:00
|
|
|
-behaviour(gen_mod).
|
|
|
|
|
2005-06-20 05:18:13 +02:00
|
|
|
-export([start/2,
|
|
|
|
stop/1,
|
2005-09-04 03:58:47 +02:00
|
|
|
get_local_identity/5,
|
|
|
|
get_local_features/5,
|
|
|
|
get_local_items/5,
|
|
|
|
get_sm_features/5,
|
|
|
|
get_sm_items/5,
|
2003-01-21 21:36:55 +01:00
|
|
|
process_local_iq/3,
|
|
|
|
process_sm_iq/3]).
|
2003-01-19 21:17:56 +01:00
|
|
|
|
|
|
|
-include("ejabberd.hrl").
|
2003-03-09 21:46:47 +01:00
|
|
|
-include("jlib.hrl").
|
2003-01-19 21:17:56 +01:00
|
|
|
|
|
|
|
|
2005-06-20 05:18:13 +02:00
|
|
|
start(Host, Opts) ->
|
2003-01-24 21:18:33 +01:00
|
|
|
IQDisc = gen_mod:get_opt(iqdisc, Opts, one_queue),
|
2005-06-20 05:18:13 +02:00
|
|
|
gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_EJABBERD_CONFIG,
|
2003-01-24 21:18:33 +01:00
|
|
|
?MODULE, process_local_iq, IQDisc),
|
2005-06-20 05:18:13 +02:00
|
|
|
gen_iq_handler:add_iq_handler(ejabberd_sm, Host, ?NS_EJABBERD_CONFIG,
|
2003-01-24 21:18:33 +01:00
|
|
|
?MODULE, process_sm_iq, IQDisc),
|
2005-09-04 03:58:47 +02:00
|
|
|
ejabberd_hooks:add(disco_local_items, Host, ?MODULE, get_local_items, 50),
|
|
|
|
ejabberd_hooks:add(disco_local_features, Host, ?MODULE, get_local_features, 50),
|
|
|
|
ejabberd_hooks:add(disco_local_identity, Host, ?MODULE, get_local_identity, 50),
|
|
|
|
ejabberd_hooks:add(disco_sm_items, Host, ?MODULE, get_sm_items, 50),
|
|
|
|
ejabberd_hooks:add(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
|
2003-01-21 21:36:55 +01:00
|
|
|
ok.
|
2003-01-19 21:17:56 +01:00
|
|
|
|
2005-06-20 05:18:13 +02:00
|
|
|
stop(Host) ->
|
2005-09-04 03:58:47 +02:00
|
|
|
ejabberd_hooks:delete(disco_sm_features, Host, ?MODULE, get_sm_features, 50),
|
|
|
|
ejabberd_hooks:delete(disco_sm_items, Host, ?MODULE, get_sm_items, 50),
|
|
|
|
ejabberd_hooks:delete(disco_local_identity, Host, ?MODULE, get_local_identity, 50),
|
|
|
|
ejabberd_hooks:delete(disco_local_features, Host, ?MODULE, get_local_features, 50),
|
|
|
|
ejabberd_hooks:delete(disco_local_items, Host, ?MODULE, get_local_items, 50),
|
2005-06-20 05:18:13 +02:00
|
|
|
gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_EJABBERD_CONFIG),
|
|
|
|
gen_iq_handler:remove_iq_handler(ejabberd_sm, Host, ?NS_EJABBERD_CONFIG).
|
2003-01-29 18:12:23 +01:00
|
|
|
|
2003-01-19 21:17:56 +01:00
|
|
|
|
2005-09-04 03:58:47 +02:00
|
|
|
-define(EMPTY_INFO_RESULT, {result, Feats}).
|
|
|
|
|
|
|
|
get_sm_features({error, _Error} = Acc, _From, _To, _Node, _Lang) ->
|
|
|
|
Acc;
|
|
|
|
|
|
|
|
get_sm_features(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
|
|
|
|
case {acl:match_rule(LServer, configure, From), Node} of
|
|
|
|
{allow, []} ->
|
|
|
|
case Acc of
|
|
|
|
{result, Features} ->
|
|
|
|
{result, [?NS_EJABBERD_CONFIG | Features]};
|
|
|
|
empty ->
|
|
|
|
{result, [?NS_EJABBERD_CONFIG]}
|
|
|
|
end;
|
|
|
|
_ ->
|
|
|
|
Acc
|
|
|
|
end.
|
|
|
|
|
|
|
|
get_local_identity(Acc, _From, _To, Node, _Lang) ->
|
|
|
|
case Node of
|
|
|
|
["running nodes", ENode] ->
|
|
|
|
[{xmlelement, "identity",
|
|
|
|
[{"category", "ejabberd"},
|
|
|
|
{"type", "node"},
|
|
|
|
{"name", ENode}], []}];
|
|
|
|
_ ->
|
|
|
|
Acc
|
|
|
|
end.
|
|
|
|
|
|
|
|
get_local_features({error, _Error} = Acc, _From, _To, _Node, _Lang) ->
|
|
|
|
Acc;
|
|
|
|
|
|
|
|
get_local_features(Acc, _From, _To, [], _Lang) ->
|
|
|
|
Acc;
|
|
|
|
|
|
|
|
get_local_features(Acc, From, #jid{lserver = LServer} = _To, Node, _Lang) ->
|
|
|
|
Feats = case Acc of
|
|
|
|
{result, Features} -> Features;
|
|
|
|
empty -> []
|
|
|
|
end,
|
|
|
|
case {acl:match_rule(LServer, configure, From), Node} of
|
|
|
|
{deny, _} ->
|
|
|
|
{error, ?ERR_NOT_ALLOWED};
|
|
|
|
{allow, ["config"]} ->
|
|
|
|
?EMPTY_INFO_RESULT;
|
|
|
|
{allow, ["online users"]} ->
|
|
|
|
?EMPTY_INFO_RESULT;
|
|
|
|
{allow, ["all users"]} ->
|
|
|
|
?EMPTY_INFO_RESULT;
|
|
|
|
{allow, ["all users", [$@ | _]]} ->
|
|
|
|
?EMPTY_INFO_RESULT;
|
|
|
|
{allow, ["outgoing s2s" | _]} ->
|
|
|
|
?EMPTY_INFO_RESULT;
|
|
|
|
{allow, ["running nodes"]} ->
|
|
|
|
?EMPTY_INFO_RESULT;
|
|
|
|
{allow, ["stopped nodes"]} ->
|
|
|
|
?EMPTY_INFO_RESULT;
|
|
|
|
{allow, ["running nodes", _ENode]} ->
|
|
|
|
{result, [?NS_STATS | Feats]};
|
|
|
|
{allow, ["running nodes", _ENode, "DB"]} ->
|
|
|
|
{result, [?NS_EJABBERD_CONFIG | Feats]};
|
|
|
|
{allow, ["running nodes", _ENode, "modules"]} ->
|
|
|
|
?EMPTY_INFO_RESULT;
|
|
|
|
{allow, ["running nodes", _ENode, "modules", _]} ->
|
|
|
|
{result, [?NS_EJABBERD_CONFIG | Feats]};
|
|
|
|
{allow, ["running nodes", _ENode, "backup"]} ->
|
|
|
|
?EMPTY_INFO_RESULT;
|
|
|
|
{allow, ["running nodes", _ENode, "backup", _]} ->
|
|
|
|
{result, [?NS_EJABBERD_CONFIG | Feats]};
|
|
|
|
{allow, ["running nodes", _ENode, "import"]} ->
|
|
|
|
?EMPTY_INFO_RESULT;
|
|
|
|
{allow, ["running nodes", _ENode, "import", _]} ->
|
|
|
|
{result, [?NS_EJABBERD_CONFIG | Feats]};
|
|
|
|
{allow, ["config", _]} ->
|
|
|
|
{result, [?NS_EJABBERD_CONFIG | Feats]};
|
|
|
|
_ ->
|
|
|
|
Acc
|
|
|
|
end.
|
|
|
|
|
|
|
|
get_sm_items({error, _Error} = Acc, _From, _To, _Node, _Lang) ->
|
|
|
|
Acc;
|
|
|
|
|
|
|
|
get_sm_items(Acc, From,
|
|
|
|
#jid{user = User, server = Server, lserver = LServer} = _To,
|
|
|
|
Node, _Lang) ->
|
|
|
|
case {acl:match_rule(LServer, configure, From), Node} of
|
|
|
|
{allow, []} ->
|
|
|
|
Items = case Acc of
|
|
|
|
{result, Its} ->
|
|
|
|
Its;
|
|
|
|
empty ->
|
|
|
|
[]
|
|
|
|
end,
|
|
|
|
{result, Items ++ get_user_resources(User, Server)};
|
|
|
|
_ ->
|
|
|
|
Acc
|
|
|
|
end.
|
|
|
|
|
|
|
|
get_user_resources(User, Server) ->
|
|
|
|
Rs = ejabberd_sm:get_user_resources(User, Server),
|
|
|
|
lists:map(fun(R) ->
|
|
|
|
{xmlelement, "item",
|
|
|
|
[{"jid", User ++ "@" ++ Server ++ "/" ++ R},
|
|
|
|
{"name", User}], []}
|
|
|
|
end, lists:sort(Rs)).
|
|
|
|
|
|
|
|
get_local_items({error, _Error} = Acc, _From, _To, _Node, _Lang) ->
|
|
|
|
Acc;
|
|
|
|
|
|
|
|
get_local_items(Acc, From, #jid{lserver = LServer} = To, Node, Lang) ->
|
|
|
|
Items = case Acc of
|
|
|
|
{result, Its} ->
|
|
|
|
Its;
|
|
|
|
empty ->
|
|
|
|
[]
|
|
|
|
end,
|
|
|
|
case acl:match_rule(LServer, configure, From) of
|
|
|
|
deny when Node /= [] ->
|
|
|
|
{error, ?ERR_NOT_ALLOWED};
|
|
|
|
deny ->
|
|
|
|
{result, Items};
|
|
|
|
_ ->
|
|
|
|
case get_local_items(To#jid.lserver, Node,
|
|
|
|
jlib:jid_to_string(To), Lang) of
|
|
|
|
{result, Res} ->
|
|
|
|
{result, Items ++ Res};
|
|
|
|
{error, Error} ->
|
|
|
|
{error, Error}
|
|
|
|
end
|
|
|
|
end.
|
|
|
|
|
|
|
|
-define(NODE(Name, Node),
|
|
|
|
{xmlelement, "item",
|
|
|
|
[{"jid", Server},
|
|
|
|
{"name", translate:translate(Lang, Name)},
|
|
|
|
{"node", Node}], []}).
|
|
|
|
|
|
|
|
get_local_items(_Host, [], Server, Lang) ->
|
|
|
|
{result,
|
|
|
|
[?NODE("Configuration", "config"),
|
|
|
|
?NODE("Online Users", "online users"),
|
|
|
|
?NODE("All Users", "all users"),
|
|
|
|
?NODE("Outgoing S2S connections", "outgoing s2s"),
|
|
|
|
?NODE("Running Nodes", "running nodes"),
|
|
|
|
?NODE("Stopped Nodes", "stopped nodes")
|
|
|
|
]};
|
|
|
|
|
|
|
|
get_local_items(_Host, ["config"], Server, Lang) ->
|
|
|
|
{result,
|
|
|
|
[?NODE("Host Name", "config/hostname"),
|
|
|
|
?NODE("Access Control Lists", "config/acls"),
|
|
|
|
?NODE("Access Rules", "config/access")
|
|
|
|
% Too expensive on big hosts
|
|
|
|
%?NODE("Remove Users", "config/remusers")
|
|
|
|
]};
|
|
|
|
|
|
|
|
get_local_items(_Host, ["config", _], _Server, _Lang) ->
|
|
|
|
{result, []};
|
|
|
|
|
|
|
|
get_local_items(Host, ["online users"], _Server, _Lang) ->
|
|
|
|
{result, get_online_vh_users(Host)};
|
|
|
|
|
|
|
|
get_local_items(Host, ["all users"], _Server, _Lang) ->
|
|
|
|
{result, get_all_vh_users(Host)};
|
|
|
|
|
|
|
|
get_local_items(_Host, ["all users", [$@ | Diap]], _Server, _Lang) ->
|
|
|
|
case catch ejabberd_auth:dirty_get_registered_users() of
|
|
|
|
{'EXIT', _Reason} ->
|
|
|
|
?ERR_INTERNAL_SERVER_ERROR;
|
|
|
|
Users ->
|
|
|
|
SUsers = lists:sort([{S, U} || {U, S} <- Users]),
|
|
|
|
case catch begin
|
|
|
|
{ok, [S1, S2]} = regexp:split(Diap, "-"),
|
|
|
|
N1 = list_to_integer(S1),
|
|
|
|
N2 = list_to_integer(S2),
|
|
|
|
Sub = lists:sublist(SUsers, N1, N2 - N1 + 1),
|
|
|
|
lists:map(fun({S, U}) ->
|
|
|
|
{xmlelement, "item",
|
|
|
|
[{"jid", U ++ "@" ++ S},
|
|
|
|
{"name", U ++ "@" ++ S}], []}
|
|
|
|
end, Sub)
|
|
|
|
end of
|
|
|
|
{'EXIT', _Reason} ->
|
|
|
|
?ERR_NOT_ACCEPTABLE;
|
|
|
|
Res ->
|
|
|
|
{result, Res}
|
|
|
|
end
|
|
|
|
end;
|
|
|
|
|
|
|
|
get_local_items(Host, ["outgoing s2s"], _Server, Lang) ->
|
|
|
|
{result, get_outgoing_s2s(Host, Lang)};
|
|
|
|
|
|
|
|
get_local_items(Host, ["outgoing s2s", To], _Server, Lang) ->
|
|
|
|
{result, get_outgoing_s2s(Host, Lang, To)};
|
|
|
|
|
|
|
|
get_local_items(_Host, ["running nodes"], _Server, Lang) ->
|
|
|
|
{result, get_running_nodes(Lang)};
|
|
|
|
|
|
|
|
get_local_items(_Host, ["stopped nodes"], _Server, Lang) ->
|
|
|
|
{result, get_stopped_nodes(Lang)};
|
|
|
|
|
|
|
|
get_local_items(_Host, ["running nodes", ENode], Server, Lang) ->
|
|
|
|
{result,
|
|
|
|
[?NODE("DB", "running nodes/" ++ ENode ++ "/DB"),
|
|
|
|
?NODE("Modules", "running nodes/" ++ ENode ++ "/modules"),
|
|
|
|
?NODE("Backup Management", "running nodes/" ++ ENode ++ "/backup"),
|
|
|
|
?NODE("Import users from jabberd1.4 spool files",
|
|
|
|
"running nodes/" ++ ENode ++ "/import")
|
|
|
|
]};
|
|
|
|
|
|
|
|
get_local_items(_Host, ["running nodes", _ENode, "DB"], _Server, _Lang) ->
|
|
|
|
{result, []};
|
|
|
|
|
|
|
|
get_local_items(_Host, ["running nodes", ENode, "modules"], Server, Lang) ->
|
|
|
|
{result,
|
|
|
|
[?NODE("Start Modules", "running nodes/" ++ ENode ++ "/modules/start"),
|
|
|
|
?NODE("Stop Modules", "running nodes/" ++ ENode ++ "/modules/stop")
|
|
|
|
]};
|
|
|
|
|
|
|
|
get_local_items(_Host, ["running nodes", _ENode, "modules", _], _Server, _Lang) ->
|
|
|
|
{result, []};
|
|
|
|
|
|
|
|
get_local_items(_Host, ["running nodes", ENode, "backup"], Server, Lang) ->
|
|
|
|
{result,
|
|
|
|
[?NODE("Backup", "running nodes/" ++ ENode ++ "/backup/backup"),
|
|
|
|
?NODE("Restore", "running nodes/" ++ ENode ++ "/backup/restore"),
|
|
|
|
?NODE("Dump to Text File",
|
|
|
|
"running nodes/" ++ ENode ++ "/backup/textfile")
|
|
|
|
]};
|
|
|
|
|
|
|
|
get_local_items(_Host, ["running nodes", _ENode, "backup", _], _Server, _Lang) ->
|
|
|
|
{result, []};
|
|
|
|
|
|
|
|
get_local_items(_Host, ["running nodes", ENode, "import"], Server, Lang) ->
|
|
|
|
{result,
|
|
|
|
[?NODE("Import File", "running nodes/" ++ ENode ++ "/import/file"),
|
|
|
|
?NODE("Import Directory", "running nodes/" ++ ENode ++ "/import/dir")
|
|
|
|
]};
|
|
|
|
|
|
|
|
get_local_items(_Host, ["running nodes", _ENode, "import", _], _Server, _Lang) ->
|
|
|
|
{result, []};
|
|
|
|
|
|
|
|
get_local_items(_Host, _, _Server, _Lang) ->
|
|
|
|
{error, ?ERR_ITEM_NOT_FOUND}.
|
|
|
|
|
|
|
|
|
|
|
|
get_online_vh_users(Host) ->
|
|
|
|
case catch ejabberd_sm:get_vh_session_list(Host) of
|
|
|
|
{'EXIT', _Reason} ->
|
|
|
|
[];
|
|
|
|
USRs ->
|
|
|
|
SURs = lists:sort([{S, U, R} || {U, S, R} <- USRs]),
|
|
|
|
lists:map(fun({S, U, R}) ->
|
|
|
|
{xmlelement, "item",
|
|
|
|
[{"jid", U ++ "@" ++ S ++ "/" ++ R},
|
|
|
|
{"name", U ++ "@" ++ S}], []}
|
|
|
|
end, SURs)
|
|
|
|
end.
|
|
|
|
|
|
|
|
get_all_vh_users(Host) ->
|
|
|
|
case catch ejabberd_auth:get_vh_registered_users(Host) of
|
|
|
|
{'EXIT', _Reason} ->
|
|
|
|
[];
|
|
|
|
Users ->
|
|
|
|
SUsers = lists:sort([{S, U} || {U, S} <- Users]),
|
|
|
|
case length(SUsers) of
|
|
|
|
N when N =< 100 ->
|
|
|
|
lists:map(fun({S, U}) ->
|
|
|
|
{xmlelement, "item",
|
|
|
|
[{"jid", U ++ "@" ++ S},
|
|
|
|
{"name", U ++ "@" ++ S}], []}
|
|
|
|
end, SUsers);
|
|
|
|
N ->
|
|
|
|
NParts = trunc(math:sqrt(N * 0.618)) + 1,
|
|
|
|
M = trunc(N / NParts) + 1,
|
|
|
|
lists:map(fun(K) ->
|
|
|
|
L = K + M - 1,
|
|
|
|
Node =
|
|
|
|
"@" ++ integer_to_list(K) ++
|
|
|
|
"-" ++ integer_to_list(L),
|
|
|
|
{FS, FU} = lists:nth(K, SUsers),
|
|
|
|
{LS, LU} =
|
|
|
|
if L < N -> lists:nth(L, SUsers);
|
|
|
|
true -> lists:last(SUsers)
|
|
|
|
end,
|
|
|
|
Name =
|
|
|
|
FU ++ "@" ++ FS ++
|
|
|
|
" -- " ++
|
|
|
|
LU ++ "@" ++ LS,
|
|
|
|
{xmlelement, "item",
|
|
|
|
[{"jid", Host},
|
|
|
|
{"node", "all users/" ++ Node},
|
|
|
|
{"name", Name}], []}
|
|
|
|
end, lists:seq(1, N, M))
|
|
|
|
end
|
|
|
|
end.
|
|
|
|
|
|
|
|
get_outgoing_s2s(Host, Lang) ->
|
|
|
|
case catch ejabberd_s2s:dirty_get_connections() of
|
|
|
|
{'EXIT', _Reason} ->
|
|
|
|
[];
|
|
|
|
Connections ->
|
|
|
|
DotHost = "." ++ Host,
|
|
|
|
TConns = [TH || {FH, TH} <- Connections,
|
|
|
|
Host == FH orelse lists:suffix(DotHost, FH)],
|
|
|
|
lists:map(
|
|
|
|
fun(T) ->
|
|
|
|
{xmlelement, "item",
|
|
|
|
[{"jid", Host},
|
|
|
|
{"node", "outgoing s2s/" ++ T},
|
|
|
|
{"name",
|
|
|
|
lists:flatten(
|
|
|
|
io_lib:format(
|
|
|
|
translate:translate(Lang, "To ~s"), [T]))}],
|
|
|
|
[]}
|
|
|
|
end, lists:usort(TConns))
|
|
|
|
end.
|
|
|
|
|
|
|
|
get_outgoing_s2s(Host, Lang, To) ->
|
|
|
|
case catch ejabberd_s2s:dirty_get_connections() of
|
|
|
|
{'EXIT', _Reason} ->
|
|
|
|
[];
|
|
|
|
Connections ->
|
|
|
|
lists:map(
|
|
|
|
fun({F, _T}) ->
|
|
|
|
{xmlelement, "item",
|
|
|
|
[{"jid", Host},
|
|
|
|
{"node", "outgoing s2s/" ++ To ++ "/" ++ F},
|
|
|
|
{"name",
|
|
|
|
lists:flatten(
|
|
|
|
io_lib:format(
|
|
|
|
translate:translate(Lang, "From ~s"), [F]))}],
|
|
|
|
[]}
|
|
|
|
end, lists:keysort(1, lists:filter(fun(E) ->
|
|
|
|
element(2, E) == To
|
|
|
|
end, Connections)))
|
|
|
|
end.
|
|
|
|
|
|
|
|
|
|
|
|
get_running_nodes(_Lang) ->
|
|
|
|
case catch mnesia:system_info(running_db_nodes) of
|
|
|
|
{'EXIT', _Reason} ->
|
|
|
|
[];
|
|
|
|
DBNodes ->
|
|
|
|
lists:map(
|
|
|
|
fun(N) ->
|
|
|
|
S = atom_to_list(N),
|
|
|
|
{xmlelement, "item",
|
|
|
|
[{"jid", ?MYNAME},
|
|
|
|
{"node", "running nodes/" ++ S},
|
|
|
|
{"name", S}],
|
|
|
|
[]}
|
|
|
|
end, lists:sort(DBNodes))
|
|
|
|
end.
|
|
|
|
|
|
|
|
get_stopped_nodes(_Lang) ->
|
|
|
|
case catch (lists:usort(mnesia:system_info(db_nodes) ++
|
|
|
|
mnesia:system_info(extra_db_nodes)) --
|
|
|
|
mnesia:system_info(running_db_nodes)) of
|
|
|
|
{'EXIT', _Reason} ->
|
|
|
|
[];
|
|
|
|
DBNodes ->
|
|
|
|
lists:map(
|
|
|
|
fun(N) ->
|
|
|
|
S = atom_to_list(N),
|
|
|
|
{xmlelement, "item",
|
|
|
|
[{"jid", ?MYNAME},
|
|
|
|
{"node", "stopped nodes/" ++ S},
|
|
|
|
{"name", S}],
|
|
|
|
[]}
|
|
|
|
end, lists:sort(DBNodes))
|
|
|
|
end.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
process_local_iq(From, To, #iq{type = Type, xmlns = XMLNS,
|
2004-02-26 23:00:04 +01:00
|
|
|
lang = Lang, sub_el = SubEl} = IQ) ->
|
2005-06-20 05:18:13 +02:00
|
|
|
case acl:match_rule(To#jid.lserver, configure, From) of
|
2003-01-19 21:17:56 +01:00
|
|
|
deny ->
|
2003-12-17 21:13:21 +01:00
|
|
|
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
2003-01-19 21:17:56 +01:00
|
|
|
allow ->
|
|
|
|
case Type of
|
|
|
|
set ->
|
2004-02-15 21:10:40 +01:00
|
|
|
XDataEl = find_xdata_el(SubEl),
|
|
|
|
case XDataEl of
|
|
|
|
false ->
|
|
|
|
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ACCEPTABLE]};
|
2005-09-04 03:58:47 +02:00
|
|
|
{xmlelement, _Name, Attrs, _SubEls} ->
|
2004-02-15 21:10:40 +01:00
|
|
|
case xml:get_attr_s("type", Attrs) of
|
|
|
|
"cancel" ->
|
|
|
|
IQ#iq{type = result,
|
|
|
|
sub_el = [{xmlelement, "query",
|
|
|
|
[{"xmlns", XMLNS}], []}]};
|
|
|
|
"submit" ->
|
|
|
|
XData = jlib:parse_xdata_submit(XDataEl),
|
|
|
|
case XData of
|
|
|
|
invalid ->
|
2003-12-17 21:13:21 +01:00
|
|
|
IQ#iq{type = error,
|
2004-02-15 21:10:40 +01:00
|
|
|
sub_el = [SubEl, ?ERR_BAD_REQUEST]};
|
|
|
|
_ ->
|
|
|
|
Node =
|
|
|
|
string:tokens(
|
|
|
|
xml:get_tag_attr_s("node", SubEl),
|
|
|
|
"/"),
|
|
|
|
case set_form(Node, Lang, XData) of
|
|
|
|
{result, Res} ->
|
|
|
|
IQ#iq{type = result,
|
|
|
|
sub_el =
|
|
|
|
[{xmlelement, "query",
|
|
|
|
[{"xmlns", XMLNS}],
|
|
|
|
Res
|
|
|
|
}]};
|
|
|
|
{error, Error} ->
|
|
|
|
IQ#iq{type = error,
|
|
|
|
sub_el = [SubEl, Error]}
|
|
|
|
end
|
|
|
|
end;
|
|
|
|
_ ->
|
|
|
|
IQ#iq{type = error,
|
|
|
|
sub_el = [SubEl, ?ERR_BAD_REQUEST]}
|
|
|
|
end
|
2003-01-19 21:17:56 +01:00
|
|
|
end;
|
|
|
|
get ->
|
|
|
|
Node =
|
|
|
|
string:tokens(xml:get_tag_attr_s("node", SubEl), "/"),
|
|
|
|
case get_form(Node, Lang) of
|
|
|
|
{result, Res} ->
|
2003-12-17 21:13:21 +01:00
|
|
|
IQ#iq{type = result,
|
|
|
|
sub_el =
|
|
|
|
[{xmlelement, "query", [{"xmlns", XMLNS}],
|
|
|
|
Res
|
|
|
|
}]};
|
2003-03-09 21:46:47 +01:00
|
|
|
{error, Error} ->
|
2003-12-17 21:13:21 +01:00
|
|
|
IQ#iq{type = error,
|
|
|
|
sub_el = [SubEl, Error]}
|
2003-01-19 21:17:56 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end.
|
|
|
|
|
|
|
|
-define(TLFIELD(Type, Label, Var),
|
|
|
|
{xmlelement, "field", [{"type", Type},
|
|
|
|
{"label", translate:translate(Lang, Label)},
|
|
|
|
{"var", Var}], []}).
|
|
|
|
|
2003-01-21 21:36:55 +01:00
|
|
|
-define(XFIELD(Type, Label, Var, Val),
|
|
|
|
{xmlelement, "field", [{"type", Type},
|
|
|
|
{"label", translate:translate(Lang, Label)},
|
|
|
|
{"var", Var}],
|
|
|
|
[{xmlelement, "value", [], [{xmlcdata, Val}]}]}).
|
|
|
|
|
2003-01-19 21:17:56 +01:00
|
|
|
-define(TABLEFIELD(Table, Val),
|
|
|
|
{xmlelement, "field", [{"type", "list-single"},
|
|
|
|
{"label", atom_to_list(Table)},
|
|
|
|
{"var", atom_to_list(Table)}],
|
|
|
|
[{xmlelement, "value", [], [{xmlcdata, atom_to_list(Val)}]},
|
|
|
|
{xmlelement, "option", [{"label",
|
|
|
|
translate:translate(Lang, "RAM copy")}],
|
|
|
|
[{xmlelement, "value", [], [{xmlcdata, "ram_copies"}]}]},
|
|
|
|
{xmlelement, "option", [{"label",
|
|
|
|
translate:translate(Lang,
|
|
|
|
"RAM and disc copy")}],
|
|
|
|
[{xmlelement, "value", [], [{xmlcdata, "disc_copies"}]}]},
|
|
|
|
{xmlelement, "option", [{"label",
|
2003-01-21 21:36:55 +01:00
|
|
|
translate:translate(Lang,
|
|
|
|
"Disc only copy")}],
|
2003-01-19 21:17:56 +01:00
|
|
|
[{xmlelement, "value", [], [{xmlcdata, "disc_only_copies"}]}]},
|
|
|
|
{xmlelement, "option", [{"label",
|
|
|
|
translate:translate(Lang, "Remote copy")}],
|
|
|
|
[{xmlelement, "value", [], [{xmlcdata, "unknown"}]}]}
|
|
|
|
]}).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get_form(["running nodes", ENode, "DB"], Lang) ->
|
|
|
|
case search_running_node(ENode) of
|
|
|
|
false ->
|
2003-10-16 20:17:44 +02:00
|
|
|
{error, ?ERR_ITEM_NOT_FOUND};
|
2003-01-19 21:17:56 +01:00
|
|
|
Node ->
|
|
|
|
case rpc:call(Node, mnesia, system_info, [tables]) of
|
2003-12-17 21:13:21 +01:00
|
|
|
{badrpc, _Reason} ->
|
2003-03-09 21:46:47 +01:00
|
|
|
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
2003-01-19 21:17:56 +01:00
|
|
|
Tables ->
|
2003-01-21 21:36:55 +01:00
|
|
|
STables = lists:sort(Tables),
|
2004-02-15 21:10:40 +01:00
|
|
|
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
|
|
|
|
[{xmlelement, "title", [],
|
|
|
|
[{xmlcdata,
|
|
|
|
translate:translate(
|
2004-02-26 23:00:04 +01:00
|
|
|
Lang, "DB Tables Configuration at ") ++
|
|
|
|
ENode}]},
|
2004-02-15 21:10:40 +01:00
|
|
|
{xmlelement, "instructions", [],
|
|
|
|
[{xmlcdata,
|
|
|
|
translate:translate(
|
|
|
|
Lang, "Choose storage type of tables")}]} |
|
|
|
|
lists:map(
|
|
|
|
fun(Table) ->
|
|
|
|
case rpc:call(Node,
|
|
|
|
mnesia,
|
|
|
|
table_info,
|
|
|
|
[Table, storage_type]) of
|
|
|
|
{badrpc, _} ->
|
|
|
|
?TABLEFIELD(Table, unknown);
|
|
|
|
Type ->
|
|
|
|
?TABLEFIELD(Table, Type)
|
|
|
|
end
|
|
|
|
end, STables)
|
|
|
|
]}]}
|
2003-01-19 21:17:56 +01:00
|
|
|
end
|
|
|
|
end;
|
|
|
|
|
2003-01-28 20:45:13 +01:00
|
|
|
get_form(["running nodes", ENode, "modules", "stop"], Lang) ->
|
|
|
|
case search_running_node(ENode) of
|
|
|
|
false ->
|
2003-10-16 20:17:44 +02:00
|
|
|
{error, ?ERR_ITEM_NOT_FOUND};
|
2003-01-28 20:45:13 +01:00
|
|
|
Node ->
|
|
|
|
case rpc:call(Node, gen_mod, loaded_modules, []) of
|
2003-12-17 21:13:21 +01:00
|
|
|
{badrpc, _Reason} ->
|
2003-03-09 21:46:47 +01:00
|
|
|
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
2003-01-28 20:45:13 +01:00
|
|
|
Modules ->
|
|
|
|
SModules = lists:sort(Modules),
|
2004-02-15 21:10:40 +01:00
|
|
|
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
|
|
|
|
[{xmlelement, "title", [],
|
|
|
|
[{xmlcdata,
|
|
|
|
translate:translate(
|
2004-02-26 23:00:04 +01:00
|
|
|
Lang, "Stop Modules at ") ++ ENode}]},
|
2004-02-15 21:10:40 +01:00
|
|
|
{xmlelement, "instructions", [],
|
|
|
|
[{xmlcdata,
|
|
|
|
translate:translate(
|
|
|
|
Lang, "Choose modules to stop")}]} |
|
|
|
|
lists:map(fun(M) ->
|
|
|
|
S = atom_to_list(M),
|
|
|
|
?XFIELD("boolean", S, S, "0")
|
|
|
|
end, SModules)
|
|
|
|
]}]}
|
2003-01-28 20:45:13 +01:00
|
|
|
end
|
|
|
|
end;
|
|
|
|
|
|
|
|
get_form(["running nodes", ENode, "modules", "start"], Lang) ->
|
2004-02-15 21:10:40 +01:00
|
|
|
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
|
|
|
|
[{xmlelement, "title", [],
|
|
|
|
[{xmlcdata,
|
|
|
|
translate:translate(
|
2004-02-26 23:00:04 +01:00
|
|
|
Lang, "Start Modules at ") ++ ENode}]},
|
2004-02-15 21:10:40 +01:00
|
|
|
{xmlelement, "instructions", [],
|
|
|
|
[{xmlcdata,
|
|
|
|
translate:translate(
|
|
|
|
Lang, "Enter list of {Module, [Options]}")}]},
|
|
|
|
{xmlelement, "field", [{"type", "text-multi"},
|
|
|
|
{"label",
|
|
|
|
translate:translate(
|
|
|
|
Lang, "List of modules to start")},
|
|
|
|
{"var", "modules"}],
|
|
|
|
[{xmlelement, "value", [], [{xmlcdata, "[]."}]}]
|
|
|
|
}
|
|
|
|
]}]};
|
2003-01-28 20:45:13 +01:00
|
|
|
|
2003-02-22 20:11:00 +01:00
|
|
|
get_form(["running nodes", ENode, "backup", "backup"], Lang) ->
|
2004-02-15 21:10:40 +01:00
|
|
|
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
|
|
|
|
[{xmlelement, "title", [],
|
|
|
|
[{xmlcdata,
|
|
|
|
translate:translate(
|
2004-02-26 23:00:04 +01:00
|
|
|
Lang, "Backup to File at ") ++ ENode}]},
|
2004-02-15 21:10:40 +01:00
|
|
|
{xmlelement, "instructions", [],
|
|
|
|
[{xmlcdata,
|
|
|
|
translate:translate(
|
|
|
|
Lang, "Enter path to backup file")}]},
|
|
|
|
{xmlelement, "field", [{"type", "text-single"},
|
|
|
|
{"label",
|
|
|
|
translate:translate(
|
|
|
|
Lang, "Path to File")},
|
|
|
|
{"var", "path"}],
|
|
|
|
[{xmlelement, "value", [], [{xmlcdata, ""}]}]
|
|
|
|
}
|
|
|
|
]}]};
|
2003-02-22 20:11:00 +01:00
|
|
|
|
|
|
|
get_form(["running nodes", ENode, "backup", "restore"], Lang) ->
|
2004-02-15 21:10:40 +01:00
|
|
|
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
|
|
|
|
[{xmlelement, "title", [],
|
|
|
|
[{xmlcdata,
|
|
|
|
translate:translate(
|
2004-02-26 23:00:04 +01:00
|
|
|
Lang, "Restore Backup from File at ") ++ ENode}]},
|
2004-02-15 21:10:40 +01:00
|
|
|
{xmlelement, "instructions", [],
|
|
|
|
[{xmlcdata,
|
|
|
|
translate:translate(
|
|
|
|
Lang, "Enter path to backup file")}]},
|
|
|
|
{xmlelement, "field", [{"type", "text-single"},
|
|
|
|
{"label",
|
|
|
|
translate:translate(
|
|
|
|
Lang, "Path to File")},
|
|
|
|
{"var", "path"}],
|
|
|
|
[{xmlelement, "value", [], [{xmlcdata, ""}]}]
|
|
|
|
}
|
|
|
|
]}]};
|
2003-02-22 20:11:00 +01:00
|
|
|
|
|
|
|
get_form(["running nodes", ENode, "backup", "textfile"], Lang) ->
|
2004-02-15 21:10:40 +01:00
|
|
|
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
|
|
|
|
[{xmlelement, "title", [],
|
|
|
|
[{xmlcdata,
|
|
|
|
translate:translate(
|
2004-02-26 23:00:04 +01:00
|
|
|
Lang, "Dump Backup to Text File at ") ++ ENode}]},
|
2004-02-15 21:10:40 +01:00
|
|
|
{xmlelement, "instructions", [],
|
|
|
|
[{xmlcdata,
|
|
|
|
translate:translate(
|
|
|
|
Lang, "Enter path to text file")}]},
|
|
|
|
{xmlelement, "field", [{"type", "text-single"},
|
|
|
|
{"label",
|
|
|
|
translate:translate(
|
|
|
|
Lang, "Path to File")},
|
|
|
|
{"var", "path"}],
|
|
|
|
[{xmlelement, "value", [], [{xmlcdata, ""}]}]
|
|
|
|
}
|
|
|
|
]}]};
|
2003-02-22 20:11:00 +01:00
|
|
|
|
2003-02-04 21:45:23 +01:00
|
|
|
get_form(["running nodes", ENode, "import", "file"], Lang) ->
|
2004-02-15 21:10:40 +01:00
|
|
|
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
|
|
|
|
[{xmlelement, "title", [],
|
|
|
|
[{xmlcdata,
|
|
|
|
translate:translate(
|
2004-02-26 23:00:04 +01:00
|
|
|
Lang, "Import User from File at ") ++ ENode}]},
|
2004-02-15 21:10:40 +01:00
|
|
|
{xmlelement, "instructions", [],
|
|
|
|
[{xmlcdata,
|
|
|
|
translate:translate(
|
|
|
|
Lang, "Enter path to jabberd1.4 spool file")}]},
|
|
|
|
{xmlelement, "field", [{"type", "text-single"},
|
|
|
|
{"label",
|
|
|
|
translate:translate(
|
|
|
|
Lang, "Path to File")},
|
|
|
|
{"var", "path"}],
|
|
|
|
[{xmlelement, "value", [], [{xmlcdata, ""}]}]
|
|
|
|
}
|
|
|
|
]}]};
|
2003-02-04 21:45:23 +01:00
|
|
|
|
|
|
|
get_form(["running nodes", ENode, "import", "dir"], Lang) ->
|
2004-02-15 21:10:40 +01:00
|
|
|
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
|
|
|
|
[{xmlelement, "title", [],
|
|
|
|
[{xmlcdata,
|
|
|
|
translate:translate(
|
2004-02-26 23:00:04 +01:00
|
|
|
Lang, "Import Users from Dir at ") ++ ENode}]},
|
2004-02-15 21:10:40 +01:00
|
|
|
{xmlelement, "instructions", [],
|
|
|
|
[{xmlcdata,
|
|
|
|
translate:translate(
|
|
|
|
Lang, "Enter path to jabberd1.4 spool dir")}]},
|
|
|
|
{xmlelement, "field", [{"type", "text-single"},
|
|
|
|
{"label",
|
|
|
|
translate:translate(
|
|
|
|
Lang, "Path to Dir")},
|
|
|
|
{"var", "path"}],
|
|
|
|
[{xmlelement, "value", [], [{xmlcdata, ""}]}]
|
|
|
|
}
|
|
|
|
]}]};
|
2003-02-04 21:45:23 +01:00
|
|
|
|
2003-01-21 21:36:55 +01:00
|
|
|
get_form(["config", "hostname"], Lang) ->
|
2004-02-15 21:10:40 +01:00
|
|
|
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
|
|
|
|
[{xmlelement, "title", [],
|
|
|
|
[{xmlcdata,
|
|
|
|
translate:translate(
|
|
|
|
Lang, "Hostname Configuration")}]},
|
|
|
|
{xmlelement, "instructions", [],
|
|
|
|
[{xmlcdata,
|
|
|
|
translate:translate(
|
|
|
|
Lang, "Choose host name")}]},
|
|
|
|
{xmlelement, "field", [{"type", "text-single"},
|
|
|
|
{"label",
|
2004-02-26 23:00:04 +01:00
|
|
|
translate:translate(Lang,
|
|
|
|
"Host name")},
|
2004-02-15 21:10:40 +01:00
|
|
|
{"var", "hostname"}],
|
|
|
|
[{xmlelement, "value", [], [{xmlcdata, ?MYNAME}]}]}
|
|
|
|
]}]};
|
2003-01-21 21:36:55 +01:00
|
|
|
|
2003-01-22 21:40:40 +01:00
|
|
|
get_form(["config", "acls"], Lang) ->
|
2004-02-15 21:10:40 +01:00
|
|
|
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
|
|
|
|
[{xmlelement, "title", [],
|
|
|
|
[{xmlcdata,
|
|
|
|
translate:translate(
|
2004-02-26 23:00:04 +01:00
|
|
|
Lang, "Access Control List Configuration")}]},
|
2004-02-15 21:10:40 +01:00
|
|
|
%{xmlelement, "instructions", [],
|
|
|
|
% [{xmlcdata,
|
|
|
|
% translate:translate(
|
|
|
|
% Lang, "")}]},
|
|
|
|
{xmlelement, "field", [{"type", "text-multi"},
|
|
|
|
{"label",
|
2004-02-26 23:00:04 +01:00
|
|
|
translate:translate(
|
|
|
|
Lang, "Access control lists")},
|
2004-02-15 21:10:40 +01:00
|
|
|
{"var", "acls"}],
|
|
|
|
lists:map(fun(S) ->
|
|
|
|
{xmlelement, "value", [], [{xmlcdata, S}]}
|
|
|
|
end,
|
|
|
|
string:tokens(
|
|
|
|
lists:flatten(io_lib:format("~p.",
|
|
|
|
[ets:tab2list(acl)])),
|
|
|
|
"\n"))
|
|
|
|
}
|
|
|
|
]}]};
|
2003-02-06 20:09:22 +01:00
|
|
|
|
|
|
|
get_form(["config", "access"], Lang) ->
|
2004-02-15 21:10:40 +01:00
|
|
|
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
|
|
|
|
[{xmlelement, "title", [],
|
|
|
|
[{xmlcdata,
|
|
|
|
translate:translate(
|
|
|
|
Lang, "Access Configuration")}]},
|
|
|
|
%{xmlelement, "instructions", [],
|
|
|
|
% [{xmlcdata,
|
|
|
|
% translate:translate(
|
|
|
|
% Lang, "")}]},
|
|
|
|
{xmlelement, "field", [{"type", "text-multi"},
|
|
|
|
{"label",
|
|
|
|
translate:translate(
|
2004-02-26 23:00:04 +01:00
|
|
|
Lang, "Access rules")},
|
2004-02-15 21:10:40 +01:00
|
|
|
{"var", "access"}],
|
|
|
|
lists:map(fun(S) ->
|
|
|
|
{xmlelement, "value", [], [{xmlcdata, S}]}
|
|
|
|
end,
|
|
|
|
string:tokens(
|
|
|
|
lists:flatten(
|
|
|
|
io_lib:format(
|
|
|
|
"~p.",
|
|
|
|
[ets:select(config,
|
|
|
|
[{{config, {access, '$1'}, '$2'},
|
|
|
|
[],
|
|
|
|
[{{access, '$1', '$2'}}]}])
|
|
|
|
])),
|
|
|
|
"\n"))
|
|
|
|
}
|
|
|
|
]}]};
|
2003-01-22 21:40:40 +01:00
|
|
|
|
2003-01-26 21:16:53 +01:00
|
|
|
get_form(["config", "remusers"], Lang) ->
|
2004-02-15 21:10:40 +01:00
|
|
|
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
|
|
|
|
[{xmlelement, "title", [],
|
|
|
|
[{xmlcdata,
|
|
|
|
translate:translate(
|
|
|
|
Lang, "Remove Users")}]},
|
|
|
|
{xmlelement, "instructions", [],
|
|
|
|
[{xmlcdata,
|
|
|
|
translate:translate(
|
|
|
|
Lang, "Choose users to remove")}]}] ++
|
|
|
|
case catch ejabberd_auth:dirty_get_registered_users() of
|
2005-09-04 03:58:47 +02:00
|
|
|
{'EXIT', _Reason} ->
|
2004-02-15 21:10:40 +01:00
|
|
|
[];
|
|
|
|
Users ->
|
|
|
|
lists:map(fun(U) ->
|
|
|
|
?XFIELD("boolean", U, U, "0")
|
|
|
|
end, lists:sort(Users))
|
|
|
|
end
|
|
|
|
}]};
|
2003-01-26 21:16:53 +01:00
|
|
|
|
2005-09-04 03:58:47 +02:00
|
|
|
get_form(_, _Lang) ->
|
2003-03-09 21:46:47 +01:00
|
|
|
{error, ?ERR_SERVICE_UNAVAILABLE}.
|
2003-01-19 21:17:56 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
2005-09-04 03:58:47 +02:00
|
|
|
set_form(["running nodes", ENode, "DB"], _Lang, XData) ->
|
2003-01-19 21:17:56 +01:00
|
|
|
case search_running_node(ENode) of
|
|
|
|
false ->
|
2003-10-16 20:17:44 +02:00
|
|
|
{error, ?ERR_ITEM_NOT_FOUND};
|
2003-01-19 21:17:56 +01:00
|
|
|
Node ->
|
|
|
|
lists:foreach(
|
|
|
|
fun({SVar, SVals}) ->
|
2004-05-16 22:13:38 +02:00
|
|
|
% We believe that this is allowed only for good people
|
2003-01-19 21:17:56 +01:00
|
|
|
Table = list_to_atom(SVar),
|
|
|
|
Type = case SVals of
|
|
|
|
["unknown"] -> unknown;
|
|
|
|
["ram_copies"] -> ram_copies;
|
|
|
|
["disc_copies"] -> disc_copies;
|
|
|
|
["disc_only_copies"] -> disc_only_copies;
|
|
|
|
_ -> false
|
|
|
|
end,
|
|
|
|
if
|
|
|
|
Type == false ->
|
|
|
|
ok;
|
|
|
|
Type == unknown ->
|
|
|
|
mnesia:del_table_copy(Table, Node);
|
|
|
|
true ->
|
|
|
|
case mnesia:add_table_copy(Table, Node, Type) of
|
|
|
|
{aborted, _} ->
|
|
|
|
mnesia:change_table_copy_type(
|
|
|
|
Table, Node, Type);
|
|
|
|
_ ->
|
|
|
|
ok
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end, XData),
|
|
|
|
{result, []}
|
|
|
|
end;
|
|
|
|
|
2005-09-04 03:58:47 +02:00
|
|
|
set_form(["running nodes", ENode, "modules", "stop"], _Lang, XData) ->
|
2003-01-28 20:45:13 +01:00
|
|
|
case search_running_node(ENode) of
|
|
|
|
false ->
|
2003-10-16 20:17:44 +02:00
|
|
|
{error, ?ERR_ITEM_NOT_FOUND};
|
2003-01-28 20:45:13 +01:00
|
|
|
Node ->
|
|
|
|
lists:foreach(
|
|
|
|
fun({Var, Vals}) ->
|
|
|
|
case Vals of
|
|
|
|
["1"] ->
|
|
|
|
Module = list_to_atom(Var),
|
|
|
|
rpc:call(Node, gen_mod, stop_module, [Module]);
|
|
|
|
_ ->
|
|
|
|
ok
|
|
|
|
end
|
|
|
|
end, XData),
|
|
|
|
{result, []}
|
|
|
|
end;
|
|
|
|
|
2005-09-04 03:58:47 +02:00
|
|
|
set_form(["running nodes", ENode, "modules", "start"], _Lang, XData) ->
|
2003-01-28 20:45:13 +01:00
|
|
|
case search_running_node(ENode) of
|
|
|
|
false ->
|
2003-10-16 20:17:44 +02:00
|
|
|
{error, ?ERR_ITEM_NOT_FOUND};
|
2003-01-28 20:45:13 +01:00
|
|
|
Node ->
|
|
|
|
case lists:keysearch("modules", 1, XData) of
|
|
|
|
false ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST};
|
2003-01-28 20:45:13 +01:00
|
|
|
{value, {_, Strings}} ->
|
|
|
|
String = lists:foldl(fun(S, Res) ->
|
|
|
|
Res ++ S ++ "\n"
|
|
|
|
end, "", Strings),
|
|
|
|
case erl_scan:string(String) of
|
|
|
|
{ok, Tokens, _} ->
|
|
|
|
case erl_parse:parse_term(Tokens) of
|
|
|
|
{ok, Modules} ->
|
2003-02-01 21:21:28 +01:00
|
|
|
lists:foreach(
|
|
|
|
fun({Module, Args}) ->
|
|
|
|
rpc:call(Node,
|
|
|
|
gen_mod,
|
|
|
|
start_module,
|
|
|
|
[Module, Args])
|
|
|
|
end, Modules),
|
|
|
|
{result, []};
|
2003-01-28 20:45:13 +01:00
|
|
|
_ ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST}
|
2003-01-28 20:45:13 +01:00
|
|
|
end;
|
|
|
|
_ ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST}
|
2003-01-28 20:45:13 +01:00
|
|
|
end;
|
|
|
|
_ ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST}
|
2003-01-28 20:45:13 +01:00
|
|
|
end
|
2003-02-04 21:45:23 +01:00
|
|
|
end;
|
|
|
|
|
|
|
|
|
2005-09-04 03:58:47 +02:00
|
|
|
set_form(["running nodes", ENode, "backup", "backup"], _Lang, XData) ->
|
2003-02-22 20:11:00 +01:00
|
|
|
case search_running_node(ENode) of
|
|
|
|
false ->
|
2003-10-16 20:17:44 +02:00
|
|
|
{error, ?ERR_ITEM_NOT_FOUND};
|
2003-02-22 20:11:00 +01:00
|
|
|
Node ->
|
|
|
|
case lists:keysearch("path", 1, XData) of
|
|
|
|
false ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST};
|
2003-02-22 20:11:00 +01:00
|
|
|
{value, {_, [String]}} ->
|
|
|
|
case rpc:call(Node, mnesia, backup, [String]) of
|
2005-09-04 03:58:47 +02:00
|
|
|
{badrpc, _Reason} ->
|
2003-03-09 21:46:47 +01:00
|
|
|
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
2005-09-04 03:58:47 +02:00
|
|
|
{error, _Reason} ->
|
2003-03-09 21:46:47 +01:00
|
|
|
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
2003-02-22 20:11:00 +01:00
|
|
|
_ ->
|
|
|
|
{result, []}
|
|
|
|
end;
|
|
|
|
_ ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST}
|
2003-02-22 20:11:00 +01:00
|
|
|
end
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2005-09-04 03:58:47 +02:00
|
|
|
set_form(["running nodes", ENode, "backup", "restore"], _Lang, XData) ->
|
2003-02-22 20:11:00 +01:00
|
|
|
case search_running_node(ENode) of
|
|
|
|
false ->
|
2003-10-16 20:17:44 +02:00
|
|
|
{error, ?ERR_ITEM_NOT_FOUND};
|
2003-02-22 20:11:00 +01:00
|
|
|
Node ->
|
|
|
|
case lists:keysearch("path", 1, XData) of
|
|
|
|
false ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST};
|
2003-02-22 20:11:00 +01:00
|
|
|
{value, {_, [String]}} ->
|
|
|
|
case rpc:call(Node, mnesia, restore,
|
|
|
|
[String, [{default_op, keep_tables}]]) of
|
2005-09-04 03:58:47 +02:00
|
|
|
{badrpc, _Reason} ->
|
2003-03-09 21:46:47 +01:00
|
|
|
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
2005-09-04 03:58:47 +02:00
|
|
|
{error, _Reason} ->
|
2003-03-09 21:46:47 +01:00
|
|
|
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
2003-02-22 20:11:00 +01:00
|
|
|
_ ->
|
|
|
|
{result, []}
|
|
|
|
end;
|
|
|
|
_ ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST}
|
2003-02-22 20:11:00 +01:00
|
|
|
end
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2005-09-04 03:58:47 +02:00
|
|
|
set_form(["running nodes", ENode, "backup", "textfile"], _Lang, XData) ->
|
2003-02-22 20:11:00 +01:00
|
|
|
case search_running_node(ENode) of
|
|
|
|
false ->
|
2003-10-16 20:17:44 +02:00
|
|
|
{error, ?ERR_ITEM_NOT_FOUND};
|
2003-02-22 20:11:00 +01:00
|
|
|
Node ->
|
|
|
|
case lists:keysearch("path", 1, XData) of
|
|
|
|
false ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST};
|
2003-02-22 20:11:00 +01:00
|
|
|
{value, {_, [String]}} ->
|
|
|
|
case rpc:call(Node, mnesia, dump_to_textfile, [String]) of
|
2005-09-04 03:58:47 +02:00
|
|
|
{badrpc, _Reason} ->
|
2003-03-09 21:46:47 +01:00
|
|
|
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
2005-09-04 03:58:47 +02:00
|
|
|
{error, _Reason} ->
|
2003-03-09 21:46:47 +01:00
|
|
|
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
2003-02-22 20:11:00 +01:00
|
|
|
_ ->
|
|
|
|
{result, []}
|
|
|
|
end;
|
|
|
|
_ ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST}
|
2003-02-22 20:11:00 +01:00
|
|
|
end
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2005-09-04 03:58:47 +02:00
|
|
|
set_form(["running nodes", ENode, "import", "file"], _Lang, XData) ->
|
2003-02-04 21:45:23 +01:00
|
|
|
case search_running_node(ENode) of
|
|
|
|
false ->
|
2003-10-16 20:17:44 +02:00
|
|
|
{error, ?ERR_ITEM_NOT_FOUND};
|
2003-02-04 21:45:23 +01:00
|
|
|
Node ->
|
|
|
|
case lists:keysearch("path", 1, XData) of
|
|
|
|
false ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST};
|
2003-02-04 21:45:23 +01:00
|
|
|
{value, {_, [String]}} ->
|
2003-02-22 20:11:00 +01:00
|
|
|
rpc:call(Node, jd2ejd, import_file, [String]),
|
|
|
|
{result, []};
|
2003-02-04 21:45:23 +01:00
|
|
|
_ ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST}
|
2003-02-04 21:45:23 +01:00
|
|
|
end
|
|
|
|
end;
|
|
|
|
|
|
|
|
|
2005-09-04 03:58:47 +02:00
|
|
|
set_form(["running nodes", ENode, "import", "dir"], _Lang, XData) ->
|
2003-02-04 21:45:23 +01:00
|
|
|
case search_running_node(ENode) of
|
|
|
|
false ->
|
2003-10-16 20:17:44 +02:00
|
|
|
{error, ?ERR_ITEM_NOT_FOUND};
|
2003-02-04 21:45:23 +01:00
|
|
|
Node ->
|
|
|
|
case lists:keysearch("path", 1, XData) of
|
|
|
|
false ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST};
|
2003-02-04 21:45:23 +01:00
|
|
|
{value, {_, [String]}} ->
|
2003-10-20 20:23:30 +02:00
|
|
|
rpc:call(Node, jd2ejd, import_dir, [String]),
|
|
|
|
{result, []};
|
2003-02-04 21:45:23 +01:00
|
|
|
_ ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST}
|
2003-02-04 21:45:23 +01:00
|
|
|
end
|
2003-01-28 20:45:13 +01:00
|
|
|
end;
|
|
|
|
|
|
|
|
|
2005-09-04 03:58:47 +02:00
|
|
|
set_form(["config", "hostname"], _Lang, XData) ->
|
2003-01-21 21:36:55 +01:00
|
|
|
case lists:keysearch("hostname", 1, XData) of
|
|
|
|
false ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST};
|
2003-01-21 21:36:55 +01:00
|
|
|
{value, {_, [""]}} ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST};
|
2003-01-21 21:36:55 +01:00
|
|
|
{value, {_, [NewName]}} ->
|
|
|
|
ejabberd_config:add_global_option(hostname, NewName),
|
|
|
|
{result, []};
|
|
|
|
_ ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST}
|
2003-01-21 21:36:55 +01:00
|
|
|
end;
|
2003-02-01 21:21:28 +01:00
|
|
|
|
2005-09-04 03:58:47 +02:00
|
|
|
set_form(["config", "acls"], _Lang, XData) ->
|
2003-02-01 21:21:28 +01:00
|
|
|
case lists:keysearch("acls", 1, XData) of
|
|
|
|
{value, {_, Strings}} ->
|
2003-02-06 20:09:22 +01:00
|
|
|
String = lists:foldl(fun(S, Res) ->
|
|
|
|
Res ++ S ++ "\n"
|
|
|
|
end, "", Strings),
|
|
|
|
case erl_scan:string(String) of
|
|
|
|
{ok, Tokens, _} ->
|
|
|
|
case erl_parse:parse_term(Tokens) of
|
|
|
|
{ok, ACLs} ->
|
|
|
|
case acl:add_list(ACLs, true) of
|
|
|
|
ok ->
|
|
|
|
{result, []};
|
2003-02-01 21:21:28 +01:00
|
|
|
_ ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST}
|
2003-02-01 21:21:28 +01:00
|
|
|
end;
|
|
|
|
_ ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST}
|
2003-02-01 21:21:28 +01:00
|
|
|
end;
|
2003-02-06 20:09:22 +01:00
|
|
|
_ ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST}
|
2003-02-06 20:09:22 +01:00
|
|
|
end;
|
|
|
|
_ ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST}
|
2003-02-06 20:09:22 +01:00
|
|
|
end;
|
|
|
|
|
2005-09-04 03:58:47 +02:00
|
|
|
set_form(["config", "access"], _Lang, XData) ->
|
2003-02-06 20:09:22 +01:00
|
|
|
SetAccess =
|
|
|
|
fun(Rs) ->
|
|
|
|
mnesia:transaction(
|
|
|
|
fun() ->
|
|
|
|
Os = mnesia:select(config,
|
|
|
|
[{{config, {access, '$1'}, '$2'},
|
|
|
|
[],
|
|
|
|
['$_']}]),
|
|
|
|
lists:foreach(fun(O) ->
|
|
|
|
mnesia:delete_object(O)
|
|
|
|
end, Os),
|
|
|
|
lists:foreach(
|
|
|
|
fun({access, Name, Rules}) ->
|
|
|
|
mnesia:write({config,
|
|
|
|
{access, Name},
|
|
|
|
Rules})
|
|
|
|
end, Rs)
|
|
|
|
end)
|
|
|
|
end,
|
|
|
|
case lists:keysearch("access", 1, XData) of
|
|
|
|
{value, {_, Strings}} ->
|
|
|
|
String = lists:foldl(fun(S, Res) ->
|
|
|
|
Res ++ S ++ "\n"
|
|
|
|
end, "", Strings),
|
|
|
|
case erl_scan:string(String) of
|
|
|
|
{ok, Tokens, _} ->
|
|
|
|
case erl_parse:parse_term(Tokens) of
|
|
|
|
{ok, Rs} ->
|
|
|
|
case SetAccess(Rs) of
|
|
|
|
{atomic, _} ->
|
|
|
|
{result, []};
|
|
|
|
E ->
|
|
|
|
io:format("A: ~p~n", [E]),
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST}
|
2003-02-06 20:09:22 +01:00
|
|
|
end;
|
|
|
|
_ ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST}
|
2003-02-06 20:09:22 +01:00
|
|
|
end;
|
|
|
|
_ ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST}
|
2003-02-06 20:09:22 +01:00
|
|
|
end;
|
2003-02-01 21:21:28 +01:00
|
|
|
_ ->
|
2003-05-09 21:32:59 +02:00
|
|
|
{error, ?ERR_BAD_REQUEST}
|
2003-02-01 21:21:28 +01:00
|
|
|
end;
|
2003-01-21 21:36:55 +01:00
|
|
|
|
2005-09-04 03:58:47 +02:00
|
|
|
set_form(["config", "remusers"], _Lang, XData) ->
|
2003-01-26 21:16:53 +01:00
|
|
|
lists:foreach(
|
|
|
|
fun({Var, Vals}) ->
|
|
|
|
case Vals of
|
|
|
|
["1"] ->
|
2003-11-01 22:06:50 +01:00
|
|
|
catch ejabberd_auth:remove_user(Var);
|
2003-01-26 21:16:53 +01:00
|
|
|
_ ->
|
|
|
|
ok
|
|
|
|
end
|
|
|
|
end, XData),
|
|
|
|
{result, []};
|
|
|
|
|
2005-09-04 03:58:47 +02:00
|
|
|
set_form(_, _Lang, _XData) ->
|
2003-03-09 21:46:47 +01:00
|
|
|
{error, ?ERR_SERVICE_UNAVAILABLE}.
|
2003-01-19 21:17:56 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
search_running_node(SNode) ->
|
|
|
|
search_running_node(SNode, mnesia:system_info(running_db_nodes)).
|
|
|
|
|
|
|
|
search_running_node(_, []) ->
|
|
|
|
false;
|
|
|
|
search_running_node(SNode, [Node | Nodes]) ->
|
|
|
|
case atom_to_list(Node) of
|
|
|
|
SNode ->
|
|
|
|
Node;
|
|
|
|
_ ->
|
|
|
|
search_running_node(SNode, Nodes)
|
|
|
|
end.
|
|
|
|
|
2003-01-21 21:36:55 +01:00
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
2003-01-19 21:17:56 +01:00
|
|
|
|
2003-12-17 21:13:21 +01:00
|
|
|
process_sm_iq(From, To,
|
2004-02-26 23:00:04 +01:00
|
|
|
#iq{type = Type, xmlns = XMLNS, lang = Lang, sub_el = SubEl} = IQ) ->
|
2005-06-20 05:18:13 +02:00
|
|
|
case acl:match_rule(To#jid.lserver, configure, From) of
|
2003-01-21 21:36:55 +01:00
|
|
|
deny ->
|
2003-12-17 21:13:21 +01:00
|
|
|
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
|
2003-01-21 21:36:55 +01:00
|
|
|
allow ->
|
2005-04-17 20:08:34 +02:00
|
|
|
#jid{user = User, server = Server} = To,
|
2003-01-21 21:36:55 +01:00
|
|
|
case Type of
|
|
|
|
set ->
|
2004-02-15 21:10:40 +01:00
|
|
|
XDataEl = find_xdata_el(SubEl),
|
|
|
|
case XDataEl of
|
|
|
|
false ->
|
|
|
|
IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ACCEPTABLE]};
|
2005-09-04 03:58:47 +02:00
|
|
|
{xmlelement, _Name, Attrs, _SubEls} ->
|
2004-02-15 21:10:40 +01:00
|
|
|
case xml:get_attr_s("type", Attrs) of
|
|
|
|
"cancel" ->
|
|
|
|
IQ#iq{type = result,
|
|
|
|
sub_el = [{xmlelement, "query",
|
|
|
|
[{"xmlns", XMLNS}], []}]};
|
|
|
|
"submit" ->
|
|
|
|
XData = jlib:parse_xdata_submit(XDataEl),
|
|
|
|
case XData of
|
|
|
|
invalid ->
|
2003-12-17 21:13:21 +01:00
|
|
|
IQ#iq{type = error,
|
2004-02-15 21:10:40 +01:00
|
|
|
sub_el = [SubEl, ?ERR_BAD_REQUEST]};
|
|
|
|
_ ->
|
|
|
|
Node =
|
|
|
|
string:tokens(
|
|
|
|
xml:get_tag_attr_s("node", SubEl),
|
|
|
|
"/"),
|
|
|
|
case set_sm_form(
|
2005-04-17 20:08:34 +02:00
|
|
|
User, Server, Node,
|
|
|
|
Lang, XData) of
|
2004-02-15 21:10:40 +01:00
|
|
|
{result, Res} ->
|
|
|
|
IQ#iq{type = result,
|
2005-04-17 20:08:34 +02:00
|
|
|
sub_el =
|
2004-02-15 21:10:40 +01:00
|
|
|
[{xmlelement, "query",
|
|
|
|
[{"xmlns", XMLNS}],
|
|
|
|
Res
|
|
|
|
}]};
|
|
|
|
{error, Error} ->
|
|
|
|
IQ#iq{type = error,
|
|
|
|
sub_el = [SubEl, Error]}
|
|
|
|
end
|
|
|
|
end;
|
|
|
|
_ ->
|
|
|
|
IQ#iq{type = error,
|
|
|
|
sub_el = [SubEl, ?ERR_BAD_REQUEST]}
|
|
|
|
end
|
2003-01-21 21:36:55 +01:00
|
|
|
end;
|
|
|
|
get ->
|
|
|
|
Node =
|
|
|
|
string:tokens(xml:get_tag_attr_s("node", SubEl), "/"),
|
2005-04-17 20:08:34 +02:00
|
|
|
case get_sm_form(User, Server, Node, Lang) of
|
2003-01-21 21:36:55 +01:00
|
|
|
{result, Res} ->
|
2003-12-17 21:13:21 +01:00
|
|
|
IQ#iq{type = result,
|
|
|
|
sub_el =
|
|
|
|
[{xmlelement, "query", [{"xmlns", XMLNS}],
|
|
|
|
Res
|
|
|
|
}]};
|
2003-03-09 21:46:47 +01:00
|
|
|
{error, Error} ->
|
2003-12-17 21:13:21 +01:00
|
|
|
IQ#iq{type = error, sub_el = [SubEl, Error]}
|
2003-01-21 21:36:55 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end.
|
|
|
|
|
|
|
|
|
2005-04-17 20:08:34 +02:00
|
|
|
get_sm_form(User, Server, [], Lang) ->
|
2004-02-15 21:10:40 +01:00
|
|
|
{result, [{xmlelement, "x", [{"xmlns", ?NS_XDATA}],
|
|
|
|
[{xmlelement, "title", [],
|
|
|
|
[{xmlcdata,
|
|
|
|
translate:translate(
|
2004-02-26 23:00:04 +01:00
|
|
|
Lang, "Administration of ") ++ User}]},
|
2004-02-15 21:10:40 +01:00
|
|
|
%{xmlelement, "instructions", [],
|
|
|
|
% [{xmlcdata,
|
|
|
|
% translate:translate(
|
|
|
|
% Lang, "Choose host name")}]},
|
|
|
|
{xmlelement, "field",
|
|
|
|
[{"type", "list-single"},
|
|
|
|
{"label", translate:translate(Lang, "Action on user")},
|
|
|
|
{"var", "action"}],
|
|
|
|
[{xmlelement, "value", [], [{xmlcdata, "edit"}]},
|
|
|
|
{xmlelement, "option",
|
|
|
|
[{"label", translate:translate(Lang, "Edit Properties")}],
|
|
|
|
[{xmlelement, "value", [], [{xmlcdata, "edit"}]}]},
|
|
|
|
{xmlelement, "option",
|
|
|
|
[{"label", translate:translate(Lang, "Remove User")}],
|
|
|
|
[{xmlelement, "value", [], [{xmlcdata, "remove"}]}]}
|
|
|
|
]},
|
|
|
|
?XFIELD("text-private", "Password", "password",
|
2005-04-17 20:08:34 +02:00
|
|
|
ejabberd_auth:get_password_s(User, Server))
|
2004-02-15 21:10:40 +01:00
|
|
|
%{xmlelement, "field", [{"type", "text-single"},
|
|
|
|
% {"label",
|
|
|
|
% translate:translate(Lang, "Host name")},
|
|
|
|
% {"var", "hostname"}],
|
|
|
|
% [{xmlelement, "value", [], [{xmlcdata, ?MYNAME}]}]}
|
|
|
|
]}]};
|
2003-01-21 21:36:55 +01:00
|
|
|
|
2005-09-04 03:58:47 +02:00
|
|
|
get_sm_form(_User, _Server, _Node, _Lang) ->
|
2003-03-09 21:46:47 +01:00
|
|
|
{error, ?ERR_SERVICE_UNAVAILABLE}.
|
2003-01-21 21:36:55 +01:00
|
|
|
|
|
|
|
|
2005-09-04 03:58:47 +02:00
|
|
|
set_sm_form(User, Server, [], _Lang, XData) ->
|
2003-10-09 20:09:05 +02:00
|
|
|
case lists:keysearch("action", 1, XData) of
|
|
|
|
{value, {_, ["edit"]}} ->
|
2003-11-09 21:18:36 +01:00
|
|
|
case lists:keysearch("password", 1, XData) of
|
|
|
|
{value, {_, [Password]}} ->
|
2005-04-17 20:08:34 +02:00
|
|
|
ejabberd_auth:set_password(User, Server, Password),
|
2003-11-09 21:18:36 +01:00
|
|
|
{result, []};
|
|
|
|
_ ->
|
|
|
|
{error, ?ERR_BAD_REQUEST}
|
|
|
|
end;
|
2003-10-09 20:09:05 +02:00
|
|
|
{value, {_, ["remove"]}} ->
|
2005-04-17 20:08:34 +02:00
|
|
|
catch ejabberd_auth:remove_user(User, Server),
|
2003-10-09 20:09:05 +02:00
|
|
|
{result, []};
|
|
|
|
_ ->
|
|
|
|
{error, ?ERR_BAD_REQUEST}
|
|
|
|
end;
|
2005-09-04 03:58:47 +02:00
|
|
|
set_sm_form(_User, _Server, _Node, _Lang, _XData) ->
|
2003-03-09 21:46:47 +01:00
|
|
|
{error, ?ERR_SERVICE_UNAVAILABLE}.
|
2004-02-15 21:10:40 +01:00
|
|
|
|
|
|
|
find_xdata_el({xmlelement, _Name, _Attrs, SubEls}) ->
|
|
|
|
find_xdata_el1(SubEls).
|
|
|
|
|
|
|
|
find_xdata_el1([]) ->
|
|
|
|
false;
|
|
|
|
|
|
|
|
find_xdata_el1([{xmlelement, Name, Attrs, SubEls} | Els]) ->
|
|
|
|
case xml:get_attr_s("xmlns", Attrs) of
|
|
|
|
?NS_XDATA ->
|
|
|
|
{xmlelement, Name, Attrs, SubEls};
|
|
|
|
_ ->
|
|
|
|
find_xdata_el1(Els)
|
|
|
|
end;
|
|
|
|
|
|
|
|
find_xdata_el1([_ | Els]) ->
|
|
|
|
find_xdata_el1(Els).
|