Setting up a exim3 mailserver to windows 2000 domain

Scenario: User accounts and passwords are stored only in Windows 2000 server and mail is received to Linux server. Users can access their mail from webmail and change their password with webmail too.

Linux-server is Debian 3.0.

Required software

Samba3, winbind3, exim3 and some scripts.

Addional software to get spam and virusfiltering

Amavis, spamassassin, vipul's razor, virus-defence.

Adding linux-mailserver to Windows-domain

Add kerberos-libraries first

edumail:/etc# dpkg -l |grep krb
ii  krb5-config    1.4            Configuration files for Kerberos Version 5
ii  libkrb-1-kerbe 1.1-8-2.3      Kerberos Libraries for Kerberos4 From KTH
ii  libkrb5-17-hei 0.4e-7.woody.9 Libraries for Heimdal Kerberos
ii  libkrb53       1.2.4-5woody6  MIT Kerberos runtime libraries  

Set up kerberos according to yours domain:

edumail:/etc# cat krb5.conf
[libdefaults]
        default_realm = EDU.LOCAL

# http://fi.samba.org/samba/docs/man/Samba-HOWTO-Collection/domain-member.html#a
ds-member

        default_etypes     = des-cbc-crc des-cbc-md5
        default_etypes_des = des-cbc-crc des-cbc-md5

# The following krb5.conf variables are only for MIT Kerberos.
        default_tgs_enctypes = des3-hmac-sha1 des-cbc-crc des-cbc-md5
        default_tkt_enctypes = des3-hmac-sha1 des-cbc-crc des-cbc-md5
permitted_enctypes = des3-hmac-sha1 des-cbc-crc des-cbc-md5
        krb4_config = /etc/krb.conf
        krb4_realms = /etc/krb.realms
        kdc_timesync = 1
        ccache_type = 4
        forwardable = true
        proxiable = true
# The following libdefaults parameters are only for Heimdal Kerberos.
        v4_instance_resolve = false
        v4_name_convert = {
                host = {
                        rcmd = host
                        ftp = ftp
                }
                plain = {
                        something = something-else
                }
        }

[realms]
EDU.LOCAL = {
         kdc = edusrv1.edu.local
        admin_server = edusrv1.edu.local
}

[domain_realm]
        .kerberos.server = EDU.LOCAL

[login]
        krb4_convert = true
        krb4_get_tickets = true 

Set up winbind, note security, realm and winbind use default domain-settings:

edumail:/etc/samba# cat smb.conf
[global]
   workgroup = EDU
   security = ADS
   realm = EDU.LOCAL
   password server = edusrv1.edu.local
   server string = %h server (Samba %v)
   include = /etc/samba/dhcp.conf
   log file = /var/log/samba/log.%m
   max log size = 1000
   syslog = 0
   panic action = /usr/share/samba/panic-action %d
   encrypt passwords = true
   passdb backend = tdbsam guest
   invalid users = root
   passwd program = /usr/bin/passwd %u
   passwd chat = *Enter\snew\sUNIX\spassword:* %n\n *Retype\snew\sUNIX\spassword:* %n\n .

   idmap uid = 10000-20000
   idmap gid = 10000-20000
   template shell = /bin/bash
   winbind separator = +
   winbind enum users = yes
   winbind enum groups = yes
   template homedir = /home/EDU/%u
   winbind use default domain = yes
   template primary group = "Domain Users"
   browseable = yes  

(Re)start samba and winbind.

Join domain with command

net ads join -U administrator

