[SSSD] [PATCH] Add offline callback and fix info file handling

Sumit Bose sbose at redhat.com
Fri May 14 19:11:17 UTC 2010


On Fri, May 14, 2010 at 08:58:39PM +0200, Sumit Bose wrote:
> On Fri, May 14, 2010 at 11:55:01AM -0400, Stephen Gallagher wrote:
> > On 05/14/2010 08:29 AM, Sumit Bose wrote:
> > > Hi,
> > >
> > > this series of patches aims to fix the handling of the info file for the
> > > locator plugin to allow a graceful fallback to the configuration from
> > > krb5.conf is the sssd backend is offline.
> > >
> > > 0001-Revert-Create-kdcinfo-and-kpasswdinfo-file-at-startu.patch:
> > >       Remove the old commit
> > >
> > 
> > Ack.
> > 
> > > 0002-Refactor-data-provider-callbacks.patch
> > >       Remove references to 'online' from the main callback code, move
> > >       callback code to a separate file to make life easier for potential
> > >       unit test.
> > >
> > 
> > Ack.
> > 
> > > 0003-Add-offline-callbacks.patch
> > >
> > 
> > Nack. Please condense be_run_offline_cb() and be_run_online_cb() into a 
> > single function. They are nearly identical already.

There was an error in the new function. Ne versions attached.

bye.
Sumit

> 
> ok, I've put the common code into a new function. Most of the changes
> are in 0002.
> 
> > 
> > > 0004-Refactor-krb5_finalize.patch
> > >       Create a new subroutine which only unlinks the files.
> > >
> > 
> > Ack.
> > 
> > > 0005-Add-callback-to-remove-krb5-info-files-when-going-of.patch
> > >
> > 
> > Nack.
> > Nitpick: you added an extra "ret = EOK" into ipa_service_init()
> 
> done
> 
> New versions attached.
> 
> bye,
> Sumit
> 
> > 
> > > 0006-Krb5-locator-plugin-returns-KRB5_PLUGIN_NO_HANDLE.patch
> > >       KRB5_PLUGIN_NO_HANDLE is the error code which instructs libkrb5 to
> > >       try the next plugin of use krb5.conf.
> > >
> > 
> > Ack.
> > 
> > _______________________________________________
> > sssd-devel mailing list
> > sssd-devel at lists.fedorahosted.org
> > https://fedorahosted.org/mailman/listinfo/sssd-devel

> From 2ffbdfc586fa1871d0e7929e2a7e28466e840097 Mon Sep 17 00:00:00 2001
> From: Sumit Bose <sbose at redhat.com>
> Date: Fri, 14 May 2010 11:39:35 +0200
> Subject: [PATCH 1/6] Revert "Create kdcinfo and kpasswdinfo file at startup"
> 
> This reverts commit 4f5664a2ec401f43c090e6170ed9c78390c35272.
> ---
>  src/providers/ipa/ipa_common.c   |    9 --------
>  src/providers/krb5/krb5_common.c |   41 +-------------------------------------
>  src/providers/krb5/krb5_common.h |    1 -
>  3 files changed, 1 insertions(+), 50 deletions(-)
> 
> diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c
> index 4b7dfba..304df8e 100644
> --- a/src/providers/ipa/ipa_common.c
> +++ b/src/providers/ipa/ipa_common.c
> @@ -487,7 +487,6 @@ int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
>      char *realm;
>      int ret;
>      int i;
> -    struct tevent_req *req;
>  
>      tmp_ctx = talloc_new(memctx);
>      if (!tmp_ctx) {
> @@ -582,14 +581,6 @@ int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
>          goto done;
>      }
>  
> -    req = be_resolve_server_send(memctx, ctx->ev, ctx, "IPA");
> -    if (req == NULL) {
> -        DEBUG(1, ("be_resolve_server_send failed.\n"));
> -        ret = ENOMEM;
> -        goto done;
> -    }
> -    tevent_req_set_callback(req, krb5_init_resolve_done, service->krb5_service);
> -
>      ret = EOK;
>  
>  done:
> diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c
> index da7627c..f038557 100644
> --- a/src/providers/krb5/krb5_common.c
> +++ b/src/providers/krb5/krb5_common.c
> @@ -31,8 +31,6 @@
>  #include "providers/dp_backend.h"
>  #include "providers/krb5/krb5_common.h"
>  
> -#define DUMMY_ADDRESS "255.255.255.255"
> -
>  struct dp_option default_krb5_opts[] = {
>      { "krb5_kdcip", DP_OPT_STRING, NULL_STRING, NULL_STRING },
>      { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING },
> @@ -290,6 +288,7 @@ static void krb5_resolve_callback(void *private_data, struct fo_server *server)
>      return;
>  }
>  
> +
>  int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
>                        const char *service_name, const char *servers,
>                        const char *realm, struct krb5_service **_service)
> @@ -304,7 +303,6 @@ int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
>      char *server_spec;
>      char *endptr;
>      struct servent *servent;
> -    struct tevent_req *req;
>  
>      tmp_ctx = talloc_new(memctx);
>      if (!tmp_ctx) {
> @@ -427,14 +425,6 @@ int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
>          goto done;
>      }
>  
> -    req = be_resolve_server_send(memctx, ctx->ev, ctx, service_name);
> -    if (req == NULL) {
> -        DEBUG(1, ("be_resolve_server_send failed.\n"));
> -        ret = ENOMEM;
> -        goto done;
> -    }
> -    tevent_req_set_callback(req, krb5_init_resolve_done, service);
> -
>      ret = EOK;
>  
>  done:
> @@ -485,32 +475,3 @@ void krb5_finalize(struct tevent_context *ev,
>  
>      sig_term(signum);
>  }
> -
> -void krb5_init_resolve_done(struct tevent_req *req)
> -{
> -    struct krb5_service *krb5_service  = tevent_req_callback_data(req,
> -                                                           struct krb5_service);
> -    int ret;
> -    struct fo_server *srv;
> -    const char *service_name;
> -
> -    ret = be_resolve_server_recv(req, &srv);
> -    talloc_zfree(req);
> -    if (ret) {
> -        DEBUG(1, ("be_resolve_server request failed [%d][%s]. "
> -                  "Creating dummy info file.\n", ret, strerror(ret)));
> -
> -        service_name = krb5_service->name;
> -        if (strcmp(service_name, "IPA") == 0) {
> -            service_name = SSS_KRB5KDC_FO_SRV;
> -        }
> -        ret = write_krb5info_file(krb5_service->realm, DUMMY_ADDRESS,
> -                                  service_name);
> -        if (ret != EOK) {
> -            DEBUG(2, ("write_krb5info_file failed, "
> -                      "authentication might fail.\n"));
> -        }
> -    }
> -
> -    return;
> -}
> diff --git a/src/providers/krb5/krb5_common.h b/src/providers/krb5/krb5_common.h
> index dd7fdf2..87d6168 100644
> --- a/src/providers/krb5/krb5_common.h
> +++ b/src/providers/krb5/krb5_common.h
> @@ -83,5 +83,4 @@ void krb5_finalize(struct tevent_context *ev,
>                     int count,
>                     void *siginfo,
>                     void *private_data);
> -void krb5_init_resolve_done(struct tevent_req *req);
>  #endif /* __KRB5_COMMON_H__ */
> -- 
> 1.6.6.1
> 

