summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSimon MacMullen <simon@rabbitmq.com>2010-11-19 15:36:00 +0000
committerSimon MacMullen <simon@rabbitmq.com>2010-11-19 15:36:00 +0000
commit5aa8956519d383339160ca9f2e1dcacf397ea263 (patch)
tree4ac2dadb4f5617e0a9dba9c6df174f06399a8922 /src
parentc9d4f77de6c4845f262a12ad730aa592c7579142 (diff)
downloadrabbitmq-server-git-5aa8956519d383339160ca9f2e1dcacf397ea263.tar.gz
Rather impressionistic sketch of how pluggable auth backends might start out.
Diffstat (limited to 'src')
-rw-r--r--src/rabbit_access_control.erl72
-rw-r--r--src/rabbit_channel.erl32
-rw-r--r--src/rabbit_channel_sup.erl4
-rw-r--r--src/rabbit_mnesia.erl6
-rw-r--r--src/rabbit_reader.erl4
-rw-r--r--src/rabbit_registry.erl3
-rw-r--r--src/rabbit_types.erl9
7 files changed, 63 insertions, 67 deletions
diff --git a/src/rabbit_access_control.erl b/src/rabbit_access_control.erl
index a983300a8b..c380e6a225 100644
--- a/src/rabbit_access_control.erl
+++ b/src/rabbit_access_control.erl
@@ -34,7 +34,7 @@
-include("rabbit.hrl").
-export([user_pass_login/2, check_user_pass_login/2, make_salt/0,
- check_vhost_access/2, check_resource_access/3]).
+ check_password/2, check_vhost_access/2, check_resource_access/3]).
-export([add_user/2, delete_user/1, change_password/2, set_admin/1,
clear_admin/1, list_users/0, lookup_user/1]).
-export([change_password_hash/2]).
@@ -61,6 +61,7 @@
(username(), password())
-> {'ok', rabbit_types:user()} | {'refused', username()}).
-spec(make_salt/0 :: () -> binary()).
+-spec(check_password/2 :: (password(), password_hash()) -> boolean()).
-spec(check_vhost_access/2 ::
(rabbit_types:user(), rabbit_types:vhost())
-> 'ok' | rabbit_types:channel_exit()).
@@ -107,33 +108,19 @@ user_pass_login(User, Pass) ->
U
end.
-check_user_pass_login(Username, Pass) ->
- case lookup_user(Username) of
- {ok, User} ->
- case check_password(Pass, User#user.password_hash) of
- true -> {ok, User};
- _ -> refused
- end;
- {error, not_found} ->
- {refused, Username}
- end.
+check_user_pass_login(Username, Password) ->
+ {ok, Modules} = application:get_env(rabbit, auth_backends),
+ lists:foldl(
+ fun(Module, {refused, _}) ->
+ Module:check_user_pass_login(Username, Password);
+ (_, {ok, User}) ->
+ {ok, User}
+ end, {refused, Username}, Modules).
-internal_lookup_vhost_access(Username, VHostPath) ->
- %% TODO: use dirty ops instead
- rabbit_misc:execute_mnesia_transaction(
- fun () ->
- case mnesia:read({rabbit_user_permission,
- #user_vhost{username = Username,
- virtual_host = VHostPath}}) of
- [] -> not_found;
- [R] -> {ok, R}
- end
- end).
-
-check_vhost_access(#user{username = Username}, VHostPath) ->
+check_vhost_access(User = #user{username = Username}, VHostPath) ->
?LOGDEBUG("Checking VHost access for ~p to ~p~n", [Username, VHostPath]),
- case internal_lookup_vhost_access(Username, VHostPath) of
- {ok, _R} ->
+ case internal_lookup_vhost_access(User, VHostPath) of
+ ok ->
ok;
not_found ->
rabbit_misc:protocol_error(
@@ -141,17 +128,20 @@ check_vhost_access(#user{username = Username}, VHostPath) ->
[VHostPath, Username])
end.
+internal_lookup_vhost_access(User, VHostPath) ->
+ rabbit_auth_backend_internal:check_vhost_access(User, VHostPath).
+
permission_index(configure) -> #permission.configure;
permission_index(write) -> #permission.write;
permission_index(read) -> #permission.read.
-check_resource_access(Username,
+check_resource_access(User,
R = #resource{kind = exchange, name = <<"">>},
Permission) ->
- check_resource_access(Username,
+ check_resource_access(User,
R#resource{name = <<"amq.default">>},
Permission);
-check_resource_access(Username,
+check_resource_access(_User = #user{username = Username},
R = #resource{virtual_host = VHostPath, name = Name},
Permission) ->
Res = case mnesia:dirty_read({rabbit_user_permission,
@@ -177,17 +167,20 @@ check_resource_access(Username,
[rabbit_misc:rs(R), Username])
end.
+%%----------------------------------------------------------------------------
+
add_user(Username, Password) ->
R = rabbit_misc:execute_mnesia_transaction(
fun () ->
case mnesia:wread({rabbit_user, Username}) of
[] ->
- ok = mnesia:write(rabbit_user,
- #user{username = Username,
- password_hash =
- hash_password(Password),
- is_admin = false},
- write);
+ ok = mnesia:write(
+ rabbit_user,
+ #internal_user{username = Username,
+ password_hash =
+ hash_password(Password),
+ is_admin = false},
+ write);
_ ->
mnesia:abort({user_already_exists, Username})
end
@@ -220,7 +213,8 @@ change_password(Username, Password) ->
change_password_hash(Username, PasswordHash) ->
R = update_user(Username, fun(User) ->
- User#user{ password_hash = PasswordHash }
+ User#internal_user{
+ password_hash = PasswordHash }
end),
rabbit_log:info("Changed password for user ~p~n", [Username]),
R.
@@ -251,7 +245,7 @@ clear_admin(Username) ->
set_admin(Username, IsAdmin) ->
R = update_user(Username, fun(User) ->
- User#user{is_admin = IsAdmin}
+ User#internal_user{is_admin = IsAdmin}
end),
rabbit_log:info("Set user admin flag for user ~p to ~p~n",
[Username, IsAdmin]),
@@ -268,8 +262,8 @@ update_user(Username, Fun) ->
list_users() ->
[{Username, IsAdmin} ||
- #user{username = Username, is_admin = IsAdmin} <-
- mnesia:dirty_match_object(rabbit_user, #user{_ = '_'})].
+ #internal_user{username = Username, is_admin = IsAdmin} <-
+ mnesia:dirty_match_object(rabbit_user, #internal_user{_ = '_'})].
lookup_user(Username) ->
rabbit_misc:dirty_read({rabbit_user, Username}).
diff --git a/src/rabbit_channel.erl b/src/rabbit_channel.erl
index 19613a57ec..bdbb635170 100644
--- a/src/rabbit_channel.erl
+++ b/src/rabbit_channel.erl
@@ -47,7 +47,7 @@
-record(ch, {state, channel, reader_pid, writer_pid, limiter_pid,
start_limiter_fun, transaction_id, tx_participants, next_tag,
uncommitted_ack_q, unacked_message_q,
- username, virtual_host, most_recently_declared_queue,
+ user, virtual_host, most_recently_declared_queue,
consumer_mapping, blocking, queue_collector_pid, stats_timer}).
-define(MAX_PERMISSION_CACHE_SIZE, 12).
@@ -65,7 +65,7 @@
[pid,
connection,
number,
- user,
+ username,
vhost]).
-define(INFO_KEYS, ?CREATION_EVENT_KEYS ++ ?STATISTICS_KEYS -- [pid]).
@@ -79,7 +79,7 @@
-type(channel_number() :: non_neg_integer()).
-spec(start_link/7 ::
- (channel_number(), pid(), pid(), rabbit_access_control:username(),
+ (channel_number(), pid(), pid(), rabbit_access_control:user(),
rabbit_types:vhost(), pid(),
fun ((non_neg_integer()) -> rabbit_types:ok(pid()))) ->
rabbit_types:ok_pid_or_error()).
@@ -104,9 +104,9 @@
%%----------------------------------------------------------------------------
-start_link(Channel, ReaderPid, WriterPid, Username, VHost, CollectorPid,
+start_link(Channel, ReaderPid, WriterPid, User, VHost, CollectorPid,
StartLimiterFun) ->
- gen_server2:start_link(?MODULE, [Channel, ReaderPid, WriterPid, Username,
+ gen_server2:start_link(?MODULE, [Channel, ReaderPid, WriterPid, User,
VHost, CollectorPid, StartLimiterFun], []).
do(Pid, Method) ->
@@ -155,7 +155,7 @@ flush(Pid) ->
%%---------------------------------------------------------------------------
-init([Channel, ReaderPid, WriterPid, Username, VHost, CollectorPid,
+init([Channel, ReaderPid, WriterPid, User, VHost, CollectorPid,
StartLimiterFun]) ->
process_flag(trap_exit, true),
ok = pg_local:join(rabbit_channels, self()),
@@ -171,7 +171,7 @@ init([Channel, ReaderPid, WriterPid, Username, VHost, CollectorPid,
next_tag = 1,
uncommitted_ack_q = queue:new(),
unacked_message_q = queue:new(),
- username = Username,
+ user = User,
virtual_host = VHost,
most_recently_declared_queue = <<>>,
consumer_mapping = dict:new(),
@@ -321,7 +321,7 @@ return_queue_declare_ok(#resource{name = ActualName},
message_count = MessageCount,
consumer_count = ConsumerCount}).
-check_resource_access(Username, Resource, Perm) ->
+check_resource_access(User, Resource, Perm) ->
V = {Resource, Perm},
Cache = case get(permission_cache) of
undefined -> [];
@@ -331,7 +331,7 @@ check_resource_access(Username, Resource, Perm) ->
case lists:member(V, Cache) of
true -> lists:delete(V, Cache);
false -> ok = rabbit_access_control:check_resource_access(
- Username, Resource, Perm),
+ User, Resource, Perm),
lists:sublist(Cache, ?MAX_PERMISSION_CACHE_SIZE - 1)
end,
put(permission_cache, [V | CacheTail]),
@@ -341,14 +341,14 @@ clear_permission_cache() ->
erase(permission_cache),
ok.
-check_configure_permitted(Resource, #ch{username = Username}) ->
- check_resource_access(Username, Resource, configure).
+check_configure_permitted(Resource, #ch{user = User}) ->
+ check_resource_access(User, Resource, configure).
-check_write_permitted(Resource, #ch{username = Username}) ->
- check_resource_access(Username, Resource, write).
+check_write_permitted(Resource, #ch{user = User}) ->
+ check_resource_access(User, Resource, write).
-check_read_permitted(Resource, #ch{username = Username}) ->
- check_resource_access(Username, Resource, read).
+check_read_permitted(Resource, #ch{user = User}) ->
+ check_resource_access(User, Resource, read).
expand_queue_name_shortcut(<<>>, #ch{most_recently_declared_queue = <<>>}) ->
rabbit_misc:protocol_error(
@@ -1150,7 +1150,7 @@ infos(Items, State) -> [{Item, i(Item, State)} || Item <- Items].
i(pid, _) -> self();
i(connection, #ch{reader_pid = ReaderPid}) -> ReaderPid;
i(number, #ch{channel = Channel}) -> Channel;
-i(user, #ch{username = Username}) -> Username;
+i(username, #ch{user = User}) -> User#user.username;
i(vhost, #ch{virtual_host = VHost}) -> VHost;
i(transactional, #ch{transaction_id = TxnKey}) -> TxnKey =/= none;
i(consumer_count, #ch{consumer_mapping = ConsumerMapping}) ->
diff --git a/src/rabbit_channel_sup.erl b/src/rabbit_channel_sup.erl
index 02199a6516..e11f8a3e06 100644
--- a/src/rabbit_channel_sup.erl
+++ b/src/rabbit_channel_sup.erl
@@ -56,7 +56,7 @@
%%----------------------------------------------------------------------------
-start_link({Protocol, Sock, Channel, FrameMax, ReaderPid, Username, VHost,
+start_link({Protocol, Sock, Channel, FrameMax, ReaderPid, User, VHost,
Collector}) ->
{ok, SupPid} = supervisor2:start_link(?MODULE, []),
{ok, WriterPid} =
@@ -69,7 +69,7 @@ start_link({Protocol, Sock, Channel, FrameMax, ReaderPid, Username, VHost,
supervisor2:start_child(
SupPid,
{channel, {rabbit_channel, start_link,
- [Channel, ReaderPid, WriterPid, Username, VHost,
+ [Channel, ReaderPid, WriterPid, User, VHost,
Collector, start_limiter_fun(SupPid)]},
intrinsic, ?MAX_WAIT, worker, [rabbit_channel]}),
{ok, FramingChannelPid} =
diff --git a/src/rabbit_mnesia.erl b/src/rabbit_mnesia.erl
index 9d17226960..7efc2c2185 100644
--- a/src/rabbit_mnesia.erl
+++ b/src/rabbit_mnesia.erl
@@ -153,10 +153,10 @@ nodes_of_type(Type) ->
table_definitions() ->
[{rabbit_user,
- [{record_name, user},
- {attributes, record_info(fields, user)},
+ [{record_name, internal_user},
+ {attributes, record_info(fields, internal_user)},
{disc_copies, [node()]},
- {match, #user{_='_'}}]},
+ {match, #internal_user{_='_'}}]},
{rabbit_user_permission,
[{record_name, user_permission},
{attributes, record_info(fields, user_permission)},
diff --git a/src/rabbit_reader.erl b/src/rabbit_reader.erl
index 23b2ca34e9..cda6fbb13f 100644
--- a/src/rabbit_reader.erl
+++ b/src/rabbit_reader.erl
@@ -975,12 +975,12 @@ send_to_new_channel(Channel, AnalyzedFrame, State) ->
channel_sup_sup_pid = ChanSupSup,
connection = #connection{protocol = Protocol,
frame_max = FrameMax,
- user = #user{username = Username},
+ user = User,
vhost = VHost}} = State,
{ok, ChSupPid, ChFrPid} =
rabbit_channel_sup_sup:start_channel(
ChanSupSup, {Protocol, Sock, Channel, FrameMax,
- self(), Username, VHost, Collector}),
+ self(), User, VHost, Collector}),
erlang:monitor(process, ChSupPid),
put({channel, Channel}, {ch_fr_pid, ChFrPid}),
put({ch_sup_pid, ChSupPid}, {{channel, Channel}, {ch_fr_pid, ChFrPid}}),
diff --git a/src/rabbit_registry.erl b/src/rabbit_registry.erl
index 7a3fcb51e5..ca300e7261 100644
--- a/src/rabbit_registry.erl
+++ b/src/rabbit_registry.erl
@@ -111,7 +111,8 @@ sanity_check_module(ClassModule, Module) ->
end.
class_module(exchange) -> rabbit_exchange_type;
-class_module(auth_mechanism) -> rabbit_auth_mechanism.
+class_module(auth_mechanism) -> rabbit_auth_mechanism;
+class_module(auth_backend) -> rabbit_auth_backend.
%%---------------------------------------------------------------------------
diff --git a/src/rabbit_types.erl b/src/rabbit_types.erl
index b9993823d1..65d766cb3e 100644
--- a/src/rabbit_types.erl
+++ b/src/rabbit_types.erl
@@ -149,10 +149,11 @@
-type(protocol() :: rabbit_framing:protocol()).
--type(user() ::
- #user{username :: rabbit_access_control:username(),
- password_hash :: rabbit_access_control:password_hash(),
- is_admin :: boolean()}).
+%% TODO this is the wrong kind
+-type(user() ::#user{}).
+ %% #user{username :: rabbit_access_control:username(),
+ %% password_hash :: rabbit_access_control:password_hash(),
+ %% is_admin :: boolean()}).
-type(ok(A) :: {'ok', A}).
-type(error(A) :: {'error', A}).