]> granicus.if.org Git - ejabberd/commitdiff
* src/mod_pubsub/mod_pubsub.erl: Support for pubsub node
authorMickaël Rémond <mickael.remond@process-one.net>
Wed, 7 Jun 2006 08:38:37 +0000 (08:38 +0000)
committerMickaël Rémond <mickael.remond@process-one.net>
Wed, 7 Jun 2006 08:38:37 +0000 (08:38 +0000)
creation ACL.  It is now possible to limit the node creation rights
using an ACL from ejabberd config file (Thanks to Christophe Romain)
(EJAB-104).
* doc/guide.tex: Likewise.
* src/ejabberd.cfg.example.

SVN Revision: 577

ChangeLog
doc/dev.html
doc/guide.html
doc/guide.tex
src/ejabberd.cfg.example
src/mod_pubsub/mod_pubsub.erl

index 8781a885e820e9d42a6e8dd0521834ec5130e04f..ca73c8acebba8910b72be71b5237cf3096911929 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2006-06-07  Mickael Remond  <mickael.remond@process-one.net>
+
+       * src/mod_pubsub/mod_pubsub.erl: Support for pubsub node creation ACL.
+       It is now possible to limit the node creation rights using an ACL from
+       ejabberd config file (Thanks to Christophe Romain). 
+       * doc/guide.tex: Likewise.
+       * src/ejabberd.cfg.example.
+
 2006-06-02  Mickael Remond  <mickael.remond@process-one.net>
 
        * src/web/ejabberd_http_poll.erl: Messages polled between the
index 65a85172a2db1afa4d375d45ba145e1f19dcdad3..0daaf175b9f332267dd94054c208e57397000aa3 100644 (file)
@@ -4,7 +4,7 @@
 
 <HEAD>
 
-<TITLE>Ejabberd 1.0.0 Developers Guide</TITLE>
+<TITLE>Ejabberd 1.1.1 Developers Guide</TITLE>
 
 <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
 <META name="GENERATOR" content="hevea 1.08">
@@ -34,7 +34,7 @@ BLOCKQUOTE{margin-left:4ex;margin-right:4ex;text-align:left;}
 
  <TABLE CLASS="title">
 <TR><TD>
-<H1 CLASS="titlemain">Ejabberd 1.0.0 Developers Guide</H1>
+<H1 CLASS="titlemain">Ejabberd 1.1.1 Developers Guide</H1>
 <H3 CLASS="titlerest">Alexey Shchepin<BR>
 <A HREF="mailto:alexey@sevcom.net"><TT>mailto:alexey@sevcom.net</TT></A><BR>
 <A HREF="xmpp:aleksey@jabber.ru"><TT>xmpp:aleksey@jabber.ru</TT></A></H3></TD>
@@ -101,16 +101,16 @@ BLOCKQUOTE{margin-left:4ex;margin-right:4ex;text-align:left;}
 <UL CLASS="itemize"><LI CLASS="li-itemize">
 Multiplatform: <TT>ejabberd</TT> runs under Microsoft Windows and Unix derived systems such as Linux, FreeBSD and NetBSD.<BR>
 <BR>
-<LI CLASS="li-itemize">Distributed: You can run <TT>ejabberd</TT> on a cluster of machines and all of them will serve one Jabber domain. When you need more capacity you can simply add a new cheap node to your cluster. Accordingly, you do not need to buy an expensive high-end machine to support tens of thousands concurrent users.<BR>
+<LI CLASS="li-itemize">Distributed: You can run <TT>ejabberd</TT> on a cluster of machines and all of them will serve the same Jabber domain(s). When you need more capacity you can simply add a new cheap node to your cluster. Accordingly, you do not need to buy an expensive high-end machine to support tens of thousands concurrent users.<BR>
 <BR>
 <LI CLASS="li-itemize">Fault-tolerant: You can deploy an <TT>ejabberd</TT> cluster so that all the information required for a properly working service will be replicated permanently on all nodes. This means that if one of the nodes crashes, the others will continue working without disruption. In addition, nodes also can be added or replaced &#8220;on the fly&#8221;.<BR>
 <BR>
 <LI CLASS="li-itemize">Administrator Friendly: <TT>ejabberd</TT> is built on top of the Open Source Erlang. As a result you do not need to install an external database, an external web server, amongst others because everything is already included, and ready to run out of the box. Other administrator benefits include:
 <UL CLASS="itemize"><LI CLASS="li-itemize">
 Comprehensive documentation.
-<LI CLASS="li-itemize">Straightforward installers for Windows and Linux.
+<LI CLASS="li-itemize">Straightforward installers for Linux, Mac OS X, and Windows.
 <LI CLASS="li-itemize">Web interface for administration tasks.
