services: admin: Refactor and renaming of doas-service-type

main
Luis Guilherme Coelho 2024-09-22 13:56:39 -03:00
parent f6aab460c7
commit eb862f370b
No known key found for this signature in database
GPG Key ID: 1F2E76ACE3F531C8
1 changed files with 72 additions and 52 deletions

View File

@ -2,33 +2,20 @@
#:use-module (gnu packages admin)
#:use-module (gnu services configuration)
#:use-module ((gnu services) #:hide (delete))
#:use-module (gnu system privilege)
#:use-module (guix gexp)
#:use-module (guix packages)
#:use-module (guix records)
#:use-module (ice-9 format)
#:use-module (ice-9 match)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-26)
#:export (doas-service-type
#:export (opendoas-service-type
opendoas-configuration
opendoas-rule-extension
permit
make-permit-statement
permit-statement?
permit-statement-args
permit-statement-as-user
permit-statement-command
permit-statement-identity
permit-statement-keepenv?
permit-statement-nolog?
permit-statement-nopass?
permit-statement-persist?
permit-statement-setenv
deny
make-deny-statement
deny-statement?
deny-statement-args
deny-statement-as-user
deny-statement-command))
deny))
;; Dummy serializers, just to avoid warnings
(define empty-serializer
@ -47,7 +34,7 @@
(define-maybe assoc-list)
(define-maybe string)
(define-configuration/no-serialization permit-statement
(define-configuration/no-serialization permit-rule
(nopass?
(boolean #f)
"Whether the user should be permitted to run the command without a password.")
@ -85,8 +72,8 @@ without arguments.")
to #f, or simply exported, by setting them to #t. If the first character of the
value is $ then the value to be set is taken from the existing environment
variable with the given name."))
(define-syntax-rule (permit entry ...)
(permit-statement entry ...))
(define-syntax-rule (permit field ...)
(permit-rule field ...))
(define (unset? val)
"Tests if VAL is unset."
@ -97,8 +84,8 @@ variable with the given name."))
"Apply PROC to VAL if VAL is not unset, otherwise returns #f."
(if (not (unset? val)) (proc val) #f))
(define serialize-permit-statement
(match-record-lambda <permit-statement>
(define serialize-permit-rule
(match-record-lambda <permit-rule>
(identity as-user command args setenv keepenv? nopass? nolog? persist?)
(format #f "permit ~:[~;keepenv ~]~
~:[~;nopass ~]~
@ -118,7 +105,7 @@ variable with the given name."))
(if-set command)
(if-set args))))
(define-configuration/no-serialization deny-statement
(define-configuration/no-serialization deny-rule
(identity
string
"The username to match. Groups may be specified by prepending a colon ':'.")
@ -136,11 +123,11 @@ path is specified, only a restricted PATH will be searched.")
"Arguments to command. The command arguments provided by the user need to
match those specified. The keyword args alone means that command must be run
without arguments."))
(define-syntax-rule (deny entry ...)
(deny-statement entry ...))
(define-syntax-rule (deny field ...)
(deny-rule field ...))
(define serialize-deny-statement
(match-record-lambda <deny-statement>
(define serialize-deny-rule
(match-record-lambda <deny-rule>
(identity as-user command args)
(format #f "deny ~a~@[ as ~a~]~@[ cmd ~a~]~@[ args~{ ~a~}~]~%"
identity
@ -148,30 +135,63 @@ without arguments."))
(if-set command)
(if-set args))))
(define (doas-config-file config)
(plain-file "doas.conf"
(apply string-append
(map (lambda (s)
(cond ((permit-statement? s)
(serialize-permit-statement s))
((deny-statement? s)
(serialize-deny-statement s))))
config))))
(define (rule? x)
(or (permit-rule? x)
(deny-rule? x)))
(define (doas-etc-service config)
`(("doas.conf" ,(doas-config-file config))))
(define list-of-rules?
(list-of rule?))
(define doas-service-type
(service-type (name 'doas)
(define-configuration/no-serialization opendoas-configuration
(opendoas
(package opendoas)
"The doas package to be used.")
(rules
(list-of-rules '())
"The list of permit and/or deny rules used by doas."))
(define-configuration/no-serialization opendoas-rule-extension
(rules
(list-of-rules '())
"The list of permit and/or deny rules used by doas."))
(define (opendoas-extensions original-config extension-configs)
(opendoas-configuration
(inherit original-config)
(rules (append (opendoas-configuration-rules original-config)
(reverse (append-map opendoas-rule-extension-rules
extension-configs))))))
(define (opendoas-config-file config)
`(("doas.conf"
,(plain-file "doas.conf"
(apply string-append
(map (lambda (s)
(cond ((permit-rule? s)
(serialize-permit-rule s))
((deny-rule? s)
(serialize-deny-rule s))))
(opendoas-configuration-rules config)))))))
(define (opendoas-privileged-programs config)
(let ((opendoas (opendoas-configuration-opendoas config)))
(list (privileged-program
(program (file-append opendoas "/bin/doas"))
(setuid? #t)))))
(define (opendoas-packages config)
(list (opendoas-configuration-opendoas config)))
(define opendoas-service-type
(service-type (name 'opendoas)
(extensions
(list (service-extension
etc-service-type
doas-etc-service)))
(compose (compose concatenate reverse))
(extend append)
(default-value '())
(list (service-extension etc-service-type
opendoas-config-file)
(service-extension profile-service-type
opendoas-packages)
(service-extension privileged-program-service-type
opendoas-privileged-programs)))
(compose identity)
(extend opendoas-extensions)
(default-value (opendoas-configuration))
(description "Set /etc/doas.conf")))
(define (generate-documentation)
(configuration->documentation 'permit-statement)
(configuration->documentation 'deny-statement))