81 else: |
81 else: |
82 return True |
82 return True |
83 |
83 |
84 def __chkenv(self): |
84 def __chkenv(self): |
85 """""" |
85 """""" |
86 if not os.path.exists(self.__Cfg.get('misc', 'base_dir')): |
86 basedir = self.__Cfg.get('misc', 'base_directory') |
|
87 if not os.path.exists(basedir): |
87 old_umask = os.umask(0006) |
88 old_umask = os.umask(0006) |
88 os.makedirs(self.__Cfg.get('misc', 'base_dir'), 0771) |
89 os.makedirs(basedir, 0771) |
89 os.chown(self.__Cfg.get('misc', 'base_dir'), 0, |
90 os.chown(basedir, 0, self.__Cfg.getint('misc', 'gid_mail')) |
90 self.__Cfg.getint('misc', 'gid_mail')) |
|
91 os.umask(old_umask) |
91 os.umask(old_umask) |
92 elif not os.path.isdir(self.__Cfg.get('misc', 'base_dir')): |
92 elif not os.path.isdir(basedir): |
93 raise VMMException(_(u'“%s” is not a directory.\n\ |
93 raise VMMException(_(u'“%s” is not a directory.\n\ |
94 (vmm.cfg: section "misc", option "base_dir")') % |
94 (vmm.cfg: section "misc", option "base_directory")') % |
95 self.__Cfg.get('misc', 'base_dir'), ERR.NO_SUCH_DIRECTORY) |
95 basedir, ERR.NO_SUCH_DIRECTORY) |
96 for opt, val in self.__Cfg.items('bin'): |
96 for opt, val in self.__Cfg.items('bin'): |
97 if not os.path.exists(val): |
97 if not os.path.exists(val): |
98 raise VMMException(_(u'“%(binary)s” doesn\'t exist.\n\ |
98 raise VMMException(_(u'“%(binary)s” doesn\'t exist.\n\ |
99 (vmm.cfg: section "bin", option "%(option)s")') %{'binary': val,'option': opt}, |
99 (vmm.cfg: section "bin", option "%(option)s")') %{'binary': val,'option': opt}, |
100 ERR.NO_SUCH_BINARY) |
100 ERR.NO_SUCH_BINARY) |
235 def __getDomain(self, domainname, transport=None): |
235 def __getDomain(self, domainname, transport=None): |
236 if transport is None: |
236 if transport is None: |
237 transport = self.__Cfg.get('misc', 'transport') |
237 transport = self.__Cfg.get('misc', 'transport') |
238 self.__dbConnect() |
238 self.__dbConnect() |
239 return Domain(self.__dbh, domainname, |
239 return Domain(self.__dbh, domainname, |
240 self.__Cfg.get('misc', 'base_dir'), transport) |
240 self.__Cfg.get('misc', 'base_directory'), transport) |
241 |
241 |
242 def __getDiskUsage(self, directory): |
242 def __getDiskUsage(self, directory): |
243 """Estimate file space usage for the given directory. |
243 """Estimate file space usage for the given directory. |
244 |
244 |
245 Keyword arguments: |
245 Keyword arguments: |
268 os.chown(directory, uid, gid) |
268 os.chown(directory, uid, gid) |
269 |
269 |
270 def __domDirMake(self, domdir, gid): |
270 def __domDirMake(self, domdir, gid): |
271 os.umask(0006) |
271 os.umask(0006) |
272 oldpwd = os.getcwd() |
272 oldpwd = os.getcwd() |
273 basedir = self.__Cfg.get('misc', 'base_dir') |
273 basedir = self.__Cfg.get('misc', 'base_directory') |
274 domdirdirs = domdir.replace(basedir+'/', '').split('/') |
274 domdirdirs = domdir.replace(basedir+'/', '').split('/') |
275 |
275 |
276 os.chdir(basedir) |
276 os.chdir(basedir) |
277 if not os.path.isdir(domdirdirs[0]): |
277 if not os.path.isdir(domdirdirs[0]): |
278 self.__makedir(domdirdirs[0], 489, 0, |
278 self.__makedir(domdirdirs[0], 489, 0, |
346 |
346 |
347 def __domDirDelete(self, domdir, gid): |
347 def __domDirDelete(self, domdir, gid): |
348 if gid > 0: |
348 if gid > 0: |
349 if not self.__isdir(domdir): |
349 if not self.__isdir(domdir): |
350 return |
350 return |
351 basedir = self.__Cfg.get('misc', 'base_dir') |
351 basedir = self.__Cfg.get('misc', 'base_directory') |
352 domdirdirs = domdir.replace(basedir+'/', '').split('/') |
352 domdirdirs = domdir.replace(basedir+'/', '').split('/') |
353 domdirparent = os.path.join(basedir, domdirdirs[0]) |
353 domdirparent = os.path.join(basedir, domdirdirs[0]) |
354 if basedir.count('..') or domdir.count('..'): |
354 if basedir.count('..') or domdir.count('..'): |
355 raise VMMException(_(u'Found ".." in domain directory path.'), |
355 raise VMMException(_(u'Found ".." in domain directory path.'), |
356 ERR.FOUND_DOTS_IN_PATH) |
356 ERR.FOUND_DOTS_IN_PATH) |
485 raise VMMDomainException(_(u"Invalid argument: “%s”") % force, |
485 raise VMMDomainException(_(u"Invalid argument: “%s”") % force, |
486 ERR.INVALID_OPTION) |
486 ERR.INVALID_OPTION) |
487 dom = self.__getDomain(domainname) |
487 dom = self.__getDomain(domainname) |
488 gid = dom.getID() |
488 gid = dom.getID() |
489 domdir = dom.getDir() |
489 domdir = dom.getDir() |
490 if self.__Cfg.getboolean('domain', 'force_del') or force == 'delall': |
490 if self.__Cfg.getboolean('domain', 'force_deletion')\ |
|
491 or force == 'delall': |
491 dom.delete(True, True) |
492 dom.delete(True, True) |
492 elif force == 'deluser': |
493 elif force == 'deluser': |
493 dom.delete(delUser=True) |
494 dom.delete(delUser=True) |
494 elif force == 'delalias': |
495 elif force == 'delalias': |
495 dom.delete(delAlias=True) |
496 dom.delete(delAlias=True) |
587 acc = self.__getAccount(emailaddress, password) |
588 acc = self.__getAccount(emailaddress, password) |
588 if password is None: |
589 if password is None: |
589 password = self._readpass() |
590 password = self._readpass() |
590 acc.setPassword(self.__pwhash(password)) |
591 acc.setPassword(self.__pwhash(password)) |
591 acc.save(self.__Cfg.get('maildir', 'name'), |
592 acc.save(self.__Cfg.get('maildir', 'name'), |
592 self.__Cfg.getint('misc', 'dovecot_vers'), |
593 self.__Cfg.getint('misc', 'dovecot_version'), |
593 self.__Cfg.getboolean('account', 'smtp'), |
594 self.__Cfg.getboolean('account', 'smtp'), |
594 self.__Cfg.getboolean('account', 'pop3'), |
595 self.__Cfg.getboolean('account', 'pop3'), |
595 self.__Cfg.getboolean('account', 'imap'), |
596 self.__Cfg.getboolean('account', 'imap'), |
596 self.__Cfg.getboolean('account', 'sieve')) |
597 self.__Cfg.getboolean('account', 'sieve')) |
597 self.__mailDirMake(acc.getDir('domain'), acc.getUID(), acc.getGID()) |
598 self.__mailDirMake(acc.getDir('domain'), acc.getUID(), acc.getGID()) |
641 def userInfo(self, emailaddress, details=None): |
642 def userInfo(self, emailaddress, details=None): |
642 if details not in [None, 'du', 'aliases', 'full']: |
643 if details not in [None, 'du', 'aliases', 'full']: |
643 raise VMMException(_(u'Invalid argument: “%s”') % details, |
644 raise VMMException(_(u'Invalid argument: “%s”') % details, |
644 ERR.INVALID_AGUMENT) |
645 ERR.INVALID_AGUMENT) |
645 acc = self.__getAccount(emailaddress) |
646 acc = self.__getAccount(emailaddress) |
646 info = acc.getInfo(self.__Cfg.getint('misc', 'dovecot_vers')) |
647 info = acc.getInfo(self.__Cfg.getint('misc', 'dovecot_version')) |
647 if self.__Cfg.getboolean('account', 'disk_usage')\ |
648 if self.__Cfg.getboolean('account', 'disk_usage')\ |
648 or details in ['du', 'full']: |
649 or details in ['du', 'full']: |
649 info['disk usage'] = self.__getDiskUsage('%(maildir)s' % info) |
650 info['disk usage'] = self.__getDiskUsage('%(maildir)s' % info) |
650 if details in [None, 'du']: |
651 if details in [None, 'du']: |
651 return info |
652 return info |
680 self.__warnings.append(_(u'\ |
681 self.__warnings.append(_(u'\ |
681 The service name “managesieve” is deprecated and will be removed\n\ |
682 The service name “managesieve” is deprecated and will be removed\n\ |
682 in a future release.\n\ |
683 in a future release.\n\ |
683 Please use the service name “sieve” instead.')) |
684 Please use the service name “sieve” instead.')) |
684 acc = self.__getAccount(emailaddress) |
685 acc = self.__getAccount(emailaddress) |
685 acc.disable(self.__Cfg.getint('misc', 'dovecot_vers'), service) |
686 acc.disable(self.__Cfg.getint('misc', 'dovecot_version'), service) |
686 |
687 |
687 def userEnable(self, emailaddress, service=None): |
688 def userEnable(self, emailaddress, service=None): |
688 if service == 'managesieve': |
689 if service == 'managesieve': |
689 service = 'sieve' |
690 service = 'sieve' |
690 self.__warnings.append(_(u'\ |
691 self.__warnings.append(_(u'\ |
691 The service name “managesieve” is deprecated and will be removed\n\ |
692 The service name “managesieve” is deprecated and will be removed\n\ |
692 in a future release.\n\ |
693 in a future release.\n\ |
693 Please use the service name “sieve” instead.')) |
694 Please use the service name “sieve” instead.')) |
694 acc = self.__getAccount(emailaddress) |
695 acc = self.__getAccount(emailaddress) |
695 acc.enable(self.__Cfg.getint('misc', 'dovecot_vers'), service) |
696 acc.enable(self.__Cfg.getint('misc', 'dovecot_version'), service) |
696 |
697 |
697 def relocatedAdd(self, emailaddress, targetaddress): |
698 def relocatedAdd(self, emailaddress, targetaddress): |
698 relocated = self.__getRelocated(emailaddress, targetaddress) |
699 relocated = self.__getRelocated(emailaddress, targetaddress) |
699 relocated.save() |
700 relocated.save() |
700 |
701 |