r1222: Valgrind memory leak fixes. Still tracking down a strange one...
authorJeremy Allison <jra@samba.org>
Wed, 23 Jun 2004 00:20:31 +0000 (00:20 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:52:00 +0000 (10:52 -0500)
Can't fix the krb5 memory leaks inside that library :-(.
Jeremy.

source/libads/kerberos_keytab.c
source/libads/krb5_setpw.c
source/libads/ldap.c
source/libsmb/clikrb5.c
source/utils/net_ads.c

index 410aad649c41e0af7b532b975490a1721691d8ff..cb0841f2e2236c263eb1a2af1df6c0305dae1d39 100644 (file)
@@ -488,9 +488,13 @@ int ads_keytab_create_default(ADS_STRUCT *ads)
                                                break;
                                        }
                                        if (!strcmp(oldEntries[i], ktprinc)) {
+                                               krb5_free_unparsed_name(context, ktprinc);
                                                break;
                                        }
                                }
+                               if (i == found) {
+                                       krb5_free_unparsed_name(context, ktprinc);
+                               }
                        }
                        krb5_free_keytab_entry_contents(context, &kt_entry);
                        ZERO_STRUCT(kt_entry);
index 5c859f0e9952325ef33a71ab22ed5bf16fe7f58e..111834e8866a084466414c80891910140991602f 100644 (file)
@@ -56,7 +56,7 @@ static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password)
 
        princ = strdup(principal);
 
-       if ((c = strchr(princ, '/')) == NULL) {
+       if ((c = strchr_m(princ, '/')) == NULL) {
            c = princ; 
        } else {
            *c = '\0';
@@ -66,7 +66,7 @@ static DATA_BLOB encode_krb5_setpw(const char *principal, const char *password)
 
        princ_part2 = c;
 
-       if ((c = strchr(c, '@')) != NULL) {
+       if ((c = strchr_m(c, '@')) != NULL) {
            *c = '\0';
            c++;
            realm = c;
@@ -462,14 +462,16 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ,
 {
 
        ADS_STATUS aret;
-       krb5_error_code ret;
+       krb5_error_code ret = 0;
        krb5_context context = NULL;
-       krb5_principal principal;
-       char *princ_name;
-       char *realm;
-       krb5_creds creds, *credsp;
+       krb5_principal principal = NULL;
+       char *princ_name = NULL;
+       char *realm = NULL;
+       krb5_creds creds, *credsp = NULL;
        krb5_ccache ccache = NULL;
 
+       ZERO_STRUCT(creds);
+       
        ret = krb5_init_context(&context);
        if (ret) {
                DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret)));
@@ -487,14 +489,19 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ,
                return ADS_ERROR_KRB5(ret);
        }
 
-       ZERO_STRUCT(creds);
-       
-       realm = strchr(princ, '@');
+       realm = strchr_m(princ, '@');
+       if (!realm) {
+               krb5_cc_close(context, ccache);
+               krb5_free_context(context);
+               DEBUG(1,("Failed to get realm\n"));
+               return ADS_ERROR_KRB5(-1);
+       }
        realm++;
 
        asprintf(&princ_name, "kadmin/changepw@%s", realm);
        ret = krb5_parse_name(context, princ_name, &creds.server);
        if (ret) {
+               krb5_cc_close(context, ccache);
                 krb5_free_context(context);
                DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret)));
                return ADS_ERROR_KRB5(ret);
@@ -504,6 +511,8 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ,
        /* parse the principal we got as a function argument */
        ret = krb5_parse_name(context, princ, &principal);
        if (ret) {
+               krb5_cc_close(context, ccache);
+               krb5_free_principal(context, creds.server);
                 krb5_free_context(context);
                DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret)));
                return ADS_ERROR_KRB5(ret);
