From: Pavel Filipenský Date: Sun, 18 Jan 2026 00:04:11 +0000 (+0100) Subject: s3:libads: Separate use of ads->config.flags for NBT_* and DS_* values X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7483903575eab97773a992149d64511d5ec6f256;p=thirdparty%2Fsamba.git s3:libads: Separate use of ads->config.flags for NBT_* and DS_* values Use of ads->config.flags is overloaded. It is used to: - pass DS_* flags down to cldap_netlogon() - store the server_type from NETLOGON_SAM_LOGON_RESPONSE Both cases use different values and cannot be combined. E.g. flags mess up with value 0x00000080 NBT_SERVER_CLOSEST 0x00000080 DS_PDC_REQUIRED 0x00000080 Let's create two separate flags nbt_server_type server_flags; /* NBT_* cldap flags identifying the services. */ uint32 required_flags; /* DS_* - Netlogon flags */ BUG: https://bugzilla.samba.org/show_bug.cgi?id=15972 Signed-off-by: Pavel Filipenský Reviewed-by: Andreas Schneider Autobuild-User(master): Pavel Filipensky Autobuild-Date(master): Thu Jan 22 09:14:25 UTC 2026 on atb-devel-224 --- diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 92397213bdb..cc1715d151d 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -237,7 +237,7 @@ bool ads_sitename_match(ADS_STRUCT *ads) bool ads_closest_dc(ADS_STRUCT *ads) { - if (ads->config.flags & NBT_SERVER_CLOSEST) { + if (ads->config.server_flags & NBT_SERVER_CLOSEST) { DEBUG(10,("ads_closest_dc: NBT_SERVER_CLOSEST flag set\n")); return True; } @@ -344,7 +344,7 @@ static bool ads_fill_cldap_reply(ADS_STRUCT *ads, sitename_store(cldap_reply->dns_domain, cldap_reply->client_site); /* Leave this until last so that the flags are not clobbered */ - ads->config.flags = cldap_reply->server_type; + ads->config.server_flags = cldap_reply->server_type; ret = true; @@ -379,7 +379,8 @@ static bool ads_try_connect(ADS_STRUCT *ads, bool gc, ok = ads_cldap_netlogon_5(frame, ss, ads->server.realm, - ads->config.flags | DS_ONLY_LDAP_NEEDED, + ads->config.required_flags | + DS_ONLY_LDAP_NEEDED, &cldap_reply); if (!ok) { DBG_NOTICE("ads_cldap_netlogon_5(%s, %s) failed.\n", @@ -491,20 +492,21 @@ again: return status; } - status = netlogon_pings(frame, /* mem_ctx */ - lp_client_netlogon_ping_protocol(), /* proto */ - ts_list, /* servers */ - num_requests, /* num_servers */ - (struct netlogon_ping_filter){ - .ntversion = nt_version, - .domain = ads->server.realm, - .acct_ctrl = -1, - .required_flags = ads->config.flags | - DS_ONLY_LDAP_NEEDED, - }, - 1, /* wanted_servers */ - endtime, /* timeout */ - &responses); + status = netlogon_pings( + frame, /* mem_ctx */ + lp_client_netlogon_ping_protocol(), /* proto */ + ts_list, /* servers */ + num_requests, /* num_servers */ + (struct netlogon_ping_filter){ + .ntversion = nt_version, + .domain = ads->server.realm, + .acct_ctrl = -1, + .required_flags = ads->config.required_flags | + DS_ONLY_LDAP_NEEDED, + }, + 1, /* wanted_servers */ + endtime, /* timeout */ + &responses); if (!NT_STATUS_IS_OK(status)) { DBG_WARNING("netlogon_pings(realm=%s, num_requests=%zu) " "for count[%zu] - %s\n", @@ -1265,7 +1267,7 @@ void ads_disconnect(ADS_STRUCT *ads) if (ads->ldap_wrap_data.mem_ctx) { talloc_free(ads->ldap_wrap_data.mem_ctx); } - ads->config.flags = 0; + ads->config.server_flags = 0; ads_zero_ldap(ads); ZERO_STRUCT(ads->ldap_tls_data); ZERO_STRUCT(ads->ldap_wrap_data); @@ -3732,10 +3734,10 @@ ADS_STATUS ads_current_time(ADS_STRUCT *ads) } /* - * Reset ads->config.flags as it can contain the flags + * Reset flags as it can contain the flags * returned by the previous CLDAP ping when reusing the struct. */ - ads_s->config.flags = 0; + ads_s->config.server_flags = 0; status = ads_connect_simple_anon(ads_s); if ( !ADS_ERR_OK(status)) @@ -3821,10 +3823,10 @@ ADS_STATUS ads_domain_func_level(ADS_STRUCT *ads, uint32_t *val) } /* - * Reset ads->config.flags as it can contain the flags + * Reset flags as it can contain the flags * returned by the previous CLDAP ping when reusing the struct. */ - ads_s->config.flags = 0; + ads_s->config.server_flags = 0; status = ads_connect_simple_anon(ads_s); if ( !ADS_ERR_OK(status)) diff --git a/source3/librpc/idl/ads.idl b/source3/librpc/idl/ads.idl index 381447a1a29..20941e90346 100644 --- a/source3/librpc/idl/ads.idl +++ b/source3/librpc/idl/ads.idl @@ -6,6 +6,7 @@ */ import "nbt.idl"; +import "netlogon.idl"; cpp_quote("#include ") @@ -51,7 +52,8 @@ interface ads } ads_auth; typedef [nopull,nopush] struct { - nbt_server_type flags; /* cldap flags identifying the services. */ + nbt_server_type server_flags; /* NBT_* cldap flags identifying the services. */ + netr_DsRGetDCName_flags required_flags; /* DS_* - Netlogon flags */ string workgroup; string realm; string bind_path; diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index 83236e3474c..b7b12ecb6f6 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -109,7 +109,9 @@ static bool ads_dc_name(const char *domain, } #ifdef HAVE_ADS - if (is_our_primary_domain(domain) && (ads->config.flags & NBT_SERVER_KDC)) { + if (is_our_primary_domain(domain) && + (ads->config.server_flags & NBT_SERVER_KDC)) + { if (ads_closest_dc(ads)) { /* We're going to use this KDC for this realm/domain. If we are using sites, then force the krb5 libs diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index d3b48a74131..e49c72dc332 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -1053,7 +1053,7 @@ static bool dcip_check_name_ads(const struct winbindd_domain *domain, ads_status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY); goto out; } - ads->config.flags |= request_flags; + ads->config.required_flags |= request_flags; ads->server.no_fallback = true; ads_status = ads_connect_cldap_only(ads); @@ -1069,9 +1069,9 @@ static bool dcip_check_name_ads(const struct winbindd_domain *domain, } namecache_store(name, 0x20, 1, sa); - DBG_DEBUG("CLDAP flags = 0x%"PRIx32"\n", ads->config.flags); + DBG_DEBUG("CLDAP flags = 0x%" PRIx32 "\n", ads->config.server_flags); - if (domain->primary && (ads->config.flags & NBT_SERVER_KDC)) { + if (domain->primary && (ads->config.server_flags & NBT_SERVER_KDC)) { if (ads_closest_dc(ads)) { char *sitename = sitename_fetch(tmp_ctx, ads->config.realm);