aboutsummaryrefslogtreecommitdiff
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2015, 2018 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (gnu system nss)
  #:use-module (rnrs enums)
  #:use-module (guix records)
  #:use-module (srfi srfi-9)
  #:use-module (ice-9 match)
  #:export (name-service-switch?
            name-service-switch
            name-service?
            name-service

            lookup-specification

            %default-nss
            %mdns-host-lookup-nss

            %files
            %compat
            %dns

            name-service-switch->string))

;;; Commentary:
;;;
;;; Bindings for libc's name service switch (NSS) configuration.
;;;
;;; Code:

(define-record-type* <name-service> name-service
  make-name-service
  name-service?
  (name     name-service-name)
  (reaction name-service-reaction
            (default (lookup-specification))))

;; Lookup specification (info "(libc) Actions in the NSS Configuration").

(define-enumeration lookup-action
  (return continue)
  make-lookup-action)

(define-enumeration lookup-status
  (success
   not-found
   unavailable
   try-again)
  make-lookup-status)

(define-record-type <lookup-status-negation>
  (lookup-status-negation status)
  lookup-status-negation?
  (status lookup-status-negation-status))

(define-record-type <lookup-reaction>
  (make-lookup-reaction status action)
  lookup-reaction?
  (status  lookup-reaction-status)
  (action  lookup-reaction-action))

(define-syntax lookup-reaction
  (syntax-rules (not =>)
    ((_ ((not status) => action))
     (make-lookup-reaction (lookup-status-negation (lookup-status status))
                           (lookup-action action)))
    ((_ (status => action))
     (make-lookup-reaction (lookup-status status)
                           (lookup-action action)))))

(define-syntax-rule (lookup-specification reaction ...)
  "Return an NSS lookup specification."
  (list (lookup-reaction reaction) ...))


;;;
;;; Common name services and default NSS configuration.
;;;

(define %compat
  ;; Note: Starting from version 2.26, libc no longer provides libnss_compat
  ;; so this specification has become useless.
  (name-service
    (name "compat")
    (reaction (lookup-specification (not-found => return)))))

(define %files
  (name-service (name "files")))

(define %dns
  ;; DNS is supposed to be authoritative, so unless it's unavailable, return
  ;; what it finds.
  (name-service
    (name "dns")
    (reaction (lookup-specification ((not unavailable) => return)))))