You might need to put to /etc/resolf.conf (test if you can lookup workgroups IP's by hostname, like host edusrv1, if not, then add domain to resolv.conf)

edumail:/etc/samba# cat /etc/resolv.conf

domain edu.local
nameserver 192.168.176.97 

Set up /etc/nsswitch.conf to use winbind:

edumail:/etc# cat nsswitch.conf
# /etc/nsswitch.conf
#
# Example configuration of GNU Name Service Switch functionality.
# If you have the `glibc-doc' and `info' packages installed, try:
# `info libc "Name Service Switch"' for information about this file.

passwd:         files winbind db
group:          files winbind db
shadow:         files winbind db 

Time to test, wbinfo -u should give userlist from domain, wbinfo -g should give groups from Windows 2000 server. If not, then restart samba (/etc/init.d/samba restart) and winbind (/etc/init.d/winbind restart).

Test also that getent passwd gives useraccounts and homedirs from Windows 2000 server.

Winbind caches passwords and userlist in memory, that will couse troubles, change /etc/init.d/winbind script so, that it starts with -n option!

In debian I have this script:

#!/bin/sh
#
# Start/stops the winbindd daemon.
#
#

PATH=/sbin:/bin:/usr/sbin:/usr/bin

DAEMON=/usr/sbin/winbindd 

# clear conflicting settings from the environment
unset TMPDIR

# See if the daemon is there
test -x $DAEMON || exit 0

case "$1" in
        start)
                echo -n "Starting the Winbind daemon: winbindd"

                start-stop-daemon --start --quiet --exec  $DAEMON -- -n

                echo "."
                ;;
        stop)
                echo -n "Stopping the Winbind daemon: winbindd"

                start-stop-daemon --stop --quiet --oknodo --exec $DAEMON

                echo "."
                ;;
        restart|force-reload)
                echo -n "Restarting the Winbind daemon: winbindd"

                start-stop-daemon --stop --quiet --oknodo --exec $DAEMON
                sleep 2
                start-stop-daemon --start --quiet --exec $DAEMON -- -n 

                echo "."
                ;;
        *)
                echo "Usage: /etc/init.d/winbind {start|stop|restart|force-reload}"
                exit 1
                ;;
esac

Creating homedirs to Linux-server

Exim requires actual homedirs in Linux-server. Them must be created. I did this script (place that in /root/bin/homedirs.pl):

#!/usr/bin/perl

open(PASSWD, "/root/bin/passwd");

while(<PASSWD>)
{
    ($uname, $passwd, $uid, $gid, $realname, $home, $shell)=
        split(/:/);

    $mode =  (stat($home))[2];
if (-d $home or $gid < 10000 or $uid < 10000)
{
#    print "$home is already ready! \n";
# # if you use this with cron, you don't want have that message every 5 mins or so
# # remove box, if you want to test with first time
} else {
    print "$home $mode is not ready, creating!\n";
    mkdir ($home, 0700);
    chown ($uid, $gid, $home);
}

}

close PASSWD; 

It uses passwd-style file for getting user accounts and homedirs. Change directory to /root/bin and do

chmod u+x homedirs.pl
getent passwd > passwd
./homedirs.pl rm passwd

Check, that homedirectories are really made.

Set up to cron to do script every 5 minutes:

edumail:/etc/pam.d# crontab -l
*/5 * * * * cd /root/bin/; getent passwd > passwd; ./homedirs.pl ; rm passwd

Removing homedirectories from deleted users

To delete user's homedirectory, I use this bash-script in cron.weekly (it is a bad idea have this script in cron, because if windows server is down, it will delete all homedirectories and mail from folders and spool, this script tries to verify, that PDC is answering to ping and there is reasonable amount of accounts!!!):

#/bin/bash
accounts=1000
server=192.168.176.97
domain=EDU
getent passwd | grep $domain > tiedosto

if [[ ! `ping -q -c 1 -i 30 $server | grep " 0%"` ]]
then
  echo "PDC won't answer to ping."
  exit
fi

if [[ `wc -l < tiedosto` -lt "$accounts" ]] 
then
    echo "getent passwd is way too short."
    exit 
fi

for i in $( ls /home/EDU ); 
do      
   /bin/grep /home/EDU/$i tiedosto > /dev/null
   if [ "$?" != "0" ]; then
      echo "Account $i is removed from PDC."
      echo "  Removing homedirectory and subdirectories from mailserver:"      
        rm -rf /home/EDU/$i
        if [ "$?" = "0" ]; then
          echo "  ok"
        else
          echo "  NOT ok"
        fi 
      echo "  Removing messages from spool:"
        rm /var/spool/mail/$i
      echo "  Checking alias:"
      /bin/grep $i /etc/aliases > /dev/null
      if [ "$?" != "0" ]; then
        echo "  There is no alias"
      else
        /bin/grep $i /etc/aliases
        echo "  Removing alias"
        /bin/grep -v $i /etc/aliases > /etc/aliases2
        mv /etc/aliases2 /etc/aliases
        /bin/grep -v $i /etc/email-addresses > /etc/email-addresses2
        mv /etc/email-addresses2 /etc/email-addresses
      fi
   fi
done
rm tiedosto

Setting up exim3

Exim should be correctry set up out of the box. Test sending mail to some user.

If you want to set

# This setting allows anyone who has authenticated to use your host as a
# mail relay. To use this you will need to set up some authenticators at
# the end of the file host_auth_accept_relay = *

then correct authentication to the end of the file is

plain:
driver = plaintext
public_name = PLAIN
server_condition = "${if pam{$2:$3}{1}{0}}"
server_set_id = $2

