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): |