krb5 commit: Fix memory leaks in test programs

Greg Hudson ghudson at mit.edu
Wed Aug 10 20:49:26 EDT 2016


https://github.com/krb5/krb5/commit/4947c270032691d556140b290e1b10846b692968
commit 4947c270032691d556140b290e1b10846b692968
Author: Greg Hudson <ghudson at mit.edu>
Date:   Thu Jun 23 11:12:55 2016 -0400

    Fix memory leaks in test programs
    
    Eliminate memory leaks detected by asan in test programs, to make it
    easier to find more serious leaks.

 src/kadmin/testing/util/tcl_kadm5.c          |    6 +++
 src/lib/crypto/crypto_tests/camellia-test.c  |    8 ++-
 src/lib/crypto/crypto_tests/t_fork.c         |    9 ++++-
 src/lib/crypto/crypto_tests/t_str2key.c      |    4 +-
 src/lib/kadm5/clnt/client_init.c             |    3 +-
 src/lib/kadm5/unit-test/init-test.c          |    6 +-
 src/lib/kadm5/unit-test/setkey-test.c        |    4 ++
 src/lib/krb5/ccache/t_cccursor.c             |   10 ++++-
 src/lib/krb5/ccache/t_marshal.c              |    3 +
 src/lib/krb5/krb/t_cc_config.c               |    7 +++-
 src/lib/krb5/krb/t_in_ccache.c               |   13 ++++--
 src/lib/krb5/krb/t_vfy_increds.c             |    9 +++-
 src/lib/rpc/unit-test/client.c               |    7 +++
 src/plugins/preauth/pkinit/pkinit_kdf_test.c |   33 +---------------
 src/tests/adata.c                            |    5 ++-
 src/tests/asn.1/krb5_decode_test.c           |    1 +
 src/tests/gssapi/common.c                    |    3 +-
 src/tests/gssapi/t_credstore.c               |    1 +
 src/tests/gssapi/t_export_name.c             |    7 ++-
 src/tests/gssapi/t_inq_mechs_name.c          |    2 +
 src/tests/gssapi/t_s4u2proxy_krb5.c          |    2 +
 src/tests/misc/test_cxx_k5int.cpp            |    1 +
 src/tests/misc/test_cxx_krb5.cpp             |    1 +
 src/tests/plugorder.c                        |    1 +
 src/tests/responder.c                        |    5 ++-
 src/tests/s4u2proxy.c                        |    1 +
 src/tests/unlockiter.c                       |    1 +
 src/util/profile/prof_test1                  |   10 +++-
 src/util/profile/profile_tcl.c               |   53 ++++++++++++++------------
 29 files changed, 132 insertions(+), 84 deletions(-)

diff --git a/src/kadmin/testing/util/tcl_kadm5.c b/src/kadmin/testing/util/tcl_kadm5.c
index b2f51d3..a4997c6 100644
--- a/src/kadmin/testing/util/tcl_kadm5.c
+++ b/src/kadmin/testing/util/tcl_kadm5.c
@@ -1312,6 +1312,7 @@ static void free_principal_ent(kadm5_principal_ent_t *princ)
 {
     krb5_free_principal(context, (*princ)->principal);
     krb5_free_principal(context, (*princ)->mod_name);
+    free((*princ)->policy);
     free(*princ);
     *princ = 0;
 }
@@ -1493,6 +1494,7 @@ finished:
 
 static void free_policy_ent(kadm5_policy_ent_t *policy)
 {
+    free((*policy)->policy);
     free(*policy);
     *policy = 0;
 }
