[SCM] Samba Shared Repository - branch v4-0-test updated

Karolin Seeger kseeger at samba.org
Thu Oct 9 15:26:02 MDT 2014


The branch, v4-0-test has been updated
       via  6642684 s3: smb2cli: query info return length check was reversed.
       via  c6493fc s3-libads: Add all machine account principals to the keytab.
       via  bbf24d3 registry: Don't leave dangling transactions
       via  f88c106 s3-winbindd: Do not use domain SID from LookupSids for Sids2UnixIDs call
       via  f42f4d0 s3: Move init_lsa_ref_domain_list to lib
       via  372f228 s3-libnet: Make sure we do not overwrite precreated SPNs.
       via  f0b99bc s3-libnet: Add libnet_join_get_machine_spns().
       via  4e2e567 s3-libads: Add function to search for an element in an array.
       via  1d16c07 s3-libads: Add a function to retrieve the SPNs of a computer account.
      from  29f42cb s3-libads: Improve service principle guessing.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v4-0-test


- Log -----------------------------------------------------------------
commit 6642684cc01545e59613ee0845c1ee2dfffee478
Author: Jeremy Allison <jra at samba.org>
Date:   Wed Oct 1 14:20:10 2014 -0700

    s3: smb2cli: query info return length check was reversed.
    
    Make it identical to the check in libcli/smb/smb2cli_ioctl.c
    
    https://bugzilla.samba.org/show_bug.cgi?id=10848
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: "Stefan (metze) Metzmacher" <metze at samba.org>
    Reviewed-by: David Disseldorp <ddiss at suse.de>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Thu Oct  2 04:42:26 CEST 2014 on sn-devel-104
    
    (cherry picked from commit 6c05cd3e895831be7d9a68a51de2048d04c188a0)
    
    Autobuild-User(v4-0-test): Karolin Seeger <kseeger at samba.org>
    Autobuild-Date(v4-0-test): Thu Oct  9 23:25:47 CEST 2014 on sn-devel-104

commit c6493fcfb5a5d3a91f4b1b0134fef9e0f2754470
Author: Andreas Schneider <asn at samba.org>
Date:   Wed Sep 24 10:51:33 2014 +0200

    s3-libads: Add all machine account principals to the keytab.
    
    This adds all SPNs defined in the DC for the computer account to the
    keytab using 'net ads keytab create -P'.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=9985
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    (cherry picked from commit 5d58b92f8fcbc509f4fe2bd3617bcaeada1806b6)

commit bbf24d39b4c0ba81767bcdb67d5cd7c01604b16c
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Oct 8 15:39:28 2014 +0200

    registry: Don't leave dangling transactions
    
    When a createkey fails due to access denied, we need to do a
    transaction_cancel. Otherwise the lock on the db will stay around.
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=10860

commit f88c10665e628eed0b03bcabef3216b32e1bc05b
Author: Christof Schmitt <cs at samba.org>
Date:   Thu Sep 11 16:39:21 2014 -0700

    s3-winbindd: Do not use domain SID from LookupSids for Sids2UnixIDs call
    
    Create a new lsa_RefDomainList and populate it with the domain SID from
    the original query. That avoids the problem that for migrated objects,
    LookupSids returns the SID of the new domain, and combining that with
    the RID from the input results in an invalid SID.
    
    A better fix would be querying the RID of the user in the new domain,
    but the approach here at least avoids id mappings entries for invalid
    SIDs.
    
    Signed-off-by: Christof Schmitt <cs at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    
    Autobuild-User(master): Volker Lendecke <vl at samba.org>
    Autobuild-Date(master): Mon Sep 29 13:15:18 CEST 2014 on sn-devel-104
    
    (cherry picked from commit 9c9216410faf707edc4ba05f2b715d45f7f51ca4)
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=10838
    Invalid id mappings for users/groups migrated from another domain

commit f42f4d0a197f73050fdabd663a6472d396a74b80
Author: Christof Schmitt <cs at samba.org>
Date:   Thu Sep 11 16:11:06 2014 -0700

    s3: Move init_lsa_ref_domain_list to lib
    
    This will be used in the next patch in winbind.
    
    Signed-off-by: Christof Schmitt <cs at samba.org>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    
    (cherry picked from commit 16594e7fc0a46249a48d0d0635de0c1050ecd340)

