* 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)
(EJAB-104).
* doc/guide.tex: Likewise.
* src/ejabberd.cfg.example.

SVN Revision: 577
This commit is contained in:
Mickaël Rémond 2006-06-07 08:38:37 +00:00
parent 05c50cc5ca
commit 9dcd3f4080
6 changed files with 75 additions and 46 deletions

View File

@ -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

View 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.
<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">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.
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">IRC transport.
</UL>
</UL>
<!--TOC section How it works-->

View 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>

View 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}

View 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}]}.
@ -171,7 +173,7 @@
{access_admin, muc_admin}]},
% {mod_muc_log, []},
% {mod_shared_roster, []},
{mod_pubsub, []},
{mod_pubsub, [{access_createnode, pubsub_createnode}]},
{mod_time, []},
{mod_last, []},
{mod_version, []}

View 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