-<LI CLASS="li-itemize">Shared Roster groups.
+<LI CLASS="li-itemize">Shared Roster Groups.
 <LI CLASS="li-itemize">Command line administration tool.
 <LI CLASS="li-itemize">Can integrate with existing authentication mechanisms.
 <LI CLASS="li-itemize">Capability to send announce messages.
@@ -124,7 +124,7 @@ Translated in 11 languages.
 <BR>
 <LI CLASS="li-itemize">Open Standards: <TT>ejabberd</TT> is the first Open Source Jabber server claiming to fully comply to the XMPP standard.
 <UL CLASS="itemize"><LI CLASS="li-itemize">
-Fully XMPP compliant  
+Fully XMPP compliant 
 <LI CLASS="li-itemize">XML-based protocol
 <LI CLASS="li-itemize"><A HREF="http://ejabberd.jabber.ru/protocols">Many JEPs supported</A>.
 </UL></UL>
@@ -136,7 +136,7 @@ Fully XMPP compliant
 
 Besides common Jabber server features, <TT>ejabberd</TT> comes with a wide range of other features:
 <UL CLASS="itemize"><LI CLASS="li-itemize">
-Modular: <TT>ejabberd</TT>'s modular architecture allows easy customization:
+Modular
 <UL CLASS="itemize"><LI CLASS="li-itemize">
 Load only the modules you want.
 <LI CLASS="li-itemize">Extend <TT>ejabberd</TT> with your own custom modules.
@@ -145,37 +145,33 @@ Load only the modules you want.
 <UL CLASS="itemize"><LI CLASS="li-itemize">
 SASL and STARTTLS for c2s and s2s connections.
 <LI CLASS="li-itemize">STARTTLS and Dialback s2s connections.
-<LI CLASS="li-itemize">Obsolete SSL for c2s connections also supported.
 <LI CLASS="li-itemize">Web interface accessible via HTTPS secure access.
 </UL>
 <LI CLASS="li-itemize">Databases
 <UL CLASS="itemize"><LI CLASS="li-itemize">
-Native PostgreSQL support. 
+Native MySQL support.
+<LI CLASS="li-itemize">Native PostgreSQL support.
 <LI CLASS="li-itemize">Mnesia.
 <LI CLASS="li-itemize">ODBC data storage support. 
 </UL>
 <LI CLASS="li-itemize">Authentication
 <UL CLASS="itemize"><LI CLASS="li-itemize">
-LDAP. 
+LDAP and ODBC
 <LI CLASS="li-itemize">External Authentication script.
 <LI CLASS="li-itemize">Internal Authentication.
 </UL>
-<LI CLASS="li-itemize">The ability to interface via external components with networks such as:
-<UL CLASS="itemize"><LI CLASS="li-itemize">
-AIM
-<LI CLASS="li-itemize">ICQ
-<LI CLASS="li-itemize">MSN
-</UL>
 <LI CLASS="li-itemize">Others
 <UL CLASS="itemize"><LI CLASS="li-itemize">
-IPv6 support both for c2s and s2s connections. 
+Compressing XML streams with Stream Compression (<A HREF="http://www.jabber.org/jeps/jep-0138.html">JEP-0138</A>).
+<LI CLASS="li-itemize">Interface with networks such as AIM, ICQ and MSN.
+<LI CLASS="li-itemize">Statistics via Statistics Gathering (<A HREF="http://www.jabber.org/jeps/jep-0039.html">JEP-0039</A>).
+<LI CLASS="li-itemize">IPv6 support both for c2s and s2s connections.
+<LI CLASS="li-itemize"><A HREF="http://www.jabber.org/jeps/jep-0045.html">Multi-User Chat</A> module with logging.
+<LI CLASS="li-itemize">Users Directory based on users vCards.
+<LI CLASS="li-itemize"><A HREF="http://www.jabber.org/jeps/jep-0060.html">Publish-Subscribe</A> component.
 <LI CLASS="li-itemize">Support for virtual hosting. 
-<LI CLASS="li-itemize"><A HREF="http://www.jabber.org/jeps/jep-0025.html">HTTP Polling</A> service
-<LI CLASS="li-itemize"><A HREF="http://www.jabber.org/jeps/jep-0045.html">Multi-User Chat</A> module.
+<LI CLASS="li-itemize"><A HREF="http://www.jabber.org/jeps/jep-0025.html">HTTP Polling</A> service.
 <LI CLASS="li-itemize">IRC transport.
