aboutsummaryrefslogtreecommitdiff
path: root/src/acl.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/acl.erl')
-rw-r--r--src/acl.erl95
1 files changed, 67 insertions, 28 deletions
diff --git a/src/acl.erl b/src/acl.erl
index 67b928cd1..c7ffb874c 100644
--- a/src/acl.erl
+++ b/src/acl.erl
@@ -11,12 +11,12 @@
-vsn('$Revision$ ').
-export([start/0,
- to_record/2,
- add/2,
- add_list/2,
- match_rule/2,
+ to_record/3,
+ add/3,
+ add_list/3,
+ match_rule/3,
% for debugging only
- match_acl/2]).
+ match_acl/3]).
-include("ejabberd.hrl").
@@ -30,30 +30,35 @@ start() ->
mnesia:add_table_copy(acl, node(), ram_copies),
ok.
-to_record(ACLName, ACLSpec) ->
- #acl{aclname = ACLName, aclspec = ACLSpec}.
+to_record(Host, ACLName, ACLSpec) ->
+ #acl{aclname = {ACLName, Host}, aclspec = ACLSpec}.
-add(ACLName, ACLSpec) ->
+add(Host, ACLName, ACLSpec) ->
F = fun() ->
- mnesia:write(#acl{aclname = ACLName, aclspec = ACLSpec})
+ mnesia:write(#acl{aclname = {ACLName, Host},
+ aclspec = ACLSpec})
end,
mnesia:transaction(F).
-add_list(ACLs, Clear) ->
+add_list(Host, ACLs, Clear) ->
F = fun() ->
if
Clear ->
- Ks = mnesia:all_keys(acl),
+ Ks = mnesia:select(
+ acl, [{{acl, {'$1', Host}, '$2'}, [], ['$1']}]),
lists:foreach(fun(K) ->
- mnesia:delete({acl, K})
+ mnesia:delete({acl, {K, Host}})
end, Ks);
true ->
ok
end,
lists:foreach(fun(ACL) ->
case ACL of
- #acl{} ->
- mnesia:write(ACL)
+ #acl{aclname = ACLName,
+ aclspec = ACLSpec} ->
+ mnesia:write(
+ #acl{aclname = {ACLName, Host},
+ aclspec = ACLSpec})
end
end, ACLs)
end,
@@ -66,30 +71,53 @@ add_list(ACLs, Clear) ->
-match_rule(Rule, JID) ->
+match_rule(global, Rule, JID) ->
case Rule of
all -> allow;
none -> deny;
_ ->
- case ejabberd_config:get_global_option({access, Rule}) of
+ case ejabberd_config:get_global_option({access, Rule, global}) of
undefined ->
deny;
- ACLs ->
- match_acls(ACLs, JID)
+ GACLs ->
+ match_acls(GACLs, JID, global)
+ end
+ end;
+
+match_rule(Host, Rule, JID) ->
+ case Rule of
+ all -> allow;
+ none -> deny;
+ _ ->
+ case ejabberd_config:get_global_option({access, Rule, global}) of
+ undefined ->
+ case ejabberd_config:get_global_option({access, Rule, Host}) of
+ undefined ->
+ deny;
+ ACLs ->
+ match_acls(ACLs, JID, Host)
+ end;
+ GACLs ->
+ case ejabberd_config:get_global_option({access, Rule, Host}) of
+ undefined ->
+ match_acls(GACLs, JID, Host);
+ ACLs ->
+ match_acls(GACLs ++ ACLs, JID, Host)
+ end
end
end.
-match_acls([], _) ->
+match_acls([], _, Host) ->
deny;
-match_acls([{Access, ACL} | ACLs], JID) ->
- case match_acl(ACL, JID) of
+match_acls([{Access, ACL} | ACLs], JID, Host) ->
+ case match_acl(ACL, JID, Host) of
true ->
Access;
_ ->
- match_acls(ACLs, JID)
+ match_acls(ACLs, JID, Host)
end.
-match_acl(ACL, JID) ->
+match_acl(ACL, JID, Host) ->
case ACL of
all -> true;
none -> false;
@@ -100,14 +128,20 @@ match_acl(ACL, JID) ->
all ->
true;
{user, U} ->
- (U == User) andalso (?MYNAME == Server);
+ (U == User)
+ andalso
+ ((Host == Server) orelse
+ ((Host == global) andalso
+ lists:member(Server, ?MYHOSTS)));
{user, U, S} ->
(U == User) andalso (S == Server);
{server, S} ->
S == Server;
{user_regexp, UR} ->
- (?MYNAME == Server) andalso
- is_regexp_match(User, UR);
+ ((Host == Server) orelse
+ ((Host == global) andalso
+ lists:member(Server, ?MYHOSTS)))
+ andalso is_regexp_match(User, UR);
{user_regexp, UR, S} ->
(S == Server) andalso
is_regexp_match(User, UR);
@@ -117,7 +151,10 @@ match_acl(ACL, JID) ->
is_regexp_match(Server, SR) andalso
is_regexp_match(User, UR);
{user_glob, UR} ->
- (?MYNAME == Server) andalso
+ ((Host == Server) orelse
+ ((Host == global) andalso
+ lists:member(Server, ?MYHOSTS)))
+ andalso
is_glob_match(User, UR);
{user_glob, UR, S} ->
(S == Server) andalso
@@ -128,7 +165,9 @@ match_acl(ACL, JID) ->
is_glob_match(Server, SR) andalso
is_glob_match(User, UR)
end
- end, ets:lookup(acl, ACL))
+ end,
+ ets:lookup(acl, {ACL, global}) ++
+ ets:lookup(acl, {ACL, Host}))
end.
is_regexp_match(String, RegExp) ->