aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO1
-rw-r--r--src/acl.erl8
-rw-r--r--src/ejabberd.cfg6
-rw-r--r--src/ejabberd_local.erl1
-rw-r--r--src/ejabberd_s2s.erl38
-rw-r--r--src/ejabberd_sm.erl31
-rw-r--r--src/mod_configure.erl207
-rw-r--r--src/mod_disco.erl25
8 files changed, 279 insertions, 38 deletions
diff --git a/TODO b/TODO
index 87f4691ea..30f722030 100644
--- a/TODO
+++ b/TODO
@@ -1,3 +1,4 @@
+admin interface
S2S timeouts
iq:browse(?)
SVR DNS records
diff --git a/src/acl.erl b/src/acl.erl
index 109d4edd6..b9c231475 100644
--- a/src/acl.erl
+++ b/src/acl.erl
@@ -22,8 +22,12 @@ add(ACLName, ACLData) ->
ets:insert(acls, {ACLName, ACLData}).
match_rule(Rule, JID) ->
- ACLs = ejabberd_config:get_option(Rule),
- match_acls(ACLs, JID).
+ case ejabberd_config:get_option(Rule) of
+ undefined ->
+ deny;
+ ACLs ->
+ match_acls(ACLs, JID)
+ end.
match_acls([], _) ->
deny;
diff --git a/src/ejabberd.cfg b/src/ejabberd.cfg
index 538c7918f..6d3d6521d 100644
--- a/src/ejabberd.cfg
+++ b/src/ejabberd.cfg
@@ -2,12 +2,18 @@
{acl, admin, {user, "aleksey"}}.
{acl, admin, {user, "ermine"}}.
+{acl, admin, {user, "test"}}.
+{acl, admin, {user, "aleksey", "jabber.ru"}}.
+{acl, admin, {user, "ermine", "jabber.ru"}}.
+
{acl, jabberorg, {server, "jabber.org"}}.
{acl, aleksey, {user, "aleksey", "jabber.ru"}}.
{disco_admin, [{allow, admin},
{deny, all}]}.
+{configure, [{allow, admin}]}.
+
{host, "e.localhost"}.
{listen, [{5522, ejabberd_c2s, start, []},
diff --git a/src/ejabberd_local.erl b/src/ejabberd_local.erl
index f96aab3ee..ddae487be 100644
--- a/src/ejabberd_local.erl
+++ b/src/ejabberd_local.erl
@@ -22,6 +22,7 @@ start() ->
register(ejabberd_local, spawn(ejabberd_local, init, [])),
mod_register:start(),
mod_roster:start(),
+ mod_configure:start(),
mod_disco:start(),
mod_stats:start(),
mod_vcard:start(),
diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl
index a597a6247..d834dea5c 100644
--- a/src/ejabberd_s2s.erl
+++ b/src/ejabberd_s2s.erl
@@ -86,24 +86,40 @@ clean_table_from_bad_node(Node) ->
end,
mnesia:transaction(F).
+%have_connection(FromTo) ->
+% F = fun() ->
+% [E] = mnesia:read({s2s, FromTo})
+% end,
+% case mnesia:transaction(F) of
+% {atomic, _} ->
+% true;
+% _ ->
+% false
+% end.
+
have_connection(FromTo) ->
- F = fun() ->
- [E] = mnesia:read({s2s, FromTo})
- end,
- case mnesia:transaction(F) of
- {atomic, _} ->
+ case catch mnesia:dirty_read(s2s, FromTo) of
+ [_] ->
true;
_ ->
false
end.
+%get_key(FromTo) ->
+% F = fun() ->
+% [E] = mnesia:read({s2s, FromTo}),
+% E
+% end,
+% case mnesia:transaction(F) of
+% {atomic, E} ->
+% E#s2s.key;
+% _ ->
+% ""
+% end.
+
get_key(FromTo) ->
- F = fun() ->
- [E] = mnesia:read({s2s, FromTo}),
- E
- end,
- case mnesia:transaction(F) of
- {atomic, E} ->
+ case catch mnesia:dirty_read(s2s, FromTo) of
+ [E] ->
E#s2s.key;
_ ->
""
diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl
index a86dce479..cbb695bea 100644
--- a/src/ejabberd_sm.erl
+++ b/src/ejabberd_sm.erl
@@ -297,18 +297,16 @@ route_message(From, To, Packet) ->
get_user_resources(User) ->
LUser = jlib:tolower(User),
- F = fun() ->
- mnemosyne:eval(query [X.ur || X <- table(session),
- X.user = LUser]
- end)
- end,
- case mnesia:transaction(F) of
- {atomic, Rs} ->
- lists:map(fun(R) -> element(2, R) end, Rs);
- {aborted, Reason} ->
- []
+ case catch mnesia:dirty_index_read(session, LUser, #session.user) of
+ {'EXIT', Reason} ->
+ [];
+ Rs ->
+ lists:map(fun(R) ->
+ element(2, R#session.ur)
+ end, Rs)
end.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
set_presence(User, Resource, Priority) ->
@@ -330,16 +328,13 @@ unset_presence(User, Resource) ->
get_user_present_resources(User) ->
LUser = jlib:tolower(User),
- F = fun() ->
- mnesia:index_read(presence, LUser, #presence.user)
- end,
- case mnesia:transaction(F) of
- {atomic, Rs} ->
+ case catch mnesia:dirty_index_read(presence, LUser, #presence.user) of
+ {'EXIT', Reason} ->
+ [];
+ Rs ->
lists:map(fun(R) ->
{R#presence.priority, element(2, R#presence.ur)}
- end, Rs);
- {aborted, Reason} ->
- []
+ end, Rs)
end.
dirty_get_sessions_list() ->
diff --git a/src/mod_configure.erl b/src/mod_configure.erl
new file mode 100644
index 000000000..b72f180b5
--- /dev/null
+++ b/src/mod_configure.erl
@@ -0,0 +1,207 @@
+%%%----------------------------------------------------------------------
+%%% File : mod_configure.erl
+%%% Author : Alexey Shchepin <alexey@sevcom.net>
+%%% Purpose :
+%%% Created : 19 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
+%%% Id : $Id$
+%%%----------------------------------------------------------------------
+
+-module(mod_configure).
+-author('alexey@sevcom.net').
+-vsn('$Revision$ ').
+
+-export([start/0,
+ process_local_iq/3]).
+
+-include("ejabberd.hrl").
+-include("namespaces.hrl").
+
+
+start() ->
+ ejabberd_local:register_iq_handler(?NS_XDATA,
+ ?MODULE, process_local_iq).
+
+
+process_local_iq(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
+ case acl:match_rule(configure, From) of
+ deny ->
+ {iq, ID, error, XMLNS, [SubEl, {xmlelement, "error",
+ [{"code", "405"}],
+ [{xmlcdata, "Not Allowed"}]}]};
+ allow ->
+ Lang = xml:get_tag_attr_s("xml:lang", SubEl),
+ case Type of
+ set ->
+ case xml:get_tag_attr_s("type", SubEl) of
+ "cancel" ->
+ {iq, ID, result, XMLNS,
+ [{xmlelement, "query", [{"xmlns", XMLNS}], []}]};
+ "submit" ->
+ XData = jlib:parse_xdata_submit(SubEl),
+ case XData of
+ invalid ->
+ {iq, ID, error, XMLNS,
+ [SubEl, {xmlelement, "error",
+ [{"code", "400"}],
+ [{xmlcdata, "Bad Request"}]}]};
+ _ ->
+ Node =
+ string:tokens(
+ xml:get_tag_attr_s("node", SubEl),
+ "/"),
+ case set_form(Node, Lang, XData) of
+ {result, Res} ->
+ {iq, ID, result, XMLNS,
+ [{xmlelement, "query",
+ [{"xmlns", XMLNS}],
+ Res
+ }]};
+ {error, Code, Desc} ->
+ {iq, ID, error, XMLNS,
+ [SubEl, {xmlelement, "error",
+ [{"code", Code}],
+ [{xmlcdata, Desc}]}]}
+ end
+ end;
+ _ ->
+ {iq, ID, error, XMLNS,
+ [SubEl, {xmlelement, "error",
+ [{"code", "405"}],
+ [{xmlcdata, "Not Allowed"}]}]}
+ end;
+ get ->
+ Node =
+ string:tokens(xml:get_tag_attr_s("node", SubEl), "/"),
+ case get_form(Node, Lang) of
+ {result, Res} ->
+ {iq, ID, result, XMLNS,
+ [{xmlelement, "query", [{"xmlns", XMLNS}],
+ Res
+ }]};
+ {error, Code, Desc} ->
+ {iq, ID, error, XMLNS,
+ [SubEl, {xmlelement, "error",
+ [{"code", Code}],
+ [{xmlcdata, Desc}]}]}
+ end
+ end
+ end.
+
+-define(TLFIELD(Type, Label, Var),
+ {xmlelement, "field", [{"type", Type},
+ {"label", translate:translate(Lang, Label)},
+ {"var", Var}], []}).
+
+-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",
+ translate:translate(Lang, "Disk copy")}],
+ [{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 ->
+ {error, "404", "Not Found"};
+ Node ->
+ case rpc:call(Node, mnesia, system_info, [tables]) of
+ {badrpc, Reason} ->
+ {error, "500", "Internal Server Error"};
+ Tables ->
+ {result, [{xmlelement, "title", [],
+ [{xmlcdata,
+ translate:translate(
+ Lang, "DB Tables Configuration")}]},
+ {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, Tables)
+ ]}
+ end
+ end;
+
+get_form(_, Lang) ->
+ {error, "503", "Service Unavailable"}.
+
+
+
+set_form(["running nodes", ENode, "DB"], Lang, XData) ->
+ case search_running_node(ENode) of
+ false ->
+ {error, "404", "Not Found"};
+ Node ->
+ lists:foreach(
+ fun({SVar, SVals}) ->
+ % We believe that this allowed only for good peoples
+ 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;
+
+set_form(_, Lang, XData) ->
+ {error, "503", "Service Unavailable"}.
+
+
+
+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.
+
+
diff --git a/src/mod_disco.erl b/src/mod_disco.erl
index aee3fc13c..9bf9c6dcf 100644
--- a/src/mod_disco.erl
+++ b/src/mod_disco.erl
@@ -106,6 +106,13 @@ process_local_iq_info(From, To, {iq, ID, Type, XMLNS, SubEl}) ->
feature_to_xml({?NS_STATS})
]
}]};
+ ["running nodes", ENode, "DB"] ->
+ {iq, ID, result, XMLNS, [{xmlelement,
+ "query",
+ [{"xmlns", ?NS_DISCO_INFO}],
+ [feature_to_xml({?NS_XDATA})
+ ]
+ }]};
_ ->
{iq, ID, error, XMLNS,
[SubEl, {xmlelement, "error",
@@ -122,7 +129,7 @@ domain_to_xml(Domain) ->
{xmlelement, "item", [{"jid", Domain}], []}.
--define(TOP_NODE(Name, Node),
+-define(NODE(Name, Node),
{xmlelement, "item",
[{"jid", Server},
{"name", translate:translate(Lang, Name)},
@@ -135,11 +142,11 @@ get_local_items([], Server, Lang) ->
ejabberd_router:dirty_get_all_routes()),
{result,
Domains ++
- [?TOP_NODE("Online Users", "online users"),
- ?TOP_NODE("All Users", "all users"),
- ?TOP_NODE("Outgoing S2S connections", "outgoing s2s"),
- ?TOP_NODE("Running Nodes", "running nodes"),
- ?TOP_NODE("Stopped Nodes", "stopped nodes")
+ [?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(["online users"], Server, Lang) ->
@@ -157,7 +164,11 @@ get_local_items(["running nodes"], Server, Lang) ->
get_local_items(["stopped nodes"], Server, Lang) ->
{result, get_stopped_nodes(Lang)};
-get_local_items(["running nodes", _], Server, Lang) ->
+get_local_items(["running nodes", ENode], Server, Lang) ->
+ {result,
+ [?NODE("DB", "running nodes/" ++ ENode ++ "/DB")]};
+
+get_local_items(["running nodes", ENode, "DB"], Server, Lang) ->
{result, []};
get_local_items(_, _, _) ->