aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBadlop <badlop@process-one.net>2013-12-04 14:55:21 +0100
committerBadlop <badlop@process-one.net>2013-12-04 14:57:44 +0100
commit5a1300bc7019c603a777b173bd62cc309d74da8d (patch)
tree8bcd2fba2c8e1a4f9a5baa6270158654e104d4b4 /src
parentbind values for get_parentnodes_tree (diff)
Add access rule to mod_roster (EJAB-72)
Diffstat (limited to 'src')
-rw-r--r--src/ejabberd_c2s.erl26
-rw-r--r--src/mod_roster.erl14
2 files changed, 30 insertions, 10 deletions
diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl
index fa8ec3f5b..e5304044a 100644
--- a/src/ejabberd_c2s.erl
+++ b/src/ejabberd_c2s.erl
@@ -1879,10 +1879,7 @@ presence_track(From, To, Packet, StateData) ->
A = remove_element(LTo, StateData#state.pres_a),
StateData#state{pres_a = A};
<<"subscribe">> ->
- ejabberd_hooks:run(roster_out_subscription, Server,
- [User, Server, To, subscribe]),
- check_privacy_route(From, StateData,
- jlib:jid_remove_resource(From), To, Packet),
+ try_roster_subscribe(subscribe, User, Server, From, To, Packet, StateData),
StateData;
<<"subscribed">> ->
ejabberd_hooks:run(roster_out_subscription, Server,
@@ -1891,10 +1888,7 @@ presence_track(From, To, Packet, StateData) ->
jlib:jid_remove_resource(From), To, Packet),
StateData;
<<"unsubscribe">> ->
- ejabberd_hooks:run(roster_out_subscription, Server,
- [User, Server, To, unsubscribe]),
- check_privacy_route(From, StateData,
- jlib:jid_remove_resource(From), To, Packet),
+ try_roster_subscribe(unsubscribe, User, Server, From, To, Packet, StateData),
StateData;
<<"unsubscribed">> ->
ejabberd_hooks:run(roster_out_subscription, Server,
@@ -1943,6 +1937,22 @@ is_privacy_allow(StateData, From, To, Packet, Dir) ->
allow ==
privacy_check_packet(StateData, From, To, Packet, Dir).
+%%% Check ACL before allowing to send a subscription stanza
+try_roster_subscribe(Type, User, Server, From, To, Packet, StateData) ->
+ JID1 = jlib:make_jid(User, Server, <<"">>),
+ Access = gen_mod:get_module_opt(Server, mod_roster, access, fun(A) when is_atom(A) -> A end, all),
+ case acl:match_rule(Server, Access, JID1) of
+ deny ->
+ %% Silently drop this (un)subscription request
+ ok;
+ allow ->
+ ejabberd_hooks:run(roster_out_subscription,
+ Server,
+ [User, Server, To, Type]),
+ check_privacy_route(From, StateData, jlib:jid_remove_resource(From),
+ To, Packet)
+ end.
+
%% Send presence when disconnecting
presence_broadcast(StateData, From, JIDSet, Packet) ->
JIDs = ?SETS:to_list(JIDSet),
diff --git a/src/mod_roster.erl b/src/mod_roster.erl
index dd211b95a..7415aa3de 100644
--- a/src/mod_roster.erl
+++ b/src/mod_roster.erl
@@ -142,7 +142,7 @@ process_iq(From, To, IQ) ->
process_local_iq(From, To, #iq{type = Type} = IQ) ->
case Type of
- set -> process_iq_set(From, To, IQ);
+ set -> try_process_iq_set(From, To, IQ);
get -> process_iq_get(From, To, IQ)
end.
@@ -455,6 +455,16 @@ get_roster_by_jid_t(LUser, LServer, LJID, odbc) ->
end
end.
+try_process_iq_set(From, To, #iq{sub_el = SubEl} = IQ) ->
+ #jid{server = Server} = From,
+ Access = gen_mod:get_module_opt(Server, ?MODULE, access, fun(A) when is_atom(A) -> A end, all),
+ case acl:match_rule(Server, Access, From) of
+ deny ->
+ IQ#iq{type = error, sub_el = [SubEl, ?ERR_NOT_ALLOWED]};
+ allow ->
+ process_iq_set(From, To, IQ)
+ end.
+
process_iq_set(From, To, #iq{sub_el = SubEl} = IQ) ->
#xmlel{children = Els} = SubEl,
lists:foreach(fun (El) -> process_item_set(From, To, El)
@@ -1508,7 +1518,7 @@ user_roster_item_parse_query(User, Server, Items,
{value, _} ->
UJID = jlib:make_jid(User, Server,
<<"">>),
- process_iq(UJID, UJID,
+ process_iq_set(UJID, UJID,
#iq{type = set,
sub_el =
#xmlel{name =