@@ -1635,6 +1637,10 @@ static int _tcl_kadm5_init_any(enum init_type init_type, ClientData clientData,
         ret = kadm5_init(context, client_name, pass, service_name, &params,
                          struct_version, api_version, NULL, &server_handle);
 
+    /* The string fields of params are aliases into argv[3], but
+     * params.keysalts is allocated, so clean it up. */
+    free(params.keysalts);
+
     if (ret != KADM5_OK) {
         stash_error(interp, ret);
         return TCL_ERROR;
diff --git a/src/lib/crypto/crypto_tests/camellia-test.c b/src/lib/crypto/crypto_tests/camellia-test.c
index 73ef2ca..12aeed1 100644
--- a/src/lib/crypto/crypto_tests/camellia-test.c
+++ b/src/lib/crypto/crypto_tests/camellia-test.c
@@ -77,6 +77,7 @@ static void vk_test_1(int len)
 {
     int i;
 
+    enc_key.enctype = ENCTYPE_CAMELLIA128_CTS_CMAC;
     enc_key.length = len;
     printf("\nKEYSIZE=%d\n\n", len * 8);
     memset(plain, 0, sizeof(plain));
@@ -98,10 +99,11 @@ static void vk_test()
 }
 
 /* Variable-Text tests */
-static void vt_test_1(int len)
+static void vt_test_1(int len, krb5_enctype etype)
 {
     int i;
 
+    enc_key.enctype = etype;
     enc_key.length = len;
     printf("\nKEYSIZE=%d\n\n", len * 8);
     memset(key, 0, len);
@@ -118,8 +120,8 @@ static void vt_test_1(int len)
 }
 static void vt_test()
 {
-    vt_test_1(16);
-    vt_test_1(32);
+    vt_test_1(16, ENCTYPE_CAMELLIA128_CTS_CMAC);
+    vt_test_1(32, ENCTYPE_CAMELLIA256_CTS_CMAC);
 }
 
 int main (int argc, char *argv[])
diff --git a/src/lib/crypto/crypto_tests/t_fork.c b/src/lib/crypto/crypto_tests/t_fork.c
index 7d1fe69..428fc8a 100644
--- a/src/lib/crypto/crypto_tests/t_fork.c
+++ b/src/lib/crypto/crypto_tests/t_fork.c
@@ -57,7 +57,6 @@ prepare_enc_data(krb5_key key, size_t in_len, krb5_enc_data *enc_data)
 int
 main()
 {
-    krb5_error_code ret;
     krb5_keyblock kb_aes, kb_rc4;
     krb5_key key_aes, key_rc4;
     krb5_data state_rc4, plain = string2data("plain"), decrypted;
@@ -96,6 +95,14 @@ main()
     t(krb5_k_encrypt(ctx, key_rc4, 0, &state_rc4, &plain, &out_rc4));
     t(krb5_c_free_state(ctx, &kb_rc4, &state_rc4));
 
+    krb5_free_keyblock_contents(ctx, &kb_aes);
+    krb5_free_keyblock_contents(ctx, &kb_rc4);
+    krb5_k_free_key(ctx, key_aes);
+    krb5_k_free_key(ctx, key_rc4);
+    krb5_free_data_contents(ctx, &out_aes.ciphertext);
+    krb5_free_data_contents(ctx, &out_rc4.ciphertext);
+    krb5_free_data_contents(ctx, &decrypted);
+
     /* If we're the parent, make sure the child succeeded. */
     if (pid != 0) {
         wpid = wait(&status);
diff --git a/src/lib/crypto/crypto_tests/t_str2key.c b/src/lib/crypto/crypto_tests/t_str2key.c
index bf562a5..7ff6efd 100644
--- a/src/lib/crypto/crypto_tests/t_str2key.c
+++ b/src/lib/crypto/crypto_tests/t_str2key.c
@@ -749,8 +749,10 @@ main(int argc, char **argv)
             else
                 printf("Expected error: %d\n", (int)test->expected_err);
         }
-        if (test->expected_err != 0)
+        if (test->expected_err != 0) {
+            krb5_free_keyblock(context, keyblock);
             continue;
+        }
         assert(keyblock->length == test->expected_key.length);
         if (memcmp(keyblock->contents, test->expected_key.data,
                    keyblock->length) != 0) {
diff --git a/src/lib/kadm5/clnt/client_init.c b/src/lib/kadm5/clnt/client_init.c
index 6291db7..4350a9e 100644
--- a/src/lib/kadm5/clnt/client_init.c
+++ b/src/lib/kadm5/clnt/client_init.c
@@ -145,7 +145,7 @@ init_any(krb5_context context, char *client_name, enum init_type init_type,
          krb5_ui_4 api_version, char **db_args, void **server_handle)
 {
     int fd = -1;
-
+    OM_uint32 minor_stat;
     krb5_boolean iprop_enable;
     int port;
     rpcprog_t rpc_prog;
@@ -345,6 +345,7 @@ error:
     }
     if (handle->cache_name)
         free(handle->cache_name);
+    (void)gss_release_cred(&minor_stat, &handle->cred);
     if(handle->clnt && handle->clnt->cl_auth)
         AUTH_DESTROY(handle->clnt->cl_auth);
     if(handle->clnt)
diff --git a/src/lib/kadm5/unit-test/init-test.c b/src/lib/kadm5/unit-test/init-test.c
index 880400c..9f06621 100644
--- a/src/lib/kadm5/unit-test/init-test.c
+++ b/src/lib/kadm5/unit-test/init-test.c
@@ -23,8 +23,10 @@ int main()
     ret = kadm5_init(context, "admin", "admin", NULL, &params,
                      KADM5_STRUCT_VERSION, KADM5_API_VERSION_4, NULL,
                      &server_handle);
+    if (!ret)
+        (void)kadm5_destroy(server_handle);
+    krb5_free_context(context);
     if (ret == KADM5_RPC_ERROR) {
-        krb5_free_context(context);
         exit(0);
     }
     else if (ret != 0) {
@@ -32,8 +34,6 @@ int main()
         exit(1);
     } else {
         fprintf(stderr, "Unexpected success while initializing without auth!\n");
-        (void) kadm5_destroy(server_handle);
-        krb5_free_context(context);
         exit(1);
     }
 }
diff --git a/src/lib/kadm5/unit-test/setkey-test.c b/src/lib/kadm5/unit-test/setkey-test.c
index 0729885..60be9e8 100644
--- a/src/lib/kadm5/unit-test/setkey-test.c
+++ b/src/lib/kadm5/unit-test/setkey-test.c
@@ -222,6 +222,7 @@ main(int argc, char **argv)
                 com_err(whoami, ret, "while acquiring initial ticket");
                 exit(1);
             }
+            krb5_free_cred_contents(context, &my_creds);
 
             /* since I can't specify enctype explicitly ... */
             ret = krb5_kt_remove_entry(context, kt, &ktent);
@@ -246,5 +247,8 @@ main(int argc, char **argv)
         exit(1);
     }
 
+    krb5_free_principal(context, princ);
+    krb5_free_principal(context, server);
+    krb5_free_context(context);
     return 0;
 }
