mirror of
https://git.in.rschanz.org/ryan77627/guix.git
synced 2025-01-11 21:59:08 -05:00
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
2 changed files with 60 additions and 5 deletions
|
@ -4238,7 +4238,9 @@ command, from the same-named package. This relies on the
|
||||||
@node User Accounts
|
@node User Accounts
|
||||||
@subsection 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
|
@example
|
||||||
(user-account
|
(user-account
|
||||||
|
@ -4252,6 +4254,14 @@ User accounts are specified with the @code{user-account} form:
|
||||||
(home-directory "/home/alice"))
|
(home-directory "/home/alice"))
|
||||||
@end example
|
@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
|
@deftp {Data Type} user-account
|
||||||
Objects of this type represent user accounts. The following members may
|
Objects of this type represent user accounts. The following members may
|
||||||
be specified:
|
be specified:
|
||||||
|
@ -4291,7 +4301,9 @@ graphical login managers do not list them.
|
||||||
@item @code{password} (default: @code{#f})
|
@item @code{password} (default: @code{#f})
|
||||||
You would normally leave this field to @code{#f}, initialize user
|
You would normally leave this field to @code{#f}, initialize user
|
||||||
passwords as @code{root} with the @command{passwd} command, and then let
|
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
|
If you @emph{do} want to have a preset password for an account, then
|
||||||
this field must contain the encrypted password, as a string.
|
this field must contain the encrypted password, as a string.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; 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>
|
;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
|
@ -40,6 +40,24 @@ (define-module (gnu build activation)
|
||||||
;;;
|
;;;
|
||||||
;;; Code:
|
;;; 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?
|
(define* (add-group name #:key gid password system?
|
||||||
(log-port (current-error-port)))
|
(log-port (current-error-port)))
|
||||||
"Add NAME as a user group, with the given numeric GID if specified."
|
"Add NAME as a user group, with the given numeric GID if specified."
|
||||||
|
@ -128,6 +146,17 @@ (define* (modify-user name group
|
||||||
,name)))
|
,name)))
|
||||||
(zero? (apply system* "usermod" args))))
|
(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
|
(define* (ensure-user name group
|
||||||
#:key uid comment home shell password system?
|
#:key uid comment home shell password system?
|
||||||
(supplementary-groups '())
|
(supplementary-groups '())
|
||||||
|
@ -186,8 +215,22 @@ (define activate-user
|
||||||
#:system? system?))))
|
#:system? system?))))
|
||||||
groups)
|
groups)
|
||||||
|
|
||||||
;; Finally create the other user accounts.
|
;; Create the other user accounts.
|
||||||
(for-each activate-user users))
|
(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)
|
(define (activate-etc etc)
|
||||||
"Install ETC, a directory in the store, as the source of static files for
|
"Install ETC, a directory in the store, as the source of static files for
|
||||||
|
|
Loading…
Reference in a new issue