[SCM] Samba Shared Repository - branch master updated

Amitay Isaacs amitay at samba.org
Mon Nov 28 23:39:01 MST 2011


The branch, master has been updated
       via  8eef716 s4-provision: Fix the security ace for DnsAdmins group on DNS records
       via  2e4bf8b s4-repl: Check if GC SPN exists before using it for replication
       via  1e935d1 s4-provision: Make BIND9_DLZ as the default backend for DNS
       via  7ac5c50 dlz_bind9: Added access check to verify dynamic update
       via  dcc5a7e dlz_bind9: Use the sam database in dns/ as default
       via  341979c s4-provision: Create a samdb copy for access by dlz_bind9 module
       via  6822eae s4-provision: Extract security descriptors in separate file
       via  5184fc8 s4-test: Remove metadata and ldb.d directory on clean up
       via  13545d7 s4-samdb: seqence_number() operation must be in a transaction
       via  49926a2 s4-dsdb: Added metadata to partition module for global sequence number
       via  349c545 s4-dsdb: use dsdb_module_extended instead of duplicate code
       via  422fcbb s4-dsdb: Return ldb_result context in dsdb_module_extended
       via  c199b35 s4-dsdb: Remove LDB_SEQ_HIGHEST_TIMESTAMP sequence number support
      from  5c53926 s3: Use tevent_req_simple_recv_ntstatus

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 8eef716598fa30b216ba144c74bcf5dfcfa870fd
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Mon Nov 28 14:18:31 2011 +1100

    s4-provision: Fix the security ace for DnsAdmins group on DNS records
    
    Find the objectSid for DnsAdmins group and use that instead of a fixed sid.
    
    Autobuild-User: Amitay Isaacs <amitay at samba.org>
    Autobuild-Date: Tue Nov 29 07:38:06 CET 2011 on sn-devel-104

commit 2e4bf8bfcdf7dea3beb754125c45e337a4afb228
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Mon Nov 28 10:33:53 2011 +1100

    s4-repl: Check if GC SPN exists before using it for replication
    
    Sometimes windows DC will set up dNSHostname before setting up
    GC SPN and that causes replication errors since samba tries to
    use GC SPN, which does not yet exist locally.
    
    Pair-Programmed-With: Andrew Tridgell <tridge at samba.org>

commit 1e935d1bdc095187b68cd93ff8a1ee9498f8ad11
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Fri Nov 25 15:43:53 2011 +1100

    s4-provision: Make BIND9_DLZ as the default backend for DNS

commit 7ac5c5061eafa3f6b3c85ab68eefc007564cadcb
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Wed Nov 2 14:32:37 2011 +1100

    dlz_bind9: Added access check to verify dynamic update
    
    This creates session info from kerberos ticket and verifies if
    the signer has write access to a particular DN corresponding
    to the name in dynamic update.
    
    Pair-Programmed-With: Andrew Tridgell <tridge at samba.org>

commit dcc5a7e1f23a8d24daf3f0ca16914f430d72858e
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Fri Sep 16 08:54:05 2011 +1000

    dlz_bind9: Use the sam database in dns/ as default
    
    This change is introduced to access samdb copy directly, rather
    than over ildap. The advantage is that the samba server does not
    need to be running for bind9 to start.

commit 341979cc9a14fa0ab1cbb60ae81ce1fb985d0f0e
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Sep 20 09:58:42 2011 +1000

    s4-provision: Create a samdb copy for access by dlz_bind9 module
    
    This creates a copy of rootdse, configuration and schema partitions
    for dlz_bind9 use in dns/ directory.  Since dlz_bind9 requires write
    access to DNS partitions (DomainDnsZones and ForestDnsZones), those
    partitions are hard-linked (or symlinked) to the actual partitions.
    An empty domain partition is created so samdb layer can work.

commit 6822eae32395889bf56266f89d9a7f749b8cb512
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Wed Nov 23 15:10:58 2011 +1100

    s4-provision: Extract security descriptors in separate file
    
    Need to use domain security descriptor from sambadns.py also.