@@ -514,6 +523,8 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ,
        
        ret = krb5_cc_get_principal(context, ccache, &creds.client);
        if (ret) {
+               krb5_cc_close(context, ccache);
+               krb5_free_principal(context, creds.server);
                krb5_free_principal(context, principal);
                 krb5_free_context(context);
                DEBUG(1,("Failed to get principal from ccache (%s)\n", 
@@ -523,7 +534,9 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ,
        
        ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp); 
        if (ret) {
+               krb5_cc_close(context, ccache);
                krb5_free_principal(context, creds.client);
+               krb5_free_principal(context, creds.server);
                krb5_free_principal(context, principal);
                krb5_free_context(context);
                DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret)));
@@ -538,7 +551,9 @@ ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ,
 
        krb5_free_creds(context, credsp);
        krb5_free_principal(context, creds.client);
+        krb5_free_principal(context, creds.server);
        krb5_free_principal(context, principal);
+       krb5_cc_close(context, ccache);
        krb5_free_context(context);
 
        return aret;
index 3a9c41f09d6ad4c3958edac1c0127baf1153302d..985d3cb576d7e7763a410a08d36b1c9d935764c8 100644 (file)
@@ -1003,7 +1003,7 @@ ADS_STATUS ads_add_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods,
 
 uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name)
 {
-       LDAPMessage *res;
+       LDAPMessage *res = NULL;
        uint32 kvno = (uint32)-1;      /* -1 indicates a failure */
        char *filter;
        const char *attrs[] = {"msDS-KeyVersionNumber", NULL};
@@ -1018,12 +1018,14 @@ uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name)
        SAFE_FREE(filter);
        if (!ADS_ERR_OK(ret) && ads_count_replies(ads, res)) {
                DEBUG(1,("ads_get_kvno: Computer Account For %s not found.\n", machine_name));
+               ads_msgfree(ads, res);
                return kvno;
        }
 
        dn_string = ads_get_dn(ads, res);
        if (!dn_string) {
                DEBUG(0,("ads_get_kvno: out of memory.\n"));
+               ads_msgfree(ads, res);
                return kvno;
        }
        DEBUG(5,("ads_get_kvno: Using: %s\n", dn_string));
@@ -1040,11 +1042,13 @@ uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name)
        if (!ads_pull_uint32(ads, res, "msDS-KeyVersionNumber", &kvno)) {
                DEBUG(3,("ads_get_kvno: Error Determining KVNO!\n"));
                DEBUG(3,("ads_get_kvno: Windows 2000 does not support KVNO's, so this may be normal.\n"));
+               ads_msgfree(ads, res);
                return kvno;
        }
 
        /* Success */
        DEBUG(5,("ads_get_kvno: Looked Up KVNO of: %d\n", kvno));
+       ads_msgfree(ads, res);
        return kvno;
 }
 
@@ -1058,7 +1062,7 @@ uint32 ads_get_kvno(ADS_STRUCT *ads, const char *machine_name)
 ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char *machine_name)
 {
        TALLOC_CTX *ctx;
-       LDAPMessage *res;
+       LDAPMessage *res = NULL;
        ADS_MODLIST mods;
        const char *servicePrincipalName[1] = {NULL};
        ADS_STATUS ret = ADS_ERROR(LDAP_SUCCESS);
@@ -1068,28 +1072,33 @@ ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char *machin
        if (!ADS_ERR_OK(ret) || ads_count_replies(ads, res) != 1) {
                DEBUG(5,("ads_clear_service_principal_names: WARNING: Host Account for %s not found... skipping operation.\n", machine_name));
                DEBUG(5,("ads_clear_service_principal_names: WARNING: Service Principals for %s have NOT been cleared.\n", machine_name));
+               ads_msgfree(ads, res);
                return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
        }
 
        DEBUG(5,("ads_clear_service_principal_names: Host account for %s found\n", machine_name));
        ctx = talloc_init("ads_clear_service_principal_names");
        if (!ctx) {
+               ads_msgfree(ads, res);
                return ADS_ERROR(LDAP_NO_MEMORY);
        }
 
        if (!(mods = ads_init_mods(ctx))) {
                talloc_destroy(ctx);
+               ads_msgfree(ads, res);
                return ADS_ERROR(LDAP_NO_MEMORY);
        }
        ret = ads_mod_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName);
        if (!ADS_ERR_OK(ret)) {
                DEBUG(1,("ads_clear_service_principal_names: Error creating strlist.\n"));
+               ads_msgfree(ads, res);
                talloc_destroy(ctx);
                return ret;
        }
        dn_string = ads_get_dn(ads, res);
        if (!dn_string) {
                talloc_destroy(ctx);
+               ads_msgfree(ads, res);
                return ADS_ERROR(LDAP_NO_MEMORY);
        }
        ret = ads_gen_mod(ads, dn_string, mods);
