Signed-off-by: Doug Nazar <nazard@xxxxxxxx> --- utils/gssd/gssd.c | 46 +++++++++++++++++++++++++++++++------ utils/gssd/krb5_util.c | 52 ++++++++++++++++++++++++------------------ utils/gssd/krb5_util.h | 2 +- 3 files changed, 70 insertions(+), 30 deletions(-) diff --git a/utils/gssd/gssd.c b/utils/gssd/gssd.c index f8f21f74..54d9b5de 100644 --- a/utils/gssd/gssd.c +++ b/utils/gssd/gssd.c @@ -91,6 +91,7 @@ char *ccachedir = NULL; static bool avoid_dns = true; static bool use_gssproxy = false; pthread_mutex_t clp_lock = PTHREAD_MUTEX_INITIALIZER; +static bool signal_received = false; static struct event_base *evbase = NULL; TAILQ_HEAD(topdir_list_head, topdir) topdir_list; @@ -872,10 +873,16 @@ found: static void sig_die(int signal) { - if (root_uses_machine_creds) - gssd_destroy_krb5_machine_creds(); + if (signal_received) + { + gssd_destroy_krb5_principals(root_uses_machine_creds); + printerr(1, "forced exiting on signal %d\n", signal); + exit(0); + } + + signal_received = true; printerr(1, "exiting on signal %d\n", signal); - exit(0); + event_base_loopexit(evbase, NULL); } static void @@ -932,6 +939,7 @@ main(int argc, char *argv[]) int rpc_verbosity = 0; int opt; int i; + int rc; extern char *optarg; char *progname; struct event *sighup_ev; @@ -1109,9 +1117,33 @@ main(int argc, char *argv[]) gssd_scan(); daemon_ready(); - event_base_dispatch(evbase); + rc = event_base_dispatch(evbase); - printerr(0, "ERROR: event_dispatch() returned!\n"); - return EXIT_FAILURE; -} + printerr(0, "event_dispatch() returned %i!\n", rc); + gssd_destroy_krb5_principals(root_uses_machine_creds); + + while (!TAILQ_EMPTY(&topdir_list)) { + struct topdir *tdi = TAILQ_FIRST(&topdir_list); + TAILQ_REMOVE(&topdir_list, tdi, list); + while (!TAILQ_EMPTY(&tdi->clnt_list)) { + struct clnt_info *clp = TAILQ_FIRST(&tdi->clnt_list); + TAILQ_REMOVE(&tdi->clnt_list, clp, list); + gssd_destroy_client(clp); + } + free(tdi); + } + + event_free(inotify_ev); + event_free(sighup_ev); + event_base_free(evbase); + + close(inotify_fd); + close(pipefs_fd); + closedir(pipefs_dir); + + free(preferred_realm); + free(ccachesearch); + + return rc < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/utils/gssd/krb5_util.c b/utils/gssd/krb5_util.c index 8c73748c..c49c6672 100644 --- a/utils/gssd/krb5_util.c +++ b/utils/gssd/krb5_util.c @@ -1226,7 +1226,7 @@ gssd_free_krb5_machine_cred_list(char **list) * Called upon exit. Destroys machine credentials. */ void -gssd_destroy_krb5_machine_creds(void) +gssd_destroy_krb5_principals(int destroy_machine_creds) { krb5_context context; krb5_error_code code = 0; @@ -1238,33 +1238,41 @@ gssd_destroy_krb5_machine_creds(void) if (code) { k5err = gssd_k5_err_msg(NULL, code); printerr(0, "ERROR: %s while initializing krb5\n", k5err); - goto out; + free(k5err); + return; } - for (ple = gssd_k5_kt_princ_list; ple; ple = ple->next) { - if (!ple->ccname) - continue; - if ((code = krb5_cc_resolve(context, ple->ccname, &ccache))) { - k5err = gssd_k5_err_msg(context, code); - printerr(0, "WARNING: %s while resolving credential " - "cache '%s' for destruction\n", k5err, - ple->ccname); - krb5_free_string(context, k5err); - k5err = NULL; - continue; - } + pthread_mutex_lock(&ple_lock); + while (gssd_k5_kt_princ_list) { + ple = gssd_k5_kt_princ_list; + gssd_k5_kt_princ_list = ple->next; - if ((code = krb5_cc_destroy(context, ccache))) { - k5err = gssd_k5_err_msg(context, code); - printerr(0, "WARNING: %s while destroying credential " - "cache '%s'\n", k5err, ple->ccname); - krb5_free_string(context, k5err); - k5err = NULL; + if (destroy_machine_creds && ple->ccname) { + if ((code = krb5_cc_resolve(context, ple->ccname, &ccache))) { + k5err = gssd_k5_err_msg(context, code); + printerr(0, "WARNING: %s while resolving credential " + "cache '%s' for destruction\n", k5err, + ple->ccname); + free(k5err); + k5err = NULL; + } + + if (!code && (code = krb5_cc_destroy(context, ccache))) { + k5err = gssd_k5_err_msg(context, code); + printerr(0, "WARNING: %s while destroying credential " + "cache '%s'\n", k5err, ple->ccname); + free(k5err); + k5err = NULL; + } } + + krb5_free_principal(context, ple->princ); + free(ple->ccname); + free(ple->realm); + free(ple); } + pthread_mutex_unlock(&ple_lock); krb5_free_context(context); - out: - krb5_free_string(context, k5err); } /* diff --git a/utils/gssd/krb5_util.h b/utils/gssd/krb5_util.h index b000b444..e127cc84 100644 --- a/utils/gssd/krb5_util.h +++ b/utils/gssd/krb5_util.h @@ -27,7 +27,7 @@ int gssd_setup_krb5_user_gss_ccache(uid_t uid, char *servername, char *dirname); int gssd_get_krb5_machine_cred_list(char ***list); void gssd_free_krb5_machine_cred_list(char **list); -void gssd_destroy_krb5_machine_creds(void); +void gssd_destroy_krb5_principals(int destroy_machine_creds); int gssd_refresh_krb5_machine_credential(char *hostname, struct gssd_k5_kt_princ *ple, char *service, char *srchost); -- 2.26.2