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
, "%040o");
34 BUS_DEFINE_SET_TRANSIENT(unsigned, "u", uint32_t, unsigned, "%" PRIu32
);
36 static inline 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_usec_internal(
101 sd_bus_message
*message
,
102 UnitWriteFlags flags
,
103 sd_bus_error
*error
) {
110 r
= sd_bus_message_read(message
, "t", &v
);
114 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
116 *p
= v
!= 0 ? v
: USEC_INFINITY
;
120 char *n
= strndupa_safe(name
, strlen(name
) - 4);
121 unit_write_settingf(u
, flags
, name
, "%sSec=%s", n
, FORMAT_TIMESPAN(v
, USEC_PER_MSEC
));
127 int bus_verify_manage_units_async_full(
131 const char *polkit_message
,
133 sd_bus_message
*call
,
134 sd_bus_error
*error
) {
136 const char *details
[9] = {
141 if (polkit_message
) {
142 details
[4] = "polkit.message";
143 details
[5] = polkit_message
;
144 details
[6] = "polkit.gettext_domain";
145 details
[7] = GETTEXT_PACKAGE
;
148 return bus_verify_polkit_async(
151 "org.freedesktop.systemd1.manage-units",
155 &u
->manager
->polkit_registry
,
159 /* ret_format_str is an accumulator, so if it has any pre-existing content, new options will be appended to it */
160 int bus_read_mount_options(
161 sd_bus_message
*message
,
163 MountOptions
**ret_options
,
164 char **ret_format_str
,
165 const char *separator
) {
167 _cleanup_(mount_options_free_allp
) MountOptions
*options
= NULL
;
168 _cleanup_free_
char *format_str
= NULL
;
169 const char *mount_options
, *partition
;
176 r
= sd_bus_message_enter_container(message
, 'a', "(ss)");
180 while ((r
= sd_bus_message_read(message
, "(ss)", &partition
, &mount_options
)) > 0) {
181 _cleanup_free_
char *escaped
= NULL
;
182 _cleanup_free_ MountOptions
*o
= NULL
;
183 PartitionDesignator partition_designator
;
185 if (chars_intersect(mount_options
, WHITESPACE
))
186 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
,
187 "Invalid mount options string, contains whitespace character(s): %s", mount_options
);
189 partition_designator
= partition_designator_from_string(partition
);
190 if (partition_designator
< 0)
191 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid partition name %s", partition
);
193 /* Need to store the options with the escapes, so that they can be parsed again */
194 escaped
= shell_escape(mount_options
, ":");
198 if (!strextend_with_separator(&format_str
, separator
, partition
, ":", escaped
))
201 o
= new(MountOptions
, 1);
204 *o
= (MountOptions
) {
205 .partition_designator
= partition_designator
,
206 .options
= strdup(mount_options
),
210 LIST_APPEND(mount_options
, options
, TAKE_PTR(o
));
215 r
= sd_bus_message_exit_container(message
);
220 if (ret_format_str
) {
221 char *final
= strjoin(*ret_format_str
, !isempty(*ret_format_str
) ? separator
: "", format_str
);
224 free_and_replace(*ret_format_str
, final
);
226 LIST_JOIN(mount_options
, *ret_options
, options
);
232 int bus_property_get_activation_details(
235 const char *interface
,
236 const char *property
,
237 sd_bus_message
*reply
,
239 sd_bus_error
*error
) {
241 ActivationDetails
**details
= ASSERT_PTR(userdata
);
242 _cleanup_strv_free_
char **pairs
= NULL
;
247 r
= activation_details_append_pair(*details
, &pairs
);
251 r
= sd_bus_message_open_container(reply
, 'a', "(ss)");
255 STRV_FOREACH_PAIR(key
, value
, pairs
) {
256 r
= sd_bus_message_append(reply
, "(ss)", *key
, *value
);
261 return sd_bus_message_close_container(reply
);