projects/guix·blob master · refs

676 lines · 25.3 KiB

1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2019, 2020 L p R n d n <[email protected]>
3;;; Copyright © 2020 Ricardo Wurmus <[email protected]>
4;;; Copyright © 2022 Maxim Cournoyer <[email protected]>
5;;;
6;;; This file is part of GNU Guix.
7;;;
8;;; GNU Guix is free software; you can redistribute it and/or modify it
9;;; under the terms of the GNU General Public License as published by
10;;; the Free Software Foundation; either version 3 of the License, or (at
11;;; your option) any later version.
12;;;
13;;; GNU Guix is distributed in the hope that it will be useful, but
14;;; WITHOUT ANY WARRANTY; without even the implied warranty of
15;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16;;; GNU General Public License for more details.
17;;;
18;;; You should have received a copy of the GNU General Public License
19;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
20
21(define-module (gnu services lightdm)
22 #:use-module (gnu artwork)
23 #:use-module (gnu packages admin)
24 #:use-module (gnu packages display-managers)
25 #:use-module (gnu packages freedesktop)
26 #:use-module (gnu packages gnome)
27 #:use-module (gnu packages vnc)
28 #:use-module (gnu packages xorg)
29 #:use-module (gnu services configuration)
30 #:use-module (gnu services dbus)
31 #:use-module (gnu services desktop)
32 #:use-module (gnu services shepherd)
33 #:use-module (gnu services xorg)
34 #:use-module (gnu services)
35 #:use-module (gnu system pam)
36 #:use-module (gnu system shadow)
37 #:use-module (guix diagnostics)
38 #:use-module (guix gexp)
39 #:use-module (guix i18n)
40 #:use-module (guix records)
41 #:use-module (ice-9 format)
42 #:use-module (ice-9 match)
43 #:use-module (srfi srfi-1)
44 #:use-module (srfi srfi-26)
45 #:export (lightdm-seat-configuration
46 lightdm-seat-configuration?
47 lightdm-seat-configuration-name
48 lightdm-seat-configuration-type
49 lightdm-seat-configuration-user-session
50 lightdm-seat-configuration-autologin-user
51 lightdm-seat-configuration-greeter-session
52 lightdm-seat-configuration-xserver-command
53 lightdm-seat-configuration-session-wrapper
54 lightdm-seat-configuration-extra-config
55
56 lightdm-gtk-greeter-configuration
57 lightdm-gtk-greeter-configuration?
58 lightdm-gtk-greeter-configuration-lightdm-gtk-greeter
59 lightdm-gtk-greeter-configuration-assets
60 lightdm-gtk-greeter-configuration-theme-name
61 lightdm-gtk-greeter-configuration-icon-theme-name
62 lightdm-gtk-greeter-configuration-cursor-theme-name
63 lightdm-gtk-greeter-configuration-allow-debug
64 lightdm-gtk-greeter-configuration-background
65 lightdm-gtk-greeter-configuration-a11y-states
66 lightdm-gtk-greeter-configuration-reader
67 lightdm-gtk-greeter-configuration-extra-config
68
69 lightdm-configuration
70 lightdm-configuration?
71 lightdm-configuration-lightdm
72 lightdm-configuration-allow-empty-passwords?
73 lightdm-configuration-xorg-configuration
74 lightdm-configuration-greeters
75 lightdm-configuration-seats
76 lightdm-configuration-xdmcp?
77 lightdm-configuration-xdmcp-listen-address
78 lightdm-configuration-vnc-server?
79 lightdm-configuration-vnc-server-command
80 lightdm-configuration-vnc-server-listen-address
81 lightdm-configuration-vnc-server-port
82 lightdm-configuration-extra-config
83
84 lightdm-service-type))
85
86;;;
87;;; Greeters.
88;;;
89
90(define list-of-file-likes?
91 (list-of file-like?))
92
93(define %a11y-states '(contrast font keyboard reader))
94
95(define (a11y-state? value)
96 (memq value %a11y-states))
97
98(define list-of-a11y-states?
99 (list-of a11y-state?))
100
101(define-maybe boolean)
102
103(define (serialize-boolean name value)
104 (define (strip-trailing-? name)
105 ;; field? -> field
106 (let ((str (symbol->string name)))
107 (if (string-suffix? "?" str)
108 (string-drop-right str 1)
109 str)))
110 (format #f "~a=~:[false~;true~]~%" (strip-trailing-? name) value))
111
112(define-maybe file-like)
113
114(define (serialize-file-like name value)
115 #~(format #f "~a=~a~%" '#$name #$value))
116
117(define (serialize-list-of-a11y-states name value)
118 (format #f "~a=~a~%" name (string-join (map symbol->string value) ";")))
119
120(define (serialize-string name value)
121 (format #f "~a=~a~%" name value))
122
123(define (serialize-number name value)
124 (format #f "~a=~a~%" name value))
125
126(define (serialize-list-of-strings _ value)
127 (string-join value "\n"))
128
129(define-configuration lightdm-gtk-greeter-configuration
130 (lightdm-gtk-greeter
131 (file-like lightdm-gtk-greeter)
132 "The lightdm-gtk-greeter package to use."
133 empty-serializer)
134 (assets
135 (list-of-file-likes (list adwaita-icon-theme
136 gnome-themes-extra))
137 "The list of packages complementing the greeter, such as package providing
138icon themes."
139 empty-serializer)
140 (theme-name
141 (string "Adwaita")
142 "The name of the theme to use.")
143 (icon-theme-name
144 (string "Adwaita")
145 "The name of the icon theme to use.")
146 (cursor-theme-name
147 (string "Adwaita")
148 "The name of the cursor theme to use.")
149 (cursor-theme-size
150 (number 16)
151 "The size to use for the cursor theme.")
152 (allow-debugging?
153 maybe-boolean
154 "Set to #t to enable debug log level.")
155 (background
156 (file-like (file-append %artwork-repository
157 "/backgrounds/guix-checkered-16-9.svg"))
158 "The background image to use.")
159 ;; FIXME: This should be enabled by default, but it currently doesn't work,
160 ;; failing to connect to D-Bus, causing the login to fail.
161 (at-spi-enabled?
162 (boolean #f)
163 "Enable accessibility support through the Assistive Technology Service
164Provider Interface (AT-SPI).")
165 (a11y-states
166 (list-of-a11y-states %a11y-states)
167 "The accessibility features to enable, given as list of symbols.")
168 (reader
169 maybe-file-like
170 "The command to use to launch a screen reader.")
171 (extra-config
172 (list-of-strings '())
173 "Extra configuration values to append to the LightDM GTK Greeter
174configuration file."))
175
176(define (strip-record-type-name-brackets name)
177 "Remove the '<' and '>' brackets from NAME, a symbol."
178 (let ((name (symbol->string name)))
179 (if (and (string-prefix? "<" name)
180 (string-suffix? ">" name))
181 (string->symbol (string-drop (string-drop-right name 1) 1))
182 (error "unexpected record type name" name))))
183
184(define (config->name config)
185 "Return the constructor name (a symbol) from CONFIG."
186 (strip-record-type-name-brackets
187 (record-type-name (struct-vtable config))))
188
189(define (greeter-configuration->greeter-fields config)
190 "Return the fields of CONFIG, a greeter configuration."
191 (match config
192 ;; Note: register any new greeter configuration here.
193 ((? lightdm-gtk-greeter-configuration?)
194 lightdm-gtk-greeter-configuration-fields)))
195
196(define (greeter-configuration->packages config)
197 "Return the list of greeter packages, including assets, used by CONFIG, a
198greeter configuration."
199 (match config
200 ;; Note: register any new greeter configuration here.
201 ((? lightdm-gtk-greeter-configuration?)
202 (cons (lightdm-gtk-greeter-configuration-lightdm-gtk-greeter config)
203 (lightdm-gtk-greeter-configuration-assets config)))))
204
205;;; TODO: Implement directly in (gnu services configuration), perhaps by
206;;; making the FIELDS argument optional.
207(define (serialize-configuration* config)
208 "Like `serialize-configuration', but not requiring to provide a FIELDS
209argument."
210 (define fields (greeter-configuration->greeter-fields config))
211 (serialize-configuration config fields))
212
213(define (greeter-configuration->conf-name config)
214 "Return the file name of CONFIG, a greeter configuration."
215 (format #f "~a.conf" (greeter-configuration->greeter-session config)))
216
217(define (greeter-configuration->file config)
218 "Serialize CONFIG into a file under the output directory, so that it can be
219easily added to XDG_CONF_DIRS."
220 (computed-file
221 (greeter-configuration->conf-name config)
222 #~(begin
223 (call-with-output-file #$output
224 (lambda (port)
225 (format port (string-append
226 "[greeter]\n"
227 #$(serialize-configuration* config))))))))
228
229
230;;;
231;;; Seats.
232;;;
233
234(define seat-name? string?)
235
236(define (serialize-seat-name _ value)
237 (format #f "[Seat:~a]~%" value))
238
239(define (seat-type? type)
240 (memq type '(local xremote)))
241
242(define (serialize-seat-type name value)
243 (format #f "~a=~a~%" name value))
244
245(define-maybe seat-type)
246
247(define (greeter-session? value)
248 (memq value '(lightdm-gtk-greeter)))
249
250(define (serialize-greeter-session name value)
251 (format #f "~a=~a~%" name value))
252
253(define-maybe greeter-session)
254
255(define-maybe string)
256
257;;; Note: all the fields except for the seat name should be 'maybe's, since
258;;; the real default value is set by the %lightdm-seat-default define later,
259;;; and this avoids repeating ourselves in the serialized configuration file.
260(define-configuration lightdm-seat-configuration
261 (name
262 seat-name
263 "The name of the seat. An asterisk (*) can be used in the name
264to apply the seat configuration to all the seat names it matches.")
265 (user-session
266 maybe-string
267 "The session to use by default. The session name must be provided as a
268lowercase string, such as @code{\"gnome\"}, @code{\"ratpoison\"}, etc.")
269 (type
270 (seat-type 'local)
271 "The type of the seat, either the @code{local} or @code{xremote} symbol.")
272 (autologin-user
273 maybe-string
274 "The username to automatically log in with by default.")
275 (greeter-session
276 (greeter-session 'lightdm-gtk-greeter)
277 "The greeter session to use, specified as a symbol. Currently, only
278@code{lightdm-gtk-greeter} is supported.")
279 ;; Note: xserver-command must be lazily computed, so that it can be
280 ;; overridden via 'lightdm-configuration-xorg-configuration'.
281 (xserver-command
282 maybe-file-like
283 "The Xorg server command to run.")
284 (session-wrapper
285 (file-like (xinitrc))
286 "The xinitrc session wrapper to use.")
287 (extra-config
288 (list-of-strings '())
289 "Extra configuration values to append to the seat configuration section."))
290
291(define (greeter-session->greater-configuration-pred identifier)
292 "Return the predicate to check if a configuration is of the type specifying
293a greeter identified by IDENTIFIER."
294 (match identifier
295 ;; Note: register any new greeter identifier here.
296 ('lightdm-gtk-greeter
297 lightdm-gtk-greeter-configuration?)))
298
299(define (greeter-configuration->greeter-session config)
300 "Given CONFIG, a greeter configuration object, return its identifier,
301a symbol."
302 (let ((suffix "-configuration")
303 (greeter-conf-name (config->name config)))
304 (string->symbol (string-drop-right (symbol->string greeter-conf-name)
305 (string-length suffix)))))
306
307(define list-of-seat-configurations?
308 (list-of lightdm-seat-configuration?))
309
310
311;;;
312;;; LightDM.
313;;;
314
315(define (greeter-configuration? config)
316 (or (lightdm-gtk-greeter-configuration? config)
317 ;; Note: register any new greeter configuration here.
318 ))
319
320(define (list-of-greeter-configurations? greeter-configs)
321 (and ((list-of greeter-configuration?) greeter-configs)
322 ;; Greeter configurations must also not be provided more than once.
323 (let* ((types (map (compose record-type-name struct-vtable)
324 greeter-configs))
325 (dupes (filter (lambda (type)
326 (< 1 (count (cut eq? type <>) types)))
327 types)))
328 (unless (null? dupes)
329 (leave (G_ "duplicate greeter configurations: ~a~%") dupes)))))
330
331(define-configuration/no-serialization lightdm-configuration
332 (lightdm
333 (file-like lightdm)
334 "The lightdm package to use.")
335 (allow-empty-passwords?
336 (boolean #f)
337 "Whether users not having a password set can login.")
338 (debug?
339 (boolean #f)
340 "Enable verbose output.")
341 (xorg-configuration
342 (xorg-configuration (xorg-configuration))
343 "The default Xorg server configuration to use to generate the Xorg server
344start script. It can be refined per seat via the @code{xserver-command} of
345the @code{<lightdm-seat-configuration>} record, if desired.")
346 (greeters
347 (list-of-greeter-configurations (list (lightdm-gtk-greeter-configuration)))
348 "The LightDM greeter configurations specifying the greeters to use.")
349 (seats
350 (list-of-seat-configurations (list (lightdm-seat-configuration
351 (name "*"))))
352 "The seat configurations to use. A LightDM seat is akin to a user.")
353 (xdmcp?
354 (boolean #f)
355 "Whether a XDMCP server should listen on port UDP 177.")
356 (xdmcp-listen-address
357 maybe-string
358 "The host or IP address the XDMCP server listens for incoming connections.
359When unspecified, listen on for any hosts/IP addresses.")
360 (vnc-server?
361 (boolean #f)
362 "Whether a VNC server is started.")
363 (vnc-server-command
364 (file-like (file-append tigervnc-server "/bin/Xvnc"))
365 "The Xvnc command to use for the VNC server, it's possible to provide extra
366options not otherwise exposed along the command, for example to disable
367security:
368@lisp
369(vnc-server-command
370 (file-append tigervnc-server \"/bin/Xvnc\"
371 \" -SecurityTypes None\" ))
372@end lisp
373
374Or to set a PasswordFile for the classic (unsecure) VncAuth mechanism:
375@lisp
376(vnc-server-command
377 (file-append tigervnc-server \"/bin/Xvnc\"
378 \" -PasswordFile /var/lib/lightdm/.vnc/passwd\"))
379@end lisp
380The password file should be manually created using the @command{vncpasswd}
381command.
382
383Note that LightDM will create new sessions for VNC users, which means they
384need to authenticate in the same way as local users would.
385")
386 (vnc-server-listen-address
387 maybe-string
388 "The host or IP address the VNC server listens for incoming connections.
389When unspecified, listen for any hosts/IP addresses.")
390 (vnc-server-port
391 (number 5900)
392 "The TCP port the VNC server should listen to.")
393 (extra-config
394 (list-of-strings '())
395 "Extra configuration values to append to the LightDM configuration file."))
396
397(define (lightdm-configuration->packages config)
398 "Return all the greeter packages and their assets defined in CONFIG, a
399<lightdm-configuration> object, as well as the lightdm package itself."
400 (cons (lightdm-configuration-lightdm config)
401 (append-map greeter-configuration->packages
402 (lightdm-configuration-greeters config))))
403
404(define (validate-lightdm-configuration config)
405 "Sanity check CONFIG, a <lightdm-configuration> record instance."
406 ;; This is required to make inter-field validations, such as between the
407 ;; seats and greeters.
408 (let* ((seats (lightdm-configuration-seats config))
409 (greeter-sessions (delete-duplicates
410 (map lightdm-seat-configuration-greeter-session
411 seats)
412 eq?))
413 (greeter-configurations (lightdm-configuration-greeters config))
414 (missing-greeters
415 (filter-map
416 (lambda (id)
417 (define pred (greeter-session->greater-configuration-pred id))
418 (if (find pred greeter-configurations)
419 #f ;happy path
420 id))
421 greeter-sessions)))
422 (unless (null? missing-greeters)
423 (leave (G_ "no greeter configured for seat greeter sessions: ~a~%")
424 missing-greeters))))
425
426(define (lightdm-configuration-file config)
427 (match-record config <lightdm-configuration>
428 (xorg-configuration seats
429 xdmcp? xdmcp-listen-address
430 vnc-server? vnc-server-command vnc-server-listen-address vnc-server-port
431 extra-config)
432 (apply
433 mixed-text-file
434 "lightdm.conf" "
435#
436# General configuration
437#
438[LightDM]
439greeter-user=lightdm
440sessions-directory=/run/current-system/profile/share/xsessions\
441:/run/current-system/profile/share/wayland-sessions
442remote-sessions-directory=/run/current-system/profile/share/remote-sessions
443"
444 #~(string-join '#$extra-config "\n")
445 "
446#
447# XDMCP Server configuration
448#
449[XDMCPServer]
450enabled=" (if xdmcp? "true" "false") "\n"
451(if (maybe-value-set? xdmcp-listen-address)
452 (format #f "xdmcp-listen-address=~a" xdmcp-listen-address)
453 "") "
454
455#
456# VNC Server configuration
457#
458[VNCServer]
459enabled=" (if vnc-server? "true" "false") "
460command=" vnc-server-command "
461port=" (number->string vnc-server-port) "\n"
462(if (maybe-value-set? vnc-server-listen-address)
463 (format #f "listen-address=~a" vnc-server-listen-address)
464 "") "
465
466#
467# Seat configuration.
468#
469"
470 (map (lambda (seat)
471 ;; This complication exists to propagate a default value for
472 ;; the 'xserver-command' field of the seats. Having a
473 ;; 'xorg-configuration' field at the root of the
474 ;; lightdm-configuration enables the use of
475 ;; 'set-xorg-configuration' and can be more convenient.
476 (let ((seat* (if (maybe-value-set?
477 (lightdm-seat-configuration-xserver-command seat))
478 seat
479 (lightdm-seat-configuration
480 (inherit seat)
481 (xserver-command (xorg-start-command
482 xorg-configuration))))))
483 (serialize-configuration seat*
484 lightdm-seat-configuration-fields)))
485 seats))))
486
487(define (lightdm-configuration-directory config)
488 "Return a directory containing the serialized lightdm configuration
489and all the serialized greeter configurations from CONFIG."
490 (file-union "etc-lightdm"
491 (cons `("lightdm.conf" ,(lightdm-configuration-file config))
492 (map (lambda (g)
493 `(,(greeter-configuration->conf-name g)
494 ,(greeter-configuration->file g)))
495 (lightdm-configuration-greeters config)))))
496
497(define %lightdm-accounts
498 (list (user-group (name "lightdm") (system? #t))
499 (user-account
500 (name "lightdm")
501 (group "lightdm")
502 (system? #t)
503 (comment "LightDM user")
504 (home-directory "/var/lib/lightdm")
505 (shell (file-append shadow "/sbin/nologin")))))
506
507(define %lightdm-activation
508 ;; Ensure /var/lib/lightdm is owned by the "lightdm" user. Adapted from the
509 ;; %gdm-activation.
510 (with-imported-modules '((guix build utils))
511 #~(begin
512 (use-modules (guix build utils))
513
514 (define (ensure-ownership directory)
515 (let* ((lightdm (getpwnam "lightdm"))
516 (uid (passwd:uid lightdm))
517 (gid (passwd:gid lightdm))
518 (st (stat directory #f)))
519 ;; Recurse into directory only if it has wrong ownership.
520 (when (and st
521 (or (not (= uid (stat:uid st)))
522 (not (= gid (stat:gid st)))))
523 (for-each (lambda (file)
524 (chown file uid gid))
525 (find-files directory #:directories? #t)))))
526
527 (when (not (stat "/var/lib/lightdm-data" #f))
528 (mkdir-p "/var/lib/lightdm-data"))
529 (for-each ensure-ownership
530 '("/var/lib/lightdm"
531 "/var/lib/lightdm-data")))))
532
533(define (lightdm-pam-service config)
534 "Return a PAM service for @command{lightdm}."
535 (unix-pam-service "lightdm"
536 #:login-uid? #t
537 #:allow-empty-passwords?
538 (lightdm-configuration-allow-empty-passwords? config)))
539
540(define (lightdm-greeter-pam-service)
541 "Return a PAM service for @command{lightdm-greeter}."
542 (pam-service
543 (name "lightdm-greeter")
544 (auth (list
545 ;; Load environment from /etc/environment and ~/.pam_environment.
546 (pam-entry (control "required") (module "pam_env.so"))
547 ;; Always let the greeter start without authentication.
548 (pam-entry (control "required") (module "pam_permit.so"))))
549 ;; No action required for account management
550 (account (list (pam-entry (control "required") (module "pam_permit.so"))))
551 ;; Prohibit changing password.
552 (password (list (pam-entry (control "required") (module "pam_deny.so"))))
553 ;; Setup session.
554 (session (list (pam-entry (control "required") (module "pam_unix.so"))))))
555
556(define (lightdm-autologin-pam-service)
557 "Return a PAM service for @command{lightdm-autologin}}."
558 (pam-service
559 (name "lightdm-autologin")
560 (auth
561 (list
562 ;; Block login if user is globally disabled.
563 (pam-entry (control "required") (module "pam_nologin.so"))
564 (pam-entry (control "required") (module "pam_succeed_if.so")
565 (arguments (list "uid >= 1000")))
566 ;; Allow access without authentication.
567 (pam-entry (control "required") (module "pam_permit.so"))))
568 ;; Stop autologin if account requires action.
569 (account (list (pam-entry (control "required") (module "pam_unix.so"))))
570 ;; Prohibit changing password.
571 (password (list (pam-entry (control "required") (module "pam_deny.so"))))
572 ;; Setup session.
573 (session (list (pam-entry (control "required") (module "pam_unix.so"))))))
574
575(define (lightdm-pam-services config)
576 (list (lightdm-pam-service config)
577 (lightdm-greeter-pam-service)
578 (lightdm-autologin-pam-service)))
579
580(define (lightdm-shepherd-service config)
581 "Return a <lightdm-service> for LightDM using CONFIG."
582
583 (validate-lightdm-configuration config)
584
585 (define lightdm-command
586 #~(list #$(file-append (lightdm-configuration-lightdm config)
587 "/sbin/lightdm")
588 #$@(if (lightdm-configuration-debug? config)
589 #~("--debug")
590 #~())))
591
592 (define lightdm-paths
593 (let ((lightdm (lightdm-configuration-lightdm config)))
594 #~(string-join
595 '#$(map (lambda (dir)
596 (file-append lightdm dir))
597 '("/bin" "/sbin" "/libexec"))
598 ":")))
599
600 (define data-dirs
601 ;; LightDM itself needs to be in XDG_DATA_DIRS for the accountsservice
602 ;; interface it provides to be picked up. The greeters must also be in
603 ;; XDG_DATA_DIRS to be found.
604 (let ((packages (lightdm-configuration->packages config)))
605 #~(string-join '#$(map (cut file-append <> "/share") packages)
606 ":")))
607
608 (list
609 (shepherd-service
610 (documentation "LightDM display manager")
611 (requirement '(pam dbus-system user-processes host-name))
612 (provision '(lightdm display-manager xorg-server))
613 (respawn? #f)
614 (start
615 ;; Note: sadly, environment variables defined for 'lightdm' are
616 ;; cleared and/or overridden by /etc/profile by its spawned greeters,
617 ;; so an out-of-band means such as /etc is required.
618 #~(make-forkexec-constructor #$lightdm-command
619 ;; Lightdm needs itself in its PATH.
620 #:environment-variables
621 (list
622 ;; It looks for greeter .desktop files as
623 ;; well as lightdm accountsservice
624 ;; interface in XDG_DATA_DIRS.
625 (string-append "XDG_DATA_DIRS="
626 #$data-dirs)
627 (string-append "PATH=" #$lightdm-paths))))
628 (stop #~(make-kill-destructor)))))
629
630(define (lightdm-etc-service config)
631 "Return a list of FILES for @var{etc-service-type} to build the
632/etc/lightdm directory using CONFIG"
633 (list `("lightdm" ,(lightdm-configuration-directory config))))
634
635(define lightdm-service-type
636 (handle-xorg-configuration
637 lightdm-configuration
638 (service-type
639 (name 'lightdm)
640 (default-value (lightdm-configuration))
641 (extensions
642 (list (service-extension pam-root-service-type lightdm-pam-services)
643 (service-extension shepherd-root-service-type
644 lightdm-shepherd-service)
645 (service-extension activation-service-type
646 (const %lightdm-activation))
647 (service-extension dbus-root-service-type
648 (compose list lightdm-configuration-lightdm))
649 (service-extension polkit-service-type
650 (compose list lightdm-configuration-lightdm))
651 (service-extension account-service-type
652 (const %lightdm-accounts))
653 ;; Add 'lightdm' to the system profile, so that its
654 ;; 'share/accountsservice' D-Bus service extension directory can be
655 ;; found via the 'XDG_DATA_DIRS=/run/current-system/profile/share'
656 ;; environment variable set in the wrapper of the
657 ;; libexec/accounts-daemon binary of the accountsservice package.
658 ;; This daemon is spawned by D-Bus, and there's little we can do to
659 ;; affect its environment. For more reading, see:
660 ;; https://github.com/NixOS/nixpkgs/issues/45059.
661 (service-extension profile-service-type
662 lightdm-configuration->packages)
663 ;; This is needed for lightdm and greeter
664 ;; to find their configuration
665 (service-extension etc-service-type
666 lightdm-etc-service)))
667 (description "Run @code{lightdm}, the LightDM graphical login manager."))))
668
669
670;;;
671;;; Generate documentation.
672;;;
673(define (generate-doc)
674 (configuration->documentation 'lightdm-configuration)
675 (configuration->documentation 'lightdm-gtk-greeter-configuration)
676 (configuration->documentation 'lightdm-seat-configuration))