@@ -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;
+}
@@ -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);
}
/*
@@ -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);
Signed-off-by: Doug Nazar <nazard@nazar.ca> --- utils/gssd/gssd.c | 46 +++++++++++++++++++++++++++++++------ utils/gssd/krb5_util.c | 52 ++++++++++++++++++++++++------------------ utils/gssd/krb5_util.h | 2 +- 3 files changed, 70 insertions(+), 30 deletions(-)