PageRenderTime 58ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/iRedMail/tools/create_mail_user_OpenLDAP.py

https://bitbucket.org/dineshkummarc/iredmail
Python | 236 lines | 193 code | 12 blank | 31 comment | 3 complexity | dfa79a1581b9e940f95c47fb5cbea900 MD5 | raw file
  1. #!/usr/bin/env python
  2. # encoding: utf-8
  3. # Author: Zhang Huangbin <zhb _at_ iredmail.org>
  4. # Purpose: Add new OpenLDAP user for postfix mail server.
  5. # Project: iRedMail (http://www.iredmail.org/)
  6. # --------------------------- WARNING ------------------------------
  7. # This script only works under iRedMail >= 0.4.0 due to ldap schema
  8. # changes.
  9. # ------------------------------------------------------------------
  10. # ---------------------------- USAGE -------------------------------
  11. # Put your user list in a csv format file, e.g. users.csv, and then
  12. # import users listed in the file:
  13. #
  14. # $ python create_mail_user_OpenLDAP.py users.csv
  15. #
  16. # ------------------------------------------------------------------
  17. # ------------------------- SETTINGS -------------------------------
  18. # LDAP server address.
  19. LDAP_URI = 'ldap://127.0.0.1:389'
  20. # LDAP base dn.
  21. BASEDN = 'o=domains,dc=example,dc=com'
  22. # Bind dn/password
  23. BINDDN = 'cn=Manager,dc=example,dc=com'
  24. BINDPW = 'password'
  25. # Storage base directory.
  26. STORAGE_BASE_DIRECTORY = '/var/vmail/vmail1'
  27. # Append timestamp in maildir path.
  28. APPEND_TIMESTAMP_IN_MAILDIR = True
  29. # Get base directory and storage node.
  30. std = STORAGE_BASE_DIRECTORY.rstrip('/').split('/')
  31. STORAGE_NODE = std.pop()
  32. STORAGE_BASE = '/'.join(std)
  33. # Hashed maildir: True, False.
  34. # Example:
  35. # domain: domain.ltd,
  36. # user: zhang (zhang@domain.ltd)
  37. #
  38. # - hashed: d/do/domain.ltd/z/zh/zha/zhang/
  39. # - normal: domain.ltd/zhang/
  40. HASHED_MAILDIR = True
  41. # ------------------------------------------------------------------
  42. import os
  43. import sys
  44. import time
  45. import re
  46. try:
  47. import ldap
  48. import ldif
  49. except ImportError:
  50. print '''
  51. Error: You don't have python-ldap installed, Please install it first.
  52. You can install it like this:
  53. - On RHEL/CentOS 5.x:
  54. $ sudo yum install python-ldap
  55. - On Debian & Ubuntu:
  56. $ sudo apt-get install python-ldap
  57. '''
  58. sys.exit()
  59. def usage():
  60. print '''
  61. CSV file format:
  62. domain name, username, password, [common name], [quota_in_bytes], [groups]
  63. Example #1:
  64. iredmail.org, zhang, plain_password, Zhang Huangbin, 104857600, group1:group2
  65. Example #2:
  66. iredmail.org, zhang, plain_password, Zhang Huangbin, ,
  67. Example #3:
  68. iredmail.org, zhang, plain_password, , 104857600, group1:group2
  69. Note:
  70. - Domain name, username and password are REQUIRED, others are optional:
  71. + common name.
  72. * It will be the same as username if it's empty.
  73. * Non-ascii character is allowed in this field, they will be
  74. encoded automaticly. Such as Chinese, Korea, Japanese, etc.
  75. + quota. It will be 0 (unlimited quota) if it's empty.
  76. + groups.
  77. * valid group name (hr@a.cn): hr
  78. * incorrect group name: hr@a.cn
  79. * Do *NOT* include domain name in group name, it will be
  80. appended automaticly.
  81. * Multiple groups must be seperated by colon.
  82. - Leading and trailing Space will be ignored.
  83. '''
  84. def convEmailToUserDN(email):
  85. """Convert email address to ldap dn of normail mail user."""
  86. if email.count('@') != 1: return ''
  87. user, domain = email.split('@')
  88. # User DN format.
  89. # mail=user@domain.ltd,domainName=domain.ltd,[LDAP_BASEDN]
  90. dn = 'mail=%s,ou=Users,domainName=%s,%s' % (email, domain, BASEDN)
  91. return dn
  92. def ldif_mailuser(domain, username, passwd, cn, quota, groups=''):
  93. # Append timestamp in maildir path
  94. DATE = time.strftime('%Y.%m.%d.%H.%M.%S')
  95. TIMESTAMP_IN_MAILDIR = ''
  96. if APPEND_TIMESTAMP_IN_MAILDIR:
  97. TIMESTAMP_IN_MAILDIR = '-%s' % DATE
  98. if quota == '':
  99. quota = '0'
  100. # Remove SPACE in username.
  101. username = str(username).strip().replace(' ', '')
  102. if cn == '': cn = username
  103. mail = username.lower() + '@' + domain
  104. dn = convEmailToUserDN(mail)
  105. # Get group list.
  106. if groups.strip() != '':
  107. groups = groups.strip().split(':')
  108. for i in range(len(groups)):
  109. groups[i] = groups[i] + '@' + domain
  110. maildir_domain = str(domain).lower()
  111. if HASHED_MAILDIR is True:
  112. # Hashed. Length of domain name are always >= 2.
  113. #maildir_domain = "%s/%s/%s/" % (domain[:1], domain[:2], domain)
  114. str1 = str2 = str3 = username[0]
  115. if len(username) >= 3:
  116. str2 = username[1]
  117. str3 = username[2]
  118. elif len(username) == 2:
  119. str2 = str3 = username[1]
  120. maildir_user = "%s/%s/%s/%s%s/" % (str1, str2, str3, username, TIMESTAMP_IN_MAILDIR, )
  121. mailMessageStore = maildir_domain + '/' + maildir_user
  122. else:
  123. mailMessageStore = "%s/%s%s/" % (domain, username, TIMESTAMP_IN_MAILDIR)
  124. homeDirectory = STORAGE_BASE_DIRECTORY + '/' + mailMessageStore
  125. mailMessageStore = STORAGE_NODE + '/' + mailMessageStore
  126. ldif = [
  127. ('objectClass', ['inetOrgPerson', 'mailUser', 'shadowAccount', 'amavisAccount',]),
  128. ('mail', [mail]),
  129. ('userPassword', [passwd]),
  130. ('mailQuota', [quota]),
  131. ('cn', [cn]),
  132. ('sn', [username]),
  133. ('uid', [username]),
  134. ('storageBaseDirectory', [STORAGE_BASE]),
  135. ('mailMessageStore', [mailMessageStore]),
  136. ('homeDirectory', [homeDirectory]),
  137. ('accountStatus', ['active']),
  138. ('mtaTransport', ['dovecot']),
  139. ('enabledService', ['internal', 'doveadm', 'lib-storage',
  140. 'mail', 'smtp', 'smtpsecured',
  141. 'pop3', 'pop3secured', 'imap', 'imapsecured',
  142. 'deliver', 'lda', 'forward', 'senderbcc', 'recipientbcc',
  143. 'managesieve', 'managesievesecured',
  144. 'sieve', 'sievesecured', 'shadowaddress',
  145. 'displayedInGlobalAddressBook', ]),
  146. ('memberOfGroup', groups),
  147. # shadowAccount integration.
  148. ('shadowLastChange', ['0']),
  149. # Amavisd integration.
  150. ('amavisLocal', ['TRUE']),
  151. ]
  152. return dn, ldif
  153. if len(sys.argv) != 2 or len(sys.argv) > 2:
  154. print """Usage: $ python %s users.csv""" % ( sys.argv[0] )
  155. usage()
  156. sys.exit()
  157. else:
  158. CSV = sys.argv[1]
  159. if not os.path.exists(CSV):
  160. print '''Erorr: file not exist:''', CSV
  161. sys.exit()
  162. ldif_file = CSV + '.ldif'
  163. # Remove exist LDIF file.
  164. if os.path.exists(ldif_file):
  165. print '''< INFO > Remove exist file:''', ldif_file
  166. os.remove(ldif_file)
  167. # Read user list.
  168. userList = open(CSV, 'rb')
  169. # Convert to LDIF format.
  170. for entry in userList.readlines():
  171. entry = entry.rstrip()
  172. domain, username, passwd, cn, quota, groups = re.split('\s?,\s?', entry)
  173. dn, data = ldif_mailuser(domain, username, passwd, cn, quota, groups)
  174. # Write LDIF data.
  175. result = open(ldif_file, 'a')
  176. ldif_writer = ldif.LDIFWriter(result)
  177. ldif_writer.unparse(dn, data)
  178. # Notify info.
  179. print "< INFO > User data are stored in %s, you can verify it before import it." % os.path.abspath(ldif_file)
  180. # Prompt to import user data.
  181. '''
  182. answer = raw_input("Would you like to import them now? [y|N]").lower().strip()
  183. if answer == 'y':
  184. # Import data.
  185. conn = ldap.initialize(LDAP_URI)
  186. conn.set_option(ldap.OPT_PROTOCOL_VERSION, 3) # Use LDAP v3
  187. conn.bind_s(BINDDN, BINDPW)
  188. conn.unbind()
  189. else:
  190. pass
  191. '''