activation: Remove undeclared user accounts and groups.
Fixes <http://bugs.gnu.org/19795>. Reported by David Thompson <dthompson2@worcester.edu>. * gnu/build/activation.scm (enumerate, current-users, current-groups, delete-user, delete-group): New procedures. (activate-users+groups): Add calls to 'delete-user' and 'delete-group'. * doc/guix.texi (User Accounts): Add a paragraph about statelessness. Explain that passwords are preserved.
This commit is contained in:
parent
a231ef7eec
commit
9bea87a542
@ -4238,7 +4238,9 @@ command, from the same-named package. This relies on the
|
||||
@node User Accounts
|
||||
@subsection User Accounts
|
||||
|
||||
User accounts are specified with the @code{user-account} form:
|
||||
User accounts and groups are entirely managed through the
|
||||
@code{operating-system} declaration. They are specified with the
|
||||
@code{user-account} and @code{user-group} forms:
|
||||
|
||||
@example
|
||||
(user-account
|
||||
@ -4252,6 +4254,14 @@ User accounts are specified with the @code{user-account} form:
|
||||
(home-directory "/home/alice"))
|
||||
@end example
|
||||
|
||||
When booting or upon completion of @command{guix system reconfigure},
|
||||
the system ensures that only the user accounts and groups specified in
|
||||
the @code{operating-system} declaration exist, and with the specified
|
||||
properties. Thus, account or group creations or modifications made by
|
||||
directly invoking commands such as @command{useradd} are lost upon
|
||||
reconfiguration or reboot. This ensures that the system remains exactly
|
||||
as declared.
|
||||
|
||||
@deftp {Data Type} user-account
|
||||
Objects of this type represent user accounts. The following members may
|
||||
be specified:
|
||||
@ -4291,7 +4301,9 @@ graphical login managers do not list them.
|
||||
@item @code{password} (default: @code{#f})
|
||||
You would normally leave this field to @code{#f}, initialize user
|
||||
passwords as @code{root} with the @command{passwd} command, and then let
|
||||
users change it with @command{passwd}.
|
||||
users change it with @command{passwd}. Passwords set with
|
||||
@command{passwd} are of course preserved across reboot and
|
||||
reconfiguration.
|
||||
|
||||
If you @emph{do} want to have a preset password for an account, then
|
||||
this field must contain the encrypted password, as a string.
|
||||
|
@ -1,5 +1,5 @@
|
||||
;;; GNU Guix --- Functional package management for GNU
|
||||
;;; Copyright © 2013, 2014 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
|
||||
;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
|
||||
;;;
|
||||
;;; This file is part of GNU Guix.
|
||||
@ -40,6 +40,24 @@
|
||||
;;;
|
||||
;;; Code:
|
||||
|
||||
(define (enumerate thunk)
|
||||
"Return the list of values returned by THUNK until it returned #f."
|
||||
(let loop ((entry (thunk))
|
||||
(result '()))
|
||||
(if (not entry)
|
||||
(reverse result)
|
||||
(loop (thunk) (cons entry result)))))
|
||||
|
||||
(define (current-users)
|
||||
"Return the passwd entries for all the currently defined user accounts."
|
||||
(setpw)
|
||||
(enumerate getpwent))
|
||||
|
||||
(define (current-groups)
|
||||
"Return the group entries for all the currently defined user groups."
|
||||
(setgr)
|
||||
(enumerate getgrent))
|
||||
|
||||
(define* (add-group name #:key gid password system?
|
||||
(log-port (current-error-port)))
|
||||
"Add NAME as a user group, with the given numeric GID if specified."
|
||||
@ -128,6 +146,17 @@ properties. Return #t on success."
|
||||
,name)))
|
||||
(zero? (apply system* "usermod" args))))
|
||||
|
||||
(define* (delete-user name #:key (log-port (current-error-port)))
|
||||
"Remove user account NAME. Return #t on success. This may fail if NAME is
|
||||
logged in."
|
||||
(format log-port "deleting user '~a'...~%" name)
|
||||
(zero? (system* "userdel" name)))
|
||||
|
||||
(define* (delete-group name #:key (log-port (current-error-port)))
|
||||
"Remove group NAME. Return #t on success."
|
||||
(format log-port "deleting group '~a'...~%" name)
|
||||
(zero? (system* "groupdel" name)))
|
||||
|
||||
(define* (ensure-user name group
|
||||
#:key uid comment home shell password system?
|
||||
(supplementary-groups '())
|
||||
@ -186,8 +215,22 @@ numeric gid or #f."
|
||||
#:system? system?))))
|
||||
groups)
|
||||
|
||||
;; Finally create the other user accounts.
|
||||
(for-each activate-user users))
|
||||
;; Create the other user accounts.
|
||||
(for-each activate-user users)
|
||||
|
||||
;; Finally, delete extra user accounts and groups.
|
||||
(for-each delete-user
|
||||
(lset-difference string=?
|
||||
(map passwd:name (current-users))
|
||||
(match users
|
||||
(((names . _) ...)
|
||||
names))))
|
||||
(for-each delete-group
|
||||
(lset-difference string=?
|
||||
(map group:name (current-groups))
|
||||
(match groups
|
||||
(((names . _) ...)
|
||||
names)))))
|
||||
|
||||
(define (activate-etc etc)
|
||||
"Install ETC, a directory in the store, as the source of static files for
|
||||
|
Loading…
Reference in New Issue
Block a user