diff --git a/src/lib/krb5/ccache/t_cccursor.c b/src/lib/krb5/ccache/t_cccursor.c
index dc5fa5b..4323b77 100644
--- a/src/lib/krb5/ccache/t_cccursor.c
+++ b/src/lib/krb5/ccache/t_cccursor.c
@@ -38,6 +38,7 @@
 int
 main(int argc, char **argv)
 {
+    krb5_error_code ret;
     krb5_context ctx;
     krb5_cccol_cursor cursor;
     krb5_ccache cache, hold[64];
@@ -51,8 +52,11 @@ main(int argc, char **argv)
     if (argc > 2) {
         assert(argc < 60);
         for (i = 2; i < argc; i++) {
-            if (strcmp(argv[i], "CONTENT") == 0)
-                return (krb5_cccol_have_content(ctx) != 0);
+            if (strcmp(argv[i], "CONTENT") == 0) {
+                ret = krb5_cccol_have_content(ctx);
+                krb5_free_context(ctx);
+                return ret != 0;
+            }
             assert(krb5_cc_resolve(ctx, argv[i], &hold[i - 2]) == 0);
         }
     }
@@ -71,5 +75,7 @@ main(int argc, char **argv)
 
     for (i = 2; i < argc; i++)
         krb5_cc_close(ctx, hold[i - 2]);
+
+    krb5_free_context(ctx);
     return 0;
 }
diff --git a/src/lib/krb5/ccache/t_marshal.c b/src/lib/krb5/ccache/t_marshal.c
index bad8cfc..144554c 100644
--- a/src/lib/krb5/ccache/t_marshal.c
+++ b/src/lib/krb5/ccache/t_marshal.c
@@ -386,15 +386,18 @@ main(int argc, char **argv)
         if (krb5_cc_next_cred(context, cache, &cursor, &cred1) != 0)
             abort();
         verify_cred1(&cred1);
+        krb5_free_cred_contents(context, &cred1);
         if (krb5_cc_next_cred(context, cache, &cursor, &cred2) != 0)
             abort();
         verify_cred2(&cred2);
+        krb5_free_cred_contents(context, &cred2);
         if (krb5_cc_next_cred(context, cache, &cursor, &cred2) != KRB5_CC_END)
             abort();
         if (krb5_cc_end_seq_get(context, cache, &cursor) != 0)
             abort();
         if (krb5_cc_close(context, cache) != 0)
             abort();
+        krb5_free_principal(context, princ);
     }
 
     (void)unlink(filename);
diff --git a/src/lib/krb5/krb/t_cc_config.c b/src/lib/krb5/krb/t_cc_config.c
index 51d1ef5..c2546d7 100644
--- a/src/lib/krb5/krb/t_cc_config.c
+++ b/src/lib/krb5/krb/t_cc_config.c
@@ -92,6 +92,7 @@ unset_config(krb5_context context, krb5_ccache ccache,
                         "Error storing non-config item to in-memory ccache",
                         krb5_cc_store_cred(context, tmp2, &creds));
         }
+        krb5_free_cred_contents(context, &creds);
     }
     bail_on_err(context, "Error ending traversal of first in-memory ccache",
                 krb5_cc_end_seq_get(context, tmp1, &cursor));
@@ -103,6 +104,8 @@ unset_config(krb5_context context, krb5_ccache ccache,
                 krb5_cc_destroy(context, tmp1));
     bail_on_err(context, "Error cleaning up second in-memory ccache",
                 krb5_cc_destroy(context, tmp2));
+    krb5_free_principal(context, mcreds.client);
+    krb5_free_principal(context, mcreds.server);
 }
 
 int
@@ -127,9 +130,10 @@ main(int argc, char **argv)
         case 'p':
             if (asprintf(&perr, "Error parsing principal name \"%s\"",
                          optarg) < 0)
-                perr = "Error parsing principal name";
+                abort();
             bail_on_err(context, perr,
                         krb5_parse_name(context, optarg, &server));
+            free(perr);
             break;
         }
     }
@@ -149,6 +153,7 @@ main(int argc, char **argv)
         if (ret == 0) {
             for (i = 0; i < data.length; i++)
                 putc((unsigned int)data.data[i], stdout);
+            krb5_free_data_contents(context, &data);
         }
     }
     krb5_free_principal(context, server);
