Getting reject_sender_login_mismatch/smtpd_sender_login_maps and mysql to work together

2009-01-06 Thread Jeff Weinberger

Hi:

I would very much appreciate any help, advice, pointers, etc. to  
resolve an issue I am encountering.


I am having a challenge trying to use a mysql table for  
smtpd_sender_login_maps. Right now I have:


In main.cf:
   smtpd_sender_login_maps=mysql:/path/to/map.cf
   smtpd_sender_restrictions=reject_sender_login_mismatch, 

My virtual mailbox table contains the username for authentication  
(which is also the e-mail address), the password and I am using a text  
(VARCHAR) field to hold the list of e-mail addresses that each user is  
allowed to send from.


For example, my e-mail is jeff (at) jweinberger.homeip.net. I can send  
as that e-mail, but I also want to allow sending from someothername  
(at) jweinberger.homeip.net and from jeff (at) some-other-domain-I- 
own.tld. so the table row looks like:


field username: jeff (at) jweinberger.homeip.net
field password: (password)
field valid_from: jeff (at) jweinberger.homeip.net,  someothername  
(at) jweinberger.homeip.net, jeff (at) some-other-domain-I-own.tld


The select statement in the maps.cf file is select username from  
virtual_mailbox_table where (INSTR(valid_from, %s)  0) which  
successfully (tested outside postfix) looks up the sender address and  
returns the login name (field: username).


I run into problems when more than one login name is permitted to send  
from a given address. For example, say i include one of my valid  
addresses as postmaster (at) jweinberger.homeip.net (so I can send  
from it - mail to it goes into a postmaster mailbox as required). I  
also want someone else to be able to send from postmaster (at)  
jweinberger.homeip.net. So the virtual mailbox table would contain:


Row 1:

field username: jeff (at) jweinberger.homeip.net
field password: (password)
field valid_from: jeff (at) jweinberger.homeip.net,  someothername  
(at) jweinberger.homeip.net, jeff (at) some-other-domain-I-own.tld,  
postmaster (at) jweinberger.homeip.net


Row 2:

field username: someoneelse (at) jweinberger.homeip.net
field password: (password)
field valid_from: someoneelse (at) jweinberger.homeip.net,   
yetanothername (at) jweinberger.homeip.net, postmaster (at)  
jweinberger.homeip.net


And when I try to send mail authenticated at jeff (at)  
jweinberger.homeip.net from postmaster (at) jweinberger.homeip.net it  
fails with this log entry:


postfix/smtpd[83245]: NOQUEUE: reject: RCPT from unknown[10.0.1.1]:  
553 5.7.1 postmaster (at) jweinberger.homeip.net : Sender address  
rejected: not owned by user jeff (at) jweinberger.homeip.net  
from=postmaster (at) jweinberger.homeip.net to=--edited--  
proto=ESMTP helo=[10.0.1.7]


The query in this case would return two rows, as both users are  
allowed to send from that address.


According to the description of smtpd_sender_login_maps in http://www.postfix.com/postconf.5.html 
:


In all cases the result of table lookup must be either not found or  
a list of SASL login names separated by comma and/or whitespace


I conclude that the mysql query is not returning the list in the right  
form. Since I don't know how mysql calls are implemented in postfix, I  
don't know what to do to correct this, if it's possible.


So my questions:

1) Is my analysis and conclusion (that mysql is not returning the  
result in the required form) correct?


2) Is there anything I can do to make the result come back in the form  
postfix needs it?


I would like to be able to do this in this way, as I think it makes  
sense to track which addresses are authorized for each user, rather  
than the other way around. If there is no direct way to do this, I can  
build a reverse lookup table that will return the list postfix expects.


And of course, if there is any additional information that would help  
in diagnosing or resolving this, I'd be happy to provide it.


Any help, direction, pointers, etc. are much appreciated!

Thanks,

--Jeff




Re: Getting reject_sender_login_mismatch/smtpd_sender_login_maps and mysql to work together

2009-01-06 Thread Victor Duchovni
On Tue, Jan 06, 2009 at 12:16:00PM -0800, Jeff Weinberger wrote:

 Hi:
 
 I would very much appreciate any help, advice, pointers, etc. to  
 resolve an issue I am encountering.
 
 I am having a challenge trying to use a mysql table for  
 smtpd_sender_login_maps. Right now I have:
 
 In main.cf:
