At 2005-01-30 04:05 PM, you wrote:
>I have a textfile on my desktop with the same name.  Comments below.
>
>Alexander Zhukov wrote:
>> Hi, James hackers!
>> 
... <snip>
>
>I prefer spring, but whatever.
>
>>     - multiple domains support from the ground up

herewith follows a long post.
Three things:
1) multi domain support *really* needs to be put into James
2) Pop3 user naming schemes are a red herring and are the problem for the
multi domain admin rather than the James developer
3) most of what is discussed below has already been implemented in my own code


MULTI DOMAINS

To enable multiple domain support needs a change in James core, which to
me, is the Mailet API.
There are two different types of  reasons to enable multiple domain support
from the ground up.
1)  ease of use for non-developers/DBAs.  The current way to do multiple
domain support requires the admin to maintain a custom database or XML file
and to add/manage users "by hand".  As well, running multiple domains is a
fairly common thing to do so this is a limiting factor for wider spread
usage.  I suspect that the average admin, by now, expects multiple domain
support in their mail server built-in.

2) in a multiple domain scenario using the currently supported way, any
"upstream" applications such as Fetchmail are unaware of the downstream
processing (via the mailets/matchers) of the mail recipient address.  This
can cause legitimate addresses to be marked as "not found" and illegitimate
address to be okayed.  Currently, this is okay for most James admins  since
most issues are solved via mail forwarding and/or aliasing.  However, if
you are a developer looking to extend, create or enhance any "upstream"
application *and* you are in a multiple domain situation then the lack of
multiple domain support in the James core API (Mailet) is limiting and you
will need to make you own solution (alter the Mailet API).  

I would like to stress that the lack of multiple domain support for
non-DBAs/developers is a limiting factor for non developer admins to adopt
usage of James.  Not a showstopper but a limitation.

In any case, the current methodology is dangerous.  There are numerous
scenarios in Fetchmail whereby Fetchmail will either 1) send mail for one
user incorrectly to another user or 2) it will be marked as valid when it
is invalid or 3) vice-versa.  

Example Start: $$$$$$$$$$$$$$$
A very simple example:  a single domain james server S1 is configured with
users "Sue" and "Bill" who are unrelated.
"Sue" has been configured for a fetchmail account for her domain
(company.com); the fetchmail config for company.com has a default domain
tag because the mail server at her company just uses the first name (just
like James!) for email without any domain parts.  
A completely unrelated third user Rob on S1 wants to send mail to
[EMAIL PROTECTED] who is a close lawyer friend at Sue's company.
[EMAIL PROTECTED] is thus completely and utterly unrelated to Bill the local
S1 James user.

Using the S1 James mail server Rob sends his lawyer ([EMAIL PROTECTED]) an
intensely private note "Dear Bill, about your extra-marital affair...".

If S1 was a multi-domain James server then the mail would get delivered to
Bill the lawyer because [EMAIL PROTECTED] is not a valid user on the server
and it would be delivered remotely to company.com's mail server and this
scenario work and everyone is happy.

Unfortunately for Rob, the mail server S1 being used is James in single
domain mode.

On a single domain James server this will get delivered to the local "Bill"
who is completely unrelated to either Rob, Bill the lawyer @company.com or
Sue.  It will get delivered because the because matcher RecipientIsLocal
will match the first name ("Bill") because user "Bill" does exist on S1 and
it will also match the server name as local because Fetchmail requires the
default domain name to be in the server names config list.
(        return mailetContext.isLocalServer(recipient.getHost())
            && mailetContext.isLocalUser(recipient.getUser());
)

Thus RecipientIsLocal believes "[EMAIL PROTECTED]" is local and is valid and
will deliver it the inbox "Bill" which is a different Bill. While both Bill
and company.com do exist it is plainly evident that the combination
[EMAIL PROTECTED] does not exist on the S1 mail server.

Sooooo, if my ISP or organization happen to be using James and there is a
person with an account on the domain i'm sending to and that person has
Fetchmail configured with a default domain and there exists another user@
who is the same as my user@ then my completely properly addressed mail wilI
go to a completely unknown third party who is unrelated to me, the domain I
was sending to, and the account which was using Fetchmail.  And all parties
concerned with never know about this unless the local accidental recipient
tells the S1 admin.

Since a non-techie James admin isn't going to appreciate the subtlety of
all this (***DON"T USE FETCHMAIL WITH A DEFAULT DOMAIN IN SINGLE DOMAIN
MODE***) there will be lots of problems like this.  Since they will only
happen periodically and the mail can just be sent to a seemingly random
email box (imagine if the Bill the local account was really a mailing list
or an alias for someone else entirely or itself a mailbox being fetched)
these kind of issues will tend to go unnoticed until a really really
important and private email goes to the wrong person....
Example End: $$$$$$$$$$$$$$$$$$