commit 372f22891a654b7d99d9e98083b05955d5bc89be
Author: Günther Deschner <gd at samba.org>
Date:   Fri Sep 26 03:35:43 2014 +0200

    s3-libnet: Make sure we do not overwrite precreated SPNs.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=9984
    
    Signed-off-by: Günther Deschner <gd at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    
    Autobuild-User(master): Günther Deschner <gd at samba.org>
    Autobuild-Date(master): Fri Sep 26 08:22:45 CEST 2014 on sn-devel-104
    
    (cherry picked from commit 0aacbe78bb40d76b65087c2a197c92b0101e625e)

commit f0b99bc57240bb8c65fcc6974353eed6cd740773
Author: Andreas Schneider <asn at samba.org>
Date:   Fri Sep 26 03:09:08 2014 +0200

    s3-libnet: Add libnet_join_get_machine_spns().
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=9984
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    (cherry picked from commit 7e0b8fcce5572c88d50993a1dbd90f65638ba90f)

commit 4e2e567feb583aed0107c13910ddeaeeaf12186b
Author: Andreas Schneider <asn at samba.org>
Date:   Wed Sep 24 09:23:58 2014 +0200

    s3-libads: Add function to search for an element in an array.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=9984
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    (cherry picked from commit e1ee4c8bc7018db7787dd9a0be6d3aa40a477ee2)

commit 1d16c077e04eadfd4c2a3ac9732852451dfd9e86
Author: Andreas Schneider <asn at samba.org>
Date:   Wed Sep 24 09:22:03 2014 +0200

    s3-libads: Add a function to retrieve the SPNs of a computer account.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=9984
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>
    (cherry picked from commit 4eaa4ccbdf279f1ff6d8218b36d92aeea0114cd8)

-----------------------------------------------------------------------

Summary of changes:
 libcli/smb/smb2cli_query_info.c               |    2 +-
 source3/Makefile.in                           |    4 +
 source3/{lib/version_test.c => include/lsa.h} |   17 ++---
 source3/lib/lsa.c                             |   67 ++++++++++++++++++
 source3/libads/ads_proto.h                    |    8 ++
 source3/libads/kerberos_keytab.c              |   74 ++++++++++++++------
 source3/libads/ldap.c                         |   91 +++++++++++++++++++++++++
 source3/libnet/libnet_join.c                  |   59 +++++++++++++++-
 source3/registry/reg_api.c                    |    2 +-
 source3/rpc_server/lsa/srv_lsa_nt.c           |   48 +-------------
 source3/rpc_server/wscript_build              |    2 +-
 source3/winbindd/wb_sids2xids.c               |   33 ++++++++-
 source3/wscript_build                         |    4 +
 13 files changed, 324 insertions(+), 87 deletions(-)
 copy source3/{lib/version_test.c => include/lsa.h} (74%)
 create mode 100644 source3/lib/lsa.c


Changeset truncated at 500 lines:

diff --git a/libcli/smb/smb2cli_query_info.c b/libcli/smb/smb2cli_query_info.c
index 80cec9c..0be3736 100644
--- a/libcli/smb/smb2cli_query_info.c
+++ b/libcli/smb/smb2cli_query_info.c
@@ -152,7 +152,7 @@ static void smb2cli_query_info_done(struct tevent_req *subreq)
 			return;
 		}
 
