# Author: Zhang Huangbin import sys import types import ldap import ldap.filter import web from libs import iredutils from libs.ldaplib import core, domain as domainlib, attrs, ldaputils, iredldif, connUtils, decorators # Policyd integration. from libs.policyd import throttle cfg = web.iredconfig session = web.config.get('_session') class User(core.LDAPWrap): def __del__(self): try: self.conn.unbind() except: pass # List all users under one domain. @decorators.require_domain_access def listAccounts(self, domain): self.domain = domain self.domainDN = ldaputils.convKeywordToDN(self.domain, accountType='domain') try: # Use '(!(mail=@domain.ltd))' to hide catch-all account. self.users = self.conn.search_s( attrs.DN_BETWEEN_USER_AND_DOMAIN + self.domainDN, ldap.SCOPE_SUBTREE, '(&(objectClass=mailUser)(!(mail=@%s)))' % self.domain, attrs.USER_SEARCH_ATTRS, ) connutils = connUtils.Utils() connutils.updateAttrSingleValue(self.domainDN, 'domainCurrentUserNumber', len(self.users)) return (True, self.users) except ldap.NO_SUCH_OBJECT: #self.conn.add_s( # attrs.DN_BETWEEN_USER_AND_DOMAIN + self.domainDN, # iredldif.ldif_group(attrs.GROUP_USERS), # ) return (False, 'NO_SUCH_OBJECT') except ldap.SIZELIMIT_EXCEEDED: return (False, 'EXCEEDED_LDAP_SERVER_SIZELIMIT') except Exception, e: return (False, ldaputils.getExceptionDesc(e)) # Get values of user or domain catch-all account. # accountType in ['user', 'catchall',] @decorators.require_domain_access def profile(self, domain, mail, accountType='user'): self.mail = web.safestr(mail) self.domain = self.mail.split('@', 1)[-1] if self.domain != domain: return web.seeother('/domains?msg=PERMISSION_DENIED') self.filter = '(&(objectClass=mailUser)(mail=%s))' % (self.mail,) if accountType == 'catchall': self.filter = '(&(objectClass=mailUser)(mail=@%s))' % (self.mail,) else: if not self.mail.endswith('@' + self.domain): return web.seeother('/domains?msg=PERMISSION_DENIED') if attrs.RDN_USER == 'mail': self.searchdn = ldaputils.convKeywordToDN(self.mail, accountType=accountType) self.scope = ldap.SCOPE_BASE else: self.searchdn = attrs.DN_BETWEEN_USER_AND_DOMAIN + ldaputils.convKeywordToDN(self.domain, accountType='domain') self.scope = ldap.SCOPE_SUBTREE try: self.user_profile = self.conn.search_s( self.searchdn, self.scope, self.filter, attrs.USER_ATTRS_ALL, ) return (True, self.user_profile) except Exception, e: return (False, ldaputils.getExceptionDesc(e)) @decorators.require_domain_access def add(self, domain, data): # Get domain name, username, cn. self.domain = web.safestr(data.get('domainName')).lower() self.username = web.safestr(data.get('username')).lower() self.mail = self.username + '@' + self.domain self.groups = data.get('groups', []) if not iredutils.isDomain(self.domain) or not iredutils.isEmail(self.mail): return (False, 'MISSING_DOMAIN_OR_USERNAME') # Check account existing. connutils = connUtils.Utils() if connutils.isAccountExists(domain=self.domain, filter='(|(mail=%s)(shadowAddress=%s))' % (self.mail, self.mail)): return (False, 'ALREADY_EXISTS') # Get @domainAccountSetting. domainLib = domainlib.Domain() result_domain_profile = domainLib.profile(self.domain) # Initial parameters. domainAccountSetting = {} self.aliasDomains = [] if result_domain_profile[0] is True: domainProfile = result_domain_profile[1] domainAccountSetting = ldaputils.getAccountSettingFromLdapQueryResult(domainProfile, key='domainName').get(self.domain, {}) self.aliasDomains = domainProfile[0][1].get('domainAliasName', []) # Check password. self.newpw = web.safestr(data.get('newpw')) self.confirmpw = web.safestr(data.get('confirmpw')) result = iredutils.verifyNewPasswords(self.newpw, self.confirmpw, min_passwd_length=domainAccountSetting.get('minPasswordLength', '0'), max_passwd_length=domainAccountSetting.get('maxPasswordLength', '0'), ) if result[0] is True: self.passwd = ldaputils.generatePasswd(result[1]) else: return result # Get display name. self.cn = data.get('cn') # Get user quota. Unit is MB. # 0 or empty is not allowed if domain quota is set, set to # @defaultUserQuota or @domainSpareQuotaSize # Initial final mailbox quota. self.quota = 0 # Get mail quota from web form. defaultUserQuota = domainLib.getDomainDefaultUserQuota(self.domain, domainAccountSetting) self.mailQuota = data.get('mailQuota') if str(self.mailQuota).strip().isdigit(): self.mailQuota = int(self.mailQuota) else: self.mailQuota = defaultUserQuota # 0 means unlimited. domainQuotaSize, domainQuotaUnit = domainAccountSetting.get('domainQuota', '0:GB').split(':') if int(domainQuotaSize) == 0: # Unlimited. self.quota = self.mailQuota else: # Get domain quota, convert to MB. if domainQuotaUnit == 'TB': domainQuota = int(domainQuotaSize) * 1024 * 1024 # TB elif domainQuotaUnit == 'GB': domainQuota = int(domainQuotaSize) * 1024 # GB else: domainQuota = int(domainQuotaSize) # MB # TODO Query whole domain and calculate current quota size, not read from domain profile. #domainCurrentQuotaSize = int(domainProfile[0][1].get('domainCurrentQuotaSize', ['0'])[0]) / (1024*1024) result = connutils.getDomainCurrentQuotaSizeFromLDAP(domain=self.domain) if result[0] is True: domainCurrentQuotaSize = result[1] else: domainCurrentQuotaSize = 0 # Spare quota. domainSpareQuotaSize = domainQuota - domainCurrentQuotaSize/(1024*1024) if domainSpareQuotaSize <= 0: return (False, 'EXCEEDED_DOMAIN_QUOTA_SIZE') # Get FINAL mailbox quota. if self.mailQuota == 0: self.quota = domainSpareQuotaSize else: if domainSpareQuotaSize > self.mailQuota: self.quota = self.mailQuota else: self.quota = domainSpareQuotaSize # Get default groups. self.groups = [ web.safestr(v) for v in domainAccountSetting.get('defaultList', '').split(',') if iredutils.isEmail(v) ] self.defaultStorageBaseDirectory = domainAccountSetting.get('defaultStorageBaseDirectory', None) # Get default mail list which set in domain accountSetting. ldif = iredldif.ldif_mailuser( domain=self.domain, aliasDomains=self.aliasDomains, username=self.username, cn=self.cn, passwd=self.passwd, quota=self.quota, groups=self.groups, storageBaseDirectory=self.defaultStorageBaseDirectory, ) if attrs.RDN_USER == 'mail': self.dn = ldaputils.convKeywordToDN(self.mail, accountType='user') elif attrs.RDN_USER == 'cn': self.dn = 'cn=' + self.cn + ',' + attrs.DN_BETWEEN_USER_AND_DOMAIN + \ ldaputils.convKeywordToDN(self.domain, accountType='domain') elif attrs.RDN_USER == 'uid': self.dn = 'uid=' + self.username + ',' + attrs.DN_BETWEEN_USER_AND_DOMAIN + \ ldaputils.convKeywordToDN(self.domain, accountType='domain') else: return (False, 'UNSUPPORTED_USER_RDN') try: self.conn.add_s(ldap.filter.escape_filter_chars(self.dn), ldif,) web.logger(msg="Create user: %s." % (self.mail), domain=self.domain, event='create',) return (True,) except ldap.ALREADY_EXISTS: return (False, 'ALREADY_EXISTS') except Exception, e: return (False, ldaputils.getExceptionDesc(e)) def getFilterOfDeleteUserFromGroups(self, mail): # Get valid emails as list. if isinstance(mail, types.ListType): self.mails = [web.safestr(v).lower() for v in mail if iredutils.isEmail(str(v))] else: # Single email. self.mails = [web.safestr(mail).lower()] filterUserAndAlias = '(&(|(objectClass=mailAlias)(objectClass=mailUser))(|' filterExternalUser = '(&(objectClass=mailExternalUser)(|' for mail in self.mails: filterUserAndAlias += '(mailForwardingAddress=%s)' % mail filterExternalUser += '(mail=%s)' % mail # Close filter string. filterUserAndAlias += '))' filterExternalUser += '))' filter = '(|' + filterUserAndAlias + filterExternalUser + ')' return filter # Delete single user from mail list, alias, user forwarding addresses. def deleteSingleUserFromGroups(self, mail): self.mail = web.safestr(mail) if not iredutils.isEmail(self.mail): return (False, 'INVALID_MAIL') # Get domain name of this account. self.domain = self.mail.split('@')[-1] # Get dn of mail user and domain. self.dnUser = ldaputils.convKeywordToDN(self.mail, accountType='user') self.dnDomain = ldaputils.convKeywordToDN(self.domain, accountType='domain') try: # Get accounts which contains destination email. objsHasUser = self.conn.search_s( self.dnDomain, ldap.SCOPE_SUBTREE, self.getFilterOfDeleteUserFromGroups(self.mail), ['dn'], ) if len(objsHasUser) >= 1: connutils = connUtils.Utils() for obj in objsHasUser: if obj[0].endswith(attrs.DN_BETWEEN_ALIAS_AND_DOMAIN + self.dnDomain) or \ obj[0].endswith(attrs.DN_BETWEEN_USER_AND_DOMAIN + self.dnDomain): # Remove address from alias and user. connutils.addOrDelAttrValue( dn=obj[0], attr='mailForwardingAddress', value=self.mail, action='delete', ) elif obj[0].endswith('ou=Externals,' + self.domaindn): # Remove address from external member list. connutils.addOrDelAttrValue( dn=obj[0], attr='mail', value=self.mail, action='delete', ) else: pass else: pass return (True,) except Exception, e: return (False, ldaputils.getExceptionDesc(e)) # Delete single user. def deleteSingleUser(self, mail, deleteFromGroups=True,): self.mail = web.safestr(mail) if not iredutils.isEmail(self.mail): return (False, 'INVALID_MAIL') # Get domain name of this account. self.domain = self.mail.split('@')[-1] # Get dn of mail user and domain. self.dnUser = ldaputils.convKeywordToDN(self.mail, accountType='user') # Delete user object. try: #deltree.DelTree(self.conn, self.dnUser, ldap.SCOPE_SUBTREE) self.conn.delete_s(self.dnUser) if deleteFromGroups: self.deleteSingleUserFromGroups(self.mail) # Delete record from SQL database: real-time used quota. if session.get('enableShowUsedQuota', False) is True: try: iredutils.deleteAccountFromUsedQuota([self.mail]) except: pass # Log delete action. web.logger( msg="Delete user: %s." % (self.mail), domain=self.domain, event='delete', ) return (True,) except ldap.LDAPError, e: return (False, ldaputils.getExceptionDesc(e)) # Delete mail users in same domain. @decorators.require_domain_access def delete(self, domain, mails=[]): if mails is None or len(mails) == 0: return (False, 'NO_ACCOUNT_SELECTED') self.domain = web.safestr(domain) self.mails = [str(v) for v in mails if iredutils.isEmail(v) and str(v).endswith('@'+self.domain)] self.domaindn = ldaputils.convKeywordToDN(self.domain, accountType='domain') if not iredutils.isDomain(self.domain): return (False, 'INVALID_DOMAIN_NAME') result = {} for mail in self.mails: self.mail = web.safestr(mail) try: # Delete user object (ldap.SCOPE_BASE). self.deleteSingleUser(self.mail,) # Delete user object and whole sub-tree. # Get dn of mail user and domain. """ self.userdn = ldaputils.convKeywordToDN(self.mail, accountType='user') deltree.DelTree(self.conn, self.userdn, ldap.SCOPE_SUBTREE) # Log delete action. web.logger( msg="Delete user: %s." % (self.mail), domain=self.mail.split('@')[1], event='delete', ) """ except ldap.LDAPError, e: result[self.mail] = ldaputils.getExceptionDesc(e) if result == {}: return (True,) else: return (False, str(result)) @decorators.require_domain_access def enableOrDisableAccount(self, domain, mails, action, attr='accountStatus',): if mails is None or len(mails) == 0: return (False, 'NO_ACCOUNT_SELECTED') self.mails = [str(v) for v in mails if iredutils.isEmail(v) and str(v).endswith('@'+str(domain)) ] result = {} connutils = connUtils.Utils() for mail in self.mails: self.mail = web.safestr(mail) if not iredutils.isEmail(self.mail): continue self.domain = self.mail.split('@')[-1] self.dn = ldaputils.convKeywordToDN(self.mail, accountType='user') try: connutils.enableOrDisableAccount( domain=self.domain, account=self.mail, dn=self.dn, action=web.safestr(action).strip().lower(), accountTypeInLogger='user', ) except ldap.LDAPError, e: result[self.mail] = str(e) if result == {}: return (True,) else: return (False, str(result)) @decorators.require_domain_access def update(self, profile_type, mail, data): self.profile_type = web.safestr(profile_type) self.mail = web.safestr(mail) self.domain = self.mail.split('@', 1)[-1] domainAccountSetting = {} connutils = connUtils.Utils() domainLib = domainlib.Domain() # Get account dn. self.dn = connutils.getDnWithKeyword(self.mail, accountType='user') self.domaindn = ldaputils.convKeywordToDN(self.domain, accountType='domain') try: result = domainLib.getDomainAccountSetting(domain=self.domain) if result[0] is True: domainAccountSetting = result[1] except Exception, e: pass mod_attrs = [] if self.profile_type == 'general': # Get cn. cn = data.get('cn', None) mod_attrs += ldaputils.getSingleModAttr(attr='cn', value=cn, default=self.mail.split('@')[0]) # Update employeeNumber, mobile, title. for tmp_attr in ['employeeNumber', 'mobile', 'title',]: mod_attrs += ldaputils.getSingleModAttr(attr=tmp_attr, value=data.get(tmp_attr), default=None) ############ # Get quota # Get mail quota from web form. quota = web.safestr(data.get('mailQuota', '')).strip() oldquota = web.safestr(data.get('oldMailQuota', '')).strip() if not oldquota.isdigit(): oldquota = 0 else: oldquota = int(oldquota) if quota == '' or not quota.isdigit(): # Don't touch it, keep original value. pass else: #mod_attrs += [( ldap.MOD_REPLACE, 'mailQuota', str(int(mailQuota) * 1024 * 1024) )] # Assign quota which got from web form. mailQuota = int(quota) # If mailQuota > domainSpareQuotaSize, use domainSpareQuotaSize. # if mailQuota < domainSpareQuotaSize, use mailQuota # 0 means unlimited. domainQuotaSize, domainQuotaUnit = domainAccountSetting.get('domainQuota', '0:GB').split(':') if int(domainQuotaSize) == 0: # Unlimited. Keep quota which got from web form. mod_attrs += [(ldap.MOD_REPLACE, 'mailQuota', str(mailQuota*1024*1024))] else: # Get domain quota. if domainQuotaUnit == 'TB': domainQuota = int(domainQuotaSize) * 1024 * 1024 # TB elif domainQuotaUnit == 'GB': domainQuota = int(domainQuotaSize) * 1024 # GB else: domainQuota = int(domainQuotaSize) # MB # Query LDAP and get current domain quota size. result = connutils.getDomainCurrentQuotaSizeFromLDAP(domain=self.domain) if result[0] is True: domainCurrentQuotaSizeInBytes = result[1] else: domainCurrentQuotaSizeInBytes = 0 # Spare quota. domainSpareQuotaSize = (domainQuota + oldquota) - (domainCurrentQuotaSizeInBytes/(1024*1024)) if domainSpareQuotaSize <= 0: # Don't update quota if already exceed domain quota size. #return (False, 'EXCEEDED_DOMAIN_QUOTA_SIZE') # Set to 1MB. don't exceed domain quota size. mod_attrs += [(ldap.MOD_REPLACE, 'mailQuota', str(1024*1024))] else: # Get FINAL mailbox quota. if mailQuota >= domainSpareQuotaSize: mailQuota = domainSpareQuotaSize mod_attrs += [(ldap.MOD_REPLACE, 'mailQuota', str(mailQuota*1024*1024))] # End quota ############ # Get telephoneNumber. telephoneNumber = data.get('telephoneNumber', []) nums = [str(num) for num in telephoneNumber if len(num) > 0] mod_attrs += [(ldap.MOD_REPLACE, 'telephoneNumber', nums)] # Get accountStatus. if 'accountStatus' in data.keys(): accountStatus = 'active' else: accountStatus = 'disabled' mod_attrs += [ (ldap.MOD_REPLACE, 'accountStatus', accountStatus) ] # Get enabledService=displayedInGlobalAddressBook if 'displayedInGlobalAddressBook' in data.keys(): mod_type = 'add' else: mod_type = 'delete' result = connutils.addOrDelAttrValue( dn=self.dn, attr='enabledService', value='displayedInGlobalAddressBook', action=mod_type, ) if result[0] is False: return result ########################### # Member of Groups/Aliases # self.memberOfGroup = [ web.safestr(v) for v in data.get('memberOfGroup', []) if iredutils.isEmail(v) ] if self.memberOfGroup == []: mod_attrs += [(ldap.MOD_REPLACE, 'memberOfGroup', None)] else: mod_attrs += [(ldap.MOD_REPLACE, 'memberOfGroup', self.memberOfGroup)] self.currentMemberOfAlias = [web.safestr(v) for v in data.get('memberOfAlias', []) if iredutils.isEmail(v) ] self.oldMemberOfAlias = [web.safestr(v) for v in data.get('oldMemberOfAlias', []) if iredutils.isEmail(v) ] # Get removed memberOfAlias. self.removedMemberOfAlias = [web.safestr(v) for v in self.oldMemberOfAlias if v not in self.currentMemberOfAlias and iredutils.isEmail(v) ] # Get added memberOfAlias. self.addedMemberOfAlias = [web.safestr(v) for v in self.currentMemberOfAlias if v not in self.oldMemberOfAlias and iredutils.isEmail(v) ] # Remove user from aliases in @removedMemberOfAlias. for als in self.removedMemberOfAlias: try: result = connutils.addOrDelAttrValue( dn=ldaputils.convKeywordToDN(als, accountType='alias'), attr='mailForwardingAddress', value=self.mail, action='delete', ) except Exception, e: pass # Assign user to new @addedMemberOfAlias. for als in self.addedMemberOfAlias: try: result = connutils.addOrDelAttrValue( dn=ldaputils.convKeywordToDN(als, accountType='alias'), attr='mailForwardingAddress', value=self.mail, action='add', ) except Exception, e: pass elif self.profile_type == 'forwarding': # Update 'enabledService=forwarding'. if 'forwarding' in data.keys(): mod_type = 'add' else: mod_type = 'delete' result = connutils.addOrDelAttrValue( dn=self.dn, attr='enabledService', value='forward', action=mod_type, ) if result[0] is not True: return result # Get mail forwarding addresses. forwardingAddresses = [web.safestr(v).lower().strip() for v in data.get('mailForwardingAddress', []) if iredutils.isEmail(v) ] if forwardingAddresses == [] or forwardingAddresses == [self.mail]: # If no forwarding address exists, do not update it. cur_user_profile = self.conn.search_s( self.dn, ldap.SCOPE_BASE, '(&(objectclass=mailUser)(mail=%s))' % self.mail, ['mailForwardingAddress'], ) if len(cur_user_profile[0][1]) == 0: pass elif len(cur_user_profile[0][1]) > 0: mod_attrs += [(ldap.MOD_DELETE, 'mailForwardingAddress', None)] else: # Get mail forwarding addresses. self.mailForwardingAddress = list(set(forwardingAddresses)) self.mailForwardingAddress.sort() # Check whether saving a copy in mailbox. if 'savecopy' in data.keys(): # Append current user's mail address in forwarding list. if self.mail not in self.mailForwardingAddress: self.mailForwardingAddress += [self.mail] else: # Remove current user's email from forwarding list. if self.mail in self.mailForwardingAddress: self.mailForwardingAddress.remove(self.mail) mod_attrs += [(ldap.MOD_REPLACE, 'mailForwardingAddress', self.mailForwardingAddress)] try: self.conn.modify_s(self.dn, mod_attrs) return (True,) except Exception, e: return (False, ldaputils.getExceptionDesc(e)) elif self.profile_type == 'aliases': # Update 'enabledService=shadowaddress'. if 'aliases' in data.keys(): mod_type = 'add' else: mod_type = 'delete' result = connutils.addOrDelAttrValue( dn=self.dn, attr='enabledService', value='shadowaddress', action=mod_type, ) if result[0] is not True: return result # Get available domain names, includes domainName & domainAliasName. # Shadow addresses must be ends with one of them. availableDomainNames = [] resultOfAvaDomainNames = connutils.getAvailableDomainNames(domain=self.domain) if resultOfAvaDomainNames[0] is True: availableDomainNames = resultOfAvaDomainNames[1] else: return resultOfAvaDomainNames # Get shadow addresses. shadowAddresses = [ web.safestr(v).lower().strip() for v in data.get('shadowAddress', []) if iredutils.isEmail(v) and v != self.mail and v.split('@')[-1] in availableDomainNames ] # Check whether shadow addresses exist or not. if len(shadowAddresses) > 0: filter_object_classes = '(|(objectClass=mailUser)(objectClass=mailList)(objectClass=mailAlias))' filter_attrs = '(|' for i in shadowAddresses: filter_attrs += '(mail=%s)(shadowAddress=%s)' % (i, i) filter_attrs += ')' shaddr_filter = '(&%s%s(!(mail=%s)))' % (filter_object_classes, filter_attrs, self.mail) try: qr = self.conn.search_s( self.domaindn, ldap.SCOPE_SUBTREE, shaddr_filter, ['mail', 'shadowAddress',], ) exist_addrs = [] for (dn, entry) in qr: exist_addrs += entry.get('mail', []) + entry.get('shadowAddress', []) shadowAddresses = [ str(v).lower() for v in shadowAddresses if v not in exist_addrs ] except Exception, e: pass mod_attrs += [(ldap.MOD_REPLACE, 'shadowAddress', shadowAddresses)] elif self.profile_type == 'wblist': self.whitelistSender = [str(v) for v in data.get('whitelistSender', '').splitlines() if len(v) > 1] self.blacklistSender = [str(v) for v in data.get('blacklistSender', '').splitlines() if len(v) > 1] self.whitelistRecipient = [str(v) for v in data.get('whitelistRecipient', '').splitlines() if len(v) > 1] self.blacklistRecipient = [str(v) for v in data.get('blacklistRecipient', '').splitlines() if len(v) > 1] mod_attrs += [(ldap.MOD_REPLACE, 'amavisWhitelistSender', list(set(self.whitelistSender)))] mod_attrs += [(ldap.MOD_REPLACE, 'amavisBlacklistSender', list(set(self.blacklistSender)))] mod_attrs += [(ldap.MOD_REPLACE, 'mailWhitelistRecipient', list(set(self.whitelistRecipient)))] mod_attrs += [(ldap.MOD_REPLACE, 'mailBlacklistRecipient', list(set(self.blacklistRecipient)))] elif self.profile_type == 'password': # Get password length from @domainAccountSetting. minPasswordLength = domainAccountSetting.get('minPasswordLength', cfg.general.get('min_passwd_length', '0')) maxPasswordLength = domainAccountSetting.get('maxPasswordLength', cfg.general.get('max_passwd_length', '0')) # Get new passwords from user input. self.newpw = str(data.get('newpw', None)) self.confirmpw = str(data.get('confirmpw', None)) result = iredutils.verifyNewPasswords( newpw=self.newpw, confirmpw=self.confirmpw, min_passwd_length=minPasswordLength, max_passwd_length=maxPasswordLength, ) if result[0] is True: self.passwd = ldaputils.generatePasswd(result[1]) mod_attrs += [ (ldap.MOD_REPLACE, 'userPassword', self.passwd) ] else: return result elif self.profile_type == 'throttle': # # Policyd throttling integration. # self.senderThrottlingSetting = throttle.getSenderThrottlingSettingFromForm( account=self.mail, accountType='user', form=data, ) self.recipientThrottlingSetting = throttle.getRecipientThrottlingSettingFromForm( account=self.mail, accountType='user', form=data, ) throttleLib = throttle.Throttle() try: throttleLib.updateThrottlingSetting( account=self.mail, accountType='sender', setting=self.senderThrottlingSetting, ) throttleLib.updateThrottlingSetting( account=self.mail, accountType='recipient', setting=self.recipientThrottlingSetting, ) except Exception, e: pass elif self.profile_type == 'advanced': # Maildir. # Update storageBaseDirectory. if session.get('domainGlobalAdmin') is True: self.storageBaseDirectory = data.get('storageBaseDirectory', cfg.general.get('storage_base_directory')) mod_attrs += [(ldap.MOD_REPLACE, 'storageBaseDirectory', str(self.storageBaseDirectory))] # Update mailMessageStore. self.mailMessageStore = data.get('mailMessageStore', ) mod_attrs += [(ldap.MOD_REPLACE, 'mailMessageStore', str(self.mailMessageStore))] # BCC # Update recipient bcc address. self.userRecipientBccAddress = None self.userSenderBccAddress = None # Get value from web form. tmpUserRecipientBccAddress = data.get('recipientBccAddress', None) tmpUserSenderBccAddress = data.get('senderBccAddress', None) if iredutils.isEmail(tmpUserSenderBccAddress): self.userSenderBccAddress = web.safestr(tmpUserSenderBccAddress) if iredutils.isEmail(tmpUserRecipientBccAddress): self.userRecipientBccAddress = web.safestr(tmpUserRecipientBccAddress) mod_attrs += [(ldap.MOD_REPLACE, 'userSenderBccAddress', self.userSenderBccAddress)] mod_attrs += [(ldap.MOD_REPLACE, 'userRecipientBccAddress', self.userRecipientBccAddress)] # # ---- Relay/Transport ---- # # Get default transport setting. self.default_mtaTransport = str(cfg.general.get('mtaTransport', 'dovecot')) # Store current setting. self.transport = str(data.get('transport', self.default_mtaTransport)) if self.transport == '': # Remove attr. mod_attrs += [(ldap.MOD_REPLACE, 'mtaTransport', None)] elif self.transport != self.default_mtaTransport: mod_attrs += [(ldap.MOD_REPLACE, 'mtaTransport', self.transport)] else: pass # Enabled services. self.enabledService = [ str(v).lower() for v in data.get('enabledService') if v in attrs.USER_ENABLED_SERVICES ] # Append 'sieve', 'sievesecured' for dovecot-1.2. if 'managesieve' in self.enabledService: self.enabledService += ['sieve'] if 'managesievesecured' in self.enabledService: self.enabledService += ['sievesecured'] if len(self.enabledService) < 1: self.enabledService = None mod_attrs += [(ldap.MOD_REPLACE, 'enabledService', self.enabledService)] try: self.conn.modify_s(self.dn, mod_attrs) return (True,) except Exception, e: return (False, ldaputils.getExceptionDesc(e))