|
|
cf36c6 |
diff --git a/src/OVAL/probes/unix/linux/systemdunitdependency.c b/src/OVAL/probes/unix/linux/systemdunitdependency.c
|
|
|
cf36c6 |
index 2f194ce07..e2cbdb7d2 100644
|
|
|
cf36c6 |
--- a/src/OVAL/probes/unix/linux/systemdunitdependency.c
|
|
|
cf36c6 |
+++ b/src/OVAL/probes/unix/linux/systemdunitdependency.c
|
|
|
cf36c6 |
@@ -37,6 +37,8 @@
|
|
|
cf36c6 |
#include "common/list.h"
|
|
|
cf36c6 |
#include <string.h>
|
|
|
cf36c6 |
|
|
|
cf36c6 |
+static void get_all_dependencies_by_unit(DBusConnection *conn, const char *unit, SEXP_t *item, struct oscap_htable *visited_units);
|
|
|
cf36c6 |
+
|
|
|
cf36c6 |
static char *get_property_by_unit_path(DBusConnection *conn, const char *unit_path, const char *property)
|
|
|
cf36c6 |
{
|
|
|
cf36c6 |
DBusMessage *msg = NULL;
|
|
|
cf36c6 |
@@ -135,7 +137,38 @@ static bool is_unit_name_a_target(const char *unit)
|
|
|
cf36c6 |
return strncmp(unit + len - suffix_len, suffix, suffix_len) == 0;
|
|
|
cf36c6 |
}
|
|
|
cf36c6 |
|
|
|
cf36c6 |
-static void get_all_dependencies_by_unit(DBusConnection *conn, const char *unit, int(*callback)(const char *, void *), void *cbarg, bool include_requires, bool include_wants)
|
|
|
cf36c6 |
+static int add_unit_dependency(const char *dependency, SEXP_t *item, struct oscap_htable *visited_units)
|
|
|
cf36c6 |
+{
|
|
|
cf36c6 |
+ if (oscap_htable_get(visited_units, dependency) != NULL) {
|
|
|
cf36c6 |
+ return 1;
|
|
|
cf36c6 |
+ }
|
|
|
cf36c6 |
+ oscap_htable_add(visited_units, dependency, (void *) true);
|
|
|
cf36c6 |
+ SEXP_t *se_dependency = SEXP_string_new(dependency, strlen(dependency));
|
|
|
cf36c6 |
+ probe_item_ent_add(item, "dependency", NULL, se_dependency);
|
|
|
cf36c6 |
+ SEXP_free(se_dependency);
|
|
|
cf36c6 |
+ return 0;
|
|
|
cf36c6 |
+}
|
|
|
cf36c6 |
+
|
|
|
cf36c6 |
+static void process_unit_property(const char *property, DBusConnection *conn, const char *path, SEXP_t *item, struct oscap_htable *visited_units)
|
|
|
cf36c6 |
+{
|
|
|
cf36c6 |
+ char *values_s = get_property_by_unit_path(conn, path, property);
|
|
|
cf36c6 |
+ if (values_s) {
|
|
|
cf36c6 |
+ char **values = oscap_split(values_s, ", ");
|
|
|
cf36c6 |
+ for (int i = 0; values[i] != NULL; ++i) {
|
|
|
cf36c6 |
+ if (oscap_strcmp(values[i], "") == 0) {
|
|
|
cf36c6 |
+ continue;
|
|
|
cf36c6 |
+ }
|
|
|
cf36c6 |
+
|
|
|
cf36c6 |
+ if (add_unit_dependency(values[i], item, visited_units) == 0) {
|
|
|
cf36c6 |
+ get_all_dependencies_by_unit(conn, values[i], item, visited_units);
|
|
|
cf36c6 |
+ }
|
|
|
cf36c6 |
+ }
|
|
|
cf36c6 |
+ free(values);
|
|
|
cf36c6 |
+ }
|
|
|
cf36c6 |
+ free(values_s);
|
|
|
cf36c6 |
+}
|
|
|
cf36c6 |
+
|
|
|
cf36c6 |
+static void get_all_dependencies_by_unit(DBusConnection *conn, const char *unit, SEXP_t *item, struct oscap_htable *visited_units)
|
|
|
cf36c6 |
{
|
|
|
cf36c6 |
if (!unit || strcmp(unit, "(null)") == 0)
|
|
|
cf36c6 |
return;
|
|
|
cf36c6 |
@@ -146,66 +179,12 @@ static void get_all_dependencies_by_unit(DBusConnection *conn, const char *unit,
|
|
|
cf36c6 |
|
|
|
cf36c6 |
char *path = get_path_by_unit(conn, unit);
|
|
|
cf36c6 |
|
|
|
cf36c6 |
- if (include_requires) {
|
|
|
cf36c6 |
- char *requires_s = get_property_by_unit_path(conn, path, "Requires");
|
|
|
cf36c6 |
- if (requires_s) {
|
|
|
cf36c6 |
- char **requires = oscap_split(requires_s, ", ");
|
|
|
cf36c6 |
- for (int i = 0; requires[i] != NULL; ++i) {
|
|
|
cf36c6 |
- if (oscap_strcmp(requires[i], "") == 0)
|
|
|
cf36c6 |
- continue;
|
|
|
cf36c6 |
-
|
|
|
cf36c6 |
- if (callback(requires[i], cbarg) == 0) {
|
|
|
cf36c6 |
- get_all_dependencies_by_unit(conn, requires[i],
|
|
|
cf36c6 |
- callback, cbarg,
|
|
|
cf36c6 |
- include_requires, include_wants);
|
|
|
cf36c6 |
- } else {
|
|
|
cf36c6 |
- free(requires);
|
|
|
cf36c6 |
- free(requires_s);
|
|
|
cf36c6 |
- free(path);
|
|
|
cf36c6 |
- return;
|
|
|
cf36c6 |
- }
|
|
|
cf36c6 |
- }
|
|
|
cf36c6 |
- free(requires);
|
|
|
cf36c6 |
- }
|
|
|
cf36c6 |
- free(requires_s);
|
|
|
cf36c6 |
- }
|
|
|
cf36c6 |
-
|
|
|
cf36c6 |
- if (include_wants) {
|
|
|
cf36c6 |
- char *wants_s = get_property_by_unit_path(conn, path, "Wants");
|
|
|
cf36c6 |
- if (wants_s)
|
|
|
cf36c6 |
- {
|
|
|
cf36c6 |
- char **wants = oscap_split(wants_s, ", ");
|
|
|
cf36c6 |
- for (int i = 0; wants[i] != NULL; ++i) {
|
|
|
cf36c6 |
- if (oscap_strcmp(wants[i], "") == 0)
|
|
|
cf36c6 |
- continue;
|
|
|
cf36c6 |
-
|
|
|
cf36c6 |
- if (callback(wants[i], cbarg) == 0) {
|
|
|
cf36c6 |
- get_all_dependencies_by_unit(conn, wants[i],
|
|
|
cf36c6 |
- callback, cbarg,
|
|
|
cf36c6 |
- include_requires, include_wants);
|
|
|
cf36c6 |
- } else {
|
|
|
cf36c6 |
- free(wants);
|
|
|
cf36c6 |
- free(wants_s);
|
|
|
cf36c6 |
- free(path);
|
|
|
cf36c6 |
- return;
|
|
|
cf36c6 |
- }
|
|
|
cf36c6 |
- }
|
|
|
cf36c6 |
- free(wants);
|
|
|
cf36c6 |
- }
|
|
|
cf36c6 |
- free(wants_s);
|
|
|
cf36c6 |
- }
|
|
|
cf36c6 |
+ process_unit_property("Requires", conn, path, item, visited_units);
|
|
|
cf36c6 |
+ process_unit_property("Wants", conn, path, item, visited_units);
|
|
|
cf36c6 |
|
|
|
cf36c6 |
free(path);
|
|
|
cf36c6 |
}
|
|
|
cf36c6 |
|
|
|
cf36c6 |
-static int dependency_callback(const char *dependency, void *cbarg)
|
|
|
cf36c6 |
-{
|
|
|
cf36c6 |
- SEXP_t *item = (SEXP_t *)cbarg;
|
|
|
cf36c6 |
- SEXP_t *se_dependency = SEXP_string_new(dependency, strlen(dependency));
|
|
|
cf36c6 |
- probe_item_ent_add(item, "dependency", NULL, se_dependency);
|
|
|
cf36c6 |
- return 0;
|
|
|
cf36c6 |
-}
|
|
|
cf36c6 |
-
|
|
|
cf36c6 |
static int unit_callback(const char *unit, void *cbarg)
|
|
|
cf36c6 |
{
|
|
|
cf36c6 |
struct unit_callback_vars *vars = (struct unit_callback_vars *)cbarg;
|
|
|
cf36c6 |
@@ -221,8 +200,9 @@ static int unit_callback(const char *unit, void *cbarg)
|
|
|
cf36c6 |
"unit", OVAL_DATATYPE_SEXP, se_unit,
|
|
|
cf36c6 |
NULL);
|
|
|
cf36c6 |
|
|
|
cf36c6 |
- get_all_dependencies_by_unit(vars->dbus_conn, unit,
|
|
|
cf36c6 |
- dependency_callback, item, true, true);
|
|
|
cf36c6 |
+ struct oscap_htable *visited_units = oscap_htable_new();
|
|
|
cf36c6 |
+ get_all_dependencies_by_unit(vars->dbus_conn, unit, item, visited_units);
|
|
|
cf36c6 |
+ oscap_htable_free(visited_units, NULL);
|
|
|
cf36c6 |
|
|
|
cf36c6 |
probe_item_collect(vars->ctx, item);
|
|
|
cf36c6 |
SEXP_free(se_unit);
|