-<LI CLASS="li-itemize"><A HREF="http://www.jabber.org/jeps/jep-0060.html">Publish-Subscribe</A> component.
-<LI CLASS="li-itemize">Users Directory based on users vCards.
-<LI CLASS="li-itemize">Statistics via Statistics Gathering (<A HREF="http://www.jabber.org/jeps/jep-0039.html">JEP-0039</A>).
 </UL>
 </UL>
 <!--TOC section How it works-->
index cf24854e3d3c6e50e7b2578506e0e8018825b54a..7dc2ddc2253111811cb2f160b7d8036b3132e5c5 100644 (file)
@@ -2188,14 +2188,18 @@ Options:
 
 <DT CLASS="dt-description"><B><TT>served_hosts</TT></B><DD CLASS="dd-description"> To specify which hosts needs to
  be served, you can use this option. If absent, only the main <TT>ejabberd</TT>
- host is served. </DL>
+ host is served. <DT CLASS="dt-description"><B><TT>access_createnode</TT></B><DD CLASS="dd-description"> 
+ Restricts which users are allowed to create pubsub nodes using ACL and ACCESS.
+ Default: <TT>pubsub_createnode</TT>.
+</DL>
 Example:
 <PRE CLASS="verbatim">
   {modules,
    [
     ...
     {mod_pubsub, [{served_hosts, ["example.com",
-                                  "example.org"]}]}
+                                  "example.org"]},
+                  {access_createnode, pubsub_createnode}]}
     ...
    ]}.
 </PRE>
index 3bf520849a565426e08509aa60d7c9d313a1f8c1..99e2df91af7bd60ff5bcc8504fa1b5eae57c8274 100644 (file)
@@ -1913,6 +1913,9 @@ Options:
 \titem{served\_hosts} \ind{options!served\_hosts}To specify which hosts needs to
   be served, you can use this option. If absent, only the main \ejabberd{}
   host is served. % Not a straigtforward description! This needs to be improved!
+\titem{access\_createnode} \ind{options!access\_createnode}
+    Restricts which users are allowed to create pubsub nodes using ACL and ACCESS.
+    Default: \term{pubsub\_createnode}.
 \end{description}
 
 Example:
@@ -1921,7 +1924,8 @@ Example:
    [
     ...
     {mod_pubsub, [{served_hosts, ["example.com",
-                                  "example.org"]}]}
+                                  "example.org"]},
+                  {access_createnode, pubsub_createnode}]}
     ...
    ]}.
 \end{verbatim}
index e8ef5a4c542b03b792209b428805de428ac81d0f..bcc103385a0b7a12450cc02bb0f18c21f841664f 100644 (file)
@@ -20,6 +20,8 @@
 %{acl, test, {user_regexp, "^test"}}.
 %{acl, test, {user_glob, "test*"}}.
 
+% Everybody can create pubsub nodes
+{access, pubsub_createnode, [{allow, all}]}.
 
 % Only admins can use configuration interface:
 {access, configure, [{allow, admin}]}.
                    {access_admin, muc_admin}]},
 %  {mod_muc_log,    []},
 %  {mod_shared_roster, []},
-  {mod_pubsub,     []},
+  {mod_pubsub,     [{access_createnode, pubsub_createnode}]},
   {mod_time,       []},
   {mod_last,       []},
   {mod_version,    []}
index a965153432f77981a581ce7a94a319e26a6f4e66..6c46ffdb3882627b3cc03d0cebb92288655c78a6 100644 (file)
@@ -33,7 +33,7 @@
 -include("ejabberd.hrl").
 -include("jlib.hrl").
 
--record(state, {host}).
+-record(state, {host, server_host, access}).
 
 -define(DICT, dict).
 -define(MAXITEMS, 20).
@@ -122,6 +122,7 @@ init([ServerHost, Opts]) ->
     update_table(Host),
     mnesia:add_table_index(pubsub_node, host_parent),
     ServedHosts = gen_mod:get_opt(served_hosts, Opts, []),
+    Access = gen_mod:get_opt(access_createnode, Opts, all),
 
     ejabberd_router:register_route(Host),
     create_new_node(Host, ["pubsub"], ?MYJID),
@@ -133,7 +134,7 @@ init([ServerHost, Opts]) ->
                  end, ServedHosts),
     ets:new(gen_mod:get_module_proc(Host, pubsub_presence),
            [set, named_table]),
