From b3b484389fdd2ea50bc673a2289d6d8ef037b483 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Wed, 30 Aug 2023 15:31:48 +0200 Subject: Correct remaining mistakes in Exim service Set exim user and group in the package, don't fail on existing symlink. Make exim setuid. Also refactor some code into more readable separate functions. --- container.scm | 103 ++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 82 insertions(+), 21 deletions(-) diff --git a/container.scm b/container.scm index c7fcf79..2896c3f 100644 --- a/container.scm +++ b/container.scm @@ -25,7 +25,8 @@ (guix modules) ((guix utils) #:select (substitute-keyword-arguments)) ;; The following exports account-service-type. - (gnu system shadow)) + (gnu system shadow) + ((gnu system setuid) #:select (setuid-program))) (use-package-modules web python version-control @@ -442,6 +443,56 @@ (deploy-hook %koszko-httpd-deploy-hook))))) %all-site-confs))))) +(define exim-configuration-config-file + (@@ (gnu services mail) exim-configuration-config-file)) + +(define exim-configuration-package + (@@ (gnu services mail) exim-configuration-package)) + +(define (adapt-exim-activation-extension ext) + ;; Make exim logs accessible under /var/log/exim and symlink current + ;; configuration as /etc/exim.conf. + (let ((old-activation (service-extension-compute ext))) + (define (new-activation exim-config) + #~(begin + ;; There's unfortunately no option to tell file-exist? or stat not to + ;; follow symlinks, hence we use statat... + (unless (with-input-from-file "/var/log" + (lambda _ + (false-if-exception (statat (current-input-port) + "exim" AT_SYMLINK_NOFOLLOW)))) + (symlink "../spool/exim/log" "/var/log/exim")) + ;; Exim often rereads its config file. Let's substitute it + ;; atomiacally. + (with-output-to-file "/etc/exim.conf.new" + (lambda _ + (format #t " +exim_user = exim +exim_group = exim +exim_path = /run/setuid-programs/exim +.include ~a" + #$(exim-configuration-config-file exim-config)))) + (rename-file "/etc/exim.conf.new" "/etc/exim.conf") + #$(old-activation exim-config))) + + (service-extension activation-service-type new-activation))) + +(define (adapt-exim-shepherd-extension ext) + ;; Make exim daemon use /etc/exim.conf which we made a symlink to the real + ;; config file. + (let ((old-activation (service-extension-compute ext))) + (define (new-activation exim-config) + (let ((exim-package (exim-configuration-package exim-config))) + (map (lambda (shepherd-service-record) + (shepherd-service + (inherit shepherd-service-record) + (start #~(make-forkexec-constructor + '(#$(file-append exim-package "/bin/exim") + "-bd" "-v"))))) + (old-activation exim-config)))) + + (service-extension shepherd-root-service-type new-activation))) + (define koszko-exim-service-type (service-type (inherit exim-service-type) @@ -452,33 +503,39 @@ ;; Avoid double declaration of "exim" user and group. #f) ((extension-of-type? ext activation-service-type) - ;; Make exim logs accessible under /var/log - (let ((old-activation (service-extension-compute ext))) - (define (new-activation exim-config) - #~(begin - (symlink "../spool/exim/log" "/var/log/exim") - #$(old-activation exim-config))) - - (service-extension activation-service-type - new-activation))) + (adapt-exim-activation-extension ext)) + ((extension-of-type? ext shepherd-root-service-type) + (adapt-exim-shepherd-extension ext)) (else ext))) (service-type-extensions exim-service-type))))) +(define koszko-adapted-exim + (package/inherit exim + (arguments + (substitute-keyword-arguments + (package-arguments exim) + ((#:phases phases) + #~(modify-phases #$phases + (add-after 'configure 'configure* + (lambda _ + (substitute* "Local/Makefile" + (("# (SUPPORT_MAILDIR=yes)" all line) + line) + (("(EXIM_USER=).*" all var) + (string-append var "106\n")) + (("# (EXIM_GROUP=).*" all var) + (string-append var "113\n"))))) + (add-after 'install 'symlink-config-file + (lambda _ + (let ((config-path (string-append #$output "/etc/exim.conf"))) + (delete-file config-path) + (symlink "/etc/exim.conf" config-path)))))))))) + (define %koszko-exim-service (service koszko-exim-service-type (exim-configuration - (package (package/inherit exim - (arguments - (substitute-keyword-arguments - (package-arguments exim) - ((#:phases phases) - #~(modify-phases #$phases - (add-after 'configure 'configure-enable-maildir - (lambda _ - (substitute* "Local/Makefile" - (("# (SUPPORT_MAILDIR=yes)" all line) - line)))))))))) + (package koszko-adapted-exim) (config-file (local-file "./exim.conf"))))) (define %koszko-mail-aliases-service @@ -571,6 +628,10 @@ (bootloader (bootloader-configuration (bootloader grub-bootloader) (targets '("/dev/sdDOES-NOT-MATTER")))) + (setuid-programs + (cons* (setuid-program + (program (file-append koszko-adapted-exim "/bin/exim"))) + %setuid-programs)) (services (cons* %koszko-httpd-service (simple-service 'koszko-org-website koszko-httpd-service-type -- cgit v1.2.3