--- /dev/null
+From 918ac8f0ed19aeaa4718fa94fcabe87d0419d768 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
+Date: Mon, 13 Jan 2014 15:59:26 +0100
+Subject: [PATCH 1/5] PATCHSET11: s3-kerberos: remove print_kdc_line()
+ completely.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Just calling print_canonical_sockaddr() is sufficient, as it already deals with
+ipv6 as well. The port handling, which was only done for IPv6 (not IPv4), is
+removed as well. It was pointless because it always derived the port number from
+the provided address which was either a SMB (usually port 445) or LDAP
+connection. No KDC will ever run on port 389 or 445 on a Windows/Samba DC.
+Finally, the kerberos libraries that we support and build with, can deal with
+ipv6 addresses in krb5.conf, so we no longer put the (unnecessary) burden of
+resolving the DC name on the kerberos library anymore.
+
+Guenther
+
+Signed-off-by: Günther Deschner <gd@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+
+Conflicts:
+ source3/libads/kerberos.c
+---
+ source3/libads/kerberos.c | 86 +++++------------------------------------------
+ 1 file changed, 9 insertions(+), 77 deletions(-)
+
+diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
+index 1153ccb..064e5f7 100644
+--- a/source3/libads/kerberos.c
++++ b/source3/libads/kerberos.c
+@@ -661,73 +661,6 @@ int kerberos_kinit_password(const char *principal,
+ }
+
+ /************************************************************************
+-************************************************************************/
+-
+-static char *print_kdc_line(char *mem_ctx,
+- const char *prev_line,
+- const struct sockaddr_storage *pss,
+- const char *kdc_name)
+-{
+- char *kdc_str = NULL;
+-
+- if (pss->ss_family == AF_INET) {
+- kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n",
+- prev_line,
+- print_canonical_sockaddr(mem_ctx, pss));
+- } else {
+- char addr[INET6_ADDRSTRLEN];
+- uint16_t port = get_sockaddr_port(pss);
+-
+- DEBUG(10,("print_kdc_line: IPv6 case for kdc_name: %s, port: %d\n",
+- kdc_name, port));
+-
+- if (port != 0 && port != DEFAULT_KRB5_PORT) {
+- /* Currently for IPv6 we can't specify a non-default
+- krb5 port with an address, as this requires a ':'.
+- Resolve to a name. */
+- char hostname[MAX_DNS_NAME_LENGTH];
+- int ret = sys_getnameinfo((const struct sockaddr *)pss,
+- sizeof(*pss),
+- hostname, sizeof(hostname),
+- NULL, 0,
+- NI_NAMEREQD);
+- if (ret) {
+- DEBUG(0,("print_kdc_line: can't resolve name "
+- "for kdc with non-default port %s. "
+- "Error %s\n.",
+- print_canonical_sockaddr(mem_ctx, pss),
+- gai_strerror(ret)));
+- return NULL;
+- }
+- /* Success, use host:port */
+- kdc_str = talloc_asprintf(mem_ctx,
+- "%s\tkdc = %s:%u\n",
+- prev_line,
+- hostname,
+- (unsigned int)port);
+- } else {
+-
+- /* no krb5 lib currently supports "kdc = ipv6 address"
+- * at all, so just fill in just the kdc_name if we have
+- * it and let the krb5 lib figure out the appropriate
+- * ipv6 address - gd */
+-
+- if (kdc_name) {
+- kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n",
+- prev_line, kdc_name);
+- } else {
+- kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n",
+- prev_line,
+- print_sockaddr(addr,
+- sizeof(addr),
+- pss));
+- }
+- }
+- }
+- return kdc_str;
+-}
+-
+-/************************************************************************
+ Create a string list of available kdc's, possibly searching by sitename.
+ Does DNS queries.
+
+@@ -746,7 +679,8 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ struct ip_service *ip_srv_nonsite = NULL;
+ int count_site = 0;
+ int count_nonsite;
+- char *kdc_str = print_kdc_line(mem_ctx, "", pss, kdc_name);
++ char *kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", "",
++ print_canonical_sockaddr(mem_ctx, pss));
+
+ if (kdc_str == NULL) {
+ return NULL;
+@@ -768,10 +702,9 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ }
+ /* Append to the string - inefficient
+ * but not done often. */
+- kdc_str = print_kdc_line(mem_ctx,
+- kdc_str,
+- &ip_srv_site[i].ss,
+- NULL);
++ kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n",
++ kdc_str,
++ print_canonical_sockaddr(mem_ctx, &ip_srv_site[i].ss));
+ if (!kdc_str) {
+ SAFE_FREE(ip_srv_site);
+ return NULL;
+@@ -806,11 +739,10 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ }
+
+ /* Append to the string - inefficient but not done often. */
+- kdc_str = print_kdc_line(mem_ctx,
+- kdc_str,
+- &ip_srv_nonsite[i].ss,
+- NULL);
+- if (!kdc_str) {
++ kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n",
++ kdc_str,
++ print_canonical_sockaddr(mem_ctx, &ip_srv_nonsite[i].ss));
++ if (kdc_str == NULL) {
+ SAFE_FREE(ip_srv_site);
+ SAFE_FREE(ip_srv_nonsite);
+ return NULL;
+--
+1.9.0
+
+
+From b4eba7d838b60230b9f6c9a08ef0ddc00e3e47f0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
+Date: Fri, 7 Mar 2014 14:47:31 +0100
+Subject: [PATCH 2/5] PATCHSET11: s3-kerberos: remove unused kdc_name from
+ create_local_private_krb5_conf_for_domain().
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Guenther
+
+Signed-off-by: Günther Deschner <gd@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+
+Autobuild-User(master): Günther Deschner <gd@samba.org>
+Autobuild-Date(master): Fri Mar 7 18:43:57 CET 2014 on sn-devel-104
+
+Conflicts:
+ source3/libads/kerberos.c
+ source3/libads/kerberos_proto.h
+ source3/libnet/libnet_join.c
+ source3/winbindd/winbindd_cm.c
+---
+ source3/libads/kerberos.c | 10 ++++------
+ source3/libads/kerberos_proto.h | 3 +--
+ source3/libnet/libnet_join.c | 2 +-
+ source3/libsmb/namequery_dc.c | 6 ++----
+ source3/winbindd/winbindd_cm.c | 6 ++----
+ 5 files changed, 10 insertions(+), 17 deletions(-)
+
+diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
+index 064e5f7..b826cb3 100644
+--- a/source3/libads/kerberos.c
++++ b/source3/libads/kerberos.c
+@@ -671,8 +671,7 @@ int kerberos_kinit_password(const char *principal,
+ static char *get_kdc_ip_string(char *mem_ctx,
+ const char *realm,
+ const char *sitename,
+- struct sockaddr_storage *pss,
+- const char *kdc_name)
++ struct sockaddr_storage *pss)
+ {
+ int i;
+ struct ip_service *ip_srv_site = NULL;
+@@ -769,8 +768,7 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ bool create_local_private_krb5_conf_for_domain(const char *realm,
+ const char *domain,
+ const char *sitename,
+- struct sockaddr_storage *pss,
+- const char *kdc_name)
++ struct sockaddr_storage *pss)
+ {
+ char *dname;
+ char *tmpname = NULL;
+@@ -794,7 +792,7 @@ bool create_local_private_krb5_conf_for_domain(const char *realm,
+ return false;
+ }
+
+- if (domain == NULL || pss == NULL || kdc_name == NULL) {
++ if (domain == NULL || pss == NULL) {
+ return false;
+ }
+
+@@ -825,7 +823,7 @@ bool create_local_private_krb5_conf_for_domain(const char *realm,
+ realm_upper = talloc_strdup(fname, realm);
+ strupper_m(realm_upper);
+
+- kdc_ip_string = get_kdc_ip_string(dname, realm, sitename, pss, kdc_name);
++ kdc_ip_string = get_kdc_ip_string(dname, realm, sitename, pss);
+ if (!kdc_ip_string) {
+ goto done;
+ }
+diff --git a/source3/libads/kerberos_proto.h b/source3/libads/kerberos_proto.h
+index 406669cc..90d7cd9 100644
+--- a/source3/libads/kerberos_proto.h
++++ b/source3/libads/kerberos_proto.h
+@@ -75,8 +75,7 @@ int kerberos_kinit_password(const char *principal,
+ bool create_local_private_krb5_conf_for_domain(const char *realm,
+ const char *domain,
+ const char *sitename,
+- struct sockaddr_storage *pss,
+- const char *kdc_name);
++ struct sockaddr_storage *pss);
+
+ /* The following definitions come from libads/authdata.c */
+
+diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
+index e84682d..f1736ec 100644
+--- a/source3/libnet/libnet_join.c
++++ b/source3/libnet/libnet_join.c
+@@ -1985,7 +1985,7 @@ static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx,
+
+ create_local_private_krb5_conf_for_domain(
+ r->out.dns_domain_name, r->out.netbios_domain_name,
+- NULL, &cli->dest_ss, cli->desthost);
++ NULL, &cli->dest_ss);
+
+ if (r->out.domain_is_ad && r->in.account_ou &&
+ !(r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_UNSECURE)) {
+diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c
+index 39b780c..149121a 100644
+--- a/source3/libsmb/namequery_dc.c
++++ b/source3/libsmb/namequery_dc.c
+@@ -111,14 +111,12 @@ static bool ads_dc_name(const char *domain,
+ create_local_private_krb5_conf_for_domain(realm,
+ domain,
+ sitename,
+- &ads->ldap.ss,
+- ads->config.ldap_server_name);
++ &ads->ldap.ss);
+ } else {
+ create_local_private_krb5_conf_for_domain(realm,
+ domain,
+ NULL,
+- &ads->ldap.ss,
+- ads->config.ldap_server_name);
++ &ads->ldap.ss);
+ }
+ }
+ #endif
+diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
+index 8271279..59f30a5 100644
+--- a/source3/winbindd/winbindd_cm.c
++++ b/source3/winbindd/winbindd_cm.c
+@@ -1226,8 +1226,7 @@ static bool dcip_to_name(TALLOC_CTX *mem_ctx,
+ create_local_private_krb5_conf_for_domain(domain->alt_name,
+ domain->name,
+ sitename,
+- pss,
+- name);
++ pss);
+
+ SAFE_FREE(sitename);
+ } else {
+@@ -1235,8 +1234,7 @@ static bool dcip_to_name(TALLOC_CTX *mem_ctx,
+ create_local_private_krb5_conf_for_domain(domain->alt_name,
+ domain->name,
+ NULL,
+- pss,
+- name);
++ pss);
+ }
+ winbindd_set_locator_kdc_envs(domain);
+
+--
+1.9.0
+
+
+From db840b57e81922cea984530e2dc1b42cc99e75de Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
+Date: Wed, 2 Apr 2014 19:37:34 +0200
+Subject: [PATCH 3/5] PATCHSET11: s3-kerberos: make ipv6 support for generated
+ krb5 config files more robust.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Older MIT Kerberos libraries will add any secondary ipv6 address as
+ipv4 address, defining the (default) krb5 port 88 circumvents that.
+
+Guenther
+
+Signed-off-by: Günther Deschner <gd@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+
+Autobuild-User(master): Günther Deschner <gd@samba.org>
+Autobuild-Date(master): Fri Apr 4 16:33:12 CEST 2014 on sn-devel-104
+
+Conflicts:
+ source3/libads/kerberos.c
+---
+ source3/libads/kerberos.c | 29 +++++++++++++++++++++++++++--
+ 1 file changed, 27 insertions(+), 2 deletions(-)
+
+diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
+index b826cb3..5e34aa3 100644
+--- a/source3/libads/kerberos.c
++++ b/source3/libads/kerberos.c
+@@ -668,6 +668,31 @@ int kerberos_kinit_password(const char *principal,
+
+ ************************************************************************/
+
++/* print_canonical_sockaddr prints an ipv6 addr in the form of
++* [ipv6.addr]. This string, when put in a generated krb5.conf file is not
++* always properly dealt with by some older krb5 libraries. Adding the hard-coded
++* portnumber workarounds the issue. - gd */
++
++static char *print_canonical_sockaddr_with_port(TALLOC_CTX *mem_ctx,
++ const struct sockaddr_storage *pss)
++{
++ char *str = NULL;
++
++ str = print_canonical_sockaddr(mem_ctx, pss);
++ if (str == NULL) {
++ return NULL;
++ }
++
++ if (pss->ss_family != AF_INET6) {
++ return str;
++ }
++
++#if defined(HAVE_IPV6)
++ str = talloc_asprintf_append(str, ":88");
++#endif
++ return str;
++}
++
+ static char *get_kdc_ip_string(char *mem_ctx,
+ const char *realm,
+ const char *sitename,
+@@ -679,7 +704,7 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ int count_site = 0;
+ int count_nonsite;
+ char *kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", "",
+- print_canonical_sockaddr(mem_ctx, pss));
++ print_canonical_sockaddr_with_port(mem_ctx, pss));
+
+ if (kdc_str == NULL) {
+ return NULL;
+@@ -740,7 +765,7 @@ static char *get_kdc_ip_string(char *mem_ctx,
+ /* Append to the string - inefficient but not done often. */
+ kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n",
+ kdc_str,
+- print_canonical_sockaddr(mem_ctx, &ip_srv_nonsite[i].ss));
++ print_canonical_sockaddr_with_port(mem_ctx, &ip_srv_nonsite[i].ss));
+ if (kdc_str == NULL) {
+ SAFE_FREE(ip_srv_site);
+ SAFE_FREE(ip_srv_nonsite);
+--
+1.9.0
+
+
+From 208f1d7b5ae557bf34a39c847aeb1925ce4cb171 Mon Sep 17 00:00:00 2001
+From: Andrew Bartlett <abartlet@samba.org>
+Date: Tue, 26 Apr 2011 17:03:32 +1000
+Subject: [PATCH 4/5] PATCHSET11: s3-libads Pass a struct sockaddr_storage to
+ cldap routines
+
+This avoids these routines doing a DNS lookup that has already been
+done, and ensures that the emulated DNS lookup isn't thrown away.
+
+Andrew Bartlett
+---
+ source3/libads/cldap.c | 14 ++++--------
+ source3/libads/cldap.h | 4 ++--
+ source3/libads/ldap.c | 41 ++++++++++-------------------------
+ source3/libsmb/dsgetdcname.c | 3 ++-
+ source3/utils/net_ads.c | 7 +++---
+ source3/winbindd/idmap_adex/gc_util.c | 12 +++++++++-
+ 6 files changed, 33 insertions(+), 48 deletions(-)
+
+diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c
+index 5d2e900..03fa17c 100644
+--- a/source3/libads/cldap.c
++++ b/source3/libads/cldap.c
+@@ -30,7 +30,7 @@
+ *******************************************************************/
+
+ bool ads_cldap_netlogon(TALLOC_CTX *mem_ctx,
+- const char *server,
++ struct sockaddr_storage *ss,
+ const char *realm,
+ uint32_t nt_version,
+ struct netlogon_samlogon_response **_reply)
+@@ -39,18 +39,12 @@ bool ads_cldap_netlogon(TALLOC_CTX *mem_ctx,
+ struct cldap_netlogon io;
+ struct netlogon_samlogon_response *reply;
+ NTSTATUS status;
+- struct sockaddr_storage ss;
+ char addrstr[INET6_ADDRSTRLEN];
+ const char *dest_str;
+ int ret;
+ struct tsocket_address *dest_addr;
+
+- if (!interpret_string_addr_prefer_ipv4(&ss, server, 0)) {
+- DEBUG(2,("Failed to resolve[%s] into an address for cldap\n",
+- server));
+- return false;
+- }
+- dest_str = print_sockaddr(addrstr, sizeof(addrstr), &ss);
++ dest_str = print_sockaddr(addrstr, sizeof(addrstr), ss);
+
+ ret = tsocket_address_inet_from_strings(mem_ctx, "ip",
+ dest_str, LDAP_PORT,
+@@ -113,7 +107,7 @@ failed:
+ *******************************************************************/
+
+ bool ads_cldap_netlogon_5(TALLOC_CTX *mem_ctx,
+- const char *server,
++ struct sockaddr_storage *ss,
+ const char *realm,
+ struct NETLOGON_SAM_LOGON_RESPONSE_EX *reply5)
+ {
+@@ -121,7 +115,7 @@ bool ads_cldap_netlogon_5(TALLOC_CTX *mem_ctx,
+ struct netlogon_samlogon_response *reply = NULL;
+ bool ret;
+
+- ret = ads_cldap_netlogon(mem_ctx, server, realm, nt_version, &reply);
++ ret = ads_cldap_netlogon(mem_ctx, ss, realm, nt_version, &reply);
+ if (!ret) {
+ return false;
+ }
+diff --git a/source3/libads/cldap.h b/source3/libads/cldap.h
+index d2ad4b0..60e1c56 100644
+--- a/source3/libads/cldap.h
++++ b/source3/libads/cldap.h
+@@ -27,12 +27,12 @@
+
+ /* The following definitions come from libads/cldap.c */
+ bool ads_cldap_netlogon(TALLOC_CTX *mem_ctx,
+- const char *server,
++ struct sockaddr_storage *ss,
+ const char *realm,
+ uint32_t nt_version,
+ struct netlogon_samlogon_response **reply);
+ bool ads_cldap_netlogon_5(TALLOC_CTX *mem_ctx,
+- const char *server,
++ struct sockaddr_storage *ss,
+ const char *realm,
+ struct NETLOGON_SAM_LOGON_RESPONSE_EX *reply5);
+
+diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
+index b841c84..0db0bcd 100644
+--- a/source3/libads/ldap.c
++++ b/source3/libads/ldap.c
+@@ -196,45 +196,32 @@ bool ads_closest_dc(ADS_STRUCT *ads)
+ */
+ static bool ads_try_connect(ADS_STRUCT *ads, const char *server, bool gc)
+ {
+- char *srv;
+ struct NETLOGON_SAM_LOGON_RESPONSE_EX cldap_reply;
+ TALLOC_CTX *frame = talloc_stackframe();
+ bool ret = false;
++ struct sockaddr_storage ss;
++ char addr[INET6_ADDRSTRLEN];
+
+ if (!server || !*server) {
+ TALLOC_FREE(frame);
+ return False;
+ }
+
+- if (!is_ipaddress(server)) {
+- struct sockaddr_storage ss;
+- char addr[INET6_ADDRSTRLEN];
+-
+- if (!resolve_name(server, &ss, 0x20, true)) {
+- DEBUG(5,("ads_try_connect: unable to resolve name %s\n",
+- server ));
+- TALLOC_FREE(frame);
+- return false;
+- }
+- print_sockaddr(addr, sizeof(addr), &ss);
+- srv = talloc_strdup(frame, addr);
+- } else {
+- /* this copes with inet_ntoa brokenness */
+- srv = talloc_strdup(frame, server);
+- }
+-
+- if (!srv) {
++ if (!resolve_name(server, &ss, 0x20, true)) {
++ DEBUG(5,("ads_try_connect: unable to resolve name %s\n",
++ server ));
+ TALLOC_FREE(frame);
+ return false;
+ }
++ print_sockaddr(addr, sizeof(addr), &ss);
+
+ DEBUG(5,("ads_try_connect: sending CLDAP request to %s (realm: %s)\n",
+- srv, ads->server.realm));
++ addr, ads->server.realm));
+
+ ZERO_STRUCT( cldap_reply );
+
+- if ( !ads_cldap_netlogon_5(frame, srv, ads->server.realm, &cldap_reply ) ) {
+- DEBUG(3,("ads_try_connect: CLDAP request %s failed.\n", srv));
++ if ( !ads_cldap_netlogon_5(frame, &ss, ads->server.realm, &cldap_reply ) ) {
++ DEBUG(3,("ads_try_connect: CLDAP request %s failed.\n", addr));
+ ret = false;
+ goto out;
+ }
+@@ -243,7 +230,7 @@ static bool ads_try_connect(ADS_STRUCT *ads, const char *server, bool gc)
+
+ if ( !(cldap_reply.server_type & NBT_SERVER_LDAP) ) {
+ DEBUG(1,("ads_try_connect: %s's CLDAP reply says it is not an LDAP server!\n",
+- srv));
++ addr));
+ ret = false;
+ goto out;
+ }
+@@ -273,13 +260,7 @@ static bool ads_try_connect(ADS_STRUCT *ads, const char *server, bool gc)
+ ads->server.workgroup = SMB_STRDUP(cldap_reply.domain_name);
+
+ ads->ldap.port = gc ? LDAP_GC_PORT : LDAP_PORT;
+- if (!interpret_string_addr(&ads->ldap.ss, srv, 0)) {
+- DEBUG(1,("ads_try_connect: unable to convert %s "
+- "to an address\n",
+- srv));
+- ret = false;
+- goto out;
+- }
++ ads->ldap.ss = ss;
+
+ /* Store our site name. */
+ sitename_store( cldap_reply.domain_name, cldap_reply.client_site);
+diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c
+index 841a179..2f8b8dc 100644
+--- a/source3/libsmb/dsgetdcname.c
++++ b/source3/libsmb/dsgetdcname.c
+@@ -863,9 +863,10 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx,
+
+ for (i=0; i<num_dcs; i++) {
+
++
+ DEBUG(10,("LDAP ping to %s\n", dclist[i].hostname));
+
+- if (ads_cldap_netlogon(mem_ctx, dclist[i].hostname,
++ if (ads_cldap_netlogon(mem_ctx, &dclist[i].ss,
+ domain_name,
+ nt_version,
+ &r))
+diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c
+index 8f8b7b4..816349d 100644
+--- a/source3/utils/net_ads.c
++++ b/source3/utils/net_ads.c
+@@ -62,7 +62,8 @@ static int net_ads_cldap_netlogon(struct net_context *c, ADS_STRUCT *ads)
+ struct NETLOGON_SAM_LOGON_RESPONSE_EX reply;
+
+ print_sockaddr(addr, sizeof(addr), &ads->ldap.ss);
+- if ( !ads_cldap_netlogon_5(talloc_tos(), addr, ads->server.realm, &reply ) ) {
++
++ if ( !ads_cldap_netlogon_5(talloc_tos(), &ads->ldap.ss, ads->server.realm, &reply ) ) {
+ d_fprintf(stderr, _("CLDAP query failed!\n"));
+ return -1;
+ }
+@@ -385,7 +386,6 @@ int net_ads_check(struct net_context *c)
+ static int net_ads_workgroup(struct net_context *c, int argc, const char **argv)
+ {
+ ADS_STRUCT *ads;
+- char addr[INET6_ADDRSTRLEN];
+ struct NETLOGON_SAM_LOGON_RESPONSE_EX reply;
+
+ if (c->display_usage) {
+@@ -407,8 +407,7 @@ static int net_ads_workgroup(struct net_context *c, int argc, const char **argv)
+ ads->ldap.port = 389;
+ }
+
+- print_sockaddr(addr, sizeof(addr), &ads->ldap.ss);
+- if ( !ads_cldap_netlogon_5(talloc_tos(), addr, ads->server.realm, &reply ) ) {
++ if ( !ads_cldap_netlogon_5(talloc_tos(), &ads->ldap.ss, ads->server.realm, &reply ) ) {
+ d_fprintf(stderr, _("CLDAP query failed!\n"));
+ ads_destroy(&ads);
+ return -1;
+diff --git a/source3/winbindd/idmap_adex/gc_util.c b/source3/winbindd/idmap_adex/gc_util.c
+index 77b318c..e625265 100644
+--- a/source3/winbindd/idmap_adex/gc_util.c
++++ b/source3/winbindd/idmap_adex/gc_util.c
+@@ -107,6 +107,7 @@ done:
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ struct NETLOGON_SAM_LOGON_RESPONSE_EX cldap_reply;
+ TALLOC_CTX *frame = talloc_stackframe();
++ struct sockaddr_storage ss;
+
+ if (!gc || !domain) {
+ return NT_STATUS_INVALID_PARAMETER;
+@@ -126,8 +127,17 @@ done:
+ nt_status = ads_ntstatus(ads_status);
+ BAIL_ON_NTSTATUS_ERROR(nt_status);
+
++ if (!resolve_name(ads->config.ldap_server_name, &ss, 0x20, true)) {
++ DEBUG(5,("gc_find_forest_root: unable to resolve name %s\n",
++ ads->config.ldap_server_name));
++ nt_status = NT_STATUS_IO_TIMEOUT;
++ /* This matches the old code which did the resolve in
++ * ads_cldap_netlogon_5 */
++ BAIL_ON_NTSTATUS_ERROR(nt_status);
++ }
++
+ if (!ads_cldap_netlogon_5(frame,
+- ads->config.ldap_server_name,
++ &ss,
+ ads->config.realm,
+ &cldap_reply))
+ {
+--
+1.9.0
+
+
+From 4eb02e7caa83b725988dd9f659b3568873522a30 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
+Date: Wed, 16 Apr 2014 16:07:14 +0200
+Subject: [PATCH 5/5] PATCHSET11: s3-libads: allow ads_try_connect() to re-use
+ a resolved ip address.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Pass down a struct sockaddr_storage to ads_try_connect.
+
+Guenther
+
+Signed-off-by: Günther Deschner <gd@samba.org>
+Reviewed-by: Andreas Schneider <asn@samba.org>
+
+Autobuild-User(master): Günther Deschner <gd@samba.org>
+Autobuild-Date(master): Thu Apr 17 19:56:16 CEST 2014 on sn-devel-104
+---
+ source3/libads/ldap.c | 44 ++++++++++++++++++++++++++------------------
+ 1 file changed, 26 insertions(+), 18 deletions(-)
+
+diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
+index 0db0bcd..f8349cf 100644
+--- a/source3/libads/ldap.c
++++ b/source3/libads/ldap.c
+@@ -194,33 +194,27 @@ bool ads_closest_dc(ADS_STRUCT *ads)
+ try a connection to a given ldap server, returning True and setting the servers IP
+ in the ads struct if successful
+ */
+-static bool ads_try_connect(ADS_STRUCT *ads, const char *server, bool gc)
++static bool ads_try_connect(ADS_STRUCT *ads, bool gc,
++ struct sockaddr_storage *ss)
+ {
+ struct NETLOGON_SAM_LOGON_RESPONSE_EX cldap_reply;
+ TALLOC_CTX *frame = talloc_stackframe();
+ bool ret = false;
+- struct sockaddr_storage ss;
+ char addr[INET6_ADDRSTRLEN];
+
+- if (!server || !*server) {
++ if (ss == NULL) {
+ TALLOC_FREE(frame);
+ return False;
+ }
+
+- if (!resolve_name(server, &ss, 0x20, true)) {
+- DEBUG(5,("ads_try_connect: unable to resolve name %s\n",
+- server ));
+- TALLOC_FREE(frame);
+- return false;
+- }
+- print_sockaddr(addr, sizeof(addr), &ss);
++ print_sockaddr(addr, sizeof(addr), ss);
+
+ DEBUG(5,("ads_try_connect: sending CLDAP request to %s (realm: %s)\n",
+ addr, ads->server.realm));
+
+ ZERO_STRUCT( cldap_reply );
+
+- if ( !ads_cldap_netlogon_5(frame, &ss, ads->server.realm, &cldap_reply ) ) {
++ if ( !ads_cldap_netlogon_5(frame, ss, ads->server.realm, &cldap_reply ) ) {
+ DEBUG(3,("ads_try_connect: CLDAP request %s failed.\n", addr));
+ ret = false;
+ goto out;
+@@ -260,7 +254,7 @@ static bool ads_try_connect(ADS_STRUCT *ads, const char *server, bool gc)
+ ads->server.workgroup = SMB_STRDUP(cldap_reply.domain_name);
+
+ ads->ldap.port = gc ? LDAP_GC_PORT : LDAP_PORT;
+- ads->ldap.ss = ss;
++ ads->ldap.ss = *ss;
+
+ /* Store our site name. */
+ sitename_store( cldap_reply.domain_name, cldap_reply.client_site);
+@@ -292,6 +286,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads)
+ bool use_own_domain = False;
+ char *sitename;
+ NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
++ bool ok = false;
+
+ /* if the realm and workgroup are both empty, assume they are ours */
+
+@@ -345,12 +340,14 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads)
+ DEBUG(6,("ads_find_dc: (ldap) looking for %s '%s'\n",
+ (got_realm ? "realm" : "domain"), realm));
+
+- if (get_dc_name(domain, realm, srv_name, &ip_out)) {
++ ok = get_dc_name(domain, realm, srv_name, &ip_out);
++ if (ok) {
+ /*
+ * we call ads_try_connect() to fill in the
+ * ads->config details
+ */
+- if (ads_try_connect(ads, srv_name, false)) {
++ ok = ads_try_connect(ads, false, &ip_out);
++ if (ok) {
+ return NT_STATUS_OK;
+ }
+ }
+@@ -406,7 +403,8 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads)
+ }
+ }
+
+- if ( ads_try_connect(ads, server, false) ) {
++ ok = ads_try_connect(ads, false, &ip_list[i].ss);
++ if (ok) {
+ SAFE_FREE(ip_list);
+ SAFE_FREE(sitename);
+ return NT_STATUS_OK;
+@@ -591,9 +589,19 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads)
+ TALLOC_FREE(s);
+ }
+
+- if (ads->server.ldap_server)
+- {
+- if (ads_try_connect(ads, ads->server.ldap_server, ads->server.gc)) {
++ if (ads->server.ldap_server) {
++ bool ok = false;
++ struct sockaddr_storage ss;
++
++ ok = resolve_name(ads->server.ldap_server, &ss, 0x20, true);
++ if (!ok) {
++ DEBUG(5,("ads_connect: unable to resolve name %s\n",
++ ads->server.ldap_server));
++ status = ADS_ERROR_NT(NT_STATUS_NOT_FOUND);
++ goto out;
++ }
++ ok = ads_try_connect(ads, ads->server.gc, &ss);
++ if (ok) {
+ goto got_connection;
+ }
+
+--
+1.9.0
+
+diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
+index b826cb3..5e34aa3 100644
+--- a/source3/libads/kerberos.c
++++ b/source3/libads/kerberos.c
+@@ -827,10 +827,6 @@
+ return false;
+ }
+
+- if (domain == NULL || pss == NULL || kdc_name == NULL) {
+- return false;
+- }
+-
+ dname = lock_path("smb_krb5");
+ if (!dname) {
+ return false;