;; The NSS.  We list all the databases here because that allows us to
;; statically ensure that the user's configuration refers to existing
;; databases.  See libc/nss/databases.def for the list of databases.  Default
;; values obtained by looking for "DEFAULT_CONFIG" in libc/nss/*.c.
;;
;; Although libc places 'dns' before 'files' in the default configurations of
;; the 'hosts' and 'networks' databases, we choose to put 'files' before 'dns'
;; by default, so that users can override host/address mappings in /etc/hosts
;; and bypass DNS to improve their privacy and escape NSA's MORECOWBELL.
(define-record-type* <name-service-switch> name-service-switch
  make-name-service-switch
  name-service-switch?
  (aliases    name-service-switch-aliases
              (default '()))
  (ethers     name-service-switch-ethers
              (default '()))
  (group      name-service-switch-group
              (default (list %files)))
  (gshadow    name-service-switch-gshadow
              (default '()))
  (hosts      name-service-switch-hosts
              (default (list %files %dns)))
  (initgroups name-service-switch-initgroups
              (default '()))
  (netgroup   name-service-switch-netgroup
              (default '()))
  (networks   name-service-switch-networks
              (default (list %files %dns)))
  (password   name-service-switch-password
              (default (list %files)))
  (public-key name-service-switch-public-key
              (default '()))
  (rpc        name-service-switch-rpc
              (default '()))
  (services   name-service-switch-services
              (default '()))
  (shadow     name-service-switch-shadow
              (default (list %files))))

(define %default-nss
  ;; Default NSS configuration.
  (name-service-switch))

(define %mdns-host-lookup-nss
  (name-service-switch
    (hosts (list %files                           ;first, check /etc/hosts

                 ;; If the above did not succeed, try with 'mdns_minimal'.
                 (name-service
                   (name "mdns_minimal")

                   ;; 'mdns_minimal' is authoritative for '.local'.  When it
                   ;; returns "not found", no need to try the next methods.
                   (reaction (lookup-specification
                              (not-found => return))))

                 ;; Then fall back to DNS.
                 (name-service
                   (name "dns"))

                 ;; Finally, try with the "full" 'mdns'.
                 (name-service
                   (name "mdns"))))))


;;;
;;; Serialization.
;;;

(define (lookup-status->string status)
  (match status
    ('success     "SUCCESS")
    ('not-found   "NOTFOUND")
    ('unavailable "UNAVAIL")
    ('try-again   "TRYAGAIN")
    (($ <lookup-status-negation> status)
     (string-append "!" (lookup-status->string status)))))

(define lookup-reaction->string
  (match-lambda
   (($ <lookup-reaction> status action)
    (string-append (lookup-status->string status) "="
                   (symbol->string action)))))

(define name-service->string
  (match-lambda
   (($ <name-service> name ())
    name)
   (($ <name-service> name reactions)
    (string-append name " ["
                   (string-join (map lookup-reaction->string reactions))
                   "]"))))

(define (name-service-switch->string nss)
  "Return the 'nsswitch.conf' contents for NSS as a string.  See \"NSS
Configuration File\" in the libc manual."
  (let-syntax ((->string
                (syntax-rules ()
                  ((_ name field)
                   (match (field nss)
                     (()                          ;keep the default config
                      "")
                     ((services (... ...))
                      (string-append name ":\t"
                                     (string-join
                                      (map name-service->string services))
                                     "\n")))))))
    (string-append (->string "aliases"    name-service-switch-aliases)
                   (->string "ethers"     name-service-switch-ethers)
                   (->string "group"      name-service-switch-group)
                   (->string "gshadow"    name-service-switch-gshadow)
                   (->string "hosts"      name-service-switch-hosts)
                   (->string "initgroups" name-service-switch-initgroups)
                   (->string "netgroup"   name-service-switch-netgroup)
                   (->string "networks"   name-service-switch-networks)
                   (->string "passwd"     name-service-switch-password)
                   (->string "publickey"  name-service-switch-public-key)
                   (->string "rpc"        name-service-switch-rpc)
                   (->string "services"   name-service-switch-services)
                   (->string "shadow"     name-service-switch-shadow))))

;;; Local Variables:
;;; eval: (put 'name-service 'scheme-indent-function 0)
;;; eval: (put 'name-service-switch 'scheme-indent-function 0)
;;; End:

;;; nss.scm ends here
usage output to the bottom Maxim Cournoyer 2022-12-27snippets: Remove unwanted git-commit-mode invocation....We only need to check if git-commit-mode is t, not enable it in all text-mode buffers. * etc/snippets/tempel/text-mode: Remove unwanted git-commit-mode invocation. Andrew Tropin 2022-12-26teams: Add 宋文武....* etc/team.scm.in: Add 宋文武. Signed-off-by: Ludovic Courtès <ludo@gnu.org> 宋文武 2022-12-26teams: Add localization....* etc/teams.scm.in (localization): New team. Signed-off-by: Ludovic Courtès <ludo@gnu.org> 宋文武 2022-12-23etc: SELinux: Allow init process to setattr on profile directories....* etc/guix-daemon.cil.in: Add rule. Ricardo Wurmus 2022-12-23etc: SELinux: Allow daemon to search run state directories....* etc/guix-daemon.cil.in: Import types init_var_run_t and system_dbusd_var_run_t; add rules. Ricardo Wurmus 2022-12-23etc: SELinux: Label guix-daemon executable in profile....* etc/guix-daemon.cil.in: Add file rule for "guix-daemon" in current-guix profile. Ricardo Wurmus 2022-12-11teams: Add Tobias Geerinckx-Rice....* etc/teams.scm.in: Add Tobias Geerinckx-Rice. Tobias Geerinckx-Rice 2022-12-16guix-install.sh: Directly exit in case of errors in chk_require....* etc/guix-install.sh (chk_require): Directly exit in case of errors in chk_require, instead of relying on 'set -e'. Maxim Cournoyer 2022-12-16guix-install.sh: Add missing "useradd" command....* etc/guix-install.sh: (REQUIRE): Add missing "useradd" command. Maxim Cournoyer 2022-12-11guix-install.sh: Gracefully fail on | bash....* etc/guix-install.sh (welcome): Print an error message and a hint if the first read fails. Tobias Geerinckx-Rice 2022-12-11news: Fix typos in French text....* etc/news.scm: Fix typos. Signed-off-by: Julien Lepiller <julien@lepiller.eu> Vivien Kraus via Guix-patches via 2022-12-10news: Add 'fr' translation....* etc/news.scm: Add French translation of 'customize-linux' entry. Julien Lepiller 2022-12-09guix-install.sh: Authorize all project build farms at once....* etc/guix-install.sh (sys_authorize_build_farms): Iterate over all hosts. Co-authored-by: Ludovic Courtès <ludo@gnu.org> Tobias Geerinckx-Rice 2022-12-09teams: science: Add modules to the scope....* etc/teams.scm.in (science): Add algebra, astronomy, geo, chemestry, maths modules to the scope. Signed-off-by: 宋文武 <iyzsong@member.fsf.org> Sharlatan Hellseher 2022-12-08news: Add 'de' translation....* etc/news.scm: Add German translation of 'customize-linux' entry. Florian Pelz 2022-12-07news: Add entry for 'customize-linux'....* etc/news.scm: Add entry. Maxim Cournoyer 2022-12-05Merge branch 'version-1.4.0'Ludovic Courtès 2022-11-28maint: Leave 'gcc-toolchain' out for i586-gnu....This is a temporary measure to work around the fact that we're currently lacking the necessary CPU power and human power to build everything up to 'gcc-toolchain'. * etc/release-manifest.scm (%base-packages/hurd): Comment out "gcc-toolchain" for now. Ludovic Courtès 2022-12-02etc: teams: Add chez.scm to Racket team's scope....Racket's variant of Chez Scheme is defined in that file. * etc/teams.scm.in (racket)[#:scope]: Add gnu/packages/chez.scm. Signed-off-by: Ludovic Courtès <ludo@gnu.org> Philip McGrath 2022-11-28snippets: yas: Add snippets for vc.el...* etc/snippets/yas/log-edit-mode/guix-vc-commit-message-add-package: * etc/snippets/yas/log-edit-mode/guix-vc-commit-message-remove-package: * etc/snippets/yas/log-edit-mode/guix-vc-commit-message-rename-package: * etc/snippets/yas/log-edit-mode/guix-vc-commit-message-update-package: * etc/snippets/yas/log-edit-mode/guix-vc-commit-message-use-https-home-page: New file Signed-off-by: Ludovic Courtès <ludo@gnu.org> Morgan Smith 2022-11-16guix-install.sh: Expand mktemp template for busybox compatibility....Fixes <https://issues.guix.gnu.org/58858>. * etc/guix-install.sh (main): Use 6 'X' characters in the template, as this is the minimum required by Busybox's mktemp (which matches glibc's mktemp behavior). Reported-by: conses <contact@conses.eu> Maxim Cournoyer 2022-11-16news: Add 'de' translation....* etc/news.scm: Add German translation of '--symlink' entry. Florian Pelz 2022-11-15news: Add entry for 'guix shell --symlink'....* etc/news.scm: Add entry. Maxim Cournoyer 2022-11-15etc/news.scm: Normalize indentation....* etc/news.scm: Normalize indentation. Maxim Cournoyer 2022-11-14guix-install.sh: Remove unnecessary XDG_DATA_DIRS export....This started out as a bug-fix for a GUI login loop that was resulting from XDG_DATA_DIRS not including any of the host distro's directories. The solution was to export the vari- able (with fail-safe defaults) before source-ing GUIX_PROFILE/etc/profile. It turns out changes have already been made to ensure that XDG_DATA_DIRS, etc. are always exported before anything guix-specific. So, this export is no longer necessary. For reference, the aforementioned bug was found on a Debian 11 machine and it's guix.sh init profile for guix version 1.2. * etc/guix-install.sh (sys_create_init_profile): Remove unnecessary XDG_DATA_DIRS export. Signed-off-by: 宋文武 <iyzsong@member.fsf.org> Prafulla Giri 2022-11-12teams: Add Raghav Gururajan....* etc/teams.scm.in: Add Raghav Gururajan. Raghav Gururajan 2022-11-12Revert "teams: Add Raghav Gururajan."...This reverts commit 56aebf7f7cbb3781c3f470902f43b361f85cba3e. Raghav Gururajan 2022-11-12teams: Add Raghav Gururajan....* etc/teams.scm.in: Add Raghav Gururajan. Raghav Gururajan