diff --git a/src/lib/krb5/krb/t_in_ccache.c b/src/lib/krb5/krb/t_in_ccache.c
index 0bb203f..3f157a4 100644
--- a/src/lib/krb5/krb/t_in_ccache.c
+++ b/src/lib/krb5/krb/t_in_ccache.c
@@ -70,6 +70,7 @@ main(int argc, char **argv)
     krb5_ccache in_ccache, out_ccache, armor_ccache;
     krb5_get_init_creds_opt *opt;
     char *user, *password, *armor_ccname = NULL, *in_ccname = NULL, *perr;
+    const char *err;
     krb5_principal client;
     krb5_creds creds;
     krb5_flags fast_flags;
@@ -124,14 +125,17 @@ main(int argc, char **argv)
     bail_on_err(ctx, "Error setting output ccache option",
                 krb5_get_init_creds_opt_set_out_ccache(ctx, opt, out_ccache));
     if (asprintf(&perr, "Error parsing principal name \"%s\"", user) < 0)
-        perr = "Error parsing principal name";
+        abort();
     bail_on_err(ctx, perr, krb5_parse_name(ctx, user, &client));
     ret = krb5_get_init_creds_password(ctx, &creds, client, password,
                                        prompter_cb, NULL, 0, NULL, opt);
-    if (ret)
-        printf("%s\n", krb5_get_error_message(ctx, ret));
-    else
+    if (ret) {
+        err = krb5_get_error_message(ctx, ret);
+        printf("%s\n", err);
+        krb5_free_error_message(ctx, err);
+    } else {
         krb5_free_cred_contents(ctx, &creds);
+    }
     krb5_get_init_creds_opt_free(ctx, opt);
     krb5_free_principal(ctx, client);
     krb5_cc_close(ctx, out_ccache);
@@ -140,5 +144,6 @@ main(int argc, char **argv)
     if (in_ccache != NULL)
         krb5_cc_close(ctx, in_ccache);
     krb5_free_context(ctx);
+    free(perr);
     return ret ? (ret - KRB5KDC_ERR_NONE) : 0;
 }
diff --git a/src/lib/krb5/krb/t_vfy_increds.c b/src/lib/krb5/krb/t_vfy_increds.c
index a128014..693eb37 100644
--- a/src/lib/krb5/krb/t_vfy_increds.c
+++ b/src/lib/krb5/krb/t_vfy_increds.c
@@ -45,6 +45,7 @@ check(krb5_error_code code)
 int
 main(int argc, char **argv)
 {
+    krb5_error_code ret;
     krb5_context context;
     krb5_ccache ccache;
     krb5_cc_cursor cursor;
@@ -70,7 +71,9 @@ main(int argc, char **argv)
     check(krb5_cc_end_seq_get(context, ccache, &cursor));
     check(krb5_cc_close(context, ccache));
 
-    if (krb5_verify_init_creds(context, &creds, princ, NULL, NULL, &opt) != 0)
-        return 1;
-    return 0;
+    ret = krb5_verify_init_creds(context, &creds, princ, NULL, NULL, &opt);
+    krb5_free_cred_contents(context, &creds);
+    krb5_free_principal(context, princ);
+    krb5_free_context(context);
+    return ret ? 1 : 0;
 }
diff --git a/src/lib/rpc/unit-test/client.c b/src/lib/rpc/unit-test/client.c
index 06b0863..5edde49 100644
--- a/src/lib/rpc/unit-test/client.c
+++ b/src/lib/rpc/unit-test/client.c
@@ -194,6 +194,7 @@ main(argc, argv)
 	       clnt_perror(clnt, whoami);
      } else {
 	  fprintf(stderr, "bad seq didn't cause failure\n");
+	  gssrpc_xdr_free(xdr_wrapstring, echo_resp);
      }
 
      AUTH_PRIVATE(clnt->cl_auth)->seq_num -= 3;
@@ -205,6 +206,8 @@ main(argc, argv)
      echo_resp = rpc_test_echo_1(&echo_arg, clnt);
      if (echo_resp == NULL)
 	  clnt_perror(clnt, "Sequence number improperly reset");
+     else
+	  gssrpc_xdr_free(xdr_wrapstring, echo_resp);
 
      /*
       * Now simulate a lost server response, and see if
@@ -215,6 +218,8 @@ main(argc, argv)
      echo_resp = rpc_test_echo_1(&echo_arg, clnt);
      if (echo_resp == NULL)
 	  clnt_perror(clnt, "Auto-resynchronization failed");
+     else
+	  gssrpc_xdr_free(xdr_wrapstring, echo_resp);
 
      /*
       * Now make sure auto-resyncrhonization actually worked
@@ -223,6 +228,8 @@ main(argc, argv)
      echo_resp = rpc_test_echo_1(&echo_arg, clnt);
      if (echo_resp == NULL)
 	  clnt_perror(clnt, "Auto-resynchronization did not work");
+     else
+	  gssrpc_xdr_free(xdr_wrapstring, echo_resp);
 
      /*
       * Test fix for secure-rpc/586, part 1: btree keys must be
diff --git a/src/plugins/preauth/pkinit/pkinit_kdf_test.c b/src/plugins/preauth/pkinit/pkinit_kdf_test.c
index afc6029..7acbd0d 100644
--- a/src/plugins/preauth/pkinit/pkinit_kdf_test.c
+++ b/src/plugins/preauth/pkinit/pkinit_kdf_test.c
@@ -82,11 +82,9 @@ main(int argc, char **argv)
 
     /* other local variables */
     int retval = 0;
