801d0a
From 05f7e9a72a1769af9d41b1ca40fe6a14b3f069d1 Mon Sep 17 00:00:00 2001
801d0a
From: Isaac Boukris <iboukris@gmail.com>
801d0a
Date: Fri, 30 Aug 2019 00:22:15 +0300
801d0a
Subject: [PATCH 1/6] libnet_join: build dnsHostName from netbios name and
801d0a
 lp_dnsdomain()
801d0a
801d0a
This make the join process much more reliable, and avoids "Constraint
801d0a
violation" error when the fqdn returned from getaddrinfo has already
801d0a
got assigned an SPN.
801d0a
801d0a
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14116
801d0a
801d0a
Signed-off-by: Isaac Boukris <iboukris@redhat.com>
801d0a
Reviewed-by: Ralph Boehme <slow@samba.org>
801d0a
Reviewed-by: Alexander Bokovoy <ab@samba.org>
801d0a
---
801d0a
 source3/libnet/libnet_join.c       | 31 +++++++++++-------------------
801d0a
 testprogs/blackbox/test_net_ads.sh |  7 +++++--
801d0a
 2 files changed, 16 insertions(+), 22 deletions(-)
801d0a
801d0a
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
801d0a
index 7943bef2cf6..818b3039cb9 100644
801d0a
--- a/source3/libnet/libnet_join.c
801d0a
+++ b/source3/libnet/libnet_join.c
801d0a
@@ -533,29 +533,23 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
801d0a
 		}
801d0a
 	}
801d0a
 
801d0a
-	if (!name_to_fqdn(my_fqdn, r->in.machine_name)
801d0a
-	    || (strchr(my_fqdn, '.') == NULL)) {
801d0a
-		fstr_sprintf(my_fqdn, "%s.%s", r->in.machine_name,
801d0a
-			     r->out.dns_domain_name);
801d0a
-	}
801d0a
+	fstr_sprintf(my_fqdn, "%s.%s", r->in.machine_name, lp_dnsdomain());
801d0a
 
801d0a
 	if (!strlower_m(my_fqdn)) {
801d0a
 		return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
 	}
801d0a
 
801d0a
-	if (!strequal(my_fqdn, r->in.machine_name)) {
801d0a
-		spn = talloc_asprintf(mem_ctx, "HOST/%s", my_fqdn);
801d0a
-		if (!spn) {
801d0a
-			return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
-		}
801d0a
+	spn = talloc_asprintf(mem_ctx, "HOST/%s", my_fqdn);
801d0a
+	if (spn == NULL) {
801d0a
+		return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+	}
801d0a
 
801d0a
-		ok = ads_element_in_array(spn_array, num_spns, spn);
801d0a
+	ok = ads_element_in_array(spn_array, num_spns, spn);
801d0a
+	if (!ok) {
801d0a
+		ok = add_string_to_array(spn_array, spn,
801d0a
+					 &spn_array, &num_spns);
801d0a
 		if (!ok) {
801d0a
-			ok = add_string_to_array(spn_array, spn,
801d0a
-						 &spn_array, &num_spns);
801d0a
-			if (!ok) {
801d0a
-				return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
-			}
801d0a
+			return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
 		}
801d0a
 	}
801d0a
 
801d0a
@@ -591,12 +585,9 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
801d0a
 			/*
801d0a
 			 * Add HOST/netbiosname.domainname
801d0a
 			 */
801d0a
-			if (r->out.dns_domain_name == NULL) {
801d0a
-				continue;
801d0a
-			}
801d0a
 			fstr_sprintf(my_fqdn, "%s.%s",
801d0a
 				     *netbios_aliases,
801d0a
-				     r->out.dns_domain_name);
801d0a
+				     lp_dnsdomain());
801d0a
 
801d0a
 			spn = talloc_asprintf(mem_ctx, "HOST/%s", my_fqdn);
