mirror of
https://github.com/processone/ejabberd.git
synced 2024-11-26 16:26:24 +01:00
MFC:
Merge revisions from 1362 to revision 1434 from trunk. SVN Revision: 1435
This commit is contained in:
parent
5610d00b4d
commit
332fb55e3a
138
ChangeLog
138
ChangeLog
@ -1,3 +1,7 @@
|
||||
2008-07-11 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||
|
||||
Merge revisions from 1362 to revision 1434 from trunk.
|
||||
|
||||
2008-07-11 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||
|
||||
* src/ejabberd_s2s_in.erl, src/ejabberd_s2s_out.erl,
|
||||
@ -7,6 +11,11 @@
|
||||
* src/ejabberd_service.erl: Convert to exmpp. Note that this module
|
||||
hasn't been tested yet!
|
||||
|
||||
2008-07-10 Badlop <badlop@process-one.net>
|
||||
|
||||
* src/configure.ac: Don't check for erlang header file (EJAB-232)
|
||||
* src/configure: Likewise
|
||||
|
||||
2008-07-09 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||
|
||||
* src/ejabberd_c2s.erl: Convert #xmlelement returned by the
|
||||
@ -16,12 +25,99 @@
|
||||
src/ejabberd_auth_odbc.erl, src/ejabberd_auth_ldap.erl,
|
||||
src/ejabberd_auth_anonymous.erl: Convert to exmpp.
|
||||
|
||||
2008-07-09 Badlop <badlop@process-one.net>
|
||||
|
||||
* src/configure.ac: Check for erlang header files (EJAB-232)
|
||||
* src/configure: Likewise
|
||||
|
||||
* src/mod_pubsub/mod_pubsub.erl: Fix compilation warnings
|
||||
* src/mod_pubsub/node_zoo.erl: Likewise
|
||||
|
||||
* src/mod_shared_roster.erl: Allow to get subscribed to a contact
|
||||
that is already in the roster by means of a shared roster group:
|
||||
add it to another roster group and it gets subscribed
|
||||
automatically (EJAB-407)
|
||||
|
||||
* src/mod_roster.erl: Likewise
|
||||
|
||||
* src/mod_muc/mod_muc_log.erl: Fix XHTML compliance: ensure some
|
||||
language is set, include ID attribute in each message, add
|
||||
microseconds to ensure unique value (EJAB-497)
|
||||
|
||||
* src/mod_register.erl: Support for io_lib newline character in
|
||||
the body of welcome_message (EJAB-501)
|
||||
* doc/guide.tex: Document the newline character
|
||||
* src/ejabberd.cfg.example: Example usage of newline character
|
||||
|
||||
* src/ejabberd_config.erl (load_file): error message on sasl.log
|
||||
is not flattened (EJAB-616)
|
||||
|
||||
* doc/guide.tex: mod_muc_log XMPP URI supports the updated version
|
||||
RFC 5122 (EJAB-631)
|
||||
* doc/guide.html: Likewise
|
||||
|
||||
2008-07-08 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||
|
||||
* src/cyrsasl.erl, src/cyrsasl_anonymous.erl, src/cyrsasl_digest.erl,
|
||||
src/cyrsasl_plain.erl, src/ejabberd_c2s.erl: Errors are now atoms, not
|
||||
strings anymore.
|
||||
|
||||
2008-07-08 Badlop <badlop@process-one.net>
|
||||
|
||||
* tools/ejabberdctl: Work also when 'which' is unavailable
|
||||
|
||||
2008-07-08 Christophe Romain <christophe.romain@process-one.net>
|
||||
|
||||
* src/web/ejabberd_http_poll.erl: improve ip fetching patch
|
||||
|
||||
2008-07-07 Badlop <badlop@process-one.net>
|
||||
|
||||
* src/Makefile.in: Spool, config and log dirs: writtable by owner,
|
||||
readable by group, nothing by others (EJAB-686)
|
||||
* doc/guide.tex: New section Securing sensible files
|
||||
* doc/guide.html: Likewise
|
||||
|
||||
* doc/guide.tex: Solaris Makefile install: use ginstall (thanks to
|
||||
Jonathan Auer)(EJAB-649)
|
||||
* doc/guide.html: Likewise
|
||||
|
||||
2008-07-03 Jerome Sautret <jerome.sautret@process-one.net>
|
||||
|
||||
* src/mod_privacy_odbc.erl: Support for privacy lists in MySQL
|
||||
(thanks to Igor Goryachev)(EJAB-538)
|
||||
|
||||
2008-07-03 Christophe Romain <christophe.romain@process-one.net>
|
||||
|
||||
* src/mod_pubsub/mod_pubsub.erl: Fix permission control on item
|
||||
retrieve (EJAB-453)
|
||||
* src/mod_pubsub/node_dispatch.erl: Likewise
|
||||
* src/mod_pubsub/node_buddy.erl: Likewise
|
||||
* src/mod_pubsub/node_private.erl: Likewise
|
||||
* src/mod_pubsub/node_public.erl: Likewise
|
||||
* src/mod_pubsub/node_default.erl: Likewise
|
||||
* src/mod_pubsub/node_pep.erl: Likewise
|
||||
* src/mod_pubsub/node_club.erl: Likewise
|
||||
* src/mod_pubsub/gen_pubsub_node.erl: Likewise
|
||||
* src/mod_pubsub/node.template: Likewise
|
||||
|
||||
* src/mod_pubsub/mod_pubsub.erl: Allow subscriber to request specific
|
||||
items by ItemID; Allow to retrieve pubsub#title configuration (thanks
|
||||
to Kevin Crosbie); Fix forbidden result on setting
|
||||
affiliation/subscription
|
||||
|
||||
* src/mod_pubsub/node_zoo.erl: Add node type without
|
||||
home/<host>/<user> constraint
|
||||
|
||||
* src/ejabberd_local.erl: prevent iq_response table overload
|
||||
(EJAB-608)
|
||||
* src/mod_caps.erl: Likewise
|
||||
|
||||
* src/web/ejabberd_http.erl: Retrieve correct IP from http connection
|
||||
* src/web/ejabberd_http_poll.erl: Likewise
|
||||
* src/ejabberd_receiver.erl: Likewise
|
||||
* src/ejabberd_sm.erl: Likewise
|
||||
* src/ejabberd_c2s.erl: Likewise
|
||||
|
||||
2008-07-01 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||
|
||||
* src/ejabberd_sm.erl: Convert to exmpp.
|
||||
@ -100,6 +196,19 @@
|
||||
src/ejabberd_s2s_out.erl: No conversion is done before calling
|
||||
ejabberd_router:route/3.
|
||||
|
||||
2008-06-29 Badlop <badlop@process-one.net>
|
||||
|
||||
* src/ejabberd_ctl.erl: Web Admin and Ad-hoc admin: dump only
|
||||
persistent tables (EJAB-678)
|
||||
|
||||
* src/mod_pubsub/node_pep.erl: Complain if mod_caps disabled and
|
||||
mod_pubsub has PEP plugin enabled (EJAB-677)
|
||||
|
||||
2008-06-28 Badlop <badlop@process-one.net>
|
||||
|
||||
* src/mod_muc/mod_muc_room.erl: Allow to store room
|
||||
description (thanks to Christopher Dupont)(EJAB-670)
|
||||
|
||||
2008-06-27 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||
|
||||
* src/ejabberd_c2s.erl, src/ejabberd_s2s_out.erl,
|
||||
@ -150,6 +259,15 @@
|
||||
expected form outside of the C2S (empty fields must be set to the
|
||||
empty string). This fixes the broken routing.
|
||||
|
||||
2008-06-21 Badlop <badlop@process-one.net>
|
||||
|
||||
* src/web/ejabberd_http.erl: Support PUT and DELETE methods in
|
||||
ejabberd_http (thanks to Eric Cestari)(EJAB-662)
|
||||
|
||||
* doc/guide.tex: Explain that S2S outgoing first tries IPv4 and if
|
||||
that fails then tries IPv6
|
||||
* doc/guide.html: Likewise
|
||||
|
||||
2008-06-20 Jean-Sébastien Pédron <js.pedron@meetic-corp.com>
|
||||
|
||||
* src/configure, src/aclocal.m4, src/Makefile.in: Add exmpp detection.
|
||||
@ -271,7 +389,7 @@
|
||||
2008-05-19 Mickael Remond <mremond@process-one.net>
|
||||
|
||||
* src/ejabberd_s2s_out.erl: Avoid an harmless error (function clause in
|
||||
logs)
|
||||
logs)
|
||||
|
||||
2008-05-17 Badlop <badlop@process-one.net>
|
||||
|
||||
@ -344,11 +462,11 @@
|
||||
being immediately shown in an 'all' special shared roster
|
||||
group (thanks to Alexey Shchepin) (EJAB-71)
|
||||
* src/mod_register.erl: New vhost event user_registered
|
||||
|
||||
|
||||
* doc/guide.tex: Document option registration_timeout (EJAB-614)
|
||||
|
||||
2008-04-25 Badlop <badlop@process-one.net>
|
||||
|
||||
|
||||
* src/ejabberd_c2s.erl: Added forbidden_session_hook
|
||||
|
||||
* src/acl.erl: New access types: resource, resource_regexp and
|
||||
@ -506,7 +624,7 @@
|
||||
* doc/webadmmainru.png: Likewise
|
||||
|
||||
* doc/disco.png: Removed because not used
|
||||
|
||||
|
||||
* doc/guide.tex: Fix Latex reference to webadmin section. Update
|
||||
explanation of screenshots. Update xmpp addresses of Mickael
|
||||
Remond and Sander Devrieze.
|
||||
@ -619,7 +737,7 @@
|
||||
|
||||
* src/eldap.erl: Faster LDAP reconnection (Thanks to Christophe
|
||||
Romain) (EJAB-581)
|
||||
|
||||
|
||||
2008-03-17 Mickael Remond <mremond@process-one.net>
|
||||
|
||||
* src/ejabberd_s2s.erl: Only trigger s2s_connect_hook on
|
||||
@ -630,7 +748,7 @@
|
||||
|
||||
* src/ejabberd_ctl.erl: API improvement: Added
|
||||
reopen_log_hook (EJAB-565)
|
||||
|
||||
|
||||
* src/ejabberd_s2s.erl: API improvement: Added s2s_connect_hook
|
||||
(EJAB-566).
|
||||
|
||||
@ -722,7 +840,7 @@
|
||||
configuration sanity checks (EJAB-533)
|
||||
* src/src/ejabberd_app.erl: Likewise
|
||||
* src/ejabberd_app.erl: Likewise
|
||||
|
||||
|
||||
2008-02-26 Badlop <badlop@process-one.net>
|
||||
|
||||
* src/msgs/it.msg: Updated (thanks to Smart2128)
|
||||
@ -858,7 +976,7 @@
|
||||
* src/mod_pubsub/node_pep.erl: Likewise
|
||||
* src/mod_pubsub/node_private.erl: Likewise
|
||||
* src/mod_pubsub/node.template: Likewise
|
||||
|
||||
|
||||
* src/mod_pubsub/gen_pubsub_node.erl: API improvement: Added a way
|
||||
to generate custom item name
|
||||
* src/mod_pubsub/node_dispatch.erl: Likewise
|
||||
@ -895,7 +1013,7 @@
|
||||
* src/mod_pubsub/gen_pubsub_nodetree.erl: Likewise
|
||||
* src/mod_pubsub/nodetree_default.erl: Likewise
|
||||
* src/mod_pubsub/nodetree_virtual.erl: Likewise
|
||||
|
||||
|
||||
2008-01-30 Badlop <badlop@process-one.net>
|
||||
|
||||
* doc/guide.tex: Removed the option served_hosts in mod_pubsub
|
||||
@ -960,7 +1078,7 @@
|
||||
* src/ejabberd.hrl: Likewise
|
||||
|
||||
* doc/introduction.tex: Updated to 22 languages
|
||||
|
||||
|
||||
* doc/Makefile: Ensure that Bash is used
|
||||
|
||||
* doc/guide.tex: Updated copyright dates to 2008.
|
||||
|
360
doc/guide.html
360
doc/guide.html
@ -106,105 +106,107 @@ BLOCKQUOTE.figure DIV.center DIV.center HR{display:none;}
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc12">2.4.4  Install</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc13">2.4.5  Start</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc14">2.4.6  Specific Notes for BSD</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc15">2.4.7  Specific Notes for Microsoft Windows</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc15">2.4.7  Specific Notes for Sun Solaris</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc16">2.4.8  Specific Notes for Microsoft Windows</A>
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc16">2.5  Create a Jabber Account for Administration</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc17">2.6  Upgrading <TT>ejabberd</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc17">2.5  Create a Jabber Account for Administration</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc18">2.6  Upgrading <TT>ejabberd</TT></A>
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc18">Chapter 3  Configuring <TT>ejabberd</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc19">Chapter 3  Configuring <TT>ejabberd</TT></A>
|
||||
<UL CLASS="toc"><LI CLASS="li-toc">
|
||||
<A HREF="#htoc19">3.1  Basic Configuration</A>
|
||||
<A HREF="#htoc20">3.1  Basic Configuration</A>
|
||||
<UL CLASS="toc"><LI CLASS="li-toc">
|
||||
<A HREF="#htoc20">3.1.1  Host Names</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc21">3.1.2  Virtual Hosting</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc22">3.1.3  Listening Ports</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc23">3.1.4  Authentication</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc24">3.1.5  Access Rules</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc25">3.1.6  Shapers</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc26">3.1.7  Default Language</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc27">3.1.8  Include Additional Configuration Files</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc28">3.1.9  Option Macros in Configuration File</A>
|
||||
<A HREF="#htoc21">3.1.1  Host Names</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc22">3.1.2  Virtual Hosting</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc23">3.1.3  Listening Ports</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc24">3.1.4  Authentication</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc25">3.1.5  Access Rules</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc26">3.1.6  Shapers</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc27">3.1.7  Default Language</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc28">3.1.8  Include Additional Configuration Files</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc29">3.1.9  Option Macros in Configuration File</A>
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc29">3.2  Database and LDAP Configuration</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc30">3.2  Database and LDAP Configuration</A>
|
||||
<UL CLASS="toc"><LI CLASS="li-toc">
|
||||
<A HREF="#htoc30">3.2.1  MySQL</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc31">3.2.2  Microsoft SQL Server</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc32">3.2.3  PostgreSQL</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc33">3.2.4  ODBC Compatible</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc34">3.2.5  LDAP</A>
|
||||
<A HREF="#htoc31">3.2.1  MySQL</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc32">3.2.2  Microsoft SQL Server</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc33">3.2.3  PostgreSQL</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc34">3.2.4  ODBC Compatible</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc35">3.2.5  LDAP</A>
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc35">3.3  Modules Configuration</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc36">3.3  Modules Configuration</A>
|
||||
<UL CLASS="toc"><LI CLASS="li-toc">
|
||||
<A HREF="#htoc36">3.3.1  Modules Overview</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc37">3.3.2  Common Options</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc38">3.3.3  <TT>mod_announce</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc39">3.3.4  <TT>mod_disco</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc40">3.3.5  <TT>mod_echo</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc41">3.3.6  <TT>mod_irc</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc42">3.3.7  <TT>mod_last</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc43">3.3.8  <TT>mod_muc</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc44">3.3.9  <TT>mod_muc_log</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc45">3.3.10  <TT>mod_offline</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc46">3.3.11  <TT>mod_privacy</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc47">3.3.12  <TT>mod_private</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc48">3.3.13  <TT>mod_proxy65</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc49">3.3.14  <TT>mod_pubsub</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc50">3.3.15  <TT>mod_register</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc51">3.3.16  <TT>mod_roster</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc52">3.3.17  <TT>mod_service_log</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc53">3.3.18  <TT>mod_shared_roster</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc54">3.3.19  <TT>mod_stats</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc55">3.3.20  <TT>mod_time</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc56">3.3.21  <TT>mod_vcard</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc57">3.3.22  <TT>mod_vcard_ldap</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc58">3.3.23  <TT>mod_version</TT></A>
|
||||
<A HREF="#htoc37">3.3.1  Modules Overview</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc38">3.3.2  Common Options</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc39">3.3.3  <TT>mod_announce</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc40">3.3.4  <TT>mod_disco</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc41">3.3.5  <TT>mod_echo</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc42">3.3.6  <TT>mod_irc</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc43">3.3.7  <TT>mod_last</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc44">3.3.8  <TT>mod_muc</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc45">3.3.9  <TT>mod_muc_log</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc46">3.3.10  <TT>mod_offline</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc47">3.3.11  <TT>mod_privacy</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc48">3.3.12  <TT>mod_private</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc49">3.3.13  <TT>mod_proxy65</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc50">3.3.14  <TT>mod_pubsub</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc51">3.3.15  <TT>mod_register</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc52">3.3.16  <TT>mod_roster</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc53">3.3.17  <TT>mod_service_log</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc54">3.3.18  <TT>mod_shared_roster</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc55">3.3.19  <TT>mod_stats</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc56">3.3.20  <TT>mod_time</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc57">3.3.21  <TT>mod_vcard</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc58">3.3.22  <TT>mod_vcard_ldap</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc59">3.3.23  <TT>mod_version</TT></A>
|
||||
</LI></UL>
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc59">Chapter 4  Managing an <TT>ejabberd</TT> server</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc60">Chapter 4  Managing an <TT>ejabberd</TT> server</A>
|
||||
<UL CLASS="toc"><LI CLASS="li-toc">
|
||||
<A HREF="#htoc60">4.1  <TT>ejabberdctl</TT></A>
|
||||
<A HREF="#htoc61">4.1  <TT>ejabberdctl</TT></A>
|
||||
<UL CLASS="toc"><LI CLASS="li-toc">
|
||||
<A HREF="#htoc61">4.1.1  Commands</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc62">4.1.2  Erlang runtime system</A>
|
||||
<A HREF="#htoc62">4.1.1  Commands</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc63">4.1.2  Erlang runtime system</A>
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc63">4.2  Web Admin</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc64">4.3  Ad-hoc Commands</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc65">4.4  Change Computer Hostname</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc64">4.2  Web Admin</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc65">4.3  Ad-hoc Commands</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc66">4.4  Change Computer Hostname</A>
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc66">Chapter 5  Securing <TT>ejabberd</TT></A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc67">Chapter 5  Securing <TT>ejabberd</TT></A>
|
||||
<UL CLASS="toc"><LI CLASS="li-toc">
|
||||
<A HREF="#htoc67">5.1  Firewall Settings</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc68">5.2  epmd</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc69">5.3  Erlang Cookie</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc70">5.4  Erlang node name</A>
|
||||
<A HREF="#htoc68">5.1  Firewall Settings</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc69">5.2  epmd</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc70">5.3  Erlang Cookie</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc71">5.4  Erlang node name</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc72">5.5  Securing sensible files</A>
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc71">Chapter 6  Clustering</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc73">Chapter 6  Clustering</A>
|
||||
<UL CLASS="toc"><LI CLASS="li-toc">
|
||||
<A HREF="#htoc72">6.1  How it Works</A>
|
||||
<A HREF="#htoc74">6.1  How it Works</A>
|
||||
<UL CLASS="toc"><LI CLASS="li-toc">
|
||||
<A HREF="#htoc73">6.1.1  Router</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc74">6.1.2  Local Router</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc75">6.1.3  Session Manager</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc76">6.1.4  s2s Manager</A>
|
||||
<A HREF="#htoc75">6.1.1  Router</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc76">6.1.2  Local Router</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc77">6.1.3  Session Manager</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc78">6.1.4  s2s Manager</A>
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc77">6.2  Clustering Setup</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc78">6.3  Service Load-Balancing</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc79">6.2  Clustering Setup</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc80">6.3  Service Load-Balancing</A>
|
||||
<UL CLASS="toc"><LI CLASS="li-toc">
|
||||
<A HREF="#htoc79">6.3.1  Components Load-Balancing</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc80">6.3.2  Domain Load-Balancing Algorithm</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc81">6.3.3  Load-Balancing Buckets</A>
|
||||
<A HREF="#htoc81">6.3.1  Components Load-Balancing</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc82">6.3.2  Domain Load-Balancing Algorithm</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc83">6.3.3  Load-Balancing Buckets</A>
|
||||
</LI></UL>
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc82">Chapter 7  Debugging</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc84">Chapter 7  Debugging</A>
|
||||
<UL CLASS="toc"><LI CLASS="li-toc">
|
||||
<A HREF="#htoc83">7.1  Watchdog Alerts</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc84">7.2  Log Files</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc85">7.3  Debug Console</A>
|
||||
<A HREF="#htoc85">7.1  Watchdog Alerts</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc86">7.2  Log Files</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc87">7.3  Debug Console</A>
|
||||
</LI></UL>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc86">Appendix A  Internationalization and Localization</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc87">Appendix B  Release Notes</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc88">Appendix C  Acknowledgements</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc89">Appendix D  Copyright Information</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc88">Appendix A  Internationalization and Localization</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc89">Appendix B  Release Notes</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc90">Appendix C  Acknowledgements</A>
|
||||
</LI><LI CLASS="li-toc"><A HREF="#htoc91">Appendix D  Copyright Information</A>
|
||||
</LI></UL><!--TOC chapter Introduction-->
|
||||
<H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc1">Chapter 1</A>  Introduction</H1><!--SEC END --><P>
|
||||
<A NAME="intro"></A></P><P><TT>ejabberd</TT> is a free and open source instant messaging server written in <A HREF="http://www.erlang.org/">Erlang</A>.</P><P><TT>ejabberd</TT> is cross-platform, distributed, fault-tolerant, and based on open standards to achieve real-time communication.</P><P><TT>ejabberd</TT> is designed to be a rock-solid and feature rich XMPP server.</P><P><TT>ejabberd</TT> is suitable for small deployments, whether they need to be scalable or not, as well as extremely big deployments.</P><!--TOC section Key Features-->
|
||||
@ -360,7 +362,7 @@ To get the full list run the command:
|
||||
</DD><DT CLASS="dt-description"><B><TT>/sbin/ejabberdctl</TT></B></DT><DD CLASS="dd-description"> Administration script
|
||||
</DD><DT CLASS="dt-description"><B><TT>/var/lib/ejabberd/</TT></B></DT><DD CLASS="dd-description">
|
||||
<DL CLASS="description"><DT CLASS="dt-description">
|
||||
<B><TT>.erlang.cookie</TT></B></DT><DD CLASS="dd-description"> Erlang cookie file
|
||||
<B><TT>.erlang.cookie</TT></B></DT><DD CLASS="dd-description"> Erlang cookie file (see section <A HREF="#cookie">5.3</A>)
|
||||
</DD><DT CLASS="dt-description"><B><TT>db</TT></B></DT><DD CLASS="dd-description"> Mnesia database spool files
|
||||
</DD><DT CLASS="dt-description"><B><TT>ebin</TT></B></DT><DD CLASS="dd-description"> Binary Erlang files (*.beam)
|
||||
</DD><DT CLASS="dt-description"><B><TT>priv</TT></B></DT><DD CLASS="dd-description">
|
||||
@ -389,8 +391,23 @@ and configurable options to fine tune the Erlang runtime system.</P><P> <A NAME=
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc14">2.4.6</A>  <A HREF="#bsd">Specific Notes for BSD</A></H3><!--SEC END --><P> <A NAME="bsd"></A>
|
||||
</P><P>The command to compile <TT>ejabberd</TT> in BSD systems is:
|
||||
</P><PRE CLASS="verbatim">gmake
|
||||
</PRE><P> <A NAME="solaris"></A> </P><!--TOC subsection Specific Notes for Sun Solaris-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc15">2.4.7</A>  <A HREF="#solaris">Specific Notes for Sun Solaris</A></H3><!--SEC END --><P> <A NAME="solaris"></A>
|
||||
</P><P>You need to have <TT>GNU install</TT>,
|
||||
but it isn’t included in Solaris.
|
||||
It can be easily installed if your Solaris system
|
||||
is set up for <A HREF="http://www.blastwave.org/">blastwave.org</A>
|
||||
package repository.
|
||||
Make sure <TT>/opt/csw/bin</TT> is in your <TT>PATH</TT> and run:
|
||||
</P><PRE CLASS="verbatim">pkg-get -i fileutils
|
||||
</PRE><P>If that program is called <TT>ginstall</TT>,
|
||||
modify the <TT>ejabberd</TT> <TT>Makefile</TT> script to suit your system,
|
||||
for example:
|
||||
</P><PRE CLASS="verbatim">cat Makefile | sed s/install/ginstall/ > Makefile.gi
|
||||
</PRE><P>And finally install <TT>ejabberd</TT> with:
|
||||
</P><PRE CLASS="verbatim">gmake -f Makefile.gi ginstall
|
||||
</PRE><P> <A NAME="windows"></A> </P><!--TOC subsection Specific Notes for Microsoft Windows-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc15">2.4.7</A>  <A HREF="#windows">Specific Notes for Microsoft Windows</A></H3><!--SEC END --><P> <A NAME="windows"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc16">2.4.8</A>  <A HREF="#windows">Specific Notes for Microsoft Windows</A></H3><!--SEC END --><P> <A NAME="windows"></A>
|
||||
</P><P> <A NAME="windowsreq"></A> </P><!--TOC subsubsection Requirements-->
|
||||
<H4 CLASS="subsubsection"><!--SEC ANCHOR --><A HREF="#windowsreq">Requirements</A></H4><!--SEC END --><P> <A NAME="windowsreq"></A> </P><P>To compile <TT>ejabberd</TT> on a Microsoft Windows system, you need:
|
||||
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
@ -428,7 +445,7 @@ nmake -f Makefile.win32
|
||||
</PRE></LI><LI CLASS="li-enumerate">Edit the file <CODE>ejabberd\src\ejabberd.cfg</CODE> and run
|
||||
<PRE CLASS="verbatim">werl -s ejabberd -name ejabberd
|
||||
</PRE></LI></OL><P> <A NAME="initialadmin"></A> </P><!--TOC section Create a Jabber Account for Administration-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc16">2.5</A>  <A HREF="#initialadmin">Create a Jabber Account for Administration</A></H2><!--SEC END --><P> <A NAME="initialadmin"></A> </P><P>You need a Jabber account and grant him administrative privileges
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc17">2.5</A>  <A HREF="#initialadmin">Create a Jabber Account for Administration</A></H2><!--SEC END --><P> <A NAME="initialadmin"></A> </P><P>You need a Jabber account and grant him administrative privileges
|
||||
to enter the <TT>ejabberd</TT> Web Admin:
|
||||
</P><OL CLASS="enumerate" type=1><LI CLASS="li-enumerate">
|
||||
Register a Jabber account on your <TT>ejabberd</TT> server, for example <TT>admin1@example.org</TT>.
|
||||
@ -449,16 +466,16 @@ favourite browser. Make sure to enter the <EM>full</EM> JID as username (in this
|
||||
example: <TT>admin1@example.org</TT>. The reason that you also need to enter the
|
||||
suffix, is because <TT>ejabberd</TT>’s virtual hosting support.
|
||||
</LI></OL><P> <A NAME="upgrade"></A> </P><!--TOC section Upgrading <TT>ejabberd</TT>-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc17">2.6</A>  <A HREF="#upgrade">Upgrading <TT>ejabberd</TT></A></H2><!--SEC END --><P> <A NAME="upgrade"></A> </P><P>To upgrade an ejabberd installation to a new version,
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc18">2.6</A>  <A HREF="#upgrade">Upgrading <TT>ejabberd</TT></A></H2><!--SEC END --><P> <A NAME="upgrade"></A> </P><P>To upgrade an ejabberd installation to a new version,
|
||||
simply uninstall the old version, and then install the new one.
|
||||
Of course, it is important that the configuration file
|
||||
and Mnesia database spool directory are not removed.</P><P><TT>ejabberd</TT> automatically updates the Mnesia table definitions at startup when needed.
|
||||
If you also use an external database for storage of some modules,
|
||||
check if the release notes of the new ejabberd version
|
||||
indicates you need to also update those tables.</P><P> <A NAME="configure"></A> </P><!--TOC chapter Configuring <TT>ejabberd</TT>-->
|
||||
<H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc18">Chapter 3</A>  <A HREF="#configure">Configuring <TT>ejabberd</TT></A></H1><!--SEC END --><P> <A NAME="configure"></A>
|
||||
<H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc19">Chapter 3</A>  <A HREF="#configure">Configuring <TT>ejabberd</TT></A></H1><!--SEC END --><P> <A NAME="configure"></A>
|
||||
</P><P> <A NAME="basicconfig"></A> </P><!--TOC section Basic Configuration-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc19">3.1</A>  <A HREF="#basicconfig">Basic Configuration</A></H2><!--SEC END --><P> <A NAME="basicconfig"></A> </P><P>The configuration file will be loaded the first time you start <TT>ejabberd</TT>. The
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc20">3.1</A>  <A HREF="#basicconfig">Basic Configuration</A></H2><!--SEC END --><P> <A NAME="basicconfig"></A> </P><P>The configuration file will be loaded the first time you start <TT>ejabberd</TT>. The
|
||||
content from this file will be parsed and stored in the internal <TT>ejabberd</TT> database. Subsequently the
|
||||
configuration will be loaded from the database and any commands in the
|
||||
configuration file are appended to the entries in the database. </P><P>Note that <TT>ejabberd</TT> never edits the configuration file.
|
||||
@ -477,7 +494,7 @@ override_acls.
|
||||
</PRE><P>With these lines the old global options (shared between all <TT>ejabberd</TT> nodes in a
|
||||
cluster), local options (which are specific for this particular <TT>ejabberd</TT> node)
|
||||
and ACLs will be removed before new ones are added.</P><P> <A NAME="hostnames"></A> </P><!--TOC subsection Host Names-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc20">3.1.1</A>  <A HREF="#hostnames">Host Names</A></H3><!--SEC END --><P> <A NAME="hostnames"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc21">3.1.1</A>  <A HREF="#hostnames">Host Names</A></H3><!--SEC END --><P> <A NAME="hostnames"></A>
|
||||
</P><P>The option <TT>hosts</TT> defines a list containing one or more domains that
|
||||
<TT>ejabberd</TT> will serve.</P><P>Examples:
|
||||
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
@ -489,7 +506,7 @@ versions:
|
||||
</PRE></LI><LI CLASS="li-itemize">Serving two domains:
|
||||
<PRE CLASS="verbatim">{hosts, ["example.net", "example.com"]}.
|
||||
</PRE></LI></UL><P> <A NAME="virtualhost"></A> </P><!--TOC subsection Virtual Hosting-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc21">3.1.2</A>  <A HREF="#virtualhost">Virtual Hosting</A></H3><!--SEC END --><P> <A NAME="virtualhost"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc22">3.1.2</A>  <A HREF="#virtualhost">Virtual Hosting</A></H3><!--SEC END --><P> <A NAME="virtualhost"></A>
|
||||
</P><P>Options can be defined separately for every virtual host using the
|
||||
<TT>host_config</TT> option. It has the following
|
||||
syntax:
|
||||
@ -561,7 +578,7 @@ other different modules for some specific virtual hosts:
|
||||
}
|
||||
]}.
|
||||
</PRE><P> <A NAME="listened"></A> </P><!--TOC subsection Listening Ports-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc22">3.1.3</A>  <A HREF="#listened">Listening Ports</A></H3><!--SEC END --><P> <A NAME="listened"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc23">3.1.3</A>  <A HREF="#listened">Listening Ports</A></H3><!--SEC END --><P> <A NAME="listened"></A>
|
||||
</P><P>The option <TT>listen</TT> defines for which addresses and ports <TT>ejabberd</TT>
|
||||
will listen and what services will be run on them. Each element of the list is a
|
||||
tuple with the following elements:
|
||||
@ -623,7 +640,10 @@ do not allow outgoing sockets on port 5222.<P>If HTTP Polling is enabled, it wil
|
||||
is also needed in the Jabber client. Remark also that HTTP Polling can be
|
||||
interesting to host a web-based Jabber client such as
|
||||
<A HREF="http://jwchat.sourceforge.net/">JWChat</A>.
|
||||
</P></DD><DT CLASS="dt-description"><B><TT>inet6</TT></B></DT><DD CLASS="dd-description"> Set up the socket for IPv6.
|
||||
</P></DD><DT CLASS="dt-description"><B><TT>inet6</TT></B></DT><DD CLASS="dd-description"> Set up the socket for IPv6 instead of IPv4.
|
||||
Note: this option is not required for S2S outgoing connections,
|
||||
because when ejabberd attempts to establish a S2S outgoing connection
|
||||
it first tries IPv4, and if that fails it attempts with IPv6.
|
||||
</DD><DT CLASS="dt-description"><B><TT>{ip, IPAddress}</TT></B></DT><DD CLASS="dd-description"> This option specifies which network
|
||||
interface to listen for. For example <CODE>{ip, {192, 168, 1, 1}}</CODE>.
|
||||
</DD><DT CLASS="dt-description"><B><TT>{max_stanza_size, Size}</TT></B></DT><DD CLASS="dd-description">
|
||||
@ -832,7 +852,7 @@ services you have to make the transports log and do XDB by themselves:
|
||||
</xdb_file>
|
||||
</xdb>
|
||||
</PRE><P> <A NAME="auth"></A> </P><!--TOC subsection Authentication-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc23">3.1.4</A>  <A HREF="#auth">Authentication</A></H3><!--SEC END --><P> <A NAME="auth"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc24">3.1.4</A>  <A HREF="#auth">Authentication</A></H3><!--SEC END --><P> <A NAME="auth"></A>
|
||||
</P><P>The option <TT>auth_method</TT> defines the authentication method that is used
|
||||
for user authentication:
|
||||
</P><PRE CLASS="verbatim">{auth_method, [<method>]}.
|
||||
@ -941,7 +961,7 @@ attacks.
|
||||
</LI><LI CLASS="li-itemize">You may want to allow login access only for certain users. <TT>pam_listfile.so</TT>
|
||||
module provides such functionality.
|
||||
</LI></UL><P> <A NAME="accessrules"></A> </P><!--TOC subsection Access Rules-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc24">3.1.5</A>  <A HREF="#accessrules">Access Rules</A></H3><!--SEC END --><P> <A NAME="accessrules"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc25">3.1.5</A>  <A HREF="#accessrules">Access Rules</A></H3><!--SEC END --><P> <A NAME="accessrules"></A>
|
||||
</P><P> <A NAME="ACLDefinition"></A> </P><!--TOC subsubsection ACL Definition-->
|
||||
<H4 CLASS="subsubsection"><!--SEC ANCHOR --><A HREF="#ACLDefinition">ACL Definition</A></H4><!--SEC END --><P> <A NAME="ACLDefinition"></A>
|
||||
</P><P>Access control in <TT>ejabberd</TT> is performed via Access Control Lists (ACLs). The
|
||||
@ -1048,7 +1068,7 @@ There’s also available the access <TT>max_s2s_connections_per_node</TT>.<
|
||||
Allow up to 3 connections with each remote server:
|
||||
<PRE CLASS="verbatim">{access, max_s2s_connections, [{3, all}]}.
|
||||
</PRE></LI></UL><P> <A NAME="shapers"></A> </P><!--TOC subsection Shapers-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc25">3.1.6</A>  <A HREF="#shapers">Shapers</A></H3><!--SEC END --><P> <A NAME="shapers"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc26">3.1.6</A>  <A HREF="#shapers">Shapers</A></H3><!--SEC END --><P> <A NAME="shapers"></A>
|
||||
</P><P>Shapers enable you to limit connection traffic. The syntax of
|
||||
shapers is like this:
|
||||
</P><PRE CLASS="verbatim">{shaper, <shapername>, <kind>}.
|
||||
@ -1067,7 +1087,7 @@ To define a shaper named ‘<TT>normal</TT>’ with traffic speed limi
|
||||
50,000 bytes/second:
|
||||
<PRE CLASS="verbatim">{shaper, fast, {maxrate, 50000}}.
|
||||
</PRE></LI></UL><P> <A NAME="language"></A> </P><!--TOC subsection Default Language-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc26">3.1.7</A>  <A HREF="#language">Default Language</A></H3><!--SEC END --><P> <A NAME="language"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc27">3.1.7</A>  <A HREF="#language">Default Language</A></H3><!--SEC END --><P> <A NAME="language"></A>
|
||||
</P><P>The option <TT>language</TT> defines the default language of server strings that
|
||||
can be seen by Jabber clients. If a Jabber client do not support
|
||||
<TT>xml:lang</TT>, the specified language is used. The default value is
|
||||
@ -1079,7 +1099,7 @@ To set Russian as default language:
|
||||
</PRE></LI><LI CLASS="li-itemize">To set Spanish as default language:
|
||||
<PRE CLASS="verbatim">{language, "es"}.
|
||||
</PRE></LI></UL><P> <A NAME="includeconfigfile"></A> </P><!--TOC subsection Include Additional Configuration Files-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc27">3.1.8</A>  <A HREF="#includeconfigfile">Include Additional Configuration Files</A></H3><!--SEC END --><P> <A NAME="includeconfigfile"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc28">3.1.8</A>  <A HREF="#includeconfigfile">Include Additional Configuration Files</A></H3><!--SEC END --><P> <A NAME="includeconfigfile"></A>
|
||||
</P><P>The option <TT>include_config_file</TT> in a configuration file instructs <TT>ejabberd</TT> to include other configuration files immediately.</P><P>The basic usage is:
|
||||
</P><PRE CLASS="verbatim">{include_config_file, <filename>}.
|
||||
</PRE><P>It is also possible to specify suboptions:
|
||||
@ -1110,7 +1130,7 @@ and later includes another file with additional rules:
|
||||
</P><PRE CLASS="verbatim">{acl, admin, {user, "bob", "localhost"}}.
|
||||
{acl, admin, {user, "jan", "localhost"}}.
|
||||
</PRE><P> <A NAME="optionmacros"></A> </P><!--TOC subsection Option Macros in Configuration File-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc28">3.1.9</A>  <A HREF="#optionmacros">Option Macros in Configuration File</A></H3><!--SEC END --><P> <A NAME="optionmacros"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc29">3.1.9</A>  <A HREF="#optionmacros">Option Macros in Configuration File</A></H3><!--SEC END --><P> <A NAME="optionmacros"></A>
|
||||
</P><P>In the <TT>ejabberd</TT> configuration file,
|
||||
it is possible to define a macro for a value
|
||||
and later use this macro when defining an option.</P><P>A macro is defined with this syntax:
|
||||
@ -1159,7 +1179,7 @@ This usage behaves as if it were defined and used this way:
|
||||
]
|
||||
}.
|
||||
</PRE><P> <A NAME="database"></A> </P><!--TOC section Database and LDAP Configuration-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc29">3.2</A>  <A HREF="#database">Database and LDAP Configuration</A></H2><!--SEC END --><P> <A NAME="database"></A>
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc30">3.2</A>  <A HREF="#database">Database and LDAP Configuration</A></H2><!--SEC END --><P> <A NAME="database"></A>
|
||||
|
||||
</P><P><TT>ejabberd</TT> uses its internal Mnesia database by default. However, it is
|
||||
possible to use a relational database or an LDAP server to store persistent,
|
||||
@ -1181,7 +1201,7 @@ different storage systems for modules, and so forth.</P><P>The following databas
|
||||
</LI><LI CLASS="li-itemize">Normally any LDAP compatible server should work; inform us about your
|
||||
success with a not-listed server so that we can list it here.
|
||||
</LI></UL><P> <A NAME="mysql"></A> </P><!--TOC subsection MySQL-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc30">3.2.1</A>  <A HREF="#mysql">MySQL</A></H3><!--SEC END --><P> <A NAME="mysql"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc31">3.2.1</A>  <A HREF="#mysql">MySQL</A></H3><!--SEC END --><P> <A NAME="mysql"></A>
|
||||
</P><P>Although this section will describe <TT>ejabberd</TT>’s configuration when you want to
|
||||
use the native MySQL driver, it does not describe MySQL’s installation and
|
||||
database creation. Check the MySQL documentation and the tutorial <A HREF="http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver">Using ejabberd with MySQL native driver</A> for information regarding these topics.
|
||||
@ -1237,7 +1257,7 @@ relational databases like MySQL. To enable storage to your database, just make
|
||||
sure that your database is running well (see previous sections), and replace the
|
||||
suffix-less or ldap module variant with the odbc module variant. Keep in mind
|
||||
that you cannot have several variants of the same module loaded!</P><P> <A NAME="mssql"></A> </P><!--TOC subsection Microsoft SQL Server-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc31">3.2.2</A>  <A HREF="#mssql">Microsoft SQL Server</A></H3><!--SEC END --><P> <A NAME="mssql"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc32">3.2.2</A>  <A HREF="#mssql">Microsoft SQL Server</A></H3><!--SEC END --><P> <A NAME="mssql"></A>
|
||||
</P><P>Although this section will describe <TT>ejabberd</TT>’s configuration when you want to
|
||||
use Microsoft SQL Server, it does not describe Microsoft SQL Server’s
|
||||
installation and database creation. Check the MySQL documentation and the
|
||||
@ -1273,7 +1293,7 @@ database, just make sure that your database is running well (see previous
|
||||
sections), and replace the suffix-less or ldap module variant with the odbc
|
||||
module variant. Keep in mind that you cannot have several variants of the same
|
||||
module loaded!</P><P> <A NAME="pgsql"></A> </P><!--TOC subsection PostgreSQL-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc32">3.2.3</A>  <A HREF="#pgsql">PostgreSQL</A></H3><!--SEC END --><P> <A NAME="pgsql"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc33">3.2.3</A>  <A HREF="#pgsql">PostgreSQL</A></H3><!--SEC END --><P> <A NAME="pgsql"></A>
|
||||
</P><P>Although this section will describe <TT>ejabberd</TT>’s configuration when you want to
|
||||
use the native PostgreSQL driver, it does not describe PostgreSQL’s installation
|
||||
and database creation. Check the PostgreSQL documentation and the tutorial <A HREF="http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver">Using ejabberd with MySQL native driver</A> for information regarding these topics.
|
||||
@ -1332,7 +1352,7 @@ relational databases like PostgreSQL. To enable storage to your database, just
|
||||
make sure that your database is running well (see previous sections), and
|
||||
replace the suffix-less or ldap module variant with the odbc module variant.
|
||||
Keep in mind that you cannot have several variants of the same module loaded!</P><P> <A NAME="odbc"></A> </P><!--TOC subsection ODBC Compatible-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc33">3.2.4</A>  <A HREF="#odbc">ODBC Compatible</A></H3><!--SEC END --><P> <A NAME="odbc"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc34">3.2.4</A>  <A HREF="#odbc">ODBC Compatible</A></H3><!--SEC END --><P> <A NAME="odbc"></A>
|
||||
</P><P>Although this section will describe <TT>ejabberd</TT>’s configuration when you want to
|
||||
use the ODBC driver, it does not describe the installation and database creation
|
||||
of your database. Check the documentation of your database. The tutorial <A HREF="http://support.process-one.net/doc/display/MESSENGER/Using+ejabberd+with+MySQL+native+driver">Using ejabberd with MySQL native driver</A> also can help you. Note that the tutorial
|
||||
@ -1375,7 +1395,7 @@ database, just make sure that your database is running well (see previous
|
||||
sections), and replace the suffix-less or ldap module variant with the odbc
|
||||
module variant. Keep in mind that you cannot have several variants of the same
|
||||
module loaded!</P><P> <A NAME="ldap"></A> </P><!--TOC subsection LDAP-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc34">3.2.5</A>  <A HREF="#ldap">LDAP</A></H3><!--SEC END --><P> <A NAME="ldap"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc35">3.2.5</A>  <A HREF="#ldap">LDAP</A></H3><!--SEC END --><P> <A NAME="ldap"></A>
|
||||
</P><P><TT>ejabberd</TT> has built-in LDAP support. You can authenticate users against LDAP
|
||||
server and use LDAP directory as vCard storage. Shared rosters are not supported
|
||||
yet.</P><P> <A NAME="ldapconnection"></A> </P><!--TOC subsubsection Connection-->
|
||||
@ -1552,7 +1572,7 @@ configuration is shown below:</P><PRE CLASS="verbatim">{auth_method, ldap}.
|
||||
...
|
||||
]}.
|
||||
</PRE><P> <A NAME="modules"></A> </P><!--TOC section Modules Configuration-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc35">3.3</A>  <A HREF="#modules">Modules Configuration</A></H2><!--SEC END --><P> <A NAME="modules"></A>
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc36">3.3</A>  <A HREF="#modules">Modules Configuration</A></H2><!--SEC END --><P> <A NAME="modules"></A>
|
||||
</P><P>The option <TT>modules</TT> defines the list of modules that will be loaded after
|
||||
<TT>ejabberd</TT>’s startup. Each entry in the list is a tuple in which the first
|
||||
element is the name of a module and the second is a list of options for that
|
||||
@ -1574,7 +1594,7 @@ all entries end with a comma:
|
||||
{mod_version, []}
|
||||
]}.
|
||||
</PRE></LI></UL><P> <A NAME="modoverview"></A> </P><!--TOC subsection Modules Overview-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc36">3.3.1</A>  <A HREF="#modoverview">Modules Overview</A></H3><!--SEC END --><P> <A NAME="modoverview"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc37">3.3.1</A>  <A HREF="#modoverview">Modules Overview</A></H3><!--SEC END --><P> <A NAME="modoverview"></A>
|
||||
</P><P>The following table lists all modules included in <TT>ejabberd</TT>.</P><BLOCKQUOTE CLASS="table"><DIV CLASS="center"><DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV>
|
||||
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1><TR><TD ALIGN=left NOWRAP><B>Module</B></TD><TD ALIGN=left NOWRAP><B>Feature</B></TD><TD ALIGN=left NOWRAP><B>Dependencies</B></TD></TR>
|
||||
<TR><TD ALIGN=left NOWRAP><TT>mod_adhoc</TT></TD><TD ALIGN=left NOWRAP>Ad-Hoc Commands (<A HREF="http://www.xmpp.org/extensions/xep-0050.html">XEP-0050</A>)</TD><TD ALIGN=left NOWRAP> </TD></TR>
|
||||
@ -1636,7 +1656,7 @@ Last connection date and time: Use <TT>mod_last_odbc</TT> instead of
|
||||
<TT>ejabberd</TT> website. Please remember that these contributions might not work or
|
||||
that they can contain severe bugs and security leaks. Therefore, use them at
|
||||
your own risk!</P><P> <A NAME="modcommonoptions"></A> </P><!--TOC subsection Common Options-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc37">3.3.2</A>  <A HREF="#modcommonoptions">Common Options</A></H3><!--SEC END --><P> <A NAME="modcommonoptions"></A> </P><P>The following options are used by many modules. Therefore, they are described in
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc38">3.3.2</A>  <A HREF="#modcommonoptions">Common Options</A></H3><!--SEC END --><P> <A NAME="modcommonoptions"></A> </P><P>The following options are used by many modules. Therefore, they are described in
|
||||
this separate section.</P><P> <A NAME="modiqdiscoption"></A> </P><!--TOC subsubsection <TT>iqdisc</TT>-->
|
||||
<H4 CLASS="subsubsection"><!--SEC ANCHOR --><A HREF="#modiqdiscoption"><TT>iqdisc</TT></A></H4><!--SEC END --><P> <A NAME="modiqdiscoption"></A>
|
||||
</P><P>Many modules define handlers for processing IQ queries of different namespaces
|
||||
@ -1688,7 +1708,7 @@ the "@HOST@" keyword must be used:
|
||||
...
|
||||
]}.
|
||||
</PRE><P> <A NAME="modannounce"></A> </P><!--TOC subsection <TT>mod_announce</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc38">3.3.3</A>  <A HREF="#modannounce"><TT>mod_announce</TT></A></H3><!--SEC END --><P> <A NAME="modannounce"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc39">3.3.3</A>  <A HREF="#modannounce"><TT>mod_announce</TT></A></H3><!--SEC END --><P> <A NAME="modannounce"></A>
|
||||
</P><P>This module enables configured users to broadcast announcements and to set
|
||||
the message of the day (MOTD).
|
||||
Configured users can perform these actions with a
|
||||
@ -1752,7 +1772,7 @@ Only administrators can send announcements:
|
||||
</PRE></LI></UL><P>Note that <TT>mod_announce</TT> can be resource intensive on large
|
||||
deployments as it can broadcast lot of messages. This module should be
|
||||
disabled for instances of <TT>ejabberd</TT> with hundreds of thousands users.</P><P> <A NAME="moddisco"></A> </P><!--TOC subsection <TT>mod_disco</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc39">3.3.4</A>  <A HREF="#moddisco"><TT>mod_disco</TT></A></H3><!--SEC END --><P> <A NAME="moddisco"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc40">3.3.4</A>  <A HREF="#moddisco"><TT>mod_disco</TT></A></H3><!--SEC END --><P> <A NAME="moddisco"></A>
|
||||
|
||||
|
||||
|
||||
@ -1795,7 +1815,7 @@ To serve a link to the Jabber User Directory on <TT>jabber.org</TT>:
|
||||
...
|
||||
]}.
|
||||
</PRE></LI></UL><P> <A NAME="modecho"></A> </P><!--TOC subsection <TT>mod_echo</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc40">3.3.5</A>  <A HREF="#modecho"><TT>mod_echo</TT></A></H3><!--SEC END --><P> <A NAME="modecho"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc41">3.3.5</A>  <A HREF="#modecho"><TT>mod_echo</TT></A></H3><!--SEC END --><P> <A NAME="modecho"></A>
|
||||
</P><P>This module simply echoes any Jabber
|
||||
packet back to the sender. This mirror can be of interest for
|
||||
<TT>ejabberd</TT> and Jabber client debugging.</P><P>Options:
|
||||
@ -1815,7 +1835,7 @@ of them all?
|
||||
...
|
||||
]}.
|
||||
</PRE><P> <A NAME="modirc"></A> </P><!--TOC subsection <TT>mod_irc</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc41">3.3.6</A>  <A HREF="#modirc"><TT>mod_irc</TT></A></H3><!--SEC END --><P> <A NAME="modirc"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc42">3.3.6</A>  <A HREF="#modirc"><TT>mod_irc</TT></A></H3><!--SEC END --><P> <A NAME="modirc"></A>
|
||||
</P><P>This module is an IRC transport that can be used to join channels on IRC
|
||||
servers.</P><P>End user information:
|
||||
|
||||
@ -1874,7 +1894,7 @@ our domains and on other servers.
|
||||
...
|
||||
]}.
|
||||
</PRE></LI></UL><P> <A NAME="modlast"></A> </P><!--TOC subsection <TT>mod_last</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc42">3.3.7</A>  <A HREF="#modlast"><TT>mod_last</TT></A></H3><!--SEC END --><P> <A NAME="modlast"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc43">3.3.7</A>  <A HREF="#modlast"><TT>mod_last</TT></A></H3><!--SEC END --><P> <A NAME="modlast"></A>
|
||||
</P><P>This module adds support for Last Activity (<A HREF="http://www.xmpp.org/extensions/xep-0012.html">XEP-0012</A>). It can be used to
|
||||
discover when a disconnected user last accessed the server, to know when a
|
||||
connected user was last active on the server, or to query the uptime of the
|
||||
@ -1883,7 +1903,7 @@ connected user was last active on the server, or to query the uptime of the
|
||||
<B><TT>iqdisc</TT></B></DT><DD CLASS="dd-description"> This specifies
|
||||
the processing discipline for Last activity (<TT>jabber:iq:last</TT>) IQ queries (see section <A HREF="#modiqdiscoption">3.3.2</A>).
|
||||
</DD></DL><P> <A NAME="modmuc"></A> </P><!--TOC subsection <TT>mod_muc</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc43">3.3.8</A>  <A HREF="#modmuc"><TT>mod_muc</TT></A></H3><!--SEC END --><P> <A NAME="modmuc"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc44">3.3.8</A>  <A HREF="#modmuc"><TT>mod_muc</TT></A></H3><!--SEC END --><P> <A NAME="modmuc"></A>
|
||||
</P><P>With this module enabled, your server will support Multi-User Chat
|
||||
(<A HREF="http://www.xmpp.org/extensions/xep-0045.html">XEP-0045</A>). End users will be able to join text conferences.</P><P>Some of the features of Multi-User Chat:
|
||||
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
@ -2083,7 +2103,7 @@ newly created chatrooms have by default those options.
|
||||
...
|
||||
]}.
|
||||
</PRE></LI></UL><P> <A NAME="modmuclog"></A> </P><!--TOC subsection <TT>mod_muc_log</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc44">3.3.9</A>  <A HREF="#modmuclog"><TT>mod_muc_log</TT></A></H3><!--SEC END --><P> <A NAME="modmuclog"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc45">3.3.9</A>  <A HREF="#modmuclog"><TT>mod_muc_log</TT></A></H3><!--SEC END --><P> <A NAME="modmuclog"></A>
|
||||
</P><P>This module enables optional logging of Multi-User Chat (MUC) conversations to
|
||||
HTML. Once you enable this module, users can join a chatroom using a MUC capable
|
||||
Jabber client, and if they have enough privileges, they can request the
|
||||
@ -2092,8 +2112,8 @@ configuration form in which they can set the option to enable chatroom logging.<
|
||||
Chatroom details are added on top of each page: room title, JID,
|
||||
author, subject and configuration.
|
||||
</LI><LI CLASS="li-itemize">
|
||||
Room title and JID are links to join the chatroom (using
|
||||
<A HREF="http://www.ietf.org/rfc/rfc4622.txt">XMPP URIs</A>).
|
||||
The room JID in the generated HTML is a link to join the chatroom (using
|
||||
<A HREF="http://www.xmpp.org/rfcs/rfc5122.html">XMPP URI</A>).
|
||||
</LI><LI CLASS="li-itemize">Subject and chatroom configuration changes are tracked and displayed.
|
||||
</LI><LI CLASS="li-itemize">Joins, leaves, nick changes, kicks, bans and ‘/me’ are tracked and
|
||||
displayed, including the reason if available.
|
||||
@ -2190,7 +2210,7 @@ top link will be the default <CODE><a href="/">Home</a></CODE>.
|
||||
...
|
||||
]}.
|
||||
</PRE></LI></UL><P> <A NAME="modoffline"></A> </P><!--TOC subsection <TT>mod_offline</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc45">3.3.10</A>  <A HREF="#modoffline"><TT>mod_offline</TT></A></H3><!--SEC END --><P> <A NAME="modoffline"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc46">3.3.10</A>  <A HREF="#modoffline"><TT>mod_offline</TT></A></H3><!--SEC END --><P> <A NAME="modoffline"></A>
|
||||
</P><P>This module implements offline message storage. This means that all messages
|
||||
sent to an offline user will be stored on the server until that user comes
|
||||
online again. Thus it is very similar to how email works. Note that
|
||||
@ -2201,7 +2221,7 @@ is use to set a max number of offline messages per user (quota). Its
|
||||
value can be either <TT>infinity</TT> or a strictly positive
|
||||
integer. The default value is <TT>infinity</TT>.
|
||||
</DD></DL><P> <A NAME="modprivacy"></A> </P><!--TOC subsection <TT>mod_privacy</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc46">3.3.11</A>  <A HREF="#modprivacy"><TT>mod_privacy</TT></A></H3><!--SEC END --><P> <A NAME="modprivacy"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc47">3.3.11</A>  <A HREF="#modprivacy"><TT>mod_privacy</TT></A></H3><!--SEC END --><P> <A NAME="modprivacy"></A>
|
||||
</P><P>This module implements Blocking Communication (also known as Privacy Rules)
|
||||
as defined in section 10 from XMPP IM. If end users have support for it in
|
||||
their Jabber client, they will be able to:
|
||||
@ -2229,7 +2249,7 @@ subscription type (or globally).
|
||||
<B><TT>iqdisc</TT></B></DT><DD CLASS="dd-description"> This specifies
|
||||
the processing discipline for Blocking Communication (<TT>jabber:iq:privacy</TT>) IQ queries (see section <A HREF="#modiqdiscoption">3.3.2</A>).
|
||||
</DD></DL><P> <A NAME="modprivate"></A> </P><!--TOC subsection <TT>mod_private</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc47">3.3.12</A>  <A HREF="#modprivate"><TT>mod_private</TT></A></H3><!--SEC END --><P> <A NAME="modprivate"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc48">3.3.12</A>  <A HREF="#modprivate"><TT>mod_private</TT></A></H3><!--SEC END --><P> <A NAME="modprivate"></A>
|
||||
</P><P>This module adds support for Private XML Storage (<A HREF="http://www.xmpp.org/extensions/xep-0049.html">XEP-0049</A>):
|
||||
</P><BLOCKQUOTE CLASS="quote">
|
||||
Using this method, Jabber entities can store private data on the server and
|
||||
@ -2241,7 +2261,7 @@ of client-specific preferences; another is Bookmark Storage (<A HREF="http://www
|
||||
<B><TT>iqdisc</TT></B></DT><DD CLASS="dd-description"> This specifies
|
||||
the processing discipline for Private XML Storage (<TT>jabber:iq:private</TT>) IQ queries (see section <A HREF="#modiqdiscoption">3.3.2</A>).
|
||||
</DD></DL><P> <A NAME="modproxy"></A> </P><!--TOC subsection <TT>mod_proxy65</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc48">3.3.13</A>  <A HREF="#modproxy"><TT>mod_proxy65</TT></A></H3><!--SEC END --><P> <A NAME="modproxy"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc49">3.3.13</A>  <A HREF="#modproxy"><TT>mod_proxy65</TT></A></H3><!--SEC END --><P> <A NAME="modproxy"></A>
|
||||
</P><P>This module implements SOCKS5 Bytestreams (<A HREF="http://www.xmpp.org/extensions/xep-0065.html">XEP-0065</A>).
|
||||
It allows <TT>ejabberd</TT> to act as a file transfer proxy between two
|
||||
XMPP clients.</P><P>Options:
|
||||
@ -2296,7 +2316,7 @@ The simpliest configuration of the module:
|
||||
...
|
||||
]}.
|
||||
</PRE></LI></UL><P> <A NAME="modpubsub"></A> </P><!--TOC subsection <TT>mod_pubsub</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc49">3.3.14</A>  <A HREF="#modpubsub"><TT>mod_pubsub</TT></A></H3><!--SEC END --><P> <A NAME="modpubsub"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc50">3.3.14</A>  <A HREF="#modpubsub"><TT>mod_pubsub</TT></A></H3><!--SEC END --><P> <A NAME="modpubsub"></A>
|
||||
</P><P>This module offers a Publish-Subscribe Service (<A HREF="http://www.xmpp.org/extensions/xep-0060.html">XEP-0060</A>).
|
||||
The functionality in <TT>mod_pubsub</TT> can be extended using plugins.
|
||||
The plugin that implements PEP (Personal Eventing via Pubsub) (<A HREF="http://www.xmpp.org/extensions/xep-0163.html">XEP-0163</A>)
|
||||
@ -2327,7 +2347,7 @@ and is shared by all node plugins.
|
||||
...
|
||||
]}.
|
||||
</PRE><P> <A NAME="modregister"></A> </P><!--TOC subsection <TT>mod_register</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc50">3.3.15</A>  <A HREF="#modregister"><TT>mod_register</TT></A></H3><!--SEC END --><P> <A NAME="modregister"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc51">3.3.15</A>  <A HREF="#modregister"><TT>mod_register</TT></A></H3><!--SEC END --><P> <A NAME="modregister"></A>
|
||||
</P><P>This module adds support for In-Band Registration (<A HREF="http://www.xmpp.org/extensions/xep-0077.html">XEP-0077</A>). This protocol
|
||||
enables end users to use a Jabber client to:
|
||||
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
@ -2343,6 +2363,7 @@ restrictions by default).
|
||||
</DD><DT CLASS="dt-description"><B><TT>welcome_message</TT></B></DT><DD CLASS="dd-description"> Set a welcome message that
|
||||
is sent to each newly registered account. The first string is the subject, and
|
||||
the second string is the message body.
|
||||
In the body you can set a newline with the characters: <TT>~n</TT>.
|
||||
</DD><DT CLASS="dt-description"><B><TT>registration_watchers</TT></B></DT><DD CLASS="dd-description"> This option defines a
|
||||
list of JIDs which will be notified each time a new account is registered.
|
||||
</DD><DT CLASS="dt-description"><B><TT>iqdisc</TT></B></DT><DD CLASS="dd-description"> This specifies
|
||||
@ -2393,19 +2414,19 @@ Also define a registration timeout of one hour:
|
||||
...
|
||||
{mod_register,
|
||||
[
|
||||
{welcome_message, {"Welcome!", "Welcome to this Jabber server. Check http://www.jabber.org"}},
|
||||
{welcome_message, {"Welcome!", "Hi.~nWelcome to this Jabber server.~n Check http://www.jabber.org~n~nBye"}},
|
||||
{registration_watchers, ["admin1@example.org", "boss@example.net"]}
|
||||
]},
|
||||
...
|
||||
]}.
|
||||
</PRE></LI></UL><P> <A NAME="modroster"></A> </P><!--TOC subsection <TT>mod_roster</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc51">3.3.16</A>  <A HREF="#modroster"><TT>mod_roster</TT></A></H3><!--SEC END --><P> <A NAME="modroster"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc52">3.3.16</A>  <A HREF="#modroster"><TT>mod_roster</TT></A></H3><!--SEC END --><P> <A NAME="modroster"></A>
|
||||
</P><P>This module implements roster management as defined in <A HREF="http://www.xmpp.org/specs/rfc3921.html#roster">RFC 3921: XMPP IM</A>.</P><P>Options:
|
||||
</P><DL CLASS="description"><DT CLASS="dt-description">
|
||||
<B><TT>iqdisc</TT></B></DT><DD CLASS="dd-description"> This specifies
|
||||
the processing discipline for Roster Management (<TT>jabber:iq:roster</TT>) IQ queries (see section <A HREF="#modiqdiscoption">3.3.2</A>).
|
||||
</DD></DL><P> <A NAME="modservicelog"></A> </P><!--TOC subsection <TT>mod_service_log</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc52">3.3.17</A>  <A HREF="#modservicelog"><TT>mod_service_log</TT></A></H3><!--SEC END --><P> <A NAME="modservicelog"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc53">3.3.17</A>  <A HREF="#modservicelog"><TT>mod_service_log</TT></A></H3><!--SEC END --><P> <A NAME="modservicelog"></A>
|
||||
</P><P>This module adds support for logging end user packets via a Jabber message
|
||||
auditing service such as
|
||||
<A HREF="http://www.funkypenguin.info/project/bandersnatch/">Bandersnatch</A>. All user
|
||||
@ -2435,7 +2456,7 @@ To log all end user packets to the Bandersnatch service running on
|
||||
...
|
||||
]}.
|
||||
</PRE></LI></UL><P> <A NAME="modsharedroster"></A> </P><!--TOC subsection <TT>mod_shared_roster</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc53">3.3.18</A>  <A HREF="#modsharedroster"><TT>mod_shared_roster</TT></A></H3><!--SEC END --><P> <A NAME="modsharedroster"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc54">3.3.18</A>  <A HREF="#modsharedroster"><TT>mod_shared_roster</TT></A></H3><!--SEC END --><P> <A NAME="modsharedroster"></A>
|
||||
</P><P>This module enables you to create shared roster groups. This means that you can
|
||||
create groups of people that can see members from (other) groups in their
|
||||
rosters. The big advantages of this feature are that end users do not need to
|
||||
@ -2510,7 +2531,7 @@ roster groups as shown in the following table:
|
||||
</TABLE>
|
||||
<DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV></DIV></BLOCKQUOTE>
|
||||
</LI></UL><P> <A NAME="modstats"></A> </P><!--TOC subsection <TT>mod_stats</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc54">3.3.19</A>  <A HREF="#modstats"><TT>mod_stats</TT></A></H3><!--SEC END --><P> <A NAME="modstats"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc55">3.3.19</A>  <A HREF="#modstats"><TT>mod_stats</TT></A></H3><!--SEC END --><P> <A NAME="modstats"></A>
|
||||
</P><P>This module adds support for Statistics Gathering (<A HREF="http://www.xmpp.org/extensions/xep-0039.html">XEP-0039</A>). This protocol
|
||||
allows you to retrieve next statistics from your <TT>ejabberd</TT> deployment:
|
||||
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
@ -2542,14 +2563,14 @@ by sending:
|
||||
</query>
|
||||
</iq>
|
||||
</PRE></LI></UL><P> <A NAME="modtime"></A> </P><!--TOC subsection <TT>mod_time</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc55">3.3.20</A>  <A HREF="#modtime"><TT>mod_time</TT></A></H3><!--SEC END --><P> <A NAME="modtime"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc56">3.3.20</A>  <A HREF="#modtime"><TT>mod_time</TT></A></H3><!--SEC END --><P> <A NAME="modtime"></A>
|
||||
</P><P>This module features support for Entity Time (<A HREF="http://www.xmpp.org/extensions/xep-0090.html">XEP-0090</A>). By using this XEP,
|
||||
you are able to discover the time at another entity’s location.</P><P>Options:
|
||||
</P><DL CLASS="description"><DT CLASS="dt-description">
|
||||
<B><TT>iqdisc</TT></B></DT><DD CLASS="dd-description"> This specifies
|
||||
the processing discipline for Entity Time (<TT>jabber:iq:time</TT>) IQ queries (see section <A HREF="#modiqdiscoption">3.3.2</A>).
|
||||
</DD></DL><P> <A NAME="modvcard"></A> </P><!--TOC subsection <TT>mod_vcard</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc56">3.3.21</A>  <A HREF="#modvcard"><TT>mod_vcard</TT></A></H3><!--SEC END --><P> <A NAME="modvcard"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc57">3.3.21</A>  <A HREF="#modvcard"><TT>mod_vcard</TT></A></H3><!--SEC END --><P> <A NAME="modvcard"></A>
|
||||
</P><P>This module allows end users to store and retrieve their vCard, and to retrieve
|
||||
other users vCards, as defined in vcard-temp (<A HREF="http://www.xmpp.org/extensions/xep-0054.html">XEP-0054</A>). The module also
|
||||
implements an uncomplicated Jabber User Directory based on the vCards of
|
||||
@ -2604,7 +2625,7 @@ and that all virtual hosts will be searched instead of only the current one:
|
||||
...
|
||||
]}.
|
||||
</PRE></LI></UL><P> <A NAME="modvcardldap"></A> </P><!--TOC subsection <TT>mod_vcard_ldap</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc57">3.3.22</A>  <A HREF="#modvcardldap"><TT>mod_vcard_ldap</TT></A></H3><!--SEC END --><P> <A NAME="modvcardldap"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc58">3.3.22</A>  <A HREF="#modvcardldap"><TT>mod_vcard_ldap</TT></A></H3><!--SEC END --><P> <A NAME="modvcardldap"></A>
|
||||
</P><P><TT>ejabberd</TT> can map LDAP attributes to vCard fields. This behaviour is
|
||||
implemented in the <TT>mod_vcard_ldap</TT> module. This module does not depend on the
|
||||
authentication method (see <A HREF="#ldapauth">3.2.5</A>).</P><P>The <TT>mod_vcard_ldap</TT> module has
|
||||
@ -2778,7 +2799,7 @@ searching his info in LDAP.</P></LI><LI CLASS="li-itemize"><TT>ldap_vcard_map</T
|
||||
{"Nickname", "NICKNAME"}
|
||||
]},
|
||||
</PRE></LI></UL><P> <A NAME="modversion"></A> </P><!--TOC subsection <TT>mod_version</TT>-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc58">3.3.23</A>  <A HREF="#modversion"><TT>mod_version</TT></A></H3><!--SEC END --><P> <A NAME="modversion"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc59">3.3.23</A>  <A HREF="#modversion"><TT>mod_version</TT></A></H3><!--SEC END --><P> <A NAME="modversion"></A>
|
||||
</P><P>This module implements Software Version (<A HREF="http://www.xmpp.org/extensions/xep-0092.html">XEP-0092</A>). Consequently, it
|
||||
answers <TT>ejabberd</TT>’s version when queried.</P><P>Options:
|
||||
</P><DL CLASS="description"><DT CLASS="dt-description">
|
||||
@ -2787,9 +2808,9 @@ The default value is <TT>true</TT>.
|
||||
</DD><DT CLASS="dt-description"><B><TT>iqdisc</TT></B></DT><DD CLASS="dd-description"> This specifies
|
||||
the processing discipline for Software Version (<TT>jabber:iq:version</TT>) IQ queries (see section <A HREF="#modiqdiscoption">3.3.2</A>).
|
||||
</DD></DL><P> <A NAME="manage"></A> </P><!--TOC chapter Managing an <TT>ejabberd</TT> server-->
|
||||
<H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc59">Chapter 4</A>  <A HREF="#manage">Managing an <TT>ejabberd</TT> server</A></H1><!--SEC END --><P> <A NAME="manage"></A> </P><P> <A NAME="ejabberdctl"></A> </P><!--TOC section <TT>ejabberdctl</TT>-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc60">4.1</A>  <A HREF="#ejabberdctl"><TT>ejabberdctl</TT></A></H2><!--SEC END --><P> <A NAME="ejabberdctl"></A> </P><P> <A NAME="commands"></A> </P><!--TOC subsection Commands-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc61">4.1.1</A>  <A HREF="#commands">Commands</A></H3><!--SEC END --><P> <A NAME="commands"></A> </P><P>The <TT>ejabberdctl</TT> command line administration script allows to start, stop and perform
|
||||
<H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc60">Chapter 4</A>  <A HREF="#manage">Managing an <TT>ejabberd</TT> server</A></H1><!--SEC END --><P> <A NAME="manage"></A> </P><P> <A NAME="ejabberdctl"></A> </P><!--TOC section <TT>ejabberdctl</TT>-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc61">4.1</A>  <A HREF="#ejabberdctl"><TT>ejabberdctl</TT></A></H2><!--SEC END --><P> <A NAME="ejabberdctl"></A> </P><P> <A NAME="commands"></A> </P><!--TOC subsection Commands-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc62">4.1.1</A>  <A HREF="#commands">Commands</A></H3><!--SEC END --><P> <A NAME="commands"></A> </P><P>The <TT>ejabberdctl</TT> command line administration script allows to start, stop and perform
|
||||
many other administrative tasks in a local or remote <TT>ejabberd</TT> server.</P><P>When <TT>ejabberdctl</TT> is executed without any parameter,
|
||||
it displays the available options. If there isn’t an <TT>ejabberd</TT> server running,
|
||||
the available parameters are:
|
||||
@ -2822,7 +2843,7 @@ and other codes may be used for specifical results.
|
||||
This can be used by other scripts to determine automatically
|
||||
if a command succedded or failed,
|
||||
for example using: <TT>echo $?</TT></P><P> <A NAME="erlangconfiguration"></A> </P><!--TOC subsection Erlang runtime system-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc62">4.1.2</A>  <A HREF="#erlangconfiguration">Erlang runtime system</A></H3><!--SEC END --><P> <A NAME="erlangconfiguration"></A> </P><P><TT>ejabberd</TT> is an Erlang/OTP application that runs inside an Erlang runtime system.
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc63">4.1.2</A>  <A HREF="#erlangconfiguration">Erlang runtime system</A></H3><!--SEC END --><P> <A NAME="erlangconfiguration"></A> </P><P><TT>ejabberd</TT> is an Erlang/OTP application that runs inside an Erlang runtime system.
|
||||
This system is configured using environment variables and command line parameters.
|
||||
The <TT>ejabberdctl</TT> administration script uses many of those possibilities.
|
||||
You can configure some of them with the file <TT>ejabberdctl.cfg</TT>,
|
||||
@ -2889,7 +2910,7 @@ Starts the Erlang system detached from the system console.
|
||||
</DD></DL><P>
|
||||
Note that some characters need to be escaped when used in shell scripts, for instance <CODE>"</CODE> and <CODE>{}</CODE>.
|
||||
You can find other options in the Erlang manual page (<TT>erl -man erl</TT>).</P><P> <A NAME="webadmin"></A> </P><!--TOC section Web Admin-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc63">4.2</A>  <A HREF="#webadmin">Web Admin</A></H2><!--SEC END --><P> <A NAME="webadmin"></A>
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc64">4.2</A>  <A HREF="#webadmin">Web Admin</A></H2><!--SEC END --><P> <A NAME="webadmin"></A>
|
||||
</P><P>The <TT>ejabberd</TT> Web Admin allows to administer most of <TT>ejabberd</TT> using a web browser.</P><P>This feature is enabled by default:
|
||||
a <TT>ejabberd_http</TT> listener with the option <TT>web_admin</TT> (see
|
||||
section <A HREF="#listened">3.1.3</A>) is included in the listening ports. Then you can open
|
||||
@ -2949,15 +2970,15 @@ web browser to <CODE>https://192.168.1.1:5280/admin/</CODE>:
|
||||
...
|
||||
]}.
|
||||
</PRE></LI></UL><P> <A NAME="adhoccommands"></A> </P><!--TOC section Ad-hoc Commands-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc64">4.3</A>  <A HREF="#adhoccommands">Ad-hoc Commands</A></H2><!--SEC END --><P> <A NAME="adhoccommands"></A> </P><P>If you enable <TT>mod_configure</TT> and <TT>mod_adhoc</TT>,
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc65">4.3</A>  <A HREF="#adhoccommands">Ad-hoc Commands</A></H2><!--SEC END --><P> <A NAME="adhoccommands"></A> </P><P>If you enable <TT>mod_configure</TT> and <TT>mod_adhoc</TT>,
|
||||
you can perform several administrative tasks in <TT>ejabberd</TT>
|
||||
with a Jabber client.
|
||||
The client must support Ad-Hoc Commands (<A HREF="http://www.xmpp.org/extensions/xep-0050.html">XEP-0050</A>),
|
||||
and you must login in the Jabber server with
|
||||
an account with proper privileges.</P><P> <A NAME="changeerlangnodename"></A> </P><!--TOC section Change Computer Hostname-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc65">4.4</A>  <A HREF="#changeerlangnodename">Change Computer Hostname</A></H2><!--SEC END --><P> <A NAME="changeerlangnodename"></A> </P><P><TT>ejabberd</TT> uses the distributed Mnesia database.
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc66">4.4</A>  <A HREF="#changeerlangnodename">Change Computer Hostname</A></H2><!--SEC END --><P> <A NAME="changeerlangnodename"></A> </P><P><TT>ejabberd</TT> uses the distributed Mnesia database.
|
||||
Being distributed, Mnesia enforces consistency of its file,
|
||||
so it stores the name of the Erlang node in it.
|
||||
so it stores the name of the Erlang node in it (see section <A HREF="#nodename">5.4</A>).
|
||||
The name of an Erlang node includes the hostname of the computer.
|
||||
So, the name of the Erlang node changes
|
||||
if you change the name of the machine in which <TT>ejabberd</TT> runs,
|
||||
@ -2971,8 +2992,8 @@ you must follow these instructions:
|
||||
For example:
|
||||
<PRE CLASS="verbatim">ejabberdctl restore /tmp/ejabberd-oldhost.backup
|
||||
</PRE></LI></OL><P> <A NAME="secure"></A> </P><!--TOC chapter Securing <TT>ejabberd</TT>-->
|
||||
<H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc66">Chapter 5</A>  <A HREF="#secure">Securing <TT>ejabberd</TT></A></H1><!--SEC END --><P> <A NAME="secure"></A> </P><P> <A NAME="firewall"></A> </P><!--TOC section Firewall Settings-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc67">5.1</A>  <A HREF="#firewall">Firewall Settings</A></H2><!--SEC END --><P> <A NAME="firewall"></A>
|
||||
<H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc67">Chapter 5</A>  <A HREF="#secure">Securing <TT>ejabberd</TT></A></H1><!--SEC END --><P> <A NAME="secure"></A> </P><P> <A NAME="firewall"></A> </P><!--TOC section Firewall Settings-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc68">5.1</A>  <A HREF="#firewall">Firewall Settings</A></H2><!--SEC END --><P> <A NAME="firewall"></A>
|
||||
</P><P>You need to take the following TCP ports in mind when configuring your firewall:
|
||||
</P><BLOCKQUOTE CLASS="table"><DIV CLASS="center"><DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV>
|
||||
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1><TR><TD ALIGN=left NOWRAP><B>Port</B></TD><TD ALIGN=left NOWRAP><B>Description</B></TD></TR>
|
||||
@ -2983,7 +3004,7 @@ you must follow these instructions:
|
||||
<TR><TD ALIGN=left NOWRAP>port range</TD><TD ALIGN=left NOWRAP>Used for connections between Erlang nodes. This range is configurable (see section <A HREF="#epmd">5.2</A>).</TD></TR>
|
||||
</TABLE>
|
||||
<DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV></DIV></BLOCKQUOTE><P> <A NAME="epmd"></A> </P><!--TOC section epmd-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc68">5.2</A>  <A HREF="#epmd">epmd</A></H2><!--SEC END --><P> <A NAME="epmd"></A> </P><P><A HREF="http://www.erlang.org/doc/man/epmd.html">epmd (Erlang Port Mapper Daemon)</A>
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc69">5.2</A>  <A HREF="#epmd">epmd</A></H2><!--SEC END --><P> <A NAME="epmd"></A> </P><P><A HREF="http://www.erlang.org/doc/man/epmd.html">epmd (Erlang Port Mapper Daemon)</A>
|
||||
is a small name server included in Erlang/OTP
|
||||
and used by Erlang programs when establishing distributed Erlang communications.
|
||||
<TT>ejabberd</TT> needs <TT>epmd</TT> to use <TT>ejabberdctl</TT> and also when clustering <TT>ejabberd</TT> nodes.
|
||||
@ -3008,9 +3029,10 @@ but can be configured in the file <TT>ejabberdctl.cfg</TT>.
|
||||
The Erlang command-line parameter used internally is, for example:
|
||||
</P><PRE CLASS="verbatim">erl ... -kernel inet_dist_listen_min 4370 inet_dist_listen_max 4375
|
||||
</PRE><P> <A NAME="cookie"></A> </P><!--TOC section Erlang Cookie-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc69">5.3</A>  <A HREF="#cookie">Erlang Cookie</A></H2><!--SEC END --><P> <A NAME="cookie"></A> </P><P>The Erlang cookie is a string with numbers and letters.
|
||||
An Erlang node reads the cookie at startup from the command-line parameter <TT>-setcookie</TT>
|
||||
or from a cookie file.
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc70">5.3</A>  <A HREF="#cookie">Erlang Cookie</A></H2><!--SEC END --><P> <A NAME="cookie"></A> </P><P>The Erlang cookie is a string with numbers and letters.
|
||||
An Erlang node reads the cookie at startup from the command-line parameter <TT>-setcookie</TT>.
|
||||
If not indicated, the cookie is read from the cookie file <TT>$HOME/.erlang.cookie</TT>.
|
||||
If this file does not exist, it is created immediately with a random cookie.
|
||||
Two Erlang nodes communicate only if they have the same cookie.
|
||||
Setting a cookie on the Erlang node allows you to structure your Erlang network
|
||||
and define which nodes are allowed to connect to which.</P><P>Thanks to Erlang cookies, you can prevent access to the Erlang node by mistake,
|
||||
@ -3021,7 +3043,7 @@ to prevent unauthorized access or intrusion to an Erlang node.
|
||||
The communication between Erlang nodes are not encrypted,
|
||||
so the cookie could be read sniffing the traffic on the network.
|
||||
The recommended way to secure the Erlang node is to block the port 4369.</P><P> <A NAME="nodename"></A> </P><!--TOC section Erlang node name-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc70">5.4</A>  <A HREF="#nodename">Erlang node name</A></H2><!--SEC END --><P> <A NAME="nodename"></A> </P><P>An Erlang node may have a node name.
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc71">5.4</A>  <A HREF="#nodename">Erlang node name</A></H2><!--SEC END --><P> <A NAME="nodename"></A> </P><P>An Erlang node may have a node name.
|
||||
The name can be short (if indicated with the command-line parameter <TT>-sname</TT>)
|
||||
or long (if indicated with the parameter <TT>-name</TT>).
|
||||
Starting an Erlang node with -sname limits the communication between Erlang nodes to the LAN.</P><P>Using the option <TT>-sname</TT> instead of <TT>-name</TT> is a simple method
|
||||
@ -3029,10 +3051,30 @@ to difficult unauthorized access to your Erlang node.
|
||||
However, it is not ultimately effective to prevent access to the Erlang node,
|
||||
because it may be possible to fake the fact that you are on another network
|
||||
using a modified version of Erlang <TT>epmd</TT>.
|
||||
The recommended way to secure the Erlang node is to block the port 4369.</P><P> <A NAME="clustering"></A> </P><!--TOC chapter Clustering-->
|
||||
<H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc71">Chapter 6</A>  <A HREF="#clustering">Clustering</A></H1><!--SEC END --><P> <A NAME="clustering"></A>
|
||||
The recommended way to secure the Erlang node is to block the port 4369.</P><P> <A NAME="secure-files"></A> </P><!--TOC section Securing sensible files-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc72">5.5</A>  <A HREF="#secure-files">Securing sensible files</A></H2><!--SEC END --><P> <A NAME="secure-files"></A> </P><P><TT>ejabberd</TT> stores sensible data in the file system either in plain text or binary files.
|
||||
The file system permissions should be set to only allow the proper user to read,
|
||||
write and execute those files and directories.</P><DL CLASS="description"><DT CLASS="dt-description">
|
||||
<B><TT>ejabberd configuration file: /etc/ejabberd/ejabberd.cfg</TT></B></DT><DD CLASS="dd-description">
|
||||
Contains the JID of administrators
|
||||
and passwords of external components.
|
||||
The backup files probably contain also this information,
|
||||
so it is preferable to secure the whole <TT>/etc/ejabberd/</TT> directory.
|
||||
</DD><DT CLASS="dt-description"><B><TT>ejabberd service log: /var/log/ejabberd/ejabberd.log</TT></B></DT><DD CLASS="dd-description">
|
||||
Contains IP addresses of clients.
|
||||
If the loglevel is set to 5, it contains whole conversations and passwords.
|
||||
If a logrotate system is used, there may be several log files with similar information,
|
||||
so it is preferable to secure the whole <TT>/var/log/ejabberd/</TT> directory.
|
||||
</DD><DT CLASS="dt-description"><B><TT>Mnesia database spool files: /var/lib/ejabberd/db/*</TT></B></DT><DD CLASS="dd-description">
|
||||
The files store binary data, but some parts are still readable.
|
||||
The files are generated by Mnesia and their permissions cannot be set directly,
|
||||
so it is preferable to secure the whole <TT>/var/lib/ejabberd/db/</TT> directory.
|
||||
</DD><DT CLASS="dt-description"><B><TT>Erlang cookie file: /var/lib/ejabberd/.erlang.cookie</TT></B></DT><DD CLASS="dd-description">
|
||||
See section <A HREF="#cookie">5.3</A>.
|
||||
</DD></DL><P> <A NAME="clustering"></A> </P><!--TOC chapter Clustering-->
|
||||
<H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc73">Chapter 6</A>  <A HREF="#clustering">Clustering</A></H1><!--SEC END --><P> <A NAME="clustering"></A>
|
||||
</P><P> <A NAME="howitworks"></A> </P><!--TOC section How it Works-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc72">6.1</A>  <A HREF="#howitworks">How it Works</A></H2><!--SEC END --><P> <A NAME="howitworks"></A>
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc74">6.1</A>  <A HREF="#howitworks">How it Works</A></H2><!--SEC END --><P> <A NAME="howitworks"></A>
|
||||
</P><P>A Jabber domain is served by one or more <TT>ejabberd</TT> nodes. These nodes can
|
||||
be run on different machines that are connected via a network. They all
|
||||
must have the ability to connect to port 4369 of all another nodes, and must
|
||||
@ -3046,29 +3088,29 @@ router,
|
||||
</LI><LI CLASS="li-itemize">session manager,
|
||||
</LI><LI CLASS="li-itemize">s2s manager.
|
||||
</LI></UL><P> <A NAME="router"></A> </P><!--TOC subsection Router-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc73">6.1.1</A>  <A HREF="#router">Router</A></H3><!--SEC END --><P> <A NAME="router"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc75">6.1.1</A>  <A HREF="#router">Router</A></H3><!--SEC END --><P> <A NAME="router"></A>
|
||||
</P><P>This module is the main router of Jabber packets on each node. It
|
||||
routes them based on their destination’s domains. It uses a global
|
||||
routing table. The domain of the packet’s destination is searched in the
|
||||
routing table, and if it is found, the packet is routed to the
|
||||
appropriate process. If not, it is sent to the s2s manager.</P><P> <A NAME="localrouter"></A> </P><!--TOC subsection Local Router-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc74">6.1.2</A>  <A HREF="#localrouter">Local Router</A></H3><!--SEC END --><P> <A NAME="localrouter"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc76">6.1.2</A>  <A HREF="#localrouter">Local Router</A></H3><!--SEC END --><P> <A NAME="localrouter"></A>
|
||||
</P><P>This module routes packets which have a destination domain equal to
|
||||
one of this server’s host names. If the destination JID has a non-empty user
|
||||
part, it is routed to the session manager, otherwise it is processed depending
|
||||
on its content.</P><P> <A NAME="sessionmanager"></A> </P><!--TOC subsection Session Manager-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc75">6.1.3</A>  <A HREF="#sessionmanager">Session Manager</A></H3><!--SEC END --><P> <A NAME="sessionmanager"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc77">6.1.3</A>  <A HREF="#sessionmanager">Session Manager</A></H3><!--SEC END --><P> <A NAME="sessionmanager"></A>
|
||||
</P><P>This module routes packets to local users. It looks up to which user
|
||||
resource a packet must be sent via a presence table. Then the packet is
|
||||
either routed to the appropriate c2s process, or stored in offline
|
||||
storage, or bounced back.</P><P> <A NAME="s2smanager"></A> </P><!--TOC subsection s2s Manager-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc76">6.1.4</A>  <A HREF="#s2smanager">s2s Manager</A></H3><!--SEC END --><P> <A NAME="s2smanager"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc78">6.1.4</A>  <A HREF="#s2smanager">s2s Manager</A></H3><!--SEC END --><P> <A NAME="s2smanager"></A>
|
||||
</P><P>This module routes packets to other Jabber servers. First, it
|
||||
checks if an opened s2s connection from the domain of the packet’s
|
||||
source to the domain of the packet’s destination exists. If that is the case,
|
||||
the s2s manager routes the packet to the process
|
||||
serving this connection, otherwise a new connection is opened.</P><P> <A NAME="cluster"></A> </P><!--TOC section Clustering Setup-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc77">6.2</A>  <A HREF="#cluster">Clustering Setup</A></H2><!--SEC END --><P> <A NAME="cluster"></A>
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc79">6.2</A>  <A HREF="#cluster">Clustering Setup</A></H2><!--SEC END --><P> <A NAME="cluster"></A>
|
||||
</P><P>Suppose you already configured <TT>ejabberd</TT> on one machine named (<TT>first</TT>),
|
||||
and you need to setup another one to make an <TT>ejabberd</TT> cluster. Then do
|
||||
following steps:</P><OL CLASS="enumerate" type=1><LI CLASS="li-enumerate">
|
||||
@ -3102,10 +3144,10 @@ and ‘<CODE>access</CODE>’ options — they will be taken from
|
||||
enabled only on one machine in the cluster).
|
||||
</LI></OL><P>You can repeat these steps for other machines supposed to serve this
|
||||
domain.</P><P> <A NAME="servicelb"></A> </P><!--TOC section Service Load-Balancing-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc78">6.3</A>  <A HREF="#servicelb">Service Load-Balancing</A></H2><!--SEC END --><P> <A NAME="servicelb"></A>
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc80">6.3</A>  <A HREF="#servicelb">Service Load-Balancing</A></H2><!--SEC END --><P> <A NAME="servicelb"></A>
|
||||
</P><P> <A NAME="componentlb"></A> </P><!--TOC subsection Components Load-Balancing-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc79">6.3.1</A>  <A HREF="#componentlb">Components Load-Balancing</A></H3><!--SEC END --><P> <A NAME="componentlb"></A> </P><P> <A NAME="domainlb"></A> </P><!--TOC subsection Domain Load-Balancing Algorithm-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc80">6.3.2</A>  <A HREF="#domainlb">Domain Load-Balancing Algorithm</A></H3><!--SEC END --><P> <A NAME="domainlb"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc81">6.3.1</A>  <A HREF="#componentlb">Components Load-Balancing</A></H3><!--SEC END --><P> <A NAME="componentlb"></A> </P><P> <A NAME="domainlb"></A> </P><!--TOC subsection Domain Load-Balancing Algorithm-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc82">6.3.2</A>  <A HREF="#domainlb">Domain Load-Balancing Algorithm</A></H3><!--SEC END --><P> <A NAME="domainlb"></A>
|
||||
</P><P><TT>ejabberd</TT> includes an algorithm to load balance the components that are plugged on an <TT>ejabberd</TT> cluster. It means that you can plug one or several instances of the same component on each <TT>ejabberd</TT> cluster and that the traffic will be automatically distributed.</P><P>The default distribution algorithm try to deliver to a local instance of a component. If several local instances are available, one instance is chosen randomly. If no instance is available locally, one instance is chosen randomly among the remote component instances.</P><P>If you need a different behaviour, you can change the load balancing behaviour with the option <TT>domain_balancing</TT>. The syntax of the option is the following:</P><PRE CLASS="verbatim">{domain_balancing, "component.example.com", <balancing_criterium>}.
|
||||
</PRE><P>Several balancing criteria are available:
|
||||
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
@ -3114,13 +3156,13 @@ domain.</P><P> <A NAME="servicelb"></A> </P><!--TOC section Service Load-Balanci
|
||||
</LI><LI CLASS="li-itemize"><TT>bare_destination</TT>: the bare JID (without resource) of the packet <TT>to</TT> attribute is used.
|
||||
</LI><LI CLASS="li-itemize"><TT>bare_source</TT>: the bare JID (without resource) of the packet <TT>from</TT> attribute is used.
|
||||
</LI></UL><P>If the value corresponding to the criteria is the same, the same component instance in the cluster will be used.</P><P> <A NAME="lbbuckets"></A> </P><!--TOC subsection Load-Balancing Buckets-->
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc81">6.3.3</A>  <A HREF="#lbbuckets">Load-Balancing Buckets</A></H3><!--SEC END --><P> <A NAME="lbbuckets"></A>
|
||||
<H3 CLASS="subsection"><!--SEC ANCHOR --><A NAME="htoc83">6.3.3</A>  <A HREF="#lbbuckets">Load-Balancing Buckets</A></H3><!--SEC END --><P> <A NAME="lbbuckets"></A>
|
||||
</P><P>When there is a risk of failure for a given component, domain balancing can cause service trouble. If one component is failing the service will not work correctly unless the sessions are rebalanced.</P><P>In this case, it is best to limit the problem to the sessions handled by the failing component. This is what the <TT>domain_balancing_component_number</TT> option does, making the load balancing algorithm not dynamic, but sticky on a fix number of component instances.</P><P>The syntax is the following:
|
||||
</P><PRE CLASS="verbatim">{domain_balancing_component_number, "component.example.com", N}
|
||||
</PRE><P> <A NAME="debugging"></A> </P><!--TOC chapter Debugging-->
|
||||
<H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc82">Chapter 7</A>  <A HREF="#debugging">Debugging</A></H1><!--SEC END --><P> <A NAME="debugging"></A>
|
||||
<H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc84">Chapter 7</A>  <A HREF="#debugging">Debugging</A></H1><!--SEC END --><P> <A NAME="debugging"></A>
|
||||
</P><P> <A NAME="watchdog"></A> </P><!--TOC section Watchdog Alerts-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc83">7.1</A>  <A HREF="#watchdog">Watchdog Alerts</A></H2><!--SEC END --><P> <A NAME="watchdog"></A>
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc85">7.1</A>  <A HREF="#watchdog">Watchdog Alerts</A></H2><!--SEC END --><P> <A NAME="watchdog"></A>
|
||||
</P><P><TT>ejabberd</TT> includes a watchdog mechanism.
|
||||
If a process in the <TT>ejabberd</TT> server consumes too much memory,
|
||||
a message is sent to the Jabber accounts defined with the option
|
||||
@ -3132,7 +3174,7 @@ Example configuration:
|
||||
To remove all watchdog admins, set the option with an empty list:
|
||||
</P><PRE CLASS="verbatim">{watchdog_admins, []}.
|
||||
</PRE><P> <A NAME="logfiles"></A> </P><!--TOC section Log Files-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc84">7.2</A>  <A HREF="#logfiles">Log Files</A></H2><!--SEC END --><P> <A NAME="logfiles"></A> </P><P>An <TT>ejabberd</TT> node writes two log files:
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc86">7.2</A>  <A HREF="#logfiles">Log Files</A></H2><!--SEC END --><P> <A NAME="logfiles"></A> </P><P>An <TT>ejabberd</TT> node writes two log files:
|
||||
</P><DL CLASS="description"><DT CLASS="dt-description">
|
||||
<B><TT>ejabberd.log</TT></B></DT><DD CLASS="dd-description"> is the ejabberd service log, with the messages reported by <TT>ejabberd</TT> code
|
||||
</DD><DT CLASS="dt-description"><B><TT>sasl.log</TT></B></DT><DD CLASS="dd-description"> is the Erlang/OTP system log, with the messages reported by Erlang/OTP using SASL (System Architecture Support Libraries)
|
||||
@ -3149,12 +3191,12 @@ The possible levels are:
|
||||
For example, the default configuration is:
|
||||
</P><PRE CLASS="verbatim">{loglevel, 4}.
|
||||
</PRE><P> <A NAME="debugconsole"></A> </P><!--TOC section Debug Console-->
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc85">7.3</A>  <A HREF="#debugconsole">Debug Console</A></H2><!--SEC END --><P> <A NAME="debugconsole"></A> </P><P>The Debug Console is an Erlang shell attached to an already running <TT>ejabberd</TT> server.
|
||||
<H2 CLASS="section"><!--SEC ANCHOR --><A NAME="htoc87">7.3</A>  <A HREF="#debugconsole">Debug Console</A></H2><!--SEC END --><P> <A NAME="debugconsole"></A> </P><P>The Debug Console is an Erlang shell attached to an already running <TT>ejabberd</TT> server.
|
||||
With this Erlang shell, an experienced administrator can perform complex tasks.</P><P>This shell gives complete control over the <TT>ejabberd</TT> server,
|
||||
so it is important to use it with extremely care.
|
||||
There are some simple and safe examples in the article
|
||||
<A HREF="http://www.ejabberd.im/interconnect-erl-nodes">Interconnecting Erlang Nodes</A></P><P>To exit the shell, close the window or press the keys: control+c control+c.</P><P> <A NAME="i18ni10n"></A> </P><!--TOC chapter Internationalization and Localization-->
|
||||
<H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc86">Appendix A</A>  <A HREF="#i18ni10n">Internationalization and Localization</A></H1><!--SEC END --><P> <A NAME="i18ni10n"></A>
|
||||
<H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc88">Appendix A</A>  <A HREF="#i18ni10n">Internationalization and Localization</A></H1><!--SEC END --><P> <A NAME="i18ni10n"></A>
|
||||
</P><P>All built-in modules support the <TT>xml:lang</TT> attribute inside IQ queries.
|
||||
Figure <A HREF="#fig:discorus">A.1</A>, for example, shows the reply to the following query:
|
||||
</P><PRE CLASS="verbatim"><iq id='5'
|
||||
@ -3181,9 +3223,9 @@ HTTP header ‘Accept-Language: ru’</TD></TR>
|
||||
</TABLE></DIV>
|
||||
<A NAME="fig:webadmmainru"></A>
|
||||
<DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV></DIV></BLOCKQUOTE><P> <A NAME="releasenotes"></A> </P><!--TOC chapter Release Notes-->
|
||||
<H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc87">Appendix B</A>  <A HREF="#releasenotes">Release Notes</A></H1><!--SEC END --><P> <A NAME="releasenotes"></A>
|
||||
<H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc89">Appendix B</A>  <A HREF="#releasenotes">Release Notes</A></H1><!--SEC END --><P> <A NAME="releasenotes"></A>
|
||||
</P><P>Release notes are available from <A HREF="http://www.process-one.net/en/ejabberd/release_notes/">ejabberd Home Page</A></P><P> <A NAME="acknowledgements"></A> </P><!--TOC chapter Acknowledgements-->
|
||||
<H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc88">Appendix C</A>  <A HREF="#acknowledgements">Acknowledgements</A></H1><!--SEC END --><P> <A NAME="acknowledgements"></A> </P><P>Thanks to all people who contributed to this guide:
|
||||
<H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc90">Appendix C</A>  <A HREF="#acknowledgements">Acknowledgements</A></H1><!--SEC END --><P> <A NAME="acknowledgements"></A> </P><P>Thanks to all people who contributed to this guide:
|
||||
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
|
||||
Alexey Shchepin (<A HREF="xmpp:aleksey@jabber.ru"><TT>xmpp:aleksey@jabber.ru</TT></A>)
|
||||
</LI><LI CLASS="li-itemize">Badlop (<A HREF="xmpp:badlop@jabberes.org"><TT>xmpp:badlop@jabberes.org</TT></A>)
|
||||
@ -3195,7 +3237,7 @@ Alexey Shchepin (<A HREF="xmpp:aleksey@jabber.ru"><TT>xmpp:aleksey@jabber.ru</TT
|
||||
</LI><LI CLASS="li-itemize">Sergei Golovan (<A HREF="xmpp:sgolovan@nes.ru"><TT>xmpp:sgolovan@nes.ru</TT></A>)
|
||||
</LI><LI CLASS="li-itemize">Vsevolod Pelipas (<A HREF="xmpp:vsevoload@jabber.ru"><TT>xmpp:vsevoload@jabber.ru</TT></A>)
|
||||
</LI></UL><P> <A NAME="copyright"></A> </P><!--TOC chapter Copyright Information-->
|
||||
<H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc89">Appendix D</A>  <A HREF="#copyright">Copyright Information</A></H1><!--SEC END --><P> <A NAME="copyright"></A> </P><P>Ejabberd Installation and Operation Guide.<BR>
|
||||
<H1 CLASS="chapter"><!--SEC ANCHOR --><A NAME="htoc91">Appendix D</A>  <A HREF="#copyright">Copyright Information</A></H1><!--SEC END --><P> <A NAME="copyright"></A> </P><P>Ejabberd Installation and Operation Guide.<BR>
|
||||
Copyright © 2003 — 2008 Process-one</P><P>This document is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
|
@ -361,7 +361,7 @@ The files and directories created are, by default:
|
||||
\titem{/sbin/ejabberdctl} Administration script
|
||||
\titem{/var/lib/ejabberd/}
|
||||
\begin{description}
|
||||
\titem{.erlang.cookie} Erlang cookie file
|
||||
\titem{.erlang.cookie} Erlang cookie file (see section \ref{cookie})
|
||||
\titem{db} Mnesia database spool files
|
||||
\titem{ebin} Binary Erlang files (*.beam)
|
||||
\titem{priv}
|
||||
@ -405,6 +405,31 @@ gmake
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
\makesubsection{solaris}{Specific Notes for Sun Solaris}
|
||||
\ind{install!solaris}
|
||||
|
||||
You need to have \term{GNU install},
|
||||
but it isn't included in Solaris.
|
||||
It can be easily installed if your Solaris system
|
||||
is set up for \footahref{http://www.blastwave.org/}{blastwave.org}
|
||||
package repository.
|
||||
Make sure \term{/opt/csw/bin} is in your \term{PATH} and run:
|
||||
\begin{verbatim}
|
||||
pkg-get -i fileutils
|
||||
\end{verbatim}
|
||||
|
||||
If that program is called \term{ginstall},
|
||||
modify the \ejabberd{} \term{Makefile} script to suit your system,
|
||||
for example:
|
||||
\begin{verbatim}
|
||||
cat Makefile | sed s/install/ginstall/ > Makefile.gi
|
||||
\end{verbatim}
|
||||
And finally install \ejabberd{} with:
|
||||
\begin{verbatim}
|
||||
gmake -f Makefile.gi ginstall
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
\makesubsection{windows}{Specific Notes for Microsoft Windows}
|
||||
\ind{install!windows}
|
||||
|
||||
@ -729,7 +754,10 @@ This is a detailed description of each option allowed by the listening modules:
|
||||
is also needed in the \Jabber{} client. Remark also that HTTP Polling can be
|
||||
interesting to host a web-based \Jabber{} client such as
|
||||
\footahref{http://jwchat.sourceforge.net/}{JWChat}.
|
||||
\titem{inet6} \ind{options!inet6}\ind{IPv6}Set up the socket for IPv6.
|
||||
\titem{inet6} \ind{options!inet6}\ind{IPv6}Set up the socket for IPv6 instead of IPv4.
|
||||
Note: this option is not required for S2S outgoing connections,
|
||||
because when ejabberd attempts to establish a S2S outgoing connection
|
||||
it first tries IPv4, and if that fails it attempts with IPv6.
|
||||
\titem{\{ip, IPAddress\}} \ind{options!ip}This option specifies which network
|
||||
interface to listen for. For example \verb|{ip, {192, 168, 1, 1}}|.
|
||||
\titem{\{max\_stanza\_size, Size\}}
|
||||
@ -2710,9 +2738,9 @@ Features:
|
||||
\begin{itemize}
|
||||
\item Chatroom details are added on top of each page: room title, JID,
|
||||
author, subject and configuration.
|
||||
\item \ind{protocols!RFC 4622: Internationalized Resource Identifiers (IRIs) and Uniform Resource Identifiers (URIs) for the Extensible Messaging and Presence Protocol (XMPP)}
|
||||
Room title and JID are links to join the chatroom (using
|
||||
\footahref{http://www.ietf.org/rfc/rfc4622.txt}{XMPP URIs}).
|
||||
\item \ind{protocols!RFC 5122: Internationalized Resource Identifiers (IRIs) and Uniform Resource Identifiers (URIs) for the Extensible Messaging and Presence Protocol (XMPP)}
|
||||
The room JID in the generated HTML is a link to join the chatroom (using
|
||||
\footahref{http://www.xmpp.org/rfcs/rfc5122.html}{XMPP URI}).
|
||||
\item Subject and chatroom configuration changes are tracked and displayed.
|
||||
\item Joins, leaves, nick changes, kicks, bans and `/me' are tracked and
|
||||
displayed, including the reason if available.
|
||||
@ -3008,6 +3036,7 @@ Options:
|
||||
\titem{welcome\_message} \ind{options!welcomem}Set a welcome message that
|
||||
is sent to each newly registered account. The first string is the subject, and
|
||||
the second string is the message body.
|
||||
In the body you can set a newline with the characters: \term{\~\ n}.
|
||||
\titem{registration\_watchers} \ind{options!rwatchers}This option defines a
|
||||
list of JIDs which will be notified each time a new account is registered.
|
||||
\iqdiscitem{In-Band Registration (\ns{jabber:iq:register})}
|
||||
@ -3066,7 +3095,7 @@ Also define a registration timeout of one hour:
|
||||
...
|
||||
{mod_register,
|
||||
[
|
||||
{welcome_message, {"Welcome!", "Welcome to this Jabber server. Check http://www.jabber.org"}},
|
||||
{welcome_message, {"Welcome!", "Hi.~nWelcome to this Jabber server.~n Check http://www.jabber.org~n~nBye"}},
|
||||
{registration_watchers, ["admin1@example.org", "boss@example.net"]}
|
||||
]},
|
||||
...
|
||||
@ -3781,7 +3810,7 @@ an account with proper privileges.
|
||||
|
||||
\ejabberd{} uses the distributed Mnesia database.
|
||||
Being distributed, Mnesia enforces consistency of its file,
|
||||
so it stores the name of the Erlang node in it.
|
||||
so it stores the name of the Erlang node in it (see section \ref{nodename}).
|
||||
The name of an Erlang node includes the hostname of the computer.
|
||||
So, the name of the Erlang node changes
|
||||
if you change the name of the machine in which \ejabberd{} runs,
|
||||
@ -3861,8 +3890,9 @@ erl ... -kernel inet_dist_listen_min 4370 inet_dist_listen_max 4375
|
||||
\makesection{cookie}{Erlang Cookie}
|
||||
|
||||
The Erlang cookie is a string with numbers and letters.
|
||||
An Erlang node reads the cookie at startup from the command-line parameter \term{-setcookie}
|
||||
or from a cookie file.
|
||||
An Erlang node reads the cookie at startup from the command-line parameter \term{-setcookie}.
|
||||
If not indicated, the cookie is read from the cookie file \term{\$HOME/.erlang.cookie}.
|
||||
If this file does not exist, it is created immediately with a random cookie.
|
||||
Two Erlang nodes communicate only if they have the same cookie.
|
||||
Setting a cookie on the Erlang node allows you to structure your Erlang network
|
||||
and define which nodes are allowed to connect to which.
|
||||
@ -3894,6 +3924,32 @@ using a modified version of Erlang \term{epmd}.
|
||||
The recommended way to secure the Erlang node is to block the port 4369.
|
||||
|
||||
|
||||
\makesection{secure-files}{Securing sensible files}
|
||||
|
||||
\ejabberd{} stores sensible data in the file system either in plain text or binary files.
|
||||
The file system permissions should be set to only allow the proper user to read,
|
||||
write and execute those files and directories.
|
||||
|
||||
\begin{description}
|
||||
\titem{ejabberd configuration file: /etc/ejabberd/ejabberd.cfg}
|
||||
Contains the JID of administrators
|
||||
and passwords of external components.
|
||||
The backup files probably contain also this information,
|
||||
so it is preferable to secure the whole \term{/etc/ejabberd/} directory.
|
||||
\titem{ejabberd service log: /var/log/ejabberd/ejabberd.log}
|
||||
Contains IP addresses of clients.
|
||||
If the loglevel is set to 5, it contains whole conversations and passwords.
|
||||
If a logrotate system is used, there may be several log files with similar information,
|
||||
so it is preferable to secure the whole \term{/var/log/ejabberd/} directory.
|
||||
\titem{Mnesia database spool files: /var/lib/ejabberd/db/*}
|
||||
The files store binary data, but some parts are still readable.
|
||||
The files are generated by Mnesia and their permissions cannot be set directly,
|
||||
so it is preferable to secure the whole \term{/var/lib/ejabberd/db/} directory.
|
||||
\titem{Erlang cookie file: /var/lib/ejabberd/.erlang.cookie}
|
||||
See section \ref{cookie}.
|
||||
\end{description}
|
||||
|
||||
|
||||
\makechapter{clustering}{Clustering}
|
||||
\ind{clustering}
|
||||
|
||||
|
@ -60,6 +60,7 @@ DESTDIR =
|
||||
|
||||
EJABBERDDIR = $(DESTDIR)@localstatedir@/lib/ejabberd
|
||||
BEAMDIR = $(EJABBERDDIR)/ebin
|
||||
SPOOLDIR = $(EJABBERDDIR)/db
|
||||
PRIVDIR = $(EJABBERDDIR)/priv
|
||||
SODIR = $(PRIVDIR)/lib
|
||||
PBINDIR = $(PRIVDIR)/bin
|
||||
@ -116,20 +117,21 @@ install: all
|
||||
install -m 644 *.beam $(BEAMDIR)
|
||||
rm -f $(BEAMDIR)/configure.beam
|
||||
install -m 644 *.app $(BEAMDIR)
|
||||
install -d -m 750 $(SPOOLDIR)
|
||||
install -d $(SODIR)
|
||||
install -d $(PBINDIR)
|
||||
install -m 644 *.so $(SODIR)
|
||||
$(INSTALL_EPAM)
|
||||
install -d $(MSGSDIR)
|
||||
install -m 644 msgs/*.msg $(MSGSDIR)
|
||||
install -d $(ETCDIR)
|
||||
install -d -m 750 $(ETCDIR)
|
||||
[ -f $(ETCDIR)/ejabberd.cfg ] && install -b -m 644 ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg-new || install -b -m 644 ejabberd.cfg.example $(ETCDIR)/ejabberd.cfg
|
||||
sed -e "s*@rootdir@*@prefix@*" ejabberdctl.template > ejabberdctl.example
|
||||
[ -f $(ETCDIR)/ejabberdctl.cfg ] && install -b -m 644 ejabberdctl.cfg.example $(ETCDIR)/ejabberdctl.cfg-new || install -b -m 644 ejabberdctl.cfg.example $(ETCDIR)/ejabberdctl.cfg
|
||||
install -b -m 644 inetrc $(ETCDIR)/inetrc
|
||||
install -d $(SBINDIR)
|
||||
install -m 755 ejabberdctl.example $(SBINDIR)/ejabberdctl
|
||||
install -d $(LOGDIR)
|
||||
install -d -m 750 $(LOGDIR)
|
||||
|
||||
uninstall: uninstall-binary
|
||||
|
||||
|
3
src/configure
vendored
3
src/configure
vendored
@ -4765,6 +4765,9 @@ _ACEOF
|
||||
fi
|
||||
|
||||
|
||||
# Check Erlang headers are installed
|
||||
#AC_CHECK_HEADER(erl_driver.h,,[AC_MSG_ERROR([cannot find Erlang header files])])
|
||||
|
||||
# Change default prefix
|
||||
|
||||
|
||||
|
@ -26,6 +26,9 @@ AM_WITH_PAM
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
|
||||
# Check Erlang headers are installed
|
||||
#AC_CHECK_HEADER(erl_driver.h,,[AC_MSG_ERROR([cannot find Erlang header files])])
|
||||
|
||||
# Change default prefix
|
||||
AC_PREFIX_DEFAULT(/)
|
||||
|
||||
|
@ -459,7 +459,7 @@
|
||||
%% a message with this subject and body.
|
||||
%%
|
||||
{welcome_message, {"Welcome!",
|
||||
"Welcome to this Jabber server."}},
|
||||
"Hi.~nWelcome to this Jabber server."}},
|
||||
|
||||
%%
|
||||
%% When a user registers, send a notification to
|
||||
|
@ -1223,6 +1223,9 @@ handle_info({route, FromOld, ToOld, PacketOld}, StateName, StateData) ->
|
||||
handle_info({'DOWN', Monitor, _Type, _Object, _Info}, _StateName, StateData)
|
||||
when Monitor == StateData#state.socket_monitor ->
|
||||
{stop, normal, StateData};
|
||||
handle_info({peername, IP}, StateName, StateData) ->
|
||||
ejabberd_sm:set_session_ip(StateData#state.sid, IP),
|
||||
fsm_next_state(StateName, StateData#state{ip = IP});
|
||||
handle_info(Info, StateName, StateData) ->
|
||||
?ERROR_MSG("Unexpected info: ~p", [Info]),
|
||||
fsm_next_state(StateName, StateData).
|
||||
|
@ -96,8 +96,10 @@ get_plain_terms_file(File1) ->
|
||||
{ok, Terms} ->
|
||||
include_config_files(Terms);
|
||||
{error, Reason} ->
|
||||
?ERROR_MSG("Can't load config file ~p: ~p", [File, Reason]),
|
||||
exit(File ++ ": " ++ file:format_error(Reason))
|
||||
ExitText = lists:flatten(File ++ ": around line "
|
||||
++ file:format_error(Reason)),
|
||||
?ERROR_MSG("Problem loading ejabberd config file:~n~s", [ExitText]),
|
||||
exit(ExitText)
|
||||
end.
|
||||
|
||||
%% @doc Convert configuration filename to absolute path.
|
||||
|
@ -30,6 +30,7 @@
|
||||
-export([start/0,
|
||||
init/0,
|
||||
process/1,
|
||||
dump_to_textfile/1,
|
||||
register_commands/3,
|
||||
register_commands/4,
|
||||
unregister_commands/3,
|
||||
|
@ -37,6 +37,7 @@
|
||||
register_iq_handler/5,
|
||||
register_iq_response_handler/4,
|
||||
unregister_iq_handler/2,
|
||||
unregister_iq_response_handler/2,
|
||||
refresh_iq_handlers/0,
|
||||
bounce_resource_packet/3
|
||||
]).
|
||||
@ -168,6 +169,9 @@ register_iq_handler(Host, XMLNS, Module, Fun) ->
|
||||
register_iq_handler(Host, XMLNS, Module, Fun, Opts) ->
|
||||
ejabberd_local ! {register_iq_handler, Host, XMLNS, Module, Fun, Opts}.
|
||||
|
||||
unregister_iq_response_handler(Host, ID) ->
|
||||
ejabberd_local ! {unregister_iq_response_handler, Host, ID}.
|
||||
|
||||
unregister_iq_handler(Host, XMLNS) ->
|
||||
ejabberd_local ! {unregister_iq_handler, Host, XMLNS}.
|
||||
|
||||
@ -254,6 +258,9 @@ handle_info({route, From, To, Packet}, State) ->
|
||||
handle_info({register_iq_response_handler, _Host, ID, Module, Function}, State) ->
|
||||
mnesia:dirty_write(#iq_response{id = ID, module = Module, function = Function}),
|
||||
{noreply, State};
|
||||
handle_info({unregister_iq_response_handler, _Host, ID}, State) ->
|
||||
mnesia:dirty_delete({iq_response, ID}),
|
||||
{noreply, State};
|
||||
handle_info({register_iq_handler, Host, XMLNS, Module, Function}, State) ->
|
||||
ets:insert(?IQTABLE, {{XMLNS, Host}, Module, Function}),
|
||||
catch mod_disco:register_feature(Host, XMLNS),
|
||||
|
@ -268,7 +268,8 @@ code_change(_OldVsn, State, _Extra) ->
|
||||
%%--------------------------------------------------------------------
|
||||
|
||||
activate_socket(#state{socket = Socket,
|
||||
sock_mod = SockMod}) ->
|
||||
sock_mod = SockMod,
|
||||
c2s_pid = C2SPid}) ->
|
||||
PeerName =
|
||||
case SockMod of
|
||||
gen_tcp ->
|
||||
@ -281,7 +282,8 @@ activate_socket(#state{socket = Socket,
|
||||
case PeerName of
|
||||
{error, _Reason} ->
|
||||
self() ! {tcp_closed, Socket};
|
||||
{ok, _} ->
|
||||
{ok, IP} ->
|
||||
C2SPid ! {peername, IP},
|
||||
ok
|
||||
end.
|
||||
|
||||
|
@ -49,7 +49,8 @@
|
||||
ctl_process/2,
|
||||
get_session_pid/3,
|
||||
get_user_info/3,
|
||||
get_user_ip/3
|
||||
get_user_ip/3,
|
||||
set_session_ip/2
|
||||
]).
|
||||
|
||||
%% gen_server callbacks
|
||||
@ -186,6 +187,18 @@ get_user_info(User, Server, Resource) ->
|
||||
[{node, Node}, {conn, Conn}, {ip, IP}]
|
||||
end.
|
||||
|
||||
set_session_ip(SID, IP) ->
|
||||
case mnesia:dirty_read(session, SID) of
|
||||
[#session{info = Info} = Session] ->
|
||||
NewInfo = case lists:keymember(ip, 1, Info) of
|
||||
true -> lists:keyreplace(ip, 1, Info, {ip, IP});
|
||||
false -> [{ip, IP}|Info]
|
||||
end,
|
||||
mnesia:dirty_write(Session#session{info = NewInfo});
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
|
||||
set_presence(SID, User, Server, Resource, Priority, Presence, Info) ->
|
||||
set_session(SID, User, Server, Resource, Priority, Info),
|
||||
% XXX OLD FORMAT: Presence.
|
||||
|
@ -53,6 +53,7 @@
|
||||
|
||||
-define(PROCNAME, ejabberd_mod_caps).
|
||||
-define(DICT, dict).
|
||||
-define(CAPS_QUERY_TIMEOUT, 60000). % 1mn without answer, consider client never answer
|
||||
|
||||
-record(caps, {node, version, exts}).
|
||||
-record(caps_features, {node_pair, features}).
|
||||
@ -220,6 +221,7 @@ handle_cast({note_caps, From,
|
||||
ejabberd_local:register_iq_response_handler
|
||||
(Host, ID, ?MODULE, handle_disco_response),
|
||||
ejabberd_router:route(jlib:make_jid("", Host, ""), From, Stanza),
|
||||
timer:send_after(?CAPS_QUERY_TIMEOUT, self(), {disco_timeout, ID}),
|
||||
?DICT:store(ID, {Node, SubNode}, Dict)
|
||||
end, Requests, Missing),
|
||||
{noreply, State#state{disco_requests = NewRequests}};
|
||||
@ -274,6 +276,16 @@ handle_cast({disco_response, From, _To,
|
||||
end,
|
||||
NewRequests = ?DICT:erase(ID, Requests),
|
||||
{noreply, State#state{disco_requests = NewRequests}};
|
||||
handle_cast({disco_timeout, ID}, #state{host = Host, disco_requests = Requests} = State) ->
|
||||
%% do not wait a response anymore for this IQ, client certainly will never answer
|
||||
NewRequests = case ?DICT:is_key(ID, Requests) of
|
||||
true ->
|
||||
ejabberd_local:unregister_iq_response_handler(Host, ID),
|
||||
?DICT:erase(ID, Requests);
|
||||
false ->
|
||||
Requests
|
||||
end,
|
||||
{noreply, State#state{disco_requests = NewRequests}};
|
||||
handle_cast(visit_feature_queries, #state{feature_queries = FeatureQueries} = State) ->
|
||||
Timestamp = timestamp(),
|
||||
NewFeatureQueries =
|
||||
|
@ -1416,7 +1416,7 @@ set_form(_From, _Host, ["running nodes", ENode, "backup", "textfile"], _Lang, XD
|
||||
false ->
|
||||
{error, ?ERR_BAD_REQUEST};
|
||||
{value, {_, [String]}} ->
|
||||
case rpc:call(Node, mnesia, dump_to_textfile, [String]) of
|
||||
case rpc:call(Node, ejabberd_ctl, dump_to_textfile, [String]) of
|
||||
{badrpc, _Reason} ->
|
||||
{error, ?ERR_INTERNAL_SERVER_ERROR};
|
||||
{error, _Reason} ->
|
||||
|
@ -120,9 +120,11 @@ init([Host, Opts]) ->
|
||||
NoFollow = gen_mod:get_opt(spam_prevention, Opts, true),
|
||||
Lang = case ejabberd_config:get_local_option({language, Host}) of
|
||||
undefined ->
|
||||
"";
|
||||
L ->
|
||||
L
|
||||
case ejabberd_config:get_global_option(language) of
|
||||
undefined -> "en";
|
||||
L -> L
|
||||
end;
|
||||
L -> L
|
||||
end,
|
||||
{ok, #state{host = Host,
|
||||
out_dir = OutDir,
|
||||
@ -286,9 +288,10 @@ add_message_to_log(Nick1, Message, RoomJID, Opts, State) ->
|
||||
top_link = TopLink} = State,
|
||||
Room = get_room_info(RoomJID, Opts),
|
||||
|
||||
Now = now(),
|
||||
TimeStamp = case Timezone of
|
||||
local -> calendar:now_to_local_time(now());
|
||||
universal -> calendar:now_to_universal_time(now())
|
||||
local -> calendar:now_to_local_time(Now);
|
||||
universal -> calendar:now_to_universal_time(Now)
|
||||
end,
|
||||
{Fd, Fn, _Dir} = build_filename_string(TimeStamp, OutDir, Room#room.jid, DirType),
|
||||
{Date, Time} = TimeStamp,
|
||||
@ -382,10 +385,12 @@ add_message_to_log(Nick1, Message, RoomJID, Opts, State) ->
|
||||
{Hour, Minute, Second} = Time,
|
||||
STime = lists:flatten(
|
||||
io_lib:format("~2..0w:~2..0w:~2..0w", [Hour, Minute, Second])),
|
||||
{_, _, Microsecs} = Now,
|
||||
STimeUnique = io_lib:format("~s.~w", [STime, Microsecs]),
|
||||
|
||||
% Write message
|
||||
file:write(F, io_lib:format("<a name=\"~s\" href=\"#~s\" class=\"ts\">[~s]</a> ~s~n",
|
||||
[STime, STime, STime, Text])),
|
||||
file:write(F, io_lib:format("<a id=\"~s\" name=\"~s\" href=\"#~s\" class=\"ts\">[~s]</a> ~s~n",
|
||||
[STimeUnique, STimeUnique, STimeUnique, STime, Text])),
|
||||
|
||||
% Close file
|
||||
file:close(F),
|
||||
|
@ -59,6 +59,7 @@
|
||||
-record(lqueue, {queue, len, max}).
|
||||
|
||||
-record(config, {title = "",
|
||||
description = "",
|
||||
allow_change_subj = true,
|
||||
allow_query_users = true,
|
||||
allow_private_messages = true,
|
||||
@ -2614,7 +2615,10 @@ get_config(Lang, StateData, From) ->
|
||||
[{xmlcdata, "http://jabber.org/protocol/muc#roomconfig"}]}]},
|
||||
?STRINGXFIELD("Room title",
|
||||
"muc#roomconfig_roomname",
|
||||
Config#config.title)
|
||||
Config#config.title),
|
||||
?STRINGXFIELD("Room description",
|
||||
"muc#roomconfig_roomdesc",
|
||||
Config#config.description)
|
||||
] ++
|
||||
case acl:match_rule(StateData#state.server_host, AccessPersistent, From) of
|
||||
allow ->
|
||||
@ -2761,6 +2765,8 @@ set_xoption([], Config) ->
|
||||
Config;
|
||||
set_xoption([{"muc#roomconfig_roomname", [Val]} | Opts], Config) ->
|
||||
?SET_STRING_XOPT(title, Val);
|
||||
set_xoption([{"muc#roomconfig_roomdesc", [Val]} | Opts], Config) ->
|
||||
?SET_STRING_XOPT(description, Val);
|
||||
set_xoption([{"muc#roomconfig_changesubject", [Val]} | Opts], Config) ->
|
||||
?SET_BOOL_XOPT(allow_change_subj, Val);
|
||||
set_xoption([{"allow_query_users", [Val]} | Opts], Config) ->
|
||||
@ -2856,6 +2862,7 @@ set_opts([], StateData) ->
|
||||
set_opts([{Opt, Val} | Opts], StateData) ->
|
||||
NSD = case Opt of
|
||||
title -> StateData#state{config = (StateData#state.config)#config{title = Val}};
|
||||
description -> StateData#state{config = (StateData#state.config)#config{description = Val}};
|
||||
allow_change_subj -> StateData#state{config = (StateData#state.config)#config{allow_change_subj = Val}};
|
||||
allow_query_users -> StateData#state{config = (StateData#state.config)#config{allow_query_users = Val}};
|
||||
allow_private_messages -> StateData#state{config = (StateData#state.config)#config{allow_private_messages = Val}};
|
||||
@ -2895,6 +2902,7 @@ make_opts(StateData) ->
|
||||
Config = StateData#state.config,
|
||||
[
|
||||
?MAKE_CONFIG_OPT(title),
|
||||
?MAKE_CONFIG_OPT(description),
|
||||
?MAKE_CONFIG_OPT(allow_change_subj),
|
||||
?MAKE_CONFIG_OPT(allow_query_users),
|
||||
?MAKE_CONFIG_OPT(allow_private_messages),
|
||||
@ -2991,9 +2999,12 @@ process_iq_disco_info(_From, get, Lang, StateData) ->
|
||||
|
||||
iq_disco_info_extras(Lang, StateData) ->
|
||||
Len = length(?DICT:to_list(StateData#state.users)),
|
||||
RoomDescription = (StateData#state.config)#config.description,
|
||||
[{xmlelement, "x", [{"xmlns", ?NS_XDATA}, {"type", "result"}],
|
||||
[?RFIELDT("hidden", "FORM_TYPE",
|
||||
"http://jabber.org/protocol/muc#roominfo"),
|
||||
?RFIELD("Room description", "muc#roominfo_description",
|
||||
RoomDescription),
|
||||
?RFIELD("Number of occupants", "muc#roominfo_occupants",
|
||||
integer_to_list(Len))
|
||||
]}].
|
||||
|
@ -16,7 +16,7 @@
|
||||
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
%%% General Public License for more details.
|
||||
%%%
|
||||
%%%
|
||||
%%% You should have received a copy of the GNU General Public License
|
||||
%%% along with this program; if not, write to the Free Software
|
||||
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
@ -698,11 +698,11 @@ raw_to_item({SType, SValue, SAction, SOrder, SMatchAll, SMatchIQ,
|
||||
"d" -> deny
|
||||
end,
|
||||
Order = list_to_integer(SOrder),
|
||||
MatchAll = SMatchAll == "t",
|
||||
MatchIQ = SMatchIQ == "t",
|
||||
MatchMessage = SMatchMessage == "t",
|
||||
MatchPresenceIn = SMatchPresenceIn == "t",
|
||||
MatchPresenceOut = SMatchPresenceOut == "t",
|
||||
MatchAll = SMatchAll == "1" orelse SMatchAll == "t",
|
||||
MatchIQ = SMatchIQ == "1" orelse SMatchIQ == "t" ,
|
||||
MatchMessage = SMatchMessage == "1" orelse SMatchMessage == "t",
|
||||
MatchPresenceIn = SMatchPresenceIn == "1" orelse SMatchPresenceIn == "t",
|
||||
MatchPresenceOut = SMatchPresenceOut == "1" orelse SMatchPresenceOut == "t",
|
||||
#listitem{type = Type,
|
||||
value = Value,
|
||||
action = Action,
|
||||
@ -750,11 +750,11 @@ item_to_raw(#listitem{type = Type,
|
||||
deny -> "d"
|
||||
end,
|
||||
SOrder = integer_to_list(Order),
|
||||
SMatchAll = if MatchAll -> "t"; true -> "f" end,
|
||||
SMatchIQ = if MatchIQ -> "t"; true -> "f" end,
|
||||
SMatchMessage = if MatchMessage -> "t"; true -> "f" end,
|
||||
SMatchPresenceIn = if MatchPresenceIn -> "t"; true -> "f" end,
|
||||
SMatchPresenceOut = if MatchPresenceOut -> "t"; true -> "f" end,
|
||||
SMatchAll = if MatchAll -> "1"; true -> "0" end,
|
||||
SMatchIQ = if MatchIQ -> "1"; true -> "0" end,
|
||||
SMatchMessage = if MatchMessage -> "1"; true -> "0" end,
|
||||
SMatchPresenceIn = if MatchPresenceIn -> "1"; true -> "0" end,
|
||||
SMatchPresenceOut = if MatchPresenceOut -> "1"; true -> "0" end,
|
||||
["'", SType, "', "
|
||||
"'", SValue, "', "
|
||||
"'", SAction, "', "
|
||||
@ -871,6 +871,3 @@ sql_set_privacy_list(ID, RItems) ->
|
||||
") "
|
||||
"values ('", ID, "', ", Items, ");"])
|
||||
end, RItems).
|
||||
|
||||
|
||||
|
||||
|
@ -62,7 +62,9 @@ behaviour_info(callbacks) ->
|
||||
{get_states, 2},
|
||||
{get_state, 3},
|
||||
{set_state, 1},
|
||||
{get_items, 7},
|
||||
{get_items, 2},
|
||||
{get_item, 8},
|
||||
{get_item, 3},
|
||||
{set_item, 1},
|
||||
{get_item_name, 3}
|
||||
|
@ -30,16 +30,17 @@
|
||||
%%%
|
||||
%%% @reference See <a href="http://www.xmpp.org/extensions/xep-0060.html">XEP-0060: Pubsub</a> for
|
||||
%%% the latest version of the PubSub specification.
|
||||
%%% This module uses version 1.10 of the specification as a base.
|
||||
%%% This module uses version 1.11 of the specification as a base.
|
||||
%%% Most of the specification is implemented.
|
||||
%%% Code is derivated from the original pubsub v1.7, functions concerning config may be rewritten.
|
||||
%%% Code also inspired from the original PEP patch by Magnus Henoch (mangeATfreemail.hu)
|
||||
%%% Functions concerning configuration should be rewritten.
|
||||
%%% Code is derivated from the original pubsub v1.7, by Alexey Shchepin <alexey@process-one.net>
|
||||
|
||||
%%% TODO
|
||||
%%% plugin: generate Reply (do not use broadcast atom anymore)
|
||||
|
||||
-module(mod_pubsub).
|
||||
-version('1.10-01').
|
||||
-author('christophe.romain@process-one.net').
|
||||
-version('1.11-01').
|
||||
|
||||
-behaviour(gen_server).
|
||||
-behaviour(gen_mod).
|
||||
@ -912,7 +913,17 @@ iq_pubsub(Host, ServerHost, From, IQType, SubEl, _Lang, Access, Plugins) ->
|
||||
unsubscribe_node(Host, Node, From, JID, SubId);
|
||||
{get, "items"} ->
|
||||
MaxItems = xml:get_attr_s("max_items", Attrs),
|
||||
get_items(Host, Node, From, MaxItems);
|
||||
SubId = xml:get_attr_s("subid", Attrs),
|
||||
ItemIDs = lists:foldl(fun
|
||||
({xmlelement, "item", ItemAttrs, _}, Acc) ->
|
||||
case xml:get_attr_s("id", ItemAttrs) of
|
||||
"" -> Acc;
|
||||
ItemID -> ItemID
|
||||
end;
|
||||
(_, Acc) ->
|
||||
Acc
|
||||
end, [], xml:remove_cdata(Els)),
|
||||
get_items(Host, Node, From, SubId, MaxItems, ItemIDs);
|
||||
{get, "subscriptions"} ->
|
||||
get_subscriptions(Host, From, Plugins);
|
||||
{get, "affiliations"} ->
|
||||
@ -1436,7 +1447,7 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) ->
|
||||
Action = fun(#pubsub_node{options = Options, type = Type}) ->
|
||||
Features = features(Type),
|
||||
PublishFeature = lists:member("publish", Features),
|
||||
Model = get_option(Options, publish_model),
|
||||
PublishModel = get_option(Options, publish_model),
|
||||
MaxItems = max_items(Options),
|
||||
PayloadSize = size(term_to_binary(Payload)),
|
||||
PayloadMaxSize = get_option(Options, max_payload_size),
|
||||
@ -1459,7 +1470,7 @@ publish_item(Host, ServerHost, Node, Publisher, ItemId, Payload) ->
|
||||
%% % Publisher attempts to publish to transient notification node with item
|
||||
%% {error, extended_error(?ERR_BAD_REQUEST, "item-forbidden")};
|
||||
true ->
|
||||
node_call(Type, publish_item, [Host, Node, Publisher, Model, MaxItems, ItemId, Payload])
|
||||
node_call(Type, publish_item, [Host, Node, Publisher, PublishModel, MaxItems, ItemId, Payload])
|
||||
end
|
||||
end,
|
||||
%%ejabberd_hooks:run(pubsub_publish_item, Host, [Host, Node, JID, service_jid(Host), ItemId, Payload]),
|
||||
@ -1622,7 +1633,7 @@ purge_node(Host, Node, Owner) ->
|
||||
%% <p>The permission are not checked in this function.</p>
|
||||
%% @todo We probably need to check that the user doing the query has the right
|
||||
%% to read the items.
|
||||
get_items(Host, Node, _JID, SMaxItems) ->
|
||||
get_items(Host, Node, From, SubId, SMaxItems, ItemIDs) ->
|
||||
MaxItems =
|
||||
if
|
||||
SMaxItems == "" -> ?MAXITEMS;
|
||||
@ -1636,24 +1647,60 @@ get_items(Host, Node, _JID, SMaxItems) ->
|
||||
{error, Error} ->
|
||||
{error, Error};
|
||||
_ ->
|
||||
case get_items(Host, Node) of
|
||||
[] ->
|
||||
{error, ?ERR_ITEM_NOT_FOUND};
|
||||
Items ->
|
||||
Action = fun(#pubsub_node{options = Options, type = Type}) ->
|
||||
Features = features(Type),
|
||||
RetreiveFeature = lists:member("retrieve-items", Features),
|
||||
PersistentFeature = lists:member("persistent-items", Features),
|
||||
AccessModel = get_option(Options, access_model),
|
||||
AllowedGroups = get_option(Options, roster_groups_allowed),
|
||||
{PresenceSubscription, RosterGroup} =
|
||||
case Host of
|
||||
{OUser, OServer, _} ->
|
||||
get_roster_info(OUser, OServer,
|
||||
jlib:jid_tolower(From), AllowedGroups);
|
||||
_ ->
|
||||
{true, true}
|
||||
end,
|
||||
if
|
||||
not RetreiveFeature ->
|
||||
%% Item Retrieval Not Supported
|
||||
{error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "retrieve-items")};
|
||||
not PersistentFeature ->
|
||||
%% Persistent Items Not Supported
|
||||
{error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "persistent-items")};
|
||||
true ->
|
||||
node_call(Type, get_items,
|
||||
[Host, Node, From,
|
||||
AccessModel, PresenceSubscription, RosterGroup,
|
||||
SubId])
|
||||
end
|
||||
end,
|
||||
case transaction(Host, Node, Action, sync_dirty) of
|
||||
{error, Reason} ->
|
||||
{error, Reason};
|
||||
{result, Items} ->
|
||||
SendItems = case ItemIDs of
|
||||
[] ->
|
||||
Items;
|
||||
_ ->
|
||||
lists:filter(fun(Item) ->
|
||||
lists:member(Item, ItemIDs)
|
||||
end, Items)
|
||||
end,
|
||||
%% Generate the XML response (Item list), limiting the
|
||||
%% number of items sent to MaxItems:
|
||||
ItemsEls = lists:map(
|
||||
fun(#pubsub_item{itemid = {ItemId, _},
|
||||
payload = Payload}) ->
|
||||
ItemAttrs = case ItemId of
|
||||
"" -> [];
|
||||
_ -> [{"id", ItemId}]
|
||||
end,
|
||||
{xmlelement, "item", ItemAttrs, Payload}
|
||||
end, lists:sublist(Items, MaxItems)),
|
||||
fun(#pubsub_item{itemid = {ItemId, _},
|
||||
payload = Payload}) ->
|
||||
ItemAttrs = case ItemId of
|
||||
"" -> [];
|
||||
_ -> [{"id", ItemId}]
|
||||
end,
|
||||
{xmlelement, "item", ItemAttrs, Payload}
|
||||
end, lists:sublist(SendItems, MaxItems)),
|
||||
{result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB}],
|
||||
[{xmlelement, "items", [{"node", node_to_string(Node)}],
|
||||
ItemsEls}]}]}
|
||||
[{xmlelement, "items", [{"node", node_to_string(Node)}],
|
||||
ItemsEls}]}]}
|
||||
end
|
||||
end.
|
||||
|
||||
@ -1809,7 +1856,7 @@ set_affiliations(Host, Node, From, EntitiesEls) ->
|
||||
end, Entities),
|
||||
{result, []};
|
||||
_ ->
|
||||
{error, ?ERR_NOT_ALLOWED}
|
||||
{error, ?ERR_FORBIDDEN}
|
||||
end
|
||||
end,
|
||||
transaction(Host, Node, Action, sync_dirty)
|
||||
@ -1870,7 +1917,7 @@ get_subscriptions(Host, Node, JID) ->
|
||||
%% Service does not support manage subscriptions
|
||||
{error, extended_error(?ERR_FEATURE_NOT_IMPLEMENTED, unsupported, "manage-affiliations")};
|
||||
Affiliation /= {result, owner} ->
|
||||
% Entity is not an owner
|
||||
%% Entity is not an owner
|
||||
{error, ?ERR_FORBIDDEN};
|
||||
true ->
|
||||
node_call(Type, get_node_subscriptions, [Host, Node])
|
||||
@ -1938,7 +1985,7 @@ set_subscriptions(Host, Node, From, EntitiesEls) ->
|
||||
end, Entities),
|
||||
{result, []};
|
||||
_ ->
|
||||
{error, ?ERR_NOT_ALLOWED}
|
||||
{error, ?ERR_FORBIDDEN}
|
||||
end
|
||||
end,
|
||||
transaction(Host, Node, Action, sync_dirty)
|
||||
@ -2352,7 +2399,10 @@ get_configure(Host, Node, From, Lang) ->
|
||||
transaction(Host, Node, Action, sync_dirty).
|
||||
|
||||
get_default(Host, _Node, _From, Lang) ->
|
||||
Type = hd(plugins(Host)), % first configured plugin is default
|
||||
Type = case Host of
|
||||
{_, _, _} -> ?PEPNODE;
|
||||
_ -> hd(plugins(Host))
|
||||
end,
|
||||
Options = node_options(Type),
|
||||
{result, [{xmlelement, "pubsub", [{"xmlns", ?NS_PUBSUB_OWNER}],
|
||||
[{xmlelement, "default", [],
|
||||
@ -2435,6 +2485,7 @@ get_configure_xfields(_Type, Options, Lang, _Owners) ->
|
||||
?BOOL_CONFIG_FIELD("Notify subscribers when the node is deleted", notify_delete),
|
||||
?BOOL_CONFIG_FIELD("Notify subscribers when items are removed from the node", notify_retract),
|
||||
?BOOL_CONFIG_FIELD("Persist items to storage", persist_items),
|
||||
?STRING_CONFIG_FIELD("A friendly name for the node", title),
|
||||
?INTEGER_CONFIG_FIELD("Max # of items to persist", max_items),
|
||||
?BOOL_CONFIG_FIELD("Whether to allow subscriptions", subscribe),
|
||||
?ALIST_CONFIG_FIELD("Specify the access model", access_model,
|
||||
@ -2551,7 +2602,7 @@ set_xoption([], NewOpts) ->
|
||||
NewOpts;
|
||||
set_xoption([{"FORM_TYPE", _} | Opts], NewOpts) ->
|
||||
set_xoption(Opts, NewOpts);
|
||||
set_xoption([{"pubsub#roster_groups_allowed", Value} | Opts], NewOpts) ->
|
||||
set_xoption([{"pubsub#roster_groups_allowed", _Value} | Opts], NewOpts) ->
|
||||
?SET_LIST_XOPT(roster_groups_allowed, []); % XXX: waiting for EJAB-659 to be solved
|
||||
set_xoption([{"pubsub#deliver_payloads", [Val]} | Opts], NewOpts) ->
|
||||
?SET_BOOL_XOPT(deliver_payloads, Val);
|
||||
@ -2602,7 +2653,7 @@ features() ->
|
||||
[
|
||||
%"access-authorize", % OPTIONAL
|
||||
"access-open", % OPTIONAL this relates to access_model option in node_default
|
||||
%"access-presence", % OPTIONAL
|
||||
"access-presence", % OPTIONAL this relates to access_model option in node_pep
|
||||
%"access-roster", % OPTIONAL
|
||||
%"access-whitelist", % OPTIONAL
|
||||
% see plugin "auto-create", % OPTIONAL
|
||||
@ -2616,7 +2667,7 @@ features() ->
|
||||
% see plugin "filtered-notifications", % RECOMMENDED
|
||||
%TODO "get-pending", % OPTIONAL
|
||||
% see plugin "instant-nodes", % RECOMMENDED
|
||||
%TODO "item-ids", % RECOMMENDED
|
||||
"item-ids", % RECOMMENDED
|
||||
"last-published", % RECOMMENDED
|
||||
%TODO "cache-last-item",
|
||||
%TODO "leased-subscription", % OPTIONAL
|
||||
|
@ -61,7 +61,9 @@
|
||||
get_states/2,
|
||||
get_state/3,
|
||||
set_state/1,
|
||||
get_items/7,
|
||||
get_items/2,
|
||||
get_item/8,
|
||||
get_item/3,
|
||||
set_item/1
|
||||
]).
|
||||
@ -94,7 +96,6 @@ features() ->
|
||||
["create-nodes",
|
||||
"delete-nodes",
|
||||
"instant-nodes",
|
||||
"item-ids",
|
||||
"outcast-affiliation",
|
||||
"persistent-items",
|
||||
"publish",
|
||||
@ -170,8 +171,14 @@ set_state(State) ->
|
||||
get_items(Host, Node) ->
|
||||
node_default:get_items(Host, Node).
|
||||
|
||||
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId)
|
||||
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
||||
get_item(Host, Node, ItemId) ->
|
||||
node_default:get_item(Host, Node, ItemId).
|
||||
|
||||
get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_default:get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
||||
set_item(Item) ->
|
||||
node_default:set_item(Item).
|
||||
|
@ -62,7 +62,9 @@
|
||||
get_states/2,
|
||||
get_state/3,
|
||||
set_state/1,
|
||||
get_items/7,
|
||||
get_items/2,
|
||||
get_item/8,
|
||||
get_item/3,
|
||||
set_item/1,
|
||||
get_item_name/3
|
||||
@ -172,9 +174,15 @@ set_state(State) ->
|
||||
get_items(Host, Node) ->
|
||||
node_default:get_items(Host, Node).
|
||||
|
||||
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
||||
get_item(Host, Node, ItemId) ->
|
||||
node_default:get_item(Host, Node, ItemId).
|
||||
|
||||
get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_default:get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
||||
set_item(Item) ->
|
||||
node_default:set_item(Item).
|
||||
|
||||
|
@ -62,7 +62,9 @@
|
||||
get_states/2,
|
||||
get_state/3,
|
||||
set_state/1,
|
||||
get_items/7,
|
||||
get_items/2,
|
||||
get_item/8,
|
||||
get_item/3,
|
||||
set_item/1,
|
||||
get_item_name/3
|
||||
@ -96,7 +98,6 @@ features() ->
|
||||
["create-nodes",
|
||||
"delete-nodes",
|
||||
"instant-nodes",
|
||||
"item-ids",
|
||||
"outcast-affiliation",
|
||||
"persistent-items",
|
||||
"publish",
|
||||
@ -172,9 +173,15 @@ set_state(State) ->
|
||||
get_items(Host, Node) ->
|
||||
node_default:get_items(Host, Node).
|
||||
|
||||
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
||||
get_item(Host, Node, ItemId) ->
|
||||
node_default:get_item(Host, Node, ItemId).
|
||||
|
||||
get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_default:get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
||||
set_item(Item) ->
|
||||
node_default:set_item(Item).
|
||||
|
||||
|
@ -69,7 +69,9 @@
|
||||
get_states/2,
|
||||
get_state/3,
|
||||
set_state/1,
|
||||
get_items/7,
|
||||
get_items/2,
|
||||
get_item/8,
|
||||
get_item/3,
|
||||
set_item/1,
|
||||
get_item_name/3
|
||||
@ -158,7 +160,6 @@ features() ->
|
||||
"auto-create",
|
||||
"delete-nodes",
|
||||
"instant-nodes",
|
||||
"item-ids",
|
||||
"manage-subscriptions",
|
||||
"modify-affiliations",
|
||||
"outcast-affiliation",
|
||||
@ -192,18 +193,14 @@ features() ->
|
||||
%% module by implementing this function like this:
|
||||
%% ```check_create_user_permission(Host, Node, Owner, Access) ->
|
||||
%% node_default:check_create_user_permission(Host, Node, Owner, Access).'''</p>
|
||||
create_node_permission(Host, ServerHost, Node, _ParentNode, Owner, Access) ->
|
||||
create_node_permission(_Host, ServerHost, Node, _ParentNode, Owner, Access) ->
|
||||
LOwner = jlib:jid_tolower(Owner),
|
||||
{User, Server, _Resource} = LOwner,
|
||||
Allowed = case acl:match_rule(ServerHost, Access, LOwner) of
|
||||
allow ->
|
||||
if Server == Host -> %% Server == ServerHost ??
|
||||
true;
|
||||
true ->
|
||||
case Node of
|
||||
["home", Server, User | _] -> true;
|
||||
_ -> false
|
||||
end
|
||||
case Node of
|
||||
["home", Server, User | _] -> true;
|
||||
_ -> false
|
||||
end;
|
||||
_ ->
|
||||
case Owner of
|
||||
@ -211,8 +208,7 @@ create_node_permission(Host, ServerHost, Node, _ParentNode, Owner, Access) ->
|
||||
_ -> false
|
||||
end
|
||||
end,
|
||||
ChildOK = true, %% TODO test with ParentNode
|
||||
{result, Allowed and ChildOK}.
|
||||
{result, Allowed}.
|
||||
|
||||
%% @spec (Host, Node, Owner) ->
|
||||
%% {result, Result} | exit
|
||||
@ -297,12 +293,12 @@ subscribe_node(Host, Node, Sender, Subscriber, AccessModel,
|
||||
not Authorized ->
|
||||
%% JIDs do not match
|
||||
{error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "invalid-jid")};
|
||||
Subscription == pending ->
|
||||
%% Requesting entity has pending subscription
|
||||
{error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "pending-subscription")};
|
||||
Affiliation == outcast ->
|
||||
%% Requesting entity is blocked
|
||||
{error, ?ERR_FORBIDDEN};
|
||||
Subscription == pending ->
|
||||
%% Requesting entity has pending subscription
|
||||
{error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "pending-subscription")};
|
||||
(AccessModel == presence) and (not PresenceSubscription) ->
|
||||
%% Entity is not authorized to create a subscription (presence subscription required)
|
||||
{error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "presence-subscription-required")};
|
||||
@ -446,6 +442,7 @@ publish_item(Host, Node, Publisher, PublishModel, MaxItems, ItemId, Payload) ->
|
||||
{error, ?ERR_FORBIDDEN};
|
||||
true ->
|
||||
PubId = {PublisherKey, now()},
|
||||
%% TODO: check creation, presence, roster (EJAB-663)
|
||||
Item = case get_item(Host, Node, ItemId) of
|
||||
{error, ?ERR_ITEM_NOT_FOUND} ->
|
||||
#pubsub_item{itemid = {ItemId, {Host, Node}},
|
||||
@ -501,7 +498,7 @@ remove_extra_items(Host, Node, MaxItems, ItemIds) ->
|
||||
%% ItemId = string()
|
||||
%% @doc <p>Triggers item deletion.</p>
|
||||
%% <p>Default plugin: The user performing the deletion must be the node owner
|
||||
%% or a node publisher e item publisher.</p>
|
||||
%% or a publisher.</p>
|
||||
delete_item(Host, Node, Publisher, ItemId) ->
|
||||
PublisherKey = jlib:jid_tolower(jlib:jid_remove_resource(Publisher)),
|
||||
State = case get_state(Host, Node, PublisherKey) of
|
||||
@ -542,17 +539,16 @@ delete_item(Host, Node, Publisher, ItemId) ->
|
||||
purge_node(Host, Node, Owner) ->
|
||||
OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
|
||||
case get_state(Host, Node, OwnerKey) of
|
||||
{error, ?ERR_ITEM_NOT_FOUND} ->
|
||||
%% This should not append (case node does not exists)
|
||||
{error, ?ERR_ITEM_NOT_FOUND};
|
||||
{result, #pubsub_state{items = Items, affiliation = owner}} ->
|
||||
lists:foreach(fun(ItemId) ->
|
||||
mnesia:delete({pubsub_item, {ItemId, {Host, Node}}})
|
||||
end, Items),
|
||||
{result, {default, broadcast}};
|
||||
{result, _} ->
|
||||
%% Entity is not owner
|
||||
{error, ?ERR_FORBIDDEN};
|
||||
_ ->
|
||||
%% Entity is not an owner
|
||||
{error, ?ERR_FORBIDDEN}
|
||||
{error, ?ERR_ITEM_NOT_FOUND}
|
||||
end.
|
||||
|
||||
%% @spec (Host, JID) -> [{Node,Affiliation}]
|
||||
@ -588,7 +584,7 @@ get_affiliation(Host, Node, Owner) ->
|
||||
OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
|
||||
Affiliation = case get_state(Host, Node, OwnerKey) of
|
||||
{result, #pubsub_state{affiliation = A}} -> A;
|
||||
_ -> unknown
|
||||
_ -> none
|
||||
end,
|
||||
{result, Affiliation}.
|
||||
|
||||
@ -638,7 +634,7 @@ get_subscription(Host, Node, Owner) ->
|
||||
OwnerKey = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
|
||||
Subscription = case get_state(Host, Node, OwnerKey) of
|
||||
{result, #pubsub_state{subscription = S}} -> S;
|
||||
_ -> unknown
|
||||
_ -> none
|
||||
end,
|
||||
{result, Subscription}.
|
||||
|
||||
@ -713,6 +709,44 @@ get_items(Host, Node) ->
|
||||
Items = mnesia:match_object(
|
||||
#pubsub_item{itemid = {'_', {Host, Node}}, _ = '_'}),
|
||||
{result, Items}.
|
||||
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) ->
|
||||
{Affiliation, Subscription} =
|
||||
case get_state(Host, Node, jlib:jid_tolower(jlib:jid_remove_resource(JID))) of
|
||||
{result, #pubsub_state{affiliation = A, subscription = S}} -> {A, S};
|
||||
_ -> {none, none}
|
||||
end,
|
||||
Subscribed = not ((Subscription == none) or (Subscription == pending)),
|
||||
if
|
||||
%%SubID == "", ?? ->
|
||||
%% Entity has multiple subscriptions to the node but does not specify a subscription ID
|
||||
%{error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "subid-required")};
|
||||
%%InvalidSubID ->
|
||||
%% Entity is subscribed but specifies an invalid subscription ID
|
||||
%{error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")};
|
||||
Affiliation == outcast ->
|
||||
%% Requesting entity is blocked
|
||||
{error, ?ERR_FORBIDDEN};
|
||||
(AccessModel == open) and (not Subscribed) ->
|
||||
%% Entity is not subscribed
|
||||
{error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "not-subscribed")};
|
||||
(AccessModel == presence) and (not PresenceSubscription) ->
|
||||
%% Entity is not authorized to create a subscription (presence subscription required)
|
||||
{error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "presence-subscription-required")};
|
||||
(AccessModel == roster) and (not RosterGroup) ->
|
||||
%% Entity is not authorized to create a subscription (not in roster group)
|
||||
{error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "not-in-roster-group")};
|
||||
(AccessModel == whitelist) -> % TODO: to be done
|
||||
%% Node has whitelist access model
|
||||
{error, ?ERR_EXTENDED(?ERR_NOT_ALLOWED, "closed-node")};
|
||||
(AccessModel == authorize) -> % TODO: to be done
|
||||
%% Node has authorize access model
|
||||
{error, ?ERR_FORBIDDEN};
|
||||
%%MustPay ->
|
||||
%% % Payment is required for a subscription
|
||||
%% {error, ?ERR_PAYMENT_REQUIRED};
|
||||
true ->
|
||||
get_items(Host, Node)
|
||||
end.
|
||||
|
||||
%% @spec (Host, Node, ItemId) -> [Item] | []
|
||||
%% Host = mod_pubsub:host()
|
||||
@ -727,6 +761,44 @@ get_item(Host, Node, ItemId) ->
|
||||
_ ->
|
||||
{error, ?ERR_ITEM_NOT_FOUND}
|
||||
end.
|
||||
get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId) ->
|
||||
{Affiliation, Subscription} =
|
||||
case get_state(Host, Node, jlib:jid_tolower(jlib:jid_remove_resource(JID))) of
|
||||
{result, #pubsub_state{affiliation = A, subscription = S}} -> {A, S};
|
||||
_ -> {none, none}
|
||||
end,
|
||||
Subscribed = not ((Subscription == none) or (Subscription == pending)),
|
||||
if
|
||||
%%SubID == "", ?? ->
|
||||
%% Entity has multiple subscriptions to the node but does not specify a subscription ID
|
||||
%{error, ?ERR_EXTENDED(?ERR_BAD_REQUEST, "subid-required")};
|
||||
%%InvalidSubID ->
|
||||
%% Entity is subscribed but specifies an invalid subscription ID
|
||||
%{error, ?ERR_EXTENDED(?ERR_NOT_ACCEPTABLE, "invalid-subid")};
|
||||
Affiliation == outcast ->
|
||||
%% Requesting entity is blocked
|
||||
{error, ?ERR_FORBIDDEN};
|
||||
(AccessModel == open) and (not Subscribed) ->
|
||||
%% Entity is not subscribed
|
||||
{error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "not-subscribed")};
|
||||
(AccessModel == presence) and (not PresenceSubscription) ->
|
||||
%% Entity is not authorized to create a subscription (presence subscription required)
|
||||
{error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "presence-subscription-required")};
|
||||
(AccessModel == roster) and (not RosterGroup) ->
|
||||
%% Entity is not authorized to create a subscription (not in roster group)
|
||||
{error, ?ERR_EXTENDED(?ERR_NOT_AUTHORIZED, "not-in-roster-group")};
|
||||
(AccessModel == whitelist) -> % TODO: to be done
|
||||
%% Node has whitelist access model
|
||||
{error, ?ERR_EXTENDED(?ERR_NOT_ALLOWED, "closed-node")};
|
||||
(AccessModel == authorize) -> % TODO: to be done
|
||||
%% Node has authorize access model
|
||||
{error, ?ERR_FORBIDDEN};
|
||||
%%MustPay ->
|
||||
%% % Payment is required for a subscription
|
||||
%% {error, ?ERR_PAYMENT_REQUIRED};
|
||||
true ->
|
||||
get_item(Host, Node, ItemId)
|
||||
end.
|
||||
|
||||
%% @spec (Item) -> ok | {error, Reason::stanzaError()}
|
||||
%% Item = mod_pubsub:pubsubItems()
|
||||
|
@ -60,7 +60,9 @@
|
||||
get_states/2,
|
||||
get_state/3,
|
||||
set_state/1,
|
||||
get_items/7,
|
||||
get_items/2,
|
||||
get_item/8,
|
||||
get_item/3,
|
||||
set_item/1,
|
||||
get_item_name/3
|
||||
@ -94,7 +96,6 @@ features() ->
|
||||
["create-nodes",
|
||||
"delete-nodes",
|
||||
"instant-nodes",
|
||||
"item-ids",
|
||||
"outcast-affiliation",
|
||||
"persistent-items",
|
||||
"publish",
|
||||
@ -175,9 +176,15 @@ set_state(State) ->
|
||||
get_items(Host, Node) ->
|
||||
node_default:get_items(Host, Node).
|
||||
|
||||
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
||||
get_item(Host, Node, ItemId) ->
|
||||
node_default:get_item(Host, Node, ItemId).
|
||||
|
||||
get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_default:get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
||||
set_item(Item) ->
|
||||
node_default:set_item(Item).
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
-module(node_pep).
|
||||
-author('christophe.romain@process-one.net').
|
||||
|
||||
-include("ejabberd.hrl").
|
||||
-include("pubsub.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
@ -57,7 +58,9 @@
|
||||
get_states/2,
|
||||
get_state/3,
|
||||
set_state/1,
|
||||
get_items/7,
|
||||
get_items/2,
|
||||
get_item/8,
|
||||
get_item/3,
|
||||
set_item/1,
|
||||
get_item_name/3
|
||||
@ -65,6 +68,7 @@
|
||||
|
||||
init(Host, ServerHost, Opts) ->
|
||||
node_default:init(Host, ServerHost, Opts),
|
||||
complain_if_modcaps_disabled(ServerHost),
|
||||
ok.
|
||||
|
||||
terminate(Host, ServerHost) ->
|
||||
@ -94,7 +98,6 @@ features() ->
|
||||
"auto-subscribe", %*
|
||||
"delete-nodes", %*
|
||||
"filtered-notifications", %*
|
||||
"item-ids",
|
||||
"modify-affiliations",
|
||||
"outcast-affiliation",
|
||||
"persistent-items",
|
||||
@ -183,7 +186,7 @@ get_node_subscriptions(_Host, _Node) ->
|
||||
{result, []}.
|
||||
|
||||
get_subscription(_Host, _Node, _Owner) ->
|
||||
{result, unknown}.
|
||||
{result, none}.
|
||||
|
||||
set_subscription(_Host, _Node, _Owner, _Subscription) ->
|
||||
ok.
|
||||
@ -200,11 +203,39 @@ set_state(State) ->
|
||||
get_items(Host, Node) ->
|
||||
node_default:get_items(Host, Node).
|
||||
|
||||
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
||||
get_item(Host, Node, ItemId) ->
|
||||
node_default:get_item(Host, Node, ItemId).
|
||||
|
||||
get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_default:get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
||||
set_item(Item) ->
|
||||
node_default:set_item(Item).
|
||||
|
||||
get_item_name(Host, Node, Id) ->
|
||||
node_default:get_item_name(Host, Node, Id).
|
||||
|
||||
|
||||
%%%
|
||||
%%% Internal
|
||||
%%%
|
||||
|
||||
%% @doc Check mod_caps is enabled, otherwise show warning.
|
||||
%% The PEP plugin for mod_pubsub requires mod_caps to be enabled in the host.
|
||||
%% Check that the mod_caps module is enabled in that Jabber Host
|
||||
%% If not, show a warning message in the ejabberd log file.
|
||||
complain_if_modcaps_disabled(ServerHost) ->
|
||||
Modules = ejabberd_config:get_local_option({modules, ServerHost}),
|
||||
ModCaps = [mod_caps_enabled || {mod_caps, _Opts} <- Modules],
|
||||
case ModCaps of
|
||||
[] ->
|
||||
?WARNING_MSG("The PEP plugin is enabled in mod_pubsub of host ~p. "
|
||||
"This plugin requires mod_caps to be enabled, "
|
||||
"but it isn't.", [ServerHost]);
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
|
||||
|
@ -62,7 +62,9 @@
|
||||
get_states/2,
|
||||
get_state/3,
|
||||
set_state/1,
|
||||
get_items/7,
|
||||
get_items/2,
|
||||
get_item/8,
|
||||
get_item/3,
|
||||
set_item/1,
|
||||
get_item_name/3
|
||||
@ -96,7 +98,6 @@ features() ->
|
||||
["create-nodes",
|
||||
"delete-nodes",
|
||||
"instant-nodes",
|
||||
"item-ids",
|
||||
"outcast-affiliation",
|
||||
"persistent-items",
|
||||
"publish",
|
||||
@ -175,9 +176,15 @@ set_state(State) ->
|
||||
get_items(Host, Node) ->
|
||||
node_default:get_items(Host, Node).
|
||||
|
||||
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
||||
get_item(Host, Node, ItemId) ->
|
||||
node_default:get_item(Host, Node, ItemId).
|
||||
|
||||
get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_default:get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
||||
set_item(Item) ->
|
||||
node_default:set_item(Item).
|
||||
|
||||
|
@ -62,7 +62,9 @@
|
||||
get_states/2,
|
||||
get_state/3,
|
||||
set_state/1,
|
||||
get_items/7,
|
||||
get_items/2,
|
||||
get_item/8,
|
||||
get_item/3,
|
||||
set_item/1,
|
||||
get_item_name/3
|
||||
@ -96,7 +98,6 @@ features() ->
|
||||
["create-nodes",
|
||||
"delete-nodes",
|
||||
"instant-nodes",
|
||||
"item-ids",
|
||||
"outcast-affiliation",
|
||||
"persistent-items",
|
||||
"publish",
|
||||
@ -172,9 +173,15 @@ set_state(State) ->
|
||||
get_items(Host, Node) ->
|
||||
node_default:get_items(Host, Node).
|
||||
|
||||
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
||||
get_item(Host, Node, ItemId) ->
|
||||
node_default:get_item(Host, Node, ItemId).
|
||||
|
||||
get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_default:get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
||||
set_item(Item) ->
|
||||
node_default:set_item(Item).
|
||||
|
||||
|
181
src/mod_pubsub/node_zoo.erl
Normal file
181
src/mod_pubsub/node_zoo.erl
Normal file
@ -0,0 +1,181 @@
|
||||
%%% ====================================================================
|
||||
%%% ``The contents of this file are subject to the Erlang Public License,
|
||||
%%% Version 1.1, (the "License"); you may not use this file except in
|
||||
%%% compliance with the License. You should have received a copy of the
|
||||
%%% Erlang Public License along with this software. If not, it can be
|
||||
%%% retrieved via the world wide web at http://www.erlang.org/.
|
||||
%%%
|
||||
%%% Software distributed under the License is distributed on an "AS IS"
|
||||
%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
%%% the License for the specific language governing rights and limitations
|
||||
%%% under the License.
|
||||
%%%
|
||||
%%% The Initial Developer of the Original Code is Process-one.
|
||||
%%% Portions created by Process-one are Copyright 2006-2008, Process-one
|
||||
%%% All Rights Reserved.''
|
||||
%%% This software is copyright 2006-2008, Process-one.
|
||||
%%%
|
||||
%%% @copyright 2006-2008 Process-one
|
||||
%%% @author Christophe romain <christophe.romain@process-one.net>
|
||||
%%% [http://www.process-one.net/]
|
||||
%%% @version {@vsn}, {@date} {@time}
|
||||
%%% @end
|
||||
%%% ====================================================================
|
||||
|
||||
-module(node_zoo).
|
||||
-author('christophe.romain@process-one.net').
|
||||
|
||||
-include("pubsub.hrl").
|
||||
-include("jlib.hrl").
|
||||
|
||||
-behaviour(gen_pubsub_node).
|
||||
|
||||
%% API definition
|
||||
-export([init/3, terminate/2,
|
||||
options/0, features/0,
|
||||
create_node_permission/6,
|
||||
create_node/3,
|
||||
delete_node/2,
|
||||
purge_node/3,
|
||||
subscribe_node/8,
|
||||
unsubscribe_node/5,
|
||||
publish_item/7,
|
||||
delete_item/4,
|
||||
remove_extra_items/4,
|
||||
get_entity_affiliations/2,
|
||||
get_node_affiliations/2,
|
||||
get_affiliation/3,
|
||||
set_affiliation/4,
|
||||
get_entity_subscriptions/2,
|
||||
get_node_subscriptions/2,
|
||||
get_subscription/3,
|
||||
set_subscription/4,
|
||||
get_states/2,
|
||||
get_state/3,
|
||||
set_state/1,
|
||||
get_items/7,
|
||||
get_items/2,
|
||||
get_item/8,
|
||||
get_item/3,
|
||||
set_item/1,
|
||||
get_item_name/3
|
||||
]).
|
||||
|
||||
|
||||
init(Host, ServerHost, Opts) ->
|
||||
node_default:init(Host, ServerHost, Opts).
|
||||
|
||||
terminate(Host, ServerHost) ->
|
||||
node_default:terminate(Host, ServerHost).
|
||||
|
||||
options() ->
|
||||
[{node_type, zoo},
|
||||
{deliver_payloads, true},
|
||||
{notify_config, false},
|
||||
{notify_delete, false},
|
||||
{notify_retract, true},
|
||||
{persist_items, true},
|
||||
{max_items, ?MAXITEMS div 2},
|
||||
{subscribe, true},
|
||||
{access_model, open},
|
||||
{roster_groups_allowed, []},
|
||||
{publish_model, publishers},
|
||||
{max_payload_size, ?MAX_PAYLOAD_SIZE},
|
||||
{send_last_published_item, never},
|
||||
{deliver_notifications, true},
|
||||
{presence_based_delivery, false}].
|
||||
|
||||
features() ->
|
||||
node_default:features().
|
||||
|
||||
%% use same code as node_default, but do not limite node to
|
||||
%% the home/localhost/user/... hierarchy
|
||||
%% any node is allowed
|
||||
create_node_permission(_Host, ServerHost, _Node, _ParentNode, Owner, Access) ->
|
||||
LOwner = jlib:jid_tolower(Owner),
|
||||
%%{_User, _Server, _Resource} = LOwner,
|
||||
Allowed = case acl:match_rule(ServerHost, Access, LOwner) of
|
||||
allow ->
|
||||
true;
|
||||
_ ->
|
||||
case Owner of
|
||||
{jid, "", _, "", "", _, ""} -> true;
|
||||
_ -> false
|
||||
end
|
||||
end,
|
||||
{result, Allowed}.
|
||||
|
||||
create_node(Host, Node, Owner) ->
|
||||
node_default:create_node(Host, Node, Owner).
|
||||
|
||||
delete_node(Host, Removed) ->
|
||||
node_default:delete_node(Host, Removed).
|
||||
|
||||
subscribe_node(Host, Node, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup) ->
|
||||
node_default:subscribe_node(Host, Node, Sender, Subscriber, AccessModel, SendLast, PresenceSubscription, RosterGroup).
|
||||
|
||||
unsubscribe_node(Host, Node, Sender, Subscriber, SubID) ->
|
||||
node_default:unsubscribe_node(Host, Node, Sender, Subscriber, SubID).
|
||||
|
||||
publish_item(Host, Node, Publisher, Model, MaxItems, ItemId, Payload) ->
|
||||
node_default:publish_item(Host, Node, Publisher, Model, MaxItems, ItemId, Payload).
|
||||
|
||||
remove_extra_items(Host, Node, MaxItems, ItemIds) ->
|
||||
node_default:remove_extra_items(Host, Node, MaxItems, ItemIds).
|
||||
|
||||
delete_item(Host, Node, JID, ItemId) ->
|
||||
node_default:delete_item(Host, Node, JID, ItemId).
|
||||
|
||||
purge_node(Host, Node, Owner) ->
|
||||
node_default:purge_node(Host, Node, Owner).
|
||||
|
||||
get_entity_affiliations(Host, Owner) ->
|
||||
node_default:get_entity_affiliations(Host, Owner).
|
||||
|
||||
get_node_affiliations(Host, Node) ->
|
||||
node_default:get_node_affiliations(Host, Node).
|
||||
|
||||
get_affiliation(Host, Node, Owner) ->
|
||||
node_default:get_affiliation(Host, Node, Owner).
|
||||
|
||||
set_affiliation(Host, Node, Owner, Affiliation) ->
|
||||
node_default:set_affiliation(Host, Node, Owner, Affiliation).
|
||||
|
||||
get_entity_subscriptions(Host, Owner) ->
|
||||
node_default:get_entity_subscriptions(Host, Owner).
|
||||
|
||||
get_node_subscriptions(Host, Node) ->
|
||||
node_default:get_node_subscriptions(Host, Node).
|
||||
|
||||
get_subscription(Host, Node, Owner) ->
|
||||
node_default:get_subscription(Host, Node, Owner).
|
||||
|
||||
set_subscription(Host, Node, Owner, Subscription) ->
|
||||
node_default:set_subscription(Host, Node, Owner, Subscription).
|
||||
|
||||
get_states(Host, Node) ->
|
||||
node_default:get_states(Host, Node).
|
||||
|
||||
get_state(Host, Node, JID) ->
|
||||
node_default:get_state(Host, Node, JID).
|
||||
|
||||
set_state(State) ->
|
||||
node_default:set_state(State).
|
||||
|
||||
get_items(Host, Node) ->
|
||||
node_default:get_items(Host, Node).
|
||||
|
||||
get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_default:get_items(Host, Node, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
||||
get_item(Host, Node, ItemId) ->
|
||||
node_default:get_item(Host, Node, ItemId).
|
||||
|
||||
get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId) ->
|
||||
node_default:get_item(Host, Node, ItemId, JID, AccessModel, PresenceSubscription, RosterGroup, SubId).
|
||||
|
||||
set_item(Item) ->
|
||||
node_default:set_item(Item).
|
||||
|
||||
get_item_name(Host, Node, Id) ->
|
||||
node_default:get_item_name(Host, Node, Id).
|
@ -241,12 +241,13 @@ send_welcome_message(JID) ->
|
||||
{"", ""} ->
|
||||
ok;
|
||||
{Subj, Body} ->
|
||||
BodyFormatted = io_lib:format(Body, []),
|
||||
ejabberd_router:route(
|
||||
jlib:make_jid("", Host, ""),
|
||||
JID,
|
||||
{xmlelement, "message", [{"type", "normal"}],
|
||||
[{xmlelement, "subject", [], [{xmlcdata, Subj}]},
|
||||
{xmlelement, "body", [], [{xmlcdata, Body}]}]});
|
||||
{xmlelement, "body", [], [{xmlcdata, BodyFormatted}]}]});
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
|
@ -40,6 +40,7 @@
|
||||
set_items/3,
|
||||
remove_user/2,
|
||||
get_jid_info/4,
|
||||
item_to_xml/1,
|
||||
webadmin_page/3,
|
||||
webadmin_user/4]).
|
||||
|
||||
|
@ -155,12 +155,12 @@ get_user_roster(Items, US) ->
|
||||
{{U1, S1}, GroupNames} <- dict:to_list(SRUsersRest)],
|
||||
SRItems ++ NewItems1.
|
||||
|
||||
%% This function in use to rewrite the roster entries when moving or renaming
|
||||
%% This function rewrites the roster entries when moving or renaming
|
||||
%% them in the user contact list.
|
||||
process_item(RosterItem, Host) ->
|
||||
USFrom = RosterItem#roster.us,
|
||||
{User,Server,_Resource} = RosterItem#roster.jid,
|
||||
USTo = {User,Server},
|
||||
USFrom = {UserFrom, ServerFrom} = RosterItem#roster.us,
|
||||
{UserTo, ServerTo, ResourceTo} = RosterItem#roster.jid,
|
||||
USTo = {UserTo, ServerTo},
|
||||
DisplayedGroups = get_user_displayed_groups(USFrom),
|
||||
CommonGroups = lists:filter(fun(Group) ->
|
||||
is_user_in_group(USTo, Group, Host)
|
||||
@ -174,9 +174,83 @@ process_item(RosterItem, Host) ->
|
||||
end, CommonGroups),
|
||||
RosterItem#roster{subscription = both, ask = none,
|
||||
groups=[GroupNames]};
|
||||
_ -> RosterItem#roster{subscription = both, ask = none}
|
||||
%% Both users have at least a common shared group,
|
||||
%% So each user can see the other
|
||||
_ ->
|
||||
%% Check if the list of groups of the new roster item
|
||||
%% include at least a new one
|
||||
case lists:subtract(RosterItem#roster.groups, CommonGroups) of
|
||||
[] ->
|
||||
RosterItem#roster{subscription = both, ask = none};
|
||||
%% If so, it means the user wants to add that contact
|
||||
%% to his personal roster
|
||||
PersonalGroups ->
|
||||
%% Store roster items in From and To rosters
|
||||
set_new_rosteritems(UserFrom, ServerFrom,
|
||||
UserTo, ServerTo, ResourceTo,
|
||||
PersonalGroups)
|
||||
end
|
||||
end.
|
||||
|
||||
build_roster_record(User1, Server1, User2, Server2, Groups) ->
|
||||
USR2 = {User2, Server2, ""},
|
||||
#roster{usj = {User1, Server1, USR2},
|
||||
us = {User1, Server1},
|
||||
jid = USR2,
|
||||
name = User2,
|
||||
subscription = both,
|
||||
ask = none,
|
||||
groups = Groups
|
||||
}.
|
||||
|
||||
set_new_rosteritems(UserFrom, ServerFrom,
|
||||
UserTo, ServerTo, ResourceTo, GroupsFrom) ->
|
||||
Mod = case lists:member(mod_roster_odbc,
|
||||
gen_mod:loaded_modules(ServerFrom)) of
|
||||
true -> mod_roster_odbc;
|
||||
false -> mod_roster
|
||||
end,
|
||||
|
||||
RIFrom = build_roster_record(UserFrom, ServerFrom,
|
||||
UserTo, ServerTo, GroupsFrom),
|
||||
set_item(UserFrom, ServerFrom, ResourceTo, RIFrom),
|
||||
JIDTo = jlib:make_jid(UserTo, ServerTo, ""),
|
||||
|
||||
JIDFrom = jlib:make_jid(UserFrom, ServerFrom, ""),
|
||||
RITo = build_roster_record(UserTo, ServerTo,
|
||||
UserFrom, ServerFrom, []),
|
||||
set_item(UserTo, ServerTo, "", RITo),
|
||||
|
||||
%% From requests
|
||||
Mod:out_subscription(UserFrom, ServerFrom, JIDTo, subscribe),
|
||||
Mod:in_subscription(aaa, UserTo, ServerTo, JIDFrom, subscribe, ""),
|
||||
|
||||
%% To accepts
|
||||
Mod:out_subscription(UserTo, ServerTo, JIDFrom, subscribed),
|
||||
Mod:in_subscription(aaa, UserFrom, ServerFrom, JIDTo, subscribed, ""),
|
||||
|
||||
%% To requests
|
||||
Mod:out_subscription(UserTo, ServerTo, JIDFrom, subscribe),
|
||||
Mod:in_subscription(aaa, UserFrom, ServerFrom, JIDTo, subscribe, ""),
|
||||
|
||||
%% From accepts
|
||||
Mod:out_subscription(UserFrom, ServerFrom, JIDTo, subscribed),
|
||||
Mod:in_subscription(aaa, UserTo, ServerTo, JIDFrom, subscribed, ""),
|
||||
|
||||
RIFrom.
|
||||
|
||||
set_item(User, Server, Resource, Item) ->
|
||||
ResIQ = #iq{type = set, xmlns = ?NS_ROSTER,
|
||||
id = "push",
|
||||
sub_el = [{xmlelement, "query",
|
||||
[{"xmlns", ?NS_ROSTER}],
|
||||
[mod_roster:item_to_xml(Item)]}]},
|
||||
ejabberd_router:route(
|
||||
jlib:make_jid(User, Server, Resource),
|
||||
jlib:make_jid("", Server, ""),
|
||||
jlib:iq_to_xml(ResIQ)).
|
||||
|
||||
|
||||
get_subscription_lists({F, T}, User, Server) ->
|
||||
LUser = jlib:nodeprep(User),
|
||||
LServer = jlib:nameprep(Server),
|
||||
@ -414,10 +488,10 @@ get_user_displayed_groups(US) ->
|
||||
end, get_user_groups(US))),
|
||||
[Group || Group <- DisplayedGroups1, is_group_enabled(Host, Group)].
|
||||
|
||||
is_user_in_group(US, Group, Host) ->
|
||||
is_user_in_group({_U, S} = US, Group, Host) ->
|
||||
case catch mnesia:dirty_match_object(
|
||||
#sr_user{us=US, group_host={Group, Host}}) of
|
||||
[] -> false;
|
||||
[] -> lists:member(US, get_group_users(S, Group));
|
||||
_ -> true
|
||||
end.
|
||||
|
||||
|
@ -271,13 +271,14 @@ process(Handlers, Request) ->
|
||||
process(HandlersLeft, Request)
|
||||
end.
|
||||
|
||||
process_request(#state{request_method = 'GET',
|
||||
process_request(#state{request_method = Method,
|
||||
request_path = {abs_path, Path},
|
||||
request_auth = Auth,
|
||||
request_lang = Lang,
|
||||
request_handlers = RequestHandlers,
|
||||
sockmod = SockMod,
|
||||
socket = Socket} = State) ->
|
||||
socket = Socket} = State)
|
||||
when Method=:='GET' orelse Method=:='HEAD' orelse Method=:='DELETE' ->
|
||||
case (catch url_decode_q_split(Path)) of
|
||||
{'EXIT', _} ->
|
||||
process_request(false);
|
||||
@ -289,19 +290,19 @@ process_request(#state{request_method = 'GET',
|
||||
LQ
|
||||
end,
|
||||
LPath = string:tokens(NPath, "/"),
|
||||
{ok, {IP, _Port}} =
|
||||
{ok, IP} =
|
||||
case SockMod of
|
||||
gen_tcp ->
|
||||
inet:peername(Socket);
|
||||
_ ->
|
||||
SockMod:peername(Socket)
|
||||
end,
|
||||
Request = #request{method = 'GET',
|
||||
Request = #request{method = Method,
|
||||
path = LPath,
|
||||
q = LQuery,
|
||||
auth = Auth,
|
||||
lang = Lang,
|
||||
ip=IP},
|
||||
ip = IP},
|
||||
%% XXX bard: This previously passed control to
|
||||
%% ejabberd_web:process_get, now passes it to a local
|
||||
%% procedure (process) that handles dispatching based on
|
||||
@ -319,7 +320,7 @@ process_request(#state{request_method = 'GET',
|
||||
end
|
||||
end;
|
||||
|
||||
process_request(#state{request_method = 'POST',
|
||||
process_request(#state{request_method = Method,
|
||||
request_path = {abs_path, Path},
|
||||
request_auth = Auth,
|
||||
request_content_length = Len,
|
||||
@ -327,7 +328,7 @@ process_request(#state{request_method = 'POST',
|
||||
sockmod = SockMod,
|
||||
socket = Socket,
|
||||
request_handlers = RequestHandlers} = State)
|
||||
when is_integer(Len) ->
|
||||
when (Method=:='POST' orelse Method=:='PUT') andalso is_integer(Len) ->
|
||||
case SockMod of
|
||||
gen_tcp ->
|
||||
inet:setopts(Socket, [{packet, 0}]);
|
||||
@ -347,12 +348,20 @@ process_request(#state{request_method = 'POST',
|
||||
LQ ->
|
||||
LQ
|
||||
end,
|
||||
Request = #request{method = 'POST',
|
||||
{ok, IP} =
|
||||
case SockMod of
|
||||
gen_tcp ->
|
||||
inet:peername(Socket);
|
||||
_ ->
|
||||
SockMod:peername(Socket)
|
||||
end,
|
||||
Request = #request{method = Method,
|
||||
path = LPath,
|
||||
q = LQuery,
|
||||
auth = Auth,
|
||||
data = Data,
|
||||
lang = Lang},
|
||||
lang = Lang,
|
||||
ip = IP},
|
||||
case process(RequestHandlers, Request) of
|
||||
El when element(1, El) == xmlelement ->
|
||||
make_xhtml_output(State, 200, [], El);
|
||||
|
@ -50,13 +50,16 @@
|
||||
|
||||
-record(http_poll, {id, pid}).
|
||||
|
||||
-define(NULL_PEER, {{0, 0, 0, 0}, 0}).
|
||||
|
||||
-record(state, {id,
|
||||
key,
|
||||
output = "",
|
||||
input = "",
|
||||
waiting_input = false, %% {ReceiverPid, Tag}
|
||||
last_receiver,
|
||||
timer}).
|
||||
timer,
|
||||
ip = ?NULL_PEER }).
|
||||
|
||||
%-define(DBGFSM, true).
|
||||
|
||||
@ -94,11 +97,16 @@ setopts({http_poll, FsmRef}, Opts) ->
|
||||
ok
|
||||
end.
|
||||
|
||||
sockname(_Socket) ->
|
||||
{ok, {{0, 0, 0, 0}, 0}}.
|
||||
sockname(_) ->
|
||||
{ok, ?NULL_PEER}.
|
||||
|
||||
peername(_Socket) ->
|
||||
{ok, {{0, 0, 0, 0}, 0}}.
|
||||
peername({http_poll, FsmRef}) ->
|
||||
case catch gen_fsm:sync_send_all_state_event(FsmRef, peername, 1000) of
|
||||
{ok, IP} -> {ok, IP};
|
||||
_ -> {ok, ?NULL_PEER}
|
||||
end;
|
||||
peername(_) ->
|
||||
{ok, ?NULL_PEER}.
|
||||
|
||||
controlling_process(_Socket, _Pid) ->
|
||||
ok.
|
||||
@ -107,7 +115,7 @@ close({http_poll, FsmRef}) ->
|
||||
catch gen_fsm:sync_send_all_state_event(FsmRef, close).
|
||||
|
||||
|
||||
process([], #request{data = Data} = _Request) ->
|
||||
process([], #request{data = Data, ip = IP} = _Request) ->
|
||||
case catch parse_request(Data) of
|
||||
{ok, ID1, Key, NewKey, Packet} ->
|
||||
ID = if
|
||||
@ -123,7 +131,7 @@ process([], #request{data = Data} = _Request) ->
|
||||
true ->
|
||||
ID1
|
||||
end,
|
||||
case http_put(ID, Key, NewKey, Packet) of
|
||||
case http_put(ID, Key, NewKey, Packet, IP) of
|
||||
{error, not_exists} ->
|
||||
{200, ?BAD_REQUEST, ""};
|
||||
{error, bad_key} ->
|
||||
@ -249,7 +257,7 @@ handle_sync_event(stop, _From, _StateName, StateData) ->
|
||||
Reply = ok,
|
||||
{stop, normal, Reply, StateData};
|
||||
|
||||
handle_sync_event({http_put, Key, NewKey, Packet},
|
||||
handle_sync_event({http_put, Key, NewKey, Packet, IP},
|
||||
_From, StateName, StateData) ->
|
||||
Allow = case StateData#state.key of
|
||||
"" ->
|
||||
@ -271,7 +279,8 @@ handle_sync_event({http_put, Key, NewKey, Packet},
|
||||
Input = [StateData#state.input|Packet],
|
||||
Reply = ok,
|
||||
{reply, Reply, StateName, StateData#state{input = Input,
|
||||
key = NewKey}};
|
||||
key = NewKey,
|
||||
ip = IP}};
|
||||
{Receiver, _Tag} ->
|
||||
Receiver ! {tcp, {http_poll, self()},
|
||||
list_to_binary(Packet)},
|
||||
@ -282,7 +291,8 @@ handle_sync_event({http_put, Key, NewKey, Packet},
|
||||
StateData#state{waiting_input = false,
|
||||
last_receiver = Receiver,
|
||||
key = NewKey,
|
||||
timer = Timer}}
|
||||
timer = Timer,
|
||||
ip = IP}}
|
||||
end;
|
||||
true ->
|
||||
Reply = {error, bad_key},
|
||||
@ -293,6 +303,10 @@ handle_sync_event(http_get, _From, StateName, StateData) ->
|
||||
Reply = {ok, StateData#state.output},
|
||||
{reply, Reply, StateName, StateData#state{output = ""}};
|
||||
|
||||
handle_sync_event(peername, _From, StateName, StateData) ->
|
||||
Reply = {ok, StateData#state.ip},
|
||||
{reply, Reply, StateName, StateData};
|
||||
|
||||
handle_sync_event(_Event, _From, StateName, StateData) ->
|
||||
Reply = ok,
|
||||
{reply, Reply, StateName, StateData}.
|
||||
@ -343,13 +357,13 @@ terminate(_Reason, _StateName, StateData) ->
|
||||
%%% Internal functions
|
||||
%%%----------------------------------------------------------------------
|
||||
|
||||
http_put(ID, Key, NewKey, Packet) ->
|
||||
http_put(ID, Key, NewKey, Packet, IP) ->
|
||||
case mnesia:dirty_read({http_poll, ID}) of
|
||||
[] ->
|
||||
{error, not_exists};
|
||||
[#http_poll{pid = FsmRef}] ->
|
||||
gen_fsm:sync_send_all_state_event(
|
||||
FsmRef, {http_put, Key, NewKey, Packet})
|
||||
FsmRef, {http_put, Key, NewKey, Packet, IP})
|
||||
end.
|
||||
|
||||
http_get(ID) ->
|
||||
|
@ -2022,7 +2022,7 @@ node_backup_parse_query(Node, Query) ->
|
||||
rpc:call(Node, mnesia,
|
||||
install_fallback, [Path]);
|
||||
"dump" ->
|
||||
rpc:call(Node, mnesia,
|
||||
rpc:call(Node, ejabberd_ctl,
|
||||
dump_to_textfile, [Path]);
|
||||
"load" ->
|
||||
rpc:call(Node, mnesia,
|
||||
|
@ -4,7 +4,8 @@ NODE=ejabberd
|
||||
HOST=localhost
|
||||
|
||||
# Define ejabberd environment
|
||||
base="`dirname $(which "$0")`/.."
|
||||
here=`which "$0" 2>/dev/null || echo .`
|
||||
base="`dirname $here`/.."
|
||||
ROOTDIR=`(cd "$base"; echo $PWD)`
|
||||
SASL_LOG_PATH=$ROOTDIR/sasl.log
|
||||
EJABBERD_DB=$ROOTDIR/database/$NODE
|
||||
|
Loading…
Reference in New Issue
Block a user