From d9959421a54fb0f9fbb2a9016da036319b99adb9 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Wed, 6 May 2015 18:23:27 +0200 Subject: system: /etc/profile sources each profile's /etc/profile. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Partly fixes . Reported by 宋文武 . * gnu/system.scm (etc-directory)[profile]: Source /run/current-system/profile/etc/profile and $HOME/.guix-profile/etc/profile when available. Move definitions of SSL_CERT_DIR, SSL_CERT_FILE, and GIT_SSL_CAINFO before that. --- gnu/system.scm | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) (limited to 'gnu/system.scm') diff --git a/gnu/system.scm b/gnu/system.scm index 609604a9b5..104b223539 100644 --- a/gnu/system.scm +++ b/gnu/system.scm @@ -461,14 +461,40 @@ (define* (etc-directory #:key # Tell 'modprobe' & co. where to look for modules. export LINUX_MODULE_DIRECTORY=/run/booted-system/kernel/lib/modules -export PATH=$HOME/.guix-profile/bin:/run/current-system/profile/bin -export PATH=/run/setuid-programs:/run/current-system/profile/sbin:$PATH +# These variables are honored by OpenSSL (libssl) and Git. +export SSL_CERT_DIR=/etc/ssl/certs +export SSL_CERT_FILE=\"$SSL_CERT_DIR/ca-certificates.crt\" +export GIT_SSL_CAINFO=\"$SSL_CERT_FILE\" + +# Crucial variables that could be missing the the profiles' 'etc/profile' +# because they would require combining both profiles. +# FIXME: See . export MANPATH=$HOME/.guix-profile/share/man:/run/current-system/profile/share/man export INFOPATH=$HOME/.guix-profile/share/info:/run/current-system/profile/share/info - export XDG_DATA_DIRS=$HOME/.guix-profile/share:/run/current-system/profile/share export XDG_CONFIG_DIRS=$HOME/.guix-profile/etc/xdg:/run/current-system/profile/etc/xdg +# Ignore the default value of 'PATH'. +unset PATH + +# Load the system profile's settings. +GUIX_PROFILE=/run/current-system/profile \\ +source /run/current-system/profile/etc/profile + +# Prepend setuid programs. +export PATH=/run/setuid-programs:$PATH + +if [ -d \"$HOME/.guix-profile\" ] +then + # Load the user profile's settings. + GUIX_PROFILE=\"$HOME/.guix-profile\" \\ + source \"$HOME/.guix-profile/etc/profile\" +else + # At least define this one so that basic things just work + # when the user installs their first package. + export PATH=\"$HOME/.guix-profile/bin:$PATH\" +fi + # Append the directory of 'site-start.el' to the search path. export EMACSLOADPATH=:/etc/emacs @@ -476,11 +502,6 @@ (define* (etc-directory #:key # when /etc/machine-id is missing. Make sure these warnings are non-fatal. export DBUS_FATAL_WARNINGS=0 -# These variables are honored by OpenSSL (libssl) and Git. -export SSL_CERT_DIR=/etc/ssl/certs -export SSL_CERT_FILE=\"$SSL_CERT_DIR/ca-certificates.crt\" -export GIT_SSL_CAINFO=\"$SSL_CERT_FILE\" - # Allow Aspell to find dictionaries installed in the user profile. export ASPELL_CONF=\"dict-dir $HOME/.guix-profile/lib/aspell\" -- cgit v1.2.3 From 507c71d629d6aacf47e03a94eaf0c6b9ef45c367 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Thu, 7 May 2015 09:43:59 +0200 Subject: system: Check whether ~/.guix-profile/etc/profile exists. * gnu/system.scm (etc-directory)[profile]: Check for ~/.guix-profile/etc/profile rather than just ~/.guix-profile. --- gnu/system.scm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gnu/system.scm') diff --git a/gnu/system.scm b/gnu/system.scm index 104b223539..66574c10cb 100644 --- a/gnu/system.scm +++ b/gnu/system.scm @@ -484,7 +484,7 @@ (define* (etc-directory #:key # Prepend setuid programs. export PATH=/run/setuid-programs:$PATH -if [ -d \"$HOME/.guix-profile\" ] +if [ -f \"$HOME/.guix-profile/etc/profile\" ] then # Load the user profile's settings. GUIX_PROFILE=\"$HOME/.guix-profile\" \\ -- cgit v1.2.3 From 669786da9103c554fb474187ddab7b7c88f8e89d Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Thu, 7 May 2015 09:45:45 +0200 Subject: system: Use "." instead of "source" in /etc/profile. * gnu/system.scm (etc-directory)[profile]: Use "." instead of "source", the latter being Bash-specific. --- gnu/system.scm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'gnu/system.scm') diff --git a/gnu/system.scm b/gnu/system.scm index 66574c10cb..b8d0e62f60 100644 --- a/gnu/system.scm +++ b/gnu/system.scm @@ -479,7 +479,7 @@ (define* (etc-directory #:key # Load the system profile's settings. GUIX_PROFILE=/run/current-system/profile \\ -source /run/current-system/profile/etc/profile +. /run/current-system/profile/etc/profile # Prepend setuid programs. export PATH=/run/setuid-programs:$PATH @@ -488,7 +488,7 @@ (define* (etc-directory #:key then # Load the user profile's settings. GUIX_PROFILE=\"$HOME/.guix-profile\" \\ - source \"$HOME/.guix-profile/etc/profile\" + . \"$HOME/.guix-profile/etc/profile\" else # At least define this one so that basic things just work # when the user installs their first package. @@ -508,7 +508,7 @@ (define* (etc-directory #:key if [ -n \"$BASH_VERSION\" -a -f /etc/bashrc ] then # Load Bash-specific initialization code. - source /etc/bashrc + . /etc/bashrc fi ")) -- cgit v1.2.3 From 0c09a306e59e2feec9818335b0b4f3355c02f420 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Sun, 24 May 2015 18:02:54 +0200 Subject: system: Make sure user accounts refer to existing groups. Fixes . Reported by David Thompson . * gnu/system/shadow.scm (assert-valid-users/groups): New procedure * gnu/system.scm (operating-system-activation-script): Use it. * tests/guix-system.sh (make_user_config): New function. Add 3 tests using it. * po/guix/POTFILES.in: Add gnu/system/shadow.scm. --- gnu/system.scm | 2 ++ gnu/system/shadow.scm | 35 ++++++++++++++++++++++++++++++++++- po/guix/POTFILES.in | 1 + tests/guix-system.sh | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 1 deletion(-) (limited to 'gnu/system.scm') diff --git a/gnu/system.scm b/gnu/system.scm index b8d0e62f60..79de80a3eb 100644 --- a/gnu/system.scm +++ b/gnu/system.scm @@ -686,6 +686,8 @@ (define groups (define group-specs (map user-group->gexp groups)) + (assert-valid-users/groups accounts groups) + (gexp->file "activate" #~(begin (eval-when (expand load eval) diff --git a/gnu/system/shadow.scm b/gnu/system/shadow.scm index 16b9e4b555..a778b87306 100644 --- a/gnu/system/shadow.scm +++ b/gnu/system/shadow.scm @@ -21,12 +21,17 @@ (define-module (gnu system shadow) #:use-module (guix gexp) #:use-module (guix store) #:use-module (guix monads) + #:use-module (guix sets) + #:use-module (guix ui) #:use-module ((gnu system file-systems) #:select (%tty-gid)) #:use-module ((gnu packages admin) #:select (shadow)) #:use-module (gnu packages bash) #:use-module (gnu packages guile-wm) + #:use-module (srfi srfi-26) + #:use-module (srfi srfi-34) + #:use-module (srfi srfi-35) #:export (user-account user-account? user-account-name @@ -48,7 +53,8 @@ (define-module (gnu system shadow) default-skeletons skeleton-directory - %base-groups)) + %base-groups + assert-valid-users/groups)) ;;; Commentary: ;;; @@ -176,4 +182,31 @@ (define (skeleton-directory skeletons) '#$skeletons) #t))) +(define (assert-valid-users/groups users groups) + "Raise an error if USERS refer to groups not listed in GROUPS." + (let ((groups (list->set (map user-group-name groups)))) + (define (validate-supplementary-group user group) + (unless (set-contains? groups group) + (raise (condition + (&message + (message + (format #f (_ "supplementary group '~a' \ +of user '~a' is undeclared") + group + (user-account-name user)))))))) + + (for-each (lambda (user) + (unless (set-contains? groups (user-account-group user)) + (raise (condition + (&message + (message + (format #f (_ "primary group '~a' \ +of user '~a' is undeclared") + (user-account-group user) + (user-account-name user))))))) + + (for-each (cut validate-supplementary-group user <>) + (user-account-supplementary-groups user))) + users))) + ;;; shadow.scm ends here diff --git a/po/guix/POTFILES.in b/po/guix/POTFILES.in index 30ce28b712..59f353e427 100644 --- a/po/guix/POTFILES.in +++ b/po/guix/POTFILES.in @@ -3,6 +3,7 @@ gnu/packages.scm gnu/system.scm gnu/services/dmd.scm +gnu/system/shadow.scm guix/scripts/build.scm guix/scripts/download.scm guix/scripts/package.scm diff --git a/tests/guix-system.sh b/tests/guix-system.sh index 1b77d1a0db..7008ef8031 100644 --- a/tests/guix-system.sh +++ b/tests/guix-system.sh @@ -76,3 +76,42 @@ then else grep "service 'networking'.*more than once" "$errorfile" fi + +make_user_config () +{ + cat > "$tmpfile" < "$errorfile" +then false +else grep "primary group.*group-that-does-not-exist.*undeclared" "$errorfile"; fi + +make_user_config "users" "group-that-does-not-exist" +if guix system build "$tmpfile" -n 2> "$errorfile" +then false +else grep "supplementary group.*group-that-does-not-exist.*undeclared" "$errorfile"; fi -- cgit v1.2.3 From bf87f38ace7f0cbad5558c1ef027b9f02988e393 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Mon, 25 May 2015 16:54:05 +0200 Subject: system: Define '%base-user-accounts'. * gnu/system/shadow.scm (%base-user-accounts): New variable. * gnu/system.scm ()[users]: Use it as the default value. * gnu/system/examples/bare-bones.tmpl (users): Use it. * gnu/system/examples/desktop.tmpl (users): Likewise. * doc/guix.texi (operating-system Reference, User Accounts): Adjust accordingly. --- doc/guix.texi | 10 +++++++++- gnu/system.scm | 2 +- gnu/system/examples/bare-bones.tmpl | 5 +++-- gnu/system/examples/desktop.tmpl | 5 +++-- gnu/system/shadow.scm | 11 +++++++++++ 5 files changed, 27 insertions(+), 6 deletions(-) (limited to 'gnu/system.scm') diff --git a/doc/guix.texi b/doc/guix.texi index cfb626c705..6507b9c436 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -4453,7 +4453,7 @@ A list of strings identifying devices to be used for ``swap space'' (@pxref{Memory Concepts,,, libc, The GNU C Library Reference Manual}). For example, @code{'("/dev/sda3")}. -@item @code{users} (default: @code{'()}) +@item @code{users} (default: @code{%base-user-accounts}) @itemx @code{groups} (default: @var{%base-groups}) List of user accounts and groups. @xref{User Accounts}. @@ -4832,6 +4832,14 @@ to be present on the system. This includes groups such as ``root'', specific devices such as ``audio'', ``disk'', and ``cdrom''. @end defvr +@defvr {Scheme Variable} %base-user-accounts +This is the list of basic system accounts that programs may expect to +find on a GNU/Linux system, such as the ``nobody'' account. + +Note that the ``root'' account is not included here. It is a +special-case and is automatically added whether or not it is specified. +@end defvr + @node Locales @subsection Locales diff --git a/gnu/system.scm b/gnu/system.scm index 79de80a3eb..c4a3bee0eb 100644 --- a/gnu/system.scm +++ b/gnu/system.scm @@ -119,7 +119,7 @@ (define-record-type* operating-system (default '())) (users operating-system-users ; list of user accounts - (default '())) + (default %base-user-accounts)) (groups operating-system-groups ; list of user groups (default %base-groups)) diff --git a/gnu/system/examples/bare-bones.tmpl b/gnu/system/examples/bare-bones.tmpl index 8f4faca2d3..dc5cfc81a4 100644 --- a/gnu/system/examples/bare-bones.tmpl +++ b/gnu/system/examples/bare-bones.tmpl @@ -23,7 +23,7 @@ ;; This is where user accounts are specified. The "root" ;; account is implicit, and is initially created with the ;; empty password. - (users (list (user-account + (users (cons (user-account (name "alice") (comment "Bob's sister") (group "users") @@ -34,7 +34,8 @@ ;; and access the webcam. (supplementary-groups '("wheel" "audio" "video")) - (home-directory "/home/alice")))) + (home-directory "/home/alice")) + %base-user-accounts)) ;; Globally-installed packages. (packages (cons tcpdump %base-packages)) diff --git a/gnu/system/examples/desktop.tmpl b/gnu/system/examples/desktop.tmpl index c78188eb61..988b8f937f 100644 --- a/gnu/system/examples/desktop.tmpl +++ b/gnu/system/examples/desktop.tmpl @@ -20,13 +20,14 @@ (type "ext4")) %base-file-systems)) - (users (list (user-account + (users (cons (user-account (name "bob") (comment "Alice's brother") (group "users") (supplementary-groups '("wheel" "netdev" "audio" "video")) - (home-directory "/home/bob")))) + (home-directory "/home/bob")) + %base-user-accounts)) ;; Add Xfce and Ratpoison; that allows us to choose ;; sessions using either of these at the log-in screen. diff --git a/gnu/system/shadow.scm b/gnu/system/shadow.scm index a778b87306..aa97652678 100644 --- a/gnu/system/shadow.scm +++ b/gnu/system/shadow.scm @@ -54,6 +54,7 @@ (define-module (gnu system shadow) default-skeletons skeleton-directory %base-groups + %base-user-accounts assert-valid-users/groups)) ;;; Commentary: @@ -113,6 +114,16 @@ (define %base-groups (system-group (name "tape")) (system-group (name "kvm"))))) ; for /dev/kvm +(define %base-user-accounts + ;; List of standard user accounts. Note that "root" is a special case, so + ;; it's not listed here. + (list (user-account + (name "nobody") + (uid 65534) + (group "nogroup") + (home-directory "/var/empty") + (system? #t)))) + (define (default-skeletons) "Return the default skeleton files for /etc/skel. These files are copied by 'useradd' in the home directory of newly created user accounts." -- cgit v1.2.3 From 847658395e399d6d4ef21a247dbad02a9c921400 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Fri, 5 Jun 2015 20:22:47 +0200 Subject: system: 'sudoers' is now a file-like object. Partly fixes Reported by Alex Kost . * gnu/system.scm (etc-directory): Change default #:sudoers value to a 'plain-file'. Don't bind it. Remove #~#$. (maybe-string->file): New procedure. (operating-system-etc-directory): Use it. (%sudoers-specification): Use 'plain-file'. * doc/guix.texi (operating-system Reference): Adjust accordingly. --- doc/guix.texi | 3 ++- gnu/system.scm | 32 +++++++++++++++++++++++++------- 2 files changed, 27 insertions(+), 8 deletions(-) (limited to 'gnu/system.scm') diff --git a/doc/guix.texi b/doc/guix.texi index 2082fd765c..ecdfa1b1ce 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -4556,7 +4556,8 @@ List of string-valued G-expressions denoting setuid programs. @item @code{sudoers} (default: @var{%sudoers-specification}) @cindex sudoers -The contents of the @file{/etc/sudoers} file as a string. +The contents of the @file{/etc/sudoers} file as a file-like object +(@pxref{G-Expressions, @code{local-file} and @code{plain-file}}). This file specifies which users can use the @command{sudo} command, what they are allowed to do, and what privileges they may gain. The default diff --git a/gnu/system.scm b/gnu/system.scm index c4a3bee0eb..ede0a6f004 100644 --- a/gnu/system.scm +++ b/gnu/system.scm @@ -25,6 +25,7 @@ (define-module (gnu system) #:use-module (guix packages) #:use-module (guix derivations) #:use-module (guix profiles) + #:use-module (guix ui) #:use-module (gnu packages base) #:use-module (gnu packages bash) #:use-module (gnu packages guile) @@ -147,7 +148,7 @@ (define-record-type* operating-system (setuid-programs operating-system-setuid-programs (default %setuid-programs)) ; list of string-valued gexps - (sudoers operating-system-sudoers ; /etc/sudoers contents + (sudoers operating-system-sudoers ; file-like (default %sudoers-specification))) @@ -439,11 +440,10 @@ (define* (etc-directory #:key (pam-services '()) (profile "/run/current-system/profile") hosts-file nss (shells '()) - (sudoers "")) + (sudoers (plain-file "sudoers" ""))) "Return a derivation that builds the static part of the /etc directory." (mlet* %store-monad ((pam.d (pam-services->directory pam-services)) - (sudoers (text-file "sudoers" sudoers)) (login.defs (text-file "login.defs" "# Empty for now.\n")) (shells (shells-file shells)) (emacs (emacs-site-directory)) @@ -540,7 +540,7 @@ (define* (etc-directory #:key ("hosts" ,#~#$hosts-file) ("localtime" ,#~(string-append #$tzdata "/share/zoneinfo/" #$timezone)) - ("sudoers" ,#~#$sudoers))))) + ("sudoers" ,sudoers))))) (define (operating-system-profile os) "Return a derivation that builds the system profile of OS." @@ -570,6 +570,21 @@ (define users (return (append users (append-map service-user-accounts services))))) +(define (maybe-string->file file-name thing) + "If THING is a string, return a with THING as its content. +Otherwise just return THING. + +This is for backward-compatibility of fields that used to be strings and are +now file-like objects.." + (match thing + ((? string?) + (warning (_ "using a string for file '~a' is deprecated; \ +use 'plain-file' instead~%") + file-name) + (plain-file file-name thing)) + (x + x))) + (define (operating-system-etc-directory os) "Return that static part of the /etc directory of OS." (mlet* %store-monad @@ -591,7 +606,9 @@ (define (operating-system-etc-directory os) #:timezone (operating-system-timezone os) #:hosts-file /etc/hosts #:shells shells - #:sudoers (operating-system-sudoers os) + #:sudoers (maybe-string->file + "sudoers" + (operating-system-sudoers os)) #:profile profile-drv))) (define %setuid-programs @@ -608,8 +625,9 @@ (define %sudoers-specification ;; group can do anything. See ;; . ;; TODO: Add a declarative API. - "root ALL=(ALL) ALL -%wheel ALL=(ALL) ALL\n") + (plain-file "sudoers" "\ +root ALL=(ALL) ALL +%wheel ALL=(ALL) ALL\n")) (define (user-group->gexp group) "Turn GROUP, a object, into a list-valued gexp suitable for -- cgit v1.2.3 From 24e02c28fbf2b0efbc2fd6cdcd770037a6cff7e3 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Fri, 5 Jun 2015 22:41:55 +0200 Subject: system: 'hosts-file' is now a file-like object. Partly fixes . Reported by Alex Kost . * gnu/system.scm (default-/etc/hosts): Change 'text-file' to 'plain-file'. (maybe-file->monadic): New procedure. (operating-system-etc-directory): Use it. * doc/guix.texi (operating-system Reference, Networking Services): Adjust accordingly. --- doc/guix.texi | 10 +++++----- gnu/system.scm | 26 ++++++++++++++++++++++---- 2 files changed, 27 insertions(+), 9 deletions(-) (limited to 'gnu/system.scm') diff --git a/doc/guix.texi b/doc/guix.texi index ecdfa1b1ce..f8da9c1224 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -4480,9 +4480,9 @@ The host name. @item @code{hosts-file} @cindex hosts file -A zero-argument monadic procedure that returns a text file for use as +A file-like object (@pxref{G-Expressions, file-like objects}) for use as @file{/etc/hosts} (@pxref{Host Names,,, libc, The GNU C Library -Reference Manual}). The default is to produce a file with entries for +Reference Manual}). The default is a file with entries for @code{localhost} and @var{host-name}. @item @code{mapped-devices} (default: @code{'()}) @@ -5299,9 +5299,9 @@ This variable is typically used in the @code{hosts-file} field of an (hosts-file ;; Create a /etc/hosts file with aliases for "localhost" ;; and "mymachine", as well as for Facebook servers. - (text-file "hosts" - (string-append (local-host-aliases host-name) - %facebook-host-aliases)))) + (plain-file "hosts" + (string-append (local-host-aliases host-name) + %facebook-host-aliases)))) @end example This mechanism can prevent programs running locally, such as Web diff --git a/gnu/system.scm b/gnu/system.scm index ede0a6f004..92ed454b2c 100644 --- a/gnu/system.scm +++ b/gnu/system.scm @@ -110,7 +110,7 @@ (define-record-type* operating-system (default %base-firmware)) (host-name operating-system-host-name) ; string - (hosts-file operating-system-hosts-file ; M item | #f + (hosts-file operating-system-hosts-file ; file-like | #f (default #f)) (mapped-devices operating-system-mapped-devices ; list of @@ -374,7 +374,7 @@ (define (local-host-aliases host-name) (define (default-/etc/hosts host-name) "Return the default /etc/hosts file." - (text-file "hosts" (local-host-aliases host-name))) + (plain-file "hosts" (local-host-aliases host-name))) (define (emacs-site-file) "Return the Emacs 'site-start.el' file. That file contains the necessary @@ -585,6 +585,22 @@ (define (maybe-string->file file-name thing) (x x))) +(define (maybe-file->monadic file-name thing) + "If THING is a value in %STORE-MONAD, return it as is; otherwise return +THING in the %STORE-MONAD. + +This is for backward-compatibility of fields that used to be monadic values +and are now file-like objects." + (with-monad %store-monad + (match thing + ((? procedure?) + (warning (_ "using a monadic value for '~a' is deprecated; \ +use 'plain-file' instead~%") + file-name) + thing) + (x + (return x))))) + (define (operating-system-etc-directory os) "Return that static part of the /etc directory of OS." (mlet* %store-monad @@ -595,8 +611,10 @@ (define (operating-system-etc-directory os) (append-map service-pam-services services))) (profile-drv (operating-system-profile os)) (skeletons (operating-system-skeletons os)) - (/etc/hosts (or (operating-system-hosts-file os) - (default-/etc/hosts (operating-system-host-name os)))) + (/etc/hosts (maybe-file->monadic + "hosts" + (or (operating-system-hosts-file os) + (default-/etc/hosts (operating-system-host-name os))))) (shells (user-shells os))) (etc-directory #:pam-services pam-services #:skeletons skeletons -- cgit v1.2.3