VirtualMailManager/handler.py
branchv0.6.x
changeset 327 bb9ff81928f1
parent 325 06c0457036a0
child 329 41789df75339
equal deleted inserted replaced
326:8f8d9c4c8332 327:bb9ff81928f1
    12    or deletes directories of domains or users.
    12    or deletes directories of domains or users.
    13 """
    13 """
    14 
    14 
    15 import os
    15 import os
    16 import re
    16 import re
    17 import stat
       
    18 
    17 
    19 from shutil import rmtree
    18 from shutil import rmtree
    20 from subprocess import Popen, PIPE
    19 from subprocess import Popen, PIPE
    21 
    20 
    22 from pyPgSQL import PgSQL  # python-pgsql - http://pypgsql.sourceforge.net
    21 from pyPgSQL import PgSQL  # python-pgsql - http://pypgsql.sourceforge.net
    23 
    22 
    24 from VirtualMailManager.account import Account
    23 from VirtualMailManager.account import Account
    25 from VirtualMailManager.alias import Alias
    24 from VirtualMailManager.alias import Alias
    26 from VirtualMailManager.aliasdomain import AliasDomain
    25 from VirtualMailManager.aliasdomain import AliasDomain
    27 from VirtualMailManager.common import exec_ok
    26 from VirtualMailManager.common import exec_ok, lisdir
    28 from VirtualMailManager.config import Config as Cfg
    27 from VirtualMailManager.config import Config as Cfg
    29 from VirtualMailManager.constants import MIN_GID, MIN_UID, \
    28 from VirtualMailManager.constants import MIN_GID, MIN_UID, \
    30      ACCOUNT_EXISTS, ALIAS_EXISTS, CONF_NOFILE, CONF_NOPERM, CONF_WRONGPERM, \
    29      ACCOUNT_EXISTS, ALIAS_EXISTS, CONF_NOFILE, CONF_NOPERM, CONF_WRONGPERM, \
    31      DATABASE_ERROR, DOMAINDIR_GROUP_MISMATCH, DOMAIN_INVALID, \
    30      DATABASE_ERROR, DOMAINDIR_GROUP_MISMATCH, DOMAIN_INVALID, \
    32      FOUND_DOTS_IN_PATH, INVALID_ARGUMENT, MAILDIR_PERM_MISMATCH, \
    31      FOUND_DOTS_IN_PATH, INVALID_ARGUMENT, MAILDIR_PERM_MISMATCH, \
   117 
   116 
   118     def _chkenv(self):
   117     def _chkenv(self):
   119         """Make sure our base_directory is a directory and that all
   118         """Make sure our base_directory is a directory and that all
   120         required executables exists and are executable.
   119         required executables exists and are executable.
   121         If not, a VMMError will be raised"""
   120         If not, a VMMError will be raised"""
       
   121         dir_created = False
   122         basedir = self._cfg.dget('misc.base_directory')
   122         basedir = self._cfg.dget('misc.base_directory')
   123         if not os.path.exists(basedir):
   123         if not os.path.exists(basedir):
   124             old_umask = os.umask(0006)
   124             old_umask = os.umask(0006)
   125             os.makedirs(basedir, 0771)
   125             os.makedirs(basedir, 0771)
   126             os.chown(basedir, 0, 0)
   126             os.chown(basedir, 0, 0)
   127             os.umask(old_umask)
   127             os.umask(old_umask)
   128         elif not os.path.isdir(basedir):
   128             dir_created = True
       
   129         if not dir_created and not lisdir(basedir):
   129             raise VMMError(_(u"'%(path)s' is not a directory.\n(%(cfg_file)s: "
   130             raise VMMError(_(u"'%(path)s' is not a directory.\n(%(cfg_file)s: "
   130                              u"section 'misc', option 'base_directory')") %
   131                              u"section 'misc', option 'base_directory')") %
   131                            {'path': basedir, 'cfg_file': self._cfg_fname},
   132                            {'path': basedir, 'cfg_file': self._cfg_fname},
   132                            NO_SUCH_DIRECTORY)
   133                            NO_SUCH_DIRECTORY)
   133         for opt, val in self._cfg.items('bin'):
   134         for opt, val in self._cfg.items('bin'):
   232         Arguments:
   233         Arguments:
   233 
   234 
   234         `directory` : basestring
   235         `directory` : basestring
   235           The directory to summarize recursively disk usage for
   236           The directory to summarize recursively disk usage for
   236         """
   237         """
   237         if os.path.isdir(directory):
   238         if lisdir(directory):
   238             return Popen([self._cfg.dget('bin.du'), "-hs", directory],
   239             return Popen([self._cfg.dget('bin.du'), "-hs", directory],
   239                          stdout=PIPE).communicate()[0].split('\t')[0]
   240                          stdout=PIPE).communicate()[0].split('\t')[0]
   240         else:
   241         else:
   241             self._warnings.append(_('No such directory: %s') % directory)
   242             self._warnings.append(_('No such directory: %s') % directory)
   242             return 0
   243             return 0
   243 
   244 
   244     def _make_domain_dir(self, domain):
   245     def _make_domain_dir(self, domain):
   245         """Create a directory for the `domain` and its accounts."""
   246         """Create a directory for the `domain` and its accounts."""
   246         cwd = os.getcwd()
   247         cwd = os.getcwd()
   247         hashdir, domdir = domain.directory.split(os.path.sep)[-2:]
   248         hashdir, domdir = domain.directory.split(os.path.sep)[-2:]
       
   249         dir_created = False
   248         os.chdir(self._cfg.dget('misc.base_directory'))
   250         os.chdir(self._cfg.dget('misc.base_directory'))
   249         if not os.path.isdir(hashdir):
   251         if not os.path.exists(hashdir):
   250             os.mkdir(hashdir, 0711)
   252             os.mkdir(hashdir, 0711)
   251             os.chown(hashdir, 0, 0)
   253             os.chown(hashdir, 0, 0)
       
   254             dir_created = True
       
   255         if not dir_created and not lisdir(hashdir):
       
   256             raise VMMError(_(u"'%s' is not a directory.") % hashdir,
       
   257                            NO_SUCH_DIRECTORY)
   252         os.mkdir(os.path.join(hashdir, domdir),
   258         os.mkdir(os.path.join(hashdir, domdir),
   253                  self._cfg.dget('domain.directory_mode'))
   259                  self._cfg.dget('domain.directory_mode'))
   254         os.chown(domain.directory, 0, domain.gid)
   260         os.chown(domain.directory, 0, domain.gid)
   255         os.chdir(cwd)
   261         os.chdir(cwd)
   256 
   262 
   257     def _make_home(self, account):
   263     def _make_home(self, account):
   258         """Create a home directory for the new Account *account*."""
   264         """Create a home directory for the new Account *account*."""
       
   265         domdir = account.domain_directory
       
   266         if not lisdir(domdir):
       
   267             raise VMMError(_(u"No such directory: %s") % domdir,
       
   268                            NO_SUCH_DIRECTORY)
   259         os.umask(0007)
   269         os.umask(0007)
   260         os.chdir(account.domain_directory)
   270         uid = account.uid
   261         os.mkdir('%s' % account.uid, self._cfg.dget('account.directory_mode'))
   271         os.chdir(domdir)
   262         os.chown('%s' % account.uid, account.uid, account.gid)
   272         os.mkdir('%s' % uid, self._cfg.dget('account.directory_mode'))
       
   273         os.chown('%s' % uid, uid, account.gid)
   263 
   274 
   264     def _delete_home(self, domdir, uid, gid):
   275     def _delete_home(self, domdir, uid, gid):
   265         """Delete a user's home directory.
   276         """Delete a user's home directory.
   266 
   277 
   267         Arguments:
   278         Arguments:
   282                            'gid': gid, 'min_gid': MIN_GID, 'min_uid': MIN_UID},
   293                            'gid': gid, 'min_gid': MIN_GID, 'min_uid': MIN_UID},
   283                            MAILDIR_PERM_MISMATCH)
   294                            MAILDIR_PERM_MISMATCH)
   284         if domdir.count('..'):
   295         if domdir.count('..'):
   285             raise VMMError(_(u'Found ".." in domain directory path: %s') %
   296             raise VMMError(_(u'Found ".." in domain directory path: %s') %
   286                            domdir, FOUND_DOTS_IN_PATH)
   297                            domdir, FOUND_DOTS_IN_PATH)
   287         if not os.path.isdir(domdir):
   298         if not lisdir(domdir):
   288             raise VMMError(_(u"No such directory: %s") % domdir,
   299             raise VMMError(_(u"No such directory: %s") % domdir,
   289                            NO_SUCH_DIRECTORY)
   300                            NO_SUCH_DIRECTORY)
   290         os.chdir(domdir)
   301         os.chdir(domdir)
   291         userdir = '%s' % uid
   302         userdir = '%s' % uid
   292         if not os.path.isdir(userdir):
   303         if not lisdir(userdir):
   293             self._warnings.append(_(u"No such directory: %s") %
   304             self._warnings.append(_(u"No such directory: %s") %
   294                                   os.path.join(domdir, userdir))
   305                                   os.path.join(domdir, userdir))
   295             return
   306             return
   296         mdstat = os.lstat(userdir)
   307         mdstat = os.lstat(userdir)
   297         if (mdstat.st_uid, mdstat.st_gid) != (uid, gid):
   308         if (mdstat.st_uid, mdstat.st_gid) != (uid, gid):
   315                            {'gid': gid, 'min_gid': MIN_GID},
   326                            {'gid': gid, 'min_gid': MIN_GID},
   316                            DOMAINDIR_GROUP_MISMATCH)
   327                            DOMAINDIR_GROUP_MISMATCH)
   317         if domdir.count('..'):
   328         if domdir.count('..'):
   318             raise VMMError(_(u'Found ".." in domain directory path: %s') %
   329             raise VMMError(_(u'Found ".." in domain directory path: %s') %
   319                            domdir, FOUND_DOTS_IN_PATH)
   330                            domdir, FOUND_DOTS_IN_PATH)
   320         try:
   331         if not lisdir(domdir):
   321             dirst = os.lstat(domdir)
       
   322         except OSError:
       
   323             dirst = None
       
   324         if not dirst or not stat.S_ISDIR(dirst.st_mode):
       
   325             self._warnings.append(_('No such directory: %s') % domdir)
   332             self._warnings.append(_('No such directory: %s') % domdir)
   326             return
   333             return
       
   334         dirst = os.lstat(domdir)
   327         if dirst.st_gid != gid:
   335         if dirst.st_gid != gid:
   328             raise VMMError(_(u'Detected group mismatch in domain directory: '
   336             raise VMMError(_(u'Detected group mismatch in domain directory: '
   329                              u'%s') % domdir, DOMAINDIR_GROUP_MISMATCH)
   337                              u'%s') % domdir, DOMAINDIR_GROUP_MISMATCH)
   330         rmtree(domdir, ignore_errors=True)
   338         rmtree(domdir, ignore_errors=True)
   331 
   339