> From d790fe98bca04b192934da29bc7ca5fa3b965fee Mon Sep 17 00:00:00 2001
> From: Sumit Bose <sbose at redhat.com>
> Date: Fri, 14 May 2010 10:18:33 +0200
> Subject: [PATCH 2/6] Refactor data provider callbacks
> 
> ---
>  src/Makefile.am                         |    1 +
>  src/providers/data_provider_be.c        |  137 -----------------------
>  src/providers/data_provider_callbacks.c |  182 +++++++++++++++++++++++++++++++
>  src/providers/dp_backend.h              |   10 +-
>  4 files changed, 188 insertions(+), 142 deletions(-)
>  create mode 100644 src/providers/data_provider_callbacks.c
> 
> diff --git a/src/Makefile.am b/src/Makefile.am
> index 5c428e7..e403a77 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -393,6 +393,7 @@ sssd_be_SOURCES = \
>      providers/data_provider_be.c \
>      providers/data_provider_fo.c \
>      providers/data_provider_opts.c \
> +    providers/data_provider_callbacks.c \
>      $(SSSD_FAILOVER_OBJ) \
>      $(SSSD_UTIL_OBJ)
>  sssd_be_LDADD = $(SSSD_LIBS) $(CARES_LIBS)
> diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c
> index 9ef436e..9a7f8cf 100644
> --- a/src/providers/data_provider_be.c
> +++ b/src/providers/data_provider_be.c
> @@ -169,143 +169,6 @@ void be_mark_offline(struct be_ctx *ctx)
>      ctx->run_online_cb = true;
>  }
>  
> -
> -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 *be;
> -};
> -
> -static int online_cb_destructor(TALLOC_CTX *ptr);
> -int be_add_online_cb(TALLOC_CTX *mem_ctx,
> -                     struct be_ctx *ctx,
> -                     be_conn_online_callback_t cb,
> -                     void *pvt,
> -                     struct be_conn_online_cb **online_cb)
> -{
> -    struct be_conn_online_cb *on_cb;
> -
> -    if (!ctx || !cb) {
> -        return EINVAL;
> -    }
> -
> -    on_cb = talloc(mem_ctx, struct be_conn_online_cb);
> -    if (!on_cb) {
> -        return ENOMEM;
> -    }
> -
> -    on_cb->cb = cb;
> -    on_cb->pvt = pvt;
> -    on_cb->be = ctx;
> -
> -    DLIST_ADD(ctx->online_cb_list, on_cb);
> -
> -    talloc_set_destructor((TALLOC_CTX *)on_cb, online_cb_destructor);
> -
> -    /* Make sure we run the callback for the first
> -     * connection after startup.
> -     */
> -    ctx->run_online_cb = true;
> -
> -    if (online_cb) {
> -        *online_cb = on_cb;
> -    }
> -
> -    return EOK;
> -}
> -
> -static int online_cb_destructor(TALLOC_CTX *ptr)
> -{
> -    struct be_conn_online_cb *cb =
> -            talloc_get_type(ptr, struct be_conn_online_cb);
> -    DLIST_REMOVE(cb->be->online_cb_list, cb);
> -    return 0;
> -}
> -
> -
> -struct be_online_cb_ctx {
> -    struct be_ctx *be;
> -    struct be_conn_online_cb *callback;
> -};
> -
> -static void be_run_online_cb_step(struct tevent_context *ev,
> -                                  struct tevent_timer *te,
> -                                  struct timeval current_time,
> -                                  void *pvt);
> -void be_run_online_cb(struct be_ctx *be) {
> -    struct timeval soon;
> -    struct tevent_timer *te;
> -    struct be_online_cb_ctx *cb_ctx;
> -
> -    if (be->run_online_cb && be->online_cb_list) {
> -        /* Reset the flag. We only want to run these
> -         * callbacks when transitioning to online
> -         */
> -        be->run_online_cb = false;
> -
> -        DEBUG(3, ("Going online. Running callbacks.\n"));
> -
> -        cb_ctx = talloc(be, struct be_online_cb_ctx);
> -        if (!cb_ctx) {
> -            DEBUG(0, ("Out of memory. Could not invoke callbacks\n"));
> -            return;
> -        }
> -        cb_ctx->be = be;
> -        cb_ctx->callback = be->online_cb_list;
> -
> -        /* Delay 30ms so we don't block any other events */
> -        soon = tevent_timeval_current_ofs(0, 30000);
> -        te = tevent_add_timer(be->ev, cb_ctx, soon,
> -                              be_run_online_cb_step,
> -                              cb_ctx);
> -        if (!te) {
> -            DEBUG(0, ("Out of memory. Could not invoke callbacks\n"));
> -            talloc_free(cb_ctx);
> -        }
> -    }
> -}
> -
> -static void be_run_online_cb_step(struct tevent_context *ev,
> -                                  struct tevent_timer *te,
> -                                  struct timeval current_time,
> -                                  void *pvt)
> -{
> -    struct be_online_cb_ctx *cb_ctx =
> -            talloc_get_type(pvt, struct be_online_cb_ctx);
> -    struct tevent_timer *tev;
> -    struct timeval soon;
> -
> -    /* Call the callback */
> -    cb_ctx->callback->cb(cb_ctx->callback->pvt);
> -
> -    if (cb_ctx->callback->next) {
> -        cb_ctx->callback = cb_ctx->callback->next;
> -
> -        /* Delay 30ms so we don't block any other events */
> -        soon = tevent_timeval_current_ofs(0, 30000);
> -        tev = tevent_add_timer(cb_ctx->be->ev, cb_ctx, soon,
> -                               be_run_online_cb_step,
> -                               cb_ctx);
> -        if (!te) {
> -            DEBUG(0, ("Out of memory. Could not invoke callbacks\n"));
> -            goto final;
> -        }
> -        return;
> -    }
> -
> -final:
> -    /* Steal the timer event onto the be_ctx so it doesn't
> -     * get freed with the cb_ctx
> -     */
> -    talloc_steal(cb_ctx->be, te);
> -    talloc_free(cb_ctx);
> -}
> -
> -
>  static int be_check_online(DBusMessage *message, struct sbus_connection *conn)
>  {
>      struct be_client *becli;
> diff --git a/src/providers/data_provider_callbacks.c b/src/providers/data_provider_callbacks.c
> new file mode 100644
> index 0000000..35db2b2
> --- /dev/null
> +++ b/src/providers/data_provider_callbacks.c
> @@ -0,0 +1,182 @@
> +/*
> +    SSSD
> +
> +    Data Provider Process - Callback
> +
> +    Authors:
> +
> +        Stephen Gallagher <sgallagh at redhat.com>
> +        Sumit Bose <sbose at redhat.com>
> +
> +    Copyright (C) 2010 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 "util/util.h"
> +#include "providers/dp_backend.h"
> +
> +struct be_cb {
> +    struct be_cb *prev;
> +    struct be_cb *next;
> +
> +    be_callback_t cb;
> +    void *pvt;
> +
> +    struct be_cb *list;
> +    struct be_ctx *be;
> +};
> +
> +struct be_cb_ctx {
> +    struct be_ctx *be;
> +    struct be_cb *callback;
> +};
> +
> +static int cb_destructor(TALLOC_CTX *ptr)
> +{
> +    struct be_cb *cb = talloc_get_type(ptr, struct be_cb);
> +    DLIST_REMOVE(cb->list, cb);
> +    return 0;
> +}
> +
> +static int be_add_cb(TALLOC_CTX *mem_ctx, struct be_ctx *ctx,
> +                     be_callback_t cb, void *pvt, struct be_cb **cb_list,
> +                     struct be_cb **return_cb)
> +{
> +    struct be_cb *new_cb;
> +
> +    if (!ctx || !cb) {
> +        return EINVAL;
> +    }
> +
> +    new_cb = talloc(mem_ctx, struct be_cb);
> +    if (!new_cb) {
> +        return ENOMEM;
> +    }
> +
> +    new_cb->cb = cb;
> +    new_cb->pvt = pvt;
> +    new_cb->list = *cb_list;
> +    new_cb->be = ctx;
> +
> +    DLIST_ADD(*cb_list, new_cb);
> +
> +    talloc_set_destructor((TALLOC_CTX *) new_cb, cb_destructor);
> +
> +    if (return_cb) {
> +        *return_cb = new_cb;
> +    }
> +
> +    return EOK;
> +}
> +
> +static void be_run_cb_step(struct tevent_context *ev, struct tevent_timer *te,
> +                           struct timeval current_time, void *pvt)
> +{
> +    struct be_cb_ctx *cb_ctx = talloc_get_type(pvt, struct be_cb_ctx);
> +    struct tevent_timer *tev;
> +    struct timeval soon;
> +
> +    /* Call the callback */
> +    cb_ctx->callback->cb(cb_ctx->callback->pvt);
> +
> +    if (cb_ctx->callback->next) {
> +        cb_ctx->callback = cb_ctx->callback->next;
> +
> +        /* Delay 30ms so we don't block any other events */
> +        soon = tevent_timeval_current_ofs(0, 30000);
> +        tev = tevent_add_timer(cb_ctx->be->ev, cb_ctx, soon,
> +                               be_run_cb_step,
> +                               cb_ctx);
> +        if (!te) {
> +            DEBUG(0, ("Out of memory. Could not invoke callbacks\n"));
> +            goto final;
> +        }
> +        return;
> +    }
> +
> +final:
> +    /* Steal the timer event onto the be_ctx so it doesn't
> +     * get freed with the cb_ctx
> +     */
> +    talloc_steal(cb_ctx->be, te);
> +    talloc_free(cb_ctx);
> +}
> +
> +static errno_t be_run_cb(struct be_ctx *be) {
> +    struct timeval soon;
> +    struct tevent_timer *te;
> +    struct be_cb_ctx *cb_ctx;
> +
> +    cb_ctx = talloc(be, struct be_cb_ctx);
> +    if (!cb_ctx) {
> +        DEBUG(0, ("Out of memory. Could not invoke callbacks\n"));
> +        return ENOMEM;
> +    }
> +    cb_ctx->be = be;
> +    cb_ctx->callback = be->offline_cb_list;
> +
> +    /* Delay 30ms so we don't block any other events */
> +    soon = tevent_timeval_current_ofs(0, 30000);
> +    te = tevent_add_timer(be->ev, cb_ctx, soon,
> +                          be_run_cb_step,
> +                          cb_ctx);
> +    if (!te) {
> +        DEBUG(0, ("Out of memory. Could not invoke callbacks\n"));
> +        talloc_free(cb_ctx);
> +        return ENOMEM;
> +    }
> +
> +    return EOK;
> +}
> +
> +int be_add_online_cb(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, be_callback_t cb,
> +                     void *pvt, struct be_cb **online_cb)
> +{
> +    int ret;
> +
> +    ret = be_add_cb(mem_ctx, ctx, cb, pvt, &ctx->online_cb_list, online_cb);
> +    if (ret != EOK) {
> +        DEBUG(1, ("be_add_cb failed.\n"));
> +        return ret;
> +    }
> +
> +    /* Make sure we run the callback for the first
> +     * connection after startup.
> +     */
> +    ctx->run_online_cb = true;
> +
> +    return EOK;
> +}
> +
> +void be_run_online_cb(struct be_ctx *be) {
> +    int ret;
> +
> +    if (be->run_online_cb && be->online_cb_list) {
> +        /* Reset the flag. We only want to run these
> +         * callbacks when transitioning to online
> +         */
> +        be->run_online_cb = false;
> +
> +        DEBUG(3, ("Going online. Running callbacks.\n"));
> +
> +        ret = be_run_cb(be);
> +        if (ret != EOK) {
> +            DEBUG(1, ("be_run_cb failed.\n"));
> +        }
> +
> +    } else {
> +        DEBUG(9, ("Online call back list is empty, nothing to do.\n"));
> +    }
> +}
> diff --git a/src/providers/dp_backend.h b/src/providers/dp_backend.h
> index ec0510e..43d79ba 100644
> --- a/src/providers/dp_backend.h
> +++ b/src/providers/dp_backend.h
> @@ -40,7 +40,7 @@ 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 void (*be_conn_online_callback_t)(void *);
> +typedef void (*be_callback_t)(void *);
>  
>  enum bet_type {
>      BET_NULL = 0,
> @@ -83,7 +83,7 @@ struct be_client {
>  
>  struct be_failover_ctx;
>  
> -struct be_conn_online_cb;
> +struct be_cb;
>  
>  struct be_ctx {
>      struct tevent_context *ev;
> @@ -97,7 +97,7 @@ struct be_ctx {
>      /* Functions to be invoked when the
>       * backend goes online
>       */
> -    struct be_conn_online_cb *online_cb_list;
> +    struct be_cb *online_cb_list;
>      bool run_online_cb;
>  
>      struct be_offline_status offstat;
> @@ -143,9 +143,9 @@ void be_mark_offline(struct be_ctx *ctx);
>  
>  int be_add_online_cb(TALLOC_CTX *mem_ctx,
>                       struct be_ctx *ctx,
> -                     be_conn_online_callback_t cb,
> +                     be_callback_t cb,
>                       void *pvt,
> -                     struct be_conn_online_cb **online_cb);
> +                     struct be_cb **online_cb);
>  void be_run_online_cb(struct be_ctx *be);
>  
>  /* from data_provider_fo.c */
> -- 
> 1.6.6.1
> 

> From 46c9d5f8fc466039e8bb0f1db7a25e076bb7c718 Mon Sep 17 00:00:00 2001
> From: Sumit Bose <sbose at redhat.com>
> Date: Fri, 14 May 2010 10:57:19 +0200
> Subject: [PATCH 3/6] Add offline callbacks
> 
> ---
>  src/providers/data_provider_be.c        |    1 +
>  src/providers/data_provider_callbacks.c |   22 ++++++++++++++++++++++
>  src/providers/dp_backend.h              |   10 +++++++++-
>  3 files changed, 32 insertions(+), 1 deletions(-)
> 
> diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c
> index 9a7f8cf..4ece1b6 100644
> --- a/src/providers/data_provider_be.c
> +++ b/src/providers/data_provider_be.c
> @@ -167,6 +167,7 @@ void be_mark_offline(struct be_ctx *ctx)
>      ctx->offstat.went_offline = time(NULL);
>      ctx->offstat.offline = true;
>      ctx->run_online_cb = true;
> +    be_run_offline_cb(ctx);
>  }
>  
>  static int be_check_online(DBusMessage *message, struct sbus_connection *conn)
> diff --git a/src/providers/data_provider_callbacks.c b/src/providers/data_provider_callbacks.c
> index 35db2b2..ab8ddcb 100644
> --- a/src/providers/data_provider_callbacks.c
> +++ b/src/providers/data_provider_callbacks.c
> @@ -180,3 +180,25 @@ void be_run_online_cb(struct be_ctx *be) {
>          DEBUG(9, ("Online call back list is empty, nothing to do.\n"));
>      }
>  }
> +
> +int be_add_offline_cb(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, be_callback_t cb,
> +                      void *pvt, struct be_cb **offline_cb)
> +{
> +    return be_add_cb(mem_ctx, ctx, cb, pvt, &ctx->offline_cb_list, offline_cb);
> +}
> +
> +void be_run_offline_cb(struct be_ctx *be) {
> +    int ret;
> +
> +    if (be->offline_cb_list) {
> +        DEBUG(3, ("Going offline. Running callbacks.\n"));
> +
> +        ret = be_run_cb(be);
> +        if (ret != EOK) {
> +            DEBUG(1, ("be_run_cb failed.\n"));
> +        }
> +
> +    } else {
> +        DEBUG(9, ("Offline call back list is empty, nothing to do.\n"));
> +    }
> +}
> diff --git a/src/providers/dp_backend.h b/src/providers/dp_backend.h
> index 43d79ba..fc5e558 100644
> --- a/src/providers/dp_backend.h
> +++ b/src/providers/dp_backend.h
> @@ -95,10 +95,11 @@ struct be_ctx {
>      struct be_failover_ctx *be_fo;
>  
>      /* Functions to be invoked when the
> -     * backend goes online
> +     * backend goes online or offline
>       */
>      struct be_cb *online_cb_list;
>      bool run_online_cb;
> +    struct be_cb *offline_cb_list;
>  
>      struct be_offline_status offstat;
>  
> @@ -148,6 +149,13 @@ int be_add_online_cb(TALLOC_CTX *mem_ctx,
>                       struct be_cb **online_cb);
>  void be_run_online_cb(struct be_ctx *be);
>  
> +int be_add_offline_cb(TALLOC_CTX *mem_ctx,
> +                     struct be_ctx *ctx,
> +                     be_callback_t cb,
> +                     void *pvt,
> +                     struct be_cb **online_cb);
> +void be_run_offline_cb(struct be_ctx *be);
> +
>  /* from data_provider_fo.c */
>  typedef void (be_svc_callback_fn_t)(void *, struct fo_server *);
>  
> -- 
> 1.6.6.1
> 

> From 652825e6400a283fa50b651eb1602551db555e3a Mon Sep 17 00:00:00 2001
> From: Sumit Bose <sbose at redhat.com>
> Date: Fri, 14 May 2010 11:35:11 +0200
> Subject: [PATCH 4/6] Refactor krb5_finalize()
> 
> ---
>  src/providers/krb5/krb5_common.c |   39 ++++++++++++++++++++++++++-----------
>  1 files changed, 27 insertions(+), 12 deletions(-)
> 
> diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c
> index f038557..dfcb502 100644
> --- a/src/providers/krb5/krb5_common.c
> +++ b/src/providers/krb5/krb5_common.c
> @@ -435,22 +435,19 @@ done:
>      return ret;
>  }
>  
> -void krb5_finalize(struct tevent_context *ev,
> -                   struct tevent_signal *se,
> -                   int signum,
> -                   int count,
> -                   void *siginfo,
> -                   void *private_data)
> +
> +static errno_t remove_krb5_info_files(TALLOC_CTX *mem_ctx, const char *realm)
>  {
> -    char *realm = (char *)private_data;
>      int ret;
>      errno_t err;
>      char *file;
>  
> -    file = talloc_asprintf(se, KDCINFO_TMPL, realm);
> +    file = talloc_asprintf(mem_ctx, KDCINFO_TMPL, realm);
>      if(file == NULL) {
> -        sig_term(signum);
> +        DEBUG(1, ("talloc_asprintf failed.\n"));
> +        return ENOMEM;
>      }
> +
>      errno = 0;
>      ret = unlink(file);
>      if (ret == -1) {
> @@ -459,10 +456,10 @@ void krb5_finalize(struct tevent_context *ev,
>                    err, strerror(err)));
>      }
>  
> -    errno = 0;
> -    file = talloc_asprintf(se, KPASSWDINFO_TMPL, realm);
> +    file = talloc_asprintf(mem_ctx, KPASSWDINFO_TMPL, realm);
>      if(file == NULL) {
> -        sig_term(signum);
> +        DEBUG(1, ("talloc_asprintf failed.\n"));
> +        return ENOMEM;
>      }
>  
>      errno = 0;
> @@ -473,5 +470,23 @@ void krb5_finalize(struct tevent_context *ev,
>                    err, strerror(err)));
>      }
>  
> +    return EOK;
> +}
> +
> +void krb5_finalize(struct tevent_context *ev,
> +                   struct tevent_signal *se,
> +                   int signum,
> +                   int count,
> +                   void *siginfo,
> +                   void *private_data)
> +{
> +    char *realm = (char *)private_data;
> +    int ret;
> +
> +    ret = remove_krb5_info_files(se, realm);
> +    if (ret != EOK) {
> +        DEBUG(1, ("remove_krb5_info_files failed.\n"));
> +    }
> +
>      sig_term(signum);
>  }
> -- 
> 1.6.6.1
> 

