#include <syslog.h>
#endif /* HAVE_LIBAUDIT */
+#include "utils.h"
+
/* Store the value telling us if AppArmor D-Bus mediation is enabled. */
static dbus_bool_t apparmor_enabled = FALSE;
const char *mode; /* AppArmor confinement mode (freed by freeing *context) */
};
-typedef struct BusAppArmorConfinement BusAppArmorConfinement;
-
static BusAppArmorConfinement *bus_con = NULL;
/**
return confinement;
}
-static void
+void
bus_apparmor_confinement_unref (BusAppArmorConfinement *confinement)
{
+#ifdef HAVE_APPARMOR
if (!apparmor_enabled)
return;
free (confinement->context);
dbus_free (confinement);
}
+#endif
}
void
return FALSE;
#endif
}
+
+BusAppArmorConfinement*
+bus_apparmor_init_connection_confinement (DBusConnection *connection,
+ DBusError *error)
+{
+#ifdef HAVE_APPARMOR
+ BusAppArmorConfinement *confinement;
+ char *context, *mode;
+ int fd;
+
+ if (!apparmor_enabled)
+ return NULL;
+
+ _dbus_assert (connection != NULL);
+
+ if (!dbus_connection_get_socket (connection, &fd))
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Failed to get socket file descriptor of connection");
+ return NULL;
+ }
+
+ if (aa_getpeercon (fd, &context, &mode) == -1)
+ {
+ if (errno == ENOMEM)
+ BUS_SET_OOM (error);
+ else
+ dbus_set_error (error, _dbus_error_from_errno (errno),
+ "Failed to get AppArmor confinement information of socket peer: %s",
+ _dbus_strerror (errno));
+ return NULL;
+ }
+
+ confinement = bus_apparmor_confinement_new (context, mode);
+ if (confinement == NULL)
+ {
+ BUS_SET_OOM (error);
+ free (context);
+ return NULL;
+ }
+
+ return confinement;
+#else
+ return NULL;
+#endif /* HAVE_APPARMOR */
+}
#define BUS_APPARMOR_H
#include <dbus/dbus.h>
+#include "bus.h"
void bus_apparmor_audit_init (void);
dbus_bool_t bus_apparmor_pre_init (void);
void bus_apparmor_shutdown (void);
dbus_bool_t bus_apparmor_enabled (void);
+void bus_apparmor_confinement_unref (BusAppArmorConfinement *confinement);
+BusAppArmorConfinement* bus_apparmor_init_connection_confinement (DBusConnection *connection,
+ DBusError *error);
+
#endif /* BUS_APPARMOR_H */
typedef struct BusPolicyRule BusPolicyRule;
typedef struct BusRegistry BusRegistry;
typedef struct BusSELinuxID BusSELinuxID;
+typedef struct BusAppArmorConfinement BusAppArmorConfinement;
typedef struct BusService BusService;
typedef struct BusOwner BusOwner;
typedef struct BusTransaction BusTransaction;
#include "signals.h"
#include "expirelist.h"
#include "selinux.h"
+#include "apparmor.h"
#include <dbus/dbus-list.h>
#include <dbus/dbus-hash.h>
#include <dbus/dbus-timeout.h>
char *cached_loginfo_string;
BusSELinuxID *selinux_id;
+ BusAppArmorConfinement *apparmor_confinement;
long connection_tv_sec; /**< Time when we connected (seconds component) */
long connection_tv_usec; /**< Time when we connected (microsec component) */
if (d->selinux_id)
bus_selinux_id_unref (d->selinux_id);
+
+ if (d->apparmor_confinement)
+ bus_apparmor_confinement_unref (d->apparmor_confinement);
dbus_free (d->cached_loginfo_string);
goto out;
}
+ d->apparmor_confinement = bus_apparmor_init_connection_confinement (connection,
+ &error);
+ if (dbus_error_is_set (&error))
+ {
+ /* This is a bit bogus because we pretend all errors
+ * are OOM; this is done because we know that in bus.c
+ * an OOM error disconnects the connection, which is
+ * the same thing we want on any other error.
+ */
+ dbus_error_free (&error);
+ goto out;
+ }
+
if (!dbus_connection_set_watch_functions (connection,
add_connection_watch,
remove_connection_watch,
if (d->selinux_id)
bus_selinux_id_unref (d->selinux_id);
d->selinux_id = NULL;
+
+ if (d->apparmor_confinement)
+ bus_apparmor_confinement_unref (d->apparmor_confinement);
+ d->apparmor_confinement = NULL;
if (!dbus_connection_set_watch_functions (connection,
NULL, NULL, NULL,