add delete-userfiles flag for Domain.delete() to remove email-account data on the filesystem (if any); fixes #1239

Signed-off-by: Michael Kaufmann <d00p@froxlor.org>
This commit is contained in:
Michael Kaufmann
2024-04-28 13:49:07 +02:00
parent 7d99244b9d
commit d6b8eb08c0
8 changed files with 23 additions and 37 deletions

View File

@@ -2098,6 +2098,8 @@ class Domains extends ApiCommand implements ResourceEntity
* @param bool $is_stdsubdomain
* optional, default false, specify whether it's a std-subdomain you are deleting as it does not count
* as subdomain-resource
* @param bool $delete_userfiles
* optional, delete email account files on filesystem (if any), default false
*
* @access admin
* @return string json-encoded array
@@ -2109,7 +2111,8 @@ class Domains extends ApiCommand implements ResourceEntity
$id = $this->getParam('id', true, 0);
$dn_optional = $id > 0;
$domainname = $this->getParam('domainname', $dn_optional, '');
$is_stdsubdomain = $this->getParam('is_stdsubdomain', true, 0);
$is_stdsubdomain = $this->getBoolParam('is_stdsubdomain', true, 0);
$delete_user_emailfiles = $this->getBoolParam('delete_userfiles', true, 0);
$result = $this->apiCall('Domains.get', [
'id' => $id,
@@ -2133,6 +2136,14 @@ class Domains extends ApiCommand implements ResourceEntity
$idString = implode(' OR ', $idString);
if ($idString != '') {
if ($delete_user_emailfiles) {
// determine all connected email-accounts
$emailaccount_sel = Database::prepare("SELECT `email`, `homedir`, `maildir` FROM `" . TABLE_MAIL_USERS . "` WHERE " . $idString);
Database::pexecute($emailaccount_sel, $paramString, true, true);
while ($emailacc_row = $emailaccount_sel->fetch(PDO::FETCH_ASSOC)) {
Cronjob::inserttask(TaskId::DELETE_EMAIL_DATA, $emailacc_row['email'], FileDir::makeCorrectDir($emailacc_row['homedir'] . '/' . $emailacc_row['maildir']));
}
}
$del_stmt = Database::prepare("
DELETE FROM `" . TABLE_MAIL_USERS . "` WHERE " . $idString);
Database::pexecute($del_stmt, $paramString, true, true);

View File

@@ -563,7 +563,7 @@ class EmailAccounts extends ApiCommand implements ResourceEntity
}
if ($delete_userfiles) {
Cronjob::inserttask(TaskId::DELETE_EMAIL_DATA, $customer['loginname'], $result['email_full']);
Cronjob::inserttask(TaskId::DELETE_EMAIL_DATA, $customer['loginname'], FileDir::makeCorrectDir($result['homedir'] . '/' . $result['maildir']));
}
// decrease usage for customer

View File

@@ -348,24 +348,16 @@ class TasksCron extends FroxlorCron
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, 'TasksCron: Task7 started - deleting customer e-mail data');
if (is_array($row['data'])) {
if (isset($row['data']['loginname']) && isset($row['data']['email'])) {
if (isset($row['data']['loginname']) && isset($row['data']['emailpath'])) {
// remove specific maildir
$email_full = $row['data']['email'];
$email_full = $row['data']['emailpath'];
if (empty($email_full)) {
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, 'FATAL: Task7 asks to delete a email account but email field is empty!');
}
$email_user = substr($email_full, 0, strrpos($email_full, "@"));
$email_domain = substr($email_full, strrpos($email_full, "@") + 1);
$maildirname = trim(Settings::Get('system.vmail_maildirname'));
// Add trailing slash to Maildir if needed
$maildirpath = $maildirname;
if (!empty($maildirname) and substr($maildirname, -1) != "/") {
$maildirpath .= "/";
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, 'FATAL: Task7 asks to delete a email account but emailpath field is empty!');
}
$maildir = FileDir::makeCorrectDir(Settings::Get('system.vmail_homedir') . '/' . $row['data']['loginname'] . '/' . $email_domain . '/' . $email_user);
$maildir = FileDir::makeCorrectDir($email_full);
if ($maildir != '/' && !empty($maildir) && !empty($email_full) && $maildir != Settings::Get('system.vmail_homedir') && substr($maildir, 0, strlen(Settings::Get('system.vmail_homedir'))) == Settings::Get('system.vmail_homedir') && is_dir($maildir) && is_dir(FileDir::makeCorrectDir($maildir . '/' . $maildirpath)) && fileowner($maildir) == Settings::Get('system.vmail_uid') && filegroup($maildir) == Settings::Get('system.vmail_gid')) {
if ($maildir != '/' && !empty($maildir) && $maildir != Settings::Get('system.vmail_homedir') && substr($maildir, 0, strlen(Settings::Get('system.vmail_homedir'))) == Settings::Get('system.vmail_homedir') && is_dir($maildir) && fileowner($maildir) == Settings::Get('system.vmail_uid') && filegroup($maildir) == Settings::Get('system.vmail_gid')) {
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($maildir));
// mail-address allows many special characters, see http://en.wikipedia.org/wiki/Email_address#Local_part
$return = false;
@@ -377,23 +369,6 @@ class TasksCron extends FroxlorCron
'~',
'?'
]);
} else {
// backward-compatibility for old folder-structure
$maildir_old = FileDir::makeCorrectDir(Settings::Get('system.vmail_homedir') . '/' . $row['data']['loginname'] . '/' . $row['data']['email']);
if ($maildir_old != '/' && !empty($maildir_old) && $maildir_old != Settings::Get('system.vmail_homedir') && substr($maildir_old, 0, strlen(Settings::Get('system.vmail_homedir'))) == Settings::Get('system.vmail_homedir') && is_dir($maildir_old) && fileowner($maildir_old) == Settings::Get('system.vmail_uid') && filegroup($maildir_old) == Settings::Get('system.vmail_gid')) {
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Running: rm -rf ' . escapeshellarg($maildir_old));
// mail-address allows many special characters, see http://en.wikipedia.org/wiki/Email_address#Local_part
$return = false;
FileDir::safe_exec('rm -rf ' . escapeshellarg($maildir_old), $return, [
'|',
'&',
'`',
'$',
'~',
'?'
]);
}
}
}
}

View File

@@ -183,7 +183,7 @@ class Cronjob
} elseif ($type == TaskId::DELETE_EMAIL_DATA && count($params) == 2 && $params[0] != '' && $params[1] != '') {
$data = [];
$data['loginname'] = $params[0];
$data['email'] = $params[1];
$data['emailpath'] = $params[1];
$data = json_encode($data);
Database::pexecute($ins_stmt, [
'type' => TaskId::DELETE_EMAIL_DATA,