<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://docbook.org/xml/4.1.2/docbookx.dtd">

<article lang="en">
  <articleinfo>
    <title>datatree -- PigeonDeliver Database Structure, concepts and delivery process</title>
    <author>
      <firstname>Carlo</firstname>
      <surname>Contavalli</surname>
      <affiliation>
        <address><email>ccontavalli at masobit.net</email></address>
      </affiliation>
    </author>
    <revhistory>
      <revision>
        <revnumber>1.0.0</revnumber>
        <date>2004/07/03</date>
        <revremark>First Document Revision</revremark>
      </revision>
      <!--
      <revision>
        <revnumber>v2.2.7</revnumber>
        <date>2003-07-09</date>
        <authorinitials>es</authorinitials>
        <revremark> Fixed broken links to LDP XSL and other LDP XSL spefic filenames. </revremark>
      </revision>
      -->
    </revhistory>

    <abstract>
      <para>
        This document describes the structure of the 
	<ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> Database, how 
	users data is stored into the database, how roles and roles privileges are enforced
	and how a mail is finally delivered by the 
	<ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> mailing system.</para>
    </abstract>
  </articleinfo>

  <!-- nota: l'id deve essere diverso per ogni sezione,
   	e serv per generare automaticamente delle referenze
	incrociate (esempio: guardate la sezione X per
	maggiori informazioni. X puo` cambiare, se vengono
	spostati dei dati su e giu` per il documento. L'id
	no -->
  <sect1 id="intro">
    <title>Before starting</title>

    <para>
      This document was written as part of the documentation
      of the PigeonAir Project to provide help and support to 
      users, system administrators or developers.
    </para>

    <para>
      While every effort has been made to ensure that the 
      information is accurate at the time of publication,
      this document may contain errors, omissions, incongruences 
      or wrong technical details. No liability for damages
      is accepted by the Author/Authors, the publishers or
      any other organization or person providing the information,
      arising from any errors or omissions that may appear,
      however caused.
    </para>

    <para>
      In case you find an error, you would like to propose better
      solutions than those discussed in this document or you
      would like to discuss an idea regarding this document
      or its content, we would be glad to hear from you and
      please feel free to contact us by writing to the &lt;pigeon-dev 
      at ml.pigeonair.net&gt; mailing list or by directly 
      contacting one of the authors.
    </para>

    <sect2>
    <title>Intended Audience</title>
      <para>
        This document is meant to introduce users and administrators to the 
    	<ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> mail 
	delivery process and to provide all the information needed
	to understand users and administrators privileges, privileges enforcing
	mechanisms and configuration management. 
      </para>
      <para>
        However, this document does not provide any detail about the 
	<ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink>
    	System Architecture, how services can be distributed among machines
	or how the system deals with privileges and services in a distributed
	environment.
      </para>

    </sect2>

    <sect2>
      <title>Copyright Notice</title>

      <para>
        This document was written by Carlo Contavalli &lt;ccontavalli at masobit.net&gt; 
        and is thus Copyright (C) Carlo Contavalli 2003, 2004 and the PigeonAir Project.
      </para>
      <para>
        Permission is granted to copy, distribute and/or modify this document
        under the terms of the GNU Free Documentation License, Version 1.1 or
        any later version published by the Free Software Foundation; with no
        Invariant Sections, no Front-Cover Texts and no Back-Cover Texts.
      </para>

      <para>
        Any example of program code available in this document should be
        considered protected by the terms of the GNU General Public License.
      </para>

      <para>
        You should have received a copy of the GNU General Public License
        along with this document; if not, write to the Free Software
        Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
      </para>

      <para>
        Trademarks are owned by their respective owners. 
      </para>
    </sect2>

<!--
    <sect2>
    <title>Before reading this document</title>
    <para>
      No needed prerequisites.
    </para>
    </sect2>

    <sect2>
    <title>Further readings</title>
    <para>
     <itemizedlist>
      <listitem>
        <para><ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> Administrators FAQ</para>
      </listitem>

      <listitem>
        <para><ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> Administrators FAQ</para>
      </listitem>
 
    </para>
    </sect2>
    -->
  </sect1>


  <sect1>
    <title>Mail delivery process</title>

    <para>
      Upon every smtpd received email, the <ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> database is looked 
      up to verify:
      <itemizedlist>
        <listitem><para>
	  if the recipient exists in the local users database
	</para></listitem>
	<listitem><para>
	  if it does not, the domain is looked up to verify if
	  it does accept mail for unknown users
	</para></listitem>
	<listitem><para>
	  if none of the conditions above apply, the mail is
	  either considered for relay or rejected with the
	  corresponding smtp error
	</para></listitem>
      </itemizedlist>
    </para>

    <para>
      In case the recipient is known in the local users database or in
      case the domain is known and accepts emails even for unknown users, 
      the mail is accepted for local delivery and inserted into the ``incoming'' 
      queue of the mailing system.
    </para>

    <para>
      Once in the incoming queue, it is passed over to the <ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> delivery
      agent that attempts delivery from the ``active'' queue.
    </para>

    <para>
      The <ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> delivery agent (mailMaster) takes the name of each recipient
      in turn, and splits it up into ``username'' and ``domain''. 
    </para>

    <para>
      It then looks up the <ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> database looking for the ``domain'' configuration.
      Both the domain configuration and the user configuration is made up by a list
      of ``modules'' to be run to deliver the email.
    </para>

    <para>
      Each module performs a specific task of the delivery process and has its own
      configuration parameters into the database.
    </para>

    <para>
      Once the domain configuration is fetched, however, the delivery itself is
      started by calling each of the specified modules in turn.  The order in
      which the modules are run, at time of writing, is determined by the
      Installator or System Administrator, who decides which modules are allowed
      and how they are to be called.
    </para>

    <para>
      The first module that is usually called, if it is enabled in the domain configuration,
      is called ``mailUsers''.
    </para>

    <para>
      The mailUsers module contains a list of user specific configurations and takes care
      to fetch those configurations from the <ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> database.
    </para>

    <para>
      Once user configurations are fetched, they are then merged with domain configurations
      by using a mailUsers specific scheme that will be documented later on in this document,
      and the delivery continues by calling the remaining <ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> Modules.
    </para>

    <para>
      The remaining <ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> Modules are thus run using the mailUsers merged configurations
      as fetched from the database.
    </para>

  </sect1>

  <sect1>
    <title>Configuration structure</title>

    <para>
      Before talking about how configurations are merged by the mailUsers module, 
      it is necessary to briefly talk about how configurations are stored and
      how they are structured.
    </para>

    <para>
      It is however necessary to make it clear from the beginning that the <ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink>
      system is not bound to any particular database or database engine: the terms
      used below are those known by LDAP administrators since LDAP was the first
      database to be supported by <ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink>, but datatree handlers can be used to make
      <ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> work with other kinds of databases as well without any problem.
    </para>

    <para>
      The database is considered by <ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> as a ``tree'' of structured data, or 
      objects. Each object contains a list of properties. 
    </para>

    <para>
      Properties look like ``variable=value'' and can be multivalued, which means
      a variable may have multiple values. Properties are always string based,
      which means they will be converted to the proper type by the <ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> System.
    </para>

    <para>
      Objects are hierarchically organized, much like a directory on the file system,
      where each object contains a list of properties and can have any number of 
      children objects under it.
    </para>
  </sect1>

  <sect1>
    <title>mailUsers Configuration merging</title>

    <para>
      The mailUsers module expects at least two properties to be 
      made available with each and every object in the <ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> tree:
      <itemizedlist>
        <listitem><para>
	  the ``enable'' property, which can be ``TRUE'' or ``FALSE''
	  valued
	</para></listitem>
        <listitem><para>
	  the ``force'' property, which can be ``TRUE'' or ``FALSE''
	  valued
	</para></listitem>
      </itemizedlist>
    </para>

    <para>
      When merging user configurations with domain configurations,
      each module is considered in turn.
    </para>

    <para>
      For each module, the user configurations take precedence,
      unless the ``force'' flag has value ``TRUE'' into the domain 
      configuration.
    </para>

    <para>
      In this case, the domain configuration is used unless the ``force'' flag
      into the user configuration is also set to ``TRUE'', leading to four combinations
      (considering the force flag):
      <variablelist>
        <varlistentry>
	  <term>user FALSE, domain FALSE</term>
	  <listitem><para>
	    user configuration is used
	  </para></listitem>
	</varlistentry>

        <varlistentry>
	  <term>user TRUE, domain FALSE</term>
	  <listitem><para>
	    user configuration is used - this combination
	    is often used by web interfaces to forbid
	    access to simple users (meaningless to the
	    server).
	  </para></listitem>
	</varlistentry>

        <varlistentry>
	  <term>user TRUE, domain TRUE</term>
	  <listitem><para>
	    user configuration is used
	  </para></listitem>
	</varlistentry>

        <varlistentry>
	  <term>user FALSE, domain TRUE</term>
	  <listitem><para>
	    domain configuration is used
	  </para></listitem>
	</varlistentry>
      </variablelist>
    </para>

    <para>
      The above considerations were made upon the assumption
      that a single module is available both in the domain
      configuration and the user configuration. If this assumption
      is not true, the only available module is used.
    </para>

    <para>
      Note, however, that the absence of a module implies that
      nothing is said about the module, while its availability
      either implies that the module is enabled or disabled,
      depending on the enable flags and depending on how the
      force flags interacts with user/domain modules.
    </para>
  </sect1>

  <sect1>
    <title>Datatree Structure</title>

    <para>
      The whole <ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> system abstract databases (also known 
      as Backend Databases) as systems storing objects, 
      or group of options, in a hierarchically organized manner, 
      where we have a root with children and where children
      may have their own children but just one parent as in any
      tree.
    </para>

    <para>
      Each object has been given a name and is known to contain
      a given list of attributes, some of which are mandatory while
      others may be omitted, and where some may have a single value
      while others may be multiple valued.
    </para>

    <para>
      This structure fills well with LDAP Databases (LDAP as
      a <ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> Backend Database), but may be realized by using
      any kind of database (backends will be discussed later
      on in this document). 
    </para>

    <para>
      The <ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> system thus expects a so called ``datatree'' module
      to provide a layer of abstraction over the database, that
      makes it look like a tree made of:
      <itemizedlist>
        <listitem><para>
      	  a root, which contains the whole <ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> tree and the
	  list of domains.
	</para></listitem>
	<listitem><para>
	  a list of domains, represented by ``mailDomain'' objects.
	  By domain we mean a domain name (as those in the DNS) the
	  system will be handling mail for.
	</para></listitem>
	<listitem><para>
	  for each domain, a list of objects, each one in its own
	  objectclass (depending on the objectclass), representing
	  the list of modules to be called to deliver mails to the
	  users of this domain.</para><para>
	  Each module, however, has at least the attributes
	  defined by the ``mailModuleBase'' object.
	</para></listitem>

	<listitem><para>
	  depending on the kind of object, each object may have
	  its own list of objects below it. At time of writing,
	  the only two modules making use of this feature are
	  the ``mailNewsLetter'' object and the ``mailUsers''
	  object.
	</para></listitem>

	<listitem><para>
	  in particular, the ``mailUsers'' object contains
	  a list of ``mailUser'' (note the ``s'') objects,
	  each one representing a single user.
	</para></listitem>

	<listitem><para>
	  below each user, you may find the list of objects
	  and the corresponding configurations of the single
	  user. Like under the domain object, each object below
	  the user object represents a module to be called
	  to deliver the mail to the user and the configuration
	  to be used.
	</para></listitem>

	<listitem><para>
	  and so on...
	</para></listitem>

      </itemizedlist>
    </para>
    <para>
      You may now wonder which attributes are mandatory
      for each objectclass and which are optional.
    </para>

    <para>
      However, we won't discuss them here. Please refer
      to the documentation specific to the module using
      the indicated objectclass or read the LDAP schema
      (dscm.schema, available in the PigeonDeliver sources) describing 
      all the objects in greater detail and in a formal way.
    </para>

    <para>
      Right now, you just need to know how the tree is
      structured and that each object has at least three
      attributes:
      <itemizedlist>
        <listitem><para>a ``force'' flag, as described previously</para></listitem>
	<listitem><para>an ``enable'' flag, that tells if the object (or module) is 
		enabled or disabled</para></listitem>
	<listitem><para>the ``name'' of the object or of the objectclass</para></listitem>
      </itemizedlist>
      Additionally, each object has its own attributes that are useful for the mail
      server module that uses the given object. For example, the ``mailVacation''
      module, which reads the ``mailVacation'' object, may use the ``message'' attribute,
      containing the whole message to generate.
    </para>
    <para>
      Also note that there is a one-to-one mapping between mail server modules name
      (processes able to add features to the mail server) and the name of the objects
      stored into the database.
    </para>

    <para>
      In short, the <ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> mail delivery system reads (part of) the tree in memory. It
      then runs a module called as each object found in the ``domain directory''. The
      first module is usually the mailUsers module, which takes care of reading the
      user specific ``slice of the tree'' in memory, merging the objects as described
      previously. The delivery is then continued with the remaining objects, which are
      passed to the corresponding modules of the mail server.
    </para>

    <para>
      A new privilege enforcing mechanism is currently being studied. Changing it
      would require us to rewrite just the mailUsers module. No other changes to
      the system will be necessary.
    </para>
  </sect1>

  <sect1>
    <title>Datatree Implementations using various backends</title>

    <sect2>
      <title>LDAP Implementation</title>
      
      <para>
      LDAP is the most straightforward implementation of a datatree module
      for the <ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> mailing system. 
      </para>

      <para>
      The datatree database as described in the previous sections is just
      represented as an LDAP tree, where each object is defined as described
      in the LDAP schema.
      </para>

      <para>
      The main configuration parameter for the LDAP Datatree backend
      is the root of the datatree, or the ``dn'' of the base object
      of the <ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> tree, and the authentication parameters to be 
      used.
      </para>

      <para>
      The current implementation of the LDAP Datatree backend was tested
      with the openldap library, and supports:
      <itemizedlist>
        <listitem><para>referrals, even through different servers</para></listitem>
        <listitem><para>aliases</para></listitem>
        <listitem><para>fallbacks using the LDAP API</para></listitem>
      </itemizedlist>
      </para>
    </sect2>

    <sect2>
      <title>Preliminary SQL Support</title>
      
      <para>
        SQL support can be achieved by either using an LDAP Server
	such as slapd and configuring it to use a SQL backend or
	by using the <ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> SQL Datatree support.
      </para>

      <para>
        In the <ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> SQL Datatree, each objectclass is represented
	by a table, where each attribute is represented by a table
	field. If the field is a string, the attribute is contained
	directly in the table, while if it is an integer, the integer
	is used as a lookup key in a special table used to store
	multi valued elements.
      </para>

      <para>
        If each objectclass is represented by a specific table,
	the tree structure itself is stored in its own table, where
	the key is a sort of cursor (much like the LDAP DN) used
	to lookup all the modules available under a given level.
	This table has mainly three fields: one indicating the
	``cursor'' described previously, the second one indicating
	the objectclass of the contained object, and the third
	one indicating an uniq ``id'' used to identify the attributes
	of the specific module in the object table.
      </para>

      <para>
        Many of what you would think of as strings (as described above)
	are in reality ids used to avoid having to store the whole
	string for each and every object.
      </para>

    </sect2>

  </sect1>

  <sect1>
    <title>Final considerations</title>

    <para>
      The configuration scheme highlighted in the previous
      sections can be used by web interfaces or applications
      accessing the datatree storage (LDAP Directory Tree,
      SQL database, or so...) to enforce simple privilege
      schemes and to allow to organize mailboxes in a simple
      hierarchically organized scheme.
    </para>

    <para>
      The description of how those privileges are used by <ulink url="http://deliver.pigeonair.net/">PigeonDeliver</ulink> 
      Administration interfaces and the administratives schemes 
      they create is left to manual of the specific interfaces
      being used.
    </para>
  </sect1>
  
</article>