commit 5184fc889327d6e2fb7b446140bd17ea30cb3920
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Nov 29 11:15:05 2011 +1100

    s4-test: Remove metadata and ldb.d directory on clean up
    
    When using partitions, metadata.tdb automatically gets created in
    ${prefix}ldb.d/ directory. To correctly clean up check if metadata.tdb
    exists, then remove metadata.tdb and directory.

commit 13545d781b257afe3c3a107a669851c38cdfefbd
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Mon Nov 28 17:19:50 2011 +1100

    s4-samdb: seqence_number() operation must be in a transaction

commit 49926a2ac66b9bbaa50735b78a3bf0385c2cf48d
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Mon Nov 14 17:38:04 2011 +1100

    s4-dsdb: Added metadata to partition module for global sequence number
    
    This adds support for global sequence number which is independent of
    partition information.
    
    Signed-off-by: Andrew Tridgell <tridge at samba.org>

commit 349c54528b82946683290f436eb7220ca59505fe
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Mon Nov 14 14:14:58 2011 +1100

    s4-dsdb: use dsdb_module_extended instead of duplicate code
    
    Signed-off-by: Andrew Tridgell <tridge at samba.org>

commit 422fcbbe7244a0c14aeca5cda7f2a28e2ee821b5
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Mon Nov 14 13:52:34 2011 +1100

    s4-dsdb: Return ldb_result context in dsdb_module_extended
    
    The result of the extended operation is now available in the calling
    routine.
    
    Signed-off-by: Andrew Tridgell <tridge at samba.org>

commit c199b35dd46b2de21d89ed93edb9a815035717fc
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Nov 22 16:51:04 2011 +1100

    s4-dsdb: Remove LDB_SEQ_HIGHEST_TIMESTAMP sequence number support
    
    This was a hack for LDAP backends to store a sequence number as a
    timestamp. It is still supported in standalone ldb tdb backend.
    
    Signed-off-by: Andrew Tridgell <tridge at samba.org>

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

Summary of changes:
 source4/dns_server/dlz_bind9.c                     |  248 +++++++---
 source4/dns_server/wscript_build                   |    2 +-
 source4/dsdb/repl/drepl_partitions.c               |   57 +++-
 source4/dsdb/samdb/ldb_modules/partition.c         |  284 +++++-------
 source4/dsdb/samdb/ldb_modules/partition.h         |    7 +
 source4/dsdb/samdb/ldb_modules/partition_init.c    |    8 +-
 .../dsdb/samdb/ldb_modules/partition_metadata.c    |  492 ++++++++++++++++++++
 source4/dsdb/samdb/ldb_modules/simple_ldap_map.c   |    7 +-
 source4/dsdb/samdb/ldb_modules/util.c              |   23 +-
 source4/dsdb/samdb/ldb_modules/wscript_build       |    2 +-
 source4/scripting/python/samba/join.py             |    2 +-
 .../scripting/python/samba/provision/__init__.py   |   82 +---
 .../scripting/python/samba/provision/descriptor.py |  163 +++++++
 .../scripting/python/samba/provision/sambadns.py   |  184 +++++---
 source4/scripting/python/samba/samdb.py            |   14 +
 source4/scripting/python/samba/tests/samba3sam.py  |    5 +
 source4/scripting/python/samba/upgrade.py          |    2 +-
 source4/scripting/python/samba/upgradehelpers.py   |    2 +-
 source4/setup/provision                            |    6 +-
 source4/setup/provision_basedn_options.ldif        |    2 +
 20 files changed, 1188 insertions(+), 404 deletions(-)
 create mode 100644 source4/dsdb/samdb/ldb_modules/partition_metadata.c
 create mode 100644 source4/scripting/python/samba/provision/descriptor.py
 create mode 100644 source4/setup/provision_basedn_options.ldif


Changeset truncated at 500 lines:

diff --git a/source4/dns_server/dlz_bind9.c b/source4/dns_server/dlz_bind9.c
index e37a66e..87476d3 100644
--- a/source4/dns_server/dlz_bind9.c
+++ b/source4/dns_server/dlz_bind9.c
@@ -25,21 +25,34 @@
 #include "lib/events/events.h"
 #include "dsdb/samdb/samdb.h"
 #include "dsdb/common/util.h"
