]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:libads: Set dns_lookup_kdc=false during net ads join
authorPavel Filipenský <pfilipensky@samba.org>
Mon, 23 Mar 2026 18:05:31 +0000 (19:05 +0100)
committerPavel Filipensky <pfilipensky@samba.org>
Tue, 7 Apr 2026 14:09:40 +0000 (14:09 +0000)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15999

Signed-off-by: Pavel Filipenský <pfilipensky@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Autobuild-User(master): Pavel Filipensky <pfilipensky@samba.org>
Autobuild-Date(master): Tue Apr  7 14:09:40 UTC 2026 on atb-devel-224

source3/libnet/libnet_join.c

index 66d682a5b9524842763f92f2b3108e01a3cc707a..81bcb9793a6572d47676a30e5e1cced8b1176430 100644 (file)
@@ -2881,6 +2881,10 @@ WERROR libnet_Join(TALLOC_CTX *mem_ctx,
                   struct libnet_JoinCtx *r)
 {
        WERROR werr;
+#ifdef HAVE_ADS
+       struct sockaddr_storage dc_ss = {0};
+       bool dns_lookup_kdc_disabled = false;
+#endif /* HAVE_ADS */
 
        if (r->in.debug) {
                LIBNET_JOIN_IN_DUMP_CTX(mem_ctx, r);
@@ -2904,6 +2908,49 @@ WERROR libnet_Join(TALLOC_CTX *mem_ctx,
                }
        }
 
+#ifdef HAVE_ADS
+       /*
+        * The machine account was just created on r->in.dc_name,
+        * but might not have replicated to other DCs yet.
+        * Regenerate the krb5.conf with dns_lookup_kdc = false
+        * so that the Kerberos library only talks to the DC
+        * where the account was created. This covers all
+        * subsequent machine-credential operations:
+        *   - libnet_join_post_processing_ads_modify() (etype update)
+        *   - libnet_join_post_verify() (domain membership verification)
+        */
+       if (r->out.domain_is_ad &&
+           !(r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_UNSECURE) &&
+           !r->in.request_offline_join)
+       {
+               bool ok;
+               const char *ip = NULL;
+
+               /* dcinfo might not be set for offline joins, however this
+                * check is redundant since we have a guard:
+                * !r->in.request_offline_join
+                */
+               if (r->out.dcinfo) {
+                       ip = r->out.dcinfo->dc_address + 2; /* Strip "\\" */
+               }
+
+               if (ip && ip[0] != '\0') {
+                       ok = interpret_string_addr(&dc_ss, ip, AI_NUMERICHOST);
+               } else {
+                       ok = interpret_string_addr(&dc_ss, r->in.dc_name, 0);
+               }
+
+               if (ok) {
+                       create_local_private_krb5_conf_for_domain_join(
+                               r->out.dns_domain_name,
+                               r->out.netbios_domain_name,
+                               NULL, /* sitename */
+                               &dc_ss);
+                       dns_lookup_kdc_disabled = true;
+               }
+       }
+#endif /* HAVE_ADS */
+
        werr = libnet_join_post_processing(mem_ctx, r);
        if (!W_ERROR_IS_OK(werr)) {
                goto done;
@@ -2931,7 +2978,18 @@ WERROR libnet_Join(TALLOC_CTX *mem_ctx,
                }
        }
 
- done:
+done:
+#ifdef HAVE_ADS
+       if (dns_lookup_kdc_disabled) {
+               /* Restore dns_lookup_kdc = true for subsequent operations */
+               create_local_private_krb5_conf_for_domain(
+                       r->out.dns_domain_name,
+                       r->out.netbios_domain_name,
+                       NULL, /* sitename */
+                       &dc_ss);
+       }
+#endif /* HAVE_ADS */
+
        r->out.result = werr;
 
        if (r->in.debug) {