def ldif_mailuser(domain, username, cn, passwd, quota=0, aliasDomains=None, groups=None, storageBaseDirectory=None, mailbox_format=None): domain = str(domain).lower() username = str(username).strip().replace(' ', '').lower() mail = username + '@' + domain if storageBaseDirectory is None: tmpStorageBaseDirectory = settings.storage_base_directory.lower() else: tmpStorageBaseDirectory = storageBaseDirectory splitedSBD = tmpStorageBaseDirectory.rstrip('/').split('/') storageNode = splitedSBD.pop() storageBaseDirectory = '/'.join(splitedSBD) mailMessageStore = storageNode + '/' + iredutils.generate_maildir_path( mail) homeDirectory = storageBaseDirectory + '/' + mailMessageStore # Generate basic LDIF. ldif = [ ('objectClass', ['inetOrgPerson', 'mailUser', 'shadowAccount', 'amavisAccount']), ('mail', [mail]), ('userPassword', [str(passwd)]), ('sn', [username]), ('uid', [username]), ('storageBaseDirectory', [storageBaseDirectory]), ('mailMessageStore', [mailMessageStore]), ('homeDirectory', [homeDirectory]), ('accountStatus', ['active']), ( 'enabledService', [ 'mail', 'deliver', 'lda', 'lmtp', 'smtp', 'smtpsecured', 'pop3', 'pop3secured', 'pop3tls', 'imap', 'imapsecured', 'imaptls', 'managesieve', 'managesievesecured', 'sogo', # ManageService name In dovecot-1.2. 'sieve', 'sievesecured', 'forward', 'senderbcc', 'recipientbcc', 'internal', 'lib-storage', 'indexer-worker', 'doveadm', 'dsync', 'shadowaddress', 'displayedInGlobalAddressBook' ]), # shadowAccount integration. ('shadowLastChange', ['0']), # Amavisd integration. ('amavisLocal', ['TRUE']) ] # Append `shadowAddress` if aliasDomains: _shadowAddresses = [ username + '@' + d for d in aliasDomains if iredutils.is_domain(d) ] ldif += [('shadowAddress', _shadowAddresses)] # Append quota. No 'mailQuota' attribute means unlimited. quota = str(quota).strip() if quota.isdigit(): quota = int(quota) * 1024 * 1024 ldif += [('mailQuota', [str(quota)])] # Append mailbox format. if not mailbox_format: mailbox_format = settings.MAILBOX_FORMAT ldif += [('mailboxFormat', [str(mailbox_format)])] # Append cn. ldif += ldaputils.get_ldif_of_attr(attr='cn', value=cn, default=username) # Append groups. if groups and isinstance(groups, list): # Remove duplicate items. grps = [str(g).strip() for g in groups] ldif += [('memberOfGroup', list(set(grps)))] return ldif
def add(self, domain, data): # Get domain name, username, cn. self.domain = web.safestr(data.get('domainName')).strip().lower() mail_local_part = web.safestr(data.get('username')).strip().lower() self.mail = mail_local_part + '@' + self.domain if not iredutils.is_domain(self.domain): return (False, 'INVALID_DOMAIN_NAME') if self.domain != domain: return (False, 'PERMISSION_DENIED') if not iredutils.is_email(self.mail): return (False, 'INVALID_MAIL') # Check account existing. connutils = connUtils.Utils() if connutils.is_email_exists(mail=self.mail): return (False, 'ALREADY_EXISTS') # Get domain profile. domainLib = domainlib.Domain() resultOfDomainProfile = domainLib.profile(domain=self.domain) if resultOfDomainProfile[0] is True: domainProfile = resultOfDomainProfile[1] else: return resultOfDomainProfile # Check account limit. adminLib = adminlib.Admin() numberOfExistAccounts = adminLib.getNumberOfManagedAccounts(accountType='user', domains=[self.domain]) if domainProfile.mailboxes == -1: return (False, 'NOT_ALLOWED') elif domainProfile.mailboxes > 0: if domainProfile.mailboxes <= numberOfExistAccounts: return (False, 'EXCEEDED_DOMAIN_ACCOUNT_LIMIT') # Check spare quota and number of spare account limit. # Get quota from <form> mailQuota = str(data.get('mailQuota')).strip() if mailQuota.isdigit(): mailQuota = int(mailQuota) else: mailQuota = 0 # Re-calculate mail quota if this domain has limited max quota. if domainProfile.maxquota > 0: # Get used quota. qr = domainLib.getAllocatedQuotaSize(domain=self.domain) if qr[0] is True: allocatedQuota = qr[1] else: return qr spareQuota = domainProfile.maxquota - allocatedQuota if spareQuota > 0: if spareQuota < mailQuota: mailQuota = spareQuota else: # No enough quota. return (False, 'EXCEEDED_DOMAIN_QUOTA_SIZE') # # Get password from <form>. # newpw = web.safestr(data.get('newpw', '')) confirmpw = web.safestr(data.get('confirmpw', '')) resultOfPW = iredutils.verify_new_password( newpw, confirmpw, min_passwd_length=settings.min_passwd_length, max_passwd_length=settings.max_passwd_length, ) if resultOfPW[0] is True: pwscheme = None if 'storePasswordInPlainText' in data and settings.STORE_PASSWORD_IN_PLAIN_TEXT: pwscheme = 'PLAIN' passwd = iredutils.generate_password_for_sql_mail_account(resultOfPW[1], pwscheme=pwscheme) else: return resultOfPW # Get display name from <form> cn = data.get('cn', '') # Get storage base directory. tmpStorageBaseDirectory = settings.storage_base_directory.lower() splitedSBD = tmpStorageBaseDirectory.rstrip('/').split('/') storageNode = splitedSBD.pop() storageBaseDirectory = '/'.join(splitedSBD) try: # Store new user in SQL db. self.conn.insert( 'mailbox', domain=self.domain, username=self.mail, password=passwd, name=cn, maildir=iredutils.generate_maildir_path(self.mail), quota=mailQuota, storagebasedirectory=storageBaseDirectory, storagenode=storageNode, created=iredutils.get_gmttime(), active='1', local_part=mail_local_part, ) # Create an alias account: address=goto. self.conn.insert( 'alias', address=self.mail, goto=self.mail, domain=self.domain, created=iredutils.get_gmttime(), active='1', ) web.logger(msg="Create user: %s." % (self.mail), domain=self.domain, event='create',) return (True,) except Exception, e: return (False, str(e))
def add(self, domain, data): # Get domain name, username, cn. self.domain = web.safestr(data.get('domainName')).strip().lower() mail_local_part = web.safestr(data.get('username')).strip().lower() self.mail = mail_local_part + '@' + self.domain if not iredutils.is_domain(self.domain): return (False, 'INVALID_DOMAIN_NAME') if self.domain != domain: return (False, 'PERMISSION_DENIED') if not iredutils.is_email(self.mail): return (False, 'INVALID_MAIL') # Check account existing. connutils = connUtils.Utils() if connutils.is_email_exists(mail=self.mail): return (False, 'ALREADY_EXISTS') # Get domain profile. domainLib = domainlib.Domain() resultOfDomainProfile = domainLib.profile(domain=self.domain) if resultOfDomainProfile[0] is True: domainProfile = resultOfDomainProfile[1] else: return resultOfDomainProfile # Check account limit. adminLib = adminlib.Admin() numberOfExistAccounts = adminLib.getNumberOfManagedAccounts( accountType='user', domains=[self.domain]) if domainProfile.mailboxes == -1: return (False, 'NOT_ALLOWED') elif domainProfile.mailboxes > 0: if domainProfile.mailboxes <= numberOfExistAccounts: return (False, 'EXCEEDED_DOMAIN_ACCOUNT_LIMIT') # Check spare quota and number of spare account limit. # Get quota from <form> mailQuota = str(data.get('mailQuota')).strip() if mailQuota.isdigit(): mailQuota = int(mailQuota) else: mailQuota = 0 # Re-calculate mail quota if this domain has limited max quota. if domainProfile.maxquota > 0: # Get used quota. qr = domainLib.getAllocatedQuotaSize(domain=self.domain) if qr[0] is True: allocatedQuota = qr[1] else: return qr spareQuota = domainProfile.maxquota - allocatedQuota if spareQuota > 0: if spareQuota < mailQuota: mailQuota = spareQuota else: # No enough quota. return (False, 'EXCEEDED_DOMAIN_QUOTA_SIZE') # # Get password from <form>. # newpw = web.safestr(data.get('newpw', '')) confirmpw = web.safestr(data.get('confirmpw', '')) resultOfPW = iredutils.verify_new_password( newpw, confirmpw, min_passwd_length=settings.min_passwd_length, max_passwd_length=settings.max_passwd_length, ) if resultOfPW[0] is True: pwscheme = None if 'storePasswordInPlainText' in data and settings.STORE_PASSWORD_IN_PLAIN_TEXT: pwscheme = 'PLAIN' passwd = iredutils.generate_password_hash(resultOfPW[1], pwscheme=pwscheme) else: return resultOfPW # Get display name from <form> cn = data.get('cn', '') # Get storage base directory. tmpStorageBaseDirectory = settings.storage_base_directory.lower() splitedSBD = tmpStorageBaseDirectory.rstrip('/').split('/') storageNode = splitedSBD.pop() storageBaseDirectory = '/'.join(splitedSBD) try: # Store new user in SQL db. self.conn.insert( 'mailbox', domain=self.domain, username=self.mail, password=passwd, name=cn, maildir=iredutils.generate_maildir_path(self.mail), quota=mailQuota, storagebasedirectory=storageBaseDirectory, storagenode=storageNode, mailboxformat=settings.MAILBOX_FORMAT, created=iredutils.get_gmttime(), active='1', ) self.conn.insert('forwardings', address=self.mail, forwarding=self.mail, domain=self.domain, is_forwarding=1) web.logger( msg="Create user: %s." % (self.mail), domain=self.domain, event='create', ) return (True, ) except Exception as e: return (False, str(e))
def ldif_mailuser(domain, username, cn, passwd, quota=0, aliasDomains=[], groups=[], storageBaseDirectory=None, ): domain = str(domain).lower() username = str(username).strip().replace(' ', '').lower() mail = username + '@' + domain if storageBaseDirectory is None: tmpStorageBaseDirectory = settings.storage_base_directory.lower() else: tmpStorageBaseDirectory = storageBaseDirectory splitedSBD = tmpStorageBaseDirectory.rstrip('/').split('/') storageNode = splitedSBD.pop() storageBaseDirectory = '/'.join(splitedSBD) mailMessageStore = storageNode + '/' + iredutils.generate_maildir_path(mail) homeDirectory = storageBaseDirectory + '/' + mailMessageStore # Generate basic LDIF. ldif = [ ('objectClass', ['inetOrgPerson', 'mailUser', 'shadowAccount', 'amavisAccount', ]), ('mail', [mail]), ('userPassword', [str(passwd)]), ('sn', [username]), ('uid', [username]), ('storageBaseDirectory', [storageBaseDirectory]), ('mailMessageStore', [mailMessageStore]), ('homeDirectory', [homeDirectory]), ('accountStatus', ['active']), ('enabledService', ['mail', 'deliver', 'lda', 'lmtp', 'smtp', 'smtpsecured', 'pop3', 'pop3secured', 'imap', 'imapsecured', 'managesieve', 'managesievesecured', # ManageService name In dovecot-1.2. 'sieve', 'sievesecured', 'forward', 'senderbcc', 'recipientbcc', 'internal', 'lib-storage', 'indexer-worker', 'doveadm', 'dsync', 'shadowaddress', 'displayedInGlobalAddressBook', ] ), # shadowAccount integration. ('shadowLastChange', ['0']), # Amavisd integration. ('amavisLocal', ['TRUE']), ] # Append @shadowAddress. shadowAddresses = [] for d in aliasDomains: if iredutils.is_domain(d): shadowAddresses += [username + '@' + d] if len(shadowAddresses) > 0: ldif += [('shadowAddress', shadowAddresses)] # Append quota. No 'mailQuota' attribute means unlimited. quota = str(quota).strip() if quota.isdigit(): quota = int(quota) * 1024 * 1024 ldif += [('mailQuota', [str(quota)])] # Append cn. ldif += ldaputils.get_ldif_of_attr(attr='cn', value=cn, default=username,) # Append groups. if isinstance(groups, list) and len(groups) >= 1: # Remove duplicate items. grps = set() for g in groups: grps.update([str(g).strip()]) ldif += [('memberOfGroup', list(grps))] return ldif
def ldif_mailuser(domain, username, cn, passwd, quota=0, storage_base_directory=None, mailbox_format=None, mailbox_folder=None, mailbox_maildir=None, language=None, disabled_services=None, domain_status=None): domain = str(domain).lower() username = str(username).strip().replace(' ', '').lower() mail = username + '@' + domain if not cn: cn = username if not (storage_base_directory and os.path.isabs(storage_base_directory)): storage_base_directory = settings.storage_base_directory if mailbox_maildir and os.path.isabs(mailbox_maildir): home_directory = str(mailbox_maildir).lower() else: home_directory = os.path.join(storage_base_directory, iredutils.generate_maildir_path(mail)) enabled_services = list(attrs.USER_SERVICES_OF_NORMAL_USER ) + settings.ADDITIONAL_ENABLED_USER_SERVICES if disabled_services: enabled_services = set(enabled_services) - set(disabled_services) enabled_services = list(enabled_services) lang = language or settings.default_language if lang not in iredutils.get_language_maps(): lang = None # Generate basic LDIF. ldif = ldaputils.attrs_ldif({ 'objectClass': ['inetOrgPerson', 'mailUser', 'shadowAccount', 'amavisAccount'], 'mail': mail, 'userPassword': passwd, 'cn': cn, 'sn': username, 'uid': username, 'homeDirectory': home_directory, 'accountStatus': 'active', 'enabledService': enabled_services, 'preferredLanguage': lang, # shadowAccount integration. 'shadowLastChange': ldaputils.get_days_of_shadow_last_change(), # Amavisd integration. 'amavisLocal': 'TRUE', }) # Append quota. No 'mailQuota' attribute means unlimited. quota = str(quota).strip() if quota.isdigit(): quota = int(int(quota) * 1024 * 1024) ldif += ldaputils.attr_ldif('mailQuota', quota) # Append mailbox format. if mailbox_format: ldif += ldaputils.attr_ldif('mailboxFormat', str(mailbox_format).lower()) # mailbox folder if mailbox_folder: ldif += ldaputils.attr_ldif('mailboxFolder', mailbox_folder) if domain_status not in ['active', None]: ldif += ldaputils.attr_ldif('domainStatus', 'disabled') return ldif
def add_user_from_form(domain, form, conn=None): # Get domain name, username, cn. mail_domain = form_utils.get_domain_name(form) mail_username = form.get('username') if mail_username: mail_username = web.safestr(mail_username).strip().lower() else: return (False, 'INVALID_ACCOUNT') mail = mail_username + '@' + mail_domain if mail_domain != domain: return (False, 'PERMISSION_DENIED') if not iredutils.is_auth_email(mail): return (False, 'INVALID_MAIL') if not conn: _wrap = SQLWrap() conn = _wrap.conn # Check account existing. if sql_lib_general.is_email_exists(mail=mail, conn=conn): return (False, 'ALREADY_EXISTS') # Get domain profile. qr_profile = sql_lib_domain.profile(conn=conn, domain=domain) if qr_profile[0] is True: domain_profile = qr_profile[1] domain_settings = sqlutils.account_settings_string_to_dict( domain_profile['settings']) else: return qr_profile # Check account limit. num_exist_accounts = sql_lib_admin.num_managed_users(conn=conn, domains=[domain]) if domain_profile.mailboxes == -1: return (False, 'NOT_ALLOWED') elif domain_profile.mailboxes > 0: if domain_profile.mailboxes <= num_exist_accounts: return (False, 'EXCEEDED_DOMAIN_ACCOUNT_LIMIT') # Get quota from <form> quota = str(form.get('mailQuota', 0)).strip() try: quota = int(quota) except: quota = 0 # # Get password from <form>. # pw_hash = form.get('password_hash', '') newpw = web.safestr(form.get('newpw', '')) confirmpw = web.safestr(form.get('confirmpw', '')) if pw_hash: if not iredpwd.is_supported_password_scheme(pw_hash): return (False, 'INVALID_PASSWORD_SCHEME') passwd = pw_hash else: # Get password length limit from domain profile or global setting. min_passwd_length = domain_settings.get('min_passwd_length', 0) max_passwd_length = domain_settings.get('max_passwd_length', 0) qr_pw = iredpwd.verify_new_password( newpw, confirmpw, min_passwd_length=min_passwd_length, max_passwd_length=max_passwd_length) if qr_pw[0] is True: pwscheme = None if 'store_password_in_plain_text' in form and settings.STORE_PASSWORD_IN_PLAIN_TEXT: pwscheme = 'PLAIN' passwd = iredpwd.generate_password_hash(qr_pw[1], pwscheme=pwscheme) else: return qr_pw # Get display name from <form> cn = form_utils.get_single_value(form, input_name='cn', default_value='') # Get preferred language. preferred_language = form_utils.get_language(form) if preferred_language not in iredutils.get_language_maps(): preferred_language = '' # Get storage base directory. _storage_base_directory = settings.storage_base_directory splited_sbd = _storage_base_directory.rstrip('/').split('/') storage_node = splited_sbd.pop() storage_base_directory = '/'.join(splited_sbd) maildir = iredutils.generate_maildir_path(mail) # Read full maildir path from web form - from RESTful API. mailbox_maildir = form.get('maildir', '').lower().rstrip('/') if mailbox_maildir and os.path.isabs(mailbox_maildir): # Split storageBaseDirectory and storageNode _splited = mailbox_maildir.rstrip('/').split('/') storage_base_directory = '/' + _splited[0] storage_node = _splited[1] maildir = '/'.join(_splited[2:]) record = { 'domain': domain, 'username': mail, 'password': passwd, 'name': cn, 'quota': quota, 'storagebasedirectory': storage_base_directory, 'storagenode': storage_node, 'maildir': maildir, 'language': preferred_language, 'passwordlastchange': iredutils.get_gmttime(), 'created': iredutils.get_gmttime(), 'active': 1 } # Get settings from SQL db. db_settings = iredutils.get_settings_from_db() # Get mailbox format and folder. _mailbox_format = form.get('mailboxFormat', db_settings['mailbox_format']).lower() _mailbox_folder = form.get('mailboxFolder', db_settings['mailbox_folder']) if iredutils.is_valid_mailbox_format(_mailbox_format): record['mailboxformat'] = _mailbox_format if iredutils.is_valid_mailbox_folder(_mailbox_folder): record['mailboxfolder'] = _mailbox_folder # Always store plain password in another attribute. if settings.STORE_PLAIN_PASSWORD_IN_ADDITIONAL_ATTR: record[settings.STORE_PLAIN_PASSWORD_IN_ADDITIONAL_ATTR] = newpw # Set disabled mail services. disabled_mail_services = domain_settings.get('disabled_mail_services', []) for srv in disabled_mail_services: record['enable' + srv] = 0 # globally disabled mail services for srv in settings.ADDITIONAL_DISABLED_USER_SERVICES: record['enable' + srv] = 0 # globally enabled mail services for srv in settings.ADDITIONAL_ENABLED_USER_SERVICES: record['enable' + srv] = 1 try: # Store new user in SQL db. conn.insert('mailbox', **record) # Create an entry in `vmail.forwardings` with `address=forwarding` conn.insert('forwardings', address=mail, forwarding=mail, domain=domain, dest_domain=domain, is_forwarding=1, active=1) log_activity(msg="Create user: %s." % (mail), domain=domain, event='create') return (True, ) except Exception as e: return (False, repr(e))