packaging: Add missing quotes in smbprint
[samba.git] / source3 / libads / kerberos.c
index 52a5ac9b5e6867144e280543e65bdb862fd0fc95..72ce5b7bb348d78b83681a7f0eed6e0c8caeb3bf 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
    kerberos utility library
    Copyright (C) Andrew Tridgell 2001
 
 #ifdef HAVE_KRB5
 
-#define LIBADS_CCACHE_NAME "MEMORY:libads"
-
 /*
-  we use a prompter to avoid a crash bug in the kerberos libs when 
+  we use a prompter to avoid a crash bug in the kerberos libs when
   dealing with empty passwords
   this prompter is just a string copy ...
 */
-static krb5_error_code 
+static krb5_error_code
 kerb_prompter(krb5_context ctx, void *data,
               const char *name,
               const char *banner,
@@ -64,13 +62,13 @@ kerb_prompter(krb5_context ctx, void *data,
                     prompts[1].type == KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN) {
                        /*
                         * We don't want to change passwords here. We're
-                        * called from heimal when the KDC returns
+                        * called from heimdal when the KDC returns
                         * KRB5KDC_ERR_KEY_EXPIRED, but at this point we don't
                         * have the chance to ask the user for a new
                         * password. If we return 0 (i.e. success), we will be
                         * spinning in the endless for-loop in
                         * change_password() in
-                        * source4/heimdal/lib/krb5/init_creds_pw.c:526ff
+                        * third_party/heimdal/lib/krb5/init_creds_pw.c
                         */
                        return KRB5KDC_ERR_KEY_EXPIRED;
                }
@@ -133,6 +131,14 @@ int kerberos_kinit_password_ext(const char *given_principal,
 
        ZERO_STRUCT(my_creds);
 
+       if (cache_name == NULL) {
+               DBG_DEBUG("Missing ccache for [%s] and config [%s]\n",
+                         given_principal,
+                         getenv("KRB5_CONFIG"));
+               TALLOC_FREE(frame);
+               return EINVAL;
+       }
+
        code = smb_krb5_init_context_common(&ctx);
        if (code != 0) {
                DBG_ERR("kerberos init context failed (%s)\n",
@@ -147,10 +153,10 @@ int kerberos_kinit_password_ext(const char *given_principal,
 
        DBG_DEBUG("as %s using [%s] as ccache and config [%s]\n",
                  given_principal,
-                 cache_name ? cache_name: krb5_cc_default_name(ctx),
+                 cache_name,
                  getenv("KRB5_CONFIG"));
 
-       if ((code = krb5_cc_resolve(ctx, cache_name ? cache_name : krb5_cc_default_name(ctx), &cc))) {
+       if ((code = krb5_cc_resolve(ctx, cache_name, &cc))) {
                goto out;
        }
 
@@ -192,7 +198,7 @@ int kerberos_kinit_password_ext(const char *given_principal,
                krb5_get_init_creds_opt_set_address_list(opt, addr->addrs);
        }
 
-       if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, discard_const_p(char,password), 
+       if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, discard_const_p(char,password),
                                                 kerb_prompter, discard_const_p(char, password),
                                                 0, NULL, opt))) {
                goto out;
@@ -284,23 +290,25 @@ int ads_kdestroy(const char *cc_name)
                return code;
        }
 
-       if (!cc_name) {
-               if ((code = krb5_cc_default(ctx, &cc))) {
-                       krb5_free_context(ctx);
-                       return code;
-               }
-       } else {
-               if ((code = krb5_cc_resolve(ctx, cc_name, &cc))) {
-                       DEBUG(3, ("ads_kdestroy: krb5_cc_resolve failed: %s\n",
-                                 error_message(code)));
-                       krb5_free_context(ctx);
-                       return code;
-               }
+       /*
+        * This should not happen, if
+        * we need that behaviour we
+        * should add an ads_kdestroy_default()
+        */
+       SMB_ASSERT(cc_name != NULL);
+
+       code = krb5_cc_resolve(ctx, cc_name, &cc);
+       if (code != 0) {
+               DBG_NOTICE("krb5_cc_resolve(%s) failed: %s\n",
+                          cc_name, error_message(code));
+               krb5_free_context(ctx);
+               return code;
        }
 
-       if ((code = krb5_cc_destroy (ctx, cc))) {
-               DEBUG(3, ("ads_kdestroy: krb5_cc_destroy failed: %s\n", 
-                       error_message(code)));
+       code = krb5_cc_destroy(ctx, cc);
+       if (code != 0) {
+               DBG_ERR("krb5_cc_destroy(%s) failed: %s\n",
+                       cc_name, error_message(code));
        }
 
        krb5_free_context (ctx);
@@ -348,10 +356,10 @@ int kerberos_kinit_password(const char *principal,
                            int time_offset,
                            const char *cache_name)
 {
-       return kerberos_kinit_password_ext(principal, 
-                                          password, 
-                                          time_offset, 
-                                          0, 
+       return kerberos_kinit_password_ext(principal,
+                                          password,
+                                          time_offset,
+                                          0,
                                           0,
                                           cache_name,
                                           False,
@@ -434,18 +442,26 @@ static char *get_kdc_ip_string(char *mem_ctx,
        struct netlogon_samlogon_response **responses = NULL;
        NTSTATUS status;
        bool ok;
-       char *kdc_str = talloc_asprintf(mem_ctx, "%s\t\tkdc = %s\n", "",
-                                       print_canonical_sockaddr_with_port(mem_ctx, pss));
+       char *kdc_str = NULL;
+       char *canon_sockaddr = NULL;
 
-       if (kdc_str == NULL) {
-               TALLOC_FREE(frame);
-               return NULL;
-       }
+       if (pss != NULL) {
+               canon_sockaddr = print_canonical_sockaddr_with_port(frame, pss);
+               if (canon_sockaddr == NULL) {
+                       goto out;
+               }
 
-       ok = sockaddr_storage_to_samba_sockaddr(&sa, pss);
-       if (!ok) {
-               TALLOC_FREE(kdc_str);
-               goto out;
+               kdc_str = talloc_asprintf(frame,
+                                         "\t\tkdc = %s\n",
+                                         canon_sockaddr);
+               if (kdc_str == NULL) {
+                       goto out;
+               }
+
+               ok = sockaddr_storage_to_samba_sockaddr(&sa, pss);
+               if (!ok) {
+                       goto out;
+               }
        }
 
        /*
@@ -454,7 +470,7 @@ static char *get_kdc_ip_string(char *mem_ctx,
         */
 
        if (sitename) {
-               status = get_kdc_list(talloc_tos(),
+               status = get_kdc_list(frame,
                                        realm,
                                        sitename,
                                        &ip_sa_site,
@@ -462,7 +478,6 @@ static char *get_kdc_ip_string(char *mem_ctx,
                if (!NT_STATUS_IS_OK(status)) {
                        DBG_ERR("get_kdc_list fail %s\n",
                                nt_errstr(status));
-                       TALLOC_FREE(kdc_str);
                        goto out;
                }
                DBG_DEBUG("got %zu addresses from site %s search\n",
@@ -472,7 +487,7 @@ static char *get_kdc_ip_string(char *mem_ctx,
 
        /* Get all KDC's. */
 
-       status = get_kdc_list(talloc_tos(),
+       status = get_kdc_list(frame,
                                        realm,
                                        NULL,
                                        &ip_sa_nonsite,
@@ -480,7 +495,6 @@ static char *get_kdc_ip_string(char *mem_ctx,
        if (!NT_STATUS_IS_OK(status)) {
                DBG_ERR("get_kdc_list (site-less) fail %s\n",
                        nt_errstr(status));
-               TALLOC_FREE(kdc_str);
                goto out;
        }
        DBG_DEBUG("got %zu addresses from site-less search\n", count_nonsite);
@@ -488,7 +502,6 @@ static char *get_kdc_ip_string(char *mem_ctx,
        if (count_site + count_nonsite < count_site) {
                /* Wrap check. */
                DBG_ERR("get_kdc_list_talloc (site-less) fail wrap error\n");
-               TALLOC_FREE(kdc_str);
                goto out;
        }
 
@@ -496,7 +509,6 @@ static char *get_kdc_ip_string(char *mem_ctx,
        dc_addrs = talloc_array(talloc_tos(), struct sockaddr_storage,
                                count_site + count_nonsite);
        if (dc_addrs == NULL) {
-               TALLOC_FREE(kdc_str);
                goto out;
        }
 
@@ -516,17 +528,20 @@ static char *get_kdc_ip_string(char *mem_ctx,
                }
        }
 
-       dc_addrs2 = talloc_zero_array(talloc_tos(),
-                                     struct tsocket_address *,
-                                     num_dcs);
-
        DBG_DEBUG("%zu additional KDCs to test\n", num_dcs);
        if (num_dcs == 0) {
-               TALLOC_FREE(kdc_str);
+               /*
+                * We do not have additional KDCs, but we have the one passed
+                * in via `pss`. So just use that one and leave.
+                */
+               result = talloc_move(mem_ctx, &kdc_str);
                goto out;
        }
+
+       dc_addrs2 = talloc_zero_array(talloc_tos(),
+                                     struct tsocket_address *,
+                                     num_dcs);
        if (dc_addrs2 == NULL) {
-               TALLOC_FREE(kdc_str);
                goto out;
        }
 
@@ -543,7 +558,6 @@ static char *get_kdc_ip_string(char *mem_ctx,
                        status = map_nt_error_from_unix(errno);
                        DEBUG(2,("Failed to create tsocket_address for %s - %s\n",
                                 addr, nt_errstr(status)));
-                       TALLOC_FREE(kdc_str);
                        goto out;
                }
        }
@@ -561,7 +575,6 @@ static char *get_kdc_ip_string(char *mem_ctx,
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(10,("get_kdc_ip_string: cldap_multi_netlogon failed: "
                          "%s\n", nt_errstr(status)));
-               TALLOC_FREE(kdc_str);
                goto out;
        }
 
@@ -573,22 +586,25 @@ static char *get_kdc_ip_string(char *mem_ctx,
                }
 
                /* Append to the string - inefficient but not done often. */
-               new_kdc_str = talloc_asprintf(mem_ctx, "%s\t\tkdc = %s\n",
-                                             kdc_str,
-                                             print_canonical_sockaddr_with_port(mem_ctx, &dc_addrs[i]));
-               TALLOC_FREE(kdc_str);
+               new_kdc_str = talloc_asprintf_append(
+                               kdc_str,
+                               "\t\tkdc = %s\n",
+                               print_canonical_sockaddr_with_port(
+                                       mem_ctx, &dc_addrs[i]));
                if (new_kdc_str == NULL) {
                        goto out;
                }
                kdc_str = new_kdc_str;
        }
 
-       result = kdc_str;
+       result = talloc_move(mem_ctx, &kdc_str);
 out:
-       DBG_DEBUG("Returning\n%s\n", kdc_str);
+       if (result != NULL) {
+               DBG_DEBUG("Returning\n%s\n", result);
+       } else {
+               DBG_NOTICE("Failed to get KDC ip address\n");
+       }
 
-       TALLOC_FREE(ip_sa_site);
-       TALLOC_FREE(ip_sa_nonsite);
        TALLOC_FREE(frame);
        return result;
 }
@@ -614,20 +630,16 @@ static char *get_enctypes(TALLOC_CTX *mem_ctx)
 
        if (lp_kerberos_encryption_types() == KERBEROS_ETYPES_ALL ||
            lp_kerberos_encryption_types() == KERBEROS_ETYPES_STRONG) {
-#ifdef HAVE_ENCTYPE_AES256_CTS_HMAC_SHA1_96
                aes_enctypes = talloc_asprintf_append(
                    aes_enctypes, "%s", "aes256-cts-hmac-sha1-96 ");
                if (aes_enctypes == NULL) {
                        goto done;
                }
-#endif
-#ifdef HAVE_ENCTYPE_AES128_CTS_HMAC_SHA1_96
                aes_enctypes = talloc_asprintf_append(
                    aes_enctypes, "%s", "aes128-cts-hmac-sha1-96");
                if (aes_enctypes == NULL) {
                        goto done;
                }
-#endif
        }
 
        if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_ALLOWED &&
@@ -661,7 +673,7 @@ static char *get_enctypes(TALLOC_CTX *mem_ctx)
 
        if (lp_kerberos_encryption_types() == KERBEROS_ETYPES_ALL ||
            lp_kerberos_encryption_types() == KERBEROS_ETYPES_LEGACY) {
-               legacy_enctypes = "arcfour-hmac-md5 des-cbc-crc des-cbc-md5";
+               legacy_enctypes = "arcfour-hmac-md5";
        }
 
        enctypes = talloc_asprintf(mem_ctx, "\tdefault_etypes = %s %s\n",
@@ -700,7 +712,7 @@ bool create_local_private_krb5_conf_for_domain(const char *realm,
                return false;
        }
 
-       if (domain == NULL || pss == NULL) {
+       if (domain == NULL) {
                return false;
        }
 
@@ -785,9 +797,9 @@ bool create_local_private_krb5_conf_for_domain(const char *realm,
        fd = mkstemp(tmpname);
        umask(mask);
        if (fd == -1) {
-               DEBUG(0,("create_local_private_krb5_conf_for_domain: smb_mkstemp failed,"
-                       " for file %s. Errno %s\n",
-                       tmpname, strerror(errno) ));
+               DBG_ERR("mkstemp failed, for file %s. Errno %s\n",
+                       tmpname,
+                       strerror(errno));
                goto done;
        }
 
@@ -824,9 +836,8 @@ bool create_local_private_krb5_conf_for_domain(const char *realm,
                goto done;
        }
 
-       DEBUG(5,("create_local_private_krb5_conf_for_domain: wrote "
-               "file %s with realm %s KDC list = %s\n",
-               fname, realm_upper, kdc_ip_string));
+       DBG_INFO("wrote file %s with realm %s KDC list:\n%s\n",
+                fname, realm_upper, kdc_ip_string);
 
        /* Set the environment variable to this file. */
        setenv("KRB5_CONFIG", fname, 1);
@@ -877,7 +888,7 @@ bool create_local_private_krb5_conf_for_domain(const char *realm,
                                goto done; /* Not a fatal error. */
                        }
 
-                       /* Yes, this is a race conditon... too bad. */
+                       /* Yes, this is a race condition... too bad. */
                        if (rename(SYSTEM_KRB5_CONF_PATH, newpath) == -1) {
                                DEBUG(0,("create_local_private_krb5_conf_for_domain: rename "
                                        "of %s to %s failed. Errno %s\n",