chiark / gitweb /
initctl: check peer credentials after connection
[elogind.git] / src / dbus-execute.c
1 /*-*- Mode: C; c-basic-offset: 8 -*-*/
2
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
9   under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2 of the License, or
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
16   General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <dbus/dbus.h>
24 #include <sys/prctl.h>
25
26 #include "dbus-execute.h"
27 #include "missing.h"
28 #include "ioprio.h"
29 #include "strv.h"
30
31 DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_input, exec_input, ExecInput);
32 DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_execute_append_output, exec_output, ExecOutput);
33
34 int bus_execute_append_oom_adjust(Manager *m, DBusMessageIter *i, const char *property, void *data) {
35         ExecContext *c = data;
36         int32_t n;
37
38         assert(m);
39         assert(i);
40         assert(property);
41         assert(c);
42
43         if (c->oom_adjust_set)
44                 n = c->oom_adjust;
45         else {
46                 char *t;
47
48                 n = 0;
49                 if (read_one_line_file("/proc/self/oom_adj", &t) >= 0) {
50                         safe_atoi(t, &n);
51                         free(t);
52                 }
53         }
54
55         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
56                 return -ENOMEM;
57
58         return 0;
59 }
60
61 int bus_execute_append_nice(Manager *m, DBusMessageIter *i, const char *property, void *data) {
62         ExecContext *c = data;
63         int32_t n;
64
65         assert(m);
66         assert(i);
67         assert(property);
68         assert(c);
69
70         if (c->nice_set)
71                 n = c->nice;
72         else
73                 n = getpriority(PRIO_PROCESS, 0);
74
75         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
76                 return -ENOMEM;
77
78         return 0;
79 }
80
81 int bus_execute_append_ioprio(Manager *m, DBusMessageIter *i, const char *property, void *data) {
82         ExecContext *c = data;
83         int32_t n;
84
85         assert(m);
86         assert(i);
87         assert(property);
88         assert(c);
89
90         if (c->ioprio_set)
91                 n = c->ioprio;
92         else
93                 n = ioprio_get(IOPRIO_WHO_PROCESS, 0);
94
95         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
96                 return -ENOMEM;
97
98         return 0;
99 }
100
101 int bus_execute_append_cpu_sched_policy(Manager *m, DBusMessageIter *i, const char *property, void *data) {
102         ExecContext *c = data;
103         int32_t n;
104
105         assert(m);
106         assert(i);
107         assert(property);
108         assert(c);
109
110         if (c->cpu_sched_set)
111                 n = c->cpu_sched_policy;
112         else
113                 n = sched_getscheduler(0);
114
115         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
116                 return -ENOMEM;
117
118         return 0;
119 }
120
121 int bus_execute_append_cpu_sched_priority(Manager *m, DBusMessageIter *i, const char *property, void *data) {
122         ExecContext *c = data;
123         int32_t n;
124
125         assert(m);
126         assert(i);
127         assert(property);
128         assert(c);
129
130         if (c->cpu_sched_set)
131                 n = c->cpu_sched_priority;
132         else {
133                 struct sched_param p;
134                 n = 0;
135
136                 zero(p);
137                 if (sched_getparam(0, &p) >= 0)
138                         n = p.sched_priority;
139         }
140
141         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_INT32, &n))
142                 return -ENOMEM;
143
144         return 0;
145 }
146
147 int bus_execute_append_affinity(Manager *m, DBusMessageIter *i, const char *property, void *data) {
148         ExecContext *c = data;
149         dbus_bool_t b;
150         DBusMessageIter sub;
151
152         assert(m);
153         assert(i);
154         assert(property);
155         assert(c);
156
157         if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "y", &sub))
158                 return -ENOMEM;
159
160         if (c->cpuset)
161                 b = dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &c->cpuset, CPU_ALLOC_SIZE(c->cpuset_ncpus));
162         else
163                 b = dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &c->cpuset, 0);
164
165         if (!b)
166                 return -ENOMEM;
167
168         if (!dbus_message_iter_close_container(i, &sub))
169                 return -ENOMEM;
170
171         return 0;
172 }
173
174 int bus_execute_append_timer_slack_nsec(Manager *m, DBusMessageIter *i, const char *property, void *data) {
175         ExecContext *c = data;
176         uint64_t u;
177
178         assert(m);
179         assert(i);
180         assert(property);
181         assert(c);
182
183         if (c->timer_slack_nsec_set)
184                 u = (uint64_t) c->timer_slack_nsec;
185         else
186                 u = (uint64_t) prctl(PR_GET_TIMERSLACK);
187
188         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u))
189                 return -ENOMEM;
190
191         return 0;
192 }
193
194 int bus_execute_append_capabilities(Manager *m, DBusMessageIter *i, const char *property, void *data) {
195         ExecContext *c = data;
196         char *t = NULL;
197         const char *s;
198         dbus_bool_t b;
199
200         assert(m);
201         assert(i);
202         assert(property);
203         assert(c);
204
205         if (c->capabilities)
206                 s = t = cap_to_text(c->capabilities, NULL);
207         else
208                 s = "";
209
210         if (!t)
211                 return -ENOMEM;
212
213         b = dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &s);
214         cap_free(t);
215
216         if (!b)
217                 return -ENOMEM;
218
219         return 0;
220 }
221
222 int bus_execute_append_rlimits(Manager *m, DBusMessageIter *i, const char *property, void *data) {
223         ExecContext *c = data;
224         int r;
225         uint64_t u;
226
227         assert(m);
228         assert(i);
229         assert(property);
230         assert(c);
231
232         assert_se((r = rlimit_from_string(property)) >= 0);
233
234         if (c->rlimit[r])
235                 u = (uint64_t) c->rlimit[r]->rlim_max;
236         else {
237                 struct rlimit rl;
238
239                 zero(rl);
240                 getrlimit(r, &rl);
241
242                 u = (uint64_t) rl.rlim_max;
243         }
244
245         if (!dbus_message_iter_append_basic(i, DBUS_TYPE_UINT64, &u))
246                 return -ENOMEM;
247
248         return 0;
249 }
250
251 int bus_execute_append_command(Manager *m, DBusMessageIter *i, const char *property, void *data) {
252         ExecCommand *c = data;
253         DBusMessageIter sub, sub2, sub3;
254
255         assert(m);
256         assert(i);
257         assert(property);
258
259         if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(sasttuii)", &sub))
260                 return -ENOMEM;
261
262         LIST_FOREACH(command, c, c) {
263                 char **l;
264                 uint32_t pid;
265                 int32_t code, status;
266
267                 if (!c->path)
268                         continue;
269
270                 if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) ||
271                     !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &c->path) ||
272                     !dbus_message_iter_open_container(&sub2, DBUS_TYPE_ARRAY, "s", &sub3))
273                         return -ENOMEM;
274
275                 STRV_FOREACH(l, c->argv)
276                         if (!dbus_message_iter_append_basic(&sub3, DBUS_TYPE_STRING, l))
277                                 return -ENOMEM;
278
279                 pid = (uint32_t) c->exec_status.pid;
280                 code = (int32_t) c->exec_status.code;
281                 status = (int32_t) c->exec_status.status;
282
283                 if (!dbus_message_iter_close_container(&sub2, &sub3) ||
284                     !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &c->exec_status.start_timestamp.realtime) ||
285                     !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT64, &c->exec_status.exit_timestamp.realtime) ||
286                     !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_UINT32, &c->exec_status.pid) ||
287                     !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_INT32, &c->exec_status.code) ||
288                     !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_INT32, &c->exec_status.status))
289                         return -ENOMEM;
290
291                 if (!dbus_message_iter_close_container(&sub, &sub2))
292                         return -ENOMEM;
293         }
294
295         if (!dbus_message_iter_close_container(i, &sub))
296                 return -ENOMEM;
297
298         return 0;
299 }