Open SCAP Library
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24  *
25  * Authors:
26  *
27  */
28 
29 #pragma once
30 
31 #ifndef OPENSCAP_OVAL_PROBES_SYSTEMDSHARED_H_
32 #define OPENSCAP_OVAL_PROBES_SYSTEMDSHARED_H_
33 
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37 
38 #include <limits.h>
39 #include <stdio.h>
40 #include "common/debug_priv.h"
41 #include "oscap_helpers.h"
42 #include "oval_dbus.h"
43 
44 
45 static char *get_path_by_unit(DBusConnection *conn, const char *unit)
46 {
47  DBusMessage *msg = NULL;
48  DBusPendingCall *pending = NULL;
49  _DBusBasicValue path;
50  char *ret = NULL;
51 
52  msg = dbus_message_new_method_call(
53  "org.freedesktop.systemd1",
54  "/org/freedesktop/systemd1",
55  "org.freedesktop.systemd1.Manager",
56  // LoadUnit is similar to GetUnit except it will load the unit file
57  // if it hasn't been loaded yet.
58  "LoadUnit"
59  );
60  dD("LoadUnit: %s", unit);
61 
62  if (msg == NULL) {
63  dD("Failed to create dbus_message via dbus_message_new_method_call!");
64  goto cleanup;
65  }
66 
67  DBusMessageIter args;
68 
69  dbus_message_iter_init_append(msg, &args);
70  if (!dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &unit)) {
71  dD("Failed to append unit '%s' string parameter to dbus message!", unit);
72  goto cleanup;
73  }
74 
75  if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) {
76  dD("Failed to send message via dbus!");
77  goto cleanup;
78  }
79  if (pending == NULL) {
80  dD("Invalid dbus pending call!");
81  goto cleanup;
82  }
83 
84  dbus_connection_flush(conn);
85  dbus_message_unref(msg); msg = NULL;
86 
87  dbus_pending_call_block(pending);
88  msg = dbus_pending_call_steal_reply(pending);
89  if (msg == NULL) {
90  dD("Failed to steal dbus pending call reply.");
91  goto cleanup;
92  }
93  dbus_pending_call_unref(pending); pending = NULL;
94 
95  if (!dbus_message_iter_init(msg, &args)) {
96  dD("Failed to initialize iterator over received dbus message.");
97  goto cleanup;
98  }
99 
100  if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH) {
101  dD("Expected object path argument in reply. Instead received: %s.", dbus_message_type_to_string(dbus_message_iter_get_arg_type(&args)));
102  goto cleanup;
103  }
104 
105  dbus_message_iter_get_basic(&args, &path);
106  ret = oscap_strdup(path.str);
107  dbus_message_unref(msg); msg = NULL;
108 
109 cleanup:
110  if (pending != NULL)
111  dbus_pending_call_unref(pending);
112 
113  if (msg != NULL)
114  dbus_message_unref(msg);
115 
116  return ret;
117 }
118 
119 static int get_all_systemd_units(DBusConnection* conn, int(*callback)(const char *, void *), void *cbarg)
120 {
121  DBusMessage *msg = NULL;
122  DBusPendingCall *pending = NULL;
123  char ret = 1;
124 
125  msg = dbus_message_new_method_call(
126  "org.freedesktop.systemd1",
127  "/org/freedesktop/systemd1",
128  "org.freedesktop.systemd1.Manager",
129  "ListUnitFiles"
130  );
131  if (msg == NULL) {
132  dD("Failed to create dbus_message via dbus_message_new_method_call!");
133  goto cleanup;
134  }
135 
136  DBusMessageIter args, unit_iter;
137 
138  // the args should be empty for this call
139  dbus_message_iter_init_append(msg, &args);
140 
141  if (!dbus_connection_send_with_reply(conn, msg, &pending, -1)) {
142  dD("Failed to send message via dbus!");
143  goto cleanup;
144  }
145  if (pending == NULL) {
146  dD("Invalid dbus pending call!");
147  goto cleanup;
148  }
149 
150  dbus_connection_flush(conn);
151  dbus_message_unref(msg); msg = NULL;
152 
153  dbus_pending_call_block(pending);
154  msg = dbus_pending_call_steal_reply(pending);
155  if (msg == NULL) {
156  dD("Failed to steal dbus pending call reply.");
157  goto cleanup;
158  }
159  dbus_pending_call_unref(pending); pending = NULL;
160 
161  if (!dbus_message_iter_init(msg, &args)) {
162  dD("Failed to initialize iterator over received dbus message.");
163  goto cleanup;
164  }
165 
166  if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY) {
167  dD("Expected array of structs in reply. Instead received: %s.", dbus_message_type_to_string(dbus_message_iter_get_arg_type(&args)));
168  goto cleanup;
169  }
170 
171  dbus_message_iter_recurse(&args, &unit_iter);
172  do {
173  if (dbus_message_iter_get_arg_type(&unit_iter) != DBUS_TYPE_STRUCT) {
174  dD("Expected unit struct as elements in returned array. Instead received: %s.", dbus_message_type_to_string(dbus_message_iter_get_arg_type(&unit_iter)));
175  goto cleanup;
176  }
177 
178  DBusMessageIter unit_full_path_and_name;
179  dbus_message_iter_recurse(&unit_iter, &unit_full_path_and_name);
180 
181  if (dbus_message_iter_get_arg_type(&unit_full_path_and_name) != DBUS_TYPE_STRING) {
182  dD("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_full_path_and_name)));
183  goto cleanup;
184  }
185 
186  _DBusBasicValue value;
187  dbus_message_iter_get_basic(&unit_full_path_and_name, &value);
188  char *unit_name_s = oscap_strdup(basename(value.str));
189  oscap_strrm(unit_name_s, "@");
190  int cbret = callback(unit_name_s, cbarg);
191  free(unit_name_s);
192  if (cbret != 0) {
193  goto cleanup;
194  }
195  }
196  while (dbus_message_iter_next(&unit_iter));
197 
198  dbus_message_unref(msg); msg = NULL;
199 
200  ret = 0;
201 
202 cleanup:
203  if (pending != NULL)
204  dbus_pending_call_unref(pending);
205 
206  if (msg != NULL)
207  dbus_message_unref(msg);
208 
209  return ret;
210 }
211 
212 #endif
oscap debug helpers private header
Definition: oval_dbus.h:40
char * str
as char* (string, object path or signature)
Definition: oval_dbus.h:54