diff mbox series

[bug#67555,2/2] services: kerberos/heimdal.scm: New file, add Heimdal Kerberos services.

Message ID b0b0e3ebe07b86a83295bce34a81a71daba2fd89.1701390970.git.felix.lechner@lease-up.com
State New
Headers show
Series Add Heimdal Kerberos system services. | expand

Commit Message

Felix Lechner Dec. 1, 2023, 12:45 a.m. UTC
Includes detailed documentation and two system tests.

Change-Id: I7b3a9da1340b559f1db8a8156581e73b918cfb78
---
 doc/guix.texi                     | 101 +++++++++++++++-
 gnu/local.mk                      |   3 +
 gnu/services/kerberos.scm         | 120 ++++++++++++++++++-
 gnu/services/kerberos/heimdal.scm | 189 ++++++++++++++++++++++++++++++
 gnu/tests/heimdal-kadmind.scm     |  71 +++++++++++
 gnu/tests/heimdal-kdc.scm         |  71 +++++++++++
 6 files changed, 551 insertions(+), 4 deletions(-)
 create mode 100644 gnu/services/kerberos/heimdal.scm
 create mode 100644 gnu/tests/heimdal-kadmind.scm
 create mode 100644 gnu/tests/heimdal-kdc.scm

Comments

Bruno Victal Dec. 16, 2023, 9:35 p.m. UTC | #1
Hi Felix,

On 2023-12-01 00:45, Felix Lechner wrote:
> +  (ports
> +   (list-of-strings '())
> +   "Ports to listen on.")

I'd prefer to use a list of exact-integers. (*)
Hint: you can use the procedures in (gnu services configuration)
to define this predicate with (list-of exact-integer?).

> +  (disable-des?
> +   (boolean #f)
> +   "Disable all DES encryption types."))

I'd avoid the double negative here, i.e. by naming this enable-des?.
Another note, how about defaulting to disabled DES support
to discourage its use?

> +     (start #~(make-forkexec-constructor
> +               (list #$(file-append heimdal "/libexec/kdc")
> +                     #$@(if (maybe-value-set? config-file)
> +                            `(,(string-append "--config-file=" (maybe-value config-file)))
> +                            '())

Simply do:
`(,(string-append "--config-file=" config-file))

You don't need to use 'maybe-value' to extract the value if
you've already tested it with 'maybe-value-set?'.
> +               #:log-file "/var/log/kdc-shepherd"))

I'd make this configurable in <heimdal-kdc-configuration>.

> +  (ports
> +   (list-of-strings '())
> +   "Ports to listen on."))

See (*).

> +;;; GNU Guix --- Functional package management for GNU
> +;;; Copyright © 2017 Peter Mikkelsen <petermikkelsen10@gmail.com>
> +;;; Copyright © 2022 Bruno Victal <mirai@makinata.eu>

Copy-paste leftovers perhaps? 😅

> new file mode 100644
> index 0000000000..b6424ace9e
> --- /dev/null
> +++ b/gnu/tests/heimdal-kdc.scm

How about merging these tests under a single gnu/tests/krb-heimdal.scm
instead of splitting them as gnu/tests/heimdal-kadmind.scm and
gnu/tests/heimdal-kadmind.scm?

If you're up for it I'd love to see one more test (might
involve multiple VMs) that actually tests the kerberos integration.
(i.e. performs an actual kerberos test)
That way we could be at least sure that there's a working kerberos
setup that we can use as a reference point for documentation/cookbooks.

My 2¢!
diff mbox series

Patch

diff --git a/doc/guix.texi b/doc/guix.texi
index a5119d2058..ecb85771ad 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -29979,7 +29979,8 @@  Kerberos Services
 Other implementations have not been tested.
 
 @defvar krb5-association-service-type
-A service type for Kerberos 5 clients.
+A service type for Kerberos 5 clients. This service type was previously
+named @code{krb5-service-type}.
 @end defvar
 
 @noindent
@@ -30037,6 +30038,8 @@  Kerberos Services
 
 @deftp {Data Type} krb5-association-configuration
 
+This configuration record was previously named @code{krb5-configuration}.
+
 @table @asis
 @item @code{allow-weak-crypto?} (default: @code{#f})
 If this flag is @code{#t} then services which only offer encryption algorithms
@@ -30059,6 +30062,102 @@  Kerberos Services
 @end deftp
 
 
+@subsubheading Heimdal Key Distribution (Kdc) Service
+
+The @code{(gnu services kerberos heimdal)} module provides services
+related to the @dfn{Heimdal} implementation for the authentication
+protocol @dfn{Kerberos}.
+
+This service starts the @dfn{Kerberos Key Distribution Center}
+server. The server will remain running.
+
+Kerberos client programs can obtain the location of this server from a
+configuration file at @file{/etc/krb5.conf}. You may wish to create that
+file separately via the @code{krb5-association-service-type}.
+
+@c %start of fragment
+@deftp {Data Type} heimdal-kdc-configuration
+Available @code{heimdal-kdc-configuration} fields are:
+
+@table @asis
+@item @code{heimdal} (default: @code{heimdal}) (type: file-like)
+The heimdal package to use.
+
+@item @code{config-file} (type: maybe-string)
+Configuration file for Heimdal KDC server.
+
+@item @code{require-preauth?} (default: @code{#t}) (type: boolean)
+Require pre-authentication in the initial AS-REQ for all principals.
+
+@item @code{max-request-size} (type: maybe-non-negative-integer)
+Maximum size of requests the server is willing to handle.
+
+@item @code{enable-http?} (default: @code{#f}) (type: boolean)
+Listen on port 80 and handle requests encapsulated in HTTP.
+
+@item @code{v4-realm} (type: maybe-string)
+Realm for version 4 requests.
+
+@item @code{ports} (default: @code{()}) (type: list-of-strings)
+Ports to listen on.
+
+@item @code{addresses} (default: @code{()}) (type: list-of-strings)
+Addresses to listen on.
+
+@item @code{disable-des?} (default: @code{#f}) (type: boolean)
+Disable all DES encryption types.
+
+@end table
+
+@end deftp
+@c %end of fragment
+
+
+@subsubheading Heimdal Admin (Kadmind) Service
+
+The @code{(gnu services kerberos heimdal)} module provides services
+related to the @dfn{Heimdal} implementation for the authentication
+protocol @dfn{Kerberos}.
+
+This service starts the @dfn{Kerberos Administration} server. The server
+will remain running.
+
+Kerberos client programs can obtain the location of the server from a
+configuration file at @file{/etc/krb5.conf}. You may wish to create that
+file separately via the @code{krb5-association-service-type}.
+
+@c %start of fragment
+@deftp {Data Type} heimdal-kadmind-configuration
+Available @code{heimdal-kadmind-configuration} fields are:
+
+@table @asis
+@item @code{heimdal} (default: @code{heimdal}) (type: file-like)
+The heimdal package to use.
+
+@item @code{config-file} (type: maybe-string)
+Configuration file for Heimdal Kadmind server.
+
+@item @code{key-file} (type: maybe-string)
+Location of master key file.
+
+@item @code{keytab} (type: maybe-string)
+Kerberos keytab to use.
+
+@item @code{realm} (type: maybe-string)
+Kerberos realm to serve.
+
+@item @code{debug?} (default: @code{#f}) (type: boolean)
+Enable debugging.
+
+@item @code{ports} (default: @code{()}) (type: list-of-strings)
+Ports to listen on.
+
+@end table
+
+@end deftp
+@c %end of fragment
+
+
 @subsubheading PAM krb5 Service
 @cindex pam-krb5
 
diff --git a/gnu/local.mk b/gnu/local.mk
index a82372527e..64cda5b8b6 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -695,6 +695,7 @@  GNU_SYSTEM_MODULES =				\
   %D%/services/guix.scm			\
   %D%/services/hurd.scm				\
   %D%/services/kerberos.scm			\
+  %D%/services/kerberos/heimdal.scm		\
   %D%/services/ldap.scm		      		\
   %D%/services/lightdm.scm      		\
   %D%/services/linux.scm			\
@@ -790,6 +791,8 @@  GNU_SYSTEM_MODULES =				\
   %D%/tests/ganeti.scm				\
   %D%/tests/gdm.scm				\
   %D%/tests/guix.scm				\
+  %D%/tests/heimdal-kadmind.scm			\
+  %D%/tests/heimdal-kdc.scm			\
   %D%/tests/monitoring.scm                      \
   %D%/tests/nfs.scm				\
   %D%/tests/image.scm				\
diff --git a/gnu/services/kerberos.scm b/gnu/services/kerberos.scm
index ec9b6c10b5..432f205904 100644
--- a/gnu/services/kerberos.scm
+++ b/gnu/services/kerberos.scm
@@ -421,9 +421,123 @@  (define krb5-association-service-type
 normally expect a configuration file in @file{/etc/krb5.conf}.  This service
 generates such a file.  It does not cause any daemon to be started.")))
 
-(define-deprecated krb-configuration krb5-association-configuration)
-(define-deprecated krb-configuration? krb5-association-configuration?)
-(define-deprecated krb-service-type krb5-association-service-type)
+(define-deprecated krb5-service-type krb5-association-service-type)
+
+(define-deprecated/public-alias
+  krb5-configuration
+  krb5-association-configuration)
+(define-deprecated/public-alias
+  krb5-configuration?
+  krb5-association-configuration?)
+
+(define-deprecated/public-alias
+  krb5-configuration-allow-weak-crypto?
+  krb5-association-configuration-allow-weak-crypto?)
+(define-deprecated/public-alias
+  krb5-configuration-ap-req-checksum-type
+  krb5-association-configuration-ap-req-checksum-type)
+(define-deprecated/public-alias
+  krb5-configuration-canonicalize?
+  krb5-association-configuration-canonicalize?)
+(define-deprecated/public-alias
+  krb5-configuration-ccache-type
+  krb5-association-configuration-ccache-type)
+(define-deprecated/public-alias
+  krb5-configuration-clockskew
+  krb5-association-configuration-clockskew)
+(define-deprecated/public-alias
+  krb5-configuration-default-ccache-name
+  krb5-association-configuration-default-ccache-name)
+(define-deprecated/public-alias
+  krb5-configuration-default-client-keytab-name
+  krb5-association-configuration-default-client-keytab-name)
+(define-deprecated/public-alias
+  krb5-configuration-default-keytab-name
+  krb5-association-configuration-default-keytab-name)
+(define-deprecated/public-alias
+  krb5-configuration-default-realm
+  krb5-association-configuration-default-realm)
+(define-deprecated/public-alias
+  krb5-configuration-default-tgs-enctypes
+  krb5-association-configuration-default-tgs-enctypes)
+(define-deprecated/public-alias
+  krb5-configuration-default-tkt-enctypes
+  krb5-association-configuration-default-tkt-enctypes)
+(define-deprecated/public-alias
+  krb5-configuration-dns-canonicalize-hostname?
+  krb5-association-configuration-dns-canonicalize-hostname?)
+(define-deprecated/public-alias
+  krb5-configuration-dns-lookup-kdc?
+  krb5-association-configuration-dns-lookup-kdc?)
+(define-deprecated/public-alias
+  krb5-configuration-err-fmt
+  krb5-association-configuration-err-fmt)
+(define-deprecated/public-alias
+  krb5-configuration-forwardable?
+  krb5-association-configuration-forwardable?)
+(define-deprecated/public-alias
+  krb5-configuration-ignore-acceptor-hostname?
+  krb5-association-configuration-ignore-acceptor-hostname?)
+(define-deprecated/public-alias
+  krb5-configuration-k5login-authoritative?
+  krb5-association-configuration-k5login-authoritative?)
+(define-deprecated/public-alias
+  krb5-configuration-k5login-directory
+  krb5-association-configuration-k5login-directory)
+(define-deprecated/public-alias
+  krb5-configuration-kcm-mach-service
+  krb5-association-configuration-kcm-mach-service)
+(define-deprecated/public-alias
+  krb5-configuration-kcm-socket
+  krb5-association-configuration-kcm-socket)
+(define-deprecated/public-alias
+  krb5-configuration-kdc-default-options
+  krb5-association-configuration-kdc-default-options)
+(define-deprecated/public-alias
+  krb5-configuration-kdc-timesync
+  krb5-association-configuration-kdc-timesync)
+(define-deprecated/public-alias
+  krb5-configuration-kdc-req-checksum-type
+  krb5-association-configuration-kdc-req-checksum-type)
+(define-deprecated/public-alias
+  krb5-configuration-noaddresses?
+  krb5-association-configuration-noaddresses?)
+(define-deprecated/public-alias
+  krb5-configuration-permitted-enctypes
+  krb5-association-configuration-permitted-enctypes)
+(define-deprecated/public-alias
+  krb5-configuration-plugin-base-dir
+  krb5-association-configuration-plugin-base-dir)
+(define-deprecated/public-alias
+  krb5-configuration-preferred-preauth-types
+  krb5-association-configuration-preferred-preauth-types)
+(define-deprecated/public-alias
+  krb5-configuration-proxiable?
+  krb5-association-configuration-proxiable?)
+(define-deprecated/public-alias
+  krb5-configuration-rdns?
+  krb5-association-configuration-rdns?)
+(define-deprecated/public-alias
+  krb5-configuration-realm-try-domains
+  krb5-association-configuration-realm-try-domains)
+(define-deprecated/public-alias
+  krb5-configuration-renew-lifetime
+  krb5-association-configuration-renew-lifetime)
+(define-deprecated/public-alias
+  krb5-configuration-safe-checksum-type
+  krb5-association-configuration-safe-checksum-type)
+(define-deprecated/public-alias
+  krb5-configuration-ticket-lifetime
+  krb5-association-configuration-ticket-lifetime)
+(define-deprecated/public-alias
+  krb5-configuration-udp-preference-limit
+  krb5-association-configuration-udp-preference-limit)
+(define-deprecated/public-alias
+  krb5-configuration-verify-ap-rereq-nofail?
+  krb5-association-configuration-verify-ap-rereq-nofail?)
+(define-deprecated/public-alias
+  krb5-configuration-realms
+  krb5-association-configuration-realms)
 
 
 
diff --git a/gnu/services/kerberos/heimdal.scm b/gnu/services/kerberos/heimdal.scm
new file mode 100644
index 0000000000..0dc17f6315
--- /dev/null
+++ b/gnu/services/kerberos/heimdal.scm
@@ -0,0 +1,189 @@ 
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2023 Felix Lechner <felix.lechner@lease-up.com>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu services kerberos heimdal)
+  #:use-module (gnu packages kerberos)
+  #:use-module (gnu services)
+  #:use-module (gnu services configuration)
+  #:use-module (gnu services shepherd)
+  #:use-module (guix gexp)
+  #:use-module (guix records)
+  #:use-module (ice-9 match)
+  #:export (heimdal-kdc-configuration
+            heimdal-kdc-service-type
+            heimdal-kadmind-configuration
+            heimdal-kadmind-service-type))
+
+
+;;;
+;;; Heimdal Kdc
+;;;
+
+(define-maybe/no-serialization string)
+
+(define (non-negative-integer? val)
+  (and (exact-integer? val) (not (negative? val))))
+
+(define-maybe/no-serialization non-negative-integer)
+
+(define-configuration/no-serialization heimdal-kdc-configuration
+  (heimdal
+   (file-like heimdal)
+   "The heimdal package to use.")
+  (config-file
+   maybe-string
+   "Configuration file for Heimdal KDC server.")
+  (require-preauth?
+   (boolean #t)
+   "Require pre-authentication in the initial AS-REQ for all principals.")
+  (max-request-size
+   maybe-non-negative-integer
+   "Maximum size of requests the server is willing to handle.")
+  (enable-http?
+   (boolean #f)
+   "Listen on port 80 and handle requests encapsulated in HTTP.")
+  (v4-realm
+   maybe-string
+   "Realm for version 4 requests.")
+  (ports
+   (list-of-strings '())
+   "Ports to listen on.")
+  (addresses
+   (list-of-strings '())
+   "Addresses to listen on.")
+  (disable-des?
+   (boolean #f)
+   "Disable all DES encryption types."))
+
+(define (heimdal-kdc-shepherd-service config)
+  "Return a <shepherd-service> for Heimdal's kdc for CONFIG."
+  (match-record config
+      <heimdal-kdc-configuration> (heimdal config-file require-preauth?
+                                           max-request-size enable-http?
+                                           v4-realm ports addresses
+                                           disable-des?)
+    (shepherd-service
+     (documentation "Run the Heimdal Kerberos KDC daemon (heimdal-kdc).")
+     (provision '(heimdal-kdc))
+     (requirement '(networking))
+     (start #~(make-forkexec-constructor
+               (list #$(file-append heimdal "/libexec/kdc")
+                     #$@(if (maybe-value-set? config-file)
+                            `(,(string-append "--config-file=" (maybe-value config-file)))
+                            '())
+                     #$@(if require-preauth? '() '("--no-require-preauth"))
+                     #$@(if (maybe-value-set? max-request-size)
+                            `(,(string-append
+                                "--max-request-size="
+                                (number->string (maybe-value max-request-size))))
+                            '())
+                     #$@(if enable-http? '("--enable-http") '())
+                     #$@(if (maybe-value-set? v4-realm)
+                            `(,(string-append "--v4-realm=" (maybe-value v4-realm)))
+                            '())
+                     ;; ports parameter is white-space separated
+                     #$@(if (null? ports)
+                            '()
+                            `(,(string-append "--ports=" (string-join ports))))
+                     ;; addresses parameter is white-space separated
+                     #$@(if (null? addresses)
+                            '()
+                            `(,(string-append "--addresses=" (string-join addresses))))
+                     #$@(if disable-des? '("--disable-des") '()))
+               #:log-file "/var/log/kdc-shepherd"))
+     (stop #~(make-kill-destructor)))))
+
+(define heimdal-kdc-service-type
+  (service-type
+   (name 'heimdal-kdc)
+   (description
+    "Run the Heimdal @command{kdc} daemon.")
+   (extensions
+    (list
+     (service-extension shepherd-root-service-type
+                        (compose list heimdal-kdc-shepherd-service))))
+   (default-value (heimdal-kdc-configuration))))
+
+
+;;;
+;;; Heimdal Kadmind
+;;;
+
+(define-configuration/no-serialization heimdal-kadmind-configuration
+  (heimdal
+   (file-like heimdal)
+   "The heimdal package to use.")
+  (config-file
+   maybe-string
+   "Configuration file for Heimdal Kadmind server.")
+  (key-file
+   maybe-string
+   "Location of master key file.")
+  (keytab
+   maybe-string
+   "Kerberos keytab to use.")
+  (realm
+   maybe-string
+   "Kerberos realm to serve.")
+  (debug?
+   (boolean #f)
+   "Enable debugging.")
+  (ports
+   (list-of-strings '())
+   "Ports to listen on."))
+
+(define (heimdal-kadmind-shepherd-service config)
+  "Return a <shepherd-service> for Heimdal's kadmind for CONFIG."
+  (match-record config
+      <heimdal-kadmind-configuration> (heimdal config-file key-file keytab
+                                               realm debug? ports)
+    (shepherd-service
+     (documentation "Run the Heimdal Kerberos admin daemon (heimdal-kadmind).")
+     (provision '(heimdal-kadmind))
+     (requirement '(networking))
+     (start #~(make-forkexec-constructor
+               (list #$(file-append heimdal "/libexec/kadmind")
+                     #$@(if (maybe-value-set? config-file)
+                            `(,(string-append "--config-file=" (maybe-value config-file)))
+                            '())
+                     #$@(if (maybe-value-set? key-file)
+                            `(,(string-append "--key-file=" (maybe-value key-file)))
+                            '())
+                     #$@(if (maybe-value-set? keytab)
+                            `(,(string-append "--keytab=" (maybe-value keytab)))
+                            '())
+                     #$@(if (maybe-value-set? realm)
+                            `(,(string-append "--realm=" (maybe-value realm)))
+                            '())
+                     #$@(if debug? '("--debug") '())
+                     ;; ports parameter is white-space separated
+                     #$@(if (null? ports)
+                            '()
+                            `(,(string-append "--ports=" (string-join ports)))))))
+     (stop #~(make-kill-destructor)))))
+
+(define heimdal-kadmind-service-type
+  (service-type
+   (name 'heimdal-kadmind)
+   (description
+    "Run the Heimdal @command{kadmind} daemon.")
+   (extensions
+    (list
+     (service-extension shepherd-root-service-type
+                        (compose list heimdal-kadmind-shepherd-service))))
+   (default-value (heimdal-kadmind-configuration))))
diff --git a/gnu/tests/heimdal-kadmind.scm b/gnu/tests/heimdal-kadmind.scm
new file mode 100644
index 0000000000..b340017c69
--- /dev/null
+++ b/gnu/tests/heimdal-kadmind.scm
@@ -0,0 +1,71 @@ 
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2017 Peter Mikkelsen <petermikkelsen10@gmail.com>
+;;; Copyright © 2022 Bruno Victal <mirai@makinata.eu>
+;;; Copyright © 2023 Felix Lechner <felix.lechner@lease-up.com>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu tests heimdal-kadmind)
+  #:use-module (gnu tests)
+  #:use-module (gnu system)
+  #:use-module (gnu system vm)
+  #:use-module (gnu services)
+  #:use-module (gnu services kerberos heimdal)
+  #:use-module (gnu services networking)
+  #:use-module (guix gexp)
+  #:export (%test-heimdal-kadmind))
+
+(define %heimdal-kadmind-os
+  (simple-operating-system
+   (service dhcp-client-service-type)
+   (service heimdal-kadmind-service-type)))
+
+(define (run-heimdal-kadmind-test)
+  "Run tests in %heimdal-kadmind-os, which has heimdal-kadmind running."
+  (define os
+    (marionette-operating-system
+     %heimdal-kadmind-os
+     #:imported-modules '((gnu services herd))))
+
+  (define vm
+    (virtual-machine os))
+
+  (define test
+    (with-imported-modules '((gnu build marionette))
+      #~(begin
+          (use-modules (srfi srfi-64)
+                       (gnu build marionette))
+          (define marionette
+            (make-marionette (list #$vm)))
+
+          (test-runner-current (system-test-runner #$output))
+          (test-begin "heimdal-kadmind")
+
+          (test-assert "service is running"
+            (marionette-eval
+             '(begin
+                (use-modules (gnu services herd))
+                (start-service 'heimdal-kadmind))
+             marionette))
+
+          (test-end))))
+  (gexp->derivation "heimdal-kadmind-test" test))
+
+(define %test-heimdal-kadmind
+  (system-test
+   (name "heimdal-kadmind")
+   (description "Test that the heimdal-kadmind runs when started.")
+   (value (run-heimdal-kadmind-test))))
diff --git a/gnu/tests/heimdal-kdc.scm b/gnu/tests/heimdal-kdc.scm
new file mode 100644
index 0000000000..b6424ace9e
--- /dev/null
+++ b/gnu/tests/heimdal-kdc.scm
@@ -0,0 +1,71 @@ 
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2017 Peter Mikkelsen <petermikkelsen10@gmail.com>
+;;; Copyright © 2022 Bruno Victal <mirai@makinata.eu>
+;;; Copyright © 2023 Felix Lechner <felix.lechner@lease-up.com>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu tests heimdal-kdc)
+  #:use-module (gnu tests)
+  #:use-module (gnu system)
+  #:use-module (gnu system vm)
+  #:use-module (gnu services)
+  #:use-module (gnu services kerberos heimdal)
+  #:use-module (gnu services networking)
+  #:use-module (guix gexp)
+  #:export (%test-heimdal-kdc))
+
+(define %heimdal-kdc-os
+  (simple-operating-system
+   (service dhcp-client-service-type)
+   (service heimdal-kdc-service-type)))
+
+(define (run-heimdal-kdc-test)
+  "Run tests in %heimdal-kdc-os, which has heimdal-kdc running."
+  (define os
+    (marionette-operating-system
+     %heimdal-kdc-os
+     #:imported-modules '((gnu services herd))))
+
+  (define vm
+    (virtual-machine os))
+
+  (define test
+    (with-imported-modules '((gnu build marionette))
+      #~(begin
+          (use-modules (srfi srfi-64)
+                       (gnu build marionette))
+          (define marionette
+            (make-marionette (list #$vm)))
+
+          (test-runner-current (system-test-runner #$output))
+          (test-begin "heimdal-kdc")
+
+          (test-assert "service is running"
+            (marionette-eval
+             '(begin
+                (use-modules (gnu services herd))
+                (start-service 'heimdal-kdc))
+             marionette))
+
+          (test-end))))
+  (gexp->derivation "heimdal-kdc-test" test))
+
+(define %test-heimdal-kdc
+  (system-test
+   (name "heimdal-kdc")
+   (description "Test that the heimdal-kdc runs when started.")
+   (value (run-heimdal-kdc-test))))