(use-modules (base-system) (guix records) (guix gexp) (gnu packages admin) (gnu packages kerberos) (gnu packages linux) (gnu services kerberos) (gnu services configuration) (gnu services shepherd) (ice-9 match)) (define-record-type* kadmin-configuration make-kadmin-configuration kadmin-configuration? (pidfile kadmin-configuration-pidfile (default "/var/run/krb5kdc")) (package kadmin-configuration-package (default mit-krb5)) (directory kadmin-configuration-directory (default "/var/krb5kdc")) (kdb-password kadmin-configuration-kdb-password (default "password")) (realm kadmin-configuration-realm (default %domain-caps)) (root-princ kadmin-configuration-root-princ (default "root/admin")) (root-princ-pw kadmin-configuration-root-princ-pw (default "password"))) (define-gexp-compiler (kadmin-configuration-compiler (file ) system target) (match file (($ pidfile package directory kdb-password realm root-princ root-princ-pw) (gexp->derivation "kdc.conf" #~(call-with-output-file (ungexp output "out") (lambda (port) (display (string-append (ungexp-splicing `( ,@`("[kdcdefaults]\n") ,@`(" kdc_ports = 750,88\n") ,@`("[realms]\n") ,@`(" " ,realm " = {\n") ,@`(" database_name = " ,directory "/principal\n") ,@`(" acl_file = " ,directory "/kadm5.acl\n") ,@`(" key_stash_file = " ,directory "/.k5." ,realm "\n") ,@`(" kdc_ports = 750,88\n") ,@`(" max_life = 10h 0m 0s\n") ,@`(" max_renewable_life = 7d 0h 0m 0s\n") ,@`("}\n")))) port))) #:local-build? #t)))) (define %kadmin-accounts (list (user-group (name "krb5") (system? #t)) (user-account (name "krb5") (group "krb5") (system? #t) (comment "kadmin/kdc user account") (home-directory "/var/krb5kdc") (shell (file-append shadow "/sbin/nologin"))))) (define kadmin-activation-service (lambda (arg) (match arg (($ pidfile package directory kdb-password realm root-princ root-princ-pw) #~(begin (use-modules (guix build utils)) (let* ((user (getpw "krb5"))) (mkdir-p/perms #$directory user #o700) (symlink #$arg #$(string-append directory "/kdc.conf")))))))) (define kadmin-shepherd-services (match-lambda (($ pidfile package directory kdb-password realm root-princ root-princ-pw) (list (shepherd-service (documentation "Runs the kdc service") (provision '(kdc)) (requirement '(user-processes syslogd)) (start #~(lambda () (if (system (string-append #$package "/sbin/kdb5_util -r " #$realm " list_mkeys &> /dev/null")) (begin (system (string-join (list #$(file-append package "/sbin/kdb5_util") "-r" #$realm "create" "-s" "-P" #$kdb-password))) (system (string-join (list #$(file-append package "/sbin/kadmin.local") "-r" #$realm "add_principal" "-pw" #$root-princ-pw #$(string-append root-princ "@" %domain-caps)))) (system (string-join (list "echo" (string-append "\"" #$root-princ "@" #$realm " *\n\"") ">" (string-append #$directory "/kadm5.acl")))) (display "Kdc already initialized, skipping..."))) (fork+exec-command (list #$(file-append package "/sbin/krb5kdc") "-n" "-P" #$pidfile)))) (stop #~(make-kill-destructor))) (shepherd-service (documentation "Runs the kadmin service") (provision '(kadmin)) (requirement '(kdc user-processes syslogd)) (start #~(make-forkexec-constructor (list #$(file-append package "/sbin/kadmind") "-nofork"))) (stop #~(make-kill-destructor))))))) (define kadmin-service-type (service-type (name 'kadmin) (description "Runs the @command{kadmin} server") (extensions (list (service-extension shepherd-root-service-type kadmin-shepherd-services) (service-extension activation-service-type kadmin-activation-service) (service-extension account-service-type (const %kadmin-accounts)))) (default-value (kadmin-configuration)))) (operating-system (inherit base-server-system) (host-name (string-append "kadmin." %domain-name)) (packages (append (list strace) %my-server-packages)) (services (append (list (service kadmin-service-type)) %my-server-services)))