1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 #pragma once
3 
4 typedef struct Home Home;
5 
6 #include "homed-manager.h"
7 #include "homed-operation.h"
8 #include "list.h"
9 #include "ordered-set.h"
10 #include "stat-util.h"
11 #include "user-record.h"
12 
13 typedef enum HomeState {
14         HOME_UNFIXATED,               /* home exists, but local record does not */
15         HOME_ABSENT,                  /* local record exists, but home does not */
16         HOME_INACTIVE,                /* record and home exist, but is not logged in */
17         HOME_DIRTY,                   /* like HOME_INACTIVE, but the home directory wasn't cleanly deactivated */
18         HOME_FIXATING,                /* generating local record from home */
19         HOME_FIXATING_FOR_ACTIVATION, /* fixating in order to activate soon */
20         HOME_FIXATING_FOR_ACQUIRE,    /* fixating because Acquire() was called */
21         HOME_ACTIVATING,
22         HOME_ACTIVATING_FOR_ACQUIRE,  /* activating because Acquire() was called */
23         HOME_DEACTIVATING,
24         HOME_ACTIVE,                  /* logged in right now */
25         HOME_LINGERING,               /* not logged in anymore, but we didn't manage to deactivate (because some process keeps it busy?) but we'll keep trying */
26         HOME_LOCKING,
27         HOME_LOCKED,
28         HOME_UNLOCKING,
29         HOME_UNLOCKING_FOR_ACQUIRE,   /* unlocking because Acquire() was called */
30         HOME_CREATING,
31         HOME_REMOVING,
32         HOME_UPDATING,
33         HOME_UPDATING_WHILE_ACTIVE,
34         HOME_RESIZING,
35         HOME_RESIZING_WHILE_ACTIVE,
36         HOME_PASSWD,
37         HOME_PASSWD_WHILE_ACTIVE,
38         HOME_AUTHENTICATING,
39         HOME_AUTHENTICATING_WHILE_ACTIVE,
40         HOME_AUTHENTICATING_FOR_ACQUIRE,  /* authenticating because Acquire() was called */
41         _HOME_STATE_MAX,
42         _HOME_STATE_INVALID = -EINVAL,
43 } HomeState;
44 
HOME_STATE_IS_ACTIVE(HomeState state)45 static inline bool HOME_STATE_IS_ACTIVE(HomeState state) {
46         return IN_SET(state,
47                       HOME_ACTIVE,
48                       HOME_LINGERING,
49                       HOME_UPDATING_WHILE_ACTIVE,
50                       HOME_RESIZING_WHILE_ACTIVE,
51                       HOME_PASSWD_WHILE_ACTIVE,
52                       HOME_AUTHENTICATING_WHILE_ACTIVE,
53                       HOME_AUTHENTICATING_FOR_ACQUIRE);
54 }
55 
HOME_STATE_IS_EXECUTING_OPERATION(HomeState state)56 static inline bool HOME_STATE_IS_EXECUTING_OPERATION(HomeState state) {
57         return IN_SET(state,
58                       HOME_FIXATING,
59                       HOME_FIXATING_FOR_ACTIVATION,
60                       HOME_FIXATING_FOR_ACQUIRE,
61                       HOME_ACTIVATING,
62                       HOME_ACTIVATING_FOR_ACQUIRE,
63                       HOME_DEACTIVATING,
64                       HOME_LOCKING,
65                       HOME_UNLOCKING,
66                       HOME_UNLOCKING_FOR_ACQUIRE,
67                       HOME_CREATING,
68                       HOME_REMOVING,
69                       HOME_UPDATING,
70                       HOME_UPDATING_WHILE_ACTIVE,
71                       HOME_RESIZING,
72                       HOME_RESIZING_WHILE_ACTIVE,
73                       HOME_PASSWD,
74                       HOME_PASSWD_WHILE_ACTIVE,
75                       HOME_AUTHENTICATING,
76                       HOME_AUTHENTICATING_WHILE_ACTIVE,
77                       HOME_AUTHENTICATING_FOR_ACQUIRE);
78 }
79 
HOME_STATE_SHALL_PIN(HomeState state)80 static inline bool HOME_STATE_SHALL_PIN(HomeState state) {
81         /* Like HOME_STATE_IS_ACTIVE() – but HOME_LINGERING is missing! */
82         return IN_SET(state,
83                       HOME_ACTIVE,
84                       HOME_UPDATING_WHILE_ACTIVE,
85                       HOME_RESIZING_WHILE_ACTIVE,
86                       HOME_PASSWD_WHILE_ACTIVE,
87                       HOME_AUTHENTICATING_WHILE_ACTIVE,
88                       HOME_AUTHENTICATING_FOR_ACQUIRE);
89 }
90 
91 #define HOME_STATE_SHALL_REBALANCE(state) HOME_STATE_SHALL_PIN(state)
92 
HOME_STATE_MAY_RETRY_DEACTIVATE(HomeState state)93 static inline bool HOME_STATE_MAY_RETRY_DEACTIVATE(HomeState state) {
94         /* Indicates when to leave the deactivate retry timer active */
95         return IN_SET(state,
96                       HOME_ACTIVE,
97                       HOME_LINGERING,
98                       HOME_DEACTIVATING,
99                       HOME_LOCKING,
100                       HOME_UNLOCKING,
101                       HOME_UNLOCKING_FOR_ACQUIRE,
102                       HOME_UPDATING_WHILE_ACTIVE,
103                       HOME_RESIZING_WHILE_ACTIVE,
104                       HOME_PASSWD_WHILE_ACTIVE,
105                       HOME_AUTHENTICATING_WHILE_ACTIVE,
106                       HOME_AUTHENTICATING_FOR_ACQUIRE);
107 }
108 
109 struct Home {
110         Manager *manager;
111         char *user_name;
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
119          * state on request as needed from the mount table and similar. */
120         HomeState state;
121         int signed_locally; /* signed only by us */
122 
123         UserRecord *record;
124 
125         pid_t worker_pid;
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 
136         /* When we create a home area and that fails, we should possibly unregister the record altogether
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
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. */
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;
161 
162         /* An fd to the top-level home directory we keep while logged in, to keep the dir busy */
163         int pin_fd;
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;
167 
168         /* An fd that locks the backing file of LUKS home dirs with a BSD lock. */
169         int luks_lock_fd;
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;
176 };
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);
188 int home_activate(Home *h, UserRecord *secret, sd_bus_error *error);
189 int home_authenticate(Home *h, UserRecord *secret, sd_bus_error *error);
190 int home_deactivate(Home *h, bool force, sd_bus_error *error);
191 int home_create(Home *h, UserRecord *secret, sd_bus_error *error);
192 int home_remove(Home *h, sd_bus_error *error);
193 int home_update(Home *h, UserRecord *new_record, sd_bus_error *error);
194 int home_resize(Home *h, uint64_t disk_size, UserRecord *secret, bool automatic, sd_bus_error *error);
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 
200 HomeState home_get_state(Home *h);
201 
202 int home_get_disk_status(Home *h, uint64_t *ret_disk_size,uint64_t *ret_disk_usage, uint64_t *ret_disk_free, uint64_t *ret_disk_ceiling, uint64_t *ret_disk_floor, statfs_f_type_t *ret_fstype, mode_t *ret_access_mode);
203 
204 void home_process_notify(Home *h, char **l, int fd);
205 
206 int home_killall(Home *h);
207 
208 int home_augment_status(Home *h, UserRecordLoadFlags flags, UserRecord **ret);
209 
210 int home_create_fifo(Home *h, bool please_suspend);
211 int home_schedule_operation(Home *h, Operation *o, sd_bus_error *error);
212 
213 int home_auto_login(Home *h, char ***ret_seats);
214 
215 int home_set_current_message(Home *h, sd_bus_message *m);
216 
217 int home_wait_for_worker(Home *h);
218 
219 bool home_shall_rebalance(Home *h);
220 
221 bool home_is_busy(Home *h);
222 
223 const char *home_state_to_string(HomeState state);
224 HomeState home_state_from_string(const char *s);
225