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