Add (guix monads).
[jackhill/guix/guix.git] / gnu / system / linux.scm
CommitLineData
0ded70f3
LC
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2013 Ludovic Courtès <ludo@gnu.org>
3;;;
4;;; This file is part of GNU Guix.
5;;;
6;;; GNU Guix is free software; you can redistribute it and/or modify it
7;;; under the terms of the GNU General Public License as published by
8;;; the Free Software Foundation; either version 3 of the License, or (at
9;;; your option) any later version.
10;;;
11;;; GNU Guix is distributed in the hope that it will be useful, but
12;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
18
19(define-module (gnu system linux)
20 #:use-module (guix store)
21 #:use-module (guix records)
22 #:use-module (guix derivations)
23 #:use-module (ice-9 match)
24 #:use-module (srfi srfi-1)
25 #:use-module (srfi srfi-26)
26 #:use-module ((guix utils) #:select (%current-system))
27 #:export (pam-service
28 pam-entry
29 pam-services->directory
30 %pam-other-services
31 unix-pam-service))
32
33;;; Commentary:
34;;;
35;;; Configuration of Linux-related things, including pluggable authentication
36;;; modules (PAM).
37;;;
38;;; Code:
39
40;; PAM services (see
41;; <http://www.linux-pam.org/Linux-PAM-html/sag-configuration-file.html>.)
42(define-record-type* <pam-service> pam-service
43 make-pam-service
44 pam-service?
45 (name pam-service-name) ; string
46
47 ;; The four "management groups".
48 (account pam-service-account ; list of <pam-entry>
49 (default '()))
50 (auth pam-service-auth
51 (default '()))
52 (password pam-service-password
53 (default '()))
54 (session pam-service-session
55 (default '())))
56
57(define-record-type* <pam-entry> pam-entry
58 make-pam-entry
59 pam-entry?
60 (control pam-entry-control) ; string
61 (module pam-entry-module) ; file name
62 (arguments pam-entry-arguments ; list of strings
63 (default '())))
64
65(define (pam-service->configuration service)
66 "Return the configuration string for SERVICE, to be dumped in
67/etc/pam.d/NAME, where NAME is the name of SERVICE."
68 (define (entry->string type entry)
69 (match entry
70 (($ <pam-entry> control module (arguments ...))
71 (string-append type " "
72 control " " module " "
73 (string-join arguments)
74 "\n"))))
75
76 (match service
77 (($ <pam-service> name account auth password session)
78 (string-concatenate
79 (append (map (cut entry->string "account" <>) account)
80 (map (cut entry->string "auth" <>) auth)
81 (map (cut entry->string "password" <>) password)
82 (map (cut entry->string "session" <>) session))))))
83
84(define (pam-services->directory store services)
85 "Return the derivation to build the configuration directory to be used as
86/etc/pam.d for SERVICES."
87 (let ((names (map pam-service-name services))
88 (files (map (match-lambda
89 ((and service ($ <pam-service> name))
90 (let ((config (pam-service->configuration service)))
91 (add-text-to-store store
92 (string-append name ".pam")
93 config '()))))
94 services)))
95 (define builder
96 '(begin
97 (use-modules (ice-9 match))
98
99 (let ((out (assoc-ref %outputs "out")))
100 (mkdir out)
101 (for-each (match-lambda
102 ((name . file)
103 (symlink file (string-append out "/" name))))
104 %build-inputs)
105 #t)))
106
107 (build-expression->derivation store "pam.d" (%current-system)
108 builder
109 (zip names files))))
110
111(define %pam-other-services
112 ;; The "other" PAM configuration, which denies everything (see
113 ;; <http://www.linux-pam.org/Linux-PAM-html/sag-configuration-example.html>.)
114 (let ((deny (pam-entry
115 (control "required")
116 (module "pam_deny.so"))))
117 (pam-service
118 (name "other")
119 (account (list deny))
120 (auth (list deny))
121 (password (list deny))
122 (session (list deny)))))
123
124(define unix-pam-service
125 (let ((unix (pam-entry
126 (control "required")
127 (module "pam_unix.so"))))
43a27798 128 (lambda* (name #:key allow-empty-passwords? motd)
0ded70f3 129 "Return a standard Unix-style PAM service for NAME. When
43a27798
LC
130ALLOW-EMPTY-PASSWORDS? is true, allow empty passwords. When MOTD is true, it
131should be the name of a file used as the message-of-the-day."
0ded70f3
LC
132 ;; See <http://www.linux-pam.org/Linux-PAM-html/sag-configuration-example.html>.
133 (let ((name* name))
134 (pam-service
135 (name name*)
136 (account (list unix))
137 (auth (list (if allow-empty-passwords?
138 (pam-entry
139 (control "required")
140 (module "pam_unix.so")
141 (arguments '("nullok")))
142 unix)))
143 (password (list unix))
43a27798
LC
144 (session (if motd
145 (list unix
146 (pam-entry
147 (control "optional")
148 (module "pam_motd.so")
149 (arguments (list (string-append "motd=" motd)))))
150 (list unix))))))))
0ded70f3
LC
151
152;;; linux.scm ends here