login:
driver = plaintext
public_name = LOGIN
server_prompts = "Username:: : Password::"
server_condition = "${if pam{$1:$2}{1}{0}}"
server_set_id = $1  

and /etc/pam.d/exim

edumail:/etc/exim# cat /etc/pam.d/exim
#%PAM-1.0
auth       requisite  pam_nologin.so
auth       required     /lib/security/pam_winbind.so
account    required     /lib/security/pam_winbind.so  

This causes exim to authenticate users against winbind.

Spooling messages when windows server is down

Tricky part was getting exim3 to spool messages, when windows server was down. Exim won't see accounts and bounces messages:"unknown user". Exim3 does not has server down defer, but it has queue_only_file-option. Messages is queued when file exists. Existance is checked every time when message arrives. So I have in cron script, which checks windows server status and when it is down, it creates queue only file and exim queues all incoming messages. When windows server is again up (and winbind is restarted) queue only file is removed and exim starts delivering messages again.

I have cron to run script every minute, so in worst case I lose all messages which comes during first minute of server down problem. But it is much less than every message during windows server down problem...

In /etc/exim/exim.conf:

queue_only_file = /etc/exim/queue

And script for cron:

#/bin/bash
accounts=1000
server=192.168.176.97
domain=EDU
getent passwd | grep $domain > temppi

if [[ ! `ping -q -c 1 -i 30 $server | grep " 0%"` ]]; then
   echo "true: ping" > /etc/exim/queue
   #sends mail to admin, which is silly, because he/she cannot read mail...
   #echo "windows-server does not answer to ping"
   exit
 else
 if [[ `wc -l < temppi` -lt "$accounts" ]]; then
     echo "true: getent" > /etc/exim/queue
     #echo "getent is too short"
     /etc/init.d/winbind restart > /dev/null
     exit
 else
   if [[ -e /etc/exim/queue ]]; then
     echo "Return to immediade delivery."
     rm /etc/exim/queue
   fi
 fi
fi

rm temppi

Reading mail thru imap and pop

I used uw-imap and ipopd programs from University of Washington. (I also added uw-ftpd so users can access their .forward thru webmail) I used them, because them are pammable out of the box. Settings are:

edumail:/etc/pam.d# cat imap
#%PAM-1.0
auth       requisite  pam_nologin.so
auth       required     /lib/security/pam_winbind.so
account    required     /lib/security/pam_winbind.so
edumail:/etc/pam.d# cat pop
#%PAM-1.0
auth       requisite  pam_nologin.so
auth       required     /lib/security/pam_winbind.so
account    required     /lib/security/pam_winbind.so
edumail:/etc/pam.d# cat wu-ftpd
#%PAM-1.0
auth       requisite    pam_nologin.so
auth       required     /lib/security/pam_winbind.so
account    required     /lib/security/pam_winbind.so
session    required     /lib/security/pam_mkhomedir.so skel=/etc/skel umask=0022

It would be nice to use pam_mkhomedir.so with /etc/pam.d/exim or imap, BUT THEM DOESN'T USE SESSION from pam-file.

Test your server. It should be able to send and receive mail to Windows accounts and mail can be read with Imap and Pop protocols.

Webaccess to mail

I used Horde with Imp to read mail. I also installed password-module, so users can change their password with webmail to windows-domain. I also added vacation and forward-modules.

password-modules conf.php:

$backends['smbpasswd'] = array(
    'name' => 'email',
    'preferred' => '',
    'password policy' => array(),
    'driver' => 'smbpasswd',
    'params' => array(
        'program' => '/usr/bin/smbpasswd',
        'host' => 'edusrv1'
    )
); 

vacation-modules conf.php:

$conf['server']['params']['default'] = array(
    'host' => '192.168.176.100',
    'port' => 21,
    'hordeauth' => true
);

$conf['server']['params']['dbtype'] = 'hash3';

Spam and virusfiltering

To install them, I used Debian Stable + Exim3 + Amavisd-new with Spamassassin, Razor, F-Prot filtering for Exchange from raygibson.net.


Warning: include(/home/opettaja/moversti/public_html/palaute.php) [function.include]: failed to open stream: No such file or directory in /home/moversti/public_html/exim3_winbind_howto.php on line 392

Warning: include() [function.include]: Failed opening '/home/opettaja/moversti/public_html/palaute.php' for inclusion (include_path='.:/usr/share/php:/usr/share/pear') in /home/moversti/public_html/exim3_winbind_howto.php on line 392