diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ejabberd.cfg.example | 4 | ||||
-rw-r--r-- | src/mod_pubsub/mod_pubsub.erl | 53 |
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 |