6729ff
From 942dedb71437cd89932a7f39ca73d65c09aa59be Mon Sep 17 00:00:00 2001
6729ff
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
6729ff
Date: Wed, 2 Apr 2014 19:37:34 +0200
6729ff
Subject: [PATCH] s3-kerberos: make ipv6 support for generated krb5 config
6729ff
 files more robust.
6729ff
MIME-Version: 1.0
6729ff
Content-Type: text/plain; charset=UTF-8
6729ff
Content-Transfer-Encoding: 8bit
6729ff
6729ff
Older MIT Kerberos libraries will add any secondary ipv6 address as
6729ff
ipv4 address, defining the (default) krb5 port 88 circumvents that.
6729ff
6729ff
Guenther
6729ff
6729ff
Signed-off-by: Günther Deschner <gd@samba.org>
6729ff
---
6729ff
 source3/libads/kerberos.c | 29 +++++++++++++++++++++++++++--
6729ff
 1 file changed, 27 insertions(+), 2 deletions(-)
6729ff
6729ff
diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
6729ff
index 649e568..f3c23ea 100644
6729ff
--- a/source3/libads/kerberos.c
6729ff
+++ b/source3/libads/kerberos.c
6729ff
@@ -615,6 +615,31 @@ static void add_sockaddr_unique(struct sockaddr_storage *addrs, int *num_addrs,
6729ff
 	*num_addrs += 1;
6729ff
 }
6729ff
 
6729ff
+/* print_canonical_sockaddr prints an ipv6 addr in the form of
6729ff
+* [ipv6.addr]. This string, when put in a generated krb5.conf file is not
6729ff
+* always properly dealt with by some older krb5 libraries. Adding the hard-coded
6729ff
+* portnumber workarounds the issue. - gd */
6729ff
+
6729ff
+static char *print_canonical_sockaddr_with_port(TALLOC_CTX *mem_ctx,
6729ff
+						const struct sockaddr_storage *pss)
6729ff
+{
6729ff
+	char *str = NULL;
6729ff
+
6729ff
+	str = print_canonical_sockaddr(mem_ctx, pss);
6729ff
+	if (str == NULL) {
6729ff
+		return NULL;
6729ff
+	}
6729ff
+
6729ff
+	if (pss->ss_family != AF_INET6) {
6729ff
+		return str;
6729ff
+	}
6729ff
+
6729ff
+#if defined(HAVE_IPV6)
6729ff
+	str = talloc_asprintf_append(str, ":88");
6729ff
+#endif
6729ff
+	return str;
6729ff
+}
6729ff
+
6729ff
 static char *get_kdc_ip_string(char *mem_ctx,
6729ff
 		const char *realm,
6729ff
 		const char *sitename,
6729ff
@@ -634,7 +659,7 @@ static char *get_kdc_ip_string(char *mem_ctx,
6729ff
 	struct netlogon_samlogon_response **responses = NULL;
6729ff
 	NTSTATUS status;
6729ff
 	char *kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n", "",
6729ff
-					print_canonical_sockaddr(mem_ctx, pss));
6729ff
+					print_canonical_sockaddr_with_port(mem_ctx, pss));
6729ff
 
