]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/home/home-util.c
Merge pull request #16981 from keszybz/use-crypt_ra
[thirdparty/systemd.git] / src / home / home-util.c
CommitLineData
70a5db58
LP
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#include "dns-domain.h"
70a5db58
LP
4#include "home-util.h"
5#include "libcrypt-util.h"
6#include "memory-util.h"
7#include "path-util.h"
8#include "string-util.h"
9#include "strv.h"
10#include "user-util.h"
11
12bool suitable_user_name(const char *name) {
13
3e93027b 14 /* Checks whether the specified name is suitable for management via homed. Note that client-side
18143cd7 15 * we usually validate with the simple valid_user_group_name(), while server-side we are a bit more
2a4be3c5
ZJS
16 * restrictive, so that we can change the rules server-side without having to update things
17 * client-side too. */
70a5db58 18
7a8867ab 19 if (!valid_user_group_name(name, 0))
70a5db58
LP
20 return false;
21
22 /* We generally rely on NSS to tell us which users not to care for, but let's filter out some
23 * particularly well-known users. */
24 if (STR_IN_SET(name,
25 "root",
26 "nobody",
27 NOBODY_USER_NAME, NOBODY_GROUP_NAME))
28 return false;
29
30 /* Let's also defend our own namespace, as well as Debian's (unwritten?) logic of prefixing system
31 * users with underscores. */
32 if (STARTSWITH_SET(name, "systemd-", "_"))
33 return false;
34
35 return true;
36}
37
38int suitable_realm(const char *realm) {
39 _cleanup_free_ char *normalized = NULL;
40 int r;
41
42 /* Similar to the above: let's validate the realm a bit stricter server-side than client side */
43
44 r = dns_name_normalize(realm, 0, &normalized); /* this also checks general validity */
45 if (r == -EINVAL)
46 return 0;
47 if (r < 0)
48 return r;
49
50 if (!streq(realm, normalized)) /* is this normalized? */
51 return false;
52
53 if (dns_name_is_root(realm)) /* Don't allow top level domain */
54 return false;
55
56 return true;
57}
58
59int suitable_image_path(const char *path) {
60
61 return !empty_or_root(path) &&
62 path_is_valid(path) &&
63 path_is_absolute(path);
64}
65
c07bf7a4
LP
66bool supported_fstype(const char *fstype) {
67 /* Limit the set of supported file systems a bit, as protection against little tested kernel file
68 * systems. Also, we only support the resize ioctls for these file systems. */
69 return STR_IN_SET(fstype, "ext4", "btrfs", "xfs");
70}
71
70a5db58
LP
72int split_user_name_realm(const char *t, char **ret_user_name, char **ret_realm) {
73 _cleanup_free_ char *user_name = NULL, *realm = NULL;
74 const char *c;
75 int r;
76
77 assert(t);
78 assert(ret_user_name);
79 assert(ret_realm);
80
81 c = strchr(t, '@');
82 if (!c) {
83 user_name = strdup(t);
84 if (!user_name)
85 return -ENOMEM;
86 } else {
87 user_name = strndup(t, c - t);
88 if (!user_name)
89 return -ENOMEM;
90
91 realm = strdup(c + 1);
92 if (!realm)
93 return -ENOMEM;
94 }
95
96 if (!suitable_user_name(user_name))
97 return -EINVAL;
98
99 if (realm) {
100 r = suitable_realm(realm);
101 if (r < 0)
102 return r;
103 if (r == 0)
104 return -EINVAL;
105 }
106
107 *ret_user_name = TAKE_PTR(user_name);
108 *ret_realm = TAKE_PTR(realm);
109
110 return 0;
111}
112
113int bus_message_append_secret(sd_bus_message *m, UserRecord *secret) {
114 _cleanup_(erase_and_freep) char *formatted = NULL;
115 JsonVariant *v;
116 int r;
117
118 assert(m);
119 assert(secret);
120
121 if (!FLAGS_SET(secret->mask, USER_RECORD_SECRET))
122 return sd_bus_message_append(m, "s", "{}");
123
124 v = json_variant_by_key(secret->json, "secret");
125 if (!v)
126 return -EINVAL;
127
128 r = json_variant_format(v, 0, &formatted);
129 if (r < 0)
130 return r;
131
2ffee2c9
LP
132 (void) sd_bus_message_sensitive(m);
133
70a5db58
LP
134 return sd_bus_message_append(m, "s", formatted);
135}