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