*** empty log message ***

SVN Revision: 55
This commit is contained in:
Alexey Shchepin 2003-02-01 20:21:28 +00:00
parent 45abdd240c
commit 6599d1ecc5
20 changed files with 678 additions and 232 deletions

View File

@ -101,6 +101,14 @@ database, and in next time they will be APPENDED to existing values. E. g.
if this file will not contain ``host'' definition, then old value will be
used.<BR>
<BR>
To override old values following lines can be added in config:
<PRE>
override_global.
override_local.
override_acls.
</PRE>With this lines old global or local options or ACLs will be removed before
adding new ones.<BR>
<BR>
<!--TOC subsubsection Host Name-->
<H4>3.1.1&nbsp;&nbsp; Host Name</H4><!--SEC END -->
@ -109,42 +117,9 @@ used.<BR>
serves. E.&nbsp;g. to use <TT>jabber.org</TT> domain add following line in config:
<PRE>
{host, "jabber.org"}.
</PRE><!--TOC subsubsection Listened Sockets-->
<H4>3.1.2&nbsp;&nbsp; Listened Sockets</H4><!--SEC END -->
<A NAME="sec:configlistened"></A>Option <TT>listen</TT> defines list of listened sockets and what services
runned on them. Each element of list is a tuple with following elements:
<UL>
<LI>
Port number;
<LI> Module that serves this port;
<LI> Function in this module that starts connection (likely will be removed);
<LI> Options to this module.
</UL>Currently three modules implemented:
<UL>
<LI>
<TT>ejabberd_c2s</TT>: serves C2S connections;
<LI> <TT>ejabberd_s2s_in</TT>: serves incoming S2S connections;
<LI> <TT>ejabberd_service</TT>: serves connections to Jabber services
(i.&nbsp;e. that use <TT>jabber:component:accept</TT> namespace).
</UL>For example, following configuration defines that C2S connections listened on
port 5222, S2S on port 5269 and that service <TT>conference.jabber.org</TT>
must be connected to port 8888 with password ``<TT>secret</TT>''.<BR>
<BR>
<PRE>
{listen, [{5222, ejabberd_c2s, start, []},
{5269, ejabberd_s2s_in, start, []},
{8888, ejabberd_service, start, ["conference.jabber.org", "secret"]}
]}.
</PRE><!--TOC subsubsection Access Rules-->
<H4>3.1.3&nbsp;&nbsp; Access Rules</H4><!--SEC END -->
<H4>3.1.2&nbsp;&nbsp; Access Rules</H4><!--SEC END -->
<A NAME="sec:configaccess"></A>Access control in <TT>ejabberd</TT> is done via Access Control Lists (ACL). In
config file they looks like this:
@ -213,6 +188,12 @@ config file they looks like this:
If the first character after <TT>`['</TT> is a <TT>`!'</TT>, then any
character not enclosed is matched.
</DL>
</DL>Following ACLs pre-defined:
<DL COMPACT=compact>
<DT>
<TT>all</TT><DD> Matches all JIDs.
<DT><TT>none</TT><DD> Matches none JIDs.
</DL>Allowing or denying of different services is like this:
<PRE>
{access, &lt;accessname&gt;, [{allow, &lt;aclname&gt;},
@ -229,6 +210,57 @@ Example:
{access, configure, [{allow, admin}]}.
{access, something, [{deny, badmans},
{allow, all}]}.
</PRE>Following access rules pre-defined:
<DL COMPACT=compact>
<DT>
<TT>all</TT><DD> Always return ``<TT>allow</TT>''
<DT><TT>none</TT><DD> Always return ``<TT>deny</TT>''
</DL><!--TOC subsubsection Listened Sockets-->
<H4>3.1.3&nbsp;&nbsp; Listened Sockets</H4><!--SEC END -->
<A NAME="sec:configlistened"></A>Option <TT>listen</TT> defines list of listened sockets and what services
runned on them. Each element of list is a tuple with following elements:
<UL>
<LI>
Port number;
<LI> Module that serves this port;
<LI> Function in this module that starts connection (likely will be removed);
<LI> Options to this module.
</UL>Currently three modules implemented:
<DL COMPACT=compact>
<DT>
<TT>ejabberd_c2s</TT><DD> This module serves C2S connections.<BR>
<BR>
Following options defined:
<DL COMPACT=compact>
<DT>
<TT>{access, &lt;access rule&gt;}</TT><DD> This option defines access of users
to this C2S port. Default value is ``<TT>all</TT>''.
</DL>
<DT><TT>ejabberd_s2s_in</TT><DD> This module serves incoming S2S connections.
<DT><TT>ejabberd_service</TT><DD> This module serves connections to Jabber
services (i.&nbsp;e. that use <TT>jabber:component:accept</TT> namespace).
</DL>For example, following configuration defines that C2S connections listened on
port 5222 and denied for user ``<TT>bad</TT>'', S2S on port 5269 and that
service <TT>conference.jabber.org</TT> must be connected to port 8888 with
password ``<TT>secret</TT>''.<BR>
<BR>
<PRE>
{acl, blocked, {user, "bad"}}.
{access, c2s, [{deny, blocked},
{allow, all}]}.
{listen, [{5222, ejabberd_c2s, start, [{access, c2s}]},
{5269, ejabberd_s2s_in, start, []},
{8888, ejabberd_service, start,
[{host, "conference.jabber.org", [{password, "secret"}]}]}
]}.
</PRE><!--TOC subsubsection Modules-->
<H4>3.1.4&nbsp;&nbsp; Modules</H4><!--SEC END -->
@ -282,7 +314,7 @@ have access to connect to port 4369 of all another nodes, and must have same
magic cookie (see Erlang/OTP documentation, in short file
<TT>~ejabberd/.erlang.cookie</TT> must be the same on all nodes). This is
needed because all nodes exchange information about connected users, S2S
connection, registered services, etc...<BR>
connections, registered services, etc...<BR>
<BR>
Each <TT>ejabberd</TT> node run following modules:
<UL>

View File

@ -132,6 +132,15 @@ database, and in next time they will be APPENDED to existing values. E.\,g.\
if this file will not contain ``host'' definition, then old value will be
used.
To override old values following lines can be added in config:
\begin{verbatim}
override_global.
override_local.
override_acls.
\end{verbatim}
With this lines old global or local options or ACLs will be removed before
adding new ones.
\subsubsection{Host Name}
\label{sec:confighostname}
@ -146,38 +155,6 @@ serves. E.\,g.\ to use \texttt{jabber.org} domain add following line in config:
\subsubsection{Listened Sockets}
\label{sec:configlistened}
Option \texttt{listen} defines list of listened sockets and what services
runned on them. Each element of list is a tuple with following elements:
\begin{itemize}
\item Port number;
\item Module that serves this port;
\item Function in this module that starts connection (likely will be removed);
\item Options to this module.
\end{itemize}
Currently three modules implemented:
\begin{itemize}
\item \texttt{ejabberd\_c2s}: serves C2S connections;
\item \texttt{ejabberd\_s2s\_in}: serves incoming S2S connections;
\item \texttt{ejabberd\_service}: serves connections to \Jabber{} services
(i.\,e.\ that use \texttt{jabber:component:accept} namespace).
\end{itemize}
For example, following configuration defines that C2S connections listened on
port 5222, S2S on port 5269 and that service \texttt{conference.jabber.org}
must be connected to port 8888 with password ``\texttt{secret}''.
\begin{verbatim}
{listen, [{5222, ejabberd_c2s, start, []},
{5269, ejabberd_s2s_in, start, []},
{8888, ejabberd_service, start, ["conference.jabber.org", "secret"]}
]}.
\end{verbatim}
\subsubsection{Access Rules}
\label{sec:configaccess}
@ -253,6 +230,12 @@ config file they looks like this:
\end{description}
\end{description}
Following ACLs pre-defined:
\begin{description}
\item[\texttt{all}] Matches all JIDs.
\item[\texttt{none}] Matches none JIDs.
\end{description}
Allowing or denying of different services is like this:
\begin{verbatim}
{access, <accessname>, [{allow, <aclname>},
@ -272,6 +255,57 @@ Example:
{allow, all}]}.
\end{verbatim}
Following access rules pre-defined:
\begin{description}
\item[\texttt{all}] Always return ``\texttt{allow}''
\item[\texttt{none}] Always return ``\texttt{deny}''
\end{description}
\subsubsection{Listened Sockets}
\label{sec:configlistened}
Option \texttt{listen} defines list of listened sockets and what services
runned on them. Each element of list is a tuple with following elements:
\begin{itemize}
\item Port number;
\item Module that serves this port;
\item Function in this module that starts connection (likely will be removed);
\item Options to this module.
\end{itemize}
Currently three modules implemented:
\begin{description}
\item[\texttt{ejabberd\_c2s}] This module serves C2S connections.
Following options defined:
\begin{description}
\item[\texttt{\{access, <access rule>\}}] This option defines access of users
to this C2S port. Default value is ``\texttt{all}''.
\end{description}
\item[\texttt{ejabberd\_s2s\_in}] This module serves incoming S2S connections.
\item[\texttt{ejabberd\_service}] This module serves connections to \Jabber{}
services (i.\,e.\ that use \texttt{jabber:component:accept} namespace).
\end{description}
For example, following configuration defines that C2S connections listened on
port 5222 and denied for user ``\texttt{bad}'', S2S on port 5269 and that
service \texttt{conference.jabber.org} must be connected to port 8888 with
password ``\texttt{secret}''.
\begin{verbatim}
{acl, blocked, {user, "bad"}}.
{access, c2s, [{deny, blocked},
{allow, all}]}.
{listen, [{5222, ejabberd_c2s, start, [{access, c2s}]},
{5269, ejabberd_s2s_in, start, []},
{8888, ejabberd_service, start,
[{host, "conference.jabber.org", [{password, "secret"}]}]}
]}.
\end{verbatim}
\subsubsection{Modules}

View File

@ -3,9 +3,10 @@
include Makefile.inc
INCLUDES = -I/usr/lib/erlang/usr/include \
-I$(EI_DIR)/include
-I$(EI_DIR)/include \
-I/usr/local/include
LIBDIRS = -L$(EI_DIR)/lib
LIBDIRS = -L$(EI_DIR)/lib -L/usr/local/lib
ERLSHLIBS = expat_erl.so

View File

@ -11,7 +11,9 @@
-vsn('$Revision$ ').
-export([start/0,
to_record/2,
add/2,
add_list/2,
match_rule/2,
% for debugging only
match_acl/2]).
@ -28,6 +30,8 @@ start() ->
mnesia:add_table_copy(acl, node(), ram_copies),
ok.
to_record(ACLName, ACLSpec) ->
#acl{aclname = ACLName, aclspec = ACLSpec}.
add(ACLName, ACLSpec) ->
F = fun() ->
@ -35,12 +39,44 @@ add(ACLName, ACLSpec) ->
end,
mnesia:transaction(F).
add_list(ACLs, Clear) ->
F = fun() ->
if
Clear ->
Ks = mnesia:all_keys(acl),
lists:foreach(fun(K) ->
mnesia:delete({acl, K})
end, Ks);
true ->
ok
end,
lists:foreach(fun(ACL) ->
case ACL of
#acl{} ->
mnesia:write(ACL)
end
end, ACLs)
end,
case mnesia:transaction(F) of
{atomic, _} ->
ok;
_ ->
false
end.
match_rule(Rule, JID) ->
case ejabberd_config:get_global_option({access, Rule}) of
undefined ->
deny;
ACLs ->
match_acls(ACLs, JID)
case Rule of
all -> allow;
none -> deny;
_ ->
case ejabberd_config:get_global_option({access, Rule}) of
undefined ->
deny;
ACLs ->
match_acls(ACLs, JID)
end
end.
match_acls([], _) ->
@ -54,41 +90,46 @@ match_acls([{Access, ACL} | ACLs], JID) ->
end.
match_acl(ACL, JID) ->
{User, Server, Resource} = jlib:jid_tolower(JID),
lists:any(fun(#acl{aclspec = Spec}) ->
case Spec of
all ->
true;
{user, U} ->
(U == User) andalso (?MYNAME == Server);
{user, U, S} ->
(U == User) andalso (S == Server);
{server, S} ->
S == Server;
{user_regexp, UR} ->
(?MYNAME == Server) andalso
is_regexp_match(User, UR);
{user_regexp, UR, S} ->
(S == Server) andalso
is_regexp_match(User, UR);
{server_regexp, SR} ->
is_regexp_match(Server, SR);
{node_regexp, UR, SR} ->
is_regexp_match(Server, SR) andalso
is_regexp_match(User, UR);
{user_glob, UR} ->
(?MYNAME == Server) andalso
is_glob_match(User, UR);
{user_glob, UR, S} ->
(S == Server) andalso
is_glob_match(User, UR);
{server_glob, SR} ->
is_glob_match(Server, SR);
{node_glob, UR, SR} ->
is_glob_match(Server, SR) andalso
is_glob_match(User, UR)
end
end, ets:lookup(acl, ACL)).
case ACL of
all -> true;
none -> false;
_ ->
{User, Server, Resource} = jlib:jid_tolower(JID),
lists:any(fun(#acl{aclspec = Spec}) ->
case Spec of
all ->
true;
{user, U} ->
(U == User) andalso (?MYNAME == Server);
{user, U, S} ->
(U == User) andalso (S == Server);
{server, S} ->
S == Server;
{user_regexp, UR} ->
(?MYNAME == Server) andalso
is_regexp_match(User, UR);
{user_regexp, UR, S} ->
(S == Server) andalso
is_regexp_match(User, UR);
{server_regexp, SR} ->
is_regexp_match(Server, SR);
{node_regexp, UR, SR} ->
is_regexp_match(Server, SR) andalso
is_regexp_match(User, UR);
{user_glob, UR} ->
(?MYNAME == Server) andalso
is_glob_match(User, UR);
{user_glob, UR, S} ->
(S == Server) andalso
is_glob_match(User, UR);
{server_glob, SR} ->
is_glob_match(Server, SR);
{node_glob, UR, SR} ->
is_glob_match(Server, SR) andalso
is_glob_match(User, UR)
end
end, ets:lookup(acl, ACL))
end.
is_regexp_match(String, RegExp) ->
case regexp:first_match(String, RegExp) of

54
src/ejabberd.app Normal file
View File

@ -0,0 +1,54 @@
% $Id$
{application, ejabberd,
[{description, "ejabberd"},
{vsn, "0.0.1-alpha"},
{modules, [acl,
ejabberd,
ejabberd_auth,
ejabberd_c2s,
ejabberd_config,
ejabberd_listener,
ejabberd_local,
ejabberd_router,
ejabberd_s2s,
ejabberd_s2s_in,
ejabberd_s2s_out,
ejabberd_service,
ejabberd_sm,
jlib,
mod_configure,
mod_disco,
mod_echo,
mod_offline,
mod_private,
mod_register,
mod_roster,
mod_stats,
mod_time,
mod_vcard,
mod_version,
randoms,
sha,
translate,
xml,
xml_stream
]},
{registered, [ejabberd,
ejabberd_auth,
ejabberd_router,
ejabberd_sm,
ejabberd_s2s,
ejabberd_local,
ejabberd_mod_roster,
ejabberd_listeners
]},
{applications, [kernel, stdlib, mnesia]},
{env, []},
{mod, {ejabberd_app, []}}]}.
% Local Variables:
% mode: erlang
% End:

View File

@ -6,6 +6,9 @@
{acl, admin, {user, "aleksey", "jabber.ru"}}.
{acl, admin, {user, "ermine", "jabber.ru"}}.
{acl, blocked, {user, "test2"}}.
{acl, jabberorg, {server, "jabber.org"}}.
{acl, aleksey, {user, "aleksey", "jabber.ru"}}.
@ -18,11 +21,15 @@
{access, configure, [{allow, admin}]}.
{access, c2s, [{deny, blocked},
{allow, all}]}.
{host, "e.localhost"}.
{listen, [{5522, ejabberd_c2s, start, []},
{listen, [{5522, ejabberd_c2s, start, [{access, c2s}]},
{5269, ejabberd_s2s_in, start, []},
{8888, ejabberd_service, start, ["asd.e.localhost", "asdqwe"]}
{8888, ejabberd_service, start,
[{host, "asd.e.localhost", [{password, "asdqwe"}]}]}
]}.
% This value (5569) is only for debugging, must be 5269

View File

@ -10,62 +10,70 @@
-author('alexey@sevcom.net').
-vsn('$Revision$ ').
-export([start/0, init/0]).
-include("ejabberd.hrl").
-export([start/0, stop/0]).
start() ->
spawn(?MODULE, init, []).
application:start(mnesia),
application:start(ejabberd).
init() ->
register(ejabberd, self()),
% Profiling
%eprof:start(),
%eprof:profile([self()]),
%erlang:system_flag(fullsweep_after, 0),
error_logger:logfile({open, ?ERROR_LOG_PATH}),
randoms:start(),
ok = erl_ddll:load_driver(".", expat_erl),
Port = open_port({spawn, expat_erl}, [binary]),
db_init(),
sha:start(),
translate:start(),
acl:start(),
gen_mod:start(),
ejabberd_config:start(),
ejabberd_auth:start(),
ejabberd_router:start(),
ejabberd_sm:start(),
ejabberd_s2s:start(),
ejabberd_local:start(),
ejabberd_listener:start(),
load_modules(),
loop(Port).
stop() ->
application:stop(ejabberd).
loop(Port) ->
receive
_ ->
loop(Port)
end.
%-include("ejabberd.hrl").
db_init() ->
case mnesia:system_info(extra_db_nodes) of
[] ->
mnesia:create_schema([node()]);
_ ->
ok
end,
mnesia:start(),
mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity).
load_modules() ->
case ejabberd_config:get_local_option(modules) of
undefined ->
ok;
Modules ->
lists:foreach(fun({Module, Args}) ->
gen_mod:start_module(Module, Args)
end, Modules)
end.
%start() ->
% spawn(?MODULE, init, []).
%
%init() ->
% register(ejabberd, self()),
% % Profiling
% %eprof:start(),
% %eprof:profile([self()]),
% %erlang:system_flag(fullsweep_after, 0),
% error_logger:logfile({open, ?ERROR_LOG_PATH}),
% randoms:start(),
% ok = erl_ddll:load_driver(".", expat_erl),
% Port = open_port({spawn, expat_erl}, [binary]),
% db_init(),
% sha:start(),
% translate:start(),
% acl:start(),
% gen_mod:start(),
% ejabberd_config:start(),
% ejabberd_auth:start(),
% ejabberd_router:start(),
% ejabberd_sm:start(),
% ejabberd_s2s:start(),
% ejabberd_local:start(),
% ejabberd_listener:start(),
% load_modules(),
% loop(Port).
%
%
%loop(Port) ->
% receive
% _ ->
% loop(Port)
% end.
%
%db_init() ->
% case mnesia:system_info(extra_db_nodes) of
% [] ->
% mnesia:create_schema([node()]);
% _ ->
% ok
% end,
% mnesia:start(),
% mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity).
%
%load_modules() ->
% case ejabberd_config:get_local_option(modules) of
% undefined ->
% ok;
% Modules ->
% lists:foreach(fun({Module, Args}) ->
% gen_mod:start_module(Module, Args)
% end, Modules)
% end.

79
src/ejabberd_app.erl Normal file
View File

@ -0,0 +1,79 @@
%%%----------------------------------------------------------------------
%%% File : ejabberd_app.erl
%%% Author : Alexey Shchepin <alexey@sevcom.net>
%%% Purpose :
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
%%% Id : $Id$
%%%----------------------------------------------------------------------
-module(ejabberd_app).
-author('alexey@sevcom.net').
-vsn('$Revision$ ').
-behaviour(application).
-export([start/2, stop/1, init/0]).
-include("ejabberd.hrl").
start(normal, Args) ->
randoms:start(),
db_init(),
sha:start(),
translate:start(),
acl:start(),
gen_mod:start(),
ejabberd_config:start(),
ejabberd_auth:start(),
Sup = ejabberd_sup:start_link(),
start(),
load_modules(),
Sup;
start(_, _) ->
{error, badarg}.
stop(StartArgs) ->
ok.
start() ->
spawn(?MODULE, init, []).
init() ->
register(ejabberd, self()),
% Profiling
%eprof:start(),
%eprof:profile([self()]),
%erlang:system_flag(fullsweep_after, 0),
error_logger:logfile({open, ?ERROR_LOG_PATH}),
ok = erl_ddll:load_driver(".", expat_erl),
Port = open_port({spawn, expat_erl}, [binary]),
loop(Port).
loop(Port) ->
receive
_ ->
loop(Port)
end.
db_init() ->
case mnesia:system_info(extra_db_nodes) of
[] ->
mnesia:create_schema([node()]);
_ ->
ok
end,
mnesia:start(),
mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity).
load_modules() ->
case ejabberd_config:get_local_option(modules) of
undefined ->
ok;
Modules ->
lists:foreach(fun({Module, Args}) ->
gen_mod:start_module(Module, Args)
end, Modules)
end.

View File

@ -13,12 +13,9 @@
-behaviour(gen_fsm).
%% External exports
-export([start/1, receiver/2, sender/1, send_text/2, send_element/2]).
-export([start/2, receiver/2, sender/1, send_text/2, send_element/2]).
%% gen_fsm callbacks
%-export([init/1, state_name/2, state_name/3, handle_event/3,
% handle_sync_event/4, handle_info/3, terminate/3]).
%
-export([init/1, wait_for_stream/2, wait_for_auth/2, session_established/2,
handle_event/3,
handle_sync_event/4,
@ -32,6 +29,7 @@
-define(SETS, gb_sets).
-record(state, {socket, sender, receiver, streamid,
access,
user = "", server = ?MYNAME, resource = "",
pres_t = ?SETS:new(),
pres_f = ?SETS:new(),
@ -63,8 +61,8 @@
%%%----------------------------------------------------------------------
%%% API
%%%----------------------------------------------------------------------
start(Socket) ->
gen_fsm:start(ejabberd_c2s, [Socket], ?FSMOPTS).
start(Socket, Opts) ->
gen_fsm:start(ejabberd_c2s, [Socket, Opts], ?FSMOPTS).
%%%----------------------------------------------------------------------
%%% Callback functions from gen_fsm
@ -77,13 +75,20 @@ start(Socket) ->
%% ignore |
%% {stop, StopReason}
%%----------------------------------------------------------------------
init([Socket]) ->
init([Socket, Opts]) ->
SenderPid = spawn(?MODULE, sender, [Socket]),
ReceiverPid = spawn(?MODULE, receiver, [Socket, self()]),
{ok, wait_for_stream, #state{socket = Socket,
Access = case lists:keysearch(access, 1, Opts) of
{value, {_, A}} ->
A;
_ ->
all
end,
{ok, wait_for_stream, #state{socket = Socket,
receiver = ReceiverPid,
sender = SenderPid,
streamid = new_id()}}.
sender = SenderPid,
streamid = new_id(),
access = Access}}.
%%----------------------------------------------------------------------
%% Func: StateName/2
@ -118,20 +123,28 @@ wait_for_auth({xmlstreamelement, El}, StateData) ->
{next_state, wait_for_auth, StateData};
{auth, ID, {U, P, D, R}} ->
io:format("AUTH: ~p~n", [{U, P, D, R}]),
case ejabberd_auth:check_password(U, P,
StateData#state.streamid, D) of
true ->
ejabberd_sm:open_session(U, R),
Res = jlib:make_result_iq_reply(El),
send_element(StateData#state.sender, Res),
{Fs, Ts} = mod_roster:get_subscription_lists(U),
{next_state, session_established,
StateData#state{user = U,
resource = R,
pres_f = ?SETS:from_list(Fs),
pres_t = ?SETS:from_list(Ts)}};
case acl:match_rule(StateData#state.access, {U, ?MYNAME, R}) of
allow ->
case ejabberd_auth:check_password(
U, P, StateData#state.streamid, D) of
true ->
ejabberd_sm:open_session(U, R),
Res = jlib:make_result_iq_reply(El),
send_element(StateData#state.sender, Res),
{Fs, Ts} = mod_roster:get_subscription_lists(U),
{next_state, session_established,
StateData#state{user = U,
resource = R,
pres_f = ?SETS:from_list(Fs),
pres_t = ?SETS:from_list(Ts)}};
_ ->
Err = jlib:make_error_reply(
El, "401", "Unauthorized"),
send_element(StateData#state.sender, Err),
{next_state, wait_for_auth, StateData}
end;
_ ->
Err = jlib:make_error_reply(El, "401", "Unauthorized"),
Err = jlib:make_error_reply(El, "405", "Not Allowed"),
send_element(StateData#state.sender, Err),
{next_state, wait_for_auth, StateData}
end;

View File

@ -18,6 +18,10 @@
-record(config, {key, value}).
-record(local_config, {key, value}).
-record(state, {opts = [],
override_local = false,
override_global = false,
override_acls = false}).
start() ->
%ets:new(ejabberd_config, [named_table, public]),
@ -36,23 +40,32 @@ start() ->
load_file(File) ->
case file:consult(File) of
{ok, Terms} ->
lists:foreach(fun process_term/1, Terms);
Res = lists:foldl(fun process_term/2, #state{}, Terms),
set_opts(Res);
{error, Reason} ->
?ERROR_MSG("~p", [Reason]),
exit(file:format_error(Reason))
end.
process_term(Term) ->
process_term(Term, State) ->
case Term of
override_global ->
#state{override_global = true};
override_local ->
#state{override_local = true};
override_acls ->
#state{override_acls = true};
{acl, ACLName, ACLData} ->
acl:add(ACLName, ACLData);
#state{opts =
[acl:to_record(ACLName, ACLData) | State#state.opts]};
{access, RuleName, Rules} ->
add_global_option({access, RuleName}, Rules);
#state{opts = [#config{key = {access, RuleName}, value = Rules} |
State#state.opts]};
{Opt, Val} ->
add_option(Opt, Val)
add_option(Opt, Val, State)
end.
add_option(Opt, Val) ->
add_option(Opt, Val, State) ->
Table = case Opt of
host ->
config;
@ -61,11 +74,51 @@ add_option(Opt, Val) ->
end,
case Table of
config ->
add_global_option(Opt, Val);
#state{opts = [#config{key = Opt, value = Val} |
State#state.opts]};
local_config ->
add_local_option(Opt, Val)
#state{opts = [#local_config{key = Opt, value = Val} |
State#state.opts]}
end.
set_opts(State) ->
Opts = lists:reverse(State#state.opts),
mnesia:transaction(
fun() ->
if
State#state.override_global ->
Ksg = mnesia:all_keys(config),
lists:foreach(fun(K) ->
mnesia:delete({config, K})
end, Ksg);
true ->
ok
end,
if
State#state.override_local ->
Ksl = mnesia:all_keys(local_config),
lists:foreach(fun(K) ->
mnesia:delete({local_config, K})
end, Ksl);
true ->
ok
end,
if
State#state.override_acls ->
Ksa = mnesia:all_keys(acl),
lists:foreach(fun(K) ->
mnesia:delete({acl, K})
end, Ksa);
true ->
ok
end,
lists:foreach(fun(R) ->
mnesia:write(R)
end, Opts)
end).
add_global_option(Opt, Val) ->
mnesia:transaction(fun() ->
mnesia:write(#config{key = Opt,
@ -96,4 +149,3 @@ get_local_option(Opt) ->
end.

View File

@ -10,9 +10,9 @@
-author('alexey@sevcom.net').
-vsn('$Revision$ ').
-export([start/0, init/1, start/4, init/4]).
-export([start_link/0, init/1, start/4, init/4]).
start() ->
start_link() ->
supervisor:start_link({local, ejabberd_listeners}, ?MODULE, []).
@ -23,9 +23,9 @@ init(_) ->
Ls ->
{ok, {{one_for_one, 10, 1},
lists:map(
fun({Port, Module, Fun, Args}) ->
fun({Port, Module, Fun, Opts}) ->
{Port,
{?MODULE, start, [Port, Module, Fun, Args]},
{?MODULE, start, [Port, Module, Fun, [Opts]]},
permanent,
brutal_kill,
worker,

View File

@ -10,7 +10,7 @@
-author('alexey@sevcom.net').
-vsn('$Revision$ ').
-export([start/0, init/0]).
-export([start_link/0, init/0]).
-export([register_iq_handler/3,
register_iq_handler/4,
@ -21,9 +21,10 @@
-record(state, {mydomain, iqtable}).
start() ->
register(ejabberd_local, spawn(ejabberd_local, init, [])),
ok.
start_link() ->
register(ejabberd_local,
Pid = proc_lib:spawn_link(ejabberd_local, init, [])),
{ok, Pid}.
init() ->
MyDomain = ?MYNAME,

View File

@ -19,7 +19,7 @@
dirty_get_all_domains/0
]).
-export([start/0, init/0]).
-export([start_link/0, init/0]).
-include("ejabberd.hrl").
@ -27,8 +27,8 @@
-record(local_route, {domain, pid}).
start() ->
spawn(ejabberd_router, init, []).
start_link() ->
{ok, proc_lib:spawn_link(ejabberd_router, init, [])}.
init() ->
register(ejabberd_router, self()),

View File

@ -10,7 +10,7 @@
-author('alexey@sevcom.net').
-vsn('$Revision$ ').
-export([start/0, init/0,
-export([start_link/0, init/0,
have_connection/1,
get_key/1,
try_register/1,
@ -23,8 +23,8 @@
-record(local_s2s, {fromto, pid}).
start() ->
spawn(ejabberd_s2s, init, []).
start_link() ->
{ok, proc_lib:spawn_link(ejabberd_s2s, init, [])}.
init() ->
register(ejabberd_s2s, self()),

View File

@ -13,7 +13,7 @@
-behaviour(gen_fsm).
%% External exports
-export([start/1, receiver/2, send_text/2, send_element/2]).
-export([start/2, receiver/2, send_text/2, send_element/2]).
%% gen_fsm callbacks
-export([init/1,
@ -65,7 +65,7 @@
%%%----------------------------------------------------------------------
%%% API
%%%----------------------------------------------------------------------
start(Socket) ->
start(Socket, Opts) ->
gen_fsm:start(ejabberd_s2s_in, [Socket], ?FSMOPTS).
%%%----------------------------------------------------------------------

View File

@ -13,7 +13,7 @@
-behaviour(gen_fsm).
%% External exports
-export([start/3, receiver/2, send_text/2, send_element/2]).
-export([start/2, receiver/2, send_text/2, send_element/2]).
%% gen_fsm callbacks
-export([init/1,
@ -63,8 +63,8 @@
%%%----------------------------------------------------------------------
%%% API
%%%----------------------------------------------------------------------
start(Socket, Host, Password) ->
gen_fsm:start(ejabberd_service, [Socket, Host, Password], ?FSMOPTS).
start(Socket, Opts) ->
gen_fsm:start(ejabberd_service, [Socket, Opts], ?FSMOPTS).
%%%----------------------------------------------------------------------
%%% Callback functions from gen_fsm
@ -77,7 +77,21 @@ start(Socket, Host, Password) ->
%% ignore |
%% {stop, StopReason}
%%----------------------------------------------------------------------
init([Socket, Host, Password]) ->
init([Socket, Opts]) ->
{Host, Password} =
case lists:keysearch(host, 1, Opts) of
{value, {_, H, HOpts}} ->
case lists:keysearch(password, 1, HOpts) of
{value, {_, P}} ->
{H, P};
_ ->
% TODO: generate error
false
end;
_ ->
% TODO: generate error
false
end,
ReceiverPid = spawn(?MODULE, receiver, [Socket, self()]),
{ok, wait_for_stream, #state{socket = Socket,
receiver = ReceiverPid,

View File

@ -10,7 +10,7 @@
-author('alexey@sevcom.net').
-vsn('$Revision$ ').
-export([start/0, init/0, open_session/2, close_session/2,
-export([start_link/0, init/0, open_session/2, close_session/2,
get_user_resources/1,
set_presence/3,
unset_presence/2,
@ -28,8 +28,8 @@
-record(local_session, {ur, pid}).
-record(presence, {ur, user, priority}).
start() ->
spawn(ejabberd_sm, init, []).
start_link() ->
{ok, proc_lib:spawn_link(ejabberd_sm, init, [])}.
init() ->
register(ejabberd_sm, self()),

54
src/ejabberd_sup.erl Normal file
View File

@ -0,0 +1,54 @@
%%%----------------------------------------------------------------------
%%% File : ejabberd_sup.erl
%%% Author : Alexey Shchepin <alexey@sevcom.net>
%%% Purpose :
%%% Created : 31 Jan 2003 by Alexey Shchepin <alexey@sevcom.net>
%%% Id : $Id$
%%%----------------------------------------------------------------------
-module(ejabberd_sup).
-author('alexey@sevcom.net').
-vsn('$Revision$ ').
-behaviour(supervisor).
-export([start_link/0, init/1]).
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
init([]) ->
Router = {ejabberd_router,
{ejabberd_router, start_link, []},
permanent,
brutal_kill,
worker,
[ejabberd_router]},
SM = {ejabberd_sm,
{ejabberd_sm, start_link, []},
permanent,
brutal_kill,
worker,
[ejabberd_sm]},
S2S = {ejabberd_s2s,
{ejabberd_s2s, start_link, []},
permanent,
brutal_kill,
worker,
[ejabberd_s2s]},
Local = {ejabberd_local,
{ejabberd_local, start_link, []},
permanent,
brutal_kill,
worker,
[ejabberd_local]},
Listener = {ejabberd_listener,
{ejabberd_listener, start_link, []},
permanent,
brutal_kill,
supervisor,
[ejabberd_listener]},
{ok, {{one_for_one, 10, 1}, [Router, SM, S2S, Local, Listener]}}.

View File

@ -244,7 +244,7 @@ get_form(["config", "acls"], Lang) ->
{xmlelement, "value", [], [{xmlcdata, S}]}
end,
string:tokens(
lists:flatten(io_lib:format("~p",
lists:flatten(io_lib:format("~p.",
[ets:tab2list(acl)])),
"\n"))
%{xmlelement, "value", [], [{xmlcdata, ?MYNAME}]}
@ -343,22 +343,19 @@ set_form(["running nodes", ENode, "modules", "start"], Lang, XData) ->
{ok, Tokens, _} ->
case erl_parse:parse_term(Tokens) of
{ok, Modules} ->
case catch lists:foreach(
fun({Module, Args}) ->
gen_mod:start_module(
Module, Args)
end, Modules) of
{'EXIT', Reason} ->
{error,
"500", "Internal Server Error"};
_ ->
{result, []}
end;
lists:foreach(
fun({Module, Args}) ->
rpc:call(Node,
gen_mod,
start_module,
[Module, Args])
end, Modules),
{result, []};
_ ->
{error, "500", "Internal Server Error"}
{error, "406", "Not Acceptable"}
end;
_ ->
{error, "500", "Internal Server Error"}
{error, "406", "Not Acceptable"}
end;
_ ->
{error, "406", "Not Acceptable"}
@ -379,6 +376,32 @@ set_form(["config", "hostname"], Lang, XData) ->
{error, "406", "Not Acceptable"}
end;
set_form(["config", "acls"], Lang, XData) ->
case lists:keysearch("acls", 1, XData) of
{value, {_, Strings}} ->
String = lists:foldl(fun(S, Res) ->
Res ++ S ++ "\n"
end, "", Strings),
case erl_scan:string(String) of
{ok, Tokens, _} ->
case erl_parse:parse_term(Tokens) of
{ok, ACLs} ->
case acl:add_list(ACLs, true) of
ok ->
{result, []};
_ ->
{error, "406", "Not Acceptable"}
end;
_ ->
{error, "406", "Not Acceptable"}
end;
_ ->
{error, "406", "Not Acceptable"}
end;
_ ->
{error, "406", "Not Acceptable"}
end;
set_form(["config", "remusers"], Lang, XData) ->
lists:foreach(
fun({Var, Vals}) ->

View File

@ -1,11 +1,44 @@
% $Id$
% mod_configure.erl
{"DB Tables Configuration", "Конфигурация таблиц БД"}.
{"Choose storage type of tables", "Выберите тип хранения таблиц"}.
{"", ""}.
{"", ""}.
{"", ""}.
{"", ""}.
{"", ""}.
{"", ""}.
{"", ""}.
{"", ""}.
{"", ""}.
{"", ""}.
{"", ""}.
{"", ""}.
{"", ""}.
{"", ""}.
{"", ""}.
{"", ""}.
% mod_disco.erl
{"Configuration", "Конфигурация"}.
{"Online Users", "Подключённые пользователи"}.
{"All Users", "Все пользователи"}.
{"Outgoing S2S connections", "Исходящие S2S-соединения"}.
{"To ~s", "К ~s"}.
{"From ~s", "От ~s"}.
{"Running Nodes", "Работающие узлы"}.
{"Stopped Nodes", "Остановленные узлы"}.
{"Host Name", "Имя хоста"}.
{"ACLs", "ACLs"}.
{"Access Rules", "Правила доступа"}.
{"Remove Users", "Удаление пользователей"}.
{"DB", "БД"}.
{"Modules", "Модули"}.
{"Start Modules", "Запуск модулей"}.
{"Stop Modules", "Остановка модулей"}.
% mod_vcard.erl