summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ejabberd_auth.erl25
-rw-r--r--src/ejabberd_auth_external.erl42
-rw-r--r--src/ejabberd_auth_mnesia.erl (renamed from src/ejabberd_auth_internal.erl)4
-rw-r--r--src/ejabberd_c2s.erl6
-rw-r--r--src/ejabberd_config.erl136
-rw-r--r--src/ejabberd_ctl.erl2
-rw-r--r--src/ejabberd_riak_sup.erl4
-rw-r--r--src/ejabberd_sm.erl32
-rw-r--r--src/ejabberd_sql.erl4
-rw-r--r--src/ejd2sql.erl2
-rw-r--r--src/gen_mod.erl61
-rw-r--r--src/mod_announce.erl2
-rw-r--r--src/mod_caps.erl2
-rw-r--r--src/mod_carboncopy.erl5
-rw-r--r--src/mod_irc.erl2
-rw-r--r--src/mod_last.erl2
-rw-r--r--src/mod_mam.erl12
-rw-r--r--src/mod_metrics.erl5
-rw-r--r--src/mod_muc.erl2
-rw-r--r--src/mod_offline.erl2
-rw-r--r--src/mod_privacy.erl2
-rw-r--r--src/mod_private.erl2
-rw-r--r--src/mod_pubsub.erl31
-rw-r--r--src/mod_roster.erl2
-rw-r--r--src/mod_shared_roster.erl2
-rw-r--r--src/mod_vcard.erl2
-rw-r--r--src/mod_vcard_xupdate.erl2
-rw-r--r--src/mod_vcard_xupdate_riak.erl2
-rw-r--r--src/mod_vcard_xupdate_sql.erl2
-rw-r--r--src/shaper.erl6
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}.