diff options
author | Ben Hood <0x6e6562@gmail.com> | 2008-07-13 19:34:00 +0100 |
---|---|---|
committer | Ben Hood <0x6e6562@gmail.com> | 2008-07-13 19:34:00 +0100 |
commit | ec4276159237469a09902e29a5bf83d41667eb46 (patch) | |
tree | dfef2c6b425f8cd5c72a44a420ad1b9d964dc061 | |
parent | bb63114ae61e50aec7ce8f888ad5b2b673016b9d (diff) | |
download | rabbitmq-server-ec4276159237469a09902e29a5bf83d41667eb46.tar.gz |
Savepoint for lifecycle test that now works without realms or tickets
-rw-r--r-- | ebin/rabbit.app | 1 | ||||
-rw-r--r-- | include/rabbit.hrl | 15 | ||||
-rw-r--r-- | src/rabbit.erl | 18 | ||||
-rw-r--r-- | src/rabbit_access_control.erl | 118 | ||||
-rw-r--r-- | src/rabbit_amqqueue.erl | 36 | ||||
-rw-r--r-- | src/rabbit_channel.erl | 78 | ||||
-rw-r--r-- | src/rabbit_control.erl | 26 | ||||
-rw-r--r-- | src/rabbit_error_logger.erl | 3 | ||||
-rw-r--r-- | src/rabbit_exchange.erl | 19 | ||||
-rw-r--r-- | src/rabbit_misc.erl | 46 | ||||
-rw-r--r-- | src/rabbit_mnesia.erl | 17 | ||||
-rw-r--r-- | src/rabbit_node_monitor.erl | 1 | ||||
-rw-r--r-- | src/rabbit_realm.erl | 316 | ||||
-rw-r--r-- | src/rabbit_ticket.erl | 131 |
14 files changed, 58 insertions, 767 deletions
diff --git a/ebin/rabbit.app b/ebin/rabbit.app index 20d5afcf..730546b4 100644 --- a/ebin/rabbit.app +++ b/ebin/rabbit.app @@ -25,7 +25,6 @@ rabbit_node_monitor, rabbit_persister, rabbit_reader, - rabbit_realm, rabbit_router, rabbit_sup, rabbit_tests, diff --git a/include/rabbit.hrl b/include/rabbit.hrl index d8af670a..f153e7c4 100644 --- a/include/rabbit.hrl +++ b/include/rabbit.hrl @@ -27,12 +27,6 @@ -record(user_vhost, {username, virtual_host}). -record(vhost, {virtual_host, dummy}). --record(vhost_realm, {virtual_host, realm}). - --record(realm, {name, exchanges, queues}). --record(user_realm, {username, realm, ticket_pattern}). - --record(realm_visitor, {realm, pid}). -record(connection, {user, timeout_sec, frame_max, vhost}). @@ -45,8 +39,6 @@ -record(resource, {virtual_host, kind, name}). --record(ticket, {realm_name, passive_flag, active_flag, write_flag, read_flag}). - -record(exchange, {name, type, durable, auto_delete, arguments}). -record(amqqueue, {name, durable, auto_delete, arguments, binding_specs, pid}). @@ -78,18 +70,11 @@ #resource{virtual_host :: vhost(), kind :: Kind, name :: name()}). --type(realm_name() :: r('realm')). -type(queue_name() :: r('queue')). -type(exchange_name() :: r('exchange')). -type(user() :: #user{username :: username(), password :: password()}). --type(ticket() :: - #ticket{realm_name :: realm_name(), - passive_flag :: bool(), - active_flag :: bool(), - write_flag :: bool(), - read_flag :: bool()}). -type(permission() :: 'passive' | 'active' | 'write' | 'read'). -type(binding_spec() :: #binding_spec{exchange_name :: exchange_name(), diff --git a/src/rabbit.erl b/src/rabbit.erl index e65d532b..2c5fd614 100644 --- a/src/rabbit.erl +++ b/src/rabbit.erl @@ -150,10 +150,8 @@ start(normal, []) -> {"recovery", fun () -> ok = maybe_insert_default_data(), - ok = rabbit_exchange:recover(), - ok = rabbit_amqqueue:recover(), - ok = rabbit_realm:recover() + ok = rabbit_amqqueue:recover() end}, {"persister", fun () -> @@ -222,18 +220,8 @@ insert_default_data() -> insert_default_user(Username, Password, VHostSpecs) -> ok = rabbit_access_control:add_user(Username, Password), lists:foreach( - fun ({VHostPath, Realms}) -> - ok = rabbit_access_control:map_user_vhost( - Username, VHostPath), - lists:foreach( - fun (Realm) -> - RealmFullName = - rabbit_misc:r(VHostPath, realm, Realm), - ok = rabbit_access_control:map_user_realm( - Username, - rabbit_access_control:full_ticket( - RealmFullName)) - end, Realms) + fun (VHostPath) -> + ok = rabbit_access_control:map_user_vhost(Username, VHostPath) end, VHostSpecs), ok. diff --git a/src/rabbit_access_control.erl b/src/rabbit_access_control.erl index 2be07b19..0a410991 100644 --- a/src/rabbit_access_control.erl +++ b/src/rabbit_access_control.erl @@ -28,12 +28,11 @@ -include("rabbit.hrl"). -export([check_login/2, user_pass_login/2, - check_vhost_access/2, lookup_realm_access/2]). + check_vhost_access/2]). -export([add_user/2, delete_user/1, change_password/2, list_users/0, lookup_user/1]). -export([add_vhost/1, delete_vhost/1, list_vhosts/0, list_vhost_users/1]). -export([list_user_vhosts/1, map_user_vhost/2, unmap_user_vhost/2]). --export([list_user_realms/2, map_user_realm/2, full_ticket/1]). %%---------------------------------------------------------------------------- @@ -42,7 +41,6 @@ -spec(check_login/2 :: (binary(), binary()) -> user()). -spec(user_pass_login/2 :: (username(), password()) -> user()). -spec(check_vhost_access/2 :: (user(), vhost()) -> 'ok'). --spec(lookup_realm_access/2 :: (user(), realm_name()) -> maybe(ticket())). -spec(add_user/2 :: (username(), password()) -> 'ok'). -spec(delete_user/1 :: (username()) -> 'ok'). -spec(change_password/2 :: (username(), password()) -> 'ok'). @@ -55,9 +53,6 @@ -spec(list_user_vhosts/1 :: (username()) -> [vhost()]). -spec(map_user_vhost/2 :: (username(), vhost()) -> 'ok'). -spec(unmap_user_vhost/2 :: (username(), vhost()) -> 'ok'). --spec(map_user_realm/2 :: (username(), ticket()) -> 'ok'). --spec(list_user_realms/2 :: (username(), vhost()) -> [{name(), ticket()}]). --spec(full_ticket/1 :: (realm_name()) -> ticket()). -endif. @@ -130,18 +125,6 @@ check_vhost_access(#user{username = Username}, VHostPath) -> [VHostPath, Username]) end. -lookup_realm_access(#user{username = Username}, RealmName = #resource{kind = realm}) -> - %% TODO: use dirty ops instead - rabbit_misc:execute_mnesia_transaction( - fun () -> - case user_realms(Username, RealmName) of - [] -> - none; - [#user_realm{ticket_pattern = TicketPattern}] -> - TicketPattern - end - end). - add_user(Username, Password) -> R = rabbit_misc:execute_mnesia_transaction( fun () -> @@ -162,8 +145,7 @@ delete_user(Username) -> Username, fun () -> ok = mnesia:delete({user, Username}), - ok = mnesia:delete({user_vhost, Username}), - ok = mnesia:delete({user_realm, Username}) + ok = mnesia:delete({user_vhost, Username}) end)), rabbit_log:info("Deleted user ~p~n", [Username]), R. @@ -191,24 +173,10 @@ add_vhost(VHostPath) -> case mnesia:read({vhost, VHostPath}) of [] -> ok = mnesia:write(#vhost{virtual_host = VHostPath}), - DataRealm = - rabbit_misc:r(VHostPath, realm, <<"/data">>), - AdminRealm = - rabbit_misc:r(VHostPath, realm, <<"/admin">>), - ok = rabbit_realm:add_realm(DataRealm), - ok = rabbit_realm:add_realm(AdminRealm), - #exchange{} = rabbit_exchange:declare( - DataRealm, <<"">>, - direct, true, false, []), - #exchange{} = rabbit_exchange:declare( - DataRealm, <<"amq.direct">>, - direct, true, false, []), - #exchange{} = rabbit_exchange:declare( - DataRealm, <<"amq.topic">>, - topic, true, false, []), - #exchange{} = rabbit_exchange:declare( - DataRealm, <<"amq.fanout">>, - fanout, true, false, []), + #exchange{} = rabbit_exchange:declare(<<"">>, direct, true, false, []), + #exchange{} = rabbit_exchange:declare(<<"amq.direct">>, direct, true, false, []), + #exchange{} = rabbit_exchange:declare(<<"amq.topic">>, topic, true, false, []), + #exchange{} = rabbit_exchange:declare(<<"amq.fanout">>, fanout, true, false, []), ok; [_] -> mnesia:abort({vhost_already_exists, VHostPath}) @@ -240,11 +208,6 @@ internal_delete_vhost(VHostPath) -> ok = rabbit_exchange:delete(Name, false) end, rabbit_exchange:list_vhost_exchanges(VHostPath)), - lists:foreach(fun (RealmName) -> - ok = rabbit_realm:delete_realm( - rabbit_misc:r(VHostPath, realm, RealmName)) - end, - rabbit_realm:list_vhost_realms(VHostPath)), lists:foreach(fun (Username) -> ok = unmap_user_vhost(Username, VHostPath) end, @@ -290,77 +253,8 @@ unmap_user_vhost(Username, VHostPath) -> rabbit_misc:with_user_and_vhost( Username, VHostPath, fun () -> - lists:foreach(fun mnesia:delete_object/1, - user_realms(Username, - rabbit_misc:r(VHostPath, realm))), ok = mnesia:delete_object( #user_vhost{username = Username, virtual_host = VHostPath}) end)). -map_user_realm(Username, - Ticket = #ticket{realm_name = RealmName = - #resource{virtual_host = VHostPath, - kind = realm}}) -> - rabbit_misc:execute_mnesia_transaction( - rabbit_misc:with_user_and_vhost( - Username, VHostPath, - rabbit_misc:with_realm( - RealmName, - fun () -> - lists:foreach(fun mnesia:delete_object/1, - user_realms(Username, RealmName)), - case internal_lookup_vhost_access(Username, VHostPath) of - {ok, _R} -> - case ticket_liveness(Ticket) of - alive -> - ok = mnesia:write( - #user_realm{username = Username, - realm = RealmName, - ticket_pattern = Ticket}); - dead -> - ok - end; - not_found -> - mnesia:abort(not_mapped_to_vhost) - end - end))). - -list_user_realms(Username, VHostPath) -> - [{Name, Pattern} || - #user_realm{realm = #resource{name = Name}, - ticket_pattern = Pattern} <- - %% TODO: use dirty ops instead - rabbit_misc:execute_mnesia_transaction( - rabbit_misc:with_user_and_vhost( - Username, VHostPath, - fun () -> - case internal_lookup_vhost_access( - Username, VHostPath) of - {ok, _R} -> - user_realms(Username, - rabbit_misc:r(VHostPath, realm)); - not_found -> - mnesia:abort(not_mapped_to_vhost) - end - end))]. - -ticket_liveness(#ticket{passive_flag = false, - active_flag = false, - write_flag = false, - read_flag = false}) -> - dead; -ticket_liveness(_) -> - alive. - -full_ticket(RealmName) -> - #ticket{realm_name = RealmName, - passive_flag = true, - active_flag = true, - write_flag = true, - read_flag = true}. - -user_realms(Username, RealmName) -> - mnesia:match_object(#user_realm{username = Username, - realm = RealmName, - _ = '_'}). diff --git a/src/rabbit_amqqueue.erl b/src/rabbit_amqqueue.erl index 63f043ba..5a9849df 100644 --- a/src/rabbit_amqqueue.erl +++ b/src/rabbit_amqqueue.erl @@ -25,8 +25,8 @@ -module(rabbit_amqqueue). --export([start/0, recover/0, declare/5, delete/3, purge/1, internal_delete/1]). --export([pseudo_queue/3]). +-export([start/0, recover/0, declare/4, delete/3, purge/1, internal_delete/1]). +-export([pseudo_queue/2]). -export([lookup/1, with/2, with_or_die/2, list_vhost_queues/1, stat/1, stat_all/0, deliver/5, redeliver/2, requeue/3, ack/4, commit/2, rollback/2]). @@ -55,7 +55,7 @@ {'error', 'queue_not_found' | 'exchange_not_found'}). -spec(start/0 :: () -> 'ok'). -spec(recover/0 :: () -> 'ok'). --spec(declare/5 :: (realm_name(), name(), bool(), bool(), amqp_table()) -> +-spec(declare/4 :: (name(), bool(), bool(), amqp_table()) -> amqqueue()). -spec(add_binding/4 :: (queue_name(), exchange_name(), routing_key(), amqp_table()) -> @@ -96,7 +96,7 @@ -spec(notify_sent/2 :: (pid(), pid()) -> 'ok'). -spec(internal_delete/1 :: (queue_name()) -> 'ok' | not_found()). -spec(on_node_down/1 :: (node()) -> 'ok'). --spec(pseudo_queue/3 :: (realm_name(), binary(), pid()) -> amqqueue()). +-spec(pseudo_queue/2 :: (binary(), pid()) -> amqqueue()). -endif. @@ -130,9 +130,8 @@ recover_durable_queues() -> ok end). -declare(RealmName, NameBin, Durable, AutoDelete, Args) -> - QName = rabbit_misc:r(RealmName, queue, NameBin), - Q = start_queue_process(#amqqueue{name = QName, +declare(NameBin, Durable, AutoDelete, Args) -> + Q = start_queue_process(#amqqueue{name = NameBin, durable = Durable, auto_delete = AutoDelete, arguments = Args, @@ -140,9 +139,8 @@ declare(RealmName, NameBin, Durable, AutoDelete, Args) -> pid = none}), case rabbit_misc:execute_mnesia_transaction( fun () -> - case mnesia:wread({amqqueue, QName}) of + case mnesia:wread({amqqueue, NameBin}) of [] -> ok = recover_queue(Q), - ok = rabbit_realm:add(RealmName, QName), Q; [ExistingQ] -> ExistingQ end @@ -169,8 +167,8 @@ recover_queue(Q) -> ok = recover_bindings(Q), ok. -default_binding_spec(#resource{virtual_host = VHost, name = Name}) -> - #binding_spec{exchange_name = rabbit_misc:r(VHost, exchange, <<>>), +default_binding_spec(Name) -> + #binding_spec{exchange_name = <<>>, routing_key = Name, arguments = []}. @@ -181,7 +179,7 @@ recover_bindings(Q = #amqqueue{name = QueueName, binding_specs = Specs}) -> end, Specs), ok. -modify_bindings(QueueName, ExchangeName, RoutingKey, Arguments, +modify_bindings(#resource{name = QueueName}, ExchangeName, RoutingKey, Arguments, SpecPresentFun, SpecAbsentFun) -> rabbit_misc:execute_mnesia_transaction( fun () -> @@ -244,6 +242,7 @@ delete_binding(QueueName, ExchangeName, RoutingKey, Arguments) -> lookup(Name) -> rabbit_misc:dirty_read({amqqueue, Name}). +with(#resource{name = Name}, F, E) -> with(Name, F, E); with(Name, F, E) -> case lookup(Name) of {ok, Q} -> rabbit_misc:with_exit_handler(E, fun () -> F(Q) end); @@ -340,7 +339,6 @@ internal_delete(QueueName) -> [Q] -> ok = delete_temp(Q), ok = mnesia:delete({durable_queues, QueueName}), - ok = rabbit_realm:delete_from_all(QueueName), ok end end). @@ -353,12 +351,8 @@ delete_temp(Q = #amqqueue{name = QueueName}) -> ok. delete_queue(Q = #amqqueue{name = QueueName, durable = Durable}) -> - ok = delete_temp(Q), - if - Durable -> ok; - true -> ok = rabbit_realm:delete_from_all(QueueName) - end. - + ok = delete_temp(Q). + on_node_down(Node) -> rabbit_misc:execute_mnesia_transaction( fun () -> @@ -370,8 +364,8 @@ on_node_down(Node) -> node(Pid) == Node])) end). -pseudo_queue(RealmName, NameBin, Pid) -> - #amqqueue{name = rabbit_misc:r(RealmName, queue, NameBin), +pseudo_queue(NameBin, Pid) -> + #amqqueue{name = NameBin, durable = false, auto_delete = false, arguments = [], diff --git a/src/rabbit_channel.erl b/src/rabbit_channel.erl index ec1d1fba..e1a6b4e6 100644 --- a/src/rabbit_channel.erl +++ b/src/rabbit_channel.erl @@ -37,7 +37,7 @@ transaction_id, tx_participants, next_tag, uncommitted_ack_q, unacked_message_q, username, virtual_host, - most_recently_declared_queue, consumer_mapping, next_ticket}). + most_recently_declared_queue, consumer_mapping}). %%---------------------------------------------------------------------------- @@ -94,8 +94,7 @@ init(ProxyPid, [ReaderPid, WriterPid, Username, VHost]) -> username = Username, virtual_host = VHost, most_recently_declared_queue = <<>>, - consumer_mapping = dict:new(), - next_ticket = 101}. + consumer_mapping = dict:new()}. handle_message({method, Method, Content}, State) -> case (catch handle_method(Method, Content, State)) of @@ -140,7 +139,6 @@ handle_message(Other, State) -> terminate(Reason, State = #ch{writer_pid = WriterPid}) -> Res = notify_queues(internal_rollback(State)), - ok = rabbit_realm:leave_realms(self()), case Reason of normal -> ok = Res; _ -> ok @@ -155,8 +153,7 @@ ok_msg(true, _Msg) -> undefined; ok_msg(false, Msg) -> Msg. return_queue_declare_ok(State, NoWait, Q) -> - NewState = State#ch{most_recently_declared_queue = - (Q#amqqueue.name)#resource.name}, + NewState = State#ch{most_recently_declared_queue = Q#amqqueue.name}, case NoWait of true -> {noreply, NewState}; false -> @@ -164,7 +161,7 @@ return_queue_declare_ok(State, NoWait, Q) -> rabbit_misc:with_exit_handler( fun () -> {ok, Q#amqqueue.name, 0, 0} end, fun () -> rabbit_amqqueue:stat(Q) end), - Reply = #'queue.declare_ok'{queue = ActualName#resource.name, + Reply = #'queue.declare_ok'{queue = ActualName, message_count = MessageCount, consumer_count = ConsumerCount}, {reply, Reply, NewState} @@ -195,14 +192,6 @@ die_precondition_failed(Fmt, Params) -> rabbit_misc:protocol_error({false, 406, <<"PRECONDITION_FAILED">>}, Fmt, Params). -check_ticket(TicketNumber, FieldIndex, Name, #ch{ username = Username}) -> - rabbit_ticket:check_ticket(TicketNumber, FieldIndex, Name, Username). - -lookup_ticket(TicketNumber, FieldIndex, - #ch{ username = Username, virtual_host = VHostPath }) -> - rabbit_ticket:lookup_ticket(TicketNumber, FieldIndex, - Username, VHostPath). - %% check that an exchange/queue name does not contain the reserved %% "amq." prefix. %% @@ -235,7 +224,6 @@ handle_method(_Method, _, #ch{state = starting}) -> handle_method(#'channel.close'{}, _, State = #ch{writer_pid = WriterPid}) -> ok = notify_queues(internal_rollback(State)), - ok = rabbit_realm:leave_realms(self()), ok = rabbit_writer:send_command(WriterPid, #'channel.close_ok'{}), ok = rabbit_writer:shutdown(WriterPid), stop; @@ -245,38 +233,8 @@ handle_method(#'access.request'{realm = RealmNameBin, passive = Passive, active = Active, write = Write, - read = Read}, - _, State = #ch{username = Username, - virtual_host = VHostPath, - next_ticket = NextTicket}) -> - RealmName = rabbit_misc:r(VHostPath, realm, RealmNameBin), - Ticket = #ticket{realm_name = RealmName, - passive_flag = Passive, - active_flag = Active, - write_flag = Write, - read_flag = Read}, - case rabbit_realm:access_request(Username, Exclusive, Ticket) of - ok -> - rabbit_ticket:record_ticket(NextTicket, Ticket), - NewState = State#ch{next_ticket = NextTicket + 1}, - {reply, #'access.request_ok'{ticket = NextTicket}, NewState}; - {error, not_found} -> - rabbit_misc:protocol_error( - invalid_path, "no ~s", [rabbit_misc:rs(RealmName)]); - {error, bad_realm_path} -> - %% FIXME: spec bug? access_refused is a soft error, spec requires it to be hard - rabbit_misc:protocol_error( - access_refused, "bad path for ~s", [rabbit_misc:rs(RealmName)]); - {error, resource_locked} -> - rabbit_misc:protocol_error( - resource_locked, "~s is locked", [rabbit_misc:rs(RealmName)]); - {error, access_refused} -> - rabbit_misc:protocol_error( - access_refused, - "~w permissions denied for user '~s' attempting to access ~s", - [rabbit_misc:permission_list(Ticket), - Username, rabbit_misc:rs(RealmName)]) - end; + read = Read},_, State) -> + {reply, #'access.request_ok'{ticket = 1}, State}; handle_method(#'basic.publish'{ticket = TicketNumber, exchange = ExchangeNameBin, @@ -285,7 +243,6 @@ handle_method(#'basic.publish'{ticket = TicketNumber, immediate = Immediate}, Content, State = #ch{ virtual_host = VHostPath}) -> ExchangeName = rabbit_misc:r(VHostPath, exchange, ExchangeNameBin), - check_ticket(TicketNumber, #ticket.write_flag, ExchangeName, State), Exchange = rabbit_exchange:lookup_or_die(ExchangeName), %% We decode the content's properties here because we're almost %% certain to want to look at delivery-mode and priority. @@ -329,7 +286,6 @@ handle_method(#'basic.get'{ticket = TicketNumber, _, State = #ch{ proxy_pid = ProxyPid, writer_pid = WriterPid, next_tag = DeliveryTag }) -> QueueName = expand_queue_name_shortcut(QueueNameBin, State), - check_ticket(TicketNumber, #ticket.read_flag, QueueName, State), case rabbit_amqqueue:with_or_die( QueueName, fun (Q) -> rabbit_amqqueue:basic_get(Q, ProxyPid, NoAck) end) of @@ -365,7 +321,6 @@ handle_method(#'basic.consume'{ticket = TicketNumber, case dict:find(ConsumerTag, ConsumerMapping) of error -> QueueName = expand_queue_name_shortcut(QueueNameBin, State), - check_ticket(TicketNumber, #ticket.read_flag, QueueName, State), ActualConsumerTag = case ConsumerTag of <<>> -> rabbit_misc:binstring_guid("amq.ctag"); @@ -505,8 +460,6 @@ handle_method(#'exchange.declare'{ticket = TicketNumber, nowait = NoWait, arguments = Args}, _, State = #ch{ virtual_host = VHostPath }) -> - #ticket{realm_name = RealmName} = - lookup_ticket(TicketNumber, #ticket.active_flag, State), CheckedType = rabbit_exchange:check_type(TypeNameBin), %% FIXME: clarify spec as per declare wrt differing realms X = case rabbit_exchange:lookup( @@ -514,8 +467,7 @@ handle_method(#'exchange.declare'{ticket = TicketNumber, {ok, FoundX} -> FoundX; {error, not_found} -> ActualNameBin = check_name('exchange', ExchangeNameBin), - rabbit_exchange:declare(RealmName, - ActualNameBin, + rabbit_exchange:declare(ActualNameBin, CheckedType, Durable, AutoDelete, @@ -530,8 +482,6 @@ handle_method(#'exchange.declare'{ticket = TicketNumber, passive = true, nowait = NoWait}, _, State = #ch{ virtual_host = VHostPath }) -> - %% FIXME: spec issue: permit active_flag here as well as passive_flag? - #ticket{} = lookup_ticket(TicketNumber, #ticket.passive_flag, State), ExchangeName = rabbit_misc:r(VHostPath, exchange, ExchangeNameBin), X = rabbit_exchange:lookup_or_die(ExchangeName), ok = rabbit_exchange:assert_type(X, rabbit_exchange:check_type(TypeNameBin)), @@ -543,7 +493,6 @@ handle_method(#'exchange.delete'{ticket = TicketNumber, nowait = NoWait}, _, State = #ch { virtual_host = VHostPath }) -> ExchangeName = rabbit_misc:r(VHostPath, exchange, ExchangeNameBin), - check_ticket(TicketNumber, #ticket.active_flag, ExchangeName, State), case rabbit_exchange:delete(ExchangeName, IfUnused) of {error, not_found} -> rabbit_misc:protocol_error( @@ -565,8 +514,6 @@ handle_method(#'queue.declare'{ticket = TicketNumber, arguments = Args}, _, State = #ch { virtual_host = VHostPath, reader_pid = ReaderPid }) -> - #ticket{realm_name = RealmName} = - lookup_ticket(TicketNumber, #ticket.active_flag, State), %% FIXME: atomic create&claim Finish = fun (Q) -> @@ -597,8 +544,7 @@ handle_method(#'queue.declare'{ticket = TicketNumber, <<>> -> rabbit_misc:binstring_guid("amq.gen"); Other -> check_name('queue', Other) end, - Finish(rabbit_amqqueue:declare(RealmName, - ActualNameBin, + Finish(rabbit_amqqueue:declare(ActualNameBin, Durable, AutoDelete, Args)); @@ -611,7 +557,6 @@ handle_method(#'queue.declare'{ticket = TicketNumber, passive = true, nowait = NoWait}, _, State = #ch{ virtual_host = VHostPath }) -> - #ticket{} = lookup_ticket(TicketNumber, #ticket.passive_flag, State), QueueName = rabbit_misc:r(VHostPath, queue, QueueNameBin), Q = rabbit_amqqueue:with_or_die(QueueName, fun (Q) -> Q end), return_queue_declare_ok(State, NoWait, Q); @@ -624,7 +569,6 @@ handle_method(#'queue.delete'{ticket = TicketNumber, }, _, State) -> QueueName = expand_queue_name_shortcut(QueueNameBin, State), - check_ticket(TicketNumber, #ticket.active_flag, QueueName, State), case rabbit_amqqueue:with_or_die( QueueName, fun (Q) -> rabbit_amqqueue:delete(Q, IfUnused, IfEmpty) end) of @@ -652,14 +596,13 @@ handle_method(#'queue.bind'{ticket = TicketNumber, QueueName = expand_queue_name_shortcut(QueueNameBin, State), ActualRoutingKey = expand_routing_key_shortcut(QueueNameBin, RoutingKey, State), - check_ticket(TicketNumber, #ticket.active_flag, QueueName, State), ExchangeName = rabbit_misc:r(VHostPath, exchange, ExchangeNameBin), case rabbit_amqqueue:add_binding(QueueName, ExchangeName, ActualRoutingKey, Arguments) of - {error, queue_not_found} -> + {error, queue_not_found} -> rabbit_misc:protocol_error( not_found, "no ~s", [rabbit_misc:rs(QueueName)]); - {error, exchange_not_found} -> + {error, exchange_not_found} -> rabbit_misc:protocol_error( not_found, "no ~s", [rabbit_misc:rs(ExchangeName)]); {error, durability_settings_incompatible} -> @@ -675,7 +618,6 @@ handle_method(#'queue.purge'{ticket = TicketNumber, nowait = NoWait}, _, State) -> QueueName = expand_queue_name_shortcut(QueueNameBin, State), - check_ticket(TicketNumber, #ticket.read_flag, QueueName, State), {ok, PurgedMessageCount} = rabbit_amqqueue:with_or_die( QueueName, fun (Q) -> rabbit_amqqueue:purge(Q) end), diff --git a/src/rabbit_control.erl b/src/rabbit_control.erl index ad796b61..9f95df1e 100644 --- a/src/rabbit_control.erl +++ b/src/rabbit_control.erl @@ -198,19 +198,19 @@ action(list_realms, Node, Args = [_VHostPath]) -> io:format("Listing realms for vhost ~p ...", Args), display_list(call(Node, {rabbit_realm, list_vhost_realms, Args})); -action(set_permissions, Node, - [Username, VHostPath, RealmName | Permissions]) -> - io:format("Setting permissions for user ~p, vhost ~p, realm ~p ...", - [Username, VHostPath, RealmName]), - CheckedPermissions = check_permissions(Permissions), - Ticket = #ticket{ - realm_name = realm_rsrc(VHostPath, RealmName), - passive_flag = lists:member(passive, CheckedPermissions), - active_flag = lists:member(active, CheckedPermissions), - write_flag = lists:member(write, CheckedPermissions), - read_flag = lists:member(read, CheckedPermissions)}, - rpc_call(Node, rabbit_access_control, map_user_realm, - [list_to_binary(Username), Ticket]); +% action(set_permissions, Node, +% [Username, VHostPath, RealmName | Permissions]) -> +% io:format("Setting permissions for user ~p, vhost ~p, realm ~p ...", +% [Username, VHostPath, RealmName]), +% CheckedPermissions = check_permissions(Permissions), +% Ticket = #ticket{ +% realm_name = realm_rsrc(VHostPath, RealmName), +% passive_flag = lists:member(passive, CheckedPermissions), +% active_flag = lists:member(active, CheckedPermissions), +% write_flag = lists:member(write, CheckedPermissions), +% read_flag = lists:member(read, CheckedPermissions)}, +% rpc_call(Node, rabbit_access_control, map_user_realm, +% [list_to_binary(Username), Ticket]); action(list_permissions, Node, Args = [_Username, _VHostPath]) -> io:format("Listing permissions for user ~p in vhost ~p ...", Args), diff --git a/src/rabbit_error_logger.erl b/src/rabbit_error_logger.erl index 0ae116bb..5bc538d5 100644 --- a/src/rabbit_error_logger.erl +++ b/src/rabbit_error_logger.erl @@ -34,9 +34,6 @@ init([DefaultVHost]) -> #exchange{} = rabbit_exchange:declare( - #resource{virtual_host = DefaultVHost, - kind = realm, - name = <<"/admin">>}, ?LOG_EXCH_NAME, topic, true, false, []), {ok, #resource{virtual_host = DefaultVHost, diff --git a/src/rabbit_exchange.erl b/src/rabbit_exchange.erl index 113b7878..1fbfcd7e 100644 --- a/src/rabbit_exchange.erl +++ b/src/rabbit_exchange.erl @@ -28,7 +28,7 @@ -include("rabbit.hrl"). -include("rabbit_framing.hrl"). --export([recover/0, declare/6, lookup/1, lookup_or_die/1, +-export([recover/0, declare/5, lookup/1, lookup_or_die/1, list_vhost_exchanges/1, list_exchange_bindings/1, simple_publish/6, simple_publish/3, route/2]). @@ -50,7 +50,7 @@ not_found() | {'error', 'unroutable' | 'not_delivered'}). -spec(recover/0 :: () -> 'ok'). --spec(declare/6 :: (realm_name(), name(), exchange_type(), bool(), bool(), +-spec(declare/5 :: (name(), exchange_type(), bool(), bool(), amqp_table()) -> exchange()). -spec(check_type/1 :: (binary()) -> atom()). -spec(assert_type/2 :: (exchange(), atom()) -> 'ok'). @@ -90,23 +90,21 @@ recover_durable_exchanges() -> end, ok, durable_exchanges) end). -declare(RealmName, NameBin, Type, Durable, AutoDelete, Args) -> - XName = rabbit_misc:r(RealmName, exchange, NameBin), - Exchange = #exchange{name = XName, +declare(NameBin, Type, Durable, AutoDelete, Args) -> + Exchange = #exchange{name = NameBin, type = Type, durable = Durable, auto_delete = AutoDelete, arguments = Args}, rabbit_misc:execute_mnesia_transaction( fun () -> - case mnesia:wread({exchange, XName}) of + case mnesia:wread({exchange, NameBin}) of [] -> ok = mnesia:write(Exchange), if Durable -> ok = mnesia:write( durable_exchanges, Exchange, write); true -> ok end, - ok = rabbit_realm:add(RealmName, XName), Exchange; [ExistingX] -> ExistingX end @@ -217,6 +215,7 @@ delivery_key_for_type(fanout, Name, _RoutingKey) -> delivery_key_for_type(_Type, Name, RoutingKey) -> {Name, RoutingKey}. +call_with_exchange(#resource{name = Name}, Fun) -> call_with_exchange(Name, Fun); call_with_exchange(Name, Fun) -> case mnesia:wread({exchange, Name}) of [] -> {error, not_found}; @@ -290,7 +289,7 @@ add_handler_to_binding(BindingKey, Handler) -> ok = mnesia:write( B#binding{handlers = extend_handlers(H, Handler)}) end. - + %% Must run within a transaction. remove_handler_from_binding(BindingKey, Handler) -> case mnesia:wread({binding, BindingKey}) of @@ -334,6 +333,7 @@ last_topic_match(P, R, []) -> last_topic_match(P, R, [BacktrackNext | BacktrackList]) -> topic_matches1(P, R) or last_topic_match(P, [BacktrackNext | R], BacktrackList). +delete(#resource{name = ExchangeName}, IfUnused) -> delete(ExchangeName, IfUnused); delete(ExchangeName, IfUnused) -> rabbit_misc:execute_mnesia_transaction( fun () -> internal_delete(ExchangeName, IfUnused) end). @@ -375,6 +375,5 @@ do_internal_delete(ExchangeName, Bindings) -> ok = mnesia:delete({binding, K}) end, Bindings), ok = mnesia:delete({durable_exchanges, ExchangeName}), - ok = mnesia:delete({exchange, ExchangeName}), - ok = rabbit_realm:delete_from_all(ExchangeName) + ok = mnesia:delete({exchange, ExchangeName}) end. diff --git a/src/rabbit_misc.erl b/src/rabbit_misc.erl index 927d7712..259dc0d8 100644 --- a/src/rabbit_misc.erl +++ b/src/rabbit_misc.erl @@ -29,14 +29,12 @@ -export([method_record_type/1, polite_pause/0, polite_pause/1]). -export([die/1, frame_error/2, protocol_error/3, protocol_error/4]). --export([strict_ticket_checking/0]). -export([get_config/1, get_config/2, set_config/2]). -export([dirty_read/1]). -export([r/3, r/2, rs/1]). --export([permission_list/1]). -export([enable_cover/0, report_cover/0]). -export([with_exit_handler/2]). --export([with_user/2, with_vhost/2, with_realm/2, with_user_and_vhost/3]). +-export([with_user/2, with_vhost/2, with_user_and_vhost/3]). -export([execute_mnesia_transaction/1]). -export([ensure_ok/2]). -export([localnode/1, tcp_name/3]). @@ -64,25 +62,20 @@ (atom() | amqp_error(), string(), [any()]) -> no_return()). -spec(protocol_error/4 :: (atom() | amqp_error(), string(), [any()], atom()) -> no_return()). --spec(strict_ticket_checking/0 :: () -> bool()). -spec(get_config/1 :: (atom()) -> {'ok', any()} | not_found()). -spec(get_config/2 :: (atom(), A) -> A). -spec(set_config/2 :: (atom(), any()) -> 'ok'). -spec(dirty_read/1 :: ({atom(), any()}) -> {'ok', any()} | not_found()). --spec(r/3 :: (realm_name() | vhost(), K, name()) -> - r(K) when is_subtype(K, atom())). -spec(r/2 :: (vhost(), K) -> #resource{virtual_host :: vhost(), kind :: K, name :: '_'} when is_subtype(K, atom())). --spec(rs/1 :: (r(atom())) -> string()). --spec(permission_list/1 :: (ticket()) -> [permission()]). +-spec(rs/1 :: (r(atom())) -> string()). -spec(enable_cover/0 :: () -> 'ok' | {'error', any()}). -spec(report_cover/0 :: () -> 'ok'). -spec(with_exit_handler/2 :: (thunk(A), thunk(A)) -> A). -spec(with_user/2 :: (username(), thunk(A)) -> A). -spec(with_vhost/2 :: (vhost(), thunk(A)) -> A). --spec(with_realm/2 :: (realm_name(), thunk(A)) -> A). -spec(with_user_and_vhost/3 :: (username(), vhost(), thunk(A)) -> A). -spec(execute_mnesia_transaction/1 :: (thunk(A)) -> A). -spec(ensure_ok/2 :: ('ok' | {'error', any()}, atom()) -> 'ok'). @@ -143,9 +136,6 @@ boolean_config_param(Name, TrueValue, FalseValue, DefaultValue) -> DefaultValue == TrueValue end. -strict_ticket_checking() -> - boolean_config_param(strict_ticket_checking, enabled, disabled, disabled). - get_config(Key) -> case dirty_read({rabbit_config, Key}) of {ok, {rabbit_config, Key, V}} -> {ok, V}; @@ -180,19 +170,6 @@ rs(#resource{virtual_host = VHostPath, kind = Kind, name = Name}) -> lists:flatten(io_lib:format("~s '~s' in vhost '~s'", [Kind, Name, VHostPath])). -permission_list(Ticket = #ticket{}) -> - lists:foldr(fun ({Field, Label}, L) -> - case element(Field, Ticket) of - true -> [Label | L]; - false -> L - end - end, - [], - [{#ticket.passive_flag, passive}, - {#ticket.active_flag, active}, - {#ticket.write_flag, write}, - {#ticket.read_flag, read}]). - enable_cover() -> case cover:compile_beam_directory("ebin") of {error,Reason} -> {error,Reason}; @@ -258,25 +235,6 @@ with_vhost(VHostPath, Thunk) -> end end. -with_realm(Name = #resource{virtual_host = VHostPath, kind = realm}, - Thunk) -> - fun () -> - case mnesia:read({realm, Name}) of - [] -> - mnesia:abort({no_such_realm, Name}); - [_R] -> - case mnesia:match_object( - #vhost_realm{virtual_host = VHostPath, - realm = Name}) of - [] -> - %% This should never happen - mnesia:abort({no_such_realm, Name}); - [_VR] -> - Thunk() - end - end - end. - with_user_and_vhost(Username, VHostPath, Thunk) -> with_user(Username, with_vhost(VHostPath, Thunk)). diff --git a/src/rabbit_mnesia.erl b/src/rabbit_mnesia.erl index 82b80cb4..b1ab3da2 100644 --- a/src/rabbit_mnesia.erl +++ b/src/rabbit_mnesia.erl @@ -102,23 +102,6 @@ table_definitions() -> {index, [virtual_host]}]}, {vhost, [{disc_copies, [node()]}, {attributes, record_info(fields, vhost)}]}, - {vhost_realm, [{type, bag}, - {disc_copies, [node()]}, - {attributes, record_info(fields, vhost_realm)}, - {index, [realm]}]}, - {realm, [{disc_copies, [node()]}, - {attributes, record_info(fields, realm)}]}, - {user_realm, [{type, bag}, - {disc_copies, [node()]}, - {attributes, record_info(fields, user_realm)}, - {index, [realm]}]}, - {exclusive_realm_visitor, - [{record_name, realm_visitor}, - {attributes, record_info(fields, realm_visitor)}, - {index, [pid]}]}, - {realm_visitor, [{type, bag}, - {attributes, record_info(fields, realm_visitor)}, - {index, [pid]}]}, {rabbit_config, [{disc_copies, [node()]}]}, {listener, [{type, bag}, {attributes, record_info(fields, listener)}]}, diff --git a/src/rabbit_node_monitor.erl b/src/rabbit_node_monitor.erl index beef5285..2fb582a9 100644 --- a/src/rabbit_node_monitor.erl +++ b/src/rabbit_node_monitor.erl @@ -60,7 +60,6 @@ handle_info({nodedown, Node}, State) -> %% lots of nodes. We really only need to execute this code on %% *one* node, rather than all of them. ok = rabbit_networking:on_node_down(Node), - ok = rabbit_realm:on_node_down(Node), ok = rabbit_amqqueue:on_node_down(Node), {noreply, State}; handle_info(_Info, State) -> diff --git a/src/rabbit_realm.erl b/src/rabbit_realm.erl deleted file mode 100644 index 4463954d..00000000 --- a/src/rabbit_realm.erl +++ /dev/null @@ -1,316 +0,0 @@ -%% The contents of this file are subject to the Mozilla Public License -%% Version 1.1 (the "License"); you may not use this file except in -%% compliance with the License. You may obtain a copy of the License at -%% http://www.mozilla.org/MPL/ -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -%% License for the specific language governing rights and limitations -%% under the License. -%% -%% The Original Code is RabbitMQ. -%% -%% The Initial Developers of the Original Code are LShift Ltd., -%% Cohesive Financial Technologies LLC., and Rabbit Technologies Ltd. -%% -%% Portions created by LShift Ltd., Cohesive Financial Technologies -%% LLC., and Rabbit Technologies Ltd. are Copyright (C) 2007-2008 -%% LShift Ltd., Cohesive Financial Technologies LLC., and Rabbit -%% Technologies Ltd.; -%% -%% All Rights Reserved. -%% -%% Contributor(s): ______________________________________. -%% - --module(rabbit_realm). - --export([recover/0]). --export([add_realm/1, delete_realm/1, list_vhost_realms/1]). --export([add/2, delete/2, check/2, delete_from_all/1]). --export([access_request/3, enter_realm/3, leave_realms/1]). --export([on_node_down/1]). - --include("rabbit.hrl"). --include_lib("stdlib/include/qlc.hrl"). - -%%---------------------------------------------------------------------------- - --ifdef(use_specs). - --type(e_or_q() :: 'exchange' | 'queue'). - --spec(recover/0 :: () -> 'ok'). --spec(add_realm/1 :: (realm_name()) -> 'ok'). --spec(delete_realm/1 :: (realm_name()) -> 'ok'). --spec(list_vhost_realms/1 :: (vhost()) -> [name()]). --spec(add/2 :: (realm_name(), r(e_or_q())) -> 'ok'). --spec(delete/2 :: (realm_name(), r(e_or_q())) -> 'ok'). --spec(check/2 :: (realm_name(), r(e_or_q())) -> bool() | not_found()). --spec(delete_from_all/1 :: (r(e_or_q())) -> 'ok'). --spec(access_request/3 :: (username(), bool(), ticket()) -> - 'ok' | not_found() | {'error', 'bad_realm_path' | - 'access_refused' | - 'resource_locked'}). --spec(enter_realm/3 :: (realm_name(), bool(), pid()) -> - 'ok' | {'error', 'resource_locked'}). --spec(leave_realms/1 :: (pid()) -> 'ok'). --spec(on_node_down/1 :: (node()) -> 'ok'). - --endif. - -%%-------------------------------------------------------------------- - -recover() -> - %% preens resource lists, limiting them to currently-extant resources - rabbit_misc:execute_mnesia_transaction( - fun () -> - Realms = mnesia:foldl(fun preen_realm/2, [], realm), - lists:foreach(fun mnesia:write/1, Realms), - ok - end). - -add_realm(Name = #resource{virtual_host = VHostPath, kind = realm}) -> - rabbit_misc:execute_mnesia_transaction( - rabbit_misc:with_vhost( - VHostPath, - fun () -> - case mnesia:read({realm, Name}) of - [] -> - NewRealm = #realm{name = Name, - exchanges = ordsets:new(), - queues = ordsets:new()}, - ok = mnesia:write(NewRealm), - ok = mnesia:write( - #vhost_realm{virtual_host = VHostPath, - realm = Name}), - ok; - [_R] -> - mnesia:abort({realm_already_exists, Name}) - end - end)). - -delete_realm(Name = #resource{virtual_host = VHostPath, kind = realm}) -> - rabbit_misc:execute_mnesia_transaction( - rabbit_misc:with_vhost( - VHostPath, - rabbit_misc:with_realm( - Name, - fun () -> - ok = mnesia:delete({realm, Name}), - ok = mnesia:delete_object( - #vhost_realm{virtual_host = VHostPath, - realm = Name}), - lists:foreach(fun mnesia:delete_object/1, - mnesia:index_read(user_realm, Name, - #user_realm.realm)), - ok - end))). - -list_vhost_realms(VHostPath) -> - [Name || - #vhost_realm{realm = #resource{name = Name}} <- - %% TODO: use dirty ops instead - rabbit_misc:execute_mnesia_transaction( - rabbit_misc:with_vhost( - VHostPath, - fun () -> mnesia:read({vhost_realm, VHostPath}) end))]. - -add(Name = #resource{kind = realm}, Resource) -> - internal_update_realm_byname(Name, Resource, fun ordsets:add_element/2). - -delete(Name = #resource{kind = realm}, Resource) -> - internal_update_realm_byname(Name, Resource, fun ordsets:del_element/2). - -check(Name = #resource{kind = realm}, Resource = #resource{kind = Kind}) -> - case rabbit_misc:dirty_read({realm, Name}) of - {ok, R} -> - case Kind of - exchange -> ordsets:is_element(Resource, R#realm.exchanges); - queue -> ordsets:is_element(Resource, R#realm.queues) - end; - Other -> Other - end. - -% Requires a mnesia transaction. -delete_from_all(Resource = #resource{kind = Kind}) -> - Realms = mnesia:foldl - (fun (Realm = #realm{exchanges = E0, - queues = Q0}, - Acc) -> - IsMember = lists:member(Resource, - case Kind of - exchange -> E0; - queue -> Q0 - end), - if - IsMember -> - [internal_update_realm_record( - Realm, Resource, - fun ordsets:del_element/2) - | Acc]; - true -> - Acc - end - end, [], realm), - lists:foreach(fun mnesia:write/1, Realms), - ok. - -access_request(Username, Exclusive, Ticket = #ticket{realm_name = RealmName}) - when is_binary(Username) -> - %% FIXME: We should do this all in a single tx. Otherwise we may - %% a) get weird answers, b) create inconsistencies in the db - %% (e.g. realm_visitor records referring to non-existing realms). - case check_and_lookup(RealmName) of - {error, Reason} -> - {error, Reason}; - {ok, _Realm} -> - {ok, U} = rabbit_access_control:lookup_user(Username), - case rabbit_access_control:lookup_realm_access(U, RealmName) of - none -> - {error, access_refused}; - TicketPattern -> - case match_ticket(TicketPattern, Ticket) of - no_match -> - {error, access_refused}; - match -> - enter_realm(RealmName, Exclusive, self()) - end - end - end. - -enter_realm(Name = #resource{kind = realm}, IsExclusive, Pid) -> - RealmVisitor = #realm_visitor{realm = Name, pid = Pid}, - rabbit_misc:execute_mnesia_transaction( - fun () -> - case mnesia:read({exclusive_realm_visitor, Name}) of - [] when IsExclusive -> - ok = mnesia:delete_object(RealmVisitor), - %% TODO: find a more efficient way of checking - %% for "no machting results" that doesn't - %% involve retrieving all the records - case mnesia:read({realm_visitor, Name}) of - [] -> - mnesia:write( - exclusive_realm_visitor, RealmVisitor, write), - ok; - [_|_] -> - {error, resource_locked} - end; - [] -> - ok = mnesia:write(RealmVisitor), - ok; - [RealmVisitor] when IsExclusive -> ok; - [RealmVisitor] -> - ok = mnesia:delete({exclusive_realm_visitor, Name}), - ok = mnesia:write(RealmVisitor), - ok; - [_] -> - {error, resource_locked} - end - end). - -leave_realms(Pid) -> - rabbit_misc:execute_mnesia_transaction( - fun () -> - case mnesia:index_read(exclusive_realm_visitor, Pid, - #realm_visitor.pid) of - [] -> ok; - [R] -> - ok = mnesia:delete_object( - exclusive_realm_visitor, R, write) - end, - lists:foreach(fun mnesia:delete_object/1, - mnesia:index_read(realm_visitor, Pid, - #realm_visitor.pid)), - ok - end). - -on_node_down(Node) -> - rabbit_misc:execute_mnesia_transaction( - fun () -> - lists:foreach( - fun (T) -> ok = remove_visitors(Node, T) end, - [exclusive_realm_visitor, realm_visitor]), - ok - end). - -%%-------------------------------------------------------------------- - -preen_realm(Realm = #realm{name = #resource{kind = realm}, - exchanges = E0, - queues = Q0}, - Realms) -> - [Realm#realm{exchanges = filter_out_missing(E0, exchange), - queues = filter_out_missing(Q0, amqqueue)} - | Realms]. - -filter_out_missing(Items, TableName) -> - ordsets:filter(fun (Item) -> - case mnesia:read({TableName, Item}) of - [] -> false; - _ -> true - end - end, Items). - -internal_update_realm_byname(Name, Resource, SetUpdater) -> - rabbit_misc:execute_mnesia_transaction( - fun () -> - case mnesia:read({realm, Name}) of - [] -> - mnesia:abort(not_found); - [R] -> - ok = mnesia:write(internal_update_realm_record - (R, Resource, SetUpdater)) - end - end). - -internal_update_realm_record(R = #realm{exchanges = E0, queues = Q0}, - Resource = #resource{kind = Kind}, - SetUpdater) -> - case Kind of - exchange -> R#realm{exchanges = SetUpdater(Resource, E0)}; - queue -> R#realm{queues = SetUpdater(Resource, Q0)} - end. - -check_and_lookup(RealmName = #resource{kind = realm, - name = <<"/data", _/binary>>}) -> - lookup(RealmName); -check_and_lookup(RealmName = #resource{kind = realm, - name = <<"/admin", _/binary>>}) -> - lookup(RealmName); -check_and_lookup(_) -> - {error, bad_realm_path}. - -lookup(Name = #resource{kind = realm}) -> - rabbit_misc:dirty_read({realm, Name}). - -match_ticket(#ticket{passive_flag = PP, - active_flag = PA, - write_flag = PW, - read_flag = PR}, - #ticket{passive_flag = TP, - active_flag = TA, - write_flag = TW, - read_flag = TR}) -> - if - %% Matches if either we're not requesting passive access, or - %% passive access is permitted, and ... - (not(TP) orelse PP) andalso - (not(TA) orelse PA) andalso - (not(TW) orelse PW) andalso - (not(TR) orelse PR) -> - match; - true -> - no_match - end. - -remove_visitors(Node, T) -> - qlc:fold( - fun (R, Acc) -> - ok = mnesia:delete_object(T, R, write), - Acc - end, - ok, - qlc:q([R || R = #realm_visitor{pid = Pid} <- mnesia:table(T), - node(Pid) == Node])). diff --git a/src/rabbit_ticket.erl b/src/rabbit_ticket.erl deleted file mode 100644 index 3a608faa..00000000 --- a/src/rabbit_ticket.erl +++ /dev/null @@ -1,131 +0,0 @@ -%% The contents of this file are subject to the Mozilla Public License -%% Version 1.1 (the "License"); you may not use this file except in -%% compliance with the License. You may obtain a copy of the License at -%% http://www.mozilla.org/MPL/ -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the -%% License for the specific language governing rights and limitations -%% under the License. -%% -%% The Original Code is RabbitMQ. -%% -%% The Initial Developers of the Original Code are LShift Ltd., -%% Cohesive Financial Technologies LLC., and Rabbit Technologies Ltd. -%% -%% Portions created by LShift Ltd., Cohesive Financial Technologies -%% LLC., and Rabbit Technologies Ltd. are Copyright (C) 2007-2008 -%% LShift Ltd., Cohesive Financial Technologies LLC., and Rabbit -%% Technologies Ltd.; -%% -%% All Rights Reserved. -%% -%% Contributor(s): ______________________________________. -%% - --module(rabbit_ticket). --include("rabbit.hrl"). - --export([record_ticket/2, lookup_ticket/4, check_ticket/4]). - --import(application). - -%%---------------------------------------------------------------------------- - --ifdef(use_specs). - --type(ticket_number() :: non_neg_integer()). -%% we'd like to write #ticket.passive_flag | #ticket.active_flag | ... -%% but dialyzer doesn't support that. --type(ticket_field() :: 3..6). - --spec(record_ticket/2 :: (ticket_number(), ticket()) -> 'ok'). --spec(lookup_ticket/4 :: - (ticket_number(), ticket_field(), username(), vhost()) -> - ticket()). --spec(check_ticket/4 :: - (ticket_number(), ticket_field(), r('exchange' | 'queue'), username()) -> - 'ok'). - --endif. - -%%---------------------------------------------------------------------------- - -record_ticket(TicketNumber, Ticket) -> - put({ticket, TicketNumber}, Ticket), - ok. - -lookup_ticket(TicketNumber, FieldIndex, Username, VHostPath) -> - case get({ticket, TicketNumber}) of - undefined -> - %% Spec: "The server MUST isolate access tickets per - %% channel and treat an attempt by a client to mix these - %% as a connection exception." - rabbit_log:warning("Attempt by client to use invalid ticket ~p~n", [TicketNumber]), - maybe_relax_checks(TicketNumber, Username, VHostPath); - Ticket = #ticket{} -> - case element(FieldIndex, Ticket) of - false -> rabbit_misc:protocol_error( - access_refused, - "ticket ~w has insufficient permissions", - [TicketNumber]); - true -> Ticket - end - end. - -maybe_relax_checks(TicketNumber, Username, VHostPath) -> - case rabbit_misc:strict_ticket_checking() of - true -> - rabbit_misc:protocol_error( - access_refused, "invalid ticket ~w", [TicketNumber]); - false -> - rabbit_log:warning("Lax ticket check mode: fabricating full ticket ~p for user ~p, vhost ~p~n", - [TicketNumber, Username, VHostPath]), - Ticket = rabbit_access_control:full_ticket( - rabbit_misc:r(VHostPath, realm, <<"/data">>)), - case rabbit_realm:access_request(Username, false, Ticket) of - ok -> record_ticket(TicketNumber, Ticket), - Ticket; - {error, Reason} -> - rabbit_misc:protocol_error( - Reason, - "fabrication of ticket ~w for user '~s' in vhost '~s' failed", - [TicketNumber, Username, VHostPath]) - end - end. - -check_ticket(TicketNumber, FieldIndex, - Name = #resource{virtual_host = VHostPath}, Username) -> - #ticket{realm_name = RealmName} = - lookup_ticket(TicketNumber, FieldIndex, Username, VHostPath), - case resource_in_realm(RealmName, Name) of - false -> - case rabbit_misc:strict_ticket_checking() of - true -> - rabbit_misc:protocol_error( - access_refused, - "insufficient permissions in ticket ~w to access ~s in ~s", - [TicketNumber, rabbit_misc:rs(Name), - rabbit_misc:rs(RealmName)]); - false -> - rabbit_log:warning("Lax ticket check mode: ignoring cross-realm access for ticket ~p~n", [TicketNumber]), - ok - end; - true -> - ok - end. - -resource_in_realm(RealmName, ResourceName = #resource{kind = Kind}) -> - CacheKey = {resource_cache, RealmName, Kind}, - case get(CacheKey) of - Name when Name == ResourceName -> - true; - _ -> - case rabbit_realm:check(RealmName, ResourceName) of - true -> - put(CacheKey, ResourceName), - true; - _ -> - false - end - end. |