Allow backends to set a callback in the be_ctx that should be
invoked when the ID provider goes online.

This can be used to perform regular maintenance tasks that are
valid only when going online.

Specifically, we can use this to perform a deferred kinit on behalf of the user when we go online. We can also use this to trigger a dynamic DNS update for the IPA provider.

--
Stephen Gallagher
RHCE 804006346421761

Delivering value year after year.
Red Hat ranks #1 in value among software vendors.
http://www.redhat.com/promo/vendor/
From f826cd7518a78bd5a922296dbd4d5cee6c58cf5d Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgall...@redhat.com>
Date: Tue, 27 Apr 2010 14:57:37 -0400
Subject: [PATCH] Add callback when the ID provider switches from offline to online

Allow backends to set a callback in the be_ctx that should be
invoked when the ID provider goes online.

This can be used to perform regular maintenance tasks that are
valid only when going online.
---
 src/providers/data_provider_be.c           |   43 ++++++++++++++++++++++++++++
 src/providers/dp_backend.h                 |   21 +++++++++++++
 src/providers/ldap/sdap_async_connection.c |   20 +++++++++++++
 3 files changed, 84 insertions(+), 0 deletions(-)

diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c
index 69aba6cebf03b9922e5d843763eace3117e7d1fb..ba08f577ead07fe61cc545f5541ebd66efe54beb 100644
--- a/src/providers/data_provider_be.c
+++ b/src/providers/data_provider_be.c
@@ -168,6 +168,49 @@ void be_mark_offline(struct be_ctx *ctx)
     ctx->offstat.offline = true;
 }
 
+int be_add_online_cb(struct be_ctx *ctx,
+                     be_conn_online_callback_t cb,
+                     void *pvt)
+{
+    struct be_conn_online_cb *online_cb;
+
+    if (!ctx || !cb) {
+        return EINVAL;
+    }
+
+    online_cb = talloc(ctx, struct be_conn_online_cb);
+    if(!online_cb) {
+        return ENOMEM;
+    }
+
+    online_cb->cb = cb;
+    online_cb->pvt = pvt;
+
+    DLIST_ADD(ctx->online_cb_list, online_cb);
+    return EOK;
+}
+
+int be_remove_online_cb(struct be_ctx *ctx,
+                        be_conn_online_callback_t cb)
+{
+    int ret;
+    struct be_conn_online_cb *callback;
+
+    DLIST_FOR_EACH(callback, ctx->online_cb_list) {
+        if (callback->cb == cb) {
+            DLIST_REMOVE(ctx->online_cb_list, callback);
+            ret = talloc_free(callback);
+            if (ret == -1) {
+                return EIO;
+            }
+            return EOK;
+        }
+    }
+
+    /* Not found */
+    return ENOENT;
+}
+
 static int be_check_online(DBusMessage *message, struct sbus_connection *conn)
 {
     struct be_client *becli;
diff --git a/src/providers/dp_backend.h b/src/providers/dp_backend.h
index f1069d0db313ca278e6125908668e2aad2c25b76..516f609515239c2e79b4e7379fbfcbcb89ddfc34 100644
--- a/src/providers/dp_backend.h
+++ b/src/providers/dp_backend.h
@@ -35,6 +35,8 @@ typedef void (*be_shutdown_fn)(void *);
 typedef void (*be_req_fn_t)(struct be_req *);
 typedef void (*be_async_callback_t)(struct be_req *, int, int, const char *);
 
+typedef int (*be_conn_online_callback_t)(void *);
+
 enum bet_type {
     BET_NULL = 0,
     BET_ID,
@@ -76,6 +78,14 @@ struct be_client {
 
 struct be_failover_ctx;
 
+struct be_conn_online_cb {
+    struct be_conn_online_cb *prev;
+    struct be_conn_online_cb *next;
+
+    be_conn_online_callback_t cb;
+    void *pvt;
+};
+
 struct be_ctx {
     struct tevent_context *ev;
     struct confdb_ctx *cdb;
@@ -85,6 +95,11 @@ struct be_ctx {
     const char *conf_path;
     struct be_failover_ctx *be_fo;
 
+    /* Functions to be invoked when the
+     * backend goes online
+     */
+    struct be_conn_online_cb *online_cb_list;
+
     struct be_offline_status offstat;
 
     struct sbus_connection *mon_conn;
@@ -122,6 +137,12 @@ struct be_acct_req {
 bool be_is_offline(struct be_ctx *ctx);
 void be_mark_offline(struct be_ctx *ctx);
 
+int be_add_online_cb(struct be_ctx *ctx,
+                     be_conn_online_callback_t cb,
+                     void *pvt);
+int be_remove_online_cb(struct be_ctx *ctx,
+                        be_conn_online_callback_t cb);
+
 /* from data_provider_fo.c */
 typedef void (be_svc_callback_fn_t)(void *, struct fo_server *);
 
diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c
index 9871dc2109d2c0eac00f95401ba5dae2d16486ce..af8c659c92ef8f9916c17ac3978dfe902dcd4d0e 100644
--- a/src/providers/ldap/sdap_async_connection.c
+++ b/src/providers/ldap/sdap_async_connection.c
@@ -813,6 +813,7 @@ struct sdap_cli_connect_state {
     struct tevent_context *ev;
     struct sdap_options *opts;
     struct sdap_service *service;
+    struct be_ctx *be;
 
     bool use_rootdse;
     struct sysdb_attrs *rootdse;
@@ -848,6 +849,7 @@ struct tevent_req *sdap_cli_connect_send(TALLOC_CTX *memctx,
     state->opts = opts;
     state->service = service;
     state->srv = NULL;
+    state->be = be;
 
     if (rootdse) {
         state->use_rootdse = true;
@@ -1077,8 +1079,11 @@ static void sdap_cli_auth_done(struct tevent_req *subreq)
 {
     struct tevent_req *req = tevent_req_callback_data(subreq,
                                                       struct tevent_req);
+    struct sdap_cli_connect_state *state = tevent_req_data(req,
+                                             struct sdap_cli_connect_state);
     enum sdap_result result;
     int ret;
+    struct be_conn_online_cb *callback;
 
     ret = sdap_auth_recv(subreq, NULL, &result, NULL);
     talloc_zfree(subreq);
@@ -1091,6 +1096,21 @@ static void sdap_cli_auth_done(struct tevent_req *subreq)
         return;
     }
 
+    /* Reconnection succeeded
+     * Run any post-connection routines
+     */
+    if (state->be->online_cb_list) {
+        DLIST_FOR_EACH(callback, state->be->online_cb_list) {
+            ret = callback->cb(callback->pvt);
+            if (ret != EOK) {
+                DEBUG(0, ("Post-connection callback returned [%d][%s]",
+                          ret, strerror(ret)));
+                tevent_req_error(req, ret);
+                break;
+            }
+        }
+    }
+
     tevent_req_done(req);
 }
 
-- 
1.7.0.1

_______________________________________________
sssd-devel mailing list
sssd-devel@lists.fedorahosted.org
https://fedorahosted.org/mailman/listinfo/sssd-devel

Reply via email to