From 8f958f58c913bfcc7903a4381707cb4634175299 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Fri, 14 May 2010 12:04:36 +0200 Subject: [PATCH 06/10] Add callback to remove krb5 info files when going offline --- src/Makefile.am | 1 + src/providers/ipa/ipa_init.c | 6 ++ src/providers/krb5/krb5_auth.h | 40 ---------------- src/providers/krb5/krb5_common.c | 97 ++++++++++++++++++++++++++++++++++++++ src/providers/krb5/krb5_common.h | 52 ++++++++++++++++++++ src/providers/krb5/krb5_init.c | 7 ++- 6 files changed, 162 insertions(+), 41 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index c7a10e7..cb0685c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -515,6 +515,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_init.c b/src/providers/ipa/ipa_init.c index 0e72b1f..60501ce 100644 --- a/src/providers/ipa/ipa_init.c +++ b/src/providers/ipa/ipa_init.c @@ -287,6 +287,12 @@ int sssm_ipa_auth_init(struct be_ctx *bectx, goto done; } + ret = krb5_install_offline_callback(bectx, krb5_auth_ctx); + if (ret != EOK) { + DEBUG(1, ("krb5_install_offline_callback failed.\n")); + goto done; + } + if (debug_to_file != 0) { ret = open_debug_file_ex("krb5_child", &debug_filep); if (ret != EOK) { diff --git a/src/providers/krb5/krb5_auth.h b/src/providers/krb5/krb5_auth.h index 61b8071..7a4cb77 100644 --- a/src/providers/krb5/krb5_auth.h +++ b/src/providers/krb5/krb5_auth.h @@ -37,8 +37,6 @@ #define ILLEGAL_PATH_PATTERN "//|/\\./|/\\.\\./" -typedef enum { INIT_PW, INIT_KT, RENEW, VALIDATE } action_type; - struct krb5child_req { pid_t child_pid; int read_from_child_fd; @@ -61,44 +59,6 @@ struct krb5child_req { bool valid_tgt_present; }; -struct fo_service; -struct deferred_auth_ctx; - -struct krb5_ctx { - /* opts taken from kinit */ - /* in seconds */ - krb5_deltat starttime; - krb5_deltat lifetime; - krb5_deltat rlife; - - int forwardable; - int proxiable; - int addresses; - - int not_forwardable; - int not_proxiable; - int no_addresses; - - int verbose; - - char* principal_name; - char* service_name; - char* keytab_name; - char* k5_cache_name; - char* k4_cache_name; - - action_type action; - - struct dp_option *opts; - struct krb5_service *service; - struct krb5_service *kpasswd_service; - int child_debug_fd; - - pcre *illegal_path_re; - - struct deferred_auth_ctx *deferred_auth_ctx; -}; - void krb5_pam_handler(struct be_req *be_req); struct tevent_req *krb5_auth_send(TALLOC_CTX *mem_ctx, diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c index dfcb502..f63f516 100644 --- a/src/providers/krb5/krb5_common.c +++ b/src/providers/krb5/krb5_common.c @@ -473,6 +473,46 @@ 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 remove_info_files_ctx *ctx = talloc_get_type(pvt, + struct remove_info_files_ctx); + + ret = be_fo_run_callbacks_at_next_request(ctx->be_ctx, + ctx->kdc_service_name); + if (ret != EOK) { + DEBUG(1, ("be_fo_run_callbacks_at_next_request failed, " + "krb5 info files will not be removed, because " + "it is unclear if they will be recreated properly.\n")); + return; + } + if (ctx->kpasswd_service_name != NULL) { + ret = be_fo_run_callbacks_at_next_request(ctx->be_ctx, + ctx->kpasswd_service_name); + if (ret != EOK) { + DEBUG(1, ("be_fo_run_callbacks_at_next_request failed, " + "krb5 info files will not be removed, because " + "it is unclear if they will be recreated properly.\n")); + return; + } + } + + 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, ctx->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, @@ -490,3 +530,60 @@ void krb5_finalize(struct tevent_context *ev, sig_term(signum); } + +errno_t krb5_install_offline_callback(struct be_ctx *be_ctx, + struct krb5_ctx *krb5_ctx) +{ + int ret; + struct remove_info_files_ctx *ctx; + const char *krb5_realm; + + if (krb5_ctx->service == NULL || krb5_ctx->service->name == NULL) { + DEBUG(1, ("Missing KDC service name!\n")); + return EINVAL; + } + + ctx = talloc_zero(krb5_ctx, struct remove_info_files_ctx); + if (ctx == NULL) { + DEBUG(1, ("talloc_zfree failed.\n")); + return ENOMEM; + } + + krb5_realm = dp_opt_get_cstring(krb5_ctx->opts, KRB5_REALM); + if (krb5_realm == NULL) { + DEBUG(1, ("Missing krb5_realm option!\n")); + ret = EINVAL; + goto done; + } + + ctx->realm = talloc_strdup(ctx, krb5_realm); + if (ctx->realm == NULL) { + DEBUG(1, ("talloc_strdup failed!\n")); + ret = ENOMEM; + goto done; + } + + ctx->be_ctx = be_ctx; + ctx->kdc_service_name = krb5_ctx->service->name; + if (krb5_ctx->kpasswd_service == NULL) { + ctx->kpasswd_service_name =NULL; + } else { + ctx->kpasswd_service_name = krb5_ctx->kpasswd_service->name; + } + + ret = be_add_offline_cb(ctx, be_ctx, remove_krb5_info_files_callback, ctx, + NULL); + if (ret != EOK) { + DEBUG(1, ("be_add_offline_cb failed.\n")); + goto done; + } + + ret = EOK; + +done: + if (ret != EOK) { + talloc_zfree(ctx); + } + + return ret; +} diff --git a/src/providers/krb5/krb5_common.h b/src/providers/krb5/krb5_common.h index 87d6168..f9b6195 100644 --- a/src/providers/krb5/krb5_common.h +++ b/src/providers/krb5/krb5_common.h @@ -58,12 +58,59 @@ enum krb5_opts { KRB5_OPTS }; +typedef enum { INIT_PW, INIT_KT, RENEW, VALIDATE } action_type; + struct krb5_service { char *name; char *address; char *realm; }; +struct fo_service; +struct deferred_auth_ctx; + +struct krb5_ctx { + /* opts taken from kinit */ + /* in seconds */ + krb5_deltat starttime; + krb5_deltat lifetime; + krb5_deltat rlife; + + int forwardable; + int proxiable; + int addresses; + + int not_forwardable; + int not_proxiable; + int no_addresses; + + int verbose; + + char* principal_name; + char* service_name; + char* keytab_name; + char* k5_cache_name; + char* k4_cache_name; + + action_type action; + + struct dp_option *opts; + struct krb5_service *service; + struct krb5_service *kpasswd_service; + int child_debug_fd; + + pcre *illegal_path_re; + + struct deferred_auth_ctx *deferred_auth_ctx; +}; + +struct remove_info_files_ctx { + char *realm; + struct be_ctx *be_ctx; + const char *kdc_service_name; + const char *kpasswd_service_name; +}; + errno_t check_and_export_options(struct dp_option *opts, struct sss_domain_info *dom); @@ -77,10 +124,15 @@ 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, int count, void *siginfo, void *private_data); + +errno_t krb5_install_offline_callback(struct be_ctx *be_ctx, + struct krb5_ctx *krb_ctx); #endif /* __KRB5_COMMON_H__ */ diff --git a/src/providers/krb5/krb5_init.c b/src/providers/krb5/krb5_init.c index 4a02b05..481b088 100644 --- a/src/providers/krb5/krb5_init.c +++ b/src/providers/krb5/krb5_init.c @@ -135,7 +135,6 @@ int sssm_krb5_auth_init(struct be_ctx *bectx, goto fail; } - BlockSignals(false, SIGTERM); sig_realm = talloc_strdup(ctx, krb5_realm); if (sig_realm == NULL) { @@ -151,6 +150,12 @@ int sssm_krb5_auth_init(struct be_ctx *bectx, } talloc_steal(sige, sig_realm); + ret = krb5_install_offline_callback(bectx, ctx); + if (ret != EOK) { + DEBUG(1, ("krb5_install_offline_callback failed.\n")); + goto fail; + } + if (debug_to_file != 0) { ret = open_debug_file_ex("krb5_child", &debug_filep); if (ret != EOK) { -- 1.6.6.1