801d0a
 			if (spn == NULL) {
801d0a
diff --git a/testprogs/blackbox/test_net_ads.sh b/testprogs/blackbox/test_net_ads.sh
801d0a
index cc8345c4624..ef6f99ddea4 100755
801d0a
--- a/testprogs/blackbox/test_net_ads.sh
801d0a
+++ b/testprogs/blackbox/test_net_ads.sh
801d0a
@@ -81,7 +81,7 @@ testit "testjoin (dedicated keytab)" $VALGRIND $net_tool ads testjoin -kP || fai
801d0a
 netbios=$(grep "netbios name" $BASEDIR/$WORKDIR/client.conf | cut -f2 -d= | awk '{$1=$1};1')
801d0a
 uc_netbios=$(echo $netbios | tr '[:lower:]' '[:upper:]')
801d0a
 lc_realm=$(echo $REALM | tr '[:upper:]' '[:lower:]')
801d0a
-fqdns="$netbios.$lc_realm"
801d0a
+fqdn="$netbios.$lc_realm"
801d0a
 
801d0a
 krb_princ="primary/instance@$REALM"
801d0a
 testit "test (dedicated keytab) add a fully qualified krb5 principal" $VALGRIND $net_tool ads keytab add $krb_princ -U$DC_USERNAME%$DC_PASSWORD --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" || failed=`expr $failed + 1`
801d0a
@@ -99,7 +99,7 @@ testit "test (dedicated keytab) at least one krb5 principal created from $machin
801d0a
 service="nfs"
801d0a
 testit "test (dedicated keytab) add a $service service to keytab" $VALGRIND $net_tool ads keytab add $service -U$DC_USERNAME%$DC_PASSWORD --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" || failed=`expr $failed + 1`
801d0a
 
801d0a
-search_str="$service/$fqdns@$REALM"
801d0a
+search_str="$service/$fqdn@$REALM"
801d0a
 found=`$net_tool ads keytab list -U$DC_USERNAME%$DC_PASSWORD --option="kerberosmethod=dedicatedkeytab" --option="dedicatedkeytabfile=$dedicated_keytab_file" | grep $search_str | wc -l`
801d0a
 testit "test (dedicated keytab) at least one (long form) krb5 principal created from service added is present in keytab" test $found -gt 1 || failed=`expr $failed + 1`
801d0a
 
801d0a
@@ -206,6 +206,9 @@ testit "join" $VALGRIND $net_tool ads join -U$DC_USERNAME%$DC_PASSWORD || failed
801d0a
 
801d0a
 testit "testjoin" $VALGRIND $net_tool ads testjoin || failed=`expr $failed + 1`
801d0a
 
801d0a
+testit_grep "check dNSHostName" $fqdn $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ dNSHostName || failed=`expr $failed + 1`
801d0a
+testit_grep "check SPN" ${uc_netbios}.${lc_realm} $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ servicePrincipalName || failed=`expr $failed + 1`
801d0a
+
801d0a
 ##Goodbye...
801d0a
 testit "leave" $VALGRIND $net_tool ads leave -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1`
801d0a
 
801d0a
-- 
801d0a
2.21.0
801d0a
801d0a
801d0a
From 4cbad1eb46896bbd74c5b19dbb0a8937ffde90c2 Mon Sep 17 00:00:00 2001
801d0a
From: Isaac Boukris <iboukris@gmail.com>
801d0a
Date: Wed, 18 Sep 2019 20:00:34 +0300
801d0a
Subject: [PATCH 2/6] libnet_join_set_machine_spn: improve style and make a bit
801d0a
 room for indentation
801d0a
801d0a
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14116
801d0a
801d0a
Signed-off-by: Isaac Boukris <iboukris@redhat.com>
801d0a
Reviewed-by: Ralph Boehme <slow@samba.org>
801d0a
Reviewed-by: Alexander Bokovoy <ab@samba.org>
801d0a
---
801d0a
 source3/libnet/libnet_join.c | 95 ++++++++++++++++++------------------
801d0a
 1 file changed, 47 insertions(+), 48 deletions(-)
801d0a
801d0a
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
801d0a
index 818b3039cb9..67ab50c68a8 100644
801d0a
--- a/source3/libnet/libnet_join.c
801d0a
+++ b/source3/libnet/libnet_join.c
801d0a
@@ -517,7 +517,7 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
801d0a
 	/* Windows only creates HOST/shortname & HOST/fqdn. */
801d0a
 
801d0a
 	spn = talloc_asprintf(mem_ctx, "HOST/%s", r->in.machine_name);
801d0a
-	if (!spn) {
801d0a
+	if (spn == NULL) {
801d0a
 		return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
 	}
801d0a
 	if (!strupper_m(spn)) {
801d0a
@@ -553,60 +553,59 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
801d0a
 		}
801d0a
 	}
801d0a
 
801d0a
-	netbios_aliases = lp_netbios_aliases();
801d0a
-	if (netbios_aliases != NULL) {
801d0a
-		for (; *netbios_aliases != NULL; netbios_aliases++) {
801d0a
-			/*
801d0a
-			 * Add HOST/NETBIOSNAME
801d0a
-			 */
801d0a
-			spn = talloc_asprintf(mem_ctx, "HOST/%s", *netbios_aliases);
801d0a
-			if (spn == NULL) {
801d0a
-				TALLOC_FREE(spn);
801d0a
-				return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
-			}
801d0a
-			if (!strupper_m(spn)) {
801d0a
-				TALLOC_FREE(spn);
801d0a
-				return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
-			}
801d0a
+	for (netbios_aliases = lp_netbios_aliases();
801d0a
+	     netbios_aliases != NULL && *netbios_aliases != NULL;
801d0a
+	     netbios_aliases++) {
801d0a
+		/*
801d0a
+		 * Add HOST/NETBIOSNAME
801d0a
+		 */
801d0a
+		spn = talloc_asprintf(mem_ctx, "HOST/%s", *netbios_aliases);
801d0a
+		if (spn == NULL) {
801d0a
+			TALLOC_FREE(spn);
801d0a
+			return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+		}
801d0a
+		if (!strupper_m(spn)) {
801d0a
+			TALLOC_FREE(spn);
801d0a
+			return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+		}
801d0a
 
801d0a
-			ok = ads_element_in_array(spn_array, num_spns, spn);
801d0a
-			if (ok) {
801d0a
-				TALLOC_FREE(spn);
801d0a
-				continue;
801d0a
-			}
801d0a
-			ok = add_string_to_array(spn_array, spn,
801d0a
-						 &spn_array, &num_spns);
801d0a
-			if (!ok) {
801d0a
-				TALLOC_FREE(spn);
801d0a
-				return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
-			}
801d0a
+		ok = ads_element_in_array(spn_array, num_spns, spn);
801d0a
+		if (ok) {
801d0a
+			TALLOC_FREE(spn);
801d0a
+			continue;
801d0a
+		}
801d0a
+		ok = add_string_to_array(spn_array, spn,
801d0a
+					 &spn_array, &num_spns);
801d0a
+		if (!ok) {
801d0a
 			TALLOC_FREE(spn);
801d0a
+			return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+		}
801d0a
+		TALLOC_FREE(spn);
801d0a
 
801d0a
-			/*
801d0a
-			 * Add HOST/netbiosname.domainname
801d0a
-			 */
801d0a
-			fstr_sprintf(my_fqdn, "%s.%s",
801d0a
-				     *netbios_aliases,
801d0a
-				     lp_dnsdomain());
801d0a
+		/*
801d0a
+		 * Add HOST/netbiosname.domainname
801d0a
+		 */
801d0a
+		fstr_sprintf(my_fqdn, "%s.%s",
801d0a
+			     *netbios_aliases,
801d0a
+			     lp_dnsdomain());
801d0a
 
801d0a
-			spn = talloc_asprintf(mem_ctx, "HOST/%s", my_fqdn);
801d0a
-			if (spn == NULL) {
801d0a
-				return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
-			}
801d0a
+		spn = talloc_asprintf(mem_ctx, "HOST/%s", my_fqdn);
801d0a
+		if (spn == NULL) {
801d0a
+			return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+		}
801d0a
 
801d0a
-			ok = ads_element_in_array(spn_array, num_spns, spn);
801d0a
-			if (ok) {
801d0a
-				TALLOC_FREE(spn);
801d0a
-				continue;
801d0a
-			}
801d0a
-			ok = add_string_to_array(spn_array, spn,
801d0a
-						 &spn_array, &num_spns);
801d0a
-			if (!ok) {
801d0a
-				TALLOC_FREE(spn);
801d0a
-				return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
-			}
801d0a
+		ok = ads_element_in_array(spn_array, num_spns, spn);
801d0a
+		if (ok) {
801d0a
+			TALLOC_FREE(spn);
801d0a
+			continue;
801d0a
+		}
801d0a
+		ok = add_string_to_array(spn_array, spn,
801d0a
+					 &spn_array, &num_spns);
801d0a
+		if (!ok) {
801d0a
 			TALLOC_FREE(spn);
801d0a
+			return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
 		}
801d0a
+		TALLOC_FREE(spn);
801d0a
 	}
801d0a
 
801d0a
 	/* make sure to NULL terminate the array */
801d0a
-- 
801d0a
2.21.0
801d0a
801d0a
801d0a
From b8e1264ececf38681ca9a519a51e8336044673f0 Mon Sep 17 00:00:00 2001
801d0a
From: Isaac Boukris <iboukris@gmail.com>
801d0a
Date: Wed, 18 Sep 2019 21:29:47 +0300
801d0a
Subject: [PATCH 3/6] libnet_join_set_machine_spn: simplify memory handling
801d0a
801d0a
and avoid a possible memory leak when passing null to
801d0a
add_string_to_array() as mem_ctx.
801d0a
801d0a
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14116
801d0a
801d0a
Signed-off-by: Isaac Boukris <iboukris@redhat.com>
801d0a
Reviewed-by: Ralph Boehme <slow@samba.org>
801d0a
Reviewed-by: Alexander Bokovoy <ab@samba.org>
801d0a
---
801d0a
 source3/libnet/libnet_join.c | 74 ++++++++++++++++++++----------------
801d0a
 1 file changed, 42 insertions(+), 32 deletions(-)
801d0a
801d0a
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
801d0a
index 67ab50c68a8..43035370526 100644
801d0a
--- a/source3/libnet/libnet_join.c
801d0a
+++ b/source3/libnet/libnet_join.c
801d0a
@@ -490,6 +490,7 @@ static ADS_STATUS libnet_join_get_machine_spns(TALLOC_CTX *mem_ctx,
801d0a
 static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
801d0a
 					      struct libnet_JoinCtx *r)
801d0a
 {
801d0a
+	TALLOC_CTX *frame = talloc_stackframe();
801d0a
 	ADS_STATUS status;
801d0a
 	ADS_MODLIST mods;
801d0a
 	fstring my_fqdn;
801d0a
@@ -506,7 +507,7 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
801d0a
 		return status;
801d0a
 	}
801d0a
 
801d0a
-	status = libnet_join_get_machine_spns(mem_ctx,
801d0a
+	status = libnet_join_get_machine_spns(frame,
801d0a
 					      r,
801d0a
 					      discard_const_p(char **, &spn_array),
801d0a
 					      &num_spns);
801d0a
@@ -516,40 +517,46 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
801d0a
 
801d0a
 	/* Windows only creates HOST/shortname & HOST/fqdn. */
801d0a
 
801d0a
-	spn = talloc_asprintf(mem_ctx, "HOST/%s", r->in.machine_name);
801d0a
+	spn = talloc_asprintf(frame, "HOST/%s", r->in.machine_name);
801d0a
 	if (spn == NULL) {
801d0a
-		return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+		status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+		goto done;
801d0a
 	}
801d0a
 	if (!strupper_m(spn)) {
801d0a
-		return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+		status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+		goto done;
801d0a
 	}
801d0a
 
801d0a
 	ok = ads_element_in_array(spn_array, num_spns, spn);
801d0a
 	if (!ok) {
801d0a
-		ok = add_string_to_array(spn_array, spn,
801d0a
+		ok = add_string_to_array(frame, spn,
801d0a
 					 &spn_array, &num_spns);
801d0a
 		if (!ok) {
801d0a
-			return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+			status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+			goto done;
801d0a
 		}
801d0a
 	}
801d0a
 
801d0a
 	fstr_sprintf(my_fqdn, "%s.%s", r->in.machine_name, lp_dnsdomain());
801d0a
 
801d0a
 	if (!strlower_m(my_fqdn)) {
801d0a
-		return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+		status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+		goto done;
801d0a
 	}
801d0a
 
801d0a
-	spn = talloc_asprintf(mem_ctx, "HOST/%s", my_fqdn);
801d0a
+	spn = talloc_asprintf(frame, "HOST/%s", my_fqdn);
801d0a
 	if (spn == NULL) {
801d0a
-		return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+		status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+		goto done;
801d0a
 	}
801d0a
 
801d0a
 	ok = ads_element_in_array(spn_array, num_spns, spn);
801d0a
 	if (!ok) {
801d0a
-		ok = add_string_to_array(spn_array, spn,
801d0a
+		ok = add_string_to_array(frame, spn,
801d0a
 					 &spn_array, &num_spns);
801d0a
 		if (!ok) {
801d0a
-			return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+			status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+			goto done;
801d0a
 		}
801d0a
 	}
801d0a
 
801d0a
@@ -559,28 +566,26 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
801d0a
 		/*
801d0a
 		 * Add HOST/NETBIOSNAME
801d0a
 		 */
801d0a
-		spn = talloc_asprintf(mem_ctx, "HOST/%s", *netbios_aliases);
801d0a
+		spn = talloc_asprintf(frame, "HOST/%s", *netbios_aliases);
801d0a
 		if (spn == NULL) {
801d0a
-			TALLOC_FREE(spn);
801d0a
-			return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+			status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+			goto done;
801d0a
 		}
801d0a
 		if (!strupper_m(spn)) {
801d0a
-			TALLOC_FREE(spn);
801d0a
-			return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+			status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+			goto done;
801d0a
 		}
801d0a
 
801d0a
 		ok = ads_element_in_array(spn_array, num_spns, spn);
801d0a
 		if (ok) {
801d0a
-			TALLOC_FREE(spn);
801d0a
 			continue;
801d0a
 		}
801d0a
 		ok = add_string_to_array(spn_array, spn,
801d0a
 					 &spn_array, &num_spns);
801d0a
 		if (!ok) {
801d0a
-			TALLOC_FREE(spn);
801d0a
-			return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+			status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+			goto done;
801d0a
 		}
801d0a
-		TALLOC_FREE(spn);
801d0a
 
801d0a
 		/*
801d0a
 		 * Add HOST/netbiosname.domainname
801d0a
@@ -589,51 +594,56 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
801d0a
 			     *netbios_aliases,
801d0a
 			     lp_dnsdomain());
801d0a
 
801d0a
-		spn = talloc_asprintf(mem_ctx, "HOST/%s", my_fqdn);
801d0a
+		spn = talloc_asprintf(frame, "HOST/%s", my_fqdn);
801d0a
 		if (spn == NULL) {
801d0a
-			return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+			status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+			goto done;
801d0a
 		}
801d0a
 
801d0a
 		ok = ads_element_in_array(spn_array, num_spns, spn);
801d0a
 		if (ok) {
801d0a
-			TALLOC_FREE(spn);
801d0a
 			continue;
801d0a
 		}
801d0a
 		ok = add_string_to_array(spn_array, spn,
801d0a
 					 &spn_array, &num_spns);
801d0a
 		if (!ok) {
801d0a
-			TALLOC_FREE(spn);
801d0a
-			return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+			status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+			goto done;
801d0a
 		}
801d0a
-		TALLOC_FREE(spn);
801d0a
 	}
801d0a
 
801d0a
 	/* make sure to NULL terminate the array */
801d0a
-	spn_array = talloc_realloc(mem_ctx, spn_array, const char *, num_spns + 1);
801d0a
+	spn_array = talloc_realloc(frame, spn_array, const char *, num_spns + 1);
801d0a
 	if (spn_array == NULL) {
801d0a
-		return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+		status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+		goto done;
801d0a
 	}
801d0a
 	spn_array[num_spns] = NULL;
801d0a
 
801d0a
 	mods = ads_init_mods(mem_ctx);
801d0a
 	if (!mods) {
801d0a
-		return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+		status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+		goto done;
801d0a
 	}
801d0a
 
801d0a
 	/* fields of primary importance */
801d0a
 
801d0a
 	status = ads_mod_str(mem_ctx, &mods, "dNSHostName", my_fqdn);
801d0a
 	if (!ADS_ERR_OK(status)) {
801d0a
-		return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+		goto done;
801d0a
 	}
801d0a
 
801d0a
 	status = ads_mod_strlist(mem_ctx, &mods, "servicePrincipalName",
801d0a
 				 spn_array);
801d0a
 	if (!ADS_ERR_OK(status)) {
801d0a
-		return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+		goto done;
801d0a
 	}
801d0a
 
801d0a
-	return ads_gen_mod(r->in.ads, r->out.dn, mods);
801d0a
+	status = ads_gen_mod(r->in.ads, r->out.dn, mods);
801d0a
+
801d0a
+done:
801d0a
+	TALLOC_FREE(frame);
801d0a
+	return status;
801d0a
 }
801d0a
 
801d0a
 /****************************************************************
801d0a
-- 
801d0a
2.21.0
801d0a
801d0a
801d0a
From 3e65f72b141a7ee256ae581e5f48f1d930aed76a Mon Sep 17 00:00:00 2001
801d0a
From: Isaac Boukris <iboukris@gmail.com>
801d0a
Date: Wed, 18 Sep 2019 23:15:57 +0300
801d0a
Subject: [PATCH 4/6] libnet_join_set_machine_spn: simplify adding uniq spn to
801d0a
 array
801d0a
801d0a
and do not skip adding a fully qualified spn to netbios-aliases
801d0a
in case a short spn already existed.
801d0a
801d0a
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14116
801d0a
801d0a
Signed-off-by: Isaac Boukris <iboukris@redhat.com>
801d0a
Reviewed-by: Ralph Boehme <slow@samba.org>
801d0a
Reviewed-by: Alexander Bokovoy <ab@samba.org>
801d0a
---
801d0a
 source3/libnet/libnet_join.c | 56 +++++++++++++++---------------------
801d0a
 1 file changed, 23 insertions(+), 33 deletions(-)
801d0a
801d0a
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
801d0a
index 43035370526..a1d8a25bbc2 100644
801d0a
--- a/source3/libnet/libnet_join.c
801d0a
+++ b/source3/libnet/libnet_join.c
801d0a
@@ -483,6 +483,19 @@ static ADS_STATUS libnet_join_get_machine_spns(TALLOC_CTX *mem_ctx,
801d0a
 	return status;
801d0a
 }
801d0a
 
801d0a
+static ADS_STATUS add_uniq_spn(TALLOC_CTX *mem_ctx, const  char *spn,
801d0a
+			       const char ***array, size_t *num)
801d0a
+{
801d0a
+	bool ok = ads_element_in_array(*array, *num, spn);
801d0a
+	if (!ok) {
801d0a
+		ok = add_string_to_array(mem_ctx, spn, array, num);
801d0a
+		if (!ok) {
801d0a
+			return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+		}
801d0a
+	}
801d0a
+	return ADS_SUCCESS;
801d0a
+}
801d0a
+
801d0a
 /****************************************************************
801d0a
  Set a machines dNSHostName and servicePrincipalName attributes
801d0a
 ****************************************************************/
801d0a
@@ -497,7 +510,6 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
801d0a
 	const char **spn_array = NULL;
801d0a
 	size_t num_spns = 0;
801d0a
 	char *spn = NULL;
801d0a
-	bool ok;
801d0a
 	const char **netbios_aliases = NULL;
801d0a
 
801d0a
 	/* Find our DN */
801d0a
@@ -527,14 +539,9 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
801d0a
 		goto done;
801d0a
 	}
801d0a
 
801d0a
-	ok = ads_element_in_array(spn_array, num_spns, spn);
801d0a
-	if (!ok) {
801d0a
-		ok = add_string_to_array(frame, spn,
801d0a
-					 &spn_array, &num_spns);
801d0a
-		if (!ok) {
801d0a
-			status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
-			goto done;
801d0a
-		}
801d0a
+	status = add_uniq_spn(frame, spn, &spn_array, &num_spns);
801d0a
+	if (!ADS_ERR_OK(status)) {
801d0a
+		goto done;
801d0a
 	}
801d0a
 
801d0a
 	fstr_sprintf(my_fqdn, "%s.%s", r->in.machine_name, lp_dnsdomain());
801d0a
@@ -550,14 +557,9 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
801d0a
 		goto done;
801d0a
 	}
801d0a
 
801d0a
-	ok = ads_element_in_array(spn_array, num_spns, spn);
801d0a
-	if (!ok) {
801d0a
-		ok = add_string_to_array(frame, spn,
801d0a
-					 &spn_array, &num_spns);
801d0a
-		if (!ok) {
801d0a
-			status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
-			goto done;
801d0a
-		}
801d0a
+	status = add_uniq_spn(frame, spn, &spn_array, &num_spns);
801d0a
+	if (!ADS_ERR_OK(status)) {
801d0a
+		goto done;
801d0a
 	}
801d0a
 
801d0a
 	for (netbios_aliases = lp_netbios_aliases();
801d0a
@@ -576,14 +578,8 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
801d0a
 			goto done;
801d0a
 		}
801d0a
 
801d0a
-		ok = ads_element_in_array(spn_array, num_spns, spn);
801d0a
-		if (ok) {
801d0a
-			continue;
801d0a
-		}
801d0a
-		ok = add_string_to_array(spn_array, spn,
801d0a
-					 &spn_array, &num_spns);
801d0a
-		if (!ok) {
801d0a
-			status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+		status = add_uniq_spn(frame, spn, &spn_array, &num_spns);
801d0a
+		if (!ADS_ERR_OK(status)) {
801d0a
 			goto done;
801d0a
 		}
801d0a
 
801d0a
@@ -600,14 +596,8 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
801d0a
 			goto done;
801d0a
 		}
801d0a
 
801d0a
-		ok = ads_element_in_array(spn_array, num_spns, spn);
801d0a
-		if (ok) {
801d0a
-			continue;
801d0a
-		}
801d0a
-		ok = add_string_to_array(spn_array, spn,
801d0a
-					 &spn_array, &num_spns);
801d0a
-		if (!ok) {
801d0a
-			status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+		status = add_uniq_spn(frame, spn, &spn_array, &num_spns);
801d0a
+		if (!ADS_ERR_OK(status)) {
801d0a
 			goto done;
801d0a
 		}
801d0a
 	}
801d0a
-- 
801d0a
2.21.0
801d0a
801d0a
801d0a
From db7560ff0fb861552406bb4c422cff55c82f58bf Mon Sep 17 00:00:00 2001
801d0a
From: Isaac Boukris <iboukris@gmail.com>
801d0a
Date: Tue, 17 Sep 2019 21:38:07 +0300
801d0a
Subject: [PATCH 5/6] docs-xml: add "additional dns hostnames" smb.conf option
801d0a
801d0a
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14116
801d0a
801d0a
Signed-off-by: Isaac Boukris <iboukris@redhat.com>
801d0a
Reviewed-by: Ralph Boehme <slow@samba.org>
801d0a
Reviewed-by: Alexander Bokovoy <ab@samba.org>
801d0a
---
801d0a
 docs-xml/smbdotconf/base/additionaldnshostnames.xml | 11 +++++++++++
801d0a
 1 file changed, 11 insertions(+)
801d0a
 create mode 100644 docs-xml/smbdotconf/base/additionaldnshostnames.xml
801d0a
801d0a
diff --git a/docs-xml/smbdotconf/base/additionaldnshostnames.xml b/docs-xml/smbdotconf/base/additionaldnshostnames.xml
801d0a
new file mode 100644
801d0a
index 00000000000..ddc04ee9f81
801d0a
--- /dev/null
801d0a
+++ b/docs-xml/smbdotconf/base/additionaldnshostnames.xml
801d0a
@@ -0,0 +1,11 @@
801d0a
+
801d0a
+                 context="G"
801d0a
+                 type="cmdlist"
801d0a
+                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
801d0a
+ <description>
801d0a
+        <para> A list of additional DNS names by which this host can be identified
801d0a
+        </para>
801d0a
+</description>
801d0a
+<value type="default"><comment>empty string (no additional dns names)</comment></value>
801d0a
+<value type="example"> host2.example.com host3.other.com </value>
801d0a
+</samba:parameter>
801d0a
-- 
801d0a
2.21.0
801d0a
801d0a
801d0a
From 2669cecc51f8f7d6675b4dac9b345b3c5a7fc879 Mon Sep 17 00:00:00 2001
801d0a
From: Isaac Boukris <iboukris@gmail.com>
801d0a
Date: Fri, 13 Sep 2019 10:56:10 +0300
801d0a
Subject: [PATCH 6/6] libnet_join: add SPNs for additional-dns-hostnames
801d0a
 entries
801d0a
MIME-Version: 1.0
801d0a
Content-Type: text/plain; charset=UTF-8
801d0a
Content-Transfer-Encoding: 8bit
801d0a
801d0a
and set msDS-AdditionalDnsHostName to the specified list.
801d0a
801d0a
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14116
801d0a
801d0a
Signed-off-by: Isaac Boukris <iboukris@redhat.com>
801d0a
Reviewed-by: Ralph Boehme <slow@samba.org>
801d0a
Reviewed-by: Alexander Bokovoy <ab@samba.org>
801d0a
801d0a
Autobuild-User(master): Ralph Böhme <slow@samba.org>
801d0a
Autobuild-Date(master): Fri Oct 25 10:43:08 UTC 2019 on sn-devel-184
801d0a
---
801d0a
 source3/libnet/libnet_join.c       | 27 +++++++++++++++++++++++++++
801d0a
 testprogs/blackbox/test_net_ads.sh | 10 +++++++++-
801d0a
 2 files changed, 36 insertions(+), 1 deletion(-)
801d0a
801d0a
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
801d0a
index a1d8a25bbc2..eb8e0ea17f7 100644
801d0a
--- a/source3/libnet/libnet_join.c
801d0a
+++ b/source3/libnet/libnet_join.c
801d0a
@@ -511,6 +511,7 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
801d0a
 	size_t num_spns = 0;
801d0a
 	char *spn = NULL;
801d0a
 	const char **netbios_aliases = NULL;
801d0a
+	const char **addl_hostnames = NULL;
801d0a
 
801d0a
 	/* Find our DN */
801d0a
 
801d0a
@@ -602,6 +603,22 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
801d0a
 		}
801d0a
 	}
801d0a
 
801d0a
+	for (addl_hostnames = lp_additional_dns_hostnames();
801d0a
+	     addl_hostnames != NULL && *addl_hostnames != NULL;
801d0a
+	     addl_hostnames++) {
801d0a
+
801d0a
+		spn = talloc_asprintf(frame, "HOST/%s", *addl_hostnames);
801d0a
+		if (spn == NULL) {
801d0a
+			status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
801d0a
+			goto done;
801d0a
+		}
801d0a
+
801d0a
+		status = add_uniq_spn(frame, spn, &spn_array, &num_spns);
801d0a
+		if (!ADS_ERR_OK(status)) {
801d0a
+			goto done;
801d0a
+		}
801d0a
+	}
801d0a
+
801d0a
 	/* make sure to NULL terminate the array */
801d0a
 	spn_array = talloc_realloc(frame, spn_array, const char *, num_spns + 1);
801d0a
 	if (spn_array == NULL) {
801d0a
@@ -629,6 +646,16 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
801d0a
 		goto done;
801d0a
 	}
801d0a
 
801d0a
+	addl_hostnames = lp_additional_dns_hostnames();
801d0a
+	if (addl_hostnames != NULL && *addl_hostnames != NULL) {
801d0a
+		status = ads_mod_strlist(mem_ctx, &mods,
801d0a
+					 "msDS-AdditionalDnsHostName",
801d0a
+					 addl_hostnames);
801d0a
+		if (!ADS_ERR_OK(status)) {
801d0a
+			goto done;
801d0a
+		}
801d0a
+	}
801d0a
+
801d0a
 	status = ads_gen_mod(r->in.ads, r->out.dn, mods);
801d0a
 
801d0a
 done:
801d0a
diff --git a/testprogs/blackbox/test_net_ads.sh b/testprogs/blackbox/test_net_ads.sh
801d0a
index ef6f99ddea4..8bcff006b8e 100755
801d0a
--- a/testprogs/blackbox/test_net_ads.sh
801d0a
+++ b/testprogs/blackbox/test_net_ads.sh
801d0a
@@ -202,13 +202,21 @@ base_dn="DC=addom,DC=samba,DC=example,DC=com"
801d0a
 computers_dn="CN=Computers,$base_dn"
801d0a
 testit "ldb check for existence of machine account" $ldbsearch -U$DC_USERNAME%$DC_PASSWORD -H ldap://$SERVER.$REALM -s base -b "cn=$HOSTNAME,$computers_dn" || failed=`expr $failed + 1`
801d0a
 
801d0a
-testit "join" $VALGRIND $net_tool ads join -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1`
801d0a
+dns_alias1="${netbios}_alias1.other.${lc_realm}"
801d0a
+dns_alias2="${netbios}_alias2.other2.${lc_realm}"
801d0a
+testit "join" $VALGRIND $net_tool --option=additionaldnshostnames=$dns_alias1,$dns_alias2 ads join -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1`
801d0a
 
801d0a
 testit "testjoin" $VALGRIND $net_tool ads testjoin || failed=`expr $failed + 1`
801d0a
 
801d0a
 testit_grep "check dNSHostName" $fqdn $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ dNSHostName || failed=`expr $failed + 1`
801d0a
 testit_grep "check SPN" ${uc_netbios}.${lc_realm} $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ servicePrincipalName || failed=`expr $failed + 1`
801d0a
 
801d0a
+testit_grep "dns alias SPN" $dns_alias1 $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ servicePrincipalName || failed=`expr $failed + 1`
801d0a
+testit_grep "dns alias SPN" $dns_alias2 $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ servicePrincipalName || failed=`expr $failed + 1`
801d0a
+
801d0a
+testit_grep "dns alias addl" $dns_alias1 $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ msDS-AdditionalDnsHostName || failed=`expr $failed + 1`
801d0a
+testit_grep "dns alias addl" $dns_alias2 $VALGRIND $net_tool ads search -P samaccountname=$netbios\$ msDS-AdditionalDnsHostName || failed=`expr $failed + 1`
801d0a
+
801d0a
 ##Goodbye...
801d0a
 testit "leave" $VALGRIND $net_tool ads leave -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1`
801d0a
 
801d0a
-- 
801d0a
2.21.0
801d0a