-    int max_keylen = 2048;
     krb5_enctype enctype = 0;
     krb5_principal u_principal = NULL;
     krb5_principal v_principal = NULL;
-    krb5_keyblock *key_block_ptr = &key_block;
 
     /* initialize variables that get malloc'ed, so cleanup is safe */
     krb5_init_context (&context);
@@ -130,15 +128,6 @@ main(int argc, char **argv)
 
     enctype = enctype_aes;
 
-    /* set-up the key_block */
-    if (0 != (retval = krb5_init_keyblock(context, enctype, max_keylen,
-                                          &key_block_ptr))) {
-        printf("ERROR in pkinit_kdf_test: can't init keyblock, retval = %d",
-               retval);
-        goto cleanup;
-
-    }
-
     /* call pkinit_alg_agility_kdf() with test vector values*/
     if (0 != (retval = pkinit_alg_agility_kdf(context, &secret,
                                               &alg_id.algorithm,
@@ -171,15 +160,6 @@ main(int argc, char **argv)
 
     enctype = enctype_aes;
 
-    /* set-up the key_block */
-    if (0 != (retval = krb5_init_keyblock(context, enctype, max_keylen,
-                                          &key_block_ptr))) {
-        printf("ERROR in pkinit_kdf_test: can't init keyblock, retval = %d",
-               retval);
-        goto cleanup;
-
-    }
-
     /* call pkinit_alg_agility_kdf() with test vector values*/
     if (0 != (retval = pkinit_alg_agility_kdf(context, &secret,
                                               &alg_id.algorithm,
@@ -212,15 +192,6 @@ main(int argc, char **argv)
 
     enctype = enctype_des3;
 
-    /* set-up the key_block */
-    if (0 != (retval = krb5_init_keyblock(context, enctype, max_keylen,
-                                          &key_block_ptr))) {
-        printf("ERROR in pkinit_kdf_test: can't init keyblock, retval = %d",
-               retval);
-        goto cleanup;
-
-    }
-
     /* call pkinit_alg_agility_kdf() with test vector values*/
     if (0 != (retval = pkinit_alg_agility_kdf(context, &secret,
                                               &alg_id.algorithm,
@@ -247,8 +218,8 @@ main(int argc, char **argv)
 cleanup:
     /* release all allocated resources, whether good or bad return */
     free(secret.data);
-    free(u_principal);
-    free(v_principal);
+    krb5_free_principal(context, u_principal);
+    krb5_free_principal(context, v_principal);
     krb5_free_keyblock_contents(context, &key_block);
     exit(retval);
 }
diff --git a/src/tests/adata.c b/src/tests/adata.c
index 08bc16a..df77c80 100644
--- a/src/tests/adata.c
+++ b/src/tests/adata.c
@@ -133,7 +133,10 @@ make_authdata(const char *typestr, const char *contents)
 
     if (*typestr == '?' || *typestr == '!' || *typestr == '^') {
         inner_ad = make_authdata(typestr + 1, contents);
-        return make_container(get_type_for_prefix(*typestr), inner_ad);
+        ad = make_container(get_type_for_prefix(*typestr), inner_ad);
+        free(inner_ad->contents);
+        free(inner_ad);
+        return ad;
     }
 
     ad = malloc(sizeof(*ad));
diff --git a/src/tests/asn.1/krb5_decode_test.c b/src/tests/asn.1/krb5_decode_test.c
index e017739..f17f9b1 100644
--- a/src/tests/asn.1/krb5_decode_test.c
+++ b/src/tests/asn.1/krb5_decode_test.c
@@ -1083,6 +1083,7 @@ int main(argc, argv)
     {
         setup(krb5_kkdcp_message,ktest_make_sample_kkdcp_message);
         decode_run("kkdcp_message","","30 82 01 FC A0 82 01 EC 04 82 01 E8 6A 82 01 E4 30 82 01 E0 A1 03 02 01 05 A2 03 02 01 0A A3 26 30 24 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 30 10 A1 03 02 01 0D A2 09 04 07 70 61 2D 64 61 74 61 A4 82 01 AA 30 82 01 A6 A0 07 03 05 00 FE DC BA 98 A1 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A2 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A3 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A4 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A5 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A6 11 18 0F 31 39 39 34 30 36 31 30 30 36 30 33 31 37 5A A7 03 02 01 2A A8 08 30 06 02 01 00 02 01 01 A9 20 30 1E 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 30 0D A0 03 02 01 02 A1 06 04 04 12 D0 00 23 AA 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 AB 81 BF 30 81 BC 61 5C 30 5A A!
 0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 61 5C 30 5A A0 03 02 01 05 A1 10 1B 0E 41 54 48 45 4E 41 2E 4D 49 54 2E 45 44 55 A2 1A 30 18 A0 03 02 01 01 A1 11 30 0F 1B 06 68 66 74 73 61 69 1B 05 65 78 74 72 61 A3 25 30 23 A0 03 02 01 00 A1 03 02 01 05 A2 17 04 15 6B 72 62 41 53 4E 2E 31 20 74 65 73 74 20 6D 65 73 73 61 67 65 A1 0A 1B 08 6B 72 62 35 64 61 74 61",decode_krb5_kkdcp_message,ktest_equal_kkdcp_message,ktest_free_kkdcp_message);
+        ktest_empty_kkdcp_message(&ref);
     }
 
     /****************************************************************/
diff --git a/src/tests/gssapi/common.c b/src/tests/gssapi/common.c
index 231f44a..0de36d3 100644
--- a/src/tests/gssapi/common.c
+++ b/src/tests/gssapi/common.c
@@ -240,11 +240,10 @@ enumerate_attributes(gss_name_t name, int noisy)
 {
     OM_uint32 major, minor;
     int is_mechname;
-    gss_OID mech = GSS_C_NO_OID;
     gss_buffer_set_t attrs = GSS_C_NO_BUFFER_SET;
     size_t i;
 
-    major = gss_inquire_name(&minor, name, &is_mechname, &mech, &attrs);
+    major = gss_inquire_name(&minor, name, &is_mechname, NULL, &attrs);
     check_gsserr("gss_inquire_name", major, minor);
 
     if (attrs != GSS_C_NO_BUFFER_SET) {
diff --git a/src/tests/gssapi/t_credstore.c b/src/tests/gssapi/t_credstore.c
index e28f5d0..0278581 100644
--- a/src/tests/gssapi/t_credstore.c
+++ b/src/tests/gssapi/t_credstore.c
@@ -126,6 +126,7 @@ main(int argc, char *argv[])
                                        GSS_C_NO_CHANNEL_BINDINGS, NULL, NULL,
                                        &atok, NULL, NULL, NULL);
         check_gsserr("gss_accept_sec_context(2)", major, minor);
+        (void)gss_release_buffer(&minor, &itok);
         (void)gss_release_buffer(&minor, &atok);
         (void)gss_delete_sec_context(&minor, &actx, NULL);
     }
diff --git a/src/tests/gssapi/t_export_name.c b/src/tests/gssapi/t_export_name.c
index 5f3eccf..b7eebd4 100644
--- a/src/tests/gssapi/t_export_name.c
+++ b/src/tests/gssapi/t_export_name.c
@@ -94,11 +94,11 @@ main(int argc, char *argv[])
     /* Import and re-export the name, and compare the results. */
     ntype = use_composite ? GSS_C_NT_COMPOSITE_EXPORT : GSS_C_NT_EXPORT_NAME;
     major = gss_import_name(&minor, &buf, ntype, &impname);
-    check_gsserr("gss_export_name", major, minor);
+    check_gsserr("gss_import_name", major, minor);
     if (use_composite)
-        major = gss_export_name_composite(&minor, mechname, &buf2);
+        major = gss_export_name_composite(&minor, impname, &buf2);
     else
-        major = gss_export_name(&minor, mechname, &buf2);
+        major = gss_export_name(&minor, impname, &buf2);
     check_gsserr("gss_export_name", major, minor);
     if (buf.length != buf2.length ||
         memcmp(buf.value, buf2.value, buf.length) != 0) {
@@ -112,6 +112,7 @@ main(int argc, char *argv[])
 
     (void)gss_release_name(&minor, &name);
     (void)gss_release_name(&minor, &mechname);
+    (void)gss_release_name(&minor, &impname);
     (void)gss_release_buffer(&minor, &buf);
     (void)gss_release_buffer(&minor, &buf2);
     return 0;
diff --git a/src/tests/gssapi/t_inq_mechs_name.c b/src/tests/gssapi/t_inq_mechs_name.c
index da87b86..9f4ae4e 100644
--- a/src/tests/gssapi/t_inq_mechs_name.c
+++ b/src/tests/gssapi/t_inq_mechs_name.c
@@ -58,5 +58,7 @@ main(int argc, char *argv[])
     check_gsserr("gss_inquire_mechs_for_name", major, minor);
     for (i = 0; i < mechs->count; i++)
         display_oid(NULL, &mechs->elements[i]);
+    (void)gss_release_oid_set(&minor, &mechs);
+    (void)gss_release_name(&minor, &name);
     return 0;
 }
diff --git a/src/tests/gssapi/t_s4u2proxy_krb5.c b/src/tests/gssapi/t_s4u2proxy_krb5.c
index 483d915..0027f1f 100644
--- a/src/tests/gssapi/t_s4u2proxy_krb5.c
+++ b/src/tests/gssapi/t_s4u2proxy_krb5.c
@@ -133,6 +133,8 @@ main(int argc, char *argv[])
 
     (void)gss_delete_sec_context(&minor, &initiator_context, GSS_C_NO_BUFFER);
     (void)gss_delete_sec_context(&minor, &acceptor_context, GSS_C_NO_BUFFER);
+    (void)gss_release_name(&minor, &client_name);
+    (void)gss_release_cred(&minor, &deleg_cred);
 
     /* Establish contexts using the storage ccache. */
     service2_name = import_name(service2);
diff --git a/src/tests/misc/test_cxx_k5int.cpp b/src/tests/misc/test_cxx_k5int.cpp
index 602fe94..bb6005f 100644
--- a/src/tests/misc/test_cxx_k5int.cpp
+++ b/src/tests/misc/test_cxx_k5int.cpp
@@ -15,5 +15,6 @@ int main (int argc, char *argv[])
 	return 1;
     }
     printf("hello, world\n");
+    krb5_free_context(ctx);
     return 0;
 }
diff --git a/src/tests/misc/test_cxx_krb5.cpp b/src/tests/misc/test_cxx_krb5.cpp
index 33a046f..002120b 100644
--- a/src/tests/misc/test_cxx_krb5.cpp
+++ b/src/tests/misc/test_cxx_krb5.cpp
@@ -14,5 +14,6 @@ int main (int argc, char *argv[])
 	return 1;
     }
     printf("hello, world\n");
+    krb5_free_context(ctx);
     return 0;
 }
diff --git a/src/tests/plugorder.c b/src/tests/plugorder.c
index e13d210..e1245e4 100644
--- a/src/tests/plugorder.c
+++ b/src/tests/plugorder.c
@@ -91,5 +91,6 @@ main()
         check((*mod)(ctx, 1, 1, (krb5_plugin_vtable)&vt));
         printf("%s\n", vt.name);
     }
+    k5_plugin_free_modules(ctx, modules);
     return 0;
 }
diff --git a/src/tests/responder.c b/src/tests/responder.c
index 5f53a31..21aae65 100644
--- a/src/tests/responder.c
+++ b/src/tests/responder.c
@@ -319,6 +319,7 @@ main(int argc, char **argv)
     krb5_principal principal;
     krb5_creds creds;
     krb5_error_code err;
+    const char *errmsg;
     char *opt, *val;
     struct responder_data response;
     int c;
@@ -419,8 +420,10 @@ main(int argc, char **argv)
         fprintf(stderr, "error: responder callback wasn't called\n");
         err = 1;
     } else if (err) {
+        errmsg = krb5_get_error_message(context, err);
         fprintf(stderr, "error: krb5_get_init_creds_password failed: %s\n",
-                krb5_get_error_message(context, err));
+                errmsg);
+        krb5_free_error_message(context, errmsg);
         err = 2;
     }
     krb5_free_context(context);
diff --git a/src/tests/s4u2proxy.c b/src/tests/s4u2proxy.c
index a6baeb6..28bff61 100644
--- a/src/tests/s4u2proxy.c
+++ b/src/tests/s4u2proxy.c
@@ -106,5 +106,6 @@ main(int argc, char **argv)
     krb5_free_cred_contents(context, &ev_cred);
     krb5_free_ticket(context, ev_ticket);
     krb5_free_creds(context, new_cred);
+    krb5_free_context(context);
     return 0;
 }
