aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMickaël Rémond <mickael.remond@process-one.net>2006-06-07 08:38:37 +0000
committerMickaël Rémond <mickael.remond@process-one.net>2006-06-07 08:38:37 +0000
commit9dcd3f40805033a13bbfdbfab222fc0af11ad8c9 (patch)
tree24f03d632831f1a7edfe5e1b7176e6b3b9781764 /src
parent* src/web/ejabberd_http.erl: The web module now accepts HTTP (diff)
* src/mod_pubsub/mod_pubsub.erl: Support for pubsub node
creation ACL. It is now possible to limit the node creation rights using an ACL from ejabberd config file (Thanks to Christophe Romain) (EJAB-104). * doc/guide.tex: Likewise. * src/ejabberd.cfg.example. SVN Revision: 577
Diffstat (limited to 'src')
-rw-r--r--src/ejabberd.cfg.example4
-rw-r--r--src/mod_pubsub/mod_pubsub.erl53
2 files changed, 37 insertions, 20 deletions
diff --git a/src/ejabberd.cfg.example b/src/ejabberd.cfg.example
index e8ef5a4c5..bcc103385 100644
--- a/src/ejabberd.cfg.example
+++ b/src/ejabberd.cfg.example
@@ -20,6 +20,8 @@
%{acl, test, {user_regexp, "^test"}}.
%{acl, test, {user_glob, "test*"}}.
+% Everybody can create pubsub nodes
+{access, pubsub_createnode, [{allow, all}]}.
% Only admins can use configuration interface:
{access, configure, [{allow, admin}]}.
@@ -171,7 +173,7 @@
{access_admin, muc_admin}]},
% {mod_muc_log, []},
% {mod_shared_roster, []},
- {mod_pubsub, []},
+ {mod_pubsub, [{access_createnode, pubsub_createnode}]},
{mod_time, []},
{mod_last, []},
{mod_version, []}
diff --git a/src/mod_pubsub/mod_pubsub.erl b/src/mod_pubsub/mod_pubsub.erl
index a96515343..6c46ffdb3 100644
--- a/src/mod_pubsub/mod_pubsub.erl
+++ b/src/mod_pubsub/mod_pubsub.erl
@@ -33,7 +33,7 @@
-include("ejabberd.hrl").
-include("jlib.hrl").
--record(state, {host}).
+-record(state, {host, server_host, access}).
-define(DICT, dict).
-define(MAXITEMS, 20).
@@ -122,6 +122,7 @@ init([ServerHost, Opts]) ->
update_table(Host),
mnesia:add_table_index(pubsub_node, host_parent),
ServedHosts = gen_mod:get_opt(served_hosts, Opts, []),
+ Access = gen_mod:get_opt(access_createnode, Opts, all),
ejabberd_router:register_route(Host),
create_new_node(Host, ["pubsub"], ?MYJID),
@@ -133,7 +134,7 @@ init([ServerHost, Opts]) ->
end, ServedHosts),
ets:new(gen_mod:get_module_proc(Host, pubsub_presence),
[set, named_table]),
- {ok, #state{host = Host}}.
+ {ok, #state{host = Host, server_host = ServerHost, access = Access}}.
%%--------------------------------------------------------------------
%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
@@ -162,8 +163,9 @@ handle_cast(_Msg, State) ->
%% {stop, Reason, State}
%% Description: Handling all non call/cast messages
%%--------------------------------------------------------------------
-handle_info({route, From, To, Packet}, State) ->
- case catch do_route(To#jid.lserver, From, To, Packet) of
+handle_info({route, From, To, Packet},
+#state{server_host = ServerHost, access = Access} = State) ->
+ case catch do_route(To#jid.lserver, ServerHost, Access, From, To, Packet) of
{'EXIT', Reason} ->
?ERROR_MSG("~p", [Reason]);
_ ->
@@ -194,7 +196,7 @@ code_change(_OldVsn, State, _Extra) ->
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-do_route(Host, From, To, Packet) ->
+do_route(Host, ServerHost, Access, From, To, Packet) ->
{xmlelement, Name, Attrs, Els} = Packet,
case To of
#jid{luser = "", lresource = ""} ->
@@ -232,7 +234,7 @@ do_route(Host, From, To, Packet) ->
#iq{type = Type, xmlns = ?NS_PUBSUB = XMLNS,
sub_el = SubEl} = IQ ->
Res =
- case iq_pubsub(Host, From, Type, SubEl) of
+ case iq_pubsub(Host, ServerHost, From, Type, SubEl, Access) of
{result, IQRes} ->
jlib:iq_to_xml(
IQ#iq{type = result,
@@ -397,7 +399,7 @@ iq_get_vcard(Lang) ->
"Copyright (c) 2003-2006 Alexey Shchepin")}]}].
-iq_pubsub(Host, From, Type, SubEl) ->
+iq_pubsub(Host, ServerHost, From, Type, SubEl, Access) ->
{xmlelement, _, _, SubEls} = SubEl,
case xml:remove_cdata(SubEls) of
[{xmlelement, Name, Attrs, Els}] ->
@@ -405,7 +407,7 @@ iq_pubsub(Host, From, Type, SubEl) ->
Node = string:tokens(SNode, "/"),
case {Type, Name} of
{set, "create"} ->
- create_new_node(Host, Node, From);
+ create_new_node(Host, Node, From, ServerHost, Access);
{set, "publish"} ->
case xml:remove_cdata(Els) of
[{xmlelement, "item", ItemAttrs, Payload}] ->
@@ -484,13 +486,17 @@ iq_pubsub(Host, From, Type, SubEl) ->
%% Create new pubsub nodes
%% This function is used during init to create the first bootstrap nodes
create_new_node(Host, Node, Owner) ->
+ %% This is the case use during "bootstrapping to create the initial
+ %% hierarchy. Should always be ... undefined,all
+ create_new_node(Host, Node, Owner, undefined, all).
+create_new_node(Host, Node, Owner, ServerHost, Access) ->
case Node of
[] ->
{LOU, LOS, _} = jlib:jid_tolower(Owner),
HomeNode = ["home", LOS, LOU],
- create_new_node(Host, HomeNode, Owner),
+ create_new_node(Host, HomeNode, Owner, ServerHost, Access),
NewNode = ["home", LOS, LOU, randoms:get_string()],
- create_new_node(Host, NewNode, Owner);
+ create_new_node(Host, NewNode, Owner, ServerHost, Access);
_ ->
LOwner = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
Parent = lists:sublist(Node, length(Node) - 1),
@@ -525,7 +531,7 @@ create_new_node(Host, Node, Owner) ->
end
end
end,
- case check_create_permission(Host, Node, Owner) of
+ case check_create_permission(Host, Node, Owner, ServerHost, Access) of
true ->
case mnesia:transaction(F) of
{atomic, ok} ->
@@ -1052,14 +1058,23 @@ subscription_to_string(Subscription) ->
end.
-check_create_permission(Host, Node, Owner) ->
- if
- Owner#jid.lserver == Host ->
- true;
- true ->
- #jid{luser = User, lserver = Server} = Owner,
- case Node of
- ["home", Server, User | _] ->
+check_create_permission(Host, Node, Owner, ServerHost, Access) ->
+ #jid{luser = User, lserver = Server, lresource = Resource} = Owner,
+ case acl:match_rule(ServerHost, Access, {User, Server, Resource}) of
+ allow ->
+ if Server == Host ->
+ true;
+ true ->
+ case Node of
+ ["home", Server, User | _] ->
+ true;
+ _ ->
+ false
+ end
+ end;
+ _ ->
+ case Owner of
+ ?MYJID ->
true;
_ ->
false