diff options
| author | Leo Prikler <leo.prikler@student.tugraz.at> | 2021-01-01 12:10:01 +0100 |
|---|---|---|
| committer | Leo Prikler <leo.prikler@student.tugraz.at> | 2021-01-11 16:03:47 +0100 |
| commit | a3002104a84c60556b6616d100cb98019e48759d (patch) | |
| tree | 76dc17a0d054a66c70a300a97bf5fd92687ff20a | |
| parent | 8152fd1af551f4bcec2ef59243264c10ff48daea (diff) | |
system: Assert, that user and group names are unique.
*gnu/system/shadow.scm (find-duplicates): New variable.
(assert-unique-account-names, assert-unique-group-names): New variables.
(account-activation): Use them here.
| -rw-r--r-- | gnu/system/shadow.scm | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/gnu/system/shadow.scm b/gnu/system/shadow.scm index a69339bc074..183b2cd387e 100644 --- a/gnu/system/shadow.scm +++ b/gnu/system/shadow.scm | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. | 20 | ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. |
| 21 | 21 | ||
| 22 | (define-module (gnu system shadow) | 22 | (define-module (gnu system shadow) |
| 23 | #:use-module ((guix diagnostics) #:select (formatted-message)) | ||
| 23 | #:use-module (guix records) | 24 | #:use-module (guix records) |
| 24 | #:use-module (guix gexp) | 25 | #:use-module (guix gexp) |
| 25 | #:use-module (guix store) | 26 | #:use-module (guix store) |
| @@ -34,6 +35,7 @@ | |||
| 34 | #:use-module ((gnu packages admin) | 35 | #:use-module ((gnu packages admin) |
| 35 | #:select (shadow)) | 36 | #:select (shadow)) |
| 36 | #:use-module (gnu packages bash) | 37 | #:use-module (gnu packages bash) |
| 38 | #:use-module (ice-9 match) | ||
| 37 | #:use-module (srfi srfi-1) | 39 | #:use-module (srfi srfi-1) |
| 38 | #:use-module (srfi srfi-26) | 40 | #:use-module (srfi srfi-26) |
| 39 | #:use-module (srfi srfi-34) | 41 | #:use-module (srfi srfi-34) |
| @@ -222,6 +224,46 @@ for a colorful Guile experience.\\n\\n\"))))\n")) | |||
| 222 | (rename-file ".nanorc" ".config/nano/nanorc")) | 224 | (rename-file ".nanorc" ".config/nano/nanorc")) |
| 223 | #t)))) | 225 | #t)))) |
| 224 | 226 | ||
| 227 | (define (find-duplicates list) | ||
| 228 | "Find duplicate entries in @var{list}. | ||
| 229 | Two entries are considered duplicates, if they are @code{equal?} to each other. | ||
| 230 | This implementation is made asymptotically faster than @code{delete-duplicates} | ||
| 231 | through the internal use of hash tables." | ||
| 232 | (let loop ((list list) | ||
| 233 | ;; We actually modify table in-place, but still allocate it here | ||
| 234 | ;; so that we only need one level of indentation. | ||
| 235 | (table (make-hash-table))) | ||
| 236 | (match list | ||
| 237 | (() | ||
| 238 | (hash-fold (lambda (key value seed) | ||
| 239 | (if (> value 1) | ||
| 240 | (cons key seed) | ||
| 241 | seed)) | ||
| 242 | '() | ||
| 243 | table)) | ||
| 244 | ((first . rest) | ||
| 245 | (hash-set! table first | ||
| 246 | (1+ (hash-ref table first 0))) | ||
| 247 | (loop rest table))))) | ||
| 248 | |||
| 249 | (define (assert-unique-account-names users) | ||
| 250 | (match (find-duplicates (map user-account-name users)) | ||
| 251 | (() *unspecified*) | ||
| 252 | (duplicates | ||
| 253 | (raise | ||
| 254 | (formatted-message | ||
| 255 | (G_ "the following accounts appear more than once:~{ ~a~}") | ||
| 256 | duplicates))))) | ||
| 257 | |||
| 258 | (define (assert-unique-group-names groups) | ||
| 259 | (match (find-duplicates (map user-group-name groups)) | ||
| 260 | (() *unspecified*) | ||
| 261 | (duplicates | ||
| 262 | (raise | ||
| 263 | (formatted-message | ||
| 264 | (G_ "the following groups appear more than once:~{ ~a~}") | ||
| 265 | duplicates))))) | ||
| 266 | |||
| 225 | (define (assert-valid-users/groups users groups) | 267 | (define (assert-valid-users/groups users groups) |
| 226 | "Raise an error if USERS refer to groups not listed in GROUPS." | 268 | "Raise an error if USERS refer to groups not listed in GROUPS." |
| 227 | (let ((groups (list->set (map user-group-name groups)))) | 269 | (let ((groups (list->set (map user-group-name groups)))) |
| @@ -292,6 +334,8 @@ group." | |||
| 292 | (define group-specs | 334 | (define group-specs |
| 293 | (map user-group->gexp groups)) | 335 | (map user-group->gexp groups)) |
| 294 | 336 | ||
| 337 | (assert-unique-account-names accounts) | ||
| 338 | (assert-unique-group-names groups) | ||
| 295 | (assert-valid-users/groups accounts groups) | 339 | (assert-valid-users/groups accounts groups) |
| 296 | 340 | ||
| 297 | ;; Add users and user groups. | 341 | ;; Add users and user groups. |
