Open SCAP Library: systemdshared.h Source File

Open SCAP Library

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

systemdshared.h
1
7 /*
8 * Copyright 2014 Red Hat Inc., Durham, North Carolina.
9 * All Rights Reserved.
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 * Authors:
26 *
27 */
28
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32
33 #include <dbus/dbus.h>
34 #include "common/debug_priv.h"
35
36 // Old versions of libdbus API don't have DBusBasicValue and DBus8ByteStruct
37 // as a public typedefs.
38 // These two typedefs were copied from libdbus 1.8 branch, see
39 // http://cgit.freedesktop.org/dbus/dbus/tree/dbus/dbus-types.h?h=dbus-1.8#n137
40 typedef struct
41 {
42 dbus_uint32_t first32;
43 dbus_uint32_t second32;
44 } _DBus8ByteStruct;
45
46 typedef union
47 {
48 unsigned char bytes[8];
49 dbus_int16_t i16;
50 dbus_uint16_t u16;
51 dbus_int32_t i32;
52 dbus_uint32_t u32;
53 dbus_bool_t bool_val;
54 #ifdef DBUS_HAVE_INT64
55 dbus_int64_t i64;
56 dbus_uint64_t u64;
57 #endif
58 _DBus8ByteStruct eight;
59 double dbl;
60 unsigned char byt;
61 char *str;
62 int fd;
63 } _DBusBasicValue;
64
65 static char *get_path_by_unit(DBusConnection *conn, const char *unit)
66 {
67 DBusMessage *msg = NULL;
68 DBusPendingCall *pending = NULL;
69 _DBusBasicValue path;
70 char *ret = NULL;
71
72 msg = dbus_message_new_method_call(
73 "org.freedesktop.systemd1",
74 "/org/freedesktop/systemd1",
75 "org.freedesktop.systemd1.Manager",
76 // LoadUnit is similar to GetUnit except it will load the unit file
77 // if it hasn't been loaded yet.
78 "LoadUnit"
79 );
80 if (msg == NULL) {
81 dI("Failed to create dbus_message via dbus_message_new_method_call!");
82 goto cleanup;
83 }
84
85 DBusMessageIter args;
86
87 dbus_message_iter_init_append(msg, &args);
88 if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &unit)) {
89 dI("Failed to append unit '%s' string parameter to dbus message!", unit);
90 goto cleanup;
91 }
92
93 if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) {
94 dI("Failed to send message via dbus!");
95 goto cleanup;
96 }
97 if (pending == NULL) {
98 dI("Invalid dbus pending call!");
99 goto cleanup;
100 }
101
102 dbus_connection_flush(conn);
103 dbus_message_unref(msg); msg = NULL;
104
105 dbus_pending_call_block(pending);
106 msg = dbus_pending_call_steal_reply(pending);
107 if (msg == NULL) {
108 dI("Failed to steal dbus pending call reply.");
109 goto cleanup;
110 }
111 dbus_pending_call_unref(pending); pending = NULL;
112
113 if (!dbus_message_iter_init(msg, &args)) {
114 dI("Failed to initialize iterator over received dbus message.");
115 goto cleanup;
116 }
117
118 if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH) {
119 dI("Expected string argument in reply. Instead received: %s.", dbus_message_type_to_string(dbus_message_iter_get_arg_type(&args)));
120 goto cleanup;
121 }
122
123 dbus_message_iter_get_basic(&args, &path);
124 ret = oscap_strdup(path.str);
125 dbus_message_unref(msg); msg = NULL;
126
127 cleanup:
128 if (pending != NULL)
129 dbus_pending_call_unref(pending);
130
131 if (msg != NULL)
132 dbus_message_unref(msg);
133
134 return ret;
135 }
136
137 static int get_all_systemd_units(DBusConnection* conn, int(*callback)(const char *, void *), void *cbarg)
138 {
139 DBusMessage *msg = NULL;
140 DBusPendingCall *pending = NULL;
141 char ret = 1;
142
143 msg = dbus_message_new_method_call(
144 "org.freedesktop.systemd1",
145 "/org/freedesktop/systemd1",
146 "org.freedesktop.systemd1.Manager",
147 "ListUnits"
148 );
149 if (msg == NULL) {
150 dI("Failed to create dbus_message via dbus_message_new_method_call!");
151 goto cleanup;
152 }
153
154 DBusMessageIter args, unit_iter;
155
156 // the args should be empty for this call
157 dbus_message_iter_init_append(msg, &args);
158
159 if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) {
160 dI("Failed to send message via dbus!");
161 goto cleanup;
162 }
163 if (pending == NULL) {
164 dI("Invalid dbus pending call!");
165 goto cleanup;
166 }
167
168 dbus_connection_flush(conn);
169 dbus_message_unref(msg); msg = NULL;
170
171 dbus_pending_call_block(pending);
172 msg = dbus_pending_call_steal_reply(pending);
173 if (msg == NULL) {
174 dI("Failed to steal dbus pending call reply.");
175 goto cleanup;
176 }
177 dbus_pending_call_unref(pending); pending = NULL;
178
179 if (!dbus_message_iter_init(msg, &args)) {
180 dI("Failed to initialize iterator over received dbus message.");
181 goto cleanup;
182 }
183
184 if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY) {
185 dI("Expected array of structs in reply. Instead received: %s.", dbus_message_type_to_string(dbus_message_iter_get_arg_type(&args)));
186 goto cleanup;
187 }
188
189 dbus_message_iter_recurse(&args, &unit_iter);
190 do {
191 if (dbus_message_iter_get_arg_type(&unit_iter) != DBUS_TYPE_STRUCT) {
192 dI("Expected unit struct as elements in returned array. Instead received: %s.", dbus_message_type_to_string(dbus_message_iter_get_arg_type(&unit_iter)));
193 goto cleanup;
194 }
195
196 DBusMessageIter unit_name;
197 dbus_message_iter_recurse(&unit_iter, &unit_name);
198
199 if (dbus_message_iter_get_arg_type(&unit_name) != DBUS_TYPE_STRING) {
200 dI("Expected string as the first element in the unit struct. Instead received: %s.", dbus_message_type_to_string(dbus_message_iter_get_arg_type(&unit_name)));
201 goto cleanup;
202 }
203
204 _DBusBasicValue value;
205 dbus_message_iter_get_basic(&unit_name, &value);
206 char *unit_name_s = oscap_strdup(value.str);
207 int cbret = callback(unit_name_s, cbarg);
208 oscap_free(unit_name_s);
209 if (cbret != 0) {
210 goto cleanup;
211 }
212 }
213 while (dbus_message_iter_next(&unit_iter));
214
215 dbus_message_unref(msg); msg = NULL;
216
217 ret = 0;
218
219 cleanup:
220 if (pending != NULL)
221 dbus_pending_call_unref(pending);
222
223 if (msg != NULL)
224 dbus_message_unref(msg);
225
226 return ret;
227 }
228
229 static char *dbus_value_to_string(DBusMessageIter *iter)
230 {
231 const int arg_type = dbus_message_iter_get_arg_type(iter);
232 if (dbus_type_is_basic(arg_type)) {
233 _DBusBasicValue value;
234 dbus_message_iter_get_basic(iter, &value);
235
236 switch (arg_type)
237 {
238 case DBUS_TYPE_BYTE:
239 return oscap_sprintf("%c", value.byt);
240
241 case DBUS_TYPE_BOOLEAN:
242 return oscap_strdup(value.bool_val ? "true" : "false");
243
244 case DBUS_TYPE_INT16:
245 return oscap_sprintf("%i", value.i16);
246
247 case DBUS_TYPE_UINT16:
248 return oscap_sprintf("%u", value.u16);
249
250 case DBUS_TYPE_INT32:
251 return oscap_sprintf("%i", value.i32);
252
253 case DBUS_TYPE_UINT32:
254 return oscap_sprintf("%u", value.u32);
255
256 #ifdef DBUS_HAVE_INT64
257 case DBUS_TYPE_INT64:
258 return oscap_sprintf("%lli", value.i32);
259
260 case DBUS_TYPE_UINT64:
261 return oscap_sprintf("%llu", value.u32);
262 #endif
263
264 case DBUS_TYPE_DOUBLE:
265 return oscap_sprintf("%g", value.dbl);
266
267 case DBUS_TYPE_STRING:
268 case DBUS_TYPE_OBJECT_PATH:
269 case DBUS_TYPE_SIGNATURE:
270 return oscap_strdup(value.str);
271
272 // non-basic types
273 //case DBUS_TYPE_ARRAY:
274 //case DBUS_TYPE_STRUCT:
275 //case DBUS_TYPE_DICT_ENTRY:
276 //case DBUS_TYPE_VARIANT:
277
278 //case DBUS_TYPE_UNIX_FD:
279 // return oscap_sprintf("%i", value.fd);
280
281 default:
282 dI("Encountered unknown dbus basic type!");
283 return oscap_strdup("error, unknown basic type!");
284 }
285 }
286 else if (arg_type == DBUS_TYPE_ARRAY) {
287 DBusMessageIter array;
288 dbus_message_iter_recurse(iter, &array);
289
290 char *ret = NULL;
291 do {
292 char *element = dbus_value_to_string(&array);
293
294 if (element == NULL)
295 continue;
296
297 char *old_ret = ret;
298 if (old_ret == NULL)
299 ret = oscap_sprintf("%s", element);
300 else
301 ret = oscap_sprintf("%s, %s", old_ret, element);
302
303 oscap_free(old_ret);
304 oscap_free(element);
305 }
306 while (dbus_message_iter_next(&array));
307
308 return ret;
309 }/*
310 else if (arg_type == DBUS_TYPE_VARIANT) {
311 DBusMessageIter inner;
312 dbus_message_iter_recurse(iter, &inner);
313 return dbus_value_to_string(&inner);
314 }*/
315
316 return NULL;
317 }
318
319 static DBusConnection *connect_dbus()
320 {
321 DBusConnection *conn = NULL;
322
323 DBusError err;
324 dbus_error_init(&err);
325
326 conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
327 if (dbus_error_is_set(&err)) {
328 dI("Failed to get DBUS_BUS_SYSTEM connection - %s", err.message);
329 goto cleanup;
330 }
331 if (conn == NULL) {
332 dI("DBusConnection == NULL!");
333 goto cleanup;
334 }
335
336 dbus_bus_register(conn, &err);
337 if (dbus_error_is_set(&err)) {
338 dI("Failed to register on dbus - %s", err.message);
339 goto cleanup;
340 }
341
342 cleanup:
343 dbus_error_free(&err);
344
345 return conn;
346 }
347
348 static void disconnect_dbus(DBusConnection *conn)
349 {
350 // NOOP
351
352 // Connections retrieved via dbus_bus_get shall not be destroyed,
353 // these connections are shared.
354 }
_DBus8ByteStruct
Definition: systemdshared.h:40
_DBusBasicValue::i32
dbus_int32_t i32
as int32
Definition: systemdshared.h:51
_DBusBasicValue::byt
unsigned char byt
as byte
Definition: systemdshared.h:60
_DBusBasicValue::u32
dbus_uint32_t u32
as int32
Definition: systemdshared.h:52
_DBusBasicValue::fd
int fd
as Unix file descriptor
Definition: systemdshared.h:62
_DBusBasicValue::eight
_DBus8ByteStruct eight
as 8-byte struct
Definition: systemdshared.h:58
_DBusBasicValue::str
char * str
as char* (string, object path or signature)
Definition: systemdshared.h:61
_DBusBasicValue
Definition: systemdshared.h:46
_DBusBasicValue::i16
dbus_int16_t i16
as int16
Definition: systemdshared.h:49
debug_priv.h
oscap debug helpers private header
oscap_free
#define oscap_free(p)
free wrapper
Definition: alloc.h:152
_DBusBasicValue::bool_val
dbus_bool_t bool_val
as boolean
Definition: systemdshared.h:53
_DBusBasicValue::u16
dbus_uint16_t u16
as int16
Definition: systemdshared.h:50
_DBusBasicValue::dbl
double dbl
as double
Definition: systemdshared.h:59