> From 0f6b66c7d1ade38912aa17522effa465af69bbea Mon Sep 17 00:00:00 2001
> From: Sumit Bose <sbose at redhat.com>
> Date: Fri, 14 May 2010 12:04:36 +0200
> Subject: [PATCH 5/6] Add callback to remove krb5 info files when going offline
> 
> ---
>  src/Makefile.am                  |    1 +
>  src/providers/ipa/ipa_common.c   |    8 ++++++++
>  src/providers/krb5/krb5_common.c |   29 +++++++++++++++++++++++++++++
>  src/providers/krb5/krb5_common.h |    2 ++
>  4 files changed, 40 insertions(+), 0 deletions(-)
> 
> diff --git a/src/Makefile.am b/src/Makefile.am
> index e403a77..afe74c8 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -509,6 +509,7 @@ krb5_utils_tests_SOURCES = \
>      providers/krb5/krb5_common.c \
>      providers/data_provider_fo.c \
>      providers/data_provider_opts.c \
> +    providers/data_provider_callbacks.c \
>      $(SSSD_FAILOVER_OBJ) \
>      $(SSSD_UTIL_OBJ)
>  krb5_utils_tests_CFLAGS = \
> diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c
> index 304df8e..6738e3e 100644
> --- a/src/providers/ipa/ipa_common.c
> +++ b/src/providers/ipa/ipa_common.c
> @@ -581,6 +581,14 @@ int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
>          goto done;
>      }
>  
> +    ret = be_add_offline_cb(memctx, ctx, remove_krb5_info_files_callback,
> +                            service->krb5_service, NULL);
> +    if (ret != EOK) {
> +        /* Not a fatal error. */
> +        DEBUG(1, ("Failed to add offline callback, "
> +                  "krb5 info file will not be removed when going offline.\n"));
> +    }
> +
>      ret = EOK;
>  
>  done:
> diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c
> index dfcb502..4afa3dc 100644
> --- a/src/providers/krb5/krb5_common.c
> +++ b/src/providers/krb5/krb5_common.c
> @@ -425,6 +425,14 @@ int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
>          goto done;
>      }
>  
> +    ret = be_add_offline_cb(memctx, ctx, remove_krb5_info_files_callback,
> +                            service, NULL);
> +    if (ret != EOK) {
> +        /* Not a fatal error. */
> +        DEBUG(1, ("Failed to add offline callback, "
> +                  "krb5 info file will not be removed when going offline.\n"));
> +    }
> +
>      ret = EOK;
>  
>  done:
> @@ -473,6 +481,27 @@ static errno_t remove_krb5_info_files(TALLOC_CTX *mem_ctx, const char *realm)
>      return EOK;
>  }
>  
> +void remove_krb5_info_files_callback(void *pvt)
> +{
> +    int ret;
> +    TALLOC_CTX *tmp_ctx = NULL;
> +    struct krb5_service *krb5_service = talloc_get_type(pvt,
> +                                                        struct krb5_service);
> +
> +    tmp_ctx = talloc_new(NULL);
> +    if (tmp_ctx == NULL) {
> +        DEBUG(1, ("talloc_new failed, cannot remove krb5 info files.\n"));
> +        return;
> +    }
> +
> +    ret = remove_krb5_info_files(tmp_ctx, krb5_service->realm);
> +    if (ret != EOK) {
> +        DEBUG(1, ("remove_krb5_info_files failed.\n"));
> +    }
> +
> +    talloc_zfree(tmp_ctx);
> +}
> +
>  void krb5_finalize(struct tevent_context *ev,
>                     struct tevent_signal *se,
>                     int signum,
> diff --git a/src/providers/krb5/krb5_common.h b/src/providers/krb5/krb5_common.h
> index 87d6168..fbbd41d 100644
> --- a/src/providers/krb5/krb5_common.h
> +++ b/src/providers/krb5/krb5_common.h
> @@ -77,6 +77,8 @@ int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
>                        const char *service_name, const char *servers,
>                        const char *realm, struct krb5_service **_service);
>  
> +void remove_krb5_info_files_callback(void *pvt);
> +
>  void krb5_finalize(struct tevent_context *ev,
>                     struct tevent_signal *se,
>                     int signum,
> -- 
> 1.6.6.1
> 

> From 1e6192189a2d8edab3eacb506ad51a7813fd24ff Mon Sep 17 00:00:00 2001
> From: Sumit Bose <sbose at redhat.com>
> Date: Fri, 14 May 2010 12:16:59 +0200
> Subject: [PATCH 6/6] Krb5 locator plugin returns KRB5_PLUGIN_NO_HANDLE
> 
> To allow a fallback to the setting in krb5.conf the locator plugin
> returns KRB5_PLUGIN_NO_HANDLE in nearly all error conditions. Only if the
> call back fails the error code of the callback is returned.
> ---
>  src/krb5_plugin/sssd_krb5_locator_plugin.c |   12 ++++++------
>  1 files changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/src/krb5_plugin/sssd_krb5_locator_plugin.c b/src/krb5_plugin/sssd_krb5_locator_plugin.c
> index 153145b..dfc9c19 100644
> --- a/src/krb5_plugin/sssd_krb5_locator_plugin.c
> +++ b/src/krb5_plugin/sssd_krb5_locator_plugin.c
> @@ -223,7 +223,7 @@ krb5_error_code sssd_krb5_locator_init(krb5_context context,
>      const char *dummy;
>  
>      ctx = calloc(1,sizeof(struct sssd_ctx));
> -    if (ctx == NULL) return ENOMEM;
> +    if (ctx == NULL) return KRB5_PLUGIN_NO_HANDLE;
>  
>      dummy = getenv(SSSD_KRB5_LOCATOR_DEBUG);
>      if (dummy == NULL) {
> @@ -280,7 +280,7 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
>          ctx->sssd_realm = strdup(realm);
>          if (ctx->sssd_realm == NULL) {
>              PLUGIN_DEBUG(("strdup failed.\n"));
> -            return ENOMEM;
> +            return KRB5_PLUGIN_NO_HANDLE;
>          }
>  
>          ret = get_krb5info(realm, ctx, locate_service_kdc);
> @@ -326,7 +326,7 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
>          case locate_service_krb524:
>              return KRB5_PLUGIN_NO_HANDLE;
>          default:
> -            return EINVAL;
> +            return KRB5_PLUGIN_NO_HANDLE;
>      }
>  
>      switch (family) {
> @@ -343,7 +343,7 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
>          case SOCK_DGRAM:
>              break;
>          default:
> -            return EINVAL;
> +            return KRB5_PLUGIN_NO_HANDLE;
>      }
>  
>      if (strcmp(realm, ctx->sssd_realm) != 0)
> @@ -353,7 +353,7 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
>      ret = snprintf(port_str, PORT_STR_SIZE-1, "%u", port);
>      if (ret < 0 || ret >= (PORT_STR_SIZE-1)) {
>          PLUGIN_DEBUG(("snprintf failed.\n"));
> -        return EFAULT;
> +        return KRB5_PLUGIN_NO_HANDLE;
>      }
>  
>      memset(&ai_hints, 0, sizeof(struct addrinfo));
> @@ -368,7 +368,7 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
>              PLUGIN_DEBUG(("getaddrinfo failed [%d][%s].\n", errno,
>                                                              strerror(errno)));
>          }
> -        return EFAULT;
> +        return KRB5_PLUGIN_NO_HANDLE;
>      }
>  
>      PLUGIN_DEBUG(("addr[%s:%s] family[%d] socktype[%d]\n", addr, port_str,
> -- 
> 1.6.6.1
> 

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

-------------- next part --------------
From 2ffbdfc586fa1871d0e7929e2a7e28466e840097 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Fri, 14 May 2010 11:39:35 +0200
Subject: [PATCH 1/6] Revert "Create kdcinfo and kpasswdinfo file at startup"

This reverts commit 4f5664a2ec401f43c090e6170ed9c78390c35272.
---
 src/providers/ipa/ipa_common.c   |    9 --------
 src/providers/krb5/krb5_common.c |   41 +-------------------------------------
 src/providers/krb5/krb5_common.h |    1 -
 3 files changed, 1 insertions(+), 50 deletions(-)

diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c
index 4b7dfba..304df8e 100644
--- a/src/providers/ipa/ipa_common.c
+++ b/src/providers/ipa/ipa_common.c
@@ -487,7 +487,6 @@ int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
     char *realm;
     int ret;
     int i;
-    struct tevent_req *req;
 
     tmp_ctx = talloc_new(memctx);
     if (!tmp_ctx) {
@@ -582,14 +581,6 @@ int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
         goto done;
     }
 
-    req = be_resolve_server_send(memctx, ctx->ev, ctx, "IPA");
-    if (req == NULL) {
-        DEBUG(1, ("be_resolve_server_send failed.\n"));
-        ret = ENOMEM;
-        goto done;
-    }
-    tevent_req_set_callback(req, krb5_init_resolve_done, service->krb5_service);
-
     ret = EOK;
 
 done:
diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c
index da7627c..f038557 100644
--- a/src/providers/krb5/krb5_common.c
+++ b/src/providers/krb5/krb5_common.c
@@ -31,8 +31,6 @@
 #include "providers/dp_backend.h"
 #include "providers/krb5/krb5_common.h"
 
-#define DUMMY_ADDRESS "255.255.255.255"
-
 struct dp_option default_krb5_opts[] = {
     { "krb5_kdcip", DP_OPT_STRING, NULL_STRING, NULL_STRING },
     { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING },
@@ -290,6 +288,7 @@ static void krb5_resolve_callback(void *private_data, struct fo_server *server)
     return;
 }
 
+
 int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
                       const char *service_name, const char *servers,
                       const char *realm, struct krb5_service **_service)
@@ -304,7 +303,6 @@ int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
     char *server_spec;
     char *endptr;
     struct servent *servent;
-    struct tevent_req *req;
 
     tmp_ctx = talloc_new(memctx);
     if (!tmp_ctx) {
@@ -427,14 +425,6 @@ int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
         goto done;
     }
 
-    req = be_resolve_server_send(memctx, ctx->ev, ctx, service_name);
-    if (req == NULL) {
-        DEBUG(1, ("be_resolve_server_send failed.\n"));
-        ret = ENOMEM;
-        goto done;
-    }
-    tevent_req_set_callback(req, krb5_init_resolve_done, service);
-
     ret = EOK;
 
 done:
@@ -485,32 +475,3 @@ void krb5_finalize(struct tevent_context *ev,
 
     sig_term(signum);
 }
-
-void krb5_init_resolve_done(struct tevent_req *req)
-{
-    struct krb5_service *krb5_service  = tevent_req_callback_data(req,
-                                                           struct krb5_service);
-    int ret;
-    struct fo_server *srv;
-    const char *service_name;
-
-    ret = be_resolve_server_recv(req, &srv);
-    talloc_zfree(req);
-    if (ret) {
-        DEBUG(1, ("be_resolve_server request failed [%d][%s]. "
-                  "Creating dummy info file.\n", ret, strerror(ret)));
-
-        service_name = krb5_service->name;
-        if (strcmp(service_name, "IPA") == 0) {
-            service_name = SSS_KRB5KDC_FO_SRV;
-        }
-        ret = write_krb5info_file(krb5_service->realm, DUMMY_ADDRESS,
-                                  service_name);
-        if (ret != EOK) {
-            DEBUG(2, ("write_krb5info_file failed, "
-                      "authentication might fail.\n"));
-        }
-    }
-
-    return;
-}
diff --git a/src/providers/krb5/krb5_common.h b/src/providers/krb5/krb5_common.h
index dd7fdf2..87d6168 100644
--- a/src/providers/krb5/krb5_common.h
+++ b/src/providers/krb5/krb5_common.h
@@ -83,5 +83,4 @@ void krb5_finalize(struct tevent_context *ev,
                    int count,
                    void *siginfo,
                    void *private_data);
-void krb5_init_resolve_done(struct tevent_req *req);
 #endif /* __KRB5_COMMON_H__ */
-- 
1.6.6.1

-------------- next part --------------
From 5a8df1759685d0e24d44bce12ec22dc04654857f Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Fri, 14 May 2010 10:18:33 +0200
Subject: [PATCH 2/6] Refactor data provider callbacks

---
 src/Makefile.am                         |    1 +
 src/providers/data_provider_be.c        |  137 -----------------------
 src/providers/data_provider_callbacks.c |  182 +++++++++++++++++++++++++++++++
 src/providers/dp_backend.h              |   10 +-
 4 files changed, 188 insertions(+), 142 deletions(-)
 create mode 100644 src/providers/data_provider_callbacks.c

diff --git a/src/Makefile.am b/src/Makefile.am
index 5c428e7..e403a77 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -393,6 +393,7 @@ sssd_be_SOURCES = \
     providers/data_provider_be.c \
     providers/data_provider_fo.c \
     providers/data_provider_opts.c \
+    providers/data_provider_callbacks.c \
     $(SSSD_FAILOVER_OBJ) \
     $(SSSD_UTIL_OBJ)
 sssd_be_LDADD = $(SSSD_LIBS) $(CARES_LIBS)
diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c
index 9ef436e..9a7f8cf 100644
--- a/src/providers/data_provider_be.c
+++ b/src/providers/data_provider_be.c
@@ -169,143 +169,6 @@ void be_mark_offline(struct be_ctx *ctx)
     ctx->run_online_cb = true;
 }
 
