Paul Khavkine Tue-Jul-27-1999 I have finally finished incorporating all the features i wanted till now and my code is now usable. Here's a explaination on how to install and use it. Install: Grab the sendmail-8.9.3 source from ftp://ftp.sendmail.org untar the tree. Get the sendmail+mysql-0.2.2b.patch, copy it into sendmail-8.9.3. Do "patch -p1 < sendmail+mysql-0.2.2b.patch". Then do cd src, and edit mysql_sendmail.h you have to definr the following: #define ALIAS_LHS "address" #define ALIAS_RHS "alias" That's for the alias lookups in MySQL. Once done that do "cd .." then "make". When the build is finished do either "make install" or cp src/obj. /path/to/sendmail Now it's time to make your database(s): 1) Users table: It has to be like that mysql> desc users; +----------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+----------------+ | username | char(32) | YES | | NULL | | | passwd | char(32) | YES | | NULL | | | uid | mediumint(9) | | PRI | 0 | auto_increment | | gid | mediumint(9) | YES | | NULL | | | gecos | char(32) | YES | | NULL | | | home_dir | char(32) | YES | | NULL | | | shell | char(32) | YES | | NULL | | | maildrop | char(128) | YES | | NULL | | +----------+--------------+------+-----+---------+----------------+ 8 rows in set (0.00 sec) 2) Alias: mysql> desc alias; +---------+-----------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+-----------+------+-----+---------+-------+ ALIAS_LHS -> | address | char(128) | YES | | NULL | | ALIAS_LHS -> | alias | char(128) | YES | | NULL | | +---------+-----------+------+-----+---------+-------+ 2 rows in set (0.00 sec) 3) the Map table can be anything you want. you can define the columns to use either in sendmauil_mysql.conf (if you only use one MySQL map) or in /etc/sendmail.cf in per-map basis In my case i have 2: mysql> desc relay_users; +--------------+---------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------------+---------------+------+-----+---------+-------+ | username | char(255) | YES | | NULL | | | IP | char(18) | YES | | NULL | | | permit_relay | enum('N','Y') | YES | | NULL | | +--------------+---------------+------+-----+---------+-------+ 3 rows in set (0.00 sec) and mysql> desc domainalias; +-------------+-----------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------------+-----------+------+-----+---------+-------+ | address | char(128) | YES | | NULL | | | domainalias | char(128) | YES | | NULL | | +-------------+-----------+------+-----+---------+-------+ 2 rows in set (0.00 sec) The first i use for controlling relay through my server and the second i use to rewrite virtual domain adresses to local users. (more detail later) Then in sendmail-8.9.3 edit sendmail_mysql.conf. This file contains the default values used for user and alias lookup. If you only use one server you only have to put username and passwd in that file. Or if you only ose one map you can keep everything in here too. (Only put K mysql in /etc/sendmail.cf) Copy the file to /etc Then it's time to edit /etc/sendmail.cf: What you put is: K mysql options are: generic: -N -O -o -f -m -A -q -t -a and -T mysql specific: -H hostname of mysql server (if different from default) -U username for mysql server (if different from default) -P passwd for mysql server (if different from default) -D database name (if different from default) -M map table name (if different from default) -L key column name (if different from default) -R value column name (if different from default) The you can make any rule using the map in /etc/sendmail.cf. Here's a couple things I use it for, and some examples: 1) for controlling the relay through my sendmail: You can use POP before SMTP method to give a limited opportunity for the clients that are not connecting from local network(s) to relay through your SMTP. First the client connects to check his mailbox through POP. The POP server after making the authentication updates an entry for his IP address in the database and sets the "permit_relay" flag to "Y". Here's an example of Qualcomm Qpopper that you can modify: ------------ cut here -------------------------------------------------- mysql_init(&mysql); snprintf(queryBuf,sizeof(queryBuf),"update %s set IP = '%s', permit_relay = 'Y' where username = '%s'",RELAY_TABLE,p->ipaddr,p->user); if(!mysql_real_connect(&mysql,HOST,USER,PASS,DB,0,NULL,0)) { return(pop_msg(p,POP_FAILURE,"Error connecting to database server(%s)",mysql_error(&mysql),HOST)); } mysql_query(&mysql,queryBuf); mysql_close(&mysql); return(pop_msg(p,POP_SUCCESS,"Relay Database updated")); ------------ cut here -------------------------------------------------- Here's an example of the table you can have for all the users (or only the ones using the service ex: iPass): mysql> select * from relay_users; +----------+----------+--------------+ | username | IP | permit_relay | +----------+----------+--------------+ | user1 | 10.0.0.1 | Y | | user2 | 10.0.0.2 | N | +----------+----------+--------------+ 2 rows in set (0.00 sec) Then in your sendmail.cf you can have the following map: Krelay mysql -D"relay" -M"relay_users" -L"IP" -R"permit_relay" (keep your username and passwd in sendmail_mysql.conf if you use the same server, no need to specify it here) Then I made a modification to check_rcpt rule to make a lookup for the IP and check the "permit_relay" flag for "Y". ###################################################################### ### check_rcpt -- check SMTP `RCPT TO:' command argument ###################################################################### SLocal_check_rcpt Scheck_rcpt R$* $: $1 $| $>"Local_check_rcpt" $1 R$* $| $#$* $#$2 R$* $| $* $@ $>"Basic_check_rcpt" $1 SBasic_check_rcpt # check for deferred delivery mode R$* $: < ${deliveryMode} > $1 R< d > $* $@ deferred R< $* > $* $: $2 R$* $: $>ParseRecipient $1 strip relayable hosts # anything terminating locally is ok R$+ < @ $=w > $@ OK R$+ < @ $* $=R > $@ OK # check for local user (i.e. unqualified address) R$* $: $1 R $* < @ $+ > $: $1 < @ $2 > # local user is ok R $+ $@ OK R<$+> $* $: $2 # anything originating locally is ok R$* $: $&{client_name} # check if bracketed IP address (forward lookup != reverse lookup) R [$+] $: [$1] # pass to name server to make hostname canonical R $* $~P $: $[ $1 $2 $] R<$-> $* $: $2 R$* . $1 strip trailing dots R$@ $@ OK R$=w $@ OK R$* $=R $@ OK # check IP address R$* $: $&{client_addr} R$@ $@ OK originated locally R0 $@ OK originated locally R$=R $* $@ OK relayable IP address R$* $: [ $1 ] put brackets around it... R$=w $@ OK ... and see if it is local R$ [ $* ] $: $1 strip the [ ] R$* $: $( relay $1 $) check the IP in the map RY $@ OK if it returnes Y accept # anything else is bogus R$* $#error $@ 5.7.1 $: "550 Relaying denied" ---------------------------------------------------------------------------- Basically it the same except i added 3 more lines: R$ [ $* ] $: $1 strip the [ ] R$* $: $( relay $1 $) check the IP in the map RY $@ OK if it returnes Y accept they strip the brackets from the IP, make a lookup in the map "relay" and if the return if "Y", accept relay, else deny. Check relay.readme for more info. 2) Mapping virtual e-mail adresses for local virtual domains to local users. In your sendmail.cf you can have the following map: Kdomainalias mysql -Dmail -Mdomainalias -Lvirtual_user -Rlocal_user (works with or without quotes) and the following table MySQL table: mysql> select * from domainalias; +------------------------+-------------+ | virtual_user | local_user | +------------------------+-------------+ | user@virtualdomain.com | local_user | +------------------------+-------------+ 1 row in set (0.00 sec) In sendmail.cf i have the rule to map virtual adresses to local users: ################################################################### ### Ruleset 98 -- local part of ruleset zero (can be null) ### ################################################################### S98 S98 R$+ < $+ . > $1 < $2 > remove trailing dots R$+ < $+ > $: < > $(domainalias $1$2 $) match user@address R< > $+ @ $* $: < $1 > $(domainalias * @ $2 $) match*@address R< $+ > * $* $: < > $1 $2 replace * with userid R < $+ > $+ $: < > $2 bugfix R< > $* $: $>3 $1 and rewrite using S3 --------------------------------------------------------------------- Make sure you have tabs separating things, not spaces or sendmail will go nuts. You can also use the map fro any other key/value operations like any other maps. Well that's it for now. Let me know what you think Paul Khavkine mailto://paul@colba.net mailto://paul@spacenet.qc.ca