diff --git a/src/tests/unlockiter.c b/src/tests/unlockiter.c
index b0c48f9..e854bc9 100644
--- a/src/tests/unlockiter.c
+++ b/src/tests/unlockiter.c
@@ -137,6 +137,7 @@ iterator(struct cb_arg *cb_arg, char **db_args, pid_t child)
     retval = krb5_db_fini(ctx);
 
 cleanup:
+    krb5_free_context(ctx);
     if (retval) {
         com_err("iterator", retval, "");
         kill(child, SIGTERM);
diff --git a/src/util/profile/prof_test1 b/src/util/profile/prof_test1
index 984eb3b..7e30fc1 100644
--- a/src/util/profile/prof_test1
+++ b/src/util/profile/prof_test1
@@ -21,7 +21,7 @@ proc test1 {} {
 	}
     }
     if $verbose { puts "" }
-    #profile_iterator_free $iter
+    profile_iterator_free $iter
 
     set iter [profile_iterator_create $p $sect 0]
     set done 0
@@ -37,7 +37,7 @@ proc test1 {} {
 	}
     }
     if $verbose { puts "" }
-    #profile_iterator_free $iter
+    profile_iterator_free $iter
     catch {file delete $wd/test3.ini}
     profile_flush_to_file $p $wd/test3.ini
     profile_abandon $p
