gnu: Add aisleriot.
[jackhill/guix/guix.git] / gnu / system / nss.scm
CommitLineData
996ed739
LC
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2015 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 nss)
20 #:use-module (rnrs enums)
21 #:use-module (guix records)
22 #:use-module (srfi srfi-9)
23 #:use-module (ice-9 match)
24 #:export (name-service-switch?
25 name-service-switch
26 name-service?
27 name-service
28
29 lookup-specification
30
31 %default-nss
32 %files
33 %compat
34 %dns
35
36 name-service-switch->string))
37
38;;; Commentary:
39;;;
40;;; Bindings for libc's name service switch (NSS) configuration.
41;;;
42;;; Code:
43
44(define-record-type* <name-service> name-service
45 make-name-service
46 name-service?
47 (name name-service-name)
48 (reaction name-service-reaction
49 (default (lookup-specification))))
50
51;; Lookup specification (info "(libc) Actions in the NSS Configuration").
52
53(define-enumeration lookup-action
54 (return continue)
55 make-lookup-action)
56
57(define-enumeration lookup-status
58 (success
59 not-found
60 unavailable
61 try-again)
62 make-lookup-status)
63
64(define-record-type <lookup-status-negation>
65 (lookup-status-negation status)
66 lookup-status-negation?
67 (status lookup-status-negation-status))
68
69(define-record-type <lookup-reaction>
70 (make-lookup-reaction status action)
71 lookup-reaction?
72 (status lookup-reaction-status)
73 (action lookup-reaction-action))
74
75(define-syntax lookup-reaction
76 (syntax-rules (not =>)
77 ((_ ((not status) => action))
78 (make-lookup-reaction (lookup-status-negation (lookup-status status))
79 (lookup-action action)))
80 ((_ (status => action))
81 (make-lookup-reaction (lookup-status status)
82 (lookup-action action)))))
83
84(define-syntax-rule (lookup-specification reaction ...)
85 "Return an NSS lookup specification."
86 (list (lookup-reaction reaction) ...))
87
88\f
89;;;
90;;; Common name services and default NSS configuration.
91;;;
92
93(define %compat
94 (name-service
95 (name "compat")
96 (reaction (lookup-specification (not-found => return)))))
97
98(define %files
99 (name-service (name "files")))
100
101(define %dns
102 ;; DNS is supposed to be authoritative, so unless it's unavailable, return
103 ;; what it finds.
104 (name-service
105 (name "dns")
106 (reaction (lookup-specification ((not unavailable) => return)))))
107
108;; The NSS. We list all the databases here because that allows us to
109;; statically ensure that the user's configuration refers to existing
110;; databases. See libc/nss/databases.def for the list of databases. Default
111;; values obtained by looking for "DEFAULT_CONFIG" in libc/nss/*.c.
112;;
113;; Although libc places 'dns' before 'files' in the default configurations of
114;; the 'hosts' and 'networks' databases, we choose to put 'files' before 'dns'
115;; by default, so that users can override host/address mappings in /etc/hosts
116;; and bypass DNS to improve their privacy and escape NSA's MORECOWBELL.
117(define-record-type* <name-service-switch> name-service-switch
118 make-name-service-switch
119 name-service-switch?
120 (aliases name-service-switch-aliases
121 (default '()))
122 (ethers name-service-switch-ethers
123 (default '()))
124 (group name-service-switch-group
125 (default (list %compat %files)))
126 (gshadow name-service-switch-gshadow
127 (default '()))
128 (hosts name-service-switch-hosts
129 (default (list %files %dns)))
130 (initgroups name-service-switch-initgroups
131 (default '()))
132 (netgroup name-service-switch-netgroup
133 (default '()))
134 (networks name-service-switch-networks
135 (default (list %files %dns)))
136 (password name-service-switch-password
137 (default (list %compat %files)))
138 (public-key name-service-switch-public-key
139 (default '()))
140 (rpc name-service-switch-rpc
141 (default '()))
142 (services name-service-switch-services
143 (default '()))
144 (shadow name-service-switch-shadow
145 (default (list %compat %files))))
146
147(define %default-nss
148 ;; Default NSS configuration.
149 (name-service-switch))
150
151\f
152;;;
153;;; Serialization.
154;;;
155
156(define (lookup-status->string status)
157 (match status
158 ('success "SUCCESS")
159 ('not-found "NOTFOUND")
160 ('unavailable "UNAVAIL")
161 ('try-again "TRYAGAIN")
162 (($ <lookup-status-negation> status)
163 (string-append "!" (lookup-status->string status)))))
164
165(define lookup-reaction->string
166 (match-lambda
167 (($ <lookup-reaction> status action)
168 (string-append (lookup-status->string status) "="
169 (symbol->string action)))))
170
171(define name-service->string
172 (match-lambda
173 (($ <name-service> name ())
174 name)
175 (($ <name-service> name reactions)
176 (string-append name " ["
177 (string-join (map lookup-reaction->string reactions))
178 "]"))))
179
180(define (name-service-switch->string nss)
181 "Return the 'nsswitch.conf' contents for NSS as a string. See \"NSS
182Configuration File\" in the libc manual."
183 (let-syntax ((->string
184 (syntax-rules ()
185 ((_ name field)
186 (match (field nss)
187 (() ;keep the default config
188 "")
189 ((services (... ...))
190 (string-append name ":\t"
191 (string-join
192 (map name-service->string services))
193 "\n")))))))
194 (string-append (->string "aliases" name-service-switch-aliases)
195 (->string "ethers" name-service-switch-ethers)
196 (->string "group" name-service-switch-group)
197 (->string "gshadow" name-service-switch-gshadow)
198 (->string "hosts" name-service-switch-hosts)
199 (->string "initgroups" name-service-switch-initgroups)
200 (->string "netgroup" name-service-switch-netgroup)
201 (->string "networks" name-service-switch-networks)
202 (->string "passwd" name-service-switch-password)
203 (->string "publickey" name-service-switch-public-key)
204 (->string "rpc" name-service-switch-rpc)
205 (->string "services" name-service-switch-services)
206 (->string "shadow" name-service-switch-shadow))))
207
208;;; Local Variables:
209;;; eval: (put 'name-service 'scheme-indent-function 0)
210;;; eval: (put 'name-service-switch 'scheme-indent-function 0)
211;;; End:
212
213;;; nss.scm ends here