How to synchronise Zimbra accounts with a Samba OpenLDAP backend

Justin Freeman's picture

The holy grail of a small business is to have integrated authentication for email, file/print and desktop logins. This is possible with Zimbra and the Samba, OpenLDAP integration. Unfortunately, this is bloody hard to setup and also a real PITA to maintain, since each subsequent Zimbra upgrade requires additional steps to retain the Samba integration. There must be an easier way! Well there is :)

This blog post describes a simple method to:

  1. synchronise user accounts which have been created in Zimbra with a Samba OpenLDAP setup
  2. authenticate those accounts against the Samba OpenLDAP backend as an external authentication source
  3. providing users with the ability to login to both Samba and Zimbra using the same login/password, and
  4. allow users change to their password in a single location (via Windows desktop or other method) affecting Samba and Zimbra instantly

And best of all this does not require any modifications to the Zimbra OpenLDAP or Zimbra at all!

Assumptions

I assume you have the following working systems:
  1. Linux server
  2. Samba server
  3. OpenLDAP server
  4. Samba with OpenLDAP backend, for example see http://www.howtoforge.com/centos-5.x-samba-domain-controller-with-ldap-backend
  5. Zimbra server

I will not cover all the details on installing and configuring the above. If you need that information check out the http://www.howtoforge.com or various Wikis on the Net. So I assume you've done all that, easy huh? :)

Setup

  1. install the smbldap-tools on the Linux server
  2. verify that the Samba and OpenLDAP integration is working correctly by just running this command: smbldap-userlist If you see a list of accounts, then congrats it is working. If not, your Samba and OpenLDAP install is broke, go and fix it before proceeding.
  3. create some new Zimbra accounts using the Zimbra Admin GUI
  4. on your Linux server and as root, run the zimbra2samba.sh script which will populate the OpenLDAP server with the Zimbra accounts. Check the log output for details of the process
  5. login to a Windows desktop using the new account and default password, this confirms that the Zimbra account exists in Samba OpenLDAP
  6. if all is well, then proceed to configure your Zimbra server to authenticate against the Samba OpenLDAP server in the Zimbra Admin GUI
  7. now launch a Web Browser and login to Zimbra web mail using one of the new Zimbra accounts and the default password
  8. change the password within the Windows desktop and then login to the Zimbra web mail again, this time using the new password
  9. if this works then everything is working correctly, well done!
  10. now to prevent the Zimbra and Samba OpenLDAP passwords getting out of sync, use the Zimbra Admin GUI to disable the ability for users to change their Zimbra password in Zimbra webmail.
  11. finally, add a crontab entry to regularly export all new the Zimbra accounts, once a hour should be suffficient: 0 * * * * root /etc/custom-scripts/zimbra2samba.sh > /dev/null 2>&1
  12. You're all done!

Now with this setup you can create users in Zimbra, their accounts will be automatically created in Samba OpenLDAP with a default password, which the user can then change to whatever they want. And users can login to Zimbra, Windows, Samba using the same login credentials.

bash script: zimbra2samba.sh

#!/bin/bash
# Zimbra to Samba/LDAP user replication script
# (c) Copyright Agileware Pty Ltd. All rights reserved. http://agileware.net
# http://www.gnu.org/licenses/gpl-2.0.txt
 
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
#Never create these accounts - security precaution
BLACKLIST_ACCOUNTS="`cat /etc/passwd | awk -F: '{print $1}'`";
 
#Default password for new accounts, change this to suit
DEFAULT_PASSWD='AABBccddee';
 
LOGFILE="/var/log/zimbra-samba-ldap.log";
echo "Starting" >> $LOGFILE;
 
#use zmaccts and extract only the email address from the result
ZIMBRA_ACCOUNTS="`su - zimbra --command=/opt/zimbra/bin/zmaccts | grep '@' | grep 'active' | awk '{print $1}'`";
SAMBA_ACCOUNTS="`smbldap-userlist`";
 