-		if (output_buffer_length < dyn_len) {
+		if (output_buffer_length > dyn_len) {
 			tevent_req_nterror(
 				req, NT_STATUS_INVALID_NETWORK_RESPONSE);
 			return;
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 8d2a2cd..9c1f0b9 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -723,6 +723,8 @@ REG_FULL_OBJ = $(REG_SMBCONF_OBJ) \
 
 LIB_EVENTLOG_OBJ = lib/eventlog/eventlog.o
 
+LIB_LSA = lib/lsa.o
+
 DCE_RPC_EP_OBJ = librpc/rpc/dcerpc_ep.o
 
 RPC_LSARPC_OBJ = rpc_server/lsa/srv_lsa_nt.o \
@@ -806,6 +808,7 @@ RPC_SERVER_OBJ = $(RPC_LSARPC_OBJ) $(RPC_WINREG_OBJ) $(RPC_INITSHUTDOWN_OBJ) \
 		 $(LIBCLI_SRVSVC_OBJ) \
 		 $(LIBCLI_LSA_OBJ) \
 		 $(LIBCLI_SAMR_OBJ) \
+		 $(LIB_LSA) \
 		 $(RPC_SERVER_REGISTER_OBJ) \
 		 $(RPC_CLIENT_SCHANNEL_OBJ) \
 		 rpc_server/rpc_sock_helper.o \
@@ -1480,6 +1483,7 @@ WINBINDD_OBJ = \
 		$(LIBCLI_DSSETUP_OBJ) \
 		$(LIBCLI_LSA_OBJ) \
 		$(LIBCLI_SAMR_OBJ) \
+		$(LIB_LSA) \
 		rpc_client/init_samr.o \
 		$(PAM_ERRORS_OBJ)
 
diff --git a/source3/lib/version_test.c b/source3/include/lsa.h
similarity index 74%
copy from source3/lib/version_test.c
copy to source3/include/lsa.h
index 880cfeb..7681aed 100644
--- a/source3/lib/version_test.c
+++ b/source3/include/lsa.h
@@ -1,7 +1,5 @@
 /*
- *  Unix SMB/CIFS implementation.
- *  version_test - test program for samba_version_strion()
- *  Copyright (C) Michael Adam 2009
+ * Helper functions related to the LSA server
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -16,11 +14,12 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
+#ifndef LSA_H
+#define LSA_H
 
-#include "includes.h"
+int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
+			     struct lsa_RefDomainList *ref,
+			     const char *dom_name,
+			     struct dom_sid *dom_sid);
 
-int main(void)
-{
-	printf("%s\n", samba_version_string());
-	return 0;
-}
+#endif
diff --git a/source3/lib/lsa.c b/source3/lib/lsa.c
new file mode 100644
index 0000000..0046fda
--- /dev/null
+++ b/source3/lib/lsa.c
@@ -0,0 +1,67 @@
+/*
+ * Helper functions related to the LSA server
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/***************************************************************************
+ init_lsa_ref_domain_list - adds a domain if it's not already in, returns index.
+***************************************************************************/
+
+#include "includes.h"
+#include "libcli/security/dom_sid.h"
+#include "librpc/gen_ndr/lsa.h"
+#include "lsa.h"
+
+int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx,
+			     struct lsa_RefDomainList *ref,
+			     const char *dom_name,
+			     struct dom_sid *dom_sid)
+{
+	int num = 0;
+
+	if (dom_name != NULL) {
+		for (num = 0; num < ref->count; num++) {
+			if (dom_sid_equal(dom_sid, ref->domains[num].sid)) {
+				return num;
+			}
+		}
+	} else {
+		num = ref->count;
+	}
+
+	if (num >= LSA_REF_DOMAIN_LIST_MULTIPLIER) {
+		/* index not found, already at maximum domain limit */
+		return -1;
+	}
+
+	ref->count = num + 1;
+	ref->max_size = LSA_REF_DOMAIN_LIST_MULTIPLIER;
+
+	ref->domains = talloc_realloc(mem_ctx, ref->domains,
+					    struct lsa_DomainInfo, ref->count);
+	if (!ref->domains) {
+		return -1;
+	}
+
+	ZERO_STRUCT(ref->domains[num]);
+
+	ref->domains[num].name.string = dom_name;
+	ref->domains[num].sid = dom_sid_dup(mem_ctx, dom_sid);
+	if (!ref->domains[num].sid) {
+		return -1;
+	}
+
+	return num;
+}
diff --git a/source3/libads/ads_proto.h b/source3/libads/ads_proto.h
index 17a84d1..1e34247 100644
--- a/source3/libads/ads_proto.h
+++ b/source3/libads/ads_proto.h
@@ -87,6 +87,14 @@ ADS_STATUS ads_add_strlist(TALLOC_CTX *ctx, ADS_MODLIST *mods,
 				const char *name, const char **vals);
 uint32 ads_get_kvno(ADS_STRUCT *ads, const char *account_name);
 uint32_t ads_get_machine_kvno(ADS_STRUCT *ads, const char *machine_name);
+
+bool ads_element_in_array(const char **el_array, size_t num_el, const char *el);
+
+ADS_STATUS ads_get_service_principal_names(TALLOC_CTX *mem_ctx,
+					   ADS_STRUCT *ads,
+					   const char *machine_name,
+					   char ***spn_array,
+					   size_t *num_spns);
 ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char *machine_name);
 ADS_STATUS ads_add_service_principal_name(ADS_STRUCT *ads, const char *machine_name,
                                           const char *my_fqdn, const char *spn);