smtpd_sender_login_maps=mysql:/path/to/map.cf
smtpd_sender_restrictions=reject_sender_login_mismatch, 
 
 My virtual mailbox table contains the username for authentication  
 (which is also the e-mail address), the password and I am using a text  
 (VARCHAR) field to hold the list of e-mail addresses that each user is  
 allowed to send from.
 
 For example, my e-mail is jeff (at) jweinberger.homeip.net. I can send  
 as that e-mail, but I also want to allow sending from someothername  
 (at) jweinberger.homeip.net and from jeff (at) some-other-domain-I- 
 own.tld. so the table row looks like:
 
 field username: jeff (at) jweinberger.homeip.net
 field password: (password)
 field valid_from: jeff (at) jweinberger.homeip.net,  someothername  
 (at) jweinberger.homeip.net, jeff (at) some-other-domain-I-own.tld

This violates 1st normal form. Avoid multi-value fields stored as
a concatenation. The correct schema for this uses an additional
table to correlate addresses to users:

 The select statement in the maps.cf file is select username from  
 virtual_mailbox_table where (INSTR(valid_from, %s)  0) which  
 successfully (tested outside postfix) looks up the sender address and  
 returns the login name (field: username).

This is an inefficient table scan. You need a better schema to model this.

-- 
Viktor.

Disclaimer: off-list followups get on-list replies or get ignored.
Please do not ignore the Reply-To header.

To unsubscribe from the postfix-users list, visit
http://www.postfix.org/lists.html or click the link below:
mailto:majord...@postfix.org?body=unsubscribe%20postfix-users

If my response solves your problem, the best way to thank me is to not
send an it worked, thanks follow-up. If you must respond, please put
It worked, thanks in the Subject so I can delete these quickly.


Re: Getting reject_sender_login_mismatch/smtpd_sender_login_maps and mysql to work together

2009-01-06 Thread Jeff Weinberger

On Tue Jan 6, 2009 2:42 pm Victor Duchovni wrote:


 I know that it is not a good model for the way postfix requires the
 query,

More stronly, an SQL schema in which multiple data items are stored
concatenated in a single table element is a poor schema regardless
of the application. This violates fundamental principles of database
schema design. Multi-valued elements are stored in separate tables  
that

are joined to the main table. This is not a Postfix requirement, it is
basic database design.

 but from a logical standpoint, I am trying to this about it
 as which addresses is a user allowed to send from.

The correct design has a address table which links address objects  
to user

objects, and a user table which holds attribtues of users. To discover
the addresses of a user, join the two tables. Implement appropriate
indices and forein keys to make the expected queries efficient.

 This makes sense
 when you think about a user having e-mail service through my server,
 and using that to send e-mail from another unrelated valid address  
then
 he/she owns. (validating that is also important, but not in the  
scope

 of this issue).

 So I want to associate valid from addresses with the user, not the  
other

 way around.

In a correct SQL schema the question is moot, SQL stores relation  
tuples,

there is no notion of which is the primary element in a relation.

x R y = row (x,y) is present in table R

 I understand fully the point of view that postfix takes, asking  
who is

 allowed to send from this e-mail address (more or less masquerade as
 this e-mail identity), which makes sense also.

Yes, but your schema is poorly designed. A good schema will naturally
support a variety of queries that select ether the x values for
which x R y is true for a given y or just as easily the converse.

 There may be better schema for answering the question I am asking,
 but it sounds from your response (I am assuming, possibly  
dangerously)
 That there is no way to do what I want to do without creating  
another
 table in the database, indexed by from address with resuting lists  
of

 users. Is that correct?

I am claiming that what you can't be done with your existing schema,
perhaps it can. I am claiming that you should change your schema
as soon as you can.

 Why does postfix reject the mail when the mysql query return one or
 several valid SASL users?

To solve such questions, divide and conquer:

- Use a simple indexed file to store the sasl_sender_login table.
Make this work, resolving any issues that you find.

- Once SASL sender validation is working without SQL, create
an SQL query that given verbatim keys from the indexed file,
returns the identical RHS values. Verify with multiple postmap -q
tests. Once this works, use SQL in the Postfix configuration.

