From 5f71a8d5e99c2d3cc4c9e85900e27f90586daa23 Mon Sep 17 00:00:00 2001 From: boban Date: Mon, 27 Apr 2026 01:45:41 +0200 Subject: [PATCH] =?UTF-8?q?Fix:=20Dovecot24-Migration=20erg=C3=A4nzt=2010-?= =?UTF-8?q?master.conf,=2010-ssl.conf=20+=20dovecot=5Fstorage=5Fversion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- app/Console/Commands/MigrateDovecot24.php | 67 ++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/app/Console/Commands/MigrateDovecot24.php b/app/Console/Commands/MigrateDovecot24.php index d7d23b6..6f5765e 100644 --- a/app/Console/Commands/MigrateDovecot24.php +++ b/app/Console/Commands/MigrateDovecot24.php @@ -22,7 +22,13 @@ class MigrateDovecot24 extends Command // 3) 10-mail.conf: mail_location → mail_driver + mail_path $this->fixMailConf($dry); - // 4) auth-sql.conf.ext: neue passdb/userdb-Syntax + // 4) 10-master.conf: einzeilige Blöcke aufsplitten + $this->fixMasterConf($dry); + + // 5) 10-ssl.conf: ssl_cert/ssl_key → ssl_server_cert_file/ssl_server_key_file + $this->fixSslConf($dry); + + // 6) auth-sql.conf.ext: neue passdb/userdb-Syntax $this->fixAuthSqlConf($dry); if (!$dry) { @@ -80,6 +86,65 @@ class MigrateDovecot24 extends Command $this->info(" aktualisiert: {$file}"); } + private function fixMasterConf(bool $dry): void + { + $file = '/etc/dovecot/conf.d/10-master.conf'; + $content = @file_get_contents($file); + if ($content === false) { $this->warn("Nicht gefunden: {$file}"); return; } + + // Einzeilige Blöcke "name { key = val }" → mehrzeilig + $new = preg_replace_callback( + '/^(\s*)(\S+)\s*\{\s*([^}]+)\s*\}(\s*)$/m', + function ($m) { + $indent = $m[1]; + $name = $m[2]; + $inner = trim($m[3]); + $pairs = preg_split('/\s+(?=\w+=)/', $inner); + $body = implode("\n{$indent} ", array_map('trim', $pairs)); + return "{$indent}{$name} {\n{$indent} {$body}\n{$indent}}"; + }, + $content + ); + + if ($new === $content) { $this->line(" ok (unverändert): {$file}"); return; } + + if ($dry) { $this->line(" [dry-run] würde einzeilige Blöcke aufsplitten in {$file}"); return; } + file_put_contents($file, $new); + $this->info(" aktualisiert: {$file}"); + } + + private function fixSslConf(bool $dry): void + { + $file = '/etc/dovecot/conf.d/10-ssl.conf'; + $content = @file_get_contents($file); + if ($content === false) { $this->warn("Nicht gefunden: {$file}"); return; } + + // ssl_cert = → ssl_server_cert_file = /path + $new = preg_replace('/^ssl_cert\s*=\s*<(.+)$/m', 'ssl_server_cert_file = $1', $content); + $new = preg_replace('/^ssl_key\s*=\s*<(.+)$/m', 'ssl_server_key_file = $1', $new); + // Direkte Pfade ohne < (falls schon teilweise migriert) + $new = preg_replace('/^ssl_cert\s*=\s*(?!<)(.+)$/m', 'ssl_server_cert_file = $1', $new); + $new = preg_replace('/^ssl_key\s*=\s*(?!<)(.+)$/m', 'ssl_server_key_file = $1', $new); + + // dovecot_storage_version in dovecot.conf (wenn noch nicht vorhanden) + $mainConf = '/etc/dovecot/dovecot.conf'; + $mainContent = (string) @file_get_contents($mainConf); + if (!str_contains($mainContent, 'dovecot_storage_version')) { + if (!$dry) { + file_put_contents($mainConf, $mainContent . "\ndovecot_storage_version = 2.4.1\n"); + $this->info(" dovecot_storage_version ergänzt in {$mainConf}"); + } else { + $this->line(" [dry-run] würde dovecot_storage_version ergänzen in {$mainConf}"); + } + } + + if ($new === $content) { $this->line(" ok (unverändert): {$file}"); return; } + + if ($dry) { $this->line(" [dry-run] würde ssl_cert/ssl_key umbenennen in {$file}"); return; } + file_put_contents($file, $new); + $this->info(" aktualisiert: {$file}"); + } + private function fixAuthConf(bool $dry): void { $file = '/etc/dovecot/conf.d/10-auth.conf';