def saveDomains(self, domains): from modules.domain import Domain, DomainList domainList = DomainList() for f in domains['_items']: domainList.add(Domain.fromDict(f)) log.debug('Want to save %i domains' % (len(domainList),)) for domain in domainList: # get the old domain oldDomain = None if domain.state != Domain.STATE_CREATE: oldDomain = Domain(domain.id) oldDomain.load() domain.save(oldDomain) # check if corresponding dns file exists. if conf.getboolean('dns', 'active'): fqdn = domain.getFullDomain() fileName = '%s.db' % (fqdn,) path = os.path.join(conf.get('dns', 'cache'), fileName) if domain.state != Domain.STATE_DELETE: if not os.path.exists(path): try: with open(path, 'wb') as f: f.write('\n'.encode('utf-8')) except: pass else: self.__addZoneFile(domain, path) else: self.__addZoneFile(domain, path) else: self.__removeZoneFile(domain, path)
def getDomainZoneFile(self, domainId): from modules.domain import Domain content = '' d = Domain(domainId) if not d.load(): log.warning('Could not get the domain %s' % (domainId,)) return content content = d.generateBindFile() log.debug('Generated the domain bind file for domain %s' % (domainId,)) return content
def saveDns(self, domain, dns): from modules.domain import Domain dnsList = DNSList() for f in dns['_items']: dnsList.add(Dns.fromDict(f)) log.debug('Want to save %i dns items!' % (len(dnsList),)) for d in dnsList: d.save() if domain is not None and (type(domain) == int or len(domain.strip()) > 0) and conf.getboolean('dns', 'active'): content = self.getDomainZoneFile(domain) # now we need the Domain dom = Domain(domain) if not dom.load(): log.warning('Could not load the domain %s for generating zone file!' % (domain,)) return False # we need the fully qualified domain name! fqdn = dom.getFullDomain() # now try to save it! fileName = '%s.db' % (fqdn,) path = os.path.join(conf.get('dns', 'cache'), fileName) addToZoneFile = False if not os.path.exists(path): addToZoneFile = True try: with open(path, 'wb') as f: f.write(content.encode('utf-8')) except Exception as e: log.warning('Could not update the database file for the DNS-Service because of %s' % (str(e),)) else: log.info('Update the DNS-Service-Database %s' % (os.path.join(conf.get('dns', 'cache'), fileName),)) if addToZoneFile: self.__addZoneFile(path) # reload try: reloadDns() except Exception as e: log.critical('Could not reload the DNS-Service because of %s!' % (str(e),)) else: log.info('DNS-Service reloaded with success!') return True
def create(self): log = logging.getLogger('flscp') # create: # 1. update mail_users # 2. update credentials, if given # 3. update /etc/postfix/fls/mailboxes # 4. update aliases # 5. update sender-access (we could later be implement to restrict sending!) # postmap all relevant entries if self.exists(): # already exists! raise KeyError('Mail "%s@%s" already exists!' % (self.mail, self.domain)) # get domain id! (if not exist: create!) try: d = Domain.getByName(self.domain) except KeyError: raise # pw entered? if len(self.pw.strip()) > 0: self.hashPassword() db = MailDatabase.getInstance() cx = db.getCursor() query = ( 'INSERT INTO mail_users (mail_acc, mail_pass, mail_forward, domain_id, mail_type, status, quota, mail_addr, alternative_addr, enabled) ' \ 'VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)' ) cx.execute( query, ( self.mail, self.hashPw, ','.join(self.forward), d.id, self.type, self.state, self.quota, '%s@%s' % (self.mail, self.domain), self.altMail, str(int(self.enabled)) ) ) db.commit() log.debug('executed mysql statement: %s' % (cx.statement,)) id = cx.lastrowid if id is None: cx.close() return False else: self.id = id # update credentials... self.updateCredentials() # now update mailboxes files! if not self.updateMailboxes(): cx.close() return False # update aliases if not self.updateAliases(): # remove entry from updateMailboxes? cx.close() return False # update sender-access if not self.updateSenderAccess(): # remove entry from updateMailboxes and Aliases ? cx.close() return False cx.close() # all best? Than go forward and update set state,... self.setState(MailAccount.STATE_OK) # notify if len(self.altMail) > 0: m = Mailer(self) state = False if self.type == MailAccount.TYPE_ACCOUNT \ or self.type == MailAccount.TYPE_FWDSMTP: state = m.newAccount() else: state = m.newForward() if state: log.info('User is notified about account change!') else: log.warning('Unknown error while notifying user!') else: log.info('User is not notified because we have no address of him!') # reset info self.pw = '' self.hashPw = '' self.genPw = False
def save(self): log = logging.getLogger('flscp') conf = FLSConfig.getInstance() if self.state == MailAccount.STATE_CREATE: self.create() return elif self.state == MailAccount.STATE_DELETE: self.delete() return elif self.state == MailAccount.STATE_QUOTA: self.recalculateQuota() return # now save! # -> see create - but if key changed (mail address!) remove # all entries before and rename folder in /var/mail,... directory # get original data! if not self.exists(): self.create() # get domain id! (if not exist: create!) try: d = Domain.getByName(self.domain) except KeyError: raise # pw entered? if len(self.pw.strip()) > 0: log.info('Hash password for user %s' % (self.mail,)) self.hashPassword() db = MailDatabase.getInstance() cx = db.getCursor() query = ('SELECT mail_id, mail_addr, mail_type FROM mail_users WHERE mail_id = %s') cx.execute(query, (self.id,)) (mail_id, mail_addr, mail_type) = cx.fetchone() (mail, domain) = mail_addr.split('@') cx.close() cx = db.getCursor() if (self.type == MailAccount.TYPE_ACCOUNT and self.hashPw != '') \ or (self.type == MailAccount.TYPE_FWDSMTP and self.hashPw != '') \ or self.type == MailAccount.TYPE_FORWARD: query = ( 'UPDATE mail_users SET mail_acc = %s, mail_pass = %s, mail_forward = %s, ' \ 'domain_id = %s, mail_type = %s, status = %s, quota = %s, mail_addr = %s, ' \ 'alternative_addr = %s, enabled = %s WHERE mail_id = %s' ) params = ( self.mail, self.hashPw, ','.join(self.forward), d.id, self.type, self.state, self.quota, '%s@%s' % (self.mail, self.domain), self.altMail, str(int(self.enabled)), self.id ) else: query = ( 'UPDATE mail_users SET mail_acc = %s, mail_forward = %s, ' \ 'domain_id = %s, mail_type = %s, status = %s, quota = %s, mail_addr = %s, ' \ 'alternative_addr = %s, enabled = %s WHERE mail_id = %s' ) params = ( self.mail, ','.join(self.forward), d.id, self.type, self.state, self.quota, '%s@%s' % (self.mail, self.domain), self.altMail, str(int(self.enabled)), self.id ) cx.execute( query, params ) db.commit() log.debug('executed mysql statement: %s' % (cx.statement,)) # update credentials... # if pw was entered or type changed if mail_type != self.type or self.pw.strip() != '': self.updateCredentials() # now update mailboxes files! if not self.updateMailboxes(oldMail=mail, oldDomain=domain): cx.close() return False # update aliases if not self.updateAliases(oldMail=mail, oldDomain=domain): # remove entry from updateMailboxes? cx.close() return False # update sender-access if not self.updateSenderAccess(oldMail=mail, oldDomain=domain): # remove entry from updateMailboxes and Aliases ? cx.close() return False # rename folders - but only if target directory does not exist # (we had to throw fatal error if target directory exists!) oldPath = '%s/%s/%s/' % (conf.get('mailserver', 'basemailpath'), domain, mail) path = '%s/%s/%s/' % (conf.get('mailserver', 'basemailpath'), self.domain, self.mail) if os.path.exists(oldPath): if os.path.exists(path): log.error('Could not move "%s" to "%s", because it already exists!' % (path,)) else: try: os.rename(oldPath, path) except OSError as e: log.warning('Got OSError - Does directory exists? (%s)' % (e,)) except Exception as e: log.warning('Got unexpected exception (%s)!' % (e,)) cx.close() # all best? Than go forward and update set state,... self.setState(MailAccount.STATE_OK) # notify if len(self.altMail) > 0: m = Mailer(self) state = False if self.type == MailAccount.TYPE_ACCOUNT \ or self.type == MailAccount.TYPE_FWDSMTP: state = m.changeAccount() else: state = m.changeForward() if state: log.info('User is notified about account change!') else: log.warning('Unknown error while notifying user!') else: log.info('User is not notified because we have no address of him!') # reset info self.pw = '' self.hashPw = '' self.genPw = False