-
-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 *be;
-};
-
-static int online_cb_destructor(TALLOC_CTX *ptr);
-int be_add_online_cb(TALLOC_CTX *mem_ctx,
-                     struct be_ctx *ctx,
-                     be_conn_online_callback_t cb,
-                     void *pvt,
-                     struct be_conn_online_cb **online_cb)
-{
-    struct be_conn_online_cb *on_cb;
-
-    if (!ctx || !cb) {
-        return EINVAL;
-    }
-
-    on_cb = talloc(mem_ctx, struct be_conn_online_cb);
-    if (!on_cb) {
-        return ENOMEM;
-    }
-
-    on_cb->cb = cb;
-    on_cb->pvt = pvt;
-    on_cb->be = ctx;
-
-    DLIST_ADD(ctx->online_cb_list, on_cb);
-
-    talloc_set_destructor((TALLOC_CTX *)on_cb, online_cb_destructor);
-
-    /* Make sure we run the callback for the first
-     * connection after startup.
-     */
-    ctx->run_online_cb = true;
-
-    if (online_cb) {
-        *online_cb = on_cb;
-    }
-
-    return EOK;
-}
-
-static int online_cb_destructor(TALLOC_CTX *ptr)
-{
-    struct be_conn_online_cb *cb =
-            talloc_get_type(ptr, struct be_conn_online_cb);
-    DLIST_REMOVE(cb->be->online_cb_list, cb);
-    return 0;
-}
-
-
-struct be_online_cb_ctx {
-    struct be_ctx *be;
-    struct be_conn_online_cb *callback;
-};
-
-static void be_run_online_cb_step(struct tevent_context *ev,
-                                  struct tevent_timer *te,
-                                  struct timeval current_time,
-                                  void *pvt);
-void be_run_online_cb(struct be_ctx *be) {
-    struct timeval soon;
-    struct tevent_timer *te;
-    struct be_online_cb_ctx *cb_ctx;
-
-    if (be->run_online_cb && be->online_cb_list) {
-        /* Reset the flag. We only want to run these
-         * callbacks when transitioning to online
-         */
-        be->run_online_cb = false;
-
-        DEBUG(3, ("Going online. Running callbacks.\n"));
-
-        cb_ctx = talloc(be, struct be_online_cb_ctx);
-        if (!cb_ctx) {
-            DEBUG(0, ("Out of memory. Could not invoke callbacks\n"));
-            return;
-        }
-        cb_ctx->be = be;
-        cb_ctx->callback = be->online_cb_list;
-
-        /* Delay 30ms so we don't block any other events */
-        soon = tevent_timeval_current_ofs(0, 30000);
-        te = tevent_add_timer(be->ev, cb_ctx, soon,
-                              be_run_online_cb_step,
-                              cb_ctx);
-        if (!te) {
-            DEBUG(0, ("Out of memory. Could not invoke callbacks\n"));
-            talloc_free(cb_ctx);
-        }
-    }
-}
-
-static void be_run_online_cb_step(struct tevent_context *ev,
-                                  struct tevent_timer *te,
-                                  struct timeval current_time,
-                                  void *pvt)
-{
-    struct be_online_cb_ctx *cb_ctx =
-            talloc_get_type(pvt, struct be_online_cb_ctx);
-    struct tevent_timer *tev;
-    struct timeval soon;
-
-    /* Call the callback */
-    cb_ctx->callback->cb(cb_ctx->callback->pvt);
-
-    if (cb_ctx->callback->next) {
-        cb_ctx->callback = cb_ctx->callback->next;
-
-        /* Delay 30ms so we don't block any other events */
-        soon = tevent_timeval_current_ofs(0, 30000);
-        tev = tevent_add_timer(cb_ctx->be->ev, cb_ctx, soon,
-                               be_run_online_cb_step,
-                               cb_ctx);
-        if (!te) {
-            DEBUG(0, ("Out of memory. Could not invoke callbacks\n"));
-            goto final;
-        }
-        return;
-    }
-
-final:
-    /* Steal the timer event onto the be_ctx so it doesn't
-     * get freed with the cb_ctx
-     */
-    talloc_steal(cb_ctx->be, te);
-    talloc_free(cb_ctx);
-}
-
-
 static int be_check_online(DBusMessage *message, struct sbus_connection *conn)
 {
     struct be_client *becli;
diff --git a/src/providers/data_provider_callbacks.c b/src/providers/data_provider_callbacks.c
new file mode 100644
index 0000000..00bc8fd
--- /dev/null
+++ b/src/providers/data_provider_callbacks.c
@@ -0,0 +1,182 @@
+/*
+    SSSD
+
+    Data Provider Process - Callback
+
+    Authors:
+
+        Stephen Gallagher <sgallagh at redhat.com>
+        Sumit Bose <sbose at redhat.com>
+
+    Copyright (C) 2010 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 "util/util.h"
+#include "providers/dp_backend.h"
+
+struct be_cb {
+    struct be_cb *prev;
+    struct be_cb *next;
+
+    be_callback_t cb;
+    void *pvt;
+
+    struct be_cb *list;
+    struct be_ctx *be;
+};
+
+struct be_cb_ctx {
+    struct be_ctx *be;
+    struct be_cb *callback;
+};
+
+static int cb_destructor(TALLOC_CTX *ptr)
+{
+    struct be_cb *cb = talloc_get_type(ptr, struct be_cb);
+    DLIST_REMOVE(cb->list, cb);
+    return 0;
+}
+
+static int be_add_cb(TALLOC_CTX *mem_ctx, struct be_ctx *ctx,
+                     be_callback_t cb, void *pvt, struct be_cb **cb_list,
+                     struct be_cb **return_cb)
+{
+    struct be_cb *new_cb;
+
+    if (!ctx || !cb) {
+        return EINVAL;
+    }
+
+    new_cb = talloc(mem_ctx, struct be_cb);
+    if (!new_cb) {
+        return ENOMEM;
+    }
+
+    new_cb->cb = cb;
+    new_cb->pvt = pvt;
+    new_cb->list = *cb_list;
+    new_cb->be = ctx;
+
+    DLIST_ADD(*cb_list, new_cb);
+
+    talloc_set_destructor((TALLOC_CTX *) new_cb, cb_destructor);
+
+    if (return_cb) {
+        *return_cb = new_cb;
+    }
+
+    return EOK;
+}
+
+static void be_run_cb_step(struct tevent_context *ev, struct tevent_timer *te,
+                           struct timeval current_time, void *pvt)
+{
+    struct be_cb_ctx *cb_ctx = talloc_get_type(pvt, struct be_cb_ctx);
+    struct tevent_timer *tev;
+    struct timeval soon;
+
+    /* Call the callback */
+    cb_ctx->callback->cb(cb_ctx->callback->pvt);
+
+    if (cb_ctx->callback->next) {
+        cb_ctx->callback = cb_ctx->callback->next;
+
+        /* Delay 30ms so we don't block any other events */
+        soon = tevent_timeval_current_ofs(0, 30000);
+        tev = tevent_add_timer(cb_ctx->be->ev, cb_ctx, soon,
+                               be_run_cb_step,
+                               cb_ctx);
+        if (!te) {
+            DEBUG(0, ("Out of memory. Could not invoke callbacks\n"));
+            goto final;
+        }
+        return;
+    }
+
+final:
+    /* Steal the timer event onto the be_ctx so it doesn't
+     * get freed with the cb_ctx
+     */
+    talloc_steal(cb_ctx->be, te);
+    talloc_free(cb_ctx);
+}
+
+static errno_t be_run_cb(struct be_ctx *be, struct be_cb *cb_list) {
+    struct timeval soon;
+    struct tevent_timer *te;
+    struct be_cb_ctx *cb_ctx;
+
+    cb_ctx = talloc(be, struct be_cb_ctx);
+    if (!cb_ctx) {
+        DEBUG(0, ("Out of memory. Could not invoke callbacks\n"));
+        return ENOMEM;
+    }
+    cb_ctx->be = be;
+    cb_ctx->callback = cb_list;
+
+    /* Delay 30ms so we don't block any other events */
+    soon = tevent_timeval_current_ofs(0, 30000);
+    te = tevent_add_timer(be->ev, cb_ctx, soon,
+                          be_run_cb_step,
+                          cb_ctx);
+    if (!te) {
+        DEBUG(0, ("Out of memory. Could not invoke callbacks\n"));
+        talloc_free(cb_ctx);
+        return ENOMEM;
+    }
+
+    return EOK;
+}
+
+int be_add_online_cb(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, be_callback_t cb,
+                     void *pvt, struct be_cb **online_cb)
+{
+    int ret;
+
+    ret = be_add_cb(mem_ctx, ctx, cb, pvt, &ctx->online_cb_list, online_cb);
+    if (ret != EOK) {
+        DEBUG(1, ("be_add_cb failed.\n"));
+        return ret;
+    }
+
+    /* Make sure we run the callback for the first
+     * connection after startup.
+     */
+    ctx->run_online_cb = true;
+
+    return EOK;
+}
+
+void be_run_online_cb(struct be_ctx *be) {
+    int ret;
+
+    if (be->run_online_cb && be->online_cb_list) {
+        /* Reset the flag. We only want to run these
+         * callbacks when transitioning to online
+         */
+        be->run_online_cb = false;
+
+        DEBUG(3, ("Going online. Running callbacks.\n"));
+
+        ret = be_run_cb(be, be->online_cb_list);
+        if (ret != EOK) {
+            DEBUG(1, ("be_run_cb failed.\n"));
+        }
+
+    } else {
+        DEBUG(9, ("Online call back list is empty, nothing to do.\n"));
+    }
+}
diff --git a/src/providers/dp_backend.h b/src/providers/dp_backend.h
index ec0510e..43d79ba 100644
--- a/src/providers/dp_backend.h
+++ b/src/providers/dp_backend.h
@@ -40,7 +40,7 @@ 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 void (*be_conn_online_callback_t)(void *);
+typedef void (*be_callback_t)(void *);
 
 enum bet_type {
     BET_NULL = 0,
@@ -83,7 +83,7 @@ struct be_client {
 
 struct be_failover_ctx;
 
-struct be_conn_online_cb;
+struct be_cb;
 
 struct be_ctx {
     struct tevent_context *ev;
@@ -97,7 +97,7 @@ struct be_ctx {
     /* Functions to be invoked when the
      * backend goes online
      */
-    struct be_conn_online_cb *online_cb_list;
+    struct be_cb *online_cb_list;
     bool run_online_cb;
 
     struct be_offline_status offstat;
@@ -143,9 +143,9 @@ void be_mark_offline(struct be_ctx *ctx);
 
 int be_add_online_cb(TALLOC_CTX *mem_ctx,
                      struct be_ctx *ctx,
-                     be_conn_online_callback_t cb,
+                     be_callback_t cb,
                      void *pvt,
-                     struct be_conn_online_cb **online_cb);
+                     struct be_cb **online_cb);
 void be_run_online_cb(struct be_ctx *be);
 
 /* from data_provider_fo.c */
-- 
1.6.6.1

-------------- next part --------------
From 9a07fa7407a65034be529d59fbb958389a904498 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Fri, 14 May 2010 10:57:19 +0200
Subject: [PATCH 3/6] Add offline callbacks

---
 src/providers/data_provider_be.c        |    1 +
 src/providers/data_provider_callbacks.c |   22 ++++++++++++++++++++++
 src/providers/dp_backend.h              |   10 +++++++++-
 3 files changed, 32 insertions(+), 1 deletions(-)

diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c
index 9a7f8cf..4ece1b6 100644
--- a/src/providers/data_provider_be.c
+++ b/src/providers/data_provider_be.c
@@ -167,6 +167,7 @@ void be_mark_offline(struct be_ctx *ctx)
     ctx->offstat.went_offline = time(NULL);
     ctx->offstat.offline = true;
     ctx->run_online_cb = true;
+    be_run_offline_cb(ctx);
 }
 
 static int be_check_online(DBusMessage *message, struct sbus_connection *conn)
diff --git a/src/providers/data_provider_callbacks.c b/src/providers/data_provider_callbacks.c
index 00bc8fd..5552713 100644
--- a/src/providers/data_provider_callbacks.c
+++ b/src/providers/data_provider_callbacks.c
@@ -180,3 +180,25 @@ void be_run_online_cb(struct be_ctx *be) {
         DEBUG(9, ("Online call back list is empty, nothing to do.\n"));
     }
 }
+
+int be_add_offline_cb(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, be_callback_t cb,
+                      void *pvt, struct be_cb **offline_cb)
+{
+    return be_add_cb(mem_ctx, ctx, cb, pvt, &ctx->offline_cb_list, offline_cb);
+}
+
+void be_run_offline_cb(struct be_ctx *be) {
+    int ret;
+
+    if (be->offline_cb_list) {
+        DEBUG(3, ("Going offline. Running callbacks.\n"));
+
+        ret = be_run_cb(be, be->offline_cb_list);
+        if (ret != EOK) {
+            DEBUG(1, ("be_run_cb failed.\n"));
+        }
+
+    } else {
+        DEBUG(9, ("Offline call back list is empty, nothing to do.\n"));
+    }
+}
diff --git a/src/providers/dp_backend.h b/src/providers/dp_backend.h
index 43d79ba..fc5e558 100644
--- a/src/providers/dp_backend.h
+++ b/src/providers/dp_backend.h
@@ -95,10 +95,11 @@ struct be_ctx {
     struct be_failover_ctx *be_fo;
 
     /* Functions to be invoked when the
-     * backend goes online
+     * backend goes online or offline
      */
     struct be_cb *online_cb_list;
     bool run_online_cb;
+    struct be_cb *offline_cb_list;
 
     struct be_offline_status offstat;
 
@@ -148,6 +149,13 @@ int be_add_online_cb(TALLOC_CTX *mem_ctx,
                      struct be_cb **online_cb);
 void be_run_online_cb(struct be_ctx *be);
 
+int be_add_offline_cb(TALLOC_CTX *mem_ctx,
+                     struct be_ctx *ctx,
+                     be_callback_t cb,
+                     void *pvt,
+                     struct be_cb **online_cb);
+void be_run_offline_cb(struct be_ctx *be);
+
 /* from data_provider_fo.c */
 typedef void (be_svc_callback_fn_t)(void *, struct fo_server *);
 
-- 
1.6.6.1

-------------- next part --------------
From 4948463564088143ced20b9a6c9f191c3c9edd2d Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Fri, 14 May 2010 11:35:11 +0200
Subject: [PATCH 4/6] Refactor krb5_finalize()

---
 src/providers/krb5/krb5_common.c |   39 ++++++++++++++++++++++++++-----------
 1 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c
index f038557..dfcb502 100644
--- a/src/providers/krb5/krb5_common.c
+++ b/src/providers/krb5/krb5_common.c
@@ -435,22 +435,19 @@ done:
     return ret;
 }
 
-void krb5_finalize(struct tevent_context *ev,
-                   struct tevent_signal *se,
-                   int signum,
-                   int count,
-                   void *siginfo,
-                   void *private_data)
+
+static errno_t remove_krb5_info_files(TALLOC_CTX *mem_ctx, const char *realm)
 {
-    char *realm = (char *)private_data;
     int ret;
     errno_t err;
     char *file;
 
-    file = talloc_asprintf(se, KDCINFO_TMPL, realm);
+    file = talloc_asprintf(mem_ctx, KDCINFO_TMPL, realm);
     if(file == NULL) {
-        sig_term(signum);
+        DEBUG(1, ("talloc_asprintf failed.\n"));
+        return ENOMEM;
     }
+
     errno = 0;
     ret = unlink(file);
     if (ret == -1) {
@@ -459,10 +456,10 @@ void krb5_finalize(struct tevent_context *ev,
                   err, strerror(err)));
     }
 
-    errno = 0;
-    file = talloc_asprintf(se, KPASSWDINFO_TMPL, realm);
+    file = talloc_asprintf(mem_ctx, KPASSWDINFO_TMPL, realm);
     if(file == NULL) {
-        sig_term(signum);
+        DEBUG(1, ("talloc_asprintf failed.\n"));
+        return ENOMEM;
     }
 
     errno = 0;
@@ -473,5 +470,23 @@ void krb5_finalize(struct tevent_context *ev,
                   err, strerror(err)));
     }
 
