Example #1
0
	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)
Example #2
0
	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
Example #3
0
	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
Example #4
0
	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
Example #5
0
	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