@@ -58,7 +58,7 @@ proc test1 {} {
 	    if $verbose { puts -nonewline "\t$val" }
 	}
     }
-    #profile_iterator_free $iter
+    profile_iterator_free $iter
     profile_abandon $p
 
     if {$found_some} {
@@ -243,6 +243,7 @@ proc test5 {} {
 	puts stderr, "Error: test5: Wrong results from profile"
 	exit 1
     }
+    profile_release $p
 
     puts "OK: test5: syntax independence of included files"
 }
@@ -273,6 +274,7 @@ proc test6 {} {
 	puts stderr, "Error: test6: Got value from deleted section"
 	exit 1
     }
+    profile_abandon $p
 
     puts "OK: test6: section replacement"
 }
@@ -291,6 +293,7 @@ proc test7 {} {
     profile_update_relation $p $rel 2
     if $verbose { puts "Clearing values at {$rel}" }
     profile_clear_relation $p $rel
+    profile_abandon $p
     puts "OK: test7: profile_clear_relation with deleted node at end"
 }
 
@@ -314,6 +317,7 @@ proc test8 {} {
 	puts stderr, "Error: test8: Wrong order of values: $x"
 	exit 1
     }
+    profile_abandon $p
 
     puts "OK: test8: relation order in the presence of deletions"
 }
