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