-    {ok, #state{host = Host}}.
+    {ok, #state{host = Host, server_host = ServerHost, access = Access}}.
 
 %%--------------------------------------------------------------------
 %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
@@ -162,8 +163,9 @@ handle_cast(_Msg, State) ->
 %%                                       {stop, Reason, State}
 %% Description: Handling all non call/cast messages
 %%--------------------------------------------------------------------
-handle_info({route, From, To, Packet}, State) ->
-    case catch do_route(To#jid.lserver, From, To, Packet) of
+handle_info({route, From, To, Packet}, 
+#state{server_host = ServerHost, access = Access} = State) ->
+    case catch do_route(To#jid.lserver, ServerHost, Access, From, To, Packet) of
        {'EXIT', Reason} ->
            ?ERROR_MSG("~p", [Reason]);
        _ ->
@@ -194,7 +196,7 @@ code_change(_OldVsn, State, _Extra) ->
 %%--------------------------------------------------------------------
 %%% Internal functions
 %%--------------------------------------------------------------------
-do_route(Host, From, To, Packet) ->
+do_route(Host, ServerHost, Access, From, To, Packet) ->
     {xmlelement, Name, Attrs, Els} = Packet,
     case To of
        #jid{luser = "", lresource = ""} ->
@@ -232,7 +234,7 @@ do_route(Host, From, To, Packet) ->
                        #iq{type = Type, xmlns = ?NS_PUBSUB = XMLNS,
                            sub_el = SubEl} = IQ ->
                            Res =
-                               case iq_pubsub(Host, From, Type, SubEl) of
+                               case iq_pubsub(Host, ServerHost, From, Type, SubEl, Access) of
                                    {result, IQRes} ->
                                        jlib:iq_to_xml(
                                          IQ#iq{type = result,
@@ -397,7 +399,7 @@ iq_get_vcard(Lang) ->
                    "Copyright (c) 2003-2006 Alexey Shchepin")}]}].
 
 
-iq_pubsub(Host, From, Type, SubEl) ->
+iq_pubsub(Host, ServerHost, From, Type, SubEl, Access) ->
     {xmlelement, _, _, SubEls} = SubEl,
     case xml:remove_cdata(SubEls) of
        [{xmlelement, Name, Attrs, Els}] ->
@@ -405,7 +407,7 @@ iq_pubsub(Host, From, Type, SubEl) ->
            Node = string:tokens(SNode, "/"),
            case {Type, Name} of
                {set, "create"} ->
-                   create_new_node(Host, Node, From);
+                   create_new_node(Host, Node, From, ServerHost, Access);
                {set, "publish"} ->
                    case xml:remove_cdata(Els) of
                        [{xmlelement, "item", ItemAttrs, Payload}] ->
@@ -484,13 +486,17 @@ iq_pubsub(Host, From, Type, SubEl) ->
 %% Create new pubsub nodes
 %% This function is used during init to create the first bootstrap nodes
 create_new_node(Host, Node, Owner) ->
+    %% This is the case use during "bootstrapping to create the initial
+    %% hierarchy. Should always be ... undefined,all
+    create_new_node(Host, Node, Owner, undefined, all).
+create_new_node(Host, Node, Owner, ServerHost, Access) ->
     case Node of
        [] ->
            {LOU, LOS, _} = jlib:jid_tolower(Owner),
            HomeNode = ["home", LOS, LOU],
-           create_new_node(Host, HomeNode, Owner),
+           create_new_node(Host, HomeNode, Owner, ServerHost, Access),
            NewNode = ["home", LOS, LOU, randoms:get_string()],
-           create_new_node(Host, NewNode, Owner);
+           create_new_node(Host, NewNode, Owner, ServerHost, Access);
        _ ->
            LOwner = jlib:jid_tolower(jlib:jid_remove_resource(Owner)),
            Parent = lists:sublist(Node, length(Node) - 1),
@@ -525,7 +531,7 @@ create_new_node(Host, Node, Owner) ->
                                end
                        end
                end,
-           case check_create_permission(Host, Node, Owner) of
+           case check_create_permission(Host, Node, Owner, ServerHost, Access) of
                true ->
                    case mnesia:transaction(F) of
                        {atomic, ok} ->
@@ -1052,14 +1058,23 @@ subscription_to_string(Subscription) ->
     end.
 
 
-check_create_permission(Host, Node, Owner) ->
-    if
-       Owner#jid.lserver == Host ->
-           true;
-       true ->
-           #jid{luser = User, lserver = Server} = Owner,
-           case Node of
-               ["home", Server, User | _] ->
+check_create_permission(Host, Node, Owner, ServerHost, Access) ->
+       #jid{luser = User, lserver = Server, lresource = Resource} = Owner,
+    case acl:match_rule(ServerHost, Access, {User, Server, Resource}) of
+    allow ->
+       if Server == Host ->
+               true;
+               true ->
+               case Node of
+                       ["home", Server, User | _] ->
+                       true;
+                       _ ->
+                           false
+                   end
+           end;
+       _ ->
+           case Owner of
+               ?MYJID ->
                    true;
                _ ->
                    false