The above approach allows you to identify and solve the right problem.

--
Viktor.



Viktor:

Thank you. I agree with all your comments about the database schema,  
which I have not yet built. I am in testing mode and want to make sure  
this kind of validation will work as expected and give me the desired  
results. So if I may, I'd like to focus on getting this to work.


I did the testing you suggested before I posted. Here are the tests:

I created a hash table (text file then used postmap hash:).  The text  
file had lines like this:


sender_address1  sasl_owner
sender_address2  sasl_owner2, sasl_owner3, sasl_owner4

and so on, for the several addresses I tested.


I then used postmap -q to verify that the lookup returned the correct  
values. As speficied in the documentation for smtpd_sender_login_maps,  
it returned one single SASL user name when only one user is authorized  
to send from that from address and a string of comma-separated names  
when multiple users are authorized to send from that from address.


I then added the line:

smtpd_sender_login_maps=hash:/path/to/map

to my main.cf and send a few messages. Postfix correctly allowed and  
rejected all of the test messaages, and the logs showed the correct  
reason for the rejection, and no log entries showing a successful match.


I then, again just to test, added a field to my virtual users table to  
hold authorized addresses, and wrote the query noted above into a  
mysql_sender_login_maps.cf file.


I used postmap -q to verify that the results of the query were correct  
and were exactly the same as the results received when I used postmap - 
q on the hash: file. They all were identical for the same lookup keys.


I then changed the main.cf line to:

smtpd_sender_login_maps=hash:/path/to/mysql_sender_login_maps.cf

and tried the same series of test messages.

All of the test messages failed. The ones where the lookup produced  
the same comma-separated line as with the hash: file, and the ones  
where the lookup produced a single result. All were rejected (as noted  
in the log entry I posted previously) with the reason that the from  
address was not authorized for that sasl 

Re: Getting reject_sender_login_mismatch/smtpd_sender_login_maps and mysql to work together

2009-01-06 Thread Jeff Weinberger

On Jan 6, 2009, at 5:59 PM, Wietse Venema wrote:


Jeff Weinberger:

I then added the line:

smtpd_sender_login_maps=hash:/path/to/map

to my main.cf and send a few messages. Postfix correctly allowed and
rejected all of the test messaages, and the logs showed the correct
reason for the rejection, and no log entries showing a successful  
match.


I then, again just to test, added a field to my virtual users table  
to

hold authorized addresses, and wrote the query noted above into a
mysql_sender_login_maps.cf file.

I used postmap -q to verify that the results of the query were  
correct
and were exactly the same as the results received when I used  
postmap -
q on the hash: file. They all were identical for the same lookup  
keys.


smtpd does the same lookups as postmap -q.

If the result is different than when you run postmap -q by hand,
then it is almost certain that you are using a different search
key than Postfix uses.  Postfix does the lookups as documented in
the postconf(5) manual page:

smtpd_sender_login_maps (default: empty)
  Optional  lookup  table with the SASL login names that own  
sender (MAIL

  FROM) addresses.

  Specify zero or more type:table  lookup  tables.  With   
lookups  from
  indexed  files such as DB or DBM, or from networked tables  
such as NIS,
  LDAP or SQL, the following search operations are  done  with   
a  sender

  address of u...@domain:

  1) u...@domain
 This table lookup is always done and has the highest  
precedence.


  2) user
 This table lookup is done only  when  the  domain   
part  of  the
 sender  address  matches $myorigin, $mydestination,  
$inet_inter-

 faces or $proxy_interfaces.

  3) @domain
 This table lookup is done last and has the lowest  
precedence.


You can see what lookups Postfix does by setting the debug_peer_list
parameter in main.cf. For example:

# postconf -e debug_peer_list=static:all
# postfix reload

Wietse

Wietse


Thank you very much for your help.

I just responded to Viktor as well, and plead stupid.

I just re-ran all the same tests (by hand this time) and everything  
worked. All postmap-q commands gave the correct results, and all  
messages were accepted or rejected as expected. I checked the scripts  
I used earlier for logical errors and typos, but found none. so I have  
no idea why I was  getting odd results.


Never-the-less, all works now. I thank you and Victor for your  
generous help.


--Jeff