1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include "bus-polkit.h"
7 #include "parse-util.h"
9 #include "unit-printf.h"
10 #include "user-util.h"
13 int bus_property_get_triggered_unit(
16 const char *interface
,
18 sd_bus_message
*reply
,
20 sd_bus_error
*error
) {
22 Unit
*u
= userdata
, *trigger
;
28 trigger
= UNIT_TRIGGER(u
);
30 return sd_bus_message_append(reply
, "s", trigger
? trigger
->id
: NULL
);
33 BUS_DEFINE_SET_TRANSIENT(mode_t
, "u", uint32_t, mode_t
, "%04o");
34 BUS_DEFINE_SET_TRANSIENT(unsigned, "u", uint32_t, unsigned, "%" PRIu32
);
36 static bool valid_user_group_name_or_id_relaxed(const char *u
) {
37 return valid_user_group_name(u
, VALID_USER_ALLOW_NUMERIC
|VALID_USER_RELAX
);
40 BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(user_relaxed
, valid_user_group_name_or_id_relaxed
);
41 BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(path
, path_is_absolute
);
43 int bus_set_transient_string(
47 sd_bus_message
*message
,
49 sd_bus_error
*error
) {
56 r
= sd_bus_message_read(message
, "s", &v
);
60 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
61 r
= free_and_strdup(p
, empty_to_null(v
));
65 unit_write_settingf(u
, flags
|UNIT_ESCAPE_SPECIFIERS
, name
,
66 "%s=%s", name
, strempty(v
));
72 int bus_set_transient_bool(
76 sd_bus_message
*message
,
78 sd_bus_error
*error
) {
84 r
= sd_bus_message_read(message
, "b", &v
);
88 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
90 unit_write_settingf(u
, flags
, name
, "%s=%s", name
, yes_no(v
));
96 int bus_set_transient_tristate(
100 sd_bus_message
*message
,
101 UnitWriteFlags flags
,
102 sd_bus_error
*error
) {
108 r
= sd_bus_message_read(message
, "b", &v
);
112 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
114 unit_write_settingf(u
, flags
, name
, "%s=%s", name
, yes_no(v
));
120 int bus_set_transient_usec_internal(
125 sd_bus_message
*message
,
126 UnitWriteFlags flags
,
127 sd_bus_error
*error
) {
134 r
= sd_bus_message_read(message
, "t", &v
);
138 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
140 *p
= v
!= 0 ? v
: USEC_INFINITY
;
144 char *n
= strndupa_safe(name
, strlen(name
) - 4);
145 unit_write_settingf(u
, flags
, name
, "%sSec=%s", n
, FORMAT_TIMESPAN(v
, USEC_PER_MSEC
));
151 int bus_verify_manage_units_async_full(
154 const char *polkit_message
,
155 sd_bus_message
*call
,
156 sd_bus_error
*error
) {
158 const char *details
[9] = {
163 if (polkit_message
) {
164 details
[4] = "polkit.message";
165 details
[5] = polkit_message
;
166 details
[6] = "polkit.gettext_domain";
167 details
[7] = GETTEXT_PACKAGE
;
170 return bus_verify_polkit_async(
172 "org.freedesktop.systemd1.manage-units",
174 &u
->manager
->polkit_registry
,
178 /* ret_format_str is an accumulator, so if it has any pre-existing content, new options will be appended to it */
179 int bus_read_mount_options(
180 sd_bus_message
*message
,
182 MountOptions
**ret_options
,
183 char **ret_format_str
,
184 const char *separator
) {
186 _cleanup_(mount_options_free_allp
) MountOptions
*options
= NULL
;
187 _cleanup_free_
char *format_str
= NULL
;
188 const char *mount_options
, *partition
;
195 r
= sd_bus_message_enter_container(message
, 'a', "(ss)");
199 while ((r
= sd_bus_message_read(message
, "(ss)", &partition
, &mount_options
)) > 0) {
200 _cleanup_free_
char *escaped
= NULL
;
201 _cleanup_free_ MountOptions
*o
= NULL
;
202 PartitionDesignator partition_designator
;
204 if (chars_intersect(mount_options
, WHITESPACE
))
205 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
,
206 "Invalid mount options string, contains whitespace character(s): %s", mount_options
);
208 partition_designator
= partition_designator_from_string(partition
);
209 if (partition_designator
< 0)
210 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid partition name %s", partition
);
212 /* Need to store the options with the escapes, so that they can be parsed again */
213 escaped
= shell_escape(mount_options
, ":");
217 if (!strextend_with_separator(&format_str
, separator
, partition
, ":", escaped
))
220 o
= new(MountOptions
, 1);
223 *o
= (MountOptions
) {
224 .partition_designator
= partition_designator
,
225 .options
= strdup(mount_options
),
229 LIST_APPEND(mount_options
, options
, TAKE_PTR(o
));
234 r
= sd_bus_message_exit_container(message
);
239 if (ret_format_str
) {
240 char *final
= strjoin(*ret_format_str
, !isempty(*ret_format_str
) ? separator
: "", format_str
);
243 free_and_replace(*ret_format_str
, final
);
245 LIST_JOIN(mount_options
, *ret_options
, options
);
251 int bus_property_get_activation_details(
254 const char *interface
,
255 const char *property
,
256 sd_bus_message
*reply
,
258 sd_bus_error
*error
) {
260 ActivationDetails
**details
= ASSERT_PTR(userdata
);
261 _cleanup_strv_free_
char **pairs
= NULL
;
266 r
= activation_details_append_pair(*details
, &pairs
);
270 r
= sd_bus_message_open_container(reply
, 'a', "(ss)");
274 STRV_FOREACH_PAIR(key
, value
, pairs
) {
275 r
= sd_bus_message_append(reply
, "(ss)", *key
, *value
);
280 return sd_bus_message_close_container(reply
);