Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add dbus-announce plugin #1255

Merged
merged 1 commit into from
Aug 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/man/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ man_man8_DATA += rpm-plugin-audit.8
endif
if DBUS
man_man8_DATA += rpm-plugin-systemd-inhibit.8
man_man8_DATA += rpm-plugin-dbus-announce.8
endif
if IMA
man_man8_DATA += rpm-plugin-ima.8
Expand All @@ -42,7 +43,7 @@ endif
EXTRA_DIST += rpm-plugins.8.md rpm-plugin-prioreset.8.md rpm-plugin-syslog.8.md
EXTRA_DIST += rpm-plugin-audit.8.md rpm-plugin-systemd-inhibit.8.md
EXTRA_DIST += rpm-plugin-ima.8.md rpm-plugin-selinux.8.md rpm2archive.8.md
EXTRA_DIST += rpm-plugin-fapolicyd.8.md
EXTRA_DIST += rpm-plugin-fapolicyd.8.md rpm-plugin-dbus-announce.8.md


man_fr_man8dir = $(mandir)/fr/man8
Expand Down
38 changes: 38 additions & 0 deletions docs/man/rpm-plugin-dbus-announce.8.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
date: 03 Jun 2020
section: 8
title: 'RPM-DBUS-ANNOUNCE'
---

NAME
====

rpm-plugin-dbus-announce - DBus plugin for the RPM Package Manager

Description
===========

The plugin writes basic information about rpm transactions to the system
dbus - like packages installed or removed. Other programs can subscribe
to the signals to be notified of the packages on the system change.

DBus Signals
============

Sends **StartTransaction** and **EndTransaction** messages from the
**/org/rpm/Transaction** object with the **org.rpm.Transaction**
interface.

The signal passes the DB cookie as a string and the transaction id as an
unsigned 32 bit integer.

Configuration
=============

There are currently no options for this plugin in particular. See
**rpm-plugins**(8) on how to control plugins in general.

SEE ALSO
========

*dbus-monitor*(1) *rpm-plugins*(8)
1 change: 1 addition & 0 deletions macros.in
Original file line number Diff line number Diff line change
Expand Up @@ -1144,6 +1144,7 @@ package or when debugging this package.\
%__transaction_fsverity %{__plugindir}/fsverity.so
%__transaction_prioreset %{__plugindir}/prioreset.so
%__transaction_audit %{__plugindir}/audit.so
%__transaction_dbus_announce %{__plugindir}/dbus_announce.so

#------------------------------------------------------------------------------
# Macros for further automated spec %setup and patch application
Expand Down
9 changes: 9 additions & 0 deletions plugins/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ systemd_inhibit_la_SOURCES = systemd_inhibit.c
systemd_inhibit_la_CPPFLAGS = $(AM_CPPFLAGS) @DBUS_CFLAGS@
systemd_inhibit_la_LIBADD = $(top_builddir)/lib/librpm.la $(top_builddir)/rpmio/librpmio.la @DBUS_LIBS@
plugins_LTLIBRARIES += systemd_inhibit.la

dbus_announce_la_SOURCES = dbus_announce.c
dbus_announce_la_CPPFLAGS = $(AM_CPPFLAGS) @DBUS_CFLAGS@
dbus_announce_la_LIBADD = $(top_builddir)/lib/librpm.la $(top_builddir)/rpmio/librpmio.la @DBUS_LIBS@
plugins_LTLIBRARIES += dbus_announce.la

dbus_confdir=$(sysconfdir)/dbus-1/system.d/
dbus_conf_DATA = org.rpm.conf
EXTRA_DIST = org.rpm.conf
endif

prioreset_la_SOURCES = prioreset.c
Expand Down
142 changes: 142 additions & 0 deletions plugins/dbus_announce.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
#include "system.h"

#include <dbus/dbus.h>
#include <rpm/rpmlog.h>
#include <rpm/rpmts.h>
#include <rpm/rpmdb.h>
#include "lib/rpmplugin.h"

struct dbus_announce_data {
DBusConnection * bus;
};

