summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2010-05-14 12:04:36 +0200
committerStephen Gallagher <sgallagh@redhat.com>2010-05-18 13:06:43 -0400
commit43452c83befb2585e1081302f4f0add83ef5572a (patch)
tree3ea9aa0c58416a312e429f3e695bd8619107033e
parent5f9ccdddd96fe97bc8f99fad2b13f7496e475e13 (diff)
downloadsssd-43452c83befb2585e1081302f4f0add83ef5572a.tar.gz
sssd-43452c83befb2585e1081302f4f0add83ef5572a.tar.xz
sssd-43452c83befb2585e1081302f4f0add83ef5572a.zip
Add callback to remove krb5 info files when going offline
-rw-r--r--src/Makefile.am1
-rw-r--r--src/providers/ipa/ipa_init.c6
-rw-r--r--src/providers/krb5/krb5_auth.h40
-rw-r--r--src/providers/krb5/krb5_common.c97
-rw-r--r--src/providers/krb5/krb5_common.h52
-rw-r--r--src/providers/krb5/krb5_init.c7
6 files changed, 162 insertions, 41 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index c7a10e744..cb0685cd7 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 0e72b1fab..60501ce24 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 61b8071ef..7a4cb77ab 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 dfcb50260..f63f51641 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 87d616846..f9b61956f 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 4a02b0514..481b08804 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) {