]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/home/homework.c
Merge pull request #15433 from mrc0mmand/test-reintroduce-parallelization
[thirdparty/systemd.git] / src / home / homework.c
CommitLineData
70a5db58
LP
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#include <stddef.h>
4#include <sys/mount.h>
5
6#include "chown-recursive.h"
7#include "copy.h"
8#include "fd-util.h"
9#include "fileio.h"
1dfe5de0 10#include "fs-util.h"
70a5db58
LP
11#include "home-util.h"
12#include "homework-cifs.h"
13#include "homework-directory.h"
14#include "homework-fscrypt.h"
15#include "homework-luks.h"
16#include "homework-mount.h"
17#include "homework-pkcs11.h"
18#include "homework.h"
19#include "main-func.h"
20#include "memory-util.h"
21#include "missing_magic.h"
22#include "mount-util.h"
23#include "path-util.h"
24#include "pkcs11-util.h"
25#include "rm-rf.h"
26#include "stat-util.h"
27#include "strv.h"
28#include "tmpfile-util.h"
29#include "user-util.h"
30#include "virt.h"
31
32/* Make sure a bad password always results in a 3s delay, no matter what */
33#define BAD_PASSWORD_DELAY_USEC (3 * USEC_PER_SEC)
34
35int user_record_authenticate(
36 UserRecord *h,
37 UserRecord *secret,
38 char ***pkcs11_decrypted_passwords) {
39
40 bool need_password = false, need_token = false, need_pin = false, need_protected_authentication_path_permitted = false,
41 pin_locked = false, pin_incorrect = false, pin_incorrect_few_tries_left = false, pin_incorrect_one_try_left = false;
70a5db58
LP
42 int r;
43
44 assert(h);
45 assert(secret);
46
47 /* Tries to authenticate a user record with the supplied secrets. i.e. checks whether at least one
48 * supplied plaintext passwords matches a hashed password field of the user record. Or if a
49 * configured PKCS#11 token is around and can unlock the record.
50 *
51 * Note that the pkcs11_decrypted_passwords parameter is both an input and and output parameter: it
52 * is a list of configured, decrypted PKCS#11 passwords. We typically have to call this function
53 * multiple times over the course of an operation (think: on login we authenticate the host user
54 * record, the record embedded in the LUKS record and the one embedded in $HOME). Hence we keep a
55 * list of passwords we already decrypted, so that we don't have to do the (slow an potentially
56 * interactive) PKCS#11 dance for the relevant token again and again. */
57
58 /* First, let's see if the supplied plain-text passwords work? */
59 r = user_record_test_secret(h, secret);
60 if (r == -ENOKEY) {
61 log_info_errno(r, "None of the supplied plaintext passwords unlocks the user record's hashed passwords.");
62 need_password = true;
63 } else if (r == -ENXIO)
64 log_debug_errno(r, "User record has no hashed passwords, plaintext passwords not tested.");
65 else if (r < 0)
66 return log_error_errno(r, "Failed to validate password of record: %m");
67 else {
68 log_info("Provided password unlocks user record.");
69 return 0;
70 }
71
72 /* Second, let's see if any of the PKCS#11 security tokens are plugged in and help us */
3aeea37d 73 for (size_t n = 0; n < h->n_pkcs11_encrypted_key; n++) {
70a5db58
LP
74#if HAVE_P11KIT
75 _cleanup_(pkcs11_callback_data_release) struct pkcs11_callback_data data = {
76 .user_record = h,
77 .secret = secret,
78 .encrypted_key = h->pkcs11_encrypted_key + n,
79 };
80 char **pp;
81
82 /* See if any of the previously calculated passwords work */
83 STRV_FOREACH(pp, *pkcs11_decrypted_passwords) {
84 r = test_password_one(data.encrypted_key->hashed_password, *pp);
85 if (r < 0)
86 return log_error_errno(r, "Failed to check supplied PKCS#11 password: %m");
87 if (r > 0) {
88 log_info("Previously acquired PKCS#11 password unlocks user record.");
89 return 0;
90 }
91 }
92
93 r = pkcs11_find_token(data.encrypted_key->uri, pkcs11_callback, &data);
94 switch (r) {
95 case -EAGAIN:
96 need_token = true;
97 break;
98 case -ENOANO:
99 need_pin = true;
100 break;
101 case -ERFKILL:
102 need_protected_authentication_path_permitted = true;
103 break;
104 case -EOWNERDEAD:
105 pin_locked = true;
106 break;
107 case -ENOLCK:
108 pin_incorrect = true;
109 break;
110 case -ETOOMANYREFS:
111 pin_incorrect = pin_incorrect_few_tries_left = true;
112 break;
113 case -EUCLEAN:
114 pin_incorrect = pin_incorrect_few_tries_left = pin_incorrect_one_try_left = true;
115 break;
116 default:
117 if (r < 0)
118 return r;
119
120 r = test_password_one(data.encrypted_key->hashed_password, data.decrypted_password);
121 if (r < 0)
122 return log_error_errno(r, "Failed to test PKCS#11 password: %m");
123 if (r == 0)
124 return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Configured PKCS#11 security token %s does not decrypt encrypted key correctly.", data.encrypted_key->uri);
125
126 log_info("Decrypted password from PKCS#11 security token %s unlocks user record.", data.encrypted_key->uri);
127
128 r = strv_extend(pkcs11_decrypted_passwords, data.decrypted_password);
129 if (r < 0)
130 return log_oom();
131
132 return 0;
133 }
134#else
135 need_token = true;
136 break;
137#endif
138 }
139
140 /* Ordered by "relevance", i.e. the most "important" or "interesting" error condition is returned. */
141 if (pin_incorrect_one_try_left)
142 return -EUCLEAN;
143 if (pin_incorrect_few_tries_left)
144 return -ETOOMANYREFS;
145 if (pin_incorrect)
146 return -ENOLCK;
147 if (pin_locked)
148 return -EOWNERDEAD;
149 if (need_protected_authentication_path_permitted)
150 return -ERFKILL;
151 if (need_pin)
152 return -ENOANO;
153 if (need_token)
154 return -EBADSLT;
155 if (need_password)
156 return -ENOKEY;
157
158 /* Hmm, this means neither PCKS#11 nor classic hashed passwords were supplied, we cannot authenticate this reasonably */
159 return log_debug_errno(SYNTHETIC_ERRNO(EKEYREVOKED), "No hashed passwords and no PKCS#11 tokens defined, cannot authenticate user record.");
160}
161
162int home_setup_undo(HomeSetup *setup) {
163 int r = 0, q;
164
165 assert(setup);
166
28a7f106
LP
167 if (setup->root_fd >= 0) {
168 if (setup->do_offline_fitrim) {
169 q = run_fitrim(setup->root_fd);
170 if (q < 0)
171 r = q;
172 }
173
174 setup->root_fd = safe_close(setup->root_fd);
175 }
70a5db58
LP
176
177 if (setup->undo_mount) {
178 q = umount_verbose("/run/systemd/user-home-mount");
179 if (q < 0)
180 r = q;
181 }
182
183 if (setup->undo_dm && setup->crypt_device && setup->dm_name) {
184 q = crypt_deactivate(setup->crypt_device, setup->dm_name);
185 if (q < 0)
186 r = q;
187 }
188
28a7f106
LP
189 if (setup->image_fd >= 0) {
190 if (setup->do_offline_fallocate) {
191 q = run_fallocate(setup->image_fd, NULL);
192 if (q < 0)
193 r = q;
194 }
195
196 setup->image_fd = safe_close(setup->image_fd);
197 }
198
70a5db58
LP
199 setup->undo_mount = false;
200 setup->undo_dm = false;
28a7f106
LP
201 setup->do_offline_fitrim = false;
202 setup->do_offline_fallocate = false;
70a5db58
LP
203
204 setup->dm_name = mfree(setup->dm_name);
205 setup->dm_node = mfree(setup->dm_node);
206
207 setup->loop = loop_device_unref(setup->loop);
208 crypt_free(setup->crypt_device);
209 setup->crypt_device = NULL;
210
211 explicit_bzero_safe(setup->volume_key, setup->volume_key_size);
212 setup->volume_key = mfree(setup->volume_key);
213 setup->volume_key_size = 0;
214
215 return r;
216}
217
218int home_prepare(
219 UserRecord *h,
220 bool already_activated,
221 char ***pkcs11_decrypted_passwords,
222 HomeSetup *setup,
223 UserRecord **ret_header_home) {
224
225 int r;
226
227 assert(h);
228 assert(setup);
229 assert(!setup->loop);
230 assert(!setup->crypt_device);
231 assert(setup->root_fd < 0);
232 assert(!setup->undo_dm);
233 assert(!setup->undo_mount);
234
235 /* Makes a home directory accessible (through the root_fd file descriptor, not by path!). */
236
237 switch (user_record_storage(h)) {
238
239 case USER_LUKS:
240 return home_prepare_luks(h, already_activated, NULL, pkcs11_decrypted_passwords, setup, ret_header_home);
241
242 case USER_SUBVOLUME:
243 case USER_DIRECTORY:
244 r = home_prepare_directory(h, already_activated, setup);
245 break;
246
247 case USER_FSCRYPT:
248 r = home_prepare_fscrypt(h, already_activated, pkcs11_decrypted_passwords, setup);
249 break;
250
251 case USER_CIFS:
252 r = home_prepare_cifs(h, already_activated, setup);
253 break;
254
255 default:
256 return log_error_errno(SYNTHETIC_ERRNO(ENOLINK), "Processing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
257 }
258
259 if (r < 0)
260 return r;
261
262 if (ret_header_home)
263 *ret_header_home = NULL;
264
265 return r;
266}
267
268int home_sync_and_statfs(int root_fd, struct statfs *ret) {
269 assert(root_fd >= 0);
270
271 /* Let's sync this to disk, so that the disk space reported by fstatfs() below is accurate (for file
272 * systems such as btrfs where this is determined lazily). */
273
274 if (syncfs(root_fd) < 0)
275 return log_error_errno(errno, "Failed to synchronize file system: %m");
276
277 if (ret)
278 if (fstatfs(root_fd, ret) < 0)
279 return log_error_errno(errno, "Failed to statfs() file system: %m");
280
281 log_info("Synchronized disk.");
282
283 return 0;
284}
285
286static int read_identity_file(int root_fd, JsonVariant **ret) {
287 _cleanup_(fclosep) FILE *identity_file = NULL;
288 _cleanup_close_ int identity_fd = -1;
289 unsigned line, column;
290 int r;
291
292 assert(root_fd >= 0);
293 assert(ret);
294
295 identity_fd = openat(root_fd, ".identity", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW|O_NONBLOCK);
296 if (identity_fd < 0)
297 return log_error_errno(errno, "Failed to open .identity file in home directory: %m");
298
299 r = fd_verify_regular(identity_fd);
300 if (r < 0)
301 return log_error_errno(r, "Embedded identity file is not a regular file, refusing: %m");
302
4fa744a3 303 identity_file = take_fdopen(&identity_fd, "r");
70a5db58
LP
304 if (!identity_file)
305 return log_oom();
306
70a5db58
LP
307 r = json_parse_file(identity_file, ".identity", JSON_PARSE_SENSITIVE, ret, &line, &column);
308 if (r < 0)
309 return log_error_errno(r, "[.identity:%u:%u] Failed to parse JSON data: %m", line, column);
310
311 log_info("Read embedded .identity file.");
312
313 return 0;
314}
315
316static int write_identity_file(int root_fd, JsonVariant *v, uid_t uid) {
317 _cleanup_(json_variant_unrefp) JsonVariant *normalized = NULL;
318 _cleanup_(fclosep) FILE *identity_file = NULL;
319 _cleanup_close_ int identity_fd = -1;
320 _cleanup_free_ char *fn = NULL;
321 int r;
322
323 assert(root_fd >= 0);
324 assert(v);
325
326 normalized = json_variant_ref(v);
327
328 r = json_variant_normalize(&normalized);
329 if (r < 0)
330 log_warning_errno(r, "Failed to normalize user record, ignoring: %m");
331
332 r = tempfn_random(".identity", NULL, &fn);
333 if (r < 0)
334 return r;
335
336 identity_fd = openat(root_fd, fn, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0600);
337 if (identity_fd < 0)
338 return log_error_errno(errno, "Failed to create .identity file in home directory: %m");
339
4fa744a3 340 identity_file = take_fdopen(&identity_fd, "w");
70a5db58
LP
341 if (!identity_file) {
342 r = log_oom();
343 goto fail;
344 }
345
70a5db58
LP
346 json_variant_dump(normalized, JSON_FORMAT_PRETTY, identity_file, NULL);
347
348 r = fflush_and_check(identity_file);
349 if (r < 0) {
350 log_error_errno(r, "Failed to write .identity file: %m");
351 goto fail;
352 }
353
354 if (fchown(fileno(identity_file), uid, uid) < 0) {
355 log_error_errno(r, "Failed to change ownership of identity file: %m");
356 goto fail;
357 }
358
359 if (renameat(root_fd, fn, root_fd, ".identity") < 0) {
360 r = log_error_errno(errno, "Failed to move identity file into place: %m");
361 goto fail;
362 }
363
364 log_info("Wrote embedded .identity file.");
365
366 return 0;
367
368fail:
369 (void) unlinkat(root_fd, fn, 0);
370 return r;
371}
372
373int home_load_embedded_identity(
374 UserRecord *h,
375 int root_fd,
376 UserRecord *header_home,
377 UserReconcileMode mode,
378 char ***pkcs11_decrypted_passwords,
379 UserRecord **ret_embedded_home,
380 UserRecord **ret_new_home) {
381
382 _cleanup_(user_record_unrefp) UserRecord *embedded_home = NULL, *intermediate_home = NULL, *new_home = NULL;
383 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
384 int r;
385
386 assert(h);
387 assert(root_fd >= 0);
388
389 r = read_identity_file(root_fd, &v);
390 if (r < 0)
391 return r;
392
393 embedded_home = user_record_new();
394 if (!embedded_home)
395 return log_oom();
396
397 r = user_record_load(embedded_home, v, USER_RECORD_LOAD_EMBEDDED);
398 if (r < 0)
399 return r;
400
401 if (!user_record_compatible(h, embedded_home))
80ace4f2 402 return log_error_errno(SYNTHETIC_ERRNO(EREMCHG), "Embedded home record not compatible with host record, refusing.");
70a5db58
LP
403
404 /* Insist that credentials the user supplies also unlocks any embedded records. */
405 r = user_record_authenticate(embedded_home, h, pkcs11_decrypted_passwords);
406 if (r < 0)
407 return r;
408
409 /* At this point we have three records to deal with:
410 *
411 * · The record we got passed from the host
412 * · The record included in the LUKS header (only if LUKS is used)
413 * · The record in the home directory itself (~.identity)
414 *
415 * Now we have to reconcile all three, and let the newest one win. */
416
417 if (header_home) {
418 /* Note we relax the requirements here. Instead of insisting that the host record is strictly
419 * newer, let's also be OK if its equally new. If it is, we'll however insist that the
420 * embedded record must be newer, so that we update at least one of the two. */
421
422 r = user_record_reconcile(h, header_home, mode == USER_RECONCILE_REQUIRE_NEWER ? USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL : mode, &intermediate_home);
423 if (r == -EREMCHG) /* this was supposed to be checked earlier already, but let's check this again */
424 return log_error_errno(r, "Identity stored on host and in header don't match, refusing.");
425 if (r == -ESTALE)
426 return log_error_errno(r, "Embedded identity record is newer than supplied record, refusing.");
427 if (r < 0)
428 return log_error_errno(r, "Failed to reconcile host and header identities: %m");
429 if (r == USER_RECONCILE_EMBEDDED_WON)
430 log_info("Reconciling header user identity completed (header version was newer).");
431 else if (r == USER_RECONCILE_HOST_WON) {
432 log_info("Reconciling header user identity completed (host version was newer).");
433
434 if (mode == USER_RECONCILE_REQUIRE_NEWER) /* Host version is newer than the header
435 * version, hence we'll update
436 * something. This means we can relax the
437 * requirements on the embedded
438 * identity. */
439 mode = USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL;
440 } else {
441 assert(r == USER_RECONCILE_IDENTICAL);
442 log_info("Reconciling user identities completed (host and header version were identical).");
443 }
444
445 h = intermediate_home;
446 }
447
448 r = user_record_reconcile(h, embedded_home, mode, &new_home);
449 if (r == -EREMCHG)
450 return log_error_errno(r, "Identity stored on host and in home don't match, refusing.");
451 if (r == -ESTALE)
452 return log_error_errno(r, "Embedded identity record is equally new or newer than supplied record, refusing.");
453 if (r < 0)
454 return log_error_errno(r, "Failed to reconcile host and embedded identities: %m");
455 if (r == USER_RECONCILE_EMBEDDED_WON)
456 log_info("Reconciling embedded user identity completed (embedded version was newer).");
457 else if (r == USER_RECONCILE_HOST_WON)
458 log_info("Reconciling embedded user identity completed (host version was newer).");
459 else {
460 assert(r == USER_RECONCILE_IDENTICAL);
461 log_info("Reconciling embedded user identity completed (host and embedded version were identical).");
462 }
463
464 if (ret_embedded_home)
465 *ret_embedded_home = TAKE_PTR(embedded_home);
466
467 if (ret_new_home)
468 *ret_new_home = TAKE_PTR(new_home);
469
470 return 0;
471}
472
473int home_store_embedded_identity(UserRecord *h, int root_fd, uid_t uid, UserRecord *old_home) {
474 _cleanup_(user_record_unrefp) UserRecord *embedded = NULL;
475 int r;
476
477 assert(h);
478 assert(root_fd >= 0);
479 assert(uid_is_valid(uid));
480
481 r = user_record_clone(h, USER_RECORD_EXTRACT_EMBEDDED, &embedded);
482 if (r < 0)
483 return log_error_errno(r, "Failed to determine new embedded record: %m");
484
485 if (old_home && user_record_equal(old_home, embedded)) {
486 log_debug("Not updating embedded home record.");
487 return 0;
488 }
489
490 /* The identity has changed, let's update it in the image */
491 r = write_identity_file(root_fd, embedded->json, h->uid);
492 if (r < 0)
493 return r;
494
495 return 1;
496}
497
498static const char *file_system_type_fd(int fd) {
499 struct statfs sfs;
500
501 assert(fd >= 0);
502
503 if (fstatfs(fd, &sfs) < 0) {
504 log_debug_errno(errno, "Failed to statfs(): %m");
505 return NULL;
506 }
507
508 if (is_fs_type(&sfs, XFS_SB_MAGIC))
509 return "xfs";
510 if (is_fs_type(&sfs, EXT4_SUPER_MAGIC))
511 return "ext4";
512 if (is_fs_type(&sfs, BTRFS_SUPER_MAGIC))
513 return "btrfs";
514
515 return NULL;
516}
517
518int home_extend_embedded_identity(UserRecord *h, UserRecord *used, HomeSetup *setup) {
519 int r;
520
521 assert(h);
522 assert(used);
523 assert(setup);
524
525 r = user_record_add_binding(
526 h,
527 user_record_storage(used),
528 user_record_image_path(used),
529 setup->found_partition_uuid,
530 setup->found_luks_uuid,
531 setup->found_fs_uuid,
532 setup->crypt_device ? crypt_get_cipher(setup->crypt_device) : NULL,
533 setup->crypt_device ? crypt_get_cipher_mode(setup->crypt_device) : NULL,
534 setup->crypt_device ? luks_volume_key_size_convert(setup->crypt_device) : UINT64_MAX,
535 file_system_type_fd(setup->root_fd),
536 user_record_home_directory(used),
537 used->uid,
538 (gid_t) used->uid);
539 if (r < 0)
540 return log_error_errno(r, "Failed to update binding in record: %m");
541
542 return 0;
543}
544
545static int chown_recursive_directory(int root_fd, uid_t uid) {
546 int r;
547
548 assert(root_fd >= 0);
549 assert(uid_is_valid(uid));
550
551 r = fd_chown_recursive(root_fd, uid, (gid_t) uid, 0777);
552 if (r < 0)
553 return log_error_errno(r, "Failed to change ownership of files and directories: %m");
554 if (r == 0)
555 log_info("Recursive changing of ownership not necessary, skipped.");
556 else
557 log_info("Recursive changing of ownership completed.");
558
559 return 0;
560}
561
562int home_refresh(
563 UserRecord *h,
564 HomeSetup *setup,
565 UserRecord *header_home,
566 char ***pkcs11_decrypted_passwords,
567 struct statfs *ret_statfs,
568 UserRecord **ret_new_home) {
569
570 _cleanup_(user_record_unrefp) UserRecord *embedded_home = NULL, *new_home = NULL;
571 int r;
572
573 assert(h);
574 assert(setup);
575 assert(ret_new_home);
576
577 /* When activating a home directory, does the identity work: loads the identity from the $HOME
578 * directory, reconciles it with our idea, chown()s everything. */
579
580 r = home_load_embedded_identity(h, setup->root_fd, header_home, USER_RECONCILE_ANY, pkcs11_decrypted_passwords, &embedded_home, &new_home);
581 if (r < 0)
582 return r;
583
584 r = home_store_header_identity_luks(new_home, setup, header_home);
585 if (r < 0)
586 return r;
587
588 r = home_store_embedded_identity(new_home, setup->root_fd, h->uid, embedded_home);
589 if (r < 0)
590 return r;
591
592 r = chown_recursive_directory(setup->root_fd, h->uid);
593 if (r < 0)
594 return r;
595
596 r = home_sync_and_statfs(setup->root_fd, ret_statfs);
597 if (r < 0)
598 return r;
599
600 *ret_new_home = TAKE_PTR(new_home);
601 return 0;
602}
603
604static int home_activate(UserRecord *h, UserRecord **ret_home) {
605 _cleanup_(strv_free_erasep) char **pkcs11_decrypted_passwords = NULL;
606 _cleanup_(user_record_unrefp) UserRecord *new_home = NULL;
607 int r;
608
609 assert(h);
610
611 if (!h->user_name)
612 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks user name, refusing.");
613 if (!uid_is_valid(h->uid))
614 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks UID, refusing.");
615 if (!IN_SET(user_record_storage(h), USER_LUKS, USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT, USER_CIFS))
616 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Activating home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
617
618 r = user_record_authenticate(h, h, &pkcs11_decrypted_passwords);
619 if (r < 0)
620 return r;
621
622 r = user_record_test_home_directory_and_warn(h);
623 if (r < 0)
624 return r;
625 if (r == USER_TEST_MOUNTED)
626 return log_error_errno(SYNTHETIC_ERRNO(EALREADY), "Home directory %s is already mounted, refusing.", user_record_home_directory(h));
627
628 r = user_record_test_image_path_and_warn(h);
629 if (r < 0)
630 return r;
631 if (r == USER_TEST_ABSENT)
632 return log_error_errno(SYNTHETIC_ERRNO(ENOENT), "Image path %s is missing, refusing.", user_record_image_path(h));
633
634 switch (user_record_storage(h)) {
635
636 case USER_LUKS:
637 r = home_activate_luks(h, &pkcs11_decrypted_passwords, &new_home);
638 if (r < 0)
639 return r;
640
641 break;
642
643 case USER_SUBVOLUME:
644 case USER_DIRECTORY:
645 case USER_FSCRYPT:
646 r = home_activate_directory(h, &pkcs11_decrypted_passwords, &new_home);
647 if (r < 0)
648 return r;
649
650 break;
651
652 case USER_CIFS:
653 r = home_activate_cifs(h, &pkcs11_decrypted_passwords, &new_home);
654 if (r < 0)
655 return r;
656
657 break;
658
659 default:
660 assert_not_reached("unexpected type");
661 }
662
663 /* Note that the returned object might either be a reference to an updated version of the existing
664 * home object, or a reference to a newly allocated home object. The caller has to be able to deal
665 * with both, and consider the old object out-of-date. */
666 if (user_record_equal(h, new_home)) {
667 *ret_home = NULL;
668 return 0; /* no identity change */
669 }
670
671 *ret_home = TAKE_PTR(new_home);
672 return 1; /* identity updated */
673}
674
675static int home_deactivate(UserRecord *h, bool force) {
676 bool done = false;
677 int r;
678
679 assert(h);
680
681 if (!h->user_name)
682 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record incomplete, refusing.");
683 if (!IN_SET(user_record_storage(h), USER_LUKS, USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT, USER_CIFS))
684 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Deactivating home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
685
686 r = user_record_test_home_directory_and_warn(h);
687 if (r < 0)
688 return r;
689 if (r == USER_TEST_MOUNTED) {
28a7f106
LP
690 if (user_record_storage(h) == USER_LUKS) {
691 r = home_trim_luks(h);
692 if (r < 0)
693 return r;
694 }
695
70a5db58
LP
696 if (umount2(user_record_home_directory(h), UMOUNT_NOFOLLOW | (force ? MNT_FORCE|MNT_DETACH : 0)) < 0)
697 return log_error_errno(errno, "Failed to unmount %s: %m", user_record_home_directory(h));
698
699 log_info("Unmounting completed.");
700 done = true;
701 } else
702 log_info("Directory %s is already unmounted.", user_record_home_directory(h));
703
704 if (user_record_storage(h) == USER_LUKS) {
705 r = home_deactivate_luks(h);
706 if (r < 0)
707 return r;
708 if (r > 0)
709 done = true;
710 }
711
712 if (!done)
713 return log_error_errno(SYNTHETIC_ERRNO(ENOEXEC), "Home is not active.");
714
715 log_info("Everything completed.");
716 return 0;
717}
718
719static int copy_skel(int root_fd, const char *skel) {
720 int r;
721
722 assert(root_fd >= 0);
723
724 r = copy_tree_at(AT_FDCWD, skel, root_fd, ".", UID_INVALID, GID_INVALID, COPY_MERGE|COPY_REPLACE);
725 if (r == -ENOENT) {
726 log_info("Skeleton directory %s missing, ignoring.", skel);
727 return 0;
728 }
729 if (r < 0)
730 return log_error_errno(r, "Failed to copy in %s: %m", skel);
731
732 log_info("Copying in %s completed.", skel);
733 return 0;
734}
735
736static int change_access_mode(int root_fd, mode_t m) {
737 assert(root_fd >= 0);
738
739 if (fchmod(root_fd, m) < 0)
740 return log_error_errno(errno, "Failed to change access mode of top-level directory: %m");
741
742 log_info("Changed top-level directory access mode to 0%o.", m);
743 return 0;
744}
745
746int home_populate(UserRecord *h, int dir_fd) {
747 int r;
748
749 assert(h);
750 assert(dir_fd >= 0);
751
752 r = copy_skel(dir_fd, user_record_skeleton_directory(h));
753 if (r < 0)
754 return r;
755
756 r = home_store_embedded_identity(h, dir_fd, h->uid, NULL);
757 if (r < 0)
758 return r;
759
760 r = chown_recursive_directory(dir_fd, h->uid);
761 if (r < 0)
762 return r;
763
764 r = change_access_mode(dir_fd, user_record_access_mode(h));
765 if (r < 0)
766 return r;
767
768 return 0;
769}
770
771static int user_record_compile_effective_passwords(
772 UserRecord *h,
773 char ***ret_effective_passwords,
774 char ***ret_pkcs11_decrypted_passwords) {
775
776 _cleanup_(strv_free_erasep) char **effective = NULL, **pkcs11_passwords = NULL;
777 size_t n;
778 char **i;
779 int r;
780
781 assert(h);
782
783 /* We insist on at least one classic hashed password to be defined in addition to any PKCS#11 one, as
784 * a safe fallback, but also to simplify the password changing algorithm: there we require providing
785 * the old literal password only (and do not care for the old PKCS#11 token) */
786
787 if (strv_isempty(h->hashed_password))
788 return log_error_errno(EINVAL, "User record has no hashed passwords, refusing.");
789
790 /* Generates the list of plaintext passwords to propagate to LUKS/fscrypt devices, and checks whether
791 * we have a plaintext password for each hashed one. If we are missing one we'll fail, since we
792 * couldn't sync fscrypt/LUKS to the login account properly. */
793
794 STRV_FOREACH(i, h->hashed_password) {
795 bool found = false;
796 char **j;
797
798 log_debug("Looking for plaintext password for: %s", *i);
799
800 /* Let's scan all provided plaintext passwords */
801 STRV_FOREACH(j, h->password) {
802 r = test_password_one(*i, *j);
803 if (r < 0)
804 return log_error_errno(r, "Failed to test plain text password: %m");
805 if (r > 0) {
806 if (ret_effective_passwords) {
807 r = strv_extend(&effective, *j);
808 if (r < 0)
809 return log_oom();
810 }
811
812 log_debug("Found literal plaintext password.");
813 found = true;
814 break;
815 }
816 }
817
818 if (!found)
819 return log_error_errno(SYNTHETIC_ERRNO(ENOKEY), "Missing plaintext password for defined hashed password");
820 }
821
822 for (n = 0; n < h->n_pkcs11_encrypted_key; n++) {
823#if HAVE_P11KIT
824 _cleanup_(pkcs11_callback_data_release) struct pkcs11_callback_data data = {
825 .user_record = h,
826 .secret = h,
827 .encrypted_key = h->pkcs11_encrypted_key + n,
828 };
829
830 r = pkcs11_find_token(data.encrypted_key->uri, pkcs11_callback, &data);
831 if (r == -EAGAIN)
832 return -EBADSLT;
833 if (r < 0)
834 return r;
835
836 r = test_password_one(data.encrypted_key->hashed_password, data.decrypted_password);
837 if (r < 0)
838 return log_error_errno(r, "Failed to test PKCS#11 password: %m");
839 if (r == 0)
840 return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Decrypted password from token is not correct, refusing.");
841
842 if (ret_effective_passwords) {
843 r = strv_extend(&effective, data.decrypted_password);
844 if (r < 0)
845 return log_oom();
846 }
847
848 if (ret_pkcs11_decrypted_passwords) {
849 r = strv_extend(&pkcs11_passwords, data.decrypted_password);
850 if (r < 0)
851 return log_oom();
852 }
853#else
854 return -EBADSLT;
855#endif
856 }
857
858 if (ret_effective_passwords)
859 *ret_effective_passwords = TAKE_PTR(effective);
860 if (ret_pkcs11_decrypted_passwords)
861 *ret_pkcs11_decrypted_passwords = TAKE_PTR(pkcs11_passwords);
862
863 return 0;
864}
865
1dfe5de0
LP
866static int determine_default_storage(UserStorage *ret) {
867 UserStorage storage = _USER_STORAGE_INVALID;
868 const char *e;
869 int r;
870
871 assert(ret);
872
873 /* homed tells us via an environment variable which default storage to use */
874 e = getenv("SYSTEMD_HOME_DEFAULT_STORAGE");
875 if (e) {
876 storage = user_storage_from_string(e);
877 if (storage < 0)
878 log_warning("$SYSTEMD_HOME_DEFAULT_STORAGE set to invalid storage type, ignoring: %s", e);
879 else {
880 log_info("Using configured default storage '%s'.", user_storage_to_string(storage));
881 *ret = storage;
882 return 0;
883 }
884 }
885
886 /* When neither user nor admin specified the storage type to use, fix it to be LUKS — unless we run
887 * in a container where loopback devices and LUKS/DM are not available. Also, if /home is encrypted
888 * anyway, let's avoid duplicate encryption. Note that we typically default to the assumption of
889 * "classic" storage for most operations. However, if we create a new home, then let's user LUKS if
890 * nothing is specified. */
891
892 r = detect_container();
893 if (r < 0)
894 return log_error_errno(r, "Failed to determine whether we are in a container: %m");
895 if (r == 0) {
896 r = path_is_encrypted("/home");
897 if (r < 0)
898 log_warning_errno(r, "Failed to determine if /home is encrypted, ignoring: %m");
899 if (r <= 0) {
900 log_info("Using automatic default storage of '%s'.", user_storage_to_string(USER_LUKS));
901 *ret = USER_LUKS;
902 return 0;
903 }
904
905 log_info("/home is encrypted, not using '%s' storage, in order to avoid double encryption.", user_storage_to_string(USER_LUKS));
906 } else
907 log_info("Running in container, not using '%s' storage.", user_storage_to_string(USER_LUKS));
908
909 r = path_is_fs_type("/home", BTRFS_SUPER_MAGIC);
910 if (r < 0)
911 log_warning_errno(r, "Failed to determine file system of /home, ignoring: %m");
912 if (r > 0) {
913 log_info("/home is on btrfs, using '%s' as storage.", user_storage_to_string(USER_SUBVOLUME));
914 *ret = USER_SUBVOLUME;
915 } else {
916 log_info("/home is on simple file system, using '%s' as storage.", user_storage_to_string(USER_DIRECTORY));
917 *ret = USER_DIRECTORY;
918 }
919
920 return 0;
921}
922
70a5db58
LP
923static int home_create(UserRecord *h, UserRecord **ret_home) {
924 _cleanup_(strv_free_erasep) char **effective_passwords = NULL, **pkcs11_decrypted_passwords = NULL;
925 _cleanup_(user_record_unrefp) UserRecord *new_home = NULL;
1dfe5de0
LP
926 UserStorage new_storage = _USER_STORAGE_INVALID;
927 const char *new_fs = NULL;
70a5db58
LP
928 int r;
929
930 assert(h);
931
932 if (!h->user_name)
933 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks name, refusing.");
934 if (!uid_is_valid(h->uid))
935 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks UID, refusing.");
936
937 r = user_record_compile_effective_passwords(h, &effective_passwords, &pkcs11_decrypted_passwords);
938 if (r < 0)
939 return r;
940
941 r = user_record_test_home_directory_and_warn(h);
942 if (r < 0)
943 return r;
944 if (r != USER_TEST_ABSENT)
945 return log_error_errno(SYNTHETIC_ERRNO(EEXIST), "Home directory %s already exists, refusing.", user_record_home_directory(h));
946
70a5db58 947 if (h->storage < 0) {
1dfe5de0 948 r = determine_default_storage(&new_storage);
70a5db58 949 if (r < 0)
1dfe5de0
LP
950 return r;
951 }
70a5db58 952
1dfe5de0
LP
953 if ((h->storage == USER_LUKS ||
954 (h->storage < 0 && new_storage == USER_LUKS)) &&
955 !h->file_system_type)
956 new_fs = getenv("SYSTEMD_HOME_DEFAULT_FILE_SYSTEM_TYPE");
70a5db58 957
1dfe5de0 958 if (new_storage >= 0 || new_fs) {
70a5db58
LP
959 r = user_record_add_binding(
960 h,
961 new_storage,
962 NULL,
963 SD_ID128_NULL,
964 SD_ID128_NULL,
965 SD_ID128_NULL,
966 NULL,
967 NULL,
968 UINT64_MAX,
1dfe5de0 969 new_fs,
70a5db58
LP
970 NULL,
971 UID_INVALID,
972 GID_INVALID);
973 if (r < 0)
974 return log_error_errno(r, "Failed to change storage type to LUKS: %m");
70a5db58
LP
975 }
976
977 r = user_record_test_image_path_and_warn(h);
978 if (r < 0)
979 return r;
980 if (!IN_SET(r, USER_TEST_ABSENT, USER_TEST_UNDEFINED, USER_TEST_MAYBE))
981 return log_error_errno(SYNTHETIC_ERRNO(EEXIST), "Image path %s already exists, refusing.", user_record_image_path(h));
982
983 switch (user_record_storage(h)) {
984
985 case USER_LUKS:
986 r = home_create_luks(h, pkcs11_decrypted_passwords, effective_passwords, &new_home);
987 break;
988
989 case USER_DIRECTORY:
990 case USER_SUBVOLUME:
991 r = home_create_directory_or_subvolume(h, &new_home);
992 break;
993
994 case USER_FSCRYPT:
995 r = home_create_fscrypt(h, effective_passwords, &new_home);
996 break;
997
998 case USER_CIFS:
999 r = home_create_cifs(h, &new_home);
1000 break;
1001
1002 default:
1003 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY),
1004 "Creating home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
1005 }
1006 if (r < 0)
1007 return r;
1008
1009 if (user_record_equal(h, new_home)) {
1010 *ret_home = NULL;
1011 return 0;
1012 }
1013
1014 *ret_home = TAKE_PTR(new_home);
1015 return 1;
1016}
1017
1018static int home_remove(UserRecord *h) {
1019 bool deleted = false;
1020 const char *ip, *hd;
1021 int r;
1022
1023 assert(h);
1024
1025 if (!h->user_name)
1026 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks user name, refusing.");
1027 if (!IN_SET(user_record_storage(h), USER_LUKS, USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT, USER_CIFS))
1028 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Removing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
1029
1030 hd = user_record_home_directory(h);
1031
1032 r = user_record_test_home_directory_and_warn(h);
1033 if (r < 0)
1034 return r;
1035 if (r == USER_TEST_MOUNTED)
1036 return log_error_errno(SYNTHETIC_ERRNO(EBUSY), "Directory %s is still mounted, refusing.", hd);
1037
1038 assert(hd);
1039
1040 r = user_record_test_image_path_and_warn(h);
1041 if (r < 0)
1042 return r;
1043
1044 ip = user_record_image_path(h);
1045
1046 switch (user_record_storage(h)) {
1047
1048 case USER_LUKS: {
1049 struct stat st;
1050
1051 assert(ip);
1052
1053 if (stat(ip, &st) < 0) {
6b8664cb 1054 if (errno != ENOENT)
80ace4f2 1055 return log_error_errno(errno, "Failed to stat() %s: %m", ip);
70a5db58
LP
1056
1057 } else {
1058 if (S_ISREG(st.st_mode)) {
1059 if (unlink(ip) < 0) {
1060 if (errno != ENOENT)
1061 return log_error_errno(errno, "Failed to remove %s: %m", ip);
1062 } else
1063 deleted = true;
1064
1065 } else if (S_ISBLK(st.st_mode))
1066 log_info("Not removing file system on block device %s.", ip);
1067 else
1068 return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK), "Image file %s is neither block device, nor regular, refusing removal.", ip);
1069 }
1070
1071 break;
1072 }
1073
1074 case USER_SUBVOLUME:
1075 case USER_DIRECTORY:
1076 case USER_FSCRYPT:
1077 assert(ip);
1078
1079 r = rm_rf(ip, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
1080 if (r < 0) {
1081 if (r != -ENOENT)
1082 return log_warning_errno(r, "Failed to remove %s: %m", ip);
1083 } else
1084 deleted = true;
1085
1086 /* If the image path and the home directory are the same invalidate the home directory, so
1087 * that we don't remove it anymore */
1088 if (path_equal(ip, hd))
1089 hd = NULL;
1090
1091 break;
1092
1093 case USER_CIFS:
1094 /* Nothing else to do here: we won't remove remote stuff. */
1095 log_info("Not removing home directory on remote server.");
1096 break;
1097
1098 default:
1099 assert_not_reached("unknown storage type");
1100 }
1101
1102 if (hd) {
1103 if (rmdir(hd) < 0) {
1104 if (errno != ENOENT)
1105 return log_error_errno(errno, "Failed to remove %s, ignoring: %m", hd);
1106 } else
1107 deleted = true;
1108 }
1109
1110 if (deleted)
1111 log_info("Everything completed.");
e4ff0393
FS
1112 else
1113 return log_notice_errno(SYNTHETIC_ERRNO(EALREADY),
1114 "Nothing to remove.");
70a5db58
LP
1115
1116 return 0;
1117}
1118
1119static int home_validate_update(UserRecord *h, HomeSetup *setup) {
1120 bool has_mount = false;
1121 int r;
1122
1123 assert(h);
1124 assert(setup);
1125
1126 if (!h->user_name)
1127 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks user name, refusing.");
1128 if (!uid_is_valid(h->uid))
1129 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks UID, refusing.");
1130 if (!IN_SET(user_record_storage(h), USER_LUKS, USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT, USER_CIFS))
1131 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Processing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
1132
1133 r = user_record_test_home_directory_and_warn(h);
1134 if (r < 0)
1135 return r;
1136
1137 has_mount = r == USER_TEST_MOUNTED;
1138
1139 r = user_record_test_image_path_and_warn(h);
1140 if (r < 0)
1141 return r;
1142 if (r == USER_TEST_ABSENT)
1143 return log_error_errno(SYNTHETIC_ERRNO(ENOENT), "Image path %s does not exist", user_record_image_path(h));
1144
1145 switch (user_record_storage(h)) {
1146
1147 case USER_DIRECTORY:
1148 case USER_SUBVOLUME:
1149 case USER_FSCRYPT:
1150 case USER_CIFS:
1151 break;
1152
1153 case USER_LUKS: {
1154 r = home_validate_update_luks(h, setup);
1155 if (r < 0)
1156 return r;
1157 if ((r > 0) != has_mount)
1158 return log_error_errno(SYNTHETIC_ERRNO(EBUSY), "Home mount incompletely set up.");
1159
1160 break;
1161 }
1162
1163 default:
1164 assert_not_reached("unexpected storage type");
1165 }
1166
1167 return has_mount; /* return true if the home record is already active */
1168}
1169
1170static int home_update(UserRecord *h, UserRecord **ret) {
1171 _cleanup_(user_record_unrefp) UserRecord *new_home = NULL, *header_home = NULL, *embedded_home = NULL;
1172 _cleanup_(strv_free_erasep) char **pkcs11_decrypted_passwords = NULL;
1173 _cleanup_(home_setup_undo) HomeSetup setup = HOME_SETUP_INIT;
1174 bool already_activated = false;
1175 int r;
1176
1177 assert(h);
1178 assert(ret);
1179
1180 r = user_record_authenticate(h, h, &pkcs11_decrypted_passwords);
1181 if (r < 0)
1182 return r;
1183
1184 r = home_validate_update(h, &setup);
1185 if (r < 0)
1186 return r;
1187
1188 already_activated = r > 0;
1189
1190 r = home_prepare(h, already_activated, &pkcs11_decrypted_passwords, &setup, &header_home);
1191 if (r < 0)
1192 return r;
1193
1194 r = home_load_embedded_identity(h, setup.root_fd, header_home, USER_RECONCILE_REQUIRE_NEWER, &pkcs11_decrypted_passwords, &embedded_home, &new_home);
1195 if (r < 0)
1196 return r;
1197
1198 r = home_store_header_identity_luks(new_home, &setup, header_home);
1199 if (r < 0)
1200 return r;
1201
1202 r = home_store_embedded_identity(new_home, setup.root_fd, h->uid, embedded_home);
1203 if (r < 0)
1204 return r;
1205
1206 r = home_extend_embedded_identity(new_home, h, &setup);
1207 if (r < 0)
1208 return r;
1209
1210 r = home_sync_and_statfs(setup.root_fd, NULL);
1211 if (r < 0)
1212 return r;
1213
1214 r = home_setup_undo(&setup);
1215 if (r < 0)
1216 return r;
1217
1218 log_info("Everything completed.");
1219
1220 *ret = TAKE_PTR(new_home);
1221 return 0;
1222}
1223
1224static int home_resize(UserRecord *h, UserRecord **ret) {
1225 _cleanup_(home_setup_undo) HomeSetup setup = HOME_SETUP_INIT;
1226 _cleanup_(strv_free_erasep) char **pkcs11_decrypted_passwords = NULL;
1227 bool already_activated = false;
1228 int r;
1229
1230 assert(h);
1231 assert(ret);
1232
1233 if (h->disk_size == UINT64_MAX)
1234 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No target size specified, refusing.");
1235
1236 r = user_record_authenticate(h, h, &pkcs11_decrypted_passwords);
1237 if (r < 0)
1238 return r;
1239
1240 r = home_validate_update(h, &setup);
1241 if (r < 0)
1242 return r;
1243
1244 already_activated = r > 0;
1245
1246 switch (user_record_storage(h)) {
1247
1248 case USER_LUKS:
1249 return home_resize_luks(h, already_activated, &pkcs11_decrypted_passwords, &setup, ret);
1250
1251 case USER_DIRECTORY:
1252 case USER_SUBVOLUME:
1253 case USER_FSCRYPT:
1254 return home_resize_directory(h, already_activated, &pkcs11_decrypted_passwords, &setup, ret);
1255
1256 default:
1257 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Resizing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
1258 }
1259}
1260
1261static int home_passwd(UserRecord *h, UserRecord **ret_home) {
1262 _cleanup_(user_record_unrefp) UserRecord *header_home = NULL, *embedded_home = NULL, *new_home = NULL;
1263 _cleanup_(strv_free_erasep) char **effective_passwords = NULL, **pkcs11_decrypted_passwords = NULL;
1264 _cleanup_(home_setup_undo) HomeSetup setup = HOME_SETUP_INIT;
1265 bool already_activated = false;
1266 int r;
1267
1268 assert(h);
1269 assert(ret_home);
1270
1271 if (!IN_SET(user_record_storage(h), USER_LUKS, USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT))
1272 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Changing password of home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
1273
1274 r = user_record_compile_effective_passwords(h, &effective_passwords, &pkcs11_decrypted_passwords);
1275 if (r < 0)
1276 return r;
1277
1278 r = home_validate_update(h, &setup);
1279 if (r < 0)
1280 return r;
1281
1282 already_activated = r > 0;
1283
1284 r = home_prepare(h, already_activated, &pkcs11_decrypted_passwords, &setup, &header_home);
1285 if (r < 0)
1286 return r;
1287
1288 r = home_load_embedded_identity(h, setup.root_fd, header_home, USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL, &pkcs11_decrypted_passwords, &embedded_home, &new_home);
1289 if (r < 0)
1290 return r;
1291
1292 switch (user_record_storage(h)) {
1293
1294 case USER_LUKS:
1295 r = home_passwd_luks(h, &setup, pkcs11_decrypted_passwords, effective_passwords);
1296 if (r < 0)
1297 return r;
1298 break;
1299
1300 case USER_FSCRYPT:
1301 r = home_passwd_fscrypt(h, &setup, pkcs11_decrypted_passwords, effective_passwords);
1302 if (r < 0)
1303 return r;
1304 break;
1305
1306 default:
1307 break;
1308 }
1309
1310 r = home_store_header_identity_luks(new_home, &setup, header_home);
1311 if (r < 0)
1312 return r;
1313
1314 r = home_store_embedded_identity(new_home, setup.root_fd, h->uid, embedded_home);
1315 if (r < 0)
1316 return r;
1317
1318 r = home_extend_embedded_identity(new_home, h, &setup);
1319 if (r < 0)
1320 return r;
1321
1322 r = home_sync_and_statfs(setup.root_fd, NULL);
1323 if (r < 0)
1324 return r;
1325
1326 r = home_setup_undo(&setup);
1327 if (r < 0)
1328 return r;
1329
1330 log_info("Everything completed.");
1331
1332 *ret_home = TAKE_PTR(new_home);
1333 return 1;
1334}
1335
1336static int home_inspect(UserRecord *h, UserRecord **ret_home) {
1337 _cleanup_(user_record_unrefp) UserRecord *header_home = NULL, *new_home = NULL;
1338 _cleanup_(home_setup_undo) HomeSetup setup = HOME_SETUP_INIT;
1339 _cleanup_(strv_free_erasep) char **pkcs11_decrypted_passwords = NULL;
1340 bool already_activated = false;
1341 int r;
1342
1343 assert(h);
1344 assert(ret_home);
1345
1346 r = user_record_authenticate(h, h, &pkcs11_decrypted_passwords);
1347 if (r < 0)
1348 return r;
1349
1350 r = home_validate_update(h, &setup);
1351 if (r < 0)
1352 return r;
1353
1354 already_activated = r > 0;
1355
1356 r = home_prepare(h, already_activated, &pkcs11_decrypted_passwords, &setup, &header_home);
1357 if (r < 0)
1358 return r;
1359
1360 r = home_load_embedded_identity(h, setup.root_fd, header_home, USER_RECONCILE_ANY, &pkcs11_decrypted_passwords, NULL, &new_home);
1361 if (r < 0)
1362 return r;
1363
1364 r = home_extend_embedded_identity(new_home, h, &setup);
1365 if (r < 0)
1366 return r;
1367
1368 r = home_setup_undo(&setup);
1369 if (r < 0)
1370 return r;
1371
1372 log_info("Everything completed.");
1373
1374 *ret_home = TAKE_PTR(new_home);
1375 return 1;
1376}
1377
1378static int home_lock(UserRecord *h) {
1379 int r;
1380
1381 assert(h);
1382
1383 if (!h->user_name)
1384 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record incomplete, refusing.");
1385 if (user_record_storage(h) != USER_LUKS)
1386 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Locking home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
1387
1388 r = user_record_test_home_directory_and_warn(h);
1389 if (r < 0)
1390 return r;
1391 if (r != USER_TEST_MOUNTED)
1392 return log_error_errno(SYNTHETIC_ERRNO(ENOEXEC), "Home directory of %s is not mounted, can't lock.", h->user_name);
1393
1394 r = home_lock_luks(h);
1395 if (r < 0)
1396 return r;
1397
1398 log_info("Everything completed.");
1399 return 1;
1400}
1401
1402static int home_unlock(UserRecord *h) {
1403 _cleanup_(strv_free_erasep) char **pkcs11_decrypted_passwords = NULL;
1404 int r;
1405
1406 assert(h);
1407
1408 if (!h->user_name)
1409 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record incomplete, refusing.");
1410 if (user_record_storage(h) != USER_LUKS)
1411 return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Unlocking home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
1412
1413 /* Note that we don't check if $HOME is actually mounted, since we want to avoid disk accesses on
1414 * that mount until we have resumed the device. */
1415
1416 r = user_record_authenticate(h, h, &pkcs11_decrypted_passwords);
1417 if (r < 0)
1418 return r;
1419
1420 r = home_unlock_luks(h, &pkcs11_decrypted_passwords);
1421 if (r < 0)
1422 return r;
1423
1424 log_info("Everything completed.");
1425 return 1;
1426}
1427
1428static int run(int argc, char *argv[]) {
1429 _cleanup_(user_record_unrefp) UserRecord *home = NULL, *new_home = NULL;
1430 _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
1431 _cleanup_(fclosep) FILE *opened_file = NULL;
1432 unsigned line = 0, column = 0;
1433 const char *json_path = NULL;
1434 FILE *json_file;
1435 usec_t start;
1436 int r;
1437
1438 start = now(CLOCK_MONOTONIC);
1439
1440 log_setup_service();
1441
1442 umask(0022);
1443
1444 if (argc < 2 || argc > 3)
1445 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program takes one or two arguments.");
1446
1447 if (argc > 2) {
1448 json_path = argv[2];
1449
1450 opened_file = fopen(json_path, "re");
1451 if (!opened_file)
1452 return log_error_errno(errno, "Failed to open %s: %m", json_path);
1453
1454 json_file = opened_file;
1455 } else {
1456 json_path = "<stdin>";
1457 json_file = stdin;
1458 }
1459
1460 r = json_parse_file(json_file, json_path, JSON_PARSE_SENSITIVE, &v, &line, &column);
1461 if (r < 0)
1462 return log_error_errno(r, "[%s:%u:%u] Failed to parse JSON data: %m", json_path, line, column);
1463
1464 home = user_record_new();
1465 if (!home)
1466 return log_oom();
1467
1468 r = user_record_load(home, v, USER_RECORD_LOAD_FULL|USER_RECORD_LOG);
1469 if (r < 0)
1470 return r;
1471
1472 /* Well known return values of these operations, that systemd-homed knows and converts to proper D-Bus errors:
1473 *
162392b7
ZJS
1474 * EMSGSIZE → file systems of this type cannot be shrunk
1475 * ETXTBSY → file systems of this type can only be shrunk offline
70a5db58
LP
1476 * ERANGE → file system size too small
1477 * ENOLINK → system does not support selected storage backend
1478 * EPROTONOSUPPORT → system does not support selected file system
1479 * ENOTTY → operation not support on this storage
1480 * ESOCKTNOSUPPORT → operation not support on this file system
1481 * ENOKEY → password incorrect (or not sufficient, or not supplied)
1482 * EBADSLT → similar, but PKCS#11 device is defined and might be able to provide password, if it was plugged in which it is not
1483 * ENOANO → suitable PKCS#11 device found, but PIN is missing to unlock it
1484 * ERFKILL → suitable PKCS#11 device found, but OK to ask for on-device interactive authentication not given
1485 * EOWNERDEAD → suitable PKCS#11 device found, but its PIN is locked
1486 * ENOLCK → suitable PKCS#11 device found, but PIN incorrect
1487 * ETOOMANYREFS → suitable PKCS#11 device found, but PIN incorrect, and only few tries left
1488 * EUCLEAN → suitable PKCS#11 device found, but PIN incorrect, and only one try left
1489 * EBUSY → file system is currently active
1490 * ENOEXEC → file system is currently not active
1491 * ENOSPC → not enough disk space for operation
1492 */
1493
1494 if (streq(argv[1], "activate"))
1495 r = home_activate(home, &new_home);
1496 else if (streq(argv[1], "deactivate"))
1497 r = home_deactivate(home, false);
1498 else if (streq(argv[1], "deactivate-force"))
1499 r = home_deactivate(home, true);
1500 else if (streq(argv[1], "create"))
1501 r = home_create(home, &new_home);
1502 else if (streq(argv[1], "remove"))
1503 r = home_remove(home);
1504 else if (streq(argv[1], "update"))
1505 r = home_update(home, &new_home);
1506 else if (streq(argv[1], "resize"))
1507 r = home_resize(home, &new_home);
1508 else if (streq(argv[1], "passwd"))
1509 r = home_passwd(home, &new_home);
1510 else if (streq(argv[1], "inspect"))
1511 r = home_inspect(home, &new_home);
1512 else if (streq(argv[1], "lock"))
1513 r = home_lock(home);
1514 else if (streq(argv[1], "unlock"))
1515 r = home_unlock(home);
1516 else
1517 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown verb '%s'.", argv[1]);
1518 if (r == -ENOKEY && !strv_isempty(home->password)) { /* There were passwords specified but they were incorrect */
1519 usec_t end, n, d;
1520
1521 /* Make sure bad password replies always take at least 3s, and if longer multiples of 3s, so
1522 * that it's not clear how long we actually needed for our calculations. */
1523 n = now(CLOCK_MONOTONIC);
1524 assert(n >= start);
1525
1526 d = usec_sub_unsigned(n, start);
1527 if (d > BAD_PASSWORD_DELAY_USEC)
1528 end = start + DIV_ROUND_UP(d, BAD_PASSWORD_DELAY_USEC) * BAD_PASSWORD_DELAY_USEC;
1529 else
1530 end = start + BAD_PASSWORD_DELAY_USEC;
1531
1532 if (n < end)
1533 (void) usleep(usec_sub_unsigned(end, n));
1534 }
1535 if (r < 0)
1536 return r;
1537
1538 /* We always pass the new record back, regardless if it changed or not. This allows our caller to
1539 * prepare a fresh record, send to us, and only if it works use it without having to keep a local
1540 * copy. */
1541 if (new_home)
1542 json_variant_dump(new_home->json, JSON_FORMAT_NEWLINE, stdout, NULL);
1543
1544 return 0;
1545}
1546
1547DEFINE_MAIN_FUNCTION(run);