+#include "auth/auth.h"
 #include "auth/session.h"
 #include "auth/gensec/gensec.h"
+#include "librpc/gen_ndr/security.h"
+#include "auth/credentials/credentials.h"
+#include "system/kerberos.h"
+#include "auth/kerberos/kerberos.h"
 #include "gen_ndr/ndr_dnsp.h"
-#include "lib/cmdline/popt_common.h"
-#include "lib/cmdline/popt_credentials.h"
-#include "ldb_module.h"
+#include "gen_ndr/server_id.h"
+#include "messaging/messaging.h"
 #include "dlz_minimal.h"
 
+
+struct b9_options {
+	const char *url;
+};
+
 struct dlz_bind9_data {
+	struct b9_options options;
 	struct ldb_context *samdb;
 	struct tevent_context *ev_ctx;
 	struct loadparm_context *lp;
 	int *transaction_token;
 	uint32_t soa_serial;
 
+	/* Used for dynamic update */
+	struct smb_krb5_context *smb_krb5_ctx;
+
 	/* helper functions from the dlz_dlopen driver */
 	void (*log)(int level, const char *fmt, ...);
 	isc_result_t (*putrr)(dns_sdlzlookup_t *handle, const char *type,
@@ -415,10 +428,6 @@ static isc_result_t b9_putnamedrr(struct dlz_bind9_data *state,
 	return result;
 }
 
-struct b9_options {
-	const char *url;
-};
-
 /*
    parse options
  */
@@ -426,42 +435,12 @@ static isc_result_t parse_options(struct dlz_bind9_data *state,
 				  unsigned int argc, char *argv[],
 				  struct b9_options *options)
 {
-	int opt;
-	poptContext pc;
-	struct poptOption long_options[] = {
-		{ "url",       'H', POPT_ARG_STRING, &options->url, 0, "database URL", "URL" },
-		{ NULL }
-	};
-	struct poptOption **popt_options;
-	int ret;
-
-	fault_setup_disable();
-
-	popt_options = ldb_module_popt_options(state->samdb);
-	(*popt_options) = long_options;
-
-	ret = ldb_modules_hook(state->samdb, LDB_MODULE_HOOK_CMDLINE_OPTIONS);
-	if (ret != LDB_SUCCESS) {
-		state->log(ISC_LOG_ERROR, "dlz samba: failed cmdline hook");
-		return ISC_R_FAILURE;
-	}
-
-	pc = poptGetContext("dlz_bind9", argc, (const char **)argv, *popt_options,
-			    POPT_CONTEXT_KEEP_FIRST);
-
-	while ((opt = poptGetNextOpt(pc)) != -1) {
-		switch (opt) {
-		default:
-			state->log(ISC_LOG_ERROR, "dlz samba: Invalid option %s: %s",
-				   poptBadOption(pc, 0), poptStrerror(opt));
-			return ISC_R_FAILURE;
+	if (argc == 2) {
+		options->url = talloc_strdup(state, argv[1]);
+		if (options->url == NULL) {
+			return ISC_R_NOMEMORY;
 		}
-	}
-
-	ret = ldb_modules_hook(state->samdb, LDB_MODULE_HOOK_CMDLINE_PRECONNECT);
-	if (ret != LDB_SUCCESS) {
-		state->log(ISC_LOG_ERROR, "dlz samba: failed cmdline preconnect");
-		return ISC_R_FAILURE;
+		state->log(ISC_LOG_INFO, "samba_dlz: Using samdb URL %s", options->url);
 	}
 
 	return ISC_R_SUCCESS;
@@ -480,11 +459,8 @@ _PUBLIC_ isc_result_t dlz_create(const char *dlzname,
 	va_list ap;
 	isc_result_t result;
 	TALLOC_CTX *tmp_ctx;
-	int ret;
 	struct ldb_dn *dn;
-	struct b9_options options;
-
-	ZERO_STRUCT(options);
+	NTSTATUS nt_status;
 
 	state = talloc_zero(NULL, struct dlz_bind9_data);
 	if (state == NULL) {
@@ -506,14 +482,7 @@ _PUBLIC_ isc_result_t dlz_create(const char *dlzname,
 		goto failed;
 	}
 
-	state->samdb = ldb_init(state, state->ev_ctx);
-	if (state->samdb == NULL) {
-		state->log(ISC_LOG_ERROR, "samba_dlz: Failed to create ldb");
-		result = ISC_R_FAILURE;
-		goto failed;
-	}
-
-	result = parse_options(state, argc, argv, &options);
+	result = parse_options(state, argc, argv, &state->options);
 	if (result != ISC_R_SUCCESS) {
 		goto failed;
 	}
@@ -524,27 +493,33 @@ _PUBLIC_ isc_result_t dlz_create(const char *dlzname,
 		goto failed;
 	}
 
-	if (options.url == NULL) {
-		options.url = talloc_asprintf(tmp_ctx, "ldapi://%s",
-					      lpcfg_private_path(tmp_ctx, state->lp, "ldap_priv/ldapi"));
-		if (options.url == NULL) {
+	if (smb_krb5_init_context(state, state->ev_ctx, state->lp, &state->smb_krb5_ctx) != 0) {
+		result = ISC_R_NOMEMORY;
+		goto failed;
+	}
+
+	nt_status = gensec_init();
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		talloc_free(tmp_ctx);
+		return false;
+	}
+
+	if (state->options.url == NULL) {
+		state->options.url = lpcfg_private_path(state, state->lp, "dns/sam.ldb");
+		if (state->options.url == NULL) {
 			result = ISC_R_NOMEMORY;
 			goto failed;
 		}
 	}
 
-	ret = ldb_connect(state->samdb, options.url, 0, NULL);
-	if (ret != LDB_SUCCESS) {
-		state->log(ISC_LOG_ERROR, "samba_dlz: Failed to connect to %s - %s",
-			   options.url, ldb_errstring(state->samdb));
-		result = ISC_R_FAILURE;
-		goto failed;
-	}
+	/* Do not install samba signal handlers */
+	fault_setup_disable();
 
-	ret = ldb_modules_hook(state->samdb, LDB_MODULE_HOOK_CMDLINE_POSTCONNECT);
-	if (ret != LDB_SUCCESS) {
-		state->log(ISC_LOG_ERROR, "samba_dlz: Failed postconnect for %s - %s",
-			   options.url, ldb_errstring(state->samdb));
+	state->samdb = samdb_connect_url(state, state->ev_ctx, state->lp,
+					system_session(state->lp), 0, state->options.url);
+	if (state->samdb == NULL) {
+		state->log(ISC_LOG_ERROR, "samba_dlz: Failed to connect to %s",
+			state->options.url);
 		result = ISC_R_FAILURE;
 		goto failed;
 	}
@@ -552,7 +527,7 @@ _PUBLIC_ isc_result_t dlz_create(const char *dlzname,
 	dn = ldb_get_default_basedn(state->samdb);
 	if (dn == NULL) {
 		state->log(ISC_LOG_ERROR, "samba_dlz: Unable to get basedn for %s - %s",
-			   options.url, ldb_errstring(state->samdb));
+			   state->options.url, ldb_errstring(state->samdb));
 		result = ISC_R_FAILURE;
 		goto failed;
 	}
@@ -1044,6 +1019,17 @@ _PUBLIC_ isc_result_t dlz_configure(dns_view_t *view, void *dbdata)
 	return ISC_R_SUCCESS;
 }
 
+static char *strlower(char *str)
+{
+	int i;
+
+	for (i=0; i<strlen(str); i++) {
+		str[i] = (char) tolower(str[i]);
+	}
+
+	return str;
+}
+
 /*
   authorize a zone update
  */
@@ -1052,9 +1038,127 @@ _PUBLIC_ isc_boolean_t dlz_ssumatch(const char *signer, const char *name, const
 				    void *dbdata)
 {
 	struct dlz_bind9_data *state = talloc_get_type_abort(dbdata, struct dlz_bind9_data);
+	TALLOC_CTX *tmp_ctx;
+	DATA_BLOB ap_req;
+	struct cli_credentials *server_credentials;
+	char *keytab_name, *username;
+	bool ret;
+	int ldb_ret;
+	NTSTATUS nt_status;
+	struct gensec_security *gensec_ctx;
+	struct auth_session_info *session_info;
+	struct ldb_dn *dn;
+	isc_result_t result;
+	struct ldb_result *res;
+	const char * attrs[] = { NULL };
+	uint32_t access_mask;
+
+	tmp_ctx = talloc_new(NULL);
+	if (tmp_ctx == NULL) {
+		state->log(ISC_LOG_ERROR, "samba_dlz: no memory");
+		return false;
+	}
+
+	ap_req = data_blob_const(keydata, keydatalen);
+	server_credentials = cli_credentials_init(tmp_ctx);
+	if (!server_credentials) {
+		state->log(ISC_LOG_ERROR, "samba_dlz: failed to init server credentials");
+		talloc_free(tmp_ctx);
+		return false;
+	}
+
+	cli_credentials_set_krb5_context(server_credentials, state->smb_krb5_ctx);
+	cli_credentials_set_conf(server_credentials, state->lp);
+
+	username = talloc_asprintf(tmp_ctx, "dns-%s", lpcfg_netbios_name(state->lp));
+	username = strlower(username);
+	cli_credentials_set_username(server_credentials, username, CRED_SPECIFIED);
+	talloc_free(username);
+
+	keytab_name = talloc_asprintf(tmp_ctx, "file:%s/dns.keytab",
+					lpcfg_private_dir(state->lp));
+	ret = cli_credentials_set_keytab_name(server_credentials, state->lp, keytab_name,
+						CRED_SPECIFIED);
+	talloc_free(keytab_name);
+	if (ret != 0) {
+		state->log(ISC_LOG_ERROR, "samba_dlz: failed to obtain server credentials for %s",
+				username);
+		talloc_free(tmp_ctx);
+		return false;
+	}
+
+	nt_status = gensec_server_start(tmp_ctx,
+					lpcfg_gensec_settings(tmp_ctx, state->lp),
+					NULL, &gensec_ctx);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		state->log(ISC_LOG_ERROR, "samba_dlz: failed to start gensec server");
+		talloc_free(tmp_ctx);
+		return false;
+	}
+
+	gensec_set_credentials(gensec_ctx, server_credentials);
+	gensec_set_target_service(gensec_ctx, "dns");
+
+	nt_status = gensec_start_mech_by_name(gensec_ctx, "spnego");
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		state->log(ISC_LOG_ERROR, "samba_dlz: failed to start spnego");
+		talloc_free(tmp_ctx);
+		return false;
+	}
+
+	nt_status = gensec_update(gensec_ctx, tmp_ctx, state->ev_ctx, ap_req, &ap_req);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		state->log(ISC_LOG_ERROR, "samba_dlz: spnego update failed");
+		talloc_free(tmp_ctx);
+		return false;
+	}
+
+	nt_status = gensec_session_info(gensec_ctx, tmp_ctx, &session_info);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		state->log(ISC_LOG_ERROR, "samba_dlz: failed to create session info");
+		talloc_free(tmp_ctx);
+		return false;
+	}
 
-	state->log(ISC_LOG_INFO, "samba_dlz: allowing update of signer=%s name=%s tcpaddr=%s type=%s key=%s keydatalen=%u",
-		   signer, name, tcpaddr, type, key, keydatalen);
+	/* Get the DN from name */
+	result = b9_find_name_dn(state, name, tmp_ctx, &dn);
+	if (result != ISC_R_SUCCESS) {
+		state->log(ISC_LOG_ERROR, "samba_dlz: failed to find name %s", name);
+		talloc_free(tmp_ctx);
+		return false;
+	}
+
+	/* make sure the dn exists, or find parent dn in case new object is being added */
+	ldb_ret = ldb_search(state->samdb, tmp_ctx, &res, dn, LDB_SCOPE_BASE,
+				attrs, "objectClass=dnsNode");
+	if (ldb_ret == LDB_ERR_NO_SUCH_OBJECT) {
+		ldb_dn_remove_child_components(dn, 1);
+		access_mask = SEC_STD_REQUIRED | SEC_ADS_CREATE_CHILD;
+		talloc_free(res);
+	} else if (ldb_ret == LDB_SUCCESS) {
+		access_mask = SEC_STD_REQUIRED | SEC_ADS_SELF_WRITE;
+		talloc_free(res);
+	} else {
+		talloc_free(tmp_ctx);
+		return false;
+	}
+
+	/* Do ACL check */
+	ldb_ret = dsdb_check_access_on_dn(state->samdb, tmp_ctx, dn,
+						session_info->security_token,
+						access_mask, NULL);
+	if (ldb_ret != LDB_SUCCESS) {
+		state->log(ISC_LOG_INFO,
+			"samba_dlz: disallowing update of signer=%s name=%s type=%s error=%s",
+			signer, name, type, ldb_strerror(ldb_ret));
+		talloc_free(tmp_ctx);
+		return false;
+	}
+
+	state->log(ISC_LOG_INFO, "samba_dlz: allowing update of signer=%s name=%s tcpaddr=%s type=%s key=%s",
+		   signer, name, tcpaddr, type, key);
+
+	talloc_free(tmp_ctx);
 	return true;
 }
 
diff --git a/source4/dns_server/wscript_build b/source4/dns_server/wscript_build
index 2288f7c..8c5bb9c 100644
--- a/source4/dns_server/wscript_build
+++ b/source4/dns_server/wscript_build
@@ -16,4 +16,4 @@ bld.SAMBA_LIBRARY('dlz_bind9',
                   link_name='modules/bind9/dlz_bind9.so',
                   realname='dlz_bind9.so',
                   install_path='${MODULESDIR}/bind9',
-                  deps='samba-hostconfig ldbsamba samba-util popt')
+                  deps='samba-hostconfig samdb gensec')
diff --git a/source4/dsdb/repl/drepl_partitions.c b/source4/dsdb/repl/drepl_partitions.c
index 70f9971..927dc68 100644
--- a/source4/dsdb/repl/drepl_partitions.c
+++ b/source4/dsdb/repl/drepl_partitions.c
@@ -126,6 +126,47 @@ WERROR dreplsrv_load_partitions(struct dreplsrv_service *s)
 }
 
 /*
+  Check if particular SPN exists for an account
+ */
+static bool dreplsrv_spn_exists(struct ldb_context *samdb, struct ldb_dn *ntds_dn,
+				const char *principal_name)
+{
+	TALLOC_CTX *tmp_ctx;
+	const char *attrs[] = { "serverReference", NULL };
+	const char *attrs_empty[] = { NULL };
+	int ret;
+	struct ldb_result *res;
+	struct ldb_dn *account_dn;
+
+	tmp_ctx = talloc_new(samdb);
+
+	ret = dsdb_search_dn(samdb, tmp_ctx, &res, ntds_dn, attrs, 0);
+	if (ret != LDB_SUCCESS) {
+		talloc_free(tmp_ctx);
+		return false;
+	}
+
+	account_dn = ldb_msg_find_attr_as_dn(samdb, tmp_ctx, res->msgs[0], "serverReference");
+	if (account_dn == NULL) {
+		talloc_free(tmp_ctx);
+		return false;
+	}
+
+	talloc_free(res);
+
+	ret = dsdb_search(samdb, tmp_ctx, &res, account_dn, LDB_SCOPE_BASE, attrs_empty,
+			0, "servicePrincipalName=%s",
+			ldb_binary_encode_string(tmp_ctx, principal_name));
+	if (ret != LDB_SUCCESS || res->count != 1) {
+		talloc_free(tmp_ctx);
+		return false;
+	}
+
+	talloc_free(tmp_ctx);
+	return true;
+}
+
+/*
   work out the principal to use for DRS replication connections
  */
 NTSTATUS dreplsrv_get_target_principal(struct dreplsrv_service *s,
@@ -181,15 +222,25 @@ NTSTATUS dreplsrv_get_target_principal(struct dreplsrv_service *s,
 
 	hostname = ldb_msg_find_attr_as_string(res->msgs[0], "dNSHostName", NULL);
 	if (hostname != NULL) {
+		char *local_principal;
+
 		/*
 		  if we have the dNSHostName attribute then we can use
 		  the GC/hostname/realm SPN. All DCs should have this SPN
+
+		  Windows DC may set up it's dNSHostName before setting up
+		  GC/xx/xx SPN. So make sure it exists, before using it.
 		 */
-		*target_principal = talloc_asprintf(mem_ctx, "GC/%s/%s",
+		local_principal = talloc_asprintf(mem_ctx, "GC/%s/%s",
 						    hostname,
 						    samdb_dn_to_dns_domain(tmp_ctx, forest_dn));
-		talloc_free(tmp_ctx);
-		return NT_STATUS_OK;
+		if (dreplsrv_spn_exists(s->samdb, ntds_dn, local_principal)) {
+			*target_principal = local_principal;
+			talloc_free(tmp_ctx);
+			return NT_STATUS_OK;
+		}
+
+		talloc_free(local_principal);
 	}
 
 	/*
diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c
index 66e2a76..e4659a7 100644
--- a/source4/dsdb/samdb/ldb_modules/partition.c
+++ b/source4/dsdb/samdb/ldb_modules/partition.c
@@ -827,6 +827,13 @@ static int partition_start_trans(struct ldb_module *module)
 
 	ret = partition_reload_if_required(module, data, NULL);
 	if (ret != LDB_SUCCESS) {
+		ldb_next_del_trans(module);
+		return ret;
+	}
+
+	ret = partition_metadata_start_trans(module);
+	if (ret != LDB_SUCCESS) {
+		ldb_next_del_trans(module);
 		return ret;
 	}
 
@@ -842,6 +849,7 @@ static int partition_start_trans(struct ldb_module *module)
 				ldb_next_del_trans(data->partitions[i]->module);
 			}
 			ldb_next_del_trans(module);
+			partition_metadata_del_trans(module);
 			return ret;
 		}
 	}
@@ -857,10 +865,9 @@ static int partition_prepare_commit(struct ldb_module *module)
 	unsigned int i;
 	struct partition_private_data *data = talloc_get_type(ldb_module_get_private(module),
 							      struct partition_private_data);
+	int ret;
 
 	for (i=0; data && data->partitions && data->partitions[i]; i++) {
-		int ret;
-
 		if ((module && ldb_module_flags(ldb_module_get_ctx(module)) & LDB_FLG_ENABLE_TRACING)) {
 			ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_TRACE, "partition_prepare_commit() -> %s",
 				  ldb_dn_get_linearized(data->partitions[i]->ctrl->dn));
@@ -877,7 +884,15 @@ static int partition_prepare_commit(struct ldb_module *module)
 	if ((module && ldb_module_flags(ldb_module_get_ctx(module)) & LDB_FLG_ENABLE_TRACING)) {
 		ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_TRACE, "partition_prepare_commit() -> (metadata partition)");
 	}
-	return ldb_next_prepare_commit(module);
+
+	ret = ldb_next_prepare_commit(module);
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	/* metadata prepare commit must come last, as other partitions could modify
+	 * the database inside the prepare commit method of a module */
+	return partition_metadata_prepare_commit(module);
 }
 
 
@@ -898,6 +913,11 @@ static int partition_end_trans(struct ldb_module *module)
 		data->in_transaction--;
 	}
 
+	ret2 = partition_metadata_end_trans(module);
+	if (ret2 != LDB_SUCCESS) {
+		ret = ret2;
+	}
+
 	for (i=0; data && data->partitions && data->partitions[i]; i++) {
 		if ((module && ldb_module_flags(ldb_module_get_ctx(module)) & LDB_FLG_ENABLE_TRACING)) {
 			ldb_debug(ldb_module_get_ctx(module), LDB_DEBUG_TRACE, "partition_end_trans() -> %s",
@@ -929,6 +949,11 @@ static int partition_del_trans(struct ldb_module *module)
 	unsigned int i;
 	struct partition_private_data *data = talloc_get_type(ldb_module_get_private(module),
 							      struct partition_private_data);
+	ret = partition_metadata_del_trans(module);
+	if (ret != LDB_SUCCESS) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list