If this example doesn't work for you ("We can change the default domain tag
requirements ...") rest assured that there are a virtual unlimited number
of weirdo scenarios llike this; it just depends on what the upstream app
such as Fetchmail does and they will be very hard to test for.  There are
many subtle issues like this and it is because the upstream apps such as
Fetchmail are unable to do a proper mail address name resolution.
The inherent problem is that the James core lacks multi-domain support and
is unable to resolve "[EMAIL PROTECTED]" integrally.
Conclusion:  single domain James can be dangerous in highly unusual and
unsuspecting ways.

In order to do multi domain support in the core of James, the following
needs to be changed:

MailetContext.java
==============
add two calls that enable inbox-name resolution from a MailAddress.
Currently you can only do this from a String which represents the user@
part of the address.  
    boolean isLocalServer(String serverName);
    boolean isLocalUser(String userAccount);

should be:
    boolean isLocalUser(MailAddress address);
    String  getLocalUser(MailAddress address);

this is the entire problem/issue with multiple domain support.  In the
current model, James maps/assumes just the user@ part is the key for the
inbox name.  For multiple domains this causes major problems.  

James.java
========
fixup calls where just the user@ part is being used.
For example, in v2.2.1 line 801 from StoreMail(...)             String
originalUsername = recipient.getUser();
s/b String username = resolver.getLocalUser(recipient) or some variant

Resolver class
===========
write a class/interface with the above two methods in it.  Enable
James.java to use this class.
An implementation of this class could use a database or XML.  It would be
very similar to the JDBCVirtualUserTable
class except that it is accessible via the MailetContext which means all
applications can get at it to resolve mail names into 
inbox names rather than just the mailets and matchers.

One way to do this is in a database implementation is to use a table with a
column triplet of:
   MailAddressUser, MailAddressDomain, username  with Unique constraint on
combo of the first two columns

***There can be a default implementation that still does things the single
domain way but this is dangerous, as in the example above***.

SMTPServer, Fetchmail etc.
=====================
fixup fetchmail and any other upstream applications to make the
isLocalUser(MailAddress address) call instead of the current
isLocalUser(String) one.

Various Mailets/Matchers
===================
any that uses isLocalUser(String) needs to be changed e.g. RecipientIsLocal


RemoteManager
============
change adduser (and related calls) syntax to:
 adduser inboxname user <domain>  
where "inboxname" is what we currently called the user in James
and "user" is the "user@" part of a mail address
and <domain> is optional and is the "@domain" part of a mail address
and add a new command to name a a default domain (or put it in the config.xml).



POP3

>
>You'd have to explain how this works, since SMTP is no-brainer, and POP3 
>would not support it.  Basically this is largely a function of account 
>name mappers, but would need to be fleshed out.
>

It should be noted that when an admin is running in a multiple domain
scenario he or she has this naming problem to overcome regardless of the
mail server being used (on account of the fact that the admin has to tell
the users what userid to log in with).  

That is, the user authentication issue is decoupled from the inbox
resolution issue.  It's the user's problem to figure out the scheme and its
the mail server's problem to allow the user to express his/her solution
into the server.  
As far as I can tell, this is a point which seems to have been
misunderstood in previous threads on this topic last year and before.

Which leads to the conclusion, that James simply needs to provide the admin
with a facility to do this rather than offering up a specific
username-to-inbox-name scheme.  which one ([EMAIL PROTECTED], user-domain and
other variants) is largely besides the point.  The mail server needs to be
pop3naming-scheme-neutral.

In order to do this the following needs changing:

POP3
====
similar type of solution as the MailetContext changes above.  
The POP3 james code would change to call in to a class/interface such as:
    boolean isPopUser(String pop3Name);
    MailAddress getMailAddress(String pop3name);

Database/XML
===========
A database/XML schema table with a column triplet of: (MailAddressUser,
MailAddressDomain, pop3name).  (Similar, as above).

Remote Manager/Web App
====================
A corresponding RemoteManager command:   addpopuser pop3name user <domain>
(or a WebApp change for those using browser based admin)

This now allows James to decouple the scheme the admin chooses from the
implementation in the code.

Just as obviously, one can wrap all his into one RemoteManager change:
        adduser inboxname user pop3name <domain>

Conclusion
=========
Obviously, in a database implementation of all of this, the user can use
any Web tools/db tools to change the lookup tables directly and/or use a
WebApp that takes the place of the remote manager.

I have already implemented all of this in my own codebase except changes to
SMTPServer, RemoteManager, and Pop3.
I changed James.java, a few mailets/matchers, a few Fetchmail classes,
MailetContext.java as well as implemented a Resolver class that uses a
caching JDBC implementation running on MySQL with the schemas, more or
less, as mentioned above.  An XML version would be, relatively, a
no-brainer for anyone who wrote the XML user virtual stuff.

I didn't need to change the remotemanager stuff as I add/change users via a
webapp.  But these are also no brainers.
The POP3 change is straightforward.

It would be better for everyone concerned if we could just make the changes
in the James core.  There are other solutions.  This is the one I did.


Cheers,


Vh














---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to