+    return EOK;
+}
+
+void krb5_finalize(struct tevent_context *ev,
+                   struct tevent_signal *se,
+                   int signum,
+                   int count,
+                   void *siginfo,
+                   void *private_data)
+{
+    char *realm = (char *)private_data;
+    int ret;
+
+    ret = remove_krb5_info_files(se, realm);
+    if (ret != EOK) {
+        DEBUG(1, ("remove_krb5_info_files failed.\n"));
+    }
+
     sig_term(signum);
 }
-- 
1.6.6.1

-------------- next part --------------
From ccb67baa3ebb1a6da02fdb082de09ee6a0f25b55 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Fri, 14 May 2010 12:04:36 +0200
Subject: [PATCH 5/6] Add callback to remove krb5 info files when going offline

---
 src/Makefile.am                  |    1 +
 src/providers/ipa/ipa_common.c   |    8 ++++++++
 src/providers/krb5/krb5_common.c |   29 +++++++++++++++++++++++++++++
 src/providers/krb5/krb5_common.h |    2 ++
 4 files changed, 40 insertions(+), 0 deletions(-)

diff --git a/src/Makefile.am b/src/Makefile.am
index e403a77..afe74c8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -509,6 +509,7 @@ krb5_utils_tests_SOURCES = \
     providers/krb5/krb5_common.c \
     providers/data_provider_fo.c \
     providers/data_provider_opts.c \
