]>
| Commit | Line | Data |
|---|---|---|
| db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
| 70a5db58 LP |
2 | #pragma once |
| 3 | ||
| 572c1fe6 | 4 | #include "homed-forward.h" |
| 3b0103aa | 5 | #include "pidref.h" |
| b0a7fb15 | 6 | #include "stat-util.h" |
| 52ee9ba1 | 7 | |
| 70a5db58 LP |
8 | typedef enum HomeState { |
| 9 | HOME_UNFIXATED, /* home exists, but local record does not */ | |
| 10 | HOME_ABSENT, /* local record exists, but home does not */ | |
| 11 | HOME_INACTIVE, /* record and home exist, but is not logged in */ | |
| 9be99f81 | 12 | HOME_DIRTY, /* like HOME_INACTIVE, but the home directory wasn't cleanly deactivated */ |
| 70a5db58 LP |
13 | HOME_FIXATING, /* generating local record from home */ |
| 14 | HOME_FIXATING_FOR_ACTIVATION, /* fixating in order to activate soon */ | |
| 15 | HOME_FIXATING_FOR_ACQUIRE, /* fixating because Acquire() was called */ | |
| 16 | HOME_ACTIVATING, | |
| 17 | HOME_ACTIVATING_FOR_ACQUIRE, /* activating because Acquire() was called */ | |
| 18 | HOME_DEACTIVATING, | |
| 19 | HOME_ACTIVE, /* logged in right now */ | |
| 23cff6d4 | 20 | HOME_LINGERING, /* not logged in anymore, but we didn't manage to deactivate (because some process keeps it busy?) but we'll keep trying */ |
| 70a5db58 LP |
21 | HOME_LOCKING, |
| 22 | HOME_LOCKED, | |
| 23 | HOME_UNLOCKING, | |
| 24 | HOME_UNLOCKING_FOR_ACQUIRE, /* unlocking because Acquire() was called */ | |
| 25 | HOME_CREATING, | |
| 26 | HOME_REMOVING, | |
| 27 | HOME_UPDATING, | |
| 28 | HOME_UPDATING_WHILE_ACTIVE, | |
| 29 | HOME_RESIZING, | |
| 30 | HOME_RESIZING_WHILE_ACTIVE, | |
| 31 | HOME_PASSWD, | |
| 32 | HOME_PASSWD_WHILE_ACTIVE, | |
| 33 | HOME_AUTHENTICATING, | |
| 34 | HOME_AUTHENTICATING_WHILE_ACTIVE, | |
| 35 | HOME_AUTHENTICATING_FOR_ACQUIRE, /* authenticating because Acquire() was called */ | |
| 36 | _HOME_STATE_MAX, | |
| 2d93c20e | 37 | _HOME_STATE_INVALID = -EINVAL, |
| 70a5db58 LP |
38 | } HomeState; |
| 39 | ||
| 40 | static inline bool HOME_STATE_IS_ACTIVE(HomeState state) { | |
| 41 | return IN_SET(state, | |
| 42 | HOME_ACTIVE, | |
| 23cff6d4 | 43 | HOME_LINGERING, |
| 70a5db58 LP |
44 | HOME_UPDATING_WHILE_ACTIVE, |
| 45 | HOME_RESIZING_WHILE_ACTIVE, | |
| 46 | HOME_PASSWD_WHILE_ACTIVE, | |
| 47 | HOME_AUTHENTICATING_WHILE_ACTIVE, | |
| 48 | HOME_AUTHENTICATING_FOR_ACQUIRE); | |
| 49 | } | |
| 50 | ||
| 51 | static inline bool HOME_STATE_IS_EXECUTING_OPERATION(HomeState state) { | |
| 52 | return IN_SET(state, | |
| 53 | HOME_FIXATING, | |
| 54 | HOME_FIXATING_FOR_ACTIVATION, | |
| 55 | HOME_FIXATING_FOR_ACQUIRE, | |
| 56 | HOME_ACTIVATING, | |
| 57 | HOME_ACTIVATING_FOR_ACQUIRE, | |
| 58 | HOME_DEACTIVATING, | |
| 59 | HOME_LOCKING, | |
| 60 | HOME_UNLOCKING, | |
| 61 | HOME_UNLOCKING_FOR_ACQUIRE, | |
| 62 | HOME_CREATING, | |
| 63 | HOME_REMOVING, | |
| 64 | HOME_UPDATING, | |
| 65 | HOME_UPDATING_WHILE_ACTIVE, | |
| 66 | HOME_RESIZING, | |
| 67 | HOME_RESIZING_WHILE_ACTIVE, | |
| 68 | HOME_PASSWD, | |
| 69 | HOME_PASSWD_WHILE_ACTIVE, | |
| 70 | HOME_AUTHENTICATING, | |
| 71 | HOME_AUTHENTICATING_WHILE_ACTIVE, | |
| 72 | HOME_AUTHENTICATING_FOR_ACQUIRE); | |
| 73 | } | |
| 74 | ||
| 23cff6d4 LP |
75 | static inline bool HOME_STATE_SHALL_PIN(HomeState state) { |
| 76 | /* Like HOME_STATE_IS_ACTIVE() – but HOME_LINGERING is missing! */ | |
| 77 | return IN_SET(state, | |
| 78 | HOME_ACTIVE, | |
| 79 | HOME_UPDATING_WHILE_ACTIVE, | |
| 80 | HOME_RESIZING_WHILE_ACTIVE, | |
| 81 | HOME_PASSWD_WHILE_ACTIVE, | |
| 82 | HOME_AUTHENTICATING_WHILE_ACTIVE, | |
| 83 | HOME_AUTHENTICATING_FOR_ACQUIRE); | |
| 84 | } | |
| 85 | ||
| d357b80d LP |
86 | #define HOME_STATE_SHALL_REBALANCE(state) HOME_STATE_SHALL_PIN(state) |
| 87 | ||
| 23cff6d4 LP |
88 | static inline bool HOME_STATE_MAY_RETRY_DEACTIVATE(HomeState state) { |
| 89 | /* Indicates when to leave the deactivate retry timer active */ | |
| 90 | return IN_SET(state, | |
| 91 | HOME_ACTIVE, | |
| 92 | HOME_LINGERING, | |
| 93 | HOME_DEACTIVATING, | |
| 94 | HOME_LOCKING, | |
| 95 | HOME_UNLOCKING, | |
| 96 | HOME_UNLOCKING_FOR_ACQUIRE, | |
| 97 | HOME_UPDATING_WHILE_ACTIVE, | |
| 98 | HOME_RESIZING_WHILE_ACTIVE, | |
| 99 | HOME_PASSWD_WHILE_ACTIVE, | |
| 100 | HOME_AUTHENTICATING_WHILE_ACTIVE, | |
| 101 | HOME_AUTHENTICATING_FOR_ACQUIRE); | |
| 102 | } | |
| 103 | ||
| 52ee9ba1 | 104 | typedef struct Home { |
| 70a5db58 | 105 | Manager *manager; |
| 40fd0e04 LP |
106 | |
| 107 | /* The fields this record can be looked up by. This is kinda redundant, as the same information is | |
| 108 | * available in the .record field, but we keep separate copies of these keys to make memory | |
| 109 | * management for the hashmaps easier. */ | |
| 70a5db58 | 110 | char *user_name; |
| 40fd0e04 | 111 | char **aliases; |
| 70a5db58 LP |
112 | uid_t uid; |
| 113 | ||
| 114 | char *sysfs; /* When found via plugged in device, the sysfs path to it */ | |
| 115 | ||
| 116 | /* Note that the 'state' field is only set to a state while we are doing something (i.e. activating, | |
| 117 | * deactivating, creating, removing, and such), or when the home is an "unfixated" one. When we are | |
| 118 | * done with an operation we invalidate the state. This is hint for home_get_state() to check the | |
| 7802194a | 119 | * state on request as needed from the mount table and similar. */ |
| 70a5db58 LP |
120 | HomeState state; |
| 121 | int signed_locally; /* signed only by us */ | |
| 122 | ||
| 123 | UserRecord *record; | |
| 124 | ||
| 3b0103aa | 125 | PidRef worker_pid; |
| 70a5db58 LP |
126 | int worker_stdout_fd; |
| 127 | sd_event_source *worker_event_source; | |
| 128 | int worker_error_code; | |
| 129 | ||
| 130 | /* The message we are currently processing, and thus need to reply to on completion */ | |
| 131 | Operation *current_operation; | |
| 132 | ||
| 133 | /* Stores the raw, plaintext passwords, but only for short periods of time */ | |
| 134 | UserRecord *secret; | |
| 135 | ||
| 18143cd7 | 136 | /* When we create a home area and that fails, we should possibly unregister the record altogether |
| 70a5db58 LP |
137 | * again, which is remembered in this boolean. */ |
| 138 | bool unregister_on_failure; | |
| 139 | ||
| 140 | /* The reading side of a FIFO stored in /run/systemd/home/, the writing side being used for reference | |
| 5d490208 AV |
141 | * counting. The references dropped to zero as soon as we see EOF. This concept exists twice: once |
| 142 | * for clients that are fine if we suspend the home directory on system suspend, and once for clients | |
| 143 | * that are not ok with that. This allows us to determine for each home whether there are any clients | |
| 144 | * that support unsuspend. */ | |
| 70a5db58 LP |
145 | sd_event_source *ref_event_source_please_suspend; |
| 146 | sd_event_source *ref_event_source_dont_suspend; | |
| 147 | ||
| 148 | /* Any pending operations we still need to execute. These are for operations we want to queue if we | |
| 149 | * can't execute them right-away. */ | |
| 150 | OrderedSet *pending_operations; | |
| 151 | ||
| 152 | /* A defer event source that processes pending acquire/release/eof events. We have a common | |
| 153 | * dispatcher that processes all three kinds of events. */ | |
| 154 | sd_event_source *pending_event_source; | |
| 155 | ||
| 156 | /* Did we send out a D-Bus notification about this entry? */ | |
| 157 | bool announced; | |
| 158 | ||
| 159 | /* Used to coalesce bus PropertiesChanged events */ | |
| 160 | sd_event_source *deferred_change_event_source; | |
| 0c71e3ef LP |
161 | |
| 162 | /* An fd to the top-level home directory we keep while logged in, to keep the dir busy */ | |
| 163 | int pin_fd; | |
| 23cff6d4 LP |
164 | |
| 165 | /* A time event used to repeatedly try to unmount home dir after use if it didn't work on first try */ | |
| 166 | sd_event_source *retry_deactivate_event_source; | |
| 2aaf565a LP |
167 | |
| 168 | /* An fd that locks the backing file of LUKS home dirs with a BSD lock. */ | |
| 169 | int luks_lock_fd; | |
| d357b80d LP |
170 | |
| 171 | /* Space metrics during rebalancing */ | |
| 172 | uint64_t rebalance_size, rebalance_usage, rebalance_free, rebalance_min, rebalance_weight, rebalance_goal; | |
| 173 | ||
| 174 | /* Whether a rebalance operation is pending */ | |
| 175 | bool rebalance_pending; | |
| 52ee9ba1 | 176 | } Home; |
| 70a5db58 LP |
177 | |
| 178 | int home_new(Manager *m, UserRecord *hr, const char *sysfs, Home **ret); | |
| 179 | Home *home_free(Home *h); | |
| 180 | ||
| 181 | DEFINE_TRIVIAL_CLEANUP_FUNC(Home*, home_free); | |
| 182 | ||
| 183 | int home_set_record(Home *h, UserRecord *hr); | |
| 184 | int home_save_record(Home *h); | |
| 185 | int home_unlink_record(Home *h); | |
| 186 | ||
| 187 | int home_fixate(Home *h, UserRecord *secret, sd_bus_error *error); | |
| 336b1f19 | 188 | int home_activate(Home *h, bool if_referenced, UserRecord *secret, sd_bus_error *error); |
| 70a5db58 LP |
189 | int home_authenticate(Home *h, UserRecord *secret, sd_bus_error *error); |
| 190 | int home_deactivate(Home *h, bool force, sd_bus_error *error); | |
| a4d72746 | 191 | int home_create(Home *h, UserRecord *secret, Hashmap *blobs, uint64_t flags, sd_bus_error *error); |
| 70a5db58 | 192 | int home_remove(Home *h, sd_bus_error *error); |
| 6a9f0641 | 193 | int home_update(Home *h, UserRecord *hr, Hashmap *blobs, uint64_t flags, sd_bus_error *error); |
| 5ec87d57 | 194 | int home_resize(Home *h, uint64_t disk_size, UserRecord *secret, sd_bus_error *error); |
| 70a5db58 LP |
195 | int home_passwd(Home *h, UserRecord *new_secret, UserRecord *old_secret, sd_bus_error *error); |
| 196 | int home_unregister(Home *h, sd_bus_error *error); | |
| 197 | int home_lock(Home *h, sd_bus_error *error); | |
| 198 | int home_unlock(Home *h, UserRecord *secret, sd_bus_error *error); | |
| 199 | ||
| 64b74c86 LP |
200 | bool home_is_referenced(Home *h); |
| 201 | bool home_shall_suspend(Home *h); | |
| 70a5db58 LP |
202 | HomeState home_get_state(Home *h); |
| 203 | ||
| 6d302436 YW |
204 | int home_get_disk_status( |
| 205 | Home *h, | |
| 206 | uint64_t *ret_disk_size, | |
| 207 | uint64_t *ret_disk_usage, | |
| 208 | uint64_t *ret_disk_free, | |
| 209 | uint64_t *ret_disk_ceiling, | |
| 210 | uint64_t *ret_disk_floor, | |
| 211 | statfs_f_type_t *ret_fstype, | |
| 212 | mode_t *ret_access_mode); | |
| f639f60e | 213 | |
| 2aaf565a | 214 | void home_process_notify(Home *h, char **l, int fd); |
| 70a5db58 LP |
215 | |
| 216 | int home_killall(Home *h); | |
| 217 | ||
| 218 | int home_augment_status(Home *h, UserRecordLoadFlags flags, UserRecord **ret); | |
| 219 | ||
| 5d490208 | 220 | int home_create_fifo(Home *h, bool please_suspend); |
| 70a5db58 LP |
221 | int home_schedule_operation(Home *h, Operation *o, sd_bus_error *error); |
| 222 | ||
| 223 | int home_auto_login(Home *h, char ***ret_seats); | |
| 224 | ||
| 225 | int home_set_current_message(Home *h, sd_bus_message *m); | |
| 226 | ||
| 9796a9fb LP |
227 | int home_wait_for_worker(Home *h); |
| 228 | ||
| d357b80d LP |
229 | bool home_shall_rebalance(Home *h); |
| 230 | ||
| 231 | bool home_is_busy(Home *h); | |
| 232 | ||
| bfd5a068 | 233 | const char* home_state_to_string(HomeState state); |
| 70a5db58 | 234 | HomeState home_state_from_string(const char *s); |