diff --git a/src/util/profile/profile_tcl.c b/src/util/profile/profile_tcl.c
index 505fb80..cac4627 100644
--- a/src/util/profile/profile_tcl.c
+++ b/src/util/profile/profile_tcl.c
@@ -1712,7 +1712,10 @@ static void my_tcl_setresult(Tcl_Interp *i, const char *str, Tcl_FreeProc *f)
 #endif
 
 
-typedef void **iter_t; /* ick */
+typedef struct {
+    void *handle;
+    char **args;
+} *iter_t;
 
 
 SWIGINTERN int
@@ -1789,50 +1792,49 @@ SWIG_From_int  (int value)
 }
 
 
+static void iter_free(iter_t it)
+{
+    int i;
+
+    for (i = 0; it->args != NULL && it->args[i] != NULL; i++)
+	free(it->args[i]);
+    free(it->args);
+    profile_iterator_free(&it->handle);
+    free(it);
+}
+
 static errcode_t iter_create(profile_t p, const char **nullterm,
 			     int flags, iter_t *OUTPUT)
 {
     iter_t it;
     errcode_t err;
-    const char **args;
 
     it = malloc(sizeof(*it));
     if (it == NULL)
 	return ENOMEM;
     {
-	/* Memory leak!
-
-	   The profile code seems to assume that I'll keep the string
-	   array around for as long as the iterator is valid; I can't
-	   create the iterator and then throw them away.
-
-	   But right now, I can't be bothered to track the necessary
-	   information to do the cleanup later.  */
+	/* The current implementation requires that the names be kept around
+	 * for the lifetime of the iterator. */
 	int count, j;
 	for (count = 0; nullterm[count]; count++) ;
-	args = calloc(count+1, sizeof(char *));
-	if (args == NULL)
+	it->args = calloc(count + 1, sizeof(*it->args));
+	if (it->args == NULL)
 	    return ENOMEM;
 	for (j = 0; j < count; j++) {
-	    args[j] = strdup(nullterm[j]);
-	    if (args[j] == NULL)
+	    it->args[j] = strdup(nullterm[j]);
+	    if (it->args[j] == NULL)
 		return ENOMEM;
 	}
-	args[j] = NULL;
+	it->args[j] = NULL;
     }
-    err = profile_iterator_create(p, args, flags, it);
+    err = profile_iterator_create(p, (const char **)it->args, flags,
+				  &it->handle);
     if (err)
-	free(it);
+	iter_free(it);
     else
 	*OUTPUT = it;
     return err;
 }
-static void iter_free(iter_t i)
-{
-    profile_iterator_free(i);
-    free(i);
-}
-
 
 
 /* A TCL_AppInit() function that lets you build a new copy
@@ -2137,6 +2139,7 @@ _wrap_profile_get_values(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, i
     for (i = 0; (*arg3)[i]; i++)
     Tcl_AppendElement(interp, (*arg3)[i]);
   }
+  profile_free_list(*arg3);
   {
     /* freearg char **nullterm */
     if (arg2) {
@@ -2642,7 +2645,7 @@ _wrap_profile_iterator(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, int
     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "profile_iterator" "', argument " "1"" of type '" "iter_t""'");
   }
   arg1 = (iter_t)(argp1);
-  result = (errcode_t)profile_iterator(arg1,arg2,arg3);
+  result = (errcode_t)profile_iterator(&arg1->handle,arg2,arg3);
   {
     /* out errcode_t result */
     if (result) {
@@ -2659,6 +2662,7 @@ _wrap_profile_iterator(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, int
     Tcl_ListObjAppendElement(interp, Tcl_GetObjResult(interp),
       Tcl_NewStringObj(s, strlen(s)));
   }
+  profile_release_string(*arg2);
   {
     /* argout char **OUTPUT */
     /*    Tcl_SetResult(interp, *arg3, TCL_DYNAMIC); */
@@ -2666,6 +2670,7 @@ _wrap_profile_iterator(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, int
     Tcl_ListObjAppendElement(interp, Tcl_GetObjResult(interp),
       Tcl_NewStringObj(s, strlen(s)));
   }
+  profile_release_string(*arg3);
   return TCL_OK;
 fail:
   return TCL_ERROR;


More information about the cvs-krb5 mailing list