diff --git a/source3/libads/kerberos_keytab.c b/source3/libads/kerberos_keytab.c
index b7df50d..f9a0193 100644
--- a/source3/libads/kerberos_keytab.c
+++ b/source3/libads/kerberos_keytab.c
@@ -507,20 +507,57 @@ int ads_keytab_create_default(ADS_STRUCT *ads)
 	krb5_kt_cursor cursor;
 	krb5_keytab_entry kt_entry;
 	krb5_kvno kvno;
-	int i, found = 0;
+	size_t found = 0;
 	char *sam_account_name, *upn;
 	char **oldEntries = NULL, *princ_s[26];
-	TALLOC_CTX *tmpctx = NULL;
+	TALLOC_CTX *frame;
 	char *machine_name;
+	char **spn_array;
+	size_t num_spns;
+	size_t i;
+	ADS_STATUS status;
 
-	/* these are the main ones we need */
-	ret = ads_keytab_add_entry(ads, "host");
-	if (ret != 0) {
-		DEBUG(1, (__location__ ": ads_keytab_add_entry failed while "
-			  "adding 'host' principal.\n"));
-		return ret;
+	frame = talloc_stackframe();
+	if (frame == NULL) {
+		ret = -1;
+		goto done;
+	}
+
+	status = ads_get_service_principal_names(frame,
+						 ads,
+						 lp_netbios_name(),
+						 &spn_array,
+						 &num_spns);
+	if (!ADS_ERR_OK(status)) {
+		ret = -1;
+		goto done;
 	}
 
+	for (i = 0; i < num_spns; i++) {
+		char *srv_princ;
+		char *p;
+
+		srv_princ = strlower_talloc(frame, spn_array[i]);
+		if (srv_princ == NULL) {
+			ret = -1;
+			goto done;
+		}
+
+		p = strchr_m(srv_princ, '/');
+		if (p == NULL) {
+			continue;
+		}
+		p[0] = '\0';
+
+		/* Add the SPNs found on the DC */
+		ret = ads_keytab_add_entry(ads, srv_princ);
+		if (ret != 0) {
+			DEBUG(1, ("ads_keytab_add_entry failed while "
+				  "adding '%s' principal.\n",
+				  spn_array[i]));
+			goto done;
+		}
+	}
 
 #if 0	/* don't create the CIFS/... keytab entries since no one except smbd
 	   really needs them and we will fall back to verifying against
@@ -543,24 +580,17 @@ int ads_keytab_create_default(ADS_STRUCT *ads)
 	if (ret) {
 		DEBUG(1, (__location__ ": could not krb5_init_context: %s\n",
 			  error_message(ret)));
-		return ret;
-	}
-
-	tmpctx = talloc_init(__location__);
-	if (!tmpctx) {
-		DEBUG(0, (__location__ ": talloc_init() failed!\n"));
-		ret = -1;
 		goto done;
 	}
 
-	machine_name = talloc_strdup(tmpctx, lp_netbios_name());
+	machine_name = talloc_strdup(frame, lp_netbios_name());
 	if (!machine_name) {
 		ret = -1;
 		goto done;
 	}
 
 	/* now add the userPrincipalName and sAMAccountName entries */
-	sam_account_name = ads_get_samaccountname(ads, tmpctx, machine_name);
+	sam_account_name = ads_get_samaccountname(ads, frame, machine_name);
 	if (!sam_account_name) {
 		DEBUG(0, (__location__ ": unable to determine machine "
 			  "account's name in AD!\n"));
@@ -584,7 +614,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads)
 	}
 
 	/* remember that not every machine account will have a upn */
