201 lines
5.9 KiB
Diff
201 lines
5.9 KiB
Diff
From 09c62a6f4e4a6963a731d3018209b91dc6447f70 Mon Sep 17 00:00:00 2001
|
|
From: Steve Grubb <sgrubb@redhat.com>
|
|
Date: Mon, 11 Jul 2022 14:21:04 -0400
|
|
Subject: audisp-remote - cleanup krb5 memory leaks on error
|
|
paths
|
|
Conflict:context adaptation
|
|
---
|
|
audisp/plugins/remote/audisp-remote.c | 75 ++++++++++++++++++++-------
|
|
1 file changed, 56 insertions(+), 19 deletions(-)
|
|
|
|
diff --git a/audisp/plugins/remote/audisp-remote.c b/audisp/plugins/remote/audisp-remote.c
|
|
index 3be91b3..3b9d8f0 100644
|
|
--- a/audisp/plugins/remote/audisp-remote.c
|
|
+++ b/audisp/plugins/remote/audisp-remote.c
|
|
@@ -757,9 +757,8 @@ static void gss_failure (const char *msg, int major_status, int minor_status)
|
|
gss_failure_2 (msg, minor_status, GSS_C_MECH_CODE);
|
|
}
|
|
|
|
-#define KCHECK(x,f) if (x) { \
|
|
- syslog (LOG_ERR, "krb5 error: %s in %s\n", krb5_get_error_message (kcontext, x), f); \
|
|
- return -1; }
|
|
+#define KLOG(x,f) syslog (LOG_ERR, "krb5 error: %s in %s\n", \
|
|
+ krb5_get_error_message (kcontext, x), f);
|
|
|
|
/* Each time we connect to the server, we negotiate a set of credentials and
|
|
a security context. To do this, we need our own credentials first. For
|
|
@@ -800,7 +799,10 @@ static int negotiate_credentials (void)
|
|
recv_tok.value = NULL;
|
|
|
|
krberr = krb5_init_context (&kcontext);
|
|
- KCHECK (krberr, "krb5_init_context");
|
|
+ if (krberr) {
|
|
+ KLOG (krberr, "krb5_init_context");
|
|
+ return -1;
|
|
+ }
|
|
|
|
if (config.krb5_key_file)
|
|
key_file = config.krb5_key_file;
|
|
@@ -815,21 +817,24 @@ static int negotiate_credentials (void)
|
|
syslog (LOG_ERR,
|
|
"%s is not mode 0400 (it's %#o) - compromised key?",
|
|
key_file, st.st_mode & 07777);
|
|
- return -1;
|
|
+ goto error1;
|
|
}
|
|
if (st.st_uid != 0) {
|
|
if (!quiet)
|
|
syslog (LOG_ERR,
|
|
"%s is not owned by root (it's %d) - compromised key?",
|
|
key_file, st.st_uid);
|
|
- return -1;
|
|
+ goto error1;
|
|
}
|
|
}
|
|
|
|
/* This looks up the default real (*our* realm) from
|
|
/etc/krb5.conf (or wherever) */
|
|
krberr = krb5_get_default_realm (kcontext, &realm_name);
|
|
- KCHECK (krberr, "krb5_get_default_realm");
|
|
+ if (krberr) {
|
|
+ KLOG (krberr, "krb5_get_default_realm");
|
|
+ goto error1;
|
|
+ }
|
|
|
|
krb5_client_name = config.krb5_client_name ?
|
|
config.krb5_client_name : "auditd";
|
|
@@ -838,7 +843,7 @@ static int negotiate_credentials (void)
|
|
syslog (LOG_ERR,
|
|
"gethostname: host name longer than %ld characters?",
|
|
sizeof (host_name));
|
|
- return -1;
|
|
+ goto error2;
|
|
}
|
|
|
|
syslog (LOG_ERR, "kerberos principal: %s/%s@%s\n",
|
|
@@ -847,17 +852,26 @@ static int negotiate_credentials (void)
|
|
krberr = krb5_build_principal (kcontext, &audit_princ,
|
|
strlen(realm_name), realm_name,
|
|
krb5_client_name, host_name, NULL);
|
|
- KCHECK (krberr, "krb5_build_principal");
|
|
+ if (krberr) {
|
|
+ KLOG (krberr, "krb5_build_principal");
|
|
+ goto error2;
|
|
+ }
|
|
|
|
/* Locate our machine's key table, where our private key is
|
|
* held. */
|
|
krberr = krb5_kt_resolve (kcontext, key_file, &keytab);
|
|
- KCHECK (krberr, "krb5_kt_resolve");
|
|
+ if (krberr) {
|
|
+ KLOG (krberr, "krb5_kt_resolve");
|
|
+ goto error3;
|
|
+ }
|
|
|
|
/* Identify a cache to hold the key in. The GSS wrappers look
|
|
up our credentials here. */
|
|
krberr = krb5_cc_resolve (kcontext, CCACHE_NAME, &ccache);
|
|
- KCHECK (krberr, "krb5_cc_resolve");
|
|
+ if (krberr) {
|
|
+ KLOG (krberr, "krb5_cc_resolve");
|
|
+ goto error4;
|
|
+ }
|
|
|
|
setenv("KRB5CCNAME", CCACHE_NAME, 1);
|
|
|
|
@@ -872,15 +886,24 @@ static int negotiate_credentials (void)
|
|
krberr = krb5_get_init_creds_keytab(kcontext, &my_creds, audit_princ,
|
|
keytab, 0, NULL,
|
|
&options);
|
|
- KCHECK (krberr, "krb5_get_init_creds_keytab");
|
|
+ if (krberr) {
|
|
+ KLOG (krberr, "krb5_get_init_creds_keytab");
|
|
+ goto error5;
|
|
+ }
|
|
|
|
/* Create the cache... */
|
|
krberr = krb5_cc_initialize(kcontext, ccache, audit_princ);
|
|
- KCHECK (krberr, "krb5_cc_initialize");
|
|
+ if (krberr) {
|
|
+ KLOG (krberr, "krb5_cc_initialize");
|
|
+ goto error6;
|
|
+ }
|
|
|
|
/* ...and store our credentials in it. */
|
|
krberr = krb5_cc_store_cred(kcontext, ccache, &my_creds);
|
|
- KCHECK (krberr, "krb5_cc_store_cred");
|
|
+ if (krberr) {
|
|
+ KLOG (krberr, "krb5_cc_store_cred");
|
|
+ goto error6;
|
|
+ }
|
|
|
|
/* The GSS code now has a set of credentials for this program.
|
|
I.e. we know who "we" are. Now we talk to the server to
|
|
@@ -903,13 +926,13 @@ static int negotiate_credentials (void)
|
|
(gss_OID) gss_nt_service_name, &service_name_e);
|
|
if (major_status != GSS_S_COMPLETE) {
|
|
gss_failure("importing name", major_status, minor_status);
|
|
- return -1;
|
|
+ goto error6;
|
|
}
|
|
|
|
/* Someone has to go first. In this case, it's us. */
|
|
if (send_token(sock, empty_token) < 0) {
|
|
(void) gss_release_name(&minor_status, &service_name_e);
|
|
- return -1;
|
|
+ goto error6;
|
|
}
|
|
|
|
/* The server starts this loop with the token we just sent
|
|
@@ -936,7 +959,7 @@ static int negotiate_credentials (void)
|
|
&send_tok);
|
|
(void) gss_release_name(&minor_status,
|
|
&service_name_e);
|
|
- return -1;
|
|
+ goto error6;
|
|
}
|
|
}
|
|
(void) gss_release_buffer(&minor_status, &send_tok);
|
|
@@ -949,7 +972,7 @@ static int negotiate_credentials (void)
|
|
if (*gss_context != GSS_C_NO_CONTEXT)
|
|
gss_delete_sec_context(&minor_status,
|
|
gss_context, GSS_C_NO_BUFFER);
|
|
- return -1;
|
|
+ goto error6;
|
|
}
|
|
|
|
/* Now get any tokens the sever sends back. We use
|
|
@@ -958,7 +981,7 @@ static int negotiate_credentials (void)
|
|
if (recv_token(sock, &recv_tok) < 0) {
|
|
(void) gss_release_name(&minor_status,
|
|
&service_name_e);
|
|
- return -1;
|
|
+ goto error6;
|
|
}
|
|
token_ptr = &recv_tok;
|
|
}
|
|
@@ -985,6 +1008,20 @@ static int negotiate_credentials (void)
|
|
(char *)recv_tok.value);
|
|
#endif
|
|
return 0;
|
|
+
|
|
+error6:
|
|
+ krb5_free_creds(kcontext, &my_creds);
|
|
+error5:
|
|
+ krb5_cc_close(kcontext, ccache);
|
|
+error4:
|
|
+ krb5_kt_close(kcontext, keytab);
|
|
+error3:
|
|
+ krb5_free_principal(kcontext, audit_princ);
|
|
+error2:
|
|
+ krb5_free_default_realm(kcontext, realm_name);
|
|
+error1:
|
|
+ krb5_free_context(kcontext);
|
|
+ return -1;
|
|
}
|
|
#endif // USE_GSSAPI
|
|
|
|
--
|
|
2.27.0
|
|
|