]> granicus.if.org Git - ejabberd/commitdiff
*** empty log message ***
authorAlexey Shchepin <alexey@process-one.net>
Sat, 1 Feb 2003 20:21:28 +0000 (20:21 +0000)
committerAlexey Shchepin <alexey@process-one.net>
Sat, 1 Feb 2003 20:21:28 +0000 (20:21 +0000)
SVN Revision: 55

20 files changed:
doc/guide.html
doc/guide.tex
src/Makefile
src/acl.erl
src/ejabberd.app [new file with mode: 0644]
src/ejabberd.cfg
src/ejabberd.erl
src/ejabberd_app.erl [new file with mode: 0644]
src/ejabberd_c2s.erl
src/ejabberd_config.erl
src/ejabberd_listener.erl
src/ejabberd_local.erl
src/ejabberd_router.erl
src/ejabberd_s2s.erl
src/ejabberd_s2s_in.erl
src/ejabberd_service.erl
src/ejabberd_sm.erl
src/ejabberd_sup.erl [new file with mode: 0644]
src/mod_configure.erl
src/msgs/ru.msg

index 48d0469c8faf508510efb8e2cc01b3a307326883..6d95e6e73940dcc894e029bd3804992b71bb7425 100644 (file)
@@ -101,6 +101,14 @@ database, and in next time they will be APPENDED to existing values. E.&nbsp;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>
index 47061fadabbd5bd69af68ce1d599d5b65203b4e3..7f516a8e2b5ecb5ae94ba440f231d0a27d700bd7 100644 (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}
index 8f3c17bce1ae9de41d2aa0ceb90f8502625e5026..fe7705f9d060519103330df796f9471627d307be 100644 (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
 
index 10bd11fdb12fb07d3844a99f1b0837852281e4ba..67b928cd17f4362cef1b69322129107188b4c481 100644 (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
diff --git a/src/ejabberd.app b/src/ejabberd.app
new file mode 100644 (file)
index 0000000..a90fbae
--- /dev/null
@@ -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:
index 00992fed2535122705121d73d616fa7909936a81..8724fea6a8b56dac33e1c0af30f7fef4683e0726 100644 (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"}}.
 
 
 {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
index 2f6d2febab34be7041ffd45efa8314c86e180835..ef3b85c15f63f0b6d80b48c1d9d7acdcc52dcfe7 100644 (file)
 -author('alexey@sevcom.net').
 -vsn('$Revision$ ').
 
--export([start/0, init/0]).
-
--include("ejabberd.hrl").
+-export([start/0, stop/0]).
 
 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).
+    application:start(mnesia),
+    application:start(ejabberd).
 
+stop() ->
+    application:stop(ejabberd).
 
-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).
+%-include("ejabberd.hrl").
 
-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.
 
diff --git a/src/ejabberd_app.erl b/src/ejabberd_app.erl
new file mode 100644 (file)
index 0000000..67099f8
--- /dev/null
@@ -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.
+
index 8c66d3262dd93cefa9e3de91ab41328000619305..2fa3e1d2e98e255d29997b63b839f46a7c87a3cb 100644 (file)
 -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;
index 51a78592c846b24da6a82c2aeea97dec5354ef86..321c735cb0ee11a60ef252d02c445cf6a7fed4ef 100644 (file)
 
 -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.
 
 
-
index 9e6957c476548d76bfa35017fd78d1c594df02ad..3ed030c7b9df43015d5d56dedd6d6b25eb971d74 100644 (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,
index e0415b0d209b26893095604f10fdcb4e52ec4ea5..b5a32c977aef081f0fad17f8854c06a73b60c513 100644 (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,
 
 -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,
index 171244c03ee2f560671e43b3b509a01122a0ed19..9de7e67f4b52d374da9382714f98e120e6a8cbaf 100644 (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()),
index fbe6092f0d3cd2669429109709119e9bd37fd877..0aa36784b0948639fdedca70f7ad1dc69e643d35 100644 (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()),
index fbc572d329955cfb41918f84edb4e22fc9fe0479..38803054956b76bfc56d1fd73a47e6a317a6941b 100644 (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).
 
 %%%----------------------------------------------------------------------
index e67b0ca322d170d1eb278971aa979f44138b9c91..78e7a9c9a3ba77b187fbf5070ca3eb2d8c371a59 100644 (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,
index 8860dcf5d4863f25ec70d88836841f902deb17fa..0f5efe8392de160cf0f3a3788d67d5f2984171f6 100644 (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()),
diff --git a/src/ejabberd_sup.erl b/src/ejabberd_sup.erl
new file mode 100644 (file)
index 0000000..584cb0b
--- /dev/null
@@ -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]}}.
+
+
index fe89a2ded81f28b80c4cb093ce054c61c1fc5b51..6d0f1f2fc5b8d59cfe5cda9e8bc40aed84521f23 100644 (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}) ->
index 429a6cb7859620940b7b2ae58bb01d8dd1c31609..9469549bb5ef6d7dc8147cdb29c59b3c21b45b08 100644 (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