6729ff
 	if (kdc_str == NULL) {
6729ff
 		TALLOC_FREE(frame);
6729ff
@@ -726,7 +751,7 @@ static char *get_kdc_ip_string(char *mem_ctx,
6729ff
 		/* Append to the string - inefficient but not done often. */
6729ff
 		new_kdc_str = talloc_asprintf(mem_ctx, "%s\tkdc = %s\n",
6729ff
 					      kdc_str,
6729ff
-					      print_canonical_sockaddr(mem_ctx, &dc_addrs[i]));
6729ff
+					      print_canonical_sockaddr_with_port(mem_ctx, &dc_addrs[i]));
6729ff
 		if (new_kdc_str == NULL) {
6729ff
 			goto fail;
6729ff
 		}
6729ff
-- 
6729ff
1.9.0
6729ff
c6ebcb
From 60db71015f84dd242be889576d85ccd5c6a1f73b Mon Sep 17 00:00:00 2001
c6ebcb
From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd@samba.org>
c6ebcb
Date: Wed, 16 Apr 2014 16:07:14 +0200
c6ebcb
Subject: [PATCH] s3-libads: allow ads_try_connect() to re-use a resolved ip
c6ebcb
 address.
c6ebcb
MIME-Version: 1.0
c6ebcb
Content-Type: text/plain; charset=UTF-8
c6ebcb
Content-Transfer-Encoding: 8bit
c6ebcb
c6ebcb
Pass down a struct sockaddr_storage to ads_try_connect.
c6ebcb
c6ebcb
Guenther
c6ebcb
c6ebcb
Signed-off-by: Günther Deschner <gd@samba.org>
c6ebcb
Reviewed-by: Andreas Schneider <asn@samba.org>
c6ebcb
c6ebcb
Autobuild-User(master): Günther Deschner <gd@samba.org>
c6ebcb
Autobuild-Date(master): Thu Apr 17 19:56:16 CEST 2014 on sn-devel-104
c6ebcb
---
c6ebcb
 source3/libads/ldap.c | 44 ++++++++++++++++++++++++++------------------
c6ebcb
 1 file changed, 26 insertions(+), 18 deletions(-)
c6ebcb
c6ebcb
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
c6ebcb
index d9bb8e2..8fed8fd 100644
c6ebcb
--- a/source3/libads/ldap.c
c6ebcb
+++ b/source3/libads/ldap.c
c6ebcb
@@ -228,33 +228,27 @@ bool ads_closest_dc(ADS_STRUCT *ads)
c6ebcb
   try a connection to a given ldap server, returning True and setting the servers IP
c6ebcb
   in the ads struct if successful
c6ebcb
  */
c6ebcb
-static bool ads_try_connect(ADS_STRUCT *ads, const char *server, bool gc)
c6ebcb
+static bool ads_try_connect(ADS_STRUCT *ads, bool gc,
c6ebcb
+			    struct sockaddr_storage *ss)
c6ebcb
 {
c6ebcb
 	struct NETLOGON_SAM_LOGON_RESPONSE_EX cldap_reply;
c6ebcb
 	TALLOC_CTX *frame = talloc_stackframe();
c6ebcb
 	bool ret = false;
c6ebcb
-	struct sockaddr_storage ss;
c6ebcb
 	char addr[INET6_ADDRSTRLEN];
c6ebcb
 
c6ebcb
-	if (!server || !*server) {
c6ebcb
+	if (ss == NULL) {
c6ebcb
 		TALLOC_FREE(frame);
c6ebcb
 		return False;
c6ebcb
 	}
c6ebcb
 
c6ebcb
-	if (!resolve_name(server, &ss, 0x20, true)) {
c6ebcb
-		DEBUG(5,("ads_try_connect: unable to resolve name %s\n",
c6ebcb
-			 server ));
c6ebcb
-		TALLOC_FREE(frame);
c6ebcb
-		return false;
c6ebcb
-	}
c6ebcb
-	print_sockaddr(addr, sizeof(addr), &ss);
c6ebcb
+	print_sockaddr(addr, sizeof(addr), ss);
c6ebcb
 
c6ebcb
 	DEBUG(5,("ads_try_connect: sending CLDAP request to %s (realm: %s)\n", 
c6ebcb
 		addr, ads->server.realm));
c6ebcb
 
c6ebcb
 	ZERO_STRUCT( cldap_reply );
c6ebcb
 
c6ebcb
-	if ( !ads_cldap_netlogon_5(frame, &ss, ads->server.realm, &cldap_reply ) ) {
c6ebcb
+	if ( !ads_cldap_netlogon_5(frame, ss, ads->server.realm, &cldap_reply ) ) {
c6ebcb
 		DEBUG(3,("ads_try_connect: CLDAP request %s failed.\n", addr));
c6ebcb
 		ret = false;
c6ebcb
 		goto out;
c6ebcb
@@ -298,7 +292,7 @@ static bool ads_try_connect(ADS_STRUCT *ads, const char *server, bool gc)
c6ebcb
 	ads->server.workgroup          = SMB_STRDUP(cldap_reply.domain_name);
c6ebcb
 
c6ebcb
 	ads->ldap.port = gc ? LDAP_GC_PORT : LDAP_PORT;
c6ebcb
-	ads->ldap.ss = ss;
c6ebcb
+	ads->ldap.ss = *ss;
c6ebcb
 
c6ebcb
 	/* Store our site name. */
c6ebcb
 	sitename_store( cldap_reply.domain_name, cldap_reply.client_site);
c6ebcb
@@ -330,6 +324,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads)
c6ebcb
 	bool use_own_domain = False;
c6ebcb
 	char *sitename;
c6ebcb
 	NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
c6ebcb
+	bool ok = false;
c6ebcb
 
c6ebcb
 	/* if the realm and workgroup are both empty, assume they are ours */
c6ebcb
 
c6ebcb
@@ -384,12 +379,14 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads)
c6ebcb
 		DEBUG(6,("ads_find_dc: (ldap) looking for %s '%s'\n",
c6ebcb
 			(got_realm ? "realm" : "domain"), realm));
c6ebcb
 
c6ebcb
-		if (get_dc_name(domain, realm, srv_name, &ip_out)) {
c6ebcb
+		ok = get_dc_name(domain, realm, srv_name, &ip_out);
c6ebcb
+		if (ok) {
c6ebcb
 			/*
c6ebcb
 			 * we call ads_try_connect() to fill in the
c6ebcb
 			 * ads->config details
c6ebcb
 			 */
c6ebcb
-			if (ads_try_connect(ads, srv_name, false)) {
c6ebcb
+			ok = ads_try_connect(ads, false, &ip_out);
c6ebcb
+			if (ok) {
c6ebcb
 				return NT_STATUS_OK;
c6ebcb
 			}
c6ebcb
 		}
c6ebcb
@@ -445,7 +442,8 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads)
c6ebcb
 			}
c6ebcb
 		}
c6ebcb
 
c6ebcb
-		if ( ads_try_connect(ads, server, false) ) {
c6ebcb
+		ok = ads_try_connect(ads, false, &ip_list[i].ss);
c6ebcb
+		if (ok) {
c6ebcb
 			SAFE_FREE(ip_list);
c6ebcb
 			SAFE_FREE(sitename);
c6ebcb
 			return NT_STATUS_OK;
c6ebcb
@@ -630,9 +628,19 @@ ADS_STATUS ads_connect(ADS_STRUCT *ads)
c6ebcb
 		TALLOC_FREE(s);
c6ebcb
 	}
c6ebcb
 
c6ebcb
-	if (ads->server.ldap_server)
c6ebcb
-	{
c6ebcb
-		if (ads_try_connect(ads, ads->server.ldap_server, ads->server.gc)) {
c6ebcb
+	if (ads->server.ldap_server) {
c6ebcb
+		bool ok = false;
c6ebcb
+		struct sockaddr_storage ss;
c6ebcb
+
c6ebcb
+		ok = resolve_name(ads->server.ldap_server, &ss, 0x20, true);
c6ebcb
+		if (!ok) {
c6ebcb
+			DEBUG(5,("ads_connect: unable to resolve name %s\n",
c6ebcb
+				 ads->server.ldap_server));
c6ebcb
+			status = ADS_ERROR_NT(NT_STATUS_NOT_FOUND);
c6ebcb
+			goto out;
c6ebcb
+		}
c6ebcb
+		ok = ads_try_connect(ads, ads->server.gc, &ss);
c6ebcb
+		if (ok) {
c6ebcb
 			goto got_connection;
c6ebcb
 		}
c6ebcb
 
c6ebcb
-- 
c6ebcb
1.9.0
c6ebcb