@@ -1097,10 +1106,12 @@ ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char *machin
        if (!ADS_ERR_OK(ret)) {
                DEBUG(1,("ads_clear_service_principal_names: Error: Updating Service Principals for machine %s in LDAP\n",
                        machine_name));
+               ads_msgfree(ads, res);
                talloc_destroy(ctx);
                return ret;
        }
 
+       ads_msgfree(ads, res);
        talloc_destroy(ctx);
        return ret;
 }
@@ -1118,7 +1129,7 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n
 {
        ADS_STATUS ret;
        TALLOC_CTX *ctx;
-       LDAPMessage *res;
+       LDAPMessage *res = NULL;
        char *host_spn, *host_upn, *psp1, *psp2;
        ADS_MODLIST mods;
        fstring my_fqdn;
@@ -1131,21 +1142,25 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n
                        machine_name));
                DEBUG(1,("ads_add_service_principal_name: WARNING: Service Principal '%s/%s@%s' has NOT been added.\n",
                        spn, machine_name, ads->config.realm));
+               ads_msgfree(ads, res);
                return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
        }
 
        DEBUG(1,("ads_add_service_principal_name: Host account for %s found\n", machine_name));
        if (!(ctx = talloc_init("ads_add_service_principal_name"))) {
+               ads_msgfree(ads, res);
                return ADS_ERROR(LDAP_NO_MEMORY);
        }
 
        name_to_fqdn(my_fqdn, machine_name);
        if (!(host_spn = talloc_asprintf(ctx, "HOST/%s", my_fqdn))) {
                talloc_destroy(ctx);
+               ads_msgfree(ads, res);
                return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
        }
        if (!(host_upn = talloc_asprintf(ctx, "%s@%s", host_spn, ads->config.realm))) {
                talloc_destroy(ctx);
+               ads_msgfree(ads, res);
                return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
        }
 
@@ -1163,28 +1178,33 @@ ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_n
 
        if (!(mods = ads_init_mods(ctx))) {
                talloc_destroy(ctx);
+               ads_msgfree(ads, res);
                return ADS_ERROR(LDAP_NO_MEMORY);
        }
        ret = ads_add_strlist(ctx, &mods, "servicePrincipalName", servicePrincipalName);
        if (!ADS_ERR_OK(ret)) {
                DEBUG(1,("ads_add_service_principal_name: Error: Updating Service Principals in LDAP\n"));
                talloc_destroy(ctx);
+               ads_msgfree(ads, res);
                return ret;
        }
        dn_string = ads_get_dn(ads, res);
        if (!dn_string) {
                talloc_destroy(ctx);
+               ads_msgfree(ads, res);
                return ADS_ERROR(LDAP_NO_MEMORY);
        }
-       ret = ads_gen_mod(ads, ads_get_dn(ads, res), mods);
+       ret = ads_gen_mod(ads, dn_string, mods);
        ads_memfree(ads,dn_string);
        if (!ADS_ERR_OK(ret)) {
                DEBUG(1,("ads_add_service_principal_name: Error: Updating Service Principals in LDAP\n"));
                talloc_destroy(ctx);
+               ads_msgfree(ads, res);
                return ret;
        }
 
        talloc_destroy(ctx);
+       ads_msgfree(ads, res);
        return ret;
 }
 
@@ -1212,7 +1232,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name
        unsigned acct_control;
        unsigned exists=0;
        fstring my_fqdn;
