]> git.ipfire.org Git - ipfire-2.x.git/blobdiff - src/patches/samba/samba-3.6.23-fix_libads_krb5_ipv6.patch
samba: add current RHEL6 patches
[ipfire-2.x.git] / src / patches / samba / samba-3.6.23-fix_libads_krb5_ipv6.patch
diff --git a/src/patches/samba/samba-3.6.23-fix_libads_krb5_ipv6.patch b/src/patches/samba/samba-3.6.23-fix_libads_krb5_ipv6.patch
new file mode 100644 (file)
index 0000000..9b6d221
--- /dev/null
@@ -0,0 +1,788 @@
+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;