Zimbra autocreate accounts with Active Directory or LDAP

From Wiki

Jump to:navigation, search

he accounts are created automatically from Active Directory. There are a couple of pre-requisites for the way we do it. 1) the username must be 'sensible' - no apostrophes, dashes etc otherwise my scripts break 2)The students employeeTypemust be set to STUDENT in active directory 3) you have an ldap bind account 4) the account is enabled 5) there is a 'banned' group - and the student isn't in it 6) you need to read the script really

I run this from cron.daily

#!/bin/sh
/usr/bin/python /usr/local/sbin/zimbra.py | mail -s "Zimbra account creation"        
admin@email.address.com

edit this and copy it to /usr/local/sbin/zimbra.py

#!/usr/bin/python
# 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; GPLv3
#
# 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.
#
# To obtain a copy of the GNU General Public License, write to the Free  Software Foundation,
# Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
#
#--------------------------------------------------------------------------------------------------
# Notes:
# This script automatically creates zimbra accounts from active directory, the  actrive directory account must have
# the employeeType=STUDENT attributed set. If accounts are in the 'banned' active directory group then the
# account will automatically be locked when the script is run, and unlocked if they are no longer in the AD
# banned group
#--------------------------------------------------------------------------------------------------
# Variables can be changed here:
banned =  'CN=Banned,CN=yourschool,DC=sch,DC=uk'
# an OU for banned users
scope   = 'ou=users,dc=yourschool,dc=sch,dc=uk'
#the search scope
domain = "yourschool.sch.uk" # "example.com"
ldapserver="server1"
#ldap server
port="389"
#ldap port (389 default)
emaildomain="yourschool.sch.uk"
#the email domain
ldapbinddomain="student-domain"
#the domain of the ldap bind account
ldapbind="ldap"
#the account name of the account to bind to ldap
ldappassword="password"
#the ldap password
pathtozmprov="/opt/zimbra/bin/zmprov"
#--------------------------------------------------------------------------------------------------
import ldap, string, os, time, sys 
#output the list of all accounts from zmprov gaa (get all accounts)
f = os.popen(pathtozmprov +' gaa')
zmprovgaa= []
zmprovgaa = f.readlines() 
l=ldap.initialize("ldap://"+ldapserver+"."+domain+":"+port)
l.simple_bind_s(ldapbinddomain+"\\"+ldapbind,ldappassword) #bind to the ldap  server using name/password
try:
    res = l.search_s(scope,
    ldap.SCOPE_SUBTREE, "(&(ObjectCategory=user)  (userAccountControl=512)(employeeType=STUDENT))",  ['sAMAccountName','givenName','sn','memberOf'])
#userAccountControl  512 = normal , 514 = disabled account
    for (dn, vals) in res:
      accountname = vals['sAMAccountName'][0].lower()
      try:
        sirname = vals['sn'][0].lower()
      except:
        sirname = vals['sAMAccountName'][0].lower()
      try:
        givenname = vals['givenName'][0]
      except:
        givenname = vals['sAMAccountName'][0].lower()
      try:
        groups = vals['memberOf']
      except:
        groups = 'none'
      initial = givenname[:1].upper()
      sirname = sirname.replace(' ', )
      sirname = sirname.replace('\, )
      sirname = sirname.replace('-', )
      sirname = sirname.capitalize()
      name = initial + "." + sirname
      accountname = accountname + "@" + emaildomain
      password = "  \'\' "
      sys.stdout.flush()
      # if the account doesn't exist in the output of zmprov gaa create the  account
      if accountname +"\n" not in zmprovgaa:
        print  accountname," exists in active directory but not in zimbra, the   account is being created\n"
        time.sleep(1)
        os.system(pathtozmprov +' ca %s %s displayName %s' %  (accountname,password,name))
     # if the account is in the group 'banned' check to see if account already  locked
      if banned in groups:
        zmprovga = os.popen(pathtozmprov + ' ga %s' % (accountname))
        ga= []
        ga = zmprovga.readlines()
        locked = "zimbraAccountStatus: locked\n"
        if locked not in ga: #if account not locked then lock it
          print accountname, " has been BANNED from the internet. The email  account has been locked "
          os.system(pathtozmprov + ' ma %s zimbraAccountStatus locked' % (accountname))
          time.sleep(1)
        else:
          print accountname, " has a locked email account because they are in  the 'banned' group"
       #set any accounts to 'active' if they are not in the banned group and the account is currently locked
      else:
        zmprovga = os.popen(pathtozmprov + ' ga %s' % (accountname))
        ga= []
        ga = zmprovga.readlines()
        locked = "zimbraAccountStatus: locked\n"
        if locked in ga:
          os.system(pathtozmprov + ' ma %s zimbraAccountStatus active' %  (accountname))
          time.sleep(1)
          print accountname, " is no longer in the 'banned' group, therefore  the account has been activated"                    
except ldap.LDAPError, error_message:
  print error_message
l.unbind_s()