+    providers/data_provider_callbacks.c \
     $(SSSD_FAILOVER_OBJ) \
     $(SSSD_UTIL_OBJ)
 krb5_utils_tests_CFLAGS = \
diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c
index 304df8e..6738e3e 100644
--- a/src/providers/ipa/ipa_common.c
+++ b/src/providers/ipa/ipa_common.c
@@ -581,6 +581,14 @@ int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
         goto done;
     }
 
+    ret = be_add_offline_cb(memctx, ctx, remove_krb5_info_files_callback,
+                            service->krb5_service, NULL);
+    if (ret != EOK) {
+        /* Not a fatal error. */
+        DEBUG(1, ("Failed to add offline callback, "
+                  "krb5 info file will not be removed when going offline.\n"));
+    }
+
     ret = EOK;
 
 done:
diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c
index dfcb502..4afa3dc 100644
--- a/src/providers/krb5/krb5_common.c
+++ b/src/providers/krb5/krb5_common.c
@@ -425,6 +425,14 @@ int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
         goto done;
     }
 
+    ret = be_add_offline_cb(memctx, ctx, remove_krb5_info_files_callback,
+                            service, NULL);
+    if (ret != EOK) {
+        /* Not a fatal error. */
+        DEBUG(1, ("Failed to add offline callback, "
+                  "krb5 info file will not be removed when going offline.\n"));
+    }
+
     ret = EOK;
 
 done:
