]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/home/home-util.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include "dns-domain.h"
6 #include "libcrypt-util.h"
7 #include "memory-util.h"
9 #include "string-util.h"
11 #include "user-util.h"
13 DEFINE_HASH_OPS_FULL(blob_fd_hash_ops
, char, path_hash_func
, path_compare
, free
, void, close_fd_ptr
);
15 bool suitable_user_name(const char *name
) {
17 /* Checks whether the specified name is suitable for management via homed. Note that client-side
18 * we usually validate with the simple valid_user_group_name(), while server-side we are a bit more
19 * restrictive, so that we can change the rules server-side without having to update things
22 if (!valid_user_group_name(name
, 0))
25 /* We generally rely on NSS to tell us which users not to care for, but let's filter out some
26 * particularly well-known users. */
30 NOBODY_USER_NAME
, NOBODY_GROUP_NAME
))
33 /* Let's also defend our own namespace, as well as Debian's (unwritten?) logic of prefixing system
34 * users with underscores. */
35 if (STARTSWITH_SET(name
, "systemd-", "_"))
41 int suitable_realm(const char *realm
) {
42 _cleanup_free_
char *normalized
= NULL
;
45 /* Similar to the above: let's validate the realm a bit stricter server-side than client side */
47 r
= dns_name_normalize(realm
, 0, &normalized
); /* this also checks general validity */
53 if (!streq(realm
, normalized
)) /* is this normalized? */
56 if (dns_name_is_root(realm
)) /* Don't allow top level domain */
62 int suitable_image_path(const char *path
) {
64 return !empty_or_root(path
) &&
65 path_is_valid(path
) &&
66 path_is_absolute(path
);
69 bool supported_fstype(const char *fstype
) {
70 /* Limit the set of supported file systems a bit, as protection against little tested kernel file
71 * systems. Also, we only support the resize ioctls for these file systems. */
72 return STR_IN_SET(fstype
, "ext4", "btrfs", "xfs");
75 int split_user_name_realm(const char *t
, char **ret_user_name
, char **ret_realm
) {
76 _cleanup_free_
char *user_name
= NULL
, *realm
= NULL
;
81 assert(ret_user_name
);
86 user_name
= strdup(t
);
90 user_name
= strndup(t
, c
- t
);
94 realm
= strdup(c
+ 1);
99 if (!suitable_user_name(user_name
))
103 r
= suitable_realm(realm
);
110 *ret_user_name
= TAKE_PTR(user_name
);
111 *ret_realm
= TAKE_PTR(realm
);
116 int bus_message_append_secret(sd_bus_message
*m
, UserRecord
*secret
) {
117 _cleanup_(erase_and_freep
) char *formatted
= NULL
;
124 if (!FLAGS_SET(secret
->mask
, USER_RECORD_SECRET
))
125 return sd_bus_message_append(m
, "s", "{}");
127 v
= json_variant_by_key(secret
->json
, "secret");
131 r
= json_variant_format(v
, 0, &formatted
);
135 (void) sd_bus_message_sensitive(m
);
137 return sd_bus_message_append(m
, "s", formatted
);
140 const char *home_record_dir(void) {
141 return secure_getenv("SYSTEMD_HOME_RECORD_DIR") ?: "/var/lib/systemd/home/";
144 const char *home_system_blob_dir(void) {
145 return secure_getenv("SYSTEMD_HOME_SYSTEM_BLOB_DIR") ?: "/var/cache/systemd/home/";