]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/dbus-job.c
util-lib: split our string related calls from util.[ch] into its own file string...
[thirdparty/systemd.git] / src / core / dbus-job.c
CommitLineData
d6c9574f 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
ea430986 2
a7334b09
LP
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
a7334b09
LP
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 16 Lesser General Public License for more details.
a7334b09 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
718db961 22#include "sd-bus.h"
07630cea
LP
23
24#include "dbus.h"
718db961 25#include "job.h"
07630cea
LP
26#include "log.h"
27#include "selinux-access.h"
28#include "string-util.h"
718db961 29#include "dbus-job.h"
718db961
LP
30
31static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, job_type, JobType);
32static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_state, job_state, JobState);
33
34static int property_get_unit(
35 sd_bus *bus,
36 const char *path,
37 const char *interface,
38 const char *property,
39 sd_bus_message *reply,
ebcf1f97
LP
40 void *userdata,
41 sd_bus_error *error) {
ea430986 42
68eda4bd 43 _cleanup_free_ char *p = NULL;
718db961 44 Job *j = userdata;
86fbf370 45
718db961
LP
46 assert(bus);
47 assert(reply);
86fbf370
LP
48 assert(j);
49
cad45ba1
LP
50 p = unit_dbus_path(j->unit);
51 if (!p)
86fbf370
LP
52 return -ENOMEM;
53
718db961 54 return sd_bus_message_append(reply, "(so)", j->unit->id, p);
86fbf370
LP
55}
56
19070062 57int bus_job_method_cancel(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961 58 Job *j = userdata;
ebcf1f97 59 int r;
ea430986 60
ea430986 61 assert(message);
718db961 62 assert(j);
86fbf370 63
8a188de9 64 r = mac_selinux_unit_access_check(j->unit, message, "stop", error);
ebcf1f97
LP
65 if (r < 0)
66 return r;
67
1d22e906
LP
68 /* Access is granted to the job owner */
69 if (!sd_bus_track_contains(j->clients, sd_bus_message_get_sender(message))) {
70
71 /* And for everybody else consult PolicyKit */
72 r = bus_verify_manage_units_async(j->unit->manager, message, error);
73 if (r < 0)
74 return r;
75 if (r == 0)
76 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
77 }
78
718db961 79 job_finish_and_invalidate(j, JOB_CANCELED, true);
2cccbca4 80
df2d202e 81 return sd_bus_reply_method_return(message, NULL);
ea430986
LP
82}
83
718db961
LP
84const sd_bus_vtable bus_job_vtable[] = {
85 SD_BUS_VTABLE_START(0),
283868e1 86 SD_BUS_METHOD("Cancel", NULL, NULL, bus_job_method_cancel, SD_BUS_VTABLE_UNPRIVILEGED),
556089dc
LP
87 SD_BUS_PROPERTY("Id", "u", NULL, offsetof(Job, id), SD_BUS_VTABLE_PROPERTY_CONST),
88 SD_BUS_PROPERTY("Unit", "(so)", property_get_unit, 0, SD_BUS_VTABLE_PROPERTY_CONST),
89 SD_BUS_PROPERTY("JobType", "s", property_get_type, offsetof(Job, type), SD_BUS_VTABLE_PROPERTY_CONST),
718db961
LP
90 SD_BUS_PROPERTY("State", "s", property_get_state, offsetof(Job, state), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
91 SD_BUS_VTABLE_END
ea430986 92};
c1e1601e 93
8f8f05a9 94static int send_new_signal(sd_bus *bus, void *userdata) {
718db961 95 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
1508e858 96 _cleanup_free_ char *p = NULL;
8f8f05a9 97 Job *j = userdata;
718db961
LP
98 int r;
99
100 assert(bus);
101 assert(j);
c1e1601e 102
97e6a119
MS
103 p = job_dbus_path(j);
104 if (!p)
718db961 105 return -ENOMEM;
c1e1601e 106
718db961
LP
107 r = sd_bus_message_new_signal(
108 bus,
151b9b96 109 &m,
718db961
LP
110 "/org/freedesktop/systemd1",
111 "org.freedesktop.systemd1.Manager",
151b9b96 112 "JobNew");
718db961
LP
113 if (r < 0)
114 return r;
115
116 r = sd_bus_message_append(m, "uos", j->id, p, j->unit->id);
117 if (r < 0)
118 return r;
119
8f8f05a9 120 return sd_bus_send(bus, m, NULL);
c1e1601e
LP
121}
122
8f8f05a9 123static int send_changed_signal(sd_bus *bus, void *userdata) {
1508e858 124 _cleanup_free_ char *p = NULL;
8f8f05a9 125 Job *j = userdata;
718db961
LP
126
127 assert(bus);
128 assert(j);
c1e1601e 129
97e6a119
MS
130 p = job_dbus_path(j);
131 if (!p)
718db961 132 return -ENOMEM;
c1e1601e 133
718db961 134 return sd_bus_emit_properties_changed(bus, p, "org.freedesktop.systemd1.Job", "State", NULL);
97e6a119
MS
135}
136
137void bus_job_send_change_signal(Job *j) {
718db961
LP
138 int r;
139
97e6a119
MS
140 assert(j);
141
142 if (j->in_dbus_queue) {
71fda00f 143 LIST_REMOVE(dbus_queue, j->manager->dbus_job_queue, j);
97e6a119
MS
144 j->in_dbus_queue = false;
145 }
146
b39a2770 147 r = bus_foreach_bus(j->manager, j->clients, j->sent_dbus_new_signal ? send_changed_signal : send_new_signal, j);
718db961 148 if (r < 0)
da927ba9 149 log_debug_errno(r, "Failed to send job change signal for %u: %m", j->id);
97e6a119
MS
150
151 j->sent_dbus_new_signal = true;
718db961
LP
152}
153
8f8f05a9 154static int send_removed_signal(sd_bus *bus, void *userdata) {
718db961
LP
155 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
156 _cleanup_free_ char *p = NULL;
8f8f05a9 157 Job *j = userdata;
718db961
LP
158 int r;
159
160 assert(bus);
161 assert(j);
162
163 p = job_dbus_path(j);
164 if (!p)
165 return -ENOMEM;
c1e1601e 166
718db961
LP
167 r = sd_bus_message_new_signal(
168 bus,
151b9b96 169 &m,
718db961
LP
170 "/org/freedesktop/systemd1",
171 "org.freedesktop.systemd1.Manager",
151b9b96 172 "JobRemoved");
718db961
LP
173 if (r < 0)
174 return r;
175
176 r = sd_bus_message_append(m, "uoss", j->id, p, j->unit->id, job_result_to_string(j->result));
177 if (r < 0)
178 return r;
179
8f8f05a9 180 return sd_bus_send(bus, m, NULL);
97e6a119 181}
c1e1601e 182
97e6a119 183void bus_job_send_removed_signal(Job *j) {
718db961 184 int r;
c1e1601e 185
718db961 186 assert(j);
97e6a119
MS
187
188 if (!j->sent_dbus_new_signal)
189 bus_job_send_change_signal(j);
190
b39a2770 191 r = bus_foreach_bus(j->manager, j->clients, send_removed_signal, j);
718db961 192 if (r < 0)
da927ba9 193 log_debug_errno(r, "Failed to send job remove signal for %u: %m", j->id);
c1e1601e 194}