-       LDAPMessage *res;
+       LDAPMessage *res = NULL;
 
        if (!(ctx = talloc_init("ads_add_machine_acct")))
                return ADS_ERROR(LDAP_NO_MEMORY);
@@ -1318,6 +1338,7 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *machine_name
                }
        }
 done:
+       ads_msgfree(ads, res);
        talloc_destroy(ctx);
        return ret;
 }
@@ -1542,7 +1563,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name,
                          uint32 account_type, const char *org_unit)
 {
        ADS_STATUS status;
-       LDAPMessage *res;
+       LDAPMessage *res = NULL;
        char *machine;
 
        /* machine name must be lowercase */
@@ -1577,6 +1598,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *machine_name,
        }
 
        SAFE_FREE(machine);
+       ads_msgfree(ads, res);
 
        return status;
 }
index 01fcfcc3dd0014a3c634f7c8550338971bf5f7a1..ab9bc28fe57044d5c18a4a05f0f65cc725c6a6b9 100644 (file)
@@ -420,11 +420,12 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset,
 failed:
 
        if ( context ) {
-#if 0  /* JERRY -- disabled since it causes heimdal 0.6.1rc3 to die 
-          SuSE 9.1 Pro */
+/* Removed by jra. They really need to fix their kerberos so we don't leak memory. 
+ JERRY -- disabled since it causes heimdal 0.6.1rc3 to die
+          SuSE 9.1 Pro 
+*/
                if (ccdef)
                        krb5_cc_close(context, ccdef);
-#endif
                if (auth_context)
                        krb5_auth_con_free(context, auth_context);
                krb5_free_context(context);
index 650f9922cb185c99c56c32e25e7955d15047eae4..b5706e919ab0a1937f51bfeac4ac8c0302611b87 100644 (file)
@@ -111,8 +111,8 @@ static int net_ads_info(int argc, const char **argv)
        d_printf("LDAP port: %d\n", ads->ldap_port);
        d_printf("Server time: %s\n", http_timestring(ads->config.current_time));
 
-       d_printf("KDC server: %s\n", ads->auth.kdc_server );
-       d_printf("Server time offset: %d\n", ads->auth.time_offset );
+       d_printf("KDC server: %s\n", ads->auth.kdc_server );
+       d_printf("Server time offset: %d\n", ads->auth.time_offset );
 
        return 0;
 }
@@ -216,6 +216,7 @@ static int net_ads_workgroup(int argc, const char **argv)
        if (!(ads = ads_startup())) return -1;
 
        if (!(ctx = talloc_init("net_ads_workgroup"))) {
+               ads_destroy(&ads);
                return -1;
        }
 
@@ -223,13 +224,14 @@ static int net_ads_workgroup(int argc, const char **argv)
                d_printf("Failed to find workgroup for realm '%s'\n", 
                         ads->config.realm);
                talloc_destroy(ctx);
+               ads_destroy(&ads);
                return -1;
        }
 
        d_printf("Workgroup: %s\n", workgroup);
 
        talloc_destroy(ctx);
-
+       ads_destroy(&ads);
        return 0;
 }
 
@@ -276,7 +278,9 @@ static int ads_user_add(int argc, const char **argv)
 
        if (argc < 1) return net_ads_user_usage(argc, argv);
        
-       if (!(ads = ads_startup())) return -1;
+       if (!(ads = ads_startup())) {
+               return -1;
+       }
 
        status = ads_find_user_acct(ads, &res, argv[0]);
 
@@ -344,13 +348,18 @@ static int ads_user_info(int argc, const char **argv)
        char **grouplist;
        char *escaped_user = escape_ldap_string_alloc(argv[0]);
 
-       if (argc < 1) return net_ads_user_usage(argc, argv);
+       if (argc < 1) {
+               return net_ads_user_usage(argc, argv);
+       }
        
-       if (!(ads = ads_startup())) return -1;
+       if (!(ads = ads_startup())) {
+               return -1;
+       }
 
        if (!escaped_user) {
                d_printf("ads_user_info: failed to escape user %s\n", argv[0]);
-               return -1;
+               ads_destroy(&ads);
+               return -1;
        }
 
        asprintf(&searchstring, "(sAMAccountName=%s)", escaped_user);