-	upn = ads_get_upn(ads, tmpctx, machine_name);
+	upn = ads_get_upn(ads, frame, machine_name);
 	if (upn) {
 		ret = ads_keytab_add_entry(ads, upn);
 		if (ret != 0) {
@@ -596,7 +626,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads)
 
 	/* Now loop through the keytab and update any other existing entries */
 	kvno = (krb5_kvno)ads_get_machine_kvno(ads, machine_name);
-	if (kvno == -1) {
+	if (kvno == (krb5_kvno)-1) {
 		DEBUG(1, (__location__ ": ads_get_machine_kvno() failed to "
 			  "determine the system's kvno.\n"));
 		goto done;
@@ -629,12 +659,12 @@ int ads_keytab_create_default(ADS_STRUCT *ads)
 	 * have a race condition where someone else could add entries after
 	 * we've counted them. Re-open asap to minimise the race. JRA.
 	 */
-	DEBUG(3, (__location__ ": Found %d entries in the keytab.\n", found));
+	DEBUG(3, (__location__ ": Found %zd entries in the keytab.\n", found));
 	if (!found) {
 		goto done;
 	}
 
-	oldEntries = talloc_array(tmpctx, char *, found);
+	oldEntries = talloc_array(frame, char *, found);
 	if (!oldEntries) {
 		DEBUG(1, (__location__ ": Failed to allocate space to store "
 			  "the old keytab entries (talloc failed?).\n"));
@@ -708,7 +738,7 @@ int ads_keytab_create_default(ADS_STRUCT *ads)
 
 done:
 	TALLOC_FREE(oldEntries);
-	TALLOC_FREE(tmpctx);
+	TALLOC_FREE(frame);
 
 	{
 		krb5_keytab_entry zero_kt_entry;
diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c
index 20c2e31..dfec70e 100644
--- a/source3/libads/ldap.c
+++ b/source3/libads/ldap.c
@@ -1909,6 +1909,97 @@ ADS_STATUS ads_clear_service_principal_names(ADS_STRUCT *ads, const char *machin
 }
 
 /**
+ * @brief Search for an element in a string array.
+ *
+ * @param[in]  el_array  The string array to search.
+ *
+ * @param[in]  num_el    The number of elements in the string array.
+ *
+ * @param[in]  el        The string to search.
+ *
+ * @return               True if found, false if not.
+ */
+bool ads_element_in_array(const char **el_array, size_t num_el, const char *el)
+{
+	size_t i;
+
+	if (el_array == NULL || num_el == 0 || el == NULL) {
+		return false;
+	}
+
+	for (i = 0; i < num_el && el_array[i] != NULL; i++) {
+		int cmp;
+
+		cmp = strcasecmp_m(el_array[i], el);
+		if (cmp == 0) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+/**
+ * @brief This gets the service principal names of an existing computer account.
+ *
+ * @param[in]  mem_ctx      The memory context to use to allocate the spn array.
+ *
+ * @param[in]  ads          The ADS context to use.
+ *
+ * @param[in]  machine_name The NetBIOS name of the computer, which is used to
+ *                          identify the computer account.
+ *
+ * @param[in]  spn_array    A pointer to store the array for SPNs.
+ *
+ * @param[in]  num_spns     The number of principals stored in the array.
+ *
+ * @return                  0 on success, or a ADS error if a failure occured.
+ */
+ADS_STATUS ads_get_service_principal_names(TALLOC_CTX *mem_ctx,
+					   ADS_STRUCT *ads,
+					   const char *machine_name,
+					   char ***spn_array,
+					   size_t *num_spns)
+{
+	ADS_STATUS status;
+	LDAPMessage *res = NULL;
+	char *dn;
+	int count;
+
+	status = ads_find_machine_acct(ads,
+				       &res,
+				       machine_name);
+	if (!ADS_ERR_OK(status)) {
+		DEBUG(1,("Host Account for %s not found... skipping operation.\n",
+			 machine_name));
+		return status;
+	}
+
+	count = ads_count_replies(ads, res);
+	if (count != 1) {
+		status = ADS_ERROR(LDAP_NO_SUCH_OBJECT);
+		goto done;
+	}
+
+	dn = ads_get_dn(ads, mem_ctx, res);
+	if (dn == NULL) {
+		status = ADS_ERROR_LDAP(LDAP_NO_MEMORY);
+		goto done;
+	}
+
+	*spn_array = ads_pull_strings(ads,
+				      mem_ctx,
+				      res,
+				      "servicePrincipalName",
+				      num_spns);
+
+done:
+	ads_msgfree(ads, res);
+
+	return status;
+}
+
+/**
  * This adds a service principal name to an existing computer account
  * (found by hostname) in AD.
  * @param ads An initialized ADS_STRUCT
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index 22e6675..dcb04db 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -358,6 +358,26 @@ static ADS_STATUS libnet_join_find_machine_acct(TALLOC_CTX *mem_ctx,
 	return status;
 }
 
+static ADS_STATUS libnet_join_get_machine_spns(TALLOC_CTX *mem_ctx,
+					       struct libnet_JoinCtx *r,
+					       char ***spn_array,
+					       size_t *num_spns)
+{
+	ADS_STATUS status;
+
+	if (r->in.machine_name == NULL) {
+		return ADS_ERROR_SYSTEM(EINVAL);
+	}
+
+	status = ads_get_service_principal_names(mem_ctx,
+						 r->in.ads,
+						 r->in.machine_name,
+						 spn_array,
+						 num_spns);
+
+	return status;
+}
+
 /****************************************************************
  Set a machines dNSHostName and servicePrincipalName attributes
 ****************************************************************/
@@ -368,8 +388,10 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
 	ADS_STATUS status;
 	ADS_MODLIST mods;
 	fstring my_fqdn;
-	const char *spn_array[3] = {NULL, NULL, NULL};
+	const char **spn_array = NULL;
+	size_t num_spns = 0;
 	char *spn = NULL;
+	bool ok;
 
 	/* Find our DN */
 
@@ -378,6 +400,14 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
 		return status;
 	}
 
+	status = libnet_join_get_machine_spns(mem_ctx,
+					      r,
+					      discard_const_p(char **, &spn_array),
+					      &num_spns);
+	if (!ADS_ERR_OK(status)) {
+		DEBUG(5, ("Retrieving the servicePrincipalNames failed.\n"));
+	}
+
 	/* Windows only creates HOST/shortname & HOST/fqdn. */
 
 	spn = talloc_asprintf(mem_ctx, "HOST/%s", r->in.machine_name);
@@ -387,7 +417,15 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
 	if (!strupper_m(spn)) {
 		return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
 	}
-	spn_array[0] = spn;
+
+	ok = ads_element_in_array(spn_array, num_spns, spn);
+	if (!ok) {
+		ok = add_string_to_array(spn_array, spn,
+					 &spn_array, (int *)&num_spns);
+		if (!ok) {
+			return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
+		}
+	}
 
 	if (!name_to_fqdn(my_fqdn, r->in.machine_name)
 	    || (strchr(my_fqdn, '.') == NULL)) {
@@ -404,8 +442,23 @@ static ADS_STATUS libnet_join_set_machine_spn(TALLOC_CTX *mem_ctx,
 		if (!spn) {
 			return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
 		}
-		spn_array[1] = spn;
+
+		ok = ads_element_in_array(spn_array, num_spns, spn);
+		if (!ok) {
+			ok = add_string_to_array(spn_array, spn,
+						 &spn_array, (int *)&num_spns);
+			if (!ok) {
+				return ADS_ERROR_LDAP(LDAP_NO_MEMORY);
+			}
+		}
+	}


-- 
Samba Shared Repository


More information about the samba-cvs mailing list