;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2019 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
unix-pam-service
base-pam-services
+ session-environment-service
+ session-environment-service-type
+
pam-root-service-type
pam-root-service))
(env (pam-entry ; to honor /etc/environment.
(control "required")
(module "pam_env.so"))))
- (lambda* (name #:key allow-empty-passwords? motd)
+ (lambda* (name #:key allow-empty-passwords? (allow-root? #f) motd
+ login-uid?)
"Return a standard Unix-style PAM service for NAME. When
-ALLOW-EMPTY-PASSWORDS? is true, allow empty passwords. When MOTD is true, it
-should be a file-like object used as the message-of-the-day."
+ALLOW-EMPTY-PASSWORDS? is true, allow empty passwords. When ALLOW-ROOT? is
+true, allow root to run the command without authentication. When MOTD is
+true, it should be a file-like object used as the message-of-the-day.
+When LOGIN-UID? is true, require the 'pam_loginuid' module; that module sets
+/proc/self/loginuid, which the libc 'getlogin' function relies on."
;; See <http://www.linux-pam.org/Linux-PAM-html/sag-configuration-example.html>.
- (let ((name* name))
- (pam-service
- (name name*)
- (account (list unix))
- (auth (list (if allow-empty-passwords?
- (pam-entry
- (control "required")
- (module "pam_unix.so")
- (arguments '("nullok")))
- unix)))
- (password (list (pam-entry
- (control "required")
- (module "pam_unix.so")
- ;; Store SHA-512 encrypted passwords in /etc/shadow.
- (arguments '("sha512" "shadow")))))
- (session (if motd
- (list env unix
- (pam-entry
- (control "optional")
- (module "pam_motd.so")
- (arguments
- (list #~(string-append "motd=" #$motd)))))
- (list env unix))))))))
+ (pam-service
+ (name name)
+ (account (list unix))
+ (auth (append (if allow-root?
+ (list (pam-entry
+ (control "sufficient")
+ (module "pam_rootok.so")))
+ '())
+ (list (if allow-empty-passwords?
+ (pam-entry
+ (control "required")
+ (module "pam_unix.so")
+ (arguments '("nullok")))
+ unix))))
+ (password (list (pam-entry
+ (control "required")
+ (module "pam_unix.so")
+ ;; Store SHA-512 encrypted passwords in /etc/shadow.
+ (arguments '("sha512" "shadow")))))
+ (session `(,@(if motd
+ (list (pam-entry
+ (control "optional")
+ (module "pam_motd.so")
+ (arguments
+ (list #~(string-append "motd=" #$motd)))))
+ '())
+ ,@(if login-uid?
+ (list (pam-entry ;to fill in /proc/self/loginuid
+ (control "required")
+ (module "pam_loginuid.so")))
+ '())
+ ,env ,unix))))))
(define (rootok-pam-service command)
"Return a PAM service for COMMAND such that 'root' does not need to
;; These programs are setuid-root.
(map (cut unix-pam-service <>
#:allow-empty-passwords? allow-empty-passwords?)
- '("su" "passwd" "sudo"))
+ '("passwd" "sudo"))
+ ;; This is setuid-root, as well. Allow root to run "su" without
+ ;; authenticating.
+ (list (unix-pam-service "su"
+ #:allow-empty-passwords? allow-empty-passwords?
+ #:allow-root? #t))
;; These programs are not setuid-root, and we want root to be able
;; to run them without having to authenticate (notably because
"groupadd" "groupdel" "groupmod"))))
\f
+;;;
+;;; System-wide environment variables.
+;;;
+
+(define (environment-variables->environment-file vars)
+ "Return a file for pam_env(8) that contains environment variables VARS."
+ (apply mixed-text-file "environment"
+ (append-map (match-lambda
+ ((key . value)
+ (list key "=" value "\n")))
+ vars)))
+
+(define session-environment-service-type
+ (service-type
+ (name 'session-environment)
+ (extensions
+ (list (service-extension
+ etc-service-type
+ (lambda (vars)
+ (list `("environment"
+ ,(environment-variables->environment-file vars)))))))
+ (compose concatenate)
+ (extend append)
+ (description
+ "Populate @file{/etc/environment}, which is honored by @code{pam_env},
+with the specified environment variables. The value of this service is a list
+of name/value pairs for environments variables, such as:
+
+@example
+'((\"TZ\" . \"Canada/Pacific\"))
+@end example\n")))
+
+(define (session-environment-service vars)
+ "Return a service that builds the @file{/etc/environment}, which can be read
+by PAM-aware applications to set environment variables for sessions.
+
+VARS should be an association list in which both the keys and the values are
+strings or string-valued gexps."
+ (service session-environment-service-type vars))
+
+
+\f
;;;
;;; PAM root service.
;;;