@@ -359,6 +368,7 @@ static int ads_user_info(int argc, const char **argv)
 
        if (!ADS_ERR_OK(rc)) {
                d_printf("ads_search: %s\n", ads_errstr(rc));
+               ads_destroy(&ads);
                return -1;
        }
        
@@ -376,7 +386,6 @@ static int ads_user_info(int argc, const char **argv)
        }
        
        ads_msgfree(ads, res);
-
        ads_destroy(&ads);
        return 0;
 }
@@ -388,13 +397,18 @@ static int ads_user_delete(int argc, const char **argv)
        void *res;
        char *userdn;
 
-       if (argc < 1) return net_ads_user_usage(argc, argv);
+       if (argc < 1) {
+               return net_ads_user_usage(argc, argv);
+       }
        
-       if (!(ads = ads_startup())) return -1;
+       if (!(ads = ads_startup())) {
+               return -1;
+       }
 
        rc = ads_find_user_acct(ads, &res, argv[0]);
        if (!ADS_ERR_OK(rc)) {
                DEBUG(0, ("User %s does not exist\n", argv[0]));
+               ads_destroy(&ads);
                return -1;
        }
        userdn = ads_get_dn(ads, res);
@@ -403,10 +417,12 @@ static int ads_user_delete(int argc, const char **argv)
        ads_memfree(ads, userdn);
        if (!ADS_ERR_OK(rc)) {
                d_printf("User %s deleted\n", argv[0]);
+               ads_destroy(&ads);
                return 0;
        }
        d_printf("Error deleting user %s: %s\n", argv[0], 
                 ads_errstr(rc));
+       ads_destroy(&ads);
        return -1;
 }
 
