From 6710827b8163ff3edea3114bb4a6b611cfd4c1d7 Mon Sep 17 00:00:00 2001 From: boban Date: Mon, 27 Apr 2026 20:09:03 +0200 Subject: [PATCH] Fix: Postfix myhostname + /etc/aliases beim Domain-Speichern automatisch aktualisieren --- app/Livewire/Ui/System/SettingsForm.php | 36 +++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/app/Livewire/Ui/System/SettingsForm.php b/app/Livewire/Ui/System/SettingsForm.php index fb6ec1a..c1c7959 100644 --- a/app/Livewire/Ui/System/SettingsForm.php +++ b/app/Livewire/Ui/System/SettingsForm.php @@ -229,6 +229,10 @@ class SettingsForm extends Component $warnings[] = 'System-Domain: ' . $sysmailErr; } + if ($this->mail_domain) { + $this->applyPostfixHostname($this->mail_domain); + } + $this->loadSslStatus(); if ($warnings) { @@ -498,6 +502,38 @@ class SettingsForm extends Component file_put_contents($path, $content); } + private function applyPostfixHostname(string $mailHost): void + { + $safeHost = preg_replace('/[^a-zA-Z0-9.\-]/', '', $mailHost); + if (!$safeHost) return; + + $destination = "{$safeHost}, localhost.localdomain, localhost"; + + @shell_exec('sudo -n /usr/sbin/postconf -e ' . escapeshellarg("myhostname={$safeHost}") . ' 2>/dev/null'); + @shell_exec('sudo -n /usr/sbin/postconf -e ' . escapeshellarg("myorigin={$safeHost}") . ' 2>/dev/null'); + @shell_exec('sudo -n /usr/sbin/postconf -e ' . escapeshellarg("mydestination={$destination}") . ' 2>/dev/null'); + @shell_exec('sudo -n /usr/sbin/postfix reload 2>/dev/null'); + + // root-Alias → /dev/null verhindert Bounce-Schleife bei System-Mails von www-data + $this->sudoTee('/etc/aliases', "# Managed by Mailwolt\npostmaster: root\nroot: /dev/null\nclamav: /dev/null\n"); + @shell_exec('sudo -n /usr/bin/newaliases 2>/dev/null'); + } + + private function sudoTee(string $target, string $content): void + { + $proc = proc_open( + sprintf('sudo -n /usr/bin/tee %s >/dev/null', escapeshellarg($target)), + [0 => ['pipe', 'r'], 1 => ['pipe', 'w'], 2 => ['pipe', 'w']], + $pipes + ); + if (!is_resource($proc)) return; + fwrite($pipes[0], $content); + fclose($pipes[0]); + stream_get_contents($pipes[1]); + stream_get_contents($pipes[2]); + proc_close($proc); + } + public function render() { if (!in_array($this->tab, self::VALID_TABS, true)) {