>From 7bc6deb4119f6934e216a68d3801c25428b115b3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Wed, 3 Jun 2015 13:27:02 +0200
Subject: [PATCH 2/2] sbus: listen to NameOwnerChanged

Resolves:
https://fedorahosted.org/sssd/ticket/2326
---
 Makefile.am                         |  1 +
 src/sbus/sssd_dbus_common_signals.c | 91 +++++++++++++++++++++++++++++++++++++
 src/sbus/sssd_dbus_connection.c     |  2 +
 src/sbus/sssd_dbus_private.h        |  2 +
 4 files changed, 96 insertions(+)
 create mode 100644 src/sbus/sssd_dbus_common_signals.c

diff --git a/Makefile.am b/Makefile.am
index 5a2cc884f57bca307d8eb7f635b8e5a8b55891f2..603753439a794e1a9e0a17447bf6b9a61a47330b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -754,6 +754,7 @@ libsss_util_la_SOURCES = \
     src/sbus/sssd_dbus_request.c \
     src/sbus/sssd_dbus_server.c \
     src/sbus/sssd_dbus_signals.c \
+    src/sbus/sssd_dbus_common_signals.c \
     src/util/util.c \
     src/util/memory.c \
     src/util/safe-format-string.c \
diff --git a/src/sbus/sssd_dbus_common_signals.c b/src/sbus/sssd_dbus_common_signals.c
new file mode 100644
index 0000000000000000000000000000000000000000..2950c3554257a48ddafed7c8b3b4461382fb2fd0
--- /dev/null
+++ b/src/sbus/sssd_dbus_common_signals.c
@@ -0,0 +1,91 @@
+/*
+    Authors:
+        Pavel Březina <pbrezina@redhat.com>
+
+    Copyright (C) 2015 Red Hat
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <talloc.h>
+#include <dbus/dbus.h>
+#include <dhash.h>
+
+#include "util/util.h"
+#include "sbus/sssd_dbus.h"
+#include "sbus/sssd_dbus_private.h"
+
+static void
+sbus_signal_name_owner_changed(struct sbus_incoming_signal *signal,
+                               void *handler_data)
+{
+    hash_table_t *table = signal->conn->clients;
+    hash_key_t *keys;
+    unsigned long count;
+    unsigned long i;
+    int hret;
+
+    DEBUG(SSSDBG_TRACE_FUNC, "Clearing UIDs cache\n");
+
+    hret = hash_keys(table, &count, &keys);
+    if (hret != HASH_SUCCESS) {
+        DEBUG(SSSDBG_OP_FAILURE, "Unable to get hash keys\n");
+        return;
+    }
+
+    for (i = 0; i < count; i++) {
+        hret = hash_delete(table, &keys[i]);
+        if (hret != HASH_SUCCESS) {
+            DEBUG(SSSDBG_MINOR_FAILURE, "Could not delete key from hash\n");
+            return;
+        }
+    }
+
+    return;
+}
+
+struct signals_map {
+    const char *iface;
+    const char *signal;
+    sbus_incoming_signal_fn handler_fn;
+    int conn_type;
+};
+
+static struct signals_map signals_map[] = {
+    { "org.freedesktop.DBus", "NameOwnerChanged",
+      sbus_signal_name_owner_changed, SBUS_CONN_TYPE_SYSBUS },
+    { NULL, NULL, NULL, 0 },
+};
+
+void sbus_register_common_signals(struct sbus_connection *conn, void *pvt)
+{
+    errno_t ret;
+    int i;
+
+    for (i = 0; signals_map[i].iface != NULL; i++) {
+        if (signals_map[i].conn_type != conn->connection_type) {
+            /* Skip this signal. */
+            continue;
+        }
+
+        ret = sbus_signal_listen(conn, signals_map[i].iface,
+                                 signals_map[i].signal,
+                                 signals_map[i].handler_fn, conn);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_MINOR_FAILURE, "Unable to register signal %s.%s\n",
+                  signals_map[i].iface, signals_map[i].signal);
+            continue;
+        }
+    }
+}
diff --git a/src/sbus/sssd_dbus_connection.c b/src/sbus/sssd_dbus_connection.c
index 251ff95c55c37660e5350554e0afae88e89bdd9f..6f48e2706fbd43a37af9d79b16507570b5cc2899 100644
--- a/src/sbus/sssd_dbus_connection.c
+++ b/src/sbus/sssd_dbus_connection.c
@@ -206,6 +206,8 @@ int sbus_init_connection(TALLOC_CTX *ctx,
         return EIO;
     }
 
+    sbus_register_common_signals(conn, conn);
+
     *_conn = conn;
     return ret;
 }
diff --git a/src/sbus/sssd_dbus_private.h b/src/sbus/sssd_dbus_private.h
index c125f8b82ddffff9eec9e082161af57cdd350707..44a116e6c17b95d553fd7d12a552027d79196e5b 100644
--- a/src/sbus/sssd_dbus_private.h
+++ b/src/sbus/sssd_dbus_private.h
@@ -181,4 +181,6 @@ errno_t
 sbus_incoming_signal_hash_init(TALLOC_CTX *mem_ctx,
                                hash_table_t **_table);
 
+void sbus_register_common_signals(struct sbus_connection *conn, void *pvt);
+
 #endif /* _SSSD_DBUS_PRIVATE_H_ */
-- 
1.9.3