@@ -425,7 +441,9 @@ int net_ads_user(int argc, const char **argv)
        char *disp_fields[2] = {NULL, NULL};
        
        if (argc == 0) {
-               if (!(ads = ads_startup())) return -1;
+               if (!(ads = ads_startup())) {
+                       return -1;
+               }
 
                if (opt_long_list_entries)
                        d_printf("\nUser name             Comment"\
@@ -456,9 +474,13 @@ static int ads_group_add(int argc, const char **argv)
        void *res=NULL;
        int rc = -1;
 
-       if (argc < 1) return net_ads_group_usage(argc, argv);
+       if (argc < 1) {
+               return net_ads_group_usage(argc, argv);
+       }
        
-       if (!(ads = ads_startup())) return -1;
+       if (!(ads = ads_startup())) {
+               return -1;
+       }
 
        status = ads_find_user_acct(ads, &res, argv[0]);
 
@@ -497,13 +519,18 @@ static int ads_group_delete(int argc, const char **argv)
        void *res;
        char *groupdn;
 
-       if (argc < 1) return net_ads_group_usage(argc, argv);
+       if (argc < 1) {
+               return net_ads_group_usage(argc, argv);
+       }
        
-       if (!(ads = ads_startup())) return -1;
+       if (!(ads = ads_startup())) {
+               return -1;
+       }
 
        rc = ads_find_user_acct(ads, &res, argv[0]);
        if (!ADS_ERR_OK(rc)) {
                DEBUG(0, ("Group %s does not exist\n", argv[0]));
+               ads_destroy(&ads);
                return -1;
        }
        groupdn = ads_get_dn(ads, res);
@@ -512,10 +539,12 @@ static int ads_group_delete(int argc, const char **argv)
        ads_memfree(ads, groupdn);
        if (!ADS_ERR_OK(rc)) {
                d_printf("Group %s deleted\n", argv[0]);
+               ads_destroy(&ads);
                return 0;
        }
        d_printf("Error deleting group %s: %s\n", argv[0], 
                 ads_errstr(rc));
+       ads_destroy(&ads);
        return -1;
 }
 
@@ -533,7 +562,9 @@ int net_ads_group(int argc, const char **argv)
        char *disp_fields[2] = {NULL, NULL};
 
        if (argc == 0) {
-               if (!(ads = ads_startup())) return -1;
+               if (!(ads = ads_startup())) {
+                       return -1;
+               }
 
                if (opt_long_list_entries)
                        d_printf("\nGroup name            Comment"\
@@ -557,21 +588,25 @@ static int net_ads_status(int argc, const char **argv)
        ADS_STATUS rc;
        void *res;
 
-       if (!(ads = ads_startup())) return -1;
+       if (!(ads = ads_startup())) {
+               return -1;
+       }
 
        rc = ads_find_machine_acct(ads, &res, global_myname());
        if (!ADS_ERR_OK(rc)) {
                d_printf("ads_find_machine_acct: %s\n", ads_errstr(rc));
+               ads_destroy(&ads);
                return -1;
        }
 
        if (ads_count_replies(ads, res) == 0) {
                d_printf("No machine account for '%s' found\n", global_myname());
+               ads_destroy(&ads);
                return -1;
        }
 
        ads_dump(ads, res);
-
+       ads_destroy(&ads);
        return 0;
 }
 
@@ -595,13 +630,14 @@ static int net_ads_leave(int argc, const char **argv)
 
        rc = ads_leave_realm(ads, global_myname());
        if (!ADS_ERR_OK(rc)) {
-           d_printf("Failed to delete host '%s' from the '%s' realm.\n", 
-                    global_myname(), ads->config.realm);
-           return -1;
+               d_printf("Failed to delete host '%s' from the '%s' realm.\n", 
+                       global_myname(), ads->config.realm);
+               ads_destroy(&ads);
+               return -1;
        }
 
        d_printf("Removed '%s' from realm '%s'\n", global_myname(), ads->config.realm);
-
+       ads_destroy(&ads);
        return 0;
 }
 
@@ -661,7 +697,9 @@ int net_ads_join(int argc, const char **argv)
        const char *short_domain_name = NULL;
        TALLOC_CTX *ctx = NULL;
 
-       if (argc > 0) org_unit = argv[0];
+       if (argc > 0) {
+               org_unit = argv[0];
+       }
 
        if (!secrets_init()) {
                DEBUG(1,("Failed to initialise secrets database\n"));
@@ -671,15 +709,19 @@ int net_ads_join(int argc, const char **argv)
        tmp_password = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH);
        password = strdup(tmp_password);
 
-       if (!(ads = ads_startup())) return -1;
+       if (!(ads = ads_startup())) {
+               return -1;
+       }
 
        if (!*lp_realm()) {
                d_printf("realm must be set in in smb.conf for ADS join to succeed.\n");
+               ads_destroy(&ads);
                return -1;
        }
 
        if (strcmp(ads->config.realm, lp_realm()) != 0) {
                d_printf("realm of remote server (%s) and realm in smb.conf (%s) DO NOT match.  Aborting join\n", ads->config.realm, lp_realm());
+               ads_destroy(&ads);
                return -1;
        }
 
@@ -693,35 +735,41 @@ int net_ads_join(int argc, const char **argv)
        if (rc.error_type == ENUM_ADS_ERROR_LDAP && rc.err.rc == LDAP_NO_SUCH_OBJECT) {
                d_printf("ads_join_realm: organizational unit %s does not exist (dn:%s)\n", 
                         org_unit, dn);
+               ads_destroy(&ads);
                return -1;
        }
        free(dn);
 
        if (!ADS_ERR_OK(rc)) {
                d_printf("ads_join_realm: %s\n", ads_errstr(rc));
+               ads_destroy(&ads);
                return -1;
        }       
 
        rc = ads_join_realm(ads, global_myname(), account_type, org_unit);
        if (!ADS_ERR_OK(rc)) {
                d_printf("ads_join_realm: %s\n", ads_errstr(rc));
+               ads_destroy(&ads);
                return -1;
        }
 
        rc = ads_domain_sid(ads, &dom_sid);
        if (!ADS_ERR_OK(rc)) {
                d_printf("ads_domain_sid: %s\n", ads_errstr(rc));       
-       return -1;
+               ads_destroy(&ads);
+               return -1;
        }
 
        if (asprintf(&machine_account, "%s$", global_myname()) == -1) {
                d_printf("asprintf failed\n");
+               ads_destroy(&ads);
                return -1;
        }
 
        rc = ads_set_machine_password(ads, machine_account, password);
        if (!ADS_ERR_OK(rc)) {
                d_printf("ads_set_machine_password: %s\n", ads_errstr(rc));
+               ads_destroy(&ads);
                return -1;
        }
        
@@ -729,6 +777,7 @@ int net_ads_join(int argc, const char **argv)
        
        if ( !(ctx = talloc_init("net ads join")) ) {
                d_printf("talloc_init() failed!\n");
+               ads_destroy(&ads);
                return -1;
        }
        
@@ -753,21 +802,25 @@ int net_ads_join(int argc, const char **argv)
            
        if (!secrets_store_domain_sid(lp_workgroup(), &dom_sid)) {
                DEBUG(1,("Failed to save domain sid\n"));
+               ads_destroy(&ads);
                return -1;
        }
 
        if (!secrets_store_machine_password(password, lp_workgroup(), sec_channel_type)) {
                DEBUG(1,("Failed to save machine password\n"));
+               ads_destroy(&ads);
                return -1;
        }
 
        if (!secrets_store_domain_sid(short_domain_name, &dom_sid)) {
                DEBUG(1,("Failed to save domain sid\n"));
+               ads_destroy(&ads);
                return -1;
        }
 
        if (!secrets_store_machine_password(password, short_domain_name, sec_channel_type)) {
                DEBUG(1,("Failed to save machine password\n"));
+               ads_destroy(&ads);
                return -1;
        }
        
@@ -783,6 +836,7 @@ int net_ads_join(int argc, const char **argv)
        if ( ctx ) {
                talloc_destroy(ctx);
        }
+       ads_destroy(&ads);
        return 0;
 }
 