@@ -473,6 +481,27 @@ static errno_t remove_krb5_info_files(TALLOC_CTX *mem_ctx, const char *realm)
     return EOK;
 }
 
+void remove_krb5_info_files_callback(void *pvt)
+{
+    int ret;
+    TALLOC_CTX *tmp_ctx = NULL;
+    struct krb5_service *krb5_service = talloc_get_type(pvt,
+                                                        struct krb5_service);
+
+    tmp_ctx = talloc_new(NULL);
+    if (tmp_ctx == NULL) {
+        DEBUG(1, ("talloc_new failed, cannot remove krb5 info files.\n"));
+        return;
+    }
+
+    ret = remove_krb5_info_files(tmp_ctx, krb5_service->realm);
+    if (ret != EOK) {
+        DEBUG(1, ("remove_krb5_info_files failed.\n"));
+    }
+
+    talloc_zfree(tmp_ctx);
+}
+
 void krb5_finalize(struct tevent_context *ev,
                    struct tevent_signal *se,
                    int signum,
diff --git a/src/providers/krb5/krb5_common.h b/src/providers/krb5/krb5_common.h
index 87d6168..fbbd41d 100644
--- a/src/providers/krb5/krb5_common.h
+++ b/src/providers/krb5/krb5_common.h
@@ -77,6 +77,8 @@ int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx,
                       const char *service_name, const char *servers,
                       const char *realm, struct krb5_service **_service);
 
