]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
71d0b9d4 LP |
2 | #pragma once |
3 | ||
4 | #include <inttypes.h> | |
5 | #include <sys/types.h> | |
6 | ||
7 | #include "sd-id128.h" | |
8 | ||
1b466c09 | 9 | #include "hashmap.h" |
71d0b9d4 LP |
10 | #include "json.h" |
11 | #include "missing_resource.h" | |
12 | #include "time-util.h" | |
13 | ||
71d0b9d4 LP |
14 | typedef enum UserDisposition { |
15 | USER_INTRINSIC, /* root and nobody */ | |
16 | USER_SYSTEM, /* statically allocated users for system services */ | |
17 | USER_DYNAMIC, /* dynamically allocated users for system services */ | |
18 | USER_REGULAR, /* regular (typically human users) */ | |
19 | USER_CONTAINER, /* UID ranges allocated for container uses */ | |
20 | USER_RESERVED, /* Range above 2^31 */ | |
21 | _USER_DISPOSITION_MAX, | |
2d93c20e | 22 | _USER_DISPOSITION_INVALID = -EINVAL, |
71d0b9d4 LP |
23 | } UserDisposition; |
24 | ||
25 | typedef enum UserHomeStorage { | |
26 | USER_CLASSIC, | |
27 | USER_LUKS, | |
28 | USER_DIRECTORY, /* A directory, and a .identity file in it, which USER_CLASSIC lacks */ | |
29 | USER_SUBVOLUME, | |
30 | USER_FSCRYPT, | |
31 | USER_CIFS, | |
32 | _USER_STORAGE_MAX, | |
2d93c20e | 33 | _USER_STORAGE_INVALID = -EINVAL, |
71d0b9d4 LP |
34 | } UserStorage; |
35 | ||
36 | typedef enum UserRecordMask { | |
37 | /* The various sections an identity record may have, as bit mask */ | |
38 | USER_RECORD_REGULAR = 1U << 0, | |
39 | USER_RECORD_SECRET = 1U << 1, | |
40 | USER_RECORD_PRIVILEGED = 1U << 2, | |
41 | USER_RECORD_PER_MACHINE = 1U << 3, | |
42 | USER_RECORD_BINDING = 1U << 4, | |
43 | USER_RECORD_STATUS = 1U << 5, | |
44 | USER_RECORD_SIGNATURE = 1U << 6, | |
45 | _USER_RECORD_MASK_MAX = (1U << 7)-1 | |
46 | } UserRecordMask; | |
47 | ||
48 | typedef enum UserRecordLoadFlags { | |
49 | /* A set of flags used while loading a user record from JSON data. We leave the lower 6 bits free, | |
50 | * just as a safety precaution so that we can detect borked conversions between UserRecordMask and | |
51 | * UserRecordLoadFlags. */ | |
52 | ||
53 | /* What to require */ | |
54 | USER_RECORD_REQUIRE_REGULAR = USER_RECORD_REGULAR << 7, | |
55 | USER_RECORD_REQUIRE_SECRET = USER_RECORD_SECRET << 7, | |
56 | USER_RECORD_REQUIRE_PRIVILEGED = USER_RECORD_PRIVILEGED << 7, | |
57 | USER_RECORD_REQUIRE_PER_MACHINE = USER_RECORD_PER_MACHINE << 7, | |
58 | USER_RECORD_REQUIRE_BINDING = USER_RECORD_BINDING << 7, | |
59 | USER_RECORD_REQUIRE_STATUS = USER_RECORD_STATUS << 7, | |
60 | USER_RECORD_REQUIRE_SIGNATURE = USER_RECORD_SIGNATURE << 7, | |
61 | ||
62 | /* What to allow */ | |
63 | USER_RECORD_ALLOW_REGULAR = USER_RECORD_REGULAR << 14, | |
64 | USER_RECORD_ALLOW_SECRET = USER_RECORD_SECRET << 14, | |
65 | USER_RECORD_ALLOW_PRIVILEGED = USER_RECORD_PRIVILEGED << 14, | |
66 | USER_RECORD_ALLOW_PER_MACHINE = USER_RECORD_PER_MACHINE << 14, | |
67 | USER_RECORD_ALLOW_BINDING = USER_RECORD_BINDING << 14, | |
68 | USER_RECORD_ALLOW_STATUS = USER_RECORD_STATUS << 14, | |
69 | USER_RECORD_ALLOW_SIGNATURE = USER_RECORD_SIGNATURE << 14, | |
70 | ||
71 | /* What to strip */ | |
72 | USER_RECORD_STRIP_REGULAR = USER_RECORD_REGULAR << 21, | |
73 | USER_RECORD_STRIP_SECRET = USER_RECORD_SECRET << 21, | |
74 | USER_RECORD_STRIP_PRIVILEGED = USER_RECORD_PRIVILEGED << 21, | |
75 | USER_RECORD_STRIP_PER_MACHINE = USER_RECORD_PER_MACHINE << 21, | |
76 | USER_RECORD_STRIP_BINDING = USER_RECORD_BINDING << 21, | |
77 | USER_RECORD_STRIP_STATUS = USER_RECORD_STATUS << 21, | |
78 | USER_RECORD_STRIP_SIGNATURE = USER_RECORD_SIGNATURE << 21, | |
79 | ||
80 | /* Some special combinations that deserve explicit names */ | |
81 | USER_RECORD_LOAD_FULL = USER_RECORD_REQUIRE_REGULAR | | |
82 | USER_RECORD_ALLOW_SECRET | | |
83 | USER_RECORD_ALLOW_PRIVILEGED | | |
84 | USER_RECORD_ALLOW_PER_MACHINE | | |
85 | USER_RECORD_ALLOW_BINDING | | |
86 | USER_RECORD_ALLOW_STATUS | | |
87 | USER_RECORD_ALLOW_SIGNATURE, | |
88 | ||
89 | USER_RECORD_LOAD_REFUSE_SECRET = USER_RECORD_REQUIRE_REGULAR | | |
90 | USER_RECORD_ALLOW_PRIVILEGED | | |
91 | USER_RECORD_ALLOW_PER_MACHINE | | |
92 | USER_RECORD_ALLOW_BINDING | | |
93 | USER_RECORD_ALLOW_STATUS | | |
94 | USER_RECORD_ALLOW_SIGNATURE, | |
95 | ||
96 | USER_RECORD_LOAD_MASK_SECRET = USER_RECORD_REQUIRE_REGULAR | | |
97 | USER_RECORD_ALLOW_PRIVILEGED | | |
98 | USER_RECORD_ALLOW_PER_MACHINE | | |
99 | USER_RECORD_ALLOW_BINDING | | |
100 | USER_RECORD_ALLOW_STATUS | | |
101 | USER_RECORD_ALLOW_SIGNATURE | | |
102 | USER_RECORD_STRIP_SECRET, | |
103 | ||
104 | USER_RECORD_EXTRACT_SECRET = USER_RECORD_REQUIRE_SECRET | | |
105 | USER_RECORD_STRIP_REGULAR | | |
106 | USER_RECORD_STRIP_PRIVILEGED | | |
107 | USER_RECORD_STRIP_PER_MACHINE | | |
108 | USER_RECORD_STRIP_BINDING | | |
109 | USER_RECORD_STRIP_STATUS | | |
110 | USER_RECORD_STRIP_SIGNATURE, | |
111 | ||
112 | USER_RECORD_LOAD_SIGNABLE = USER_RECORD_REQUIRE_REGULAR | | |
113 | USER_RECORD_ALLOW_PRIVILEGED | | |
114 | USER_RECORD_ALLOW_PER_MACHINE, | |
115 | ||
116 | USER_RECORD_EXTRACT_SIGNABLE = USER_RECORD_LOAD_SIGNABLE | | |
117 | USER_RECORD_STRIP_SECRET | | |
118 | USER_RECORD_STRIP_BINDING | | |
119 | USER_RECORD_STRIP_STATUS | | |
120 | USER_RECORD_STRIP_SIGNATURE, | |
121 | ||
122 | USER_RECORD_LOAD_EMBEDDED = USER_RECORD_REQUIRE_REGULAR | | |
123 | USER_RECORD_ALLOW_PRIVILEGED | | |
124 | USER_RECORD_ALLOW_PER_MACHINE | | |
125 | USER_RECORD_ALLOW_SIGNATURE, | |
126 | ||
127 | USER_RECORD_EXTRACT_EMBEDDED = USER_RECORD_LOAD_EMBEDDED | | |
128 | USER_RECORD_STRIP_SECRET | | |
129 | USER_RECORD_STRIP_BINDING | | |
130 | USER_RECORD_STRIP_STATUS, | |
131 | ||
132 | /* Whether to log about loader errors beyond LOG_DEBUG */ | |
133 | USER_RECORD_LOG = 1U << 28, | |
134 | ||
135 | /* Whether to ignore errors and load what we can */ | |
136 | USER_RECORD_PERMISSIVE = 1U << 29, | |
1a298a20 LP |
137 | |
138 | /* Whether an empty record is OK */ | |
139 | USER_RECORD_EMPTY_OK = 1U << 30, | |
71d0b9d4 LP |
140 | } UserRecordLoadFlags; |
141 | ||
142 | static inline UserRecordLoadFlags USER_RECORD_REQUIRE(UserRecordMask m) { | |
143 | assert((m & ~_USER_RECORD_MASK_MAX) == 0); | |
144 | return m << 7; | |
145 | } | |
146 | ||
147 | static inline UserRecordLoadFlags USER_RECORD_ALLOW(UserRecordMask m) { | |
148 | assert((m & ~_USER_RECORD_MASK_MAX) == 0); | |
149 | return m << 14; | |
150 | } | |
151 | ||
152 | static inline UserRecordLoadFlags USER_RECORD_STRIP(UserRecordMask m) { | |
153 | assert((m & ~_USER_RECORD_MASK_MAX) == 0); | |
154 | return m << 21; | |
155 | } | |
156 | ||
157 | static inline UserRecordMask USER_RECORD_REQUIRE_MASK(UserRecordLoadFlags f) { | |
158 | return (f >> 7) & _USER_RECORD_MASK_MAX; | |
159 | } | |
160 | ||
161 | static inline UserRecordMask USER_RECORD_ALLOW_MASK(UserRecordLoadFlags f) { | |
162 | return ((f >> 14) & _USER_RECORD_MASK_MAX) | USER_RECORD_REQUIRE_MASK(f); | |
163 | } | |
164 | ||
165 | static inline UserRecordMask USER_RECORD_STRIP_MASK(UserRecordLoadFlags f) { | |
166 | return (f >> 21) & _USER_RECORD_MASK_MAX; | |
167 | } | |
168 | ||
169 | static inline JsonDispatchFlags USER_RECORD_LOAD_FLAGS_TO_JSON_DISPATCH_FLAGS(UserRecordLoadFlags flags) { | |
170 | return (FLAGS_SET(flags, USER_RECORD_LOG) ? JSON_LOG : 0) | | |
171 | (FLAGS_SET(flags, USER_RECORD_PERMISSIVE) ? JSON_PERMISSIVE : 0); | |
172 | } | |
173 | ||
174 | typedef struct Pkcs11EncryptedKey { | |
175 | /* The encrypted passphrase, which can be decrypted with the private key indicated below */ | |
176 | void *data; | |
177 | size_t size; | |
178 | ||
179 | /* Where to find the private key to decrypt the encrypted passphrase above */ | |
180 | char *uri; | |
181 | ||
182 | /* What to test the decrypted passphrase against to allow access (classic UNIX password hash). Note | |
183 | * that the decrypted passphrase is also used for unlocking LUKS and fscrypt, and if the account is | |
184 | * backed by LUKS or fscrypt the hashed password is only an additional layer of authentication, not | |
185 | * the only. */ | |
186 | char *hashed_password; | |
187 | } Pkcs11EncryptedKey; | |
188 | ||
5e4fa456 LP |
189 | typedef struct Fido2HmacCredential { |
190 | void *id; | |
191 | size_t size; | |
192 | } Fido2HmacCredential; | |
193 | ||
194 | typedef struct Fido2HmacSalt { | |
195 | /* The FIDO2 Cridential ID to use */ | |
196 | Fido2HmacCredential credential; | |
197 | ||
198 | /* The FIDO2 salt value */ | |
199 | void *salt; | |
200 | size_t salt_size; | |
201 | ||
f04a98e1 | 202 | /* What to test the hashed salt value against, usually UNIX password hash here. */ |
5e4fa456 | 203 | char *hashed_password; |
17e7561a LP |
204 | |
205 | /* Whether the 'up', 'uv', 'clientPin' features are enabled. */ | |
206 | int uv, up, client_pin; | |
5e4fa456 LP |
207 | } Fido2HmacSalt; |
208 | ||
b3a97fd3 LP |
209 | typedef struct RecoveryKey { |
210 | /* The type of recovery key, must be "modhex64" right now */ | |
211 | char *type; | |
212 | ||
69e3234d | 213 | /* A UNIX password hash of the normalized form of modhex64 */ |
b3a97fd3 LP |
214 | char *hashed_password; |
215 | } RecoveryKey; | |
216 | ||
8bec643c LP |
217 | typedef enum AutoResizeMode { |
218 | AUTO_RESIZE_OFF, /* no automatic grow/shrink */ | |
219 | AUTO_RESIZE_GROW, /* grow at login */ | |
220 | AUTO_RESIZE_SHRINK_AND_GROW, /* shrink at logout + grow at login */ | |
221 | _AUTO_RESIZE_MODE_MAX, | |
222 | _AUTO_RESIZE_MODE_INVALID = -EINVAL, | |
223 | } AutoResizeMode; | |
224 | ||
9aa3e5eb LP |
225 | #define REBALANCE_WEIGHT_OFF UINT64_C(0) |
226 | #define REBALANCE_WEIGHT_DEFAULT UINT64_C(100) | |
d357b80d | 227 | #define REBALANCE_WEIGHT_BACKING UINT64_C(20) |
9aa3e5eb LP |
228 | #define REBALANCE_WEIGHT_MIN UINT64_C(1) |
229 | #define REBALANCE_WEIGHT_MAX UINT64_C(10000) | |
230 | #define REBALANCE_WEIGHT_UNSET UINT64_MAX | |
231 | ||
71d0b9d4 LP |
232 | typedef struct UserRecord { |
233 | /* The following three fields are not part of the JSON record */ | |
234 | unsigned n_ref; | |
235 | UserRecordMask mask; | |
236 | bool incomplete; /* incomplete due to security restrictions. */ | |
237 | ||
238 | char *user_name; | |
239 | char *realm; | |
240 | char *user_name_and_realm_auto; /* the user_name field concatenated with '@' and the realm, if the latter is defined */ | |
241 | char *real_name; | |
242 | char *email_address; | |
243 | char *password_hint; | |
244 | char *icon_name; | |
245 | char *location; | |
246 | ||
1b466c09 AV |
247 | char *blob_directory; |
248 | Hashmap *blob_manifest; | |
249 | ||
71d0b9d4 LP |
250 | UserDisposition disposition; |
251 | uint64_t last_change_usec; | |
252 | uint64_t last_password_change_usec; | |
253 | ||
254 | char *shell; | |
255 | mode_t umask; | |
256 | char **environment; | |
257 | char *time_zone; | |
258 | char *preferred_language; | |
49e55abb | 259 | char **additional_languages; |
71d0b9d4 LP |
260 | int nice_level; |
261 | struct rlimit *rlimits[_RLIMIT_MAX]; | |
262 | ||
263 | int locked; /* prohibit activation in general */ | |
264 | uint64_t not_before_usec; /* prohibit activation before this unix time */ | |
265 | uint64_t not_after_usec; /* prohibit activation after this unix time */ | |
266 | ||
267 | UserStorage storage; | |
268 | uint64_t disk_size; | |
269 | uint64_t disk_size_relative; /* Disk size, relative to the free bytes of the medium, normalized to UINT32_MAX = 100% */ | |
270 | char *skeleton_directory; | |
271 | mode_t access_mode; | |
8bec643c | 272 | AutoResizeMode auto_resize_mode; |
9aa3e5eb | 273 | uint64_t rebalance_weight; |
71d0b9d4 LP |
274 | |
275 | uint64_t tasks_max; | |
276 | uint64_t memory_high; | |
277 | uint64_t memory_max; | |
278 | uint64_t cpu_weight; | |
279 | uint64_t io_weight; | |
280 | ||
281 | bool nosuid; | |
282 | bool nodev; | |
283 | bool noexec; | |
284 | ||
285 | char **hashed_password; | |
286 | char **ssh_authorized_keys; | |
287 | char **password; | |
c0bde0d2 | 288 | char **token_pin; |
71d0b9d4 LP |
289 | |
290 | char *cifs_domain; | |
291 | char *cifs_user_name; | |
292 | char *cifs_service; | |
4c2ee5c7 | 293 | char *cifs_extra_mount_options; |
71d0b9d4 LP |
294 | |
295 | char *image_path; | |
296 | char *image_path_auto; /* when none is configured explicitly, this is where we place the implicit image */ | |
297 | char *home_directory; | |
298 | char *home_directory_auto; /* when none is set explicitly, this is where we place the implicit home directory */ | |
299 | ||
46c60f72 LP |
300 | /* fallback shell and home dir */ |
301 | char *fallback_shell; | |
302 | char *fallback_home_directory; | |
303 | ||
71d0b9d4 LP |
304 | uid_t uid; |
305 | gid_t gid; | |
306 | ||
307 | char **member_of; | |
308 | ||
309 | char *file_system_type; | |
310 | sd_id128_t partition_uuid; | |
311 | sd_id128_t luks_uuid; | |
312 | sd_id128_t file_system_uuid; | |
313 | ||
314 | int luks_discard; | |
5e86c82a | 315 | int luks_offline_discard; |
71d0b9d4 LP |
316 | char *luks_cipher; |
317 | char *luks_cipher_mode; | |
318 | uint64_t luks_volume_key_size; | |
319 | char *luks_pbkdf_hash_algorithm; | |
320 | char *luks_pbkdf_type; | |
b04ff66b | 321 | uint64_t luks_pbkdf_force_iterations; |
71d0b9d4 LP |
322 | uint64_t luks_pbkdf_time_cost_usec; |
323 | uint64_t luks_pbkdf_memory_cost; | |
324 | uint64_t luks_pbkdf_parallel_threads; | |
fd83c98e | 325 | uint64_t luks_sector_size; |
2e0001c2 | 326 | char *luks_extra_mount_options; |
71d0b9d4 LP |
327 | |
328 | uint64_t disk_usage; | |
329 | uint64_t disk_free; | |
330 | uint64_t disk_ceiling; | |
331 | uint64_t disk_floor; | |
332 | ||
46c60f72 LP |
333 | bool use_fallback; /* if true → use fallback_shell + fallback_home_directory instead of the regular ones */ |
334 | ||
71d0b9d4 LP |
335 | char *state; |
336 | char *service; | |
337 | int signed_locally; | |
338 | ||
339 | uint64_t good_authentication_counter; | |
340 | uint64_t bad_authentication_counter; | |
341 | uint64_t last_good_authentication_usec; | |
342 | uint64_t last_bad_authentication_usec; | |
343 | ||
344 | uint64_t ratelimit_begin_usec; | |
345 | uint64_t ratelimit_count; | |
346 | uint64_t ratelimit_interval_usec; | |
347 | uint64_t ratelimit_burst; | |
348 | ||
349 | int removable; | |
350 | int enforce_password_policy; | |
351 | int auto_login; | |
86019efa | 352 | int drop_caches; |
71d0b9d4 LP |
353 | |
354 | uint64_t stop_delay_usec; /* How long to leave systemd --user around on log-out */ | |
355 | int kill_processes; /* Whether to kill user processes forcibly on log-out */ | |
356 | ||
357 | /* The following exist mostly so that we can cover the full /etc/shadow set of fields */ | |
358 | uint64_t password_change_min_usec; /* maps to .sp_min */ | |
359 | uint64_t password_change_max_usec; /* maps to .sp_max */ | |
360 | uint64_t password_change_warn_usec; /* maps to .sp_warn */ | |
361 | uint64_t password_change_inactive_usec; /* maps to .sp_inact */ | |
362 | int password_change_now; /* Require a password change immediately on next login (.sp_lstchg = 0) */ | |
363 | ||
364 | char **pkcs11_token_uri; | |
365 | Pkcs11EncryptedKey *pkcs11_encrypted_key; | |
366 | size_t n_pkcs11_encrypted_key; | |
367 | int pkcs11_protected_authentication_path_permitted; | |
368 | ||
5e4fa456 LP |
369 | Fido2HmacCredential *fido2_hmac_credential; |
370 | size_t n_fido2_hmac_credential; | |
371 | Fido2HmacSalt *fido2_hmac_salt; | |
372 | size_t n_fido2_hmac_salt; | |
7b78db28 | 373 | int fido2_user_presence_permitted; |
17e7561a | 374 | int fido2_user_verification_permitted; |
5e4fa456 | 375 | |
b3a97fd3 LP |
376 | char **recovery_key_type; |
377 | RecoveryKey *recovery_key; | |
378 | size_t n_recovery_key; | |
379 | ||
8e1bc689 LP |
380 | char **capability_bounding_set; |
381 | char **capability_ambient_set; | |
382 | ||
71d0b9d4 LP |
383 | JsonVariant *json; |
384 | } UserRecord; | |
385 | ||
386 | UserRecord* user_record_new(void); | |
387 | UserRecord* user_record_ref(UserRecord *h); | |
388 | UserRecord* user_record_unref(UserRecord *h); | |
389 | ||
390 | DEFINE_TRIVIAL_CLEANUP_FUNC(UserRecord*, user_record_unref); | |
391 | ||
392 | int user_record_load(UserRecord *h, JsonVariant *v, UserRecordLoadFlags flags); | |
393 | int user_record_build(UserRecord **ret, ...); | |
394 | ||
395 | const char *user_record_user_name_and_realm(UserRecord *h); | |
396 | UserStorage user_record_storage(UserRecord *h); | |
397 | const char *user_record_file_system_type(UserRecord *h); | |
398 | const char *user_record_skeleton_directory(UserRecord *h); | |
399 | mode_t user_record_access_mode(UserRecord *h); | |
400 | const char *user_record_home_directory(UserRecord *h); | |
401 | const char *user_record_image_path(UserRecord *h); | |
402 | unsigned long user_record_mount_flags(UserRecord *h); | |
403 | const char *user_record_cifs_user_name(UserRecord *h); | |
404 | const char *user_record_shell(UserRecord *h); | |
405 | const char *user_record_real_name(UserRecord *h); | |
406 | bool user_record_luks_discard(UserRecord *h); | |
5e86c82a | 407 | bool user_record_luks_offline_discard(UserRecord *h); |
71d0b9d4 LP |
408 | const char *user_record_luks_cipher(UserRecord *h); |
409 | const char *user_record_luks_cipher_mode(UserRecord *h); | |
410 | uint64_t user_record_luks_volume_key_size(UserRecord *h); | |
411 | const char* user_record_luks_pbkdf_type(UserRecord *h); | |
b04ff66b | 412 | uint64_t user_record_luks_pbkdf_force_iterations(UserRecord *h); |
71d0b9d4 LP |
413 | usec_t user_record_luks_pbkdf_time_cost_usec(UserRecord *h); |
414 | uint64_t user_record_luks_pbkdf_memory_cost(UserRecord *h); | |
415 | uint64_t user_record_luks_pbkdf_parallel_threads(UserRecord *h); | |
fd83c98e | 416 | uint64_t user_record_luks_sector_size(UserRecord *h); |
71d0b9d4 LP |
417 | const char *user_record_luks_pbkdf_hash_algorithm(UserRecord *h); |
418 | gid_t user_record_gid(UserRecord *h); | |
419 | UserDisposition user_record_disposition(UserRecord *h); | |
420 | int user_record_removable(UserRecord *h); | |
421 | usec_t user_record_ratelimit_interval_usec(UserRecord *h); | |
422 | uint64_t user_record_ratelimit_burst(UserRecord *h); | |
423 | bool user_record_can_authenticate(UserRecord *h); | |
86019efa | 424 | bool user_record_drop_caches(UserRecord *h); |
8bec643c | 425 | AutoResizeMode user_record_auto_resize_mode(UserRecord *h); |
9aa3e5eb | 426 | uint64_t user_record_rebalance_weight(UserRecord *h); |
8e1bc689 LP |
427 | uint64_t user_record_capability_bounding_set(UserRecord *h); |
428 | uint64_t user_record_capability_ambient_set(UserRecord *h); | |
49e55abb | 429 | int user_record_languages(UserRecord *h, char ***ret); |
71d0b9d4 | 430 | |
a43eddbd LP |
431 | int user_record_build_image_path(UserStorage storage, const char *user_name_and_realm, char **ret); |
432 | ||
71d0b9d4 LP |
433 | bool user_record_equal(UserRecord *a, UserRecord *b); |
434 | bool user_record_compatible(UserRecord *a, UserRecord *b); | |
435 | int user_record_compare_last_change(UserRecord *a, UserRecord *b); | |
436 | ||
437 | usec_t user_record_ratelimit_next_try(UserRecord *h); | |
438 | ||
439 | int user_record_clone(UserRecord *h, UserRecordLoadFlags flags, UserRecord **ret); | |
440 | int user_record_masked_equal(UserRecord *a, UserRecord *b, UserRecordMask mask); | |
441 | ||
442 | int user_record_test_blocked(UserRecord *h); | |
443 | int user_record_test_password_change_required(UserRecord *h); | |
444 | ||
445 | /* The following six are user by group-record.c, that's why we export them here */ | |
446 | int json_dispatch_realm(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata); | |
0bb43080 | 447 | int json_dispatch_gecos(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata); |
71d0b9d4 LP |
448 | int json_dispatch_user_group_list(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata); |
449 | int json_dispatch_user_disposition(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata); | |
450 | ||
451 | int per_machine_id_match(JsonVariant *ids, JsonDispatchFlags flags); | |
452 | int per_machine_hostname_match(JsonVariant *hns, JsonDispatchFlags flags); | |
f0409e7b | 453 | int per_machine_match(JsonVariant *entry, JsonDispatchFlags flags); |
71d0b9d4 LP |
454 | int user_group_record_mangle(JsonVariant *v, UserRecordLoadFlags load_flags, JsonVariant **ret_variant, UserRecordMask *ret_mask); |
455 | ||
1b466c09 AV |
456 | #define BLOB_DIR_MAX_SIZE (UINT64_C(64) * U64_MB) |
457 | int suitable_blob_filename(const char *name); | |
458 | ||
71d0b9d4 LP |
459 | const char* user_storage_to_string(UserStorage t) _const_; |
460 | UserStorage user_storage_from_string(const char *s) _pure_; | |
461 | ||
462 | const char* user_disposition_to_string(UserDisposition t) _const_; | |
463 | UserDisposition user_disposition_from_string(const char *s) _pure_; | |
8bec643c LP |
464 | |
465 | const char* auto_resize_mode_to_string(AutoResizeMode m) _const_; | |
466 | AutoResizeMode auto_resize_mode_from_string(const char *s) _pure_; |