@@ -809,26 +863,29 @@ static int net_ads_printer_search(int argc, const char **argv)
        ADS_STATUS rc;
        void *res = NULL;
 
-       if (!(ads = ads_startup())) 
+       if (!(ads = ads_startup())) {
                return -1;
+       }
 
        rc = ads_find_printers(ads, &res);
 
        if (!ADS_ERR_OK(rc)) {
                d_printf("ads_find_printer: %s\n", ads_errstr(rc));
                ads_msgfree(ads, res);
-               return -1;
+               ads_destroy(&ads);
+               return -1;
        }
 
        if (ads_count_replies(ads, res) == 0) {
                d_printf("No results found\n");
                ads_msgfree(ads, res);
+               ads_destroy(&ads);
                return -1;
        }
 
        ads_dump(ads, res);
        ads_msgfree(ads, res);
-
+       ads_destroy(&ads);
        return 0;
 }
 
@@ -839,34 +896,41 @@ static int net_ads_printer_info(int argc, const char **argv)
        const char *servername, *printername;
        void *res = NULL;
 
-       if (!(ads = ads_startup())) return -1;
+       if (!(ads = ads_startup())) {
+               return -1;
+       }
 
-       if (argc > 0)
+       if (argc > 0) {
                printername = argv[0];
-       else
+       } else {
                printername = "*";
+       }
 
-       if (argc > 1)
+       if (argc > 1) {
                servername =  argv[1];
-       else
+       } else {
                servername = global_myname();
+       }
 
        rc = ads_find_printer_on_server(ads, &res, printername, servername);
 
        if (!ADS_ERR_OK(rc)) {
                d_printf("ads_find_printer_on_server: %s\n", ads_errstr(rc));
                ads_msgfree(ads, res);
+               ads_destroy(&ads);
                return -1;
        }
 
        if (ads_count_replies(ads, res) == 0) {
                d_printf("Printer '%s' not found\n", printername);
                ads_msgfree(ads, res);
+               ads_destroy(&ads);
                return -1;
        }
 
        ads_dump(ads, res);
        ads_msgfree(ads, res);