+void remove_krb5_info_files_callback(void *pvt);
+
 void krb5_finalize(struct tevent_context *ev,
                    struct tevent_signal *se,
                    int signum,
-- 
1.6.6.1

-------------- next part --------------
From 9166fad069898f0b79aaffcf5faa4400afef2d65 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Fri, 14 May 2010 12:16:59 +0200
Subject: [PATCH 6/6] Krb5 locator plugin returns KRB5_PLUGIN_NO_HANDLE

To allow a fallback to the setting in krb5.conf the locator plugin
returns KRB5_PLUGIN_NO_HANDLE in nearly all error conditions. Only if the
call back fails the error code of the callback is returned.
---
 src/krb5_plugin/sssd_krb5_locator_plugin.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/krb5_plugin/sssd_krb5_locator_plugin.c b/src/krb5_plugin/sssd_krb5_locator_plugin.c
index 153145b..dfc9c19 100644
--- a/src/krb5_plugin/sssd_krb5_locator_plugin.c
+++ b/src/krb5_plugin/sssd_krb5_locator_plugin.c
@@ -223,7 +223,7 @@ krb5_error_code sssd_krb5_locator_init(krb5_context context,
     const char *dummy;
 
     ctx = calloc(1,sizeof(struct sssd_ctx));
-    if (ctx == NULL) return ENOMEM;
+    if (ctx == NULL) return KRB5_PLUGIN_NO_HANDLE;
 
     dummy = getenv(SSSD_KRB5_LOCATOR_DEBUG);
     if (dummy == NULL) {
@@ -280,7 +280,7 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
         ctx->sssd_realm = strdup(realm);
         if (ctx->sssd_realm == NULL) {
             PLUGIN_DEBUG(("strdup failed.\n"));
-            return ENOMEM;
+            return KRB5_PLUGIN_NO_HANDLE;
         }
 
         ret = get_krb5info(realm, ctx, locate_service_kdc);
@@ -326,7 +326,7 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
         case locate_service_krb524:
             return KRB5_PLUGIN_NO_HANDLE;
         default:
-            return EINVAL;
+            return KRB5_PLUGIN_NO_HANDLE;
     }
 
     switch (family) {
@@ -343,7 +343,7 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
         case SOCK_DGRAM:
             break;
         default:
-            return EINVAL;
+            return KRB5_PLUGIN_NO_HANDLE;
     }
 
     if (strcmp(realm, ctx->sssd_realm) != 0)
@@ -353,7 +353,7 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
     ret = snprintf(port_str, PORT_STR_SIZE-1, "%u", port);
     if (ret < 0 || ret >= (PORT_STR_SIZE-1)) {
         PLUGIN_DEBUG(("snprintf failed.\n"));
-        return EFAULT;
+        return KRB5_PLUGIN_NO_HANDLE;
     }
 
     memset(&ai_hints, 0, sizeof(struct addrinfo));
@@ -368,7 +368,7 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
             PLUGIN_DEBUG(("getaddrinfo failed [%d][%s].\n", errno,
                                                             strerror(errno)));
         }
-        return EFAULT;
+        return KRB5_PLUGIN_NO_HANDLE;
     }
 
     PLUGIN_DEBUG(("addr[%s:%s] family[%d] socktype[%d]\n", addr, port_str,
-- 
1.6.6.1



More information about the sssd-devel mailing list