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 |