+       ads_destroy(&ads);
 
        return 0;
 }
@@ -889,17 +953,21 @@ static int net_ads_printer_publish(int argc, const char **argv)
        char *prt_dn, *srv_dn, **srv_cn;
        void *res = NULL;
 
-       if (!(ads = ads_startup())) return -1;
+       if (!(ads = ads_startup())) {
+               return -1;
+       }
 
-       if (argc < 1)
+       if (argc < 1) {
                return net_ads_printer_usage(argc, argv);
+       }
        
        printername = argv[0];
 
-       if (argc == 2)
+       if (argc == 2) {
                servername = argv[1];
-       else
+       } else {
                servername = global_myname();
+       }
                
        /* Get printer data from SPOOLSS */
 
@@ -916,6 +984,7 @@ static int net_ads_printer_publish(int argc, const char **argv)
        if (NT_STATUS_IS_ERR(nt_status)) {
                d_printf("Unable to open a connnection to %s to obtain data "
                         "for %s\n", servername, printername);
+               ads_destroy(&ads);
                return -1;
        }
 
@@ -926,6 +995,7 @@ static int net_ads_printer_publish(int argc, const char **argv)
        if (ads_count_replies(ads, res) == 0) {
                d_printf("Could not find machine account for server %s\n", 
                         servername);
+               ads_destroy(&ads);
                return -1;
        }
 
@@ -940,10 +1010,12 @@ static int net_ads_printer_publish(int argc, const char **argv)
         rc = ads_add_printer_entry(ads, prt_dn, mem_ctx, &mods);
         if (!ADS_ERR_OK(rc)) {
                 d_printf("ads_publish_printer: %s\n", ads_errstr(rc));
+               ads_destroy(&ads);
                 return -1;
         }
  
         d_printf("published printer\n");
+       ads_destroy(&ads);
  
        return 0;
 }
@@ -956,27 +1028,33 @@ static int net_ads_printer_remove(int argc, const char **argv)
        char *prt_dn;
        void *res = NULL;
 
-       if (!(ads = ads_startup())) return -1;
+       if (!(ads = ads_startup())) {
+               return -1;
+       }
 
-       if (argc < 1)
+       if (argc < 1) {
                return net_ads_printer_usage(argc, argv);
+       }
 
-       if (argc > 1)
+       if (argc > 1) {
                servername = argv[1];
-       else
+       } else {
                servername = global_myname();
+       }
 
        rc = ads_find_printer_on_server(ads, &res, argv[0], servername);
 
        if (!ADS_ERR_OK(rc)) {
                d_printf("ads_find_printer_on_server: %s\n", ads_errstr(rc));
                ads_msgfree(ads, res);
+               ads_destroy(&ads);
                return -1;
        }
 
        if (ads_count_replies(ads, res) == 0) {
                d_printf("Printer '%s' not found\n", argv[1]);
                ads_msgfree(ads, res);
+               ads_destroy(&ads);
                return -1;
        }
 
@@ -987,9 +1065,11 @@ static int net_ads_printer_remove(int argc, const char **argv)
 
        if (!ADS_ERR_OK(rc)) {
                d_printf("ads_del_dn: %s\n", ads_errstr(rc));
+               ads_destroy(&ads);
                return -1;
        }
 
+       ads_destroy(&ads);
        return 0;
 }
 
@@ -1172,6 +1252,7 @@ static int net_ads_search(int argc, const char **argv)
                               ldap_exp, attrs, &res);
        if (!ADS_ERR_OK(rc)) {
                d_printf("search failed: %s\n", ads_errstr(rc));
+               ads_destroy(&ads);
                return -1;
        }       
 
@@ -1231,6 +1312,7 @@ static int net_ads_dn(int argc, const char **argv)
                               "(objectclass=*)", attrs, &res);
        if (!ADS_ERR_OK(rc)) {
                d_printf("search failed: %s\n", ads_errstr(rc));
+               ads_destroy(&ads);
                return -1;
        }