diff options
Diffstat (limited to 'src')
30 files changed, 252 insertions, 153 deletions
diff --git a/src/ejabberd_auth.erl b/src/ejabberd_auth.erl index 0267a219..6b7f537c 100644 --- a/src/ejabberd_auth.erl +++ b/src/ejabberd_auth.erl @@ -136,7 +136,7 @@ check_password(User, AuthzId, Server, Password, Digest, %% {true, AuthModule} | false %% where %% AuthModule = ejabberd_auth_anonymous | ejabberd_auth_external -%% | ejabberd_auth_internal | ejabberd_auth_ldap +%% | ejabberd_auth_mnesia | ejabberd_auth_ldap %% | ejabberd_auth_sql | ejabberd_auth_pam | ejabberd_auth_riak -spec check_password_with_authmodule(binary(), binary(), binary(), binary()) -> false | {true, atom()}. @@ -428,30 +428,21 @@ auth_modules() -> %% Return the list of authenticated modules for a given host auth_modules(Server) -> LServer = jid:nameprep(Server), - Default = case gen_mod:default_db(LServer) of - mnesia -> internal; - DBType -> DBType - end, + Default = ejabberd_config:default_db(LServer, ?MODULE), Methods = ejabberd_config:get_option( - {auth_method, LServer}, - fun(V) when is_list(V) -> - true = lists:all(fun is_atom/1, V), - V; - (V) when is_atom(V) -> - [V] - end, [Default]), + {auth_method, LServer}, opt_type(auth_method), [Default]), [jlib:binary_to_atom(<<"ejabberd_auth_", (jlib:atom_to_binary(M))/binary>>) || M <- Methods]. export(Server) -> - ejabberd_auth_internal:export(Server). + ejabberd_auth_mnesia:export(Server). import(Server) -> - ejabberd_auth_internal:import(Server). + ejabberd_auth_mnesia:import(Server). import(Server, mnesia, Passwd) -> - ejabberd_auth_internal:import(Server, mnesia, Passwd); + ejabberd_auth_mnesia:import(Server, mnesia, Passwd); import(Server, riak, Passwd) -> ejabberd_auth_riak:import(Server, riak, Passwd); import(_, _, _) -> @@ -459,7 +450,7 @@ import(_, _, _) -> opt_type(auth_method) -> fun (V) when is_list(V) -> - true = lists:all(fun is_atom/1, V), V; - (V) when is_atom(V) -> [V] + lists:map(fun(M) -> ejabberd_config:v_db(?MODULE, M) end, V); + (V) -> [ejabberd_config:v_db(?MODULE, V)] end; opt_type(_) -> [auth_method]. diff --git a/src/ejabberd_auth_external.erl b/src/ejabberd_auth_external.erl index 5897fba5..ef7c9755 100644 --- a/src/ejabberd_auth_external.erl +++ b/src/ejabberd_auth_external.erl @@ -56,7 +56,7 @@ start(Host) -> "extauth"), extauth:start(Host, Cmd), check_cache_last_options(Host), - ejabberd_auth_internal:start(Host). + ejabberd_auth_mnesia:start(Host). check_cache_last_options(Server) -> case get_cache_option(Server) of @@ -94,7 +94,7 @@ check_password(User, AuthzId, Server, Password, _Digest, set_password(User, Server, Password) -> case extauth:set_password(User, Server, Password) of true -> - set_password_internal(User, Server, Password), ok; + set_password_mnesia(User, Server, Password), ok; _ -> {error, unknown_problem} end. @@ -106,20 +106,20 @@ try_register(User, Server, Password) -> end. dirty_get_registered_users() -> - ejabberd_auth_internal:dirty_get_registered_users(). + ejabberd_auth_mnesia:dirty_get_registered_users(). get_vh_registered_users(Server) -> - ejabberd_auth_internal:get_vh_registered_users(Server). + ejabberd_auth_mnesia:get_vh_registered_users(Server). get_vh_registered_users(Server, Data) -> - ejabberd_auth_internal:get_vh_registered_users(Server, + ejabberd_auth_mnesia:get_vh_registered_users(Server, Data). get_vh_registered_users_number(Server) -> - ejabberd_auth_internal:get_vh_registered_users_number(Server). + ejabberd_auth_mnesia:get_vh_registered_users_number(Server). get_vh_registered_users_number(Server, Data) -> - ejabberd_auth_internal:get_vh_registered_users_number(Server, + ejabberd_auth_mnesia:get_vh_registered_users_number(Server, Data). %% The password can only be returned if cache is enabled, cached info exists and is fresh enough. @@ -151,7 +151,7 @@ remove_user(User, Server) -> case get_cache_option(Server) of false -> false; {true, _CacheTime} -> - ejabberd_auth_internal:remove_user(User, Server) + ejabberd_auth_mnesia:remove_user(User, Server) end end. @@ -162,7 +162,7 @@ remove_user(User, Server, Password) -> case get_cache_option(Server) of false -> false; {true, _CacheTime} -> - ejabberd_auth_internal:remove_user(User, Server, + ejabberd_auth_mnesia:remove_user(User, Server, Password) end end. @@ -197,7 +197,7 @@ check_password_cache(User, AuthzId, Server, Password, CacheTime) -> case get_last_access(User, Server) of online -> - check_password_internal(User, AuthzId, Server, Password); + check_password_mnesia(User, AuthzId, Server, Password); never -> check_password_external_cache(User, AuthzId, Server, Password); mod_last_required -> @@ -210,7 +210,7 @@ check_password_cache(User, AuthzId, Server, Password, case is_fresh_enough(TimeStamp, CacheTime) of %% If no need to refresh, check password against Mnesia true -> - case check_password_internal(User, AuthzId, Server, Password) of + case check_password_mnesia(User, AuthzId, Server, Password) of %% If password valid in Mnesia, accept it true -> true; %% Else (password nonvalid in Mnesia), check in extauth and cache result @@ -223,13 +223,13 @@ check_password_cache(User, AuthzId, Server, Password, end end. -get_password_internal(User, Server) -> - ejabberd_auth_internal:get_password(User, Server). +get_password_mnesia(User, Server) -> + ejabberd_auth_mnesia:get_password(User, Server). -spec get_password_cache(User::binary(), Server::binary(), CacheTime::integer()) -> Password::string() | false. get_password_cache(User, Server, CacheTime) -> case get_last_access(User, Server) of - online -> get_password_internal(User, Server); + online -> get_password_mnesia(User, Server); never -> false; mod_last_required -> ?ERROR_MSG("extauth is used, extauth_cache is enabled " @@ -239,7 +239,7 @@ get_password_cache(User, Server, CacheTime) -> false; TimeStamp -> case is_fresh_enough(TimeStamp, CacheTime) of - true -> get_password_internal(User, Server); + true -> get_password_mnesia(User, Server); false -> false end end. @@ -248,7 +248,7 @@ get_password_cache(User, Server, CacheTime) -> check_password_external_cache(User, AuthzId, Server, Password) -> case check_password_extauth(User, AuthzId, Server, Password) of true -> - set_password_internal(User, Server, Password), true; + set_password_mnesia(User, Server, Password), true; false -> false end. @@ -256,21 +256,21 @@ check_password_external_cache(User, AuthzId, Server, Password) -> try_register_external_cache(User, Server, Password) -> case try_register_extauth(User, Server, Password) of {atomic, ok} = R -> - set_password_internal(User, Server, Password), R; + set_password_mnesia(User, Server, Password), R; _ -> {error, not_allowed} end. %% @spec (User, AuthzId, Server, Password) -> true | false -check_password_internal(User, AuthzId, Server, Password) -> - ejabberd_auth_internal:check_password(User, AuthzId, Server, +check_password_mnesia(User, AuthzId, Server, Password) -> + ejabberd_auth_mnesia:check_password(User, AuthzId, Server, Password). %% @spec (User, Server, Password) -> ok | {error, invalid_jid} -set_password_internal(User, Server, Password) -> +set_password_mnesia(User, Server, Password) -> %% @spec (TimeLast, CacheTime) -> true | false %% TimeLast = online | never | integer() %% CacheTime = integer() | false - ejabberd_auth_internal:set_password(User, Server, + ejabberd_auth_mnesia:set_password(User, Server, Password). is_fresh_enough(TimeStampLast, CacheTime) -> diff --git a/src/ejabberd_auth_internal.erl b/src/ejabberd_auth_mnesia.erl index acbbfe50..9029404d 100644 --- a/src/ejabberd_auth_internal.erl +++ b/src/ejabberd_auth_mnesia.erl @@ -1,5 +1,5 @@ %%%---------------------------------------------------------------------- -%%% File : ejabberd_auth_internal.erl +%%% File : ejabberd_auth_mnesia.erl %%% Author : Alexey Shchepin <alexey@process-one.net> %%% Purpose : Authentification via mnesia %%% Created : 12 Dec 2004 by Alexey Shchepin <alexey@process-one.net> @@ -23,7 +23,7 @@ %%% %%%---------------------------------------------------------------------- --module(ejabberd_auth_internal). +-module(ejabberd_auth_mnesia). -behaviour(ejabberd_config). diff --git a/src/ejabberd_c2s.erl b/src/ejabberd_c2s.erl index e75cb0ab..10657c45 100644 --- a/src/ejabberd_c2s.erl +++ b/src/ejabberd_c2s.erl @@ -1563,6 +1563,12 @@ handle_info({route, From, To, {true, Attrs, StateData}; deny -> + Err = + jlib:make_error_reply(Packet, + ?ERR_SERVICE_UNAVAILABLE), + ejabberd_router:route(To, + From, + Err), {false, Attrs, StateData} end; diff --git a/src/ejabberd_config.erl b/src/ejabberd_config.erl index f73474fe..06de61b5 100644 --- a/src/ejabberd_config.erl +++ b/src/ejabberd_config.erl @@ -34,8 +34,8 @@ get_vh_by_auth_method/1, is_file_readable/1, get_version/0, get_myhosts/0, get_mylang/0, prepare_opt_val/4, convert_table_to_binary/5, - transform_options/1, collect_options/1, - convert_to_yaml/1, convert_to_yaml/2, + transform_options/1, collect_options/1, default_db/2, + convert_to_yaml/1, convert_to_yaml/2, v_db/2, env_binary_to_list/2, opt_type/1, may_hide_data/1]). -export([start/2]). @@ -227,6 +227,7 @@ get_plain_terms_file(File, Opts) when is_binary(File) -> get_plain_terms_file(binary_to_list(File), Opts); get_plain_terms_file(File1, Opts) -> File = get_absolute_path(File1), + DontStopOnError = lists:member(dont_halt_on_error, Opts), case consult(File) of {ok, Terms} -> BinTerms1 = strings_to_binary(Terms), @@ -246,9 +247,21 @@ get_plain_terms_file(File1, Opts) -> false -> BinTerms end; - {error, Reason} -> + {error, enoent, Reason} -> + case DontStopOnError of + true -> + ?WARNING_MSG(Reason, []), + []; + _ -> ?ERROR_MSG(Reason, []), exit_or_halt(Reason) + end; + {error, Reason} -> + ?ERROR_MSG(Reason, []), + case DontStopOnError of + true -> []; + _ -> exit_or_halt(Reason) + end end. consult(File) -> @@ -262,17 +275,29 @@ consult(File) -> {error, Err} -> Msg1 = "Cannot load " ++ File ++ ": ", Msg2 = fast_yaml:format_error(Err), + case Err of + enoent -> + {error, enoent, Msg1 ++ Msg2}; + _ -> {error, Msg1 ++ Msg2} + end end; _ -> case file:consult(File) of {ok, Terms} -> {ok, Terms}; + {error, enoent} -> + {error, enoent}; {error, {LineNumber, erl_parse, _ParseMessage} = Reason} -> {error, describe_config_problem(File, Reason, LineNumber)}; {error, Reason} -> + case Reason of + enoent -> + {error, enoent, describe_config_problem(File, Reason)}; + _ -> {error, describe_config_problem(File, Reason)} end + end end. parserl(<<"> ", Term/binary>>) -> @@ -488,7 +513,7 @@ transform_include_option({include_config_file, Filename, Options}) -> {Filename, Options}. include_config_file(Filename, Options) -> - Included_terms = get_plain_terms_file(Filename), + Included_terms = get_plain_terms_file(Filename, [{include_files, true}, dont_halt_on_error]), Disallow = proplists:get_value(disallow, Options, []), Included_terms2 = delete_disallowed(Disallow, Included_terms), Allow_only = proplists:get_value(allow_only, Options, all), @@ -651,9 +676,9 @@ process_host_term(Term, Host, State, Action) -> {hosts, _} -> State; {Opt, Val} when Action == set -> - set_option({rename_option(Opt), Host}, Val, State); + set_option({rename_option(Opt), Host}, change_val(Opt, Val), State); {Opt, Val} when Action == append -> - append_option({rename_option(Opt), Host}, Val, State); + append_option({rename_option(Opt), Host}, change_val(Opt, Val), State); Opt -> ?WARNING_MSG("Ignore invalid (outdated?) option ~p", [Opt]), State @@ -672,6 +697,21 @@ rename_option(Option) when is_atom(Option) -> rename_option(Option) -> Option. +change_val(auth_method, Val) -> + prepare_opt_val(auth_method, Val, + fun(V) -> + L = if is_list(V) -> V; + true -> [V] + end, + lists:map( + fun(odbc) -> sql; + (internal) -> mnesia; + (A) when is_atom(A) -> A + end, L) + end, [mnesia]); +change_val(_Opt, Val) -> + Val. + set_option(Opt, Val, State) -> State#state{opts = [#local_config{key = Opt, value = Val} | State#state.opts]}. @@ -738,13 +778,11 @@ prepare_opt_val(Opt, Val, F, Default) -> end, case Res of {'EXIT', _} -> - ?INFO_MSG("Configuration problem:~n" - "** Option: ~s~n" - "** Invalid value: ~s~n" - "** Using as fallback: ~s", - [format_term(Opt), - format_term(Val), - format_term(Default)]), + ?WARNING_MSG("incorrect value '~s' of option '~s', " + "using '~s' as fallback", + [format_term(Val), + format_term(Opt), + format_term(Default)]), Default; _ -> Res @@ -800,9 +838,57 @@ get_option(Opt, F, Default) -> end end. +init_module_db_table(Modules) -> + catch ets:new(module_db, [named_table, public, bag]), + %% Dirty hack for mod_pubsub + ets:insert(module_db, {mod_pubsub, mnesia}), + ets:insert(module_db, {mod_pubsub, sql}), + lists:foreach( + fun(M) -> + case re:split(atom_to_list(M), "_", [{return, list}]) of + [_] -> + ok; + Parts -> + [Suffix|T] = lists:reverse(Parts), + BareMod = string:join(lists:reverse(T), "_"), + ets:insert(module_db, {list_to_atom(BareMod), + list_to_atom(Suffix)}) + end + end, Modules). + +-spec v_db(module(), atom()) -> atom(). + +v_db(Mod, internal) -> v_db(Mod, mnesia); +v_db(Mod, odbc) -> v_db(Mod, sql); +v_db(Mod, Type) -> + case ets:match_object(module_db, {Mod, Type}) of + [_|_] -> Type; + [] -> erlang:error(badarg) + end. + +-spec default_db(binary(), module()) -> atom(). + +default_db(Host, Module) -> + case ejabberd_config:get_option( + {default_db, Host}, fun(T) when is_atom(T) -> T end) of + undefined -> + mnesia; + DBType -> + try + v_db(Module, DBType) + catch error:badarg -> + ?WARNING_MSG("Module '~s' doesn't support database '~s' " + "defined in option 'default_db', using " + "'mnesia' as fallback", [Module, DBType]), + mnesia + end + end. + get_modules_with_options() -> {ok, Mods} = application:get_key(ejabberd, modules), ExtMods = [Name || {Name, _Details} <- ext_mod:installed()], + AllMods = [?MODULE|ExtMods++Mods], + init_module_db_table(AllMods), lists:foldl( fun(Mod, D) -> case catch Mod:opt_type('') of @@ -814,7 +900,7 @@ get_modules_with_options() -> {'EXIT', {undef, _}} -> D end - end, dict:new(), [?MODULE|ExtMods++Mods]). + end, dict:new(), AllMods). validate_opts(#state{opts = Opts} = State) -> ModOpts = get_modules_with_options(), @@ -842,11 +928,25 @@ validate_opts(#state{opts = Opts} = State) -> -spec get_vh_by_auth_method(atom()) -> [binary()]. -%% Return the list of hosts handled by a given module +%% Return the list of hosts with a given auth method get_vh_by_auth_method(AuthMethod) -> - mnesia:dirty_select(local_config, - [{#local_config{key = {auth_method, '$1'}, - value=AuthMethod},[],['$1']}]). + Cfgs = mnesia:dirty_match_object(local_config, + #local_config{key = {auth_method, '_'}, + _ = '_'}), + lists:flatmap( + fun(#local_config{key = {auth_method, Host}, value = M}) -> + Methods = if not is_list(M) -> [M]; + true -> M + end, + case lists:member(AuthMethod, Methods) of + true when Host == global -> + get_myhosts(); + true -> + [Host]; + false -> + [] + end + end, Cfgs). %% @spec (Path::string()) -> true | false is_file_readable(Path) -> diff --git a/src/ejabberd_ctl.erl b/src/ejabberd_ctl.erl index bb16e91e..d52d1c0a 100644 --- a/src/ejabberd_ctl.erl +++ b/src/ejabberd_ctl.erl @@ -239,7 +239,7 @@ process2(["--auth", User, Server, Pass | Args], AccessCommands, Version) -> process2(Args, AccessCommands, {list_to_binary(User), list_to_binary(Server), list_to_binary(Pass), true}, Version); process2(Args, AccessCommands, Version) -> - process2(Args, AccessCommands, admin, Version). + process2(Args, AccessCommands, noauth, Version). diff --git a/src/ejabberd_riak_sup.erl b/src/ejabberd_riak_sup.erl index af811441..ad65ecf8 100644 --- a/src/ejabberd_riak_sup.erl +++ b/src/ejabberd_riak_sup.erl @@ -70,8 +70,8 @@ is_riak_configured(Host) -> {modules, Host}, fun(L) when is_list(L) -> L end, []), ModuleWithRiakDBConfigured = lists:any( - fun({_Module, Opts}) -> - gen_mod:db_type(Host, Opts) == riak + fun({Module, Opts}) -> + gen_mod:db_type(Host, Opts, Module) == riak end, Modules), ServerConfigured or PortConfigured or AuthConfigured or ModuleWithRiakDBConfigured. diff --git a/src/ejabberd_sm.erl b/src/ejabberd_sm.erl index 1fb26a6a..5ee652cc 100644 --- a/src/ejabberd_sm.erl +++ b/src/ejabberd_sm.erl @@ -602,15 +602,12 @@ route_message(From, To, Packet, Type) -> case Type of headline -> ok; _ -> - case ejabberd_auth:is_user_exists(LUser, LServer) of + case ejabberd_auth:is_user_exists(LUser, LServer) andalso + is_privacy_allow(From, To, Packet) of true -> - case is_privacy_allow(From, To, Packet) of - true -> - ejabberd_hooks:run(offline_message_hook, LServer, - [From, To, Packet]); - false -> ok - end; - _ -> + ejabberd_hooks:run(offline_message_hook, LServer, + [From, To, Packet]); + false -> Err = jlib:make_error_reply(Packet, ?ERR_SERVICE_UNAVAILABLE), ejabberd_router:route(To, From, Err) @@ -733,13 +730,10 @@ force_update_presence({LUser, LServer}) -> -spec get_sm_backend(binary()) -> module(). get_sm_backend(Host) -> - DBType = ejabberd_config:get_option({sm_db_type, Host}, - fun(mnesia) -> mnesia; - (internal) -> mnesia; - (odbc) -> sql; - (sql) -> sql; - (redis) -> redis - end, mnesia), + DBType = ejabberd_config:get_option( + {sm_db_type, Host}, + fun(T) -> ejabberd_config:v_db(?MODULE, T) end, + mnesia), list_to_atom("ejabberd_sm_" ++ atom_to_list(DBType)). -spec get_sm_backends() -> [module()]. @@ -812,11 +806,5 @@ kick_user(User, Server) -> make_sid() -> {p1_time_compat:unique_timestamp(), self()}. -opt_type(sm_db_type) -> - fun (mnesia) -> mnesia; - (internal) -> mnesia; - (sql) -> sql; - (odbc) -> sql; - (redis) -> redis - end; +opt_type(sm_db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; opt_type(_) -> [sm_db_type]. diff --git a/src/ejabberd_sql.erl b/src/ejabberd_sql.erl index 4bee08f7..850a7752 100644 --- a/src/ejabberd_sql.erl +++ b/src/ejabberd_sql.erl @@ -1,7 +1,7 @@ %%%---------------------------------------------------------------------- -%%% File : ejabberd_odbc.erl +%%% File : ejabberd_sql.erl %%% Author : Alexey Shchepin <alexey@process-one.net> -%%% Purpose : Serve ODBC connection +%%% Purpose : Serve SQL connection %%% Created : 8 Dec 2004 by Alexey Shchepin <alexey@process-one.net> %%% %%% diff --git a/src/ejd2sql.erl b/src/ejd2sql.erl index aa74286e..0457f6be 100644 --- a/src/ejd2sql.erl +++ b/src/ejd2sql.erl @@ -104,7 +104,7 @@ import_file(Server, FileName) -> LServer = jid:nameprep(Server), Mods = [{Mod, gen_mod:db_type(LServer, Mod)} || Mod <- modules(), gen_mod:is_loaded(LServer, Mod)], - AuthMods = case lists:member(ejabberd_auth_internal, + AuthMods = case lists:member(ejabberd_auth_mnesia, ejabberd_auth:auth_modules(LServer)) of true -> [{ejabberd_auth, mnesia}]; diff --git a/src/gen_mod.erl b/src/gen_mod.erl index 26e662dc..f9639719 100644 --- a/src/gen_mod.erl +++ b/src/gen_mod.erl @@ -31,12 +31,12 @@ -export([start/0, start_module/2, start_module/3, stop_module/2, stop_module_keep_config/2, get_opt/3, - get_opt/4, get_opt_host/3, db_type/1, db_type/2, + get_opt/4, get_opt_host/3, db_type/2, db_type/3, get_module_opt/4, get_module_opt/5, get_module_opt_host/3, loaded_modules/1, loaded_modules_with_opts/1, get_hosts/2, get_module_proc/2, is_loaded/2, start_modules/0, start_modules/1, stop_modules/0, stop_modules/1, - default_db/1, v_db/1, opt_type/1, db_mod/2, db_mod/3]). + opt_type/1, db_mod/2, db_mod/3]). %%-export([behaviour_info/1]). @@ -52,6 +52,7 @@ -callback start(binary(), opts()) -> any(). -callback stop(binary()) -> any(). +-callback mod_opt_type(atom()) -> fun((term()) -> term()) | [atom()]. -export_type([opts/0]). -export_type([db_type/0]). @@ -295,44 +296,46 @@ validate_opts(Module, Opts) -> false end, Opts). --spec v_db(db_type() | internal) -> db_type(). - -v_db(odbc) -> sql; -v_db(sql) -> sql; -v_db(internal) -> mnesia; -v_db(mnesia) -> mnesia; -v_db(riak) -> riak. - --spec db_type(opts()) -> db_type(). - -db_type(Opts) -> - db_type(global, Opts). - --spec db_type(binary() | global, atom() | opts()) -> db_type(). +-spec db_type(binary() | global, module()) -> db_type(); + (opts(), module()) -> db_type(). +db_type(Opts, Module) when is_list(Opts) -> + db_type(global, Opts, Module); db_type(Host, Module) when is_atom(Module) -> - get_module_opt(Host, Module, db_type, fun v_db/1, default_db(Host)); -db_type(Host, Opts) when is_list(Opts) -> - get_opt(db_type, Opts, fun v_db/1, default_db(Host)). - --spec default_db(binary() | global) -> db_type(). + case catch Module:mod_opt_type(db_type) of + F when is_function(F) -> + case get_module_opt(Host, Module, db_type, F) of + undefined -> ejabberd_config:default_db(Host, Module); + Type -> Type + end; + _ -> + undefined + end. -default_db(Host) -> - ejabberd_config:get_option({default_db, Host}, fun v_db/1, mnesia). +-spec db_type(binary(), opts(), module()) -> db_type(). + +db_type(Host, Opts, Module) -> + case catch Module:mod_opt_type(db_type) of + F when is_function(F) -> + case get_opt(db_type, Opts, F) of + undefined -> ejabberd_config:default_db(Host, Module); + Type -> Type + end; + _ -> + undefined + end. -spec db_mod(binary() | global | db_type(), module()) -> module(). -db_mod(odbc, Module) -> list_to_atom(atom_to_list(Module) ++ "_sql"); -db_mod(sql, Module) -> list_to_atom(atom_to_list(Module) ++ "_sql"); -db_mod(mnesia, Module) -> list_to_atom(atom_to_list(Module) ++ "_mnesia"); -db_mod(riak, Module) -> list_to_atom(atom_to_list(Module) ++ "_riak"); +db_mod(Type, Module) when is_atom(Type) -> + list_to_atom(atom_to_list(Module) ++ "_" ++ atom_to_list(Type)); db_mod(Host, Module) when is_binary(Host) orelse Host == global -> db_mod(db_type(Host, Module), Module). -spec db_mod(binary() | global, opts(), module()) -> module(). db_mod(Host, Opts, Module) when is_list(Opts) -> - db_mod(db_type(Host, Opts), Module). + db_mod(db_type(Host, Opts, Module), Module). -spec loaded_modules(binary()) -> [atom()]. @@ -380,6 +383,6 @@ get_module_proc(Host, Base) -> is_loaded(Host, Module) -> ets:member(ejabberd_modules, {Module, Host}). -opt_type(default_db) -> fun v_db/1; +opt_type(default_db) -> fun(T) when is_atom(T) -> T end; opt_type(modules) -> fun (L) when is_list(L) -> L end; opt_type(_) -> [default_db, modules]. diff --git a/src/mod_announce.erl b/src/mod_announce.erl index d7251c50..9a9e665f 100644 --- a/src/mod_announce.erl +++ b/src/mod_announce.erl @@ -921,5 +921,5 @@ import(LServer, DBType, LA) -> mod_opt_type(access) -> fun (A) when is_atom(A) -> A end; -mod_opt_type(db_type) -> fun gen_mod:v_db/1; +mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(_) -> [access, db_type]. diff --git a/src/mod_caps.erl b/src/mod_caps.erl index 3d5c360a..966a9baa 100644 --- a/src/mod_caps.erl +++ b/src/mod_caps.erl @@ -651,6 +651,6 @@ mod_opt_type(cache_life_time) -> fun (I) when is_integer(I), I > 0 -> I end; mod_opt_type(cache_size) -> fun (I) when is_integer(I), I > 0 -> I end; -mod_opt_type(db_type) -> fun gen_mod:v_db/1; +mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(_) -> [cache_life_time, cache_size, db_type]. diff --git a/src/mod_carboncopy.erl b/src/mod_carboncopy.erl index ebf1d0b0..bb20bd2f 100644 --- a/src/mod_carboncopy.erl +++ b/src/mod_carboncopy.erl @@ -279,8 +279,5 @@ list(User, Server) -> Mod:list(User, Server). mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; -mod_opt_type(db_type) -> - fun(internal) -> mnesia; - (mnesia) -> mnesia - end; +mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(_) -> [db_type, iqdisc]. diff --git a/src/mod_irc.erl b/src/mod_irc.erl index e0c658de..f6487a1a 100644 --- a/src/mod_irc.erl +++ b/src/mod_irc.erl @@ -1253,7 +1253,7 @@ import(LServer, DBType, Data) -> mod_opt_type(access) -> fun (A) when is_atom(A) -> A end; -mod_opt_type(db_type) -> fun gen_mod:v_db/1; +mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(default_encoding) -> fun iolist_to_binary/1; mod_opt_type(host) -> fun iolist_to_binary/1; diff --git a/src/mod_last.erl b/src/mod_last.erl index 1af1847b..c39681f6 100644 --- a/src/mod_last.erl +++ b/src/mod_last.erl @@ -244,7 +244,7 @@ transform_options({node_start, {_, _, _} = Now}, Opts) -> transform_options(Opt, Opts) -> [Opt|Opts]. -mod_opt_type(db_type) -> fun gen_mod:v_db/1; +mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; mod_opt_type(_) -> [db_type, iqdisc]. diff --git a/src/mod_mam.erl b/src/mod_mam.erl index f84519a0..12b80c45 100644 --- a/src/mod_mam.erl +++ b/src/mod_mam.erl @@ -812,9 +812,10 @@ select(_LServer, JidRequestor, JidArchive, Start, End, _With, RSM, _ -> {Msgs, true, L} end; -select(LServer, From, From, Start, End, With, RSM, MsgType) -> +select(LServer, JidRequestor, JidArchive, Start, End, With, RSM, MsgType) -> Mod = gen_mod:db_mod(LServer, ?MODULE), - Mod:select(LServer, From, From, Start, End, With, RSM, MsgType). + Mod:select(LServer, JidRequestor, JidArchive, Start, End, With, RSM, + MsgType). msg_to_el(#archive_msg{timestamp = TS, packet = Pkt1, nick = Nick, peer = Peer}, MsgType, JidRequestor, #jid{lserver = LServer} = JidArchive) -> @@ -1017,12 +1018,7 @@ mod_opt_type(cache_life_time) -> fun (I) when is_integer(I), I > 0 -> I end; mod_opt_type(cache_size) -> fun (I) when is_integer(I), I > 0 -> I end; -mod_opt_type(db_type) -> - fun(sql) -> sql; - (odbc) -> sql; - (internal) -> mnesia; - (mnesia) -> mnesia - end; +mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(default) -> fun (always) -> always; (never) -> never; diff --git a/src/mod_metrics.erl b/src/mod_metrics.erl index c175fcb8..40484e48 100644 --- a/src/mod_metrics.erl +++ b/src/mod_metrics.erl @@ -39,7 +39,7 @@ s2s_send_packet, s2s_receive_packet, remove_user, register_user]). --export([start/2, stop/1, send_metrics/4, opt_type/1]). +-export([start/2, stop/1, send_metrics/4, opt_type/1, mod_opt_type/1]). -export([offline_message_hook/3, sm_register_connection_hook/3, sm_remove_connection_hook/3, @@ -126,3 +126,6 @@ send_metrics(Host, Probe, Peer, Port) -> opt_type(_) -> []. + +mod_opt_type(_) -> + []. diff --git a/src/mod_muc.erl b/src/mod_muc.erl index 6aa18631..3d098e0d 100644 --- a/src/mod_muc.erl +++ b/src/mod_muc.erl @@ -932,7 +932,7 @@ mod_opt_type(access_create) -> fun (A) when is_atom(A) -> A end; mod_opt_type(access_persistent) -> fun (A) when is_atom(A) -> A end; -mod_opt_type(db_type) -> fun gen_mod:v_db/1; +mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(default_room_options) -> fun (L) when is_list(L) -> L end; mod_opt_type(history_size) -> diff --git a/src/mod_offline.erl b/src/mod_offline.erl index 356d89a6..4d8aba76 100644 --- a/src/mod_offline.erl +++ b/src/mod_offline.erl @@ -867,7 +867,7 @@ import(LServer, DBType, Data) -> mod_opt_type(access_max_user_messages) -> fun (A) -> A end; -mod_opt_type(db_type) -> fun gen_mod:v_db/1; +mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(store_empty_body) -> fun (V) when is_boolean(V) -> V; (unless_chat_state) -> unless_chat_state diff --git a/src/mod_privacy.erl b/src/mod_privacy.erl index 413dcb52..ad13c27c 100644 --- a/src/mod_privacy.erl +++ b/src/mod_privacy.erl @@ -593,6 +593,6 @@ import(LServer, DBType, Data) -> Mod = gen_mod:db_mod(DBType, ?MODULE), Mod:import(LServer, Data). -mod_opt_type(db_type) -> fun gen_mod:v_db/1; +mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; mod_opt_type(_) -> [db_type, iqdisc]. diff --git a/src/mod_private.erl b/src/mod_private.erl index 029789e6..38e42ca4 100644 --- a/src/mod_private.erl +++ b/src/mod_private.erl @@ -173,6 +173,6 @@ import(LServer, DBType, PD) -> Mod = gen_mod:db_mod(DBType, ?MODULE), Mod:import(LServer, PD). -mod_opt_type(db_type) -> fun gen_mod:v_db/1; +mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; mod_opt_type(_) -> [db_type, iqdisc]. diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl index e42d5c05..35173a4f 100644 --- a/src/mod_pubsub.erl +++ b/src/mod_pubsub.erl @@ -254,10 +254,12 @@ init([ServerHost, Opts]) -> fun(A) when is_integer(A) andalso A >= 0 -> A end, ?MAXITEMS), MaxSubsNode = gen_mod:get_opt(max_subscriptions_node, Opts, fun(A) when is_integer(A) andalso A >= 0 -> A end, undefined), - DefaultNodeCfg = gen_mod:get_opt(default_node_config, Opts, - fun(A) when is_list(A) -> filter_node_options(A) end, []), pubsub_index:init(Host, ServerHost, Opts), {Plugins, NodeTree, PepMapping} = init_plugins(Host, ServerHost, Opts), + DefaultModule = plugin(Host, hd(Plugins)), + BaseOptions = DefaultModule:options(), + DefaultNodeCfg = gen_mod:get_opt(default_node_config, Opts, + fun(A) when is_list(A) -> filter_node_options(A, BaseOptions) end, []), mnesia:create_table(pubsub_last_item, [{ram_copies, [node()]}, {attributes, record_info(fields, pubsub_last_item)}]), @@ -2101,6 +2103,9 @@ subscribe_node(Host, Node, From, JID, Configuration) -> Type = TNode#pubsub_node.type, Options = TNode#pubsub_node.options, send_items(Host, Node, Nidx, Type, Options, Subscriber, last), + ServerHost = serverhost(Host), + ejabberd_hooks:run(pubsub_subscribe_node, ServerHost, + [ServerHost, Host, Node, Subscriber, SubId]), case Result of default -> {result, Reply({subscribed, SubId})}; _ -> {result, Result} @@ -2147,7 +2152,11 @@ unsubscribe_node(Host, Node, From, Subscriber, SubId) -> node_call(Host, Type, unsubscribe_node, [Nidx, From, Subscriber, SubId]) end, case transaction(Host, Node, Action, sync_dirty) of - {result, {_, default}} -> {result, []}; + {result, {_, default}} -> + ServerHost = serverhost(Host), + ejabberd_hooks:run(pubsub_unsubscribe_node, ServerHost, + [ServerHost, Host, Node, Subscriber, SubId]), + {result, []}; % {result, {_, Result}} -> {result, Result}; Error -> Error end. @@ -3163,11 +3172,9 @@ subscription_to_string(_) -> <<"none">>. Host :: mod_pubsub:host()) -> jid() ). -service_jid(Host) -> - case Host of - {U, S, _} -> {jid, U, S, <<>>, U, S, <<>>}; - _ -> {jid, <<>>, Host, <<>>, <<>>, Host, <<>>} - end. +service_jid(#jid{} = Jid) -> Jid; +service_jid({U, S, R}) -> jid:make(U, S, R); +service_jid(Host) -> jid:make(<<>>, Host, <<>>). %% @spec (LJID, NotifyType, Depth, NodeOptions, SubOptions) -> boolean() %% LJID = jid() @@ -3516,7 +3523,7 @@ broadcast_stanza(Host, _Node, _Nidx, _Type, NodeOptions, SubsByDepth, NotifyType end, SubIDsByJID). broadcast_stanza({LUser, LServer, LResource}, Publisher, Node, Nidx, Type, NodeOptions, SubsByDepth, NotifyType, BaseStanza, SHIM) -> - broadcast_stanza({LUser, LServer, LResource}, Node, Nidx, Type, NodeOptions, SubsByDepth, NotifyType, BaseStanza, SHIM), + broadcast_stanza({LUser, LServer, <<>>}, Node, Nidx, Type, NodeOptions, SubsByDepth, NotifyType, BaseStanza, SHIM), %% Handles implicit presence subscriptions SenderResource = user_resource(LUser, LServer, LResource), case ejabberd_sm:get_session_pid(LUser, LServer, SenderResource) of @@ -3680,11 +3687,11 @@ node_plugin_options(Host, Type) -> Result -> Result end. -filter_node_options(Options) -> +filter_node_options(Options, BaseOptions) -> lists:foldl(fun({Key, Val}, Acc) -> DefaultValue = proplists:get_value(Key, Options, Val), [{Key, DefaultValue}|Acc] - end, [], node_flat:options()). + end, [], BaseOptions). node_owners_action(Host, Type, Nidx, []) -> case gen_mod:db_type(serverhost(Host), ?MODULE) of @@ -4468,7 +4475,7 @@ purge_offline(Host, LJID, Node) -> mod_opt_type(access_createnode) -> fun (A) when is_atom(A) -> A end; -mod_opt_type(db_type) -> fun gen_mod:v_db/1; +mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(host) -> fun iolist_to_binary/1; mod_opt_type(ignore_pep_from_offline) -> fun (A) when is_boolean(A) -> A end; diff --git a/src/mod_roster.erl b/src/mod_roster.erl index 16354dd8..b3a627f7 100644 --- a/src/mod_roster.erl +++ b/src/mod_roster.erl @@ -1236,7 +1236,7 @@ import(LServer, DBType, R) -> mod_opt_type(access) -> fun (A) when is_atom(A) -> A end; -mod_opt_type(db_type) -> fun gen_mod:v_db/1; +mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; mod_opt_type(managers) -> fun (B) when is_list(B) -> B end; diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl index 6670cf77..76a619c9 100644 --- a/src/mod_shared_roster.erl +++ b/src/mod_shared_roster.erl @@ -1120,5 +1120,5 @@ import(LServer, DBType, Data) -> Mod = gen_mod:db_mod(DBType, ?MODULE), Mod:import(LServer, Data). -mod_opt_type(db_type) -> fun gen_mod:v_db/1; +mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(_) -> [db_type]. diff --git a/src/mod_vcard.erl b/src/mod_vcard.erl index e5f5d9e3..5e042528 100644 --- a/src/mod_vcard.erl +++ b/src/mod_vcard.erl @@ -596,7 +596,7 @@ import(LServer, DBType, VCard) -> mod_opt_type(allow_return_all) -> fun (B) when is_boolean(B) -> B end; -mod_opt_type(db_type) -> fun gen_mod:v_db/1; +mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(host) -> fun iolist_to_binary/1; mod_opt_type(iqdisc) -> fun gen_iq_handler:check_type/1; mod_opt_type(matches) -> diff --git a/src/mod_vcard_xupdate.erl b/src/mod_vcard_xupdate.erl index 198312c3..041b0b64 100644 --- a/src/mod_vcard_xupdate.erl +++ b/src/mod_vcard_xupdate.erl @@ -133,5 +133,5 @@ import(LServer, DBType, LA) -> Mod = gen_mod:db_mod(DBType, ?MODULE), Mod:import(LServer, LA). -mod_opt_type(db_type) -> fun gen_mod:v_db/1; +mod_opt_type(db_type) -> fun(T) -> ejabberd_config:v_db(?MODULE, T) end; mod_opt_type(_) -> [db_type]. diff --git a/src/mod_vcard_xupdate_riak.erl b/src/mod_vcard_xupdate_riak.erl index 129a0c6a..242485bf 100644 --- a/src/mod_vcard_xupdate_riak.erl +++ b/src/mod_vcard_xupdate_riak.erl @@ -8,6 +8,8 @@ %%%------------------------------------------------------------------- -module(mod_vcard_xupdate_riak). +-behaviour(mod_vcard_xupdate). + %% API -export([init/2, import/2, add_xupdate/3, get_xupdate/2, remove_xupdate/2]). diff --git a/src/mod_vcard_xupdate_sql.erl b/src/mod_vcard_xupdate_sql.erl index 7f0079dd..00bb2950 100644 --- a/src/mod_vcard_xupdate_sql.erl +++ b/src/mod_vcard_xupdate_sql.erl @@ -8,6 +8,8 @@ %%%------------------------------------------------------------------- -module(mod_vcard_xupdate_sql). +-behaviour(mod_vcard_xupdate). + %% API -export([init/2, import/2, add_xupdate/3, get_xupdate/2, remove_xupdate/2, import/1, export/1]). diff --git a/src/shaper.erl b/src/shaper.erl index a136c213..eb82b8fa 100644 --- a/src/shaper.erl +++ b/src/shaper.erl @@ -124,9 +124,13 @@ update(#maxrate{} = State, Size) -> true -> 0 end, NextNow = p1_time_compat:system_time(micro_seconds) + Pause * 1000, + Div = case NextNow - State#maxrate.lasttime of + 0 -> 1; + V -> V + end, {State#maxrate{lastrate = (State#maxrate.lastrate + - 1000000 * Size / (NextNow - State#maxrate.lasttime)) + 1000000 * Size / Div) / 2, lasttime = NextNow}, Pause}. |