VirtualMailManager/VirtualMailManager.py
changeset 51 f5ca21303871
parent 50 927b0705d31a
child 52 c152d7714802
equal deleted inserted replaced
50:927b0705d31a 51:f5ca21303871
    42     def __init__(self):
    42     def __init__(self):
    43         """Creates a new VirtualMailManager instance.
    43         """Creates a new VirtualMailManager instance.
    44         Throws a VMMNotRootException if your uid is greater 0.
    44         Throws a VMMNotRootException if your uid is greater 0.
    45         """
    45         """
    46         self.__cfgFileName = '/usr/local/etc/vmm.cfg'
    46         self.__cfgFileName = '/usr/local/etc/vmm.cfg'
    47         self.__permWarnMsg = _(u"fix permissions for »%s«\n`chmod 0600 %s`\
    47         self.__permWarnMsg = _(u"fix permissions for »%(cfgFileName)s«\n\
    48  would be great.") % (self.__cfgFileName, self.__cfgFileName)
    48 `chmod 0600 %(cfgFileName)s` would be great.") % {'cfgFileName':
       
    49             self.__cfgFileName}
    49         self.__warnings = []
    50         self.__warnings = []
    50         self.__Cfg = None
    51         self.__Cfg = None
    51         self.__dbh = None
    52         self.__dbh = None
    52 
    53 
    53         if os.geteuid():
    54         if os.geteuid():
    87             raise VMMException(_(u'»%s« is not a directory.\n\
    88             raise VMMException(_(u'»%s« is not a directory.\n\
    88 (vmm.cfg: section "domdir", option "base")') %
    89 (vmm.cfg: section "domdir", option "base")') %
    89                 self.__Cfg.get('domdir', 'base'), ERR.NO_SUCH_DIRECTORY)
    90                 self.__Cfg.get('domdir', 'base'), ERR.NO_SUCH_DIRECTORY)
    90         for opt, val in self.__Cfg.items('bin'):
    91         for opt, val in self.__Cfg.items('bin'):
    91             if not os.path.exists(val):
    92             if not os.path.exists(val):
    92                 raise VMMException(_(u'»%s« doesn\'t exists.\n\
    93                 raise VMMException(_(u'»%(binary)s« doesn\'t exists.\n\
    93 (vmm.cfg: section "bin", option "%s")') %
    94 (vmm.cfg: section "bin", option "%(option)s")') %{'binary': val,'option': opt},
    94                     (val, opt), ERR.NO_SUCH_BINARY)
    95                     ERR.NO_SUCH_BINARY)
    95             elif not os.access(val, os.X_OK):
    96             elif not os.access(val, os.X_OK):
    96                 raise VMMException(_(u'»%s« is not executable.\n\
    97                 raise VMMException(_(u'»%(binary)s« is not executable.\n\
    97 (vmm.cfg: section "bin", option "%s")') %
    98 (vmm.cfg: section "bin", option "%(option)s")') %{'binary': val,'option': opt},
    98                     (val, opt), ERR.NOT_EXECUTABLE)
    99                     ERR.NOT_EXECUTABLE)
    99 
   100 
   100     def __dbConnect(self):
   101     def __dbConnect(self):
   101         """Creates a pyPgSQL.PgSQL.connection instance."""
   102         """Creates a pyPgSQL.PgSQL.connection instance."""
   102         try:
   103         try:
   103             self.__dbh = PgSQL.connect(
   104             self.__dbh = PgSQL.connect(
   127         ic = re.compile(RE_LOCALPART).findall(localpart)
   128         ic = re.compile(RE_LOCALPART).findall(localpart)
   128         if len(ic):
   129         if len(ic):
   129             ichrs = ''
   130             ichrs = ''
   130             for c in set(ic):
   131             for c in set(ic):
   131                 ichrs += u"»%s« " % c
   132                 ichrs += u"»%s« " % c
   132             raise VMMException(
   133             raise VMMException(_(u"The local part »%(lpart)s« contains invalid\
   133                 _(u"The local part »%s« contains invalid characters: %s") %
   134  characters: %(ichrs)s") % {'lpart': localpart, 'ichrs': ichrs},
   134                 (localpart, ichrs), ERR.LOCALPART_INVALID)
   135                 ERR.LOCALPART_INVALID)
   135         return localpart
   136         return localpart
   136     chkLocalpart = staticmethod(chkLocalpart)
   137     chkLocalpart = staticmethod(chkLocalpart)
   137 
   138 
   138     def idn2ascii(domainname):
   139     def idn2ascii(domainname):
   139         """Converts an idn domainname in punycode.
   140         """Converts an idn domainname in punycode.
   301             self.__makedir(folder, mode, uid, gid)
   302             self.__makedir(folder, mode, uid, gid)
   302             for subdir in subdirs:
   303             for subdir in subdirs:
   303                 self.__makedir(folder+'/'+subdir, mode, uid, gid)
   304                 self.__makedir(folder+'/'+subdir, mode, uid, gid)
   304         os.chdir(oldpwd)
   305         os.chdir(oldpwd)
   305 
   306 
   306     def __maildirdelete(self, domdir, uid, gid):
   307     def __userdirdelete(self, domdir, uid, gid):
   307         if uid > 0 and gid > 0:
   308         if uid > 0 and gid > 0:
   308             maildir = '%s' % uid
   309             userdir = '%s' % uid
   309             if maildir.count('..') or domdir.count('..'):
   310             if userdir.count('..') or domdir.count('..'):
   310                 raise VMMException(_(u'Found ".." in maildir path.'),
   311                 raise VMMException(_(u'Found ".." in home directory path.'),
   311                     ERR.FOUND_DOTS_IN_PATH)
   312                     ERR.FOUND_DOTS_IN_PATH)
   312             if os.path.isdir(domdir):
   313             if os.path.isdir(domdir):
   313                 os.chdir(domdir)
   314                 os.chdir(domdir)
   314                 if os.path.isdir(maildir):
   315                 if os.path.isdir(userdir):
   315                     mdstat = os.stat(maildir)
   316                     mdstat = os.stat(userdir)
   316                     if (mdstat.st_uid, mdstat.st_gid) != (uid, gid):
   317                     if (mdstat.st_uid, mdstat.st_gid) != (uid, gid):
   317                         raise VMMException(
   318                         raise VMMException(
   318                           _(u'Owner/group mismatch in maildir detected.'),
   319                          _(u'Owner/group mismatch in home directory detected.'),
   319                           ERR.MAILDIR_PERM_MISMATCH)
   320                          ERR.MAILDIR_PERM_MISMATCH)
   320                     rmtree(maildir, ignore_errors=True)
   321                     rmtree(userdir, ignore_errors=True)
   321                 else:
   322                 else:
   322                     raise VMMException(_(u"No such directory: %s/%s") %
   323                     raise VMMException(_(u"No such directory: %s") %
   323                         (domdir, uid), ERR.NO_SUCH_DIRECTORY)
   324                         domdir+'/'+userdir, ERR.NO_SUCH_DIRECTORY)
   324 
   325 
   325     def __domdirdelete(self, domdir, gid):
   326     def __domdirdelete(self, domdir, gid):
   326         if gid > 0:
   327         if gid > 0:
   327             if not self.__isdir(domdir):
   328             if not self.__isdir(domdir):
   328                 return
   329                 return
   557         uid = acc.getUID()
   558         uid = acc.getUID()
   558         gid = acc.getGID()
   559         gid = acc.getGID()
   559         acc.delete()
   560         acc.delete()
   560         if self.__Cfg.getboolean('maildir', 'delete'):
   561         if self.__Cfg.getboolean('maildir', 'delete'):
   561             try:
   562             try:
   562                 self.__maildirdelete(acc.getDir('domain'), uid, gid)
   563                 self.__userdirdelete(acc.getDir('domain'), uid, gid)
   563             except VMMException, e:
   564             except VMMException, e:
   564                 if e.code() in [ERR.FOUND_DOTS_IN_PATH,
   565                 if e.code() in [ERR.FOUND_DOTS_IN_PATH,
   565                         ERR.MAILDIR_PERM_MISMATCH, ERR.NO_SUCH_DIRECTORY]:
   566                         ERR.MAILDIR_PERM_MISMATCH, ERR.NO_SUCH_DIRECTORY]:
   566                     warning = _(u"""\
   567                     warning = _(u"""\
   567 The account has been successfully deleted from the database.
   568 The account has been successfully deleted from the database.
   568     But an error occurred while deleting the following directory:
   569     But an error occurred while deleting the following directory:
   569     »%s«
   570     »%(directory)s«
   570     Reason: %s""") % (acc.getDir('home'), e.msg())
   571     Reason: %(raeson)s""") % {'directory': acc.getDir('home'),'raeson': e.msg()}
   571                     self.__warnings.append(warning)
   572                     self.__warnings.append(warning)
   572                 else:
   573                 else:
   573                     raise e
   574                     raise e
   574 
   575 
   575     def alias_info(self, aliasaddress):
   576     def alias_info(self, aliasaddress):