for ZIMBRA_ACCOUNT in $ZIMBRA_ACCOUNTS; do
  echo "$ZIMBRA_ACCOUNT : checking" >> $LOGFILE;
  # Construct account name - remove @. Might be a bit dodgy - but faster than a zmprov call for existing SAMBA accounts
  USER_NAME=${ZIMBRA_ACCOUNT%@*};
  echo "Checking $USER_NAME";
  BLASCKLIST_ACCOUNT_TRUE=`echo "$BLACKLIST_ACCOUNTS" | grep -ic "$USER_NAME"`;
  if [ $BLASCKLIST_ACCOUNT_TRUE -eq 0 ]; then
  SAMBA_ACCOUNT_EXISTS=`echo "$SAMBA_ACCOUNTS" | grep -ic "$USER_NAME"`;
 
  # Remove this line to delete any previously created accounts. Debugging only.
  # smbldap-userdel "$USER_NAME";
 
  # See if the SAMBA account exists, if not then get all attributes and create it
  if [ $SAMBA_ACCOUNT_EXISTS -eq 0 ]; then
    echo "$ZIMBRA_ACCOUNT : No samba account exists" >> $LOGFILE;
 
    # Get all attributes for this account, slow as zmprov has to initiate
    ZIMBRA_ACCOUNT_DETAILS="`su - zimbra --command='/opt/zimbra/bin/zmprov ga '$ZIMBRA_ACCOUNT''`";
    IS_SYSTEM_ACCOUNT=`echo "$ZIMBRA_ACCOUNT_DETAILS" | grep 'zimbraIsSystemResource'`;
 
    # Skip the Wiki, Ham, Spam or other type of system accounts
    if [ -z "$IS_SYSTEM_ACCOUNT" ]; then
      echo "$ZIMBRA_ACCOUNT : Adding samba account" >> $LOGFILE;
      #USER_NAME=`echo "$ZIMBRA_ACCOUNT_DETAILS" | grep 'uid' | awk '{print $2}'`;
      USER_DISPLAYNAME=`echo "$ZIMBRA_ACCOUNT_DETAILS" | grep 'displayName' | awk '{print $2}'`;
      USER_FIRSTNAME=`echo "$ZIMBRA_ACCOUNT_DETAILS" | grep 'givenName' | awk '{print $2}'`;
      USER_SURNAME=`echo "$ZIMBRA_ACCOUNT_DETAILS" | grep 'sn' | awk '{print $2}'`;
      USER_EMAIL=$ZIMBRA_ACCOUNT;
 
      # Set new accounts options so that user can change password (A) and must change password (B)
      smbldap-useradd -m -A 1 -B 1 -a -M "$USER_EMAIL" -N "$USER_FIRSTNAME" -S "$USER_SURNAME" "$USER_NAME";
 
      # -M '$USER_EMAIL' option (email address) will raise this error:
      # failed to add entry: objectClass: value 0 invalid per syntax at /usr/sbin/smbldap-useradd line 516.
      # Solution requires the "misc.schema" to be included for localMailRecipient attribute.
      # See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=505914
 
      echo "$ZIMBRA_ACCOUNT : Set default samba passwd" >> $LOGFILE;
      # Set a default Samba password
      # User forced to change the password on next login
      # Reference: http://www.opensubscriber.com/message/samba@lists.samba.org/1683978.html
 
      echo -n -e "$DEFAULT_PASSWD\n$DEFAULT_PASSWD" | smbldap-passwd "$USER_NAME";
      echo "$ZIMBRA_ACCOUNT : Samba account created" >> $LOGFILE;
    else
      echo "$ZIMBRA_ACCOUNT : Is system account. Skipping." >> $LOGFILE;
    fi
  else
    echo "$ZIMBRA_ACCOUNT : Samba account exists. Skipping." >> $LOGFILE;
  fi
  else
   echo "$ZIMBRA_ACCOUNT : Blacklisted account. Skipping." >> $LOGFILE;
  fi   
done;
 
echo "Completed" >> $LOGFILE;
 
#Check log for errors
if [ -f $LOGFILE ]; then
  ERROR=`grep -ic 'error' $LOGFILE`;
fi
 
if [ $ERROR -eq 0 ]; then
  # Completed OK if no errors in the log
  echo "No errors.";
else
  # Report that we failed
  echo "Errors.";
fi

Hi Justin, could you please

Hi Justin,

could you please explain some more about the setup you have here. Are all components (samba, openldap, zimbra) installed on the same server?

How would I use the script if I had a
Samba server: samba.ebox.local
and a
Zimbra server : zimbra.ebox.local

Thanks,
Klaas