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