static rpmRC dbus_announce_init(rpmPlugin plugin, rpmts ts)
{
struct dbus_announce_data * state = rcalloc(1, sizeof(*state));
rpmPluginSetData(plugin, state);
return RPMRC_OK;
}

static void dbus_announce_close_bus(struct dbus_announce_data * state)
{
if (state->bus) {
dbus_connection_close(state->bus);
dbus_connection_unref(state->bus);
state->bus = NULL;
}
}

static rpmRC open_dbus(rpmPlugin plugin, rpmts ts)
{
DBusError err;
int rc = 0;
struct dbus_announce_data * state = rpmPluginGetData(plugin);

/* Already open */
if (state->bus)
return RPMRC_OK;

/* ...don't notify on test transactions */
if (rpmtsFlags(ts) & (RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_BUILD_PROBS))
return RPMRC_OK;

/* ...don't notify on chroot transactions */
if (!rstreq(rpmtsRootDir(ts), "/"))
return RPMRC_OK;

dbus_error_init(&err);

state->bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
if (dbus_error_is_set(&err))
goto err;

if (state->bus)
rc = dbus_bus_request_name(state->bus, "org.rpm.announce",
DBUS_NAME_FLAG_REPLACE_EXISTING , &err);

if (dbus_error_is_set(&err))
goto err;

if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != rc) {
dbus_announce_close_bus(state);
goto err;
}
return RPMRC_OK;
err:
rpmlog(RPMLOG_WARNING,
"dbus_announce plugin: Error connecting to dbus (%s)\n",
err.message);
dbus_error_free(&err);
return RPMRC_OK;
}

static void dbus_announce_cleanup(rpmPlugin plugin)
{
struct dbus_announce_data * state = rpmPluginGetData(plugin);
dbus_announce_close_bus(state);
free(state);
}

static rpmRC send_ts_message(rpmPlugin plugin,
const char * name,
rpmts ts,
int res)
{
struct dbus_announce_data * state = rpmPluginGetData(plugin);
DBusMessage* msg;
char * dbcookie = NULL;

if (!state->bus)
return RPMRC_OK;

msg = dbus_message_new_signal("/org/rpm/Transaction", /* object name */
"org.rpm.Transaction", /* interface name */
name); /* signal name */
if (msg == NULL)
goto err;

dbcookie = rpmdbCookie(rpmtsGetRdb(ts));
rpm_tid_t tid = rpmtsGetTid(ts);
if (!dbus_message_append_args(msg,
DBUS_TYPE_STRING, &dbcookie,
DBUS_TYPE_UINT32, &tid,
DBUS_TYPE_INVALID))
goto err;

if (!dbus_connection_send(state->bus, msg, NULL))
goto err;

dbus_connection_flush(state->bus);
dbcookie = _free(dbcookie);

return RPMRC_OK;

err:
rpmlog(RPMLOG_WARNING,
"dbus_announce plugin: Error sending message (%s)\n",
name);
pmatilai marked this conversation as resolved.
Show resolved Hide resolved
dbcookie = _free(dbcookie);
return RPMRC_OK;
}

static rpmRC dbus_announce_tsm_pre(rpmPlugin plugin, rpmts ts)
{
int rc;

rc = open_dbus(plugin, ts);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just cosmetics, but you could save a couple of lines by initializing on the declaration line.

if (rc != RPMRC_OK)
return rc;
return send_ts_message(plugin, "StartTransaction", ts, RPMRC_OK);
}

static rpmRC dbus_announce_tsm_post(rpmPlugin plugin, rpmts ts, int res)
{
return send_ts_message(plugin, "EndTransaction", ts, res);
}

struct rpmPluginHooks_s dbus_announce_hooks = {
.init = dbus_announce_init,
.cleanup = dbus_announce_cleanup,
.tsm_pre = dbus_announce_tsm_pre,
.tsm_post = dbus_announce_tsm_post,
};
10 changes: 10 additions & 0 deletions plugins/org.rpm.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE busconfig PUBLIC
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>

<policy user="root">
<allow own="org.rpm.announce"/>
</policy>

</busconfig>