[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Thu Apr 12 06:13:03 UTC 2018


The branch, master has been updated
       via  490756a Check "auth event notification" param in log_json
       via  040a526 ldb-samba: require pid match for cached ldb
       via  a7cdec9 ldb_wrap: Remove the magic cache of database handles except for sam.ldb
       via  132e932 dsdb: Use talloc_get_type_abort() in schema_load_{start,end}_transaction
       via  887b48c dsdb: ensure we take out a read lock during the dsdb_init
       via  e9483c2 dsdb: Rework schema reload during the read lock
       via  6c9e658 dsdb: Load schema during the read_lock() hook, not the search
       via  6baf7608 dsdb: Allow search before init() is called in extended_dn_out
       via  4d37f55 dsdb: Move ldb_set_default_dns() into rootdse_get_private_data()
       via  6395611 dsdb: Create rootdse_get_private_data()
       via  18d4a1c selftest: Make a transaction before @INDEXLIST etc is checked in dsdb_schema_attributes.py
       via  a4778ad dsdb: Wait until a transaction starts to call dsdb_schema_set_indices_and_attributes()
       via  a755c41 dsdb: Allow search before init() call in encrypted_secrets
       via  bd5f6f5 dsdb: Do not create a transaction in partition_init()
       via  23ef25f dsdb: Ensure to cancel the transaction if we fail to save the prefixMap
       via  46b6f2d ldb_wrap: Remove ldb_transaction_cancel_noerr from ldb_wrap_fork_hook()
       via  056b2ab dsdb: check for dSHeuristics more carefully
       via  5c7973e dsdb: Check for userPassword support after loading the databases
      from  82beaf8 s3: tests: Regression test to ensure we can never return a DIRECTORY attribute on a stream.

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


- Log -----------------------------------------------------------------
commit 490756a8401189550aa549d2eb1600c30e1c5d30
Author: Arvid Requate <requate at univention.de>
Date:   Wed Apr 11 21:46:25 2018 +0200

    Check "auth event notification" param in log_json
    
    When Samba is compiled with JSON support it logs an error message
    at log level 3 by default for every authentication event:
    
    get_auth_event_server: Failed to find 'auth_event' registered on the
    message bus to send JSON authentication events to:
    NT_STATUS_OBJECT_NAME_NOT_FOUND
    
    This patch adjusts the log_json function to consider the smb.conf
    parameter "auth event notification" before calling auth_message_send.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13381
    
    Signed-off-by: Arvid Requate <requate at univention.de>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Gary Lockyer <gary at catalyst.net.nz>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Thu Apr 12 08:12:39 CEST 2018 on sn-devel-144

commit 040a526a3bbcafeeebb6dd50a563a4635dd79fea
Author: Gary Lockyer <gary at catalyst.net.nz>
Date:   Tue Mar 13 16:43:54 2018 +1300

    ldb-samba: require pid match for cached ldb
    
    Signed-off-by: Gary Lockyer <gary at catalyst.net.nz>
    Reviewed-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit a7cdec9ded016d6a1996a0d68dc9b7b029e78c7f
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Mar 15 13:44:52 2018 +1300

    ldb_wrap: Remove the magic cache of database handles except for sam.ldb
    
    sam.ldb is handled in samdb_connect_url(), not this function.
    
    This cache caused issues when "private dir" was changed in a testing script, but also
    just generates many-owner shared mutable state that is frowned upon these days.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 132e932da2f203d005abea4412fcf2c483b7c489
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Apr 10 13:34:56 2018 +1200

    dsdb: Use talloc_get_type_abort() in schema_load_{start,end}_transaction
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13379
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 887b48c49328f7cede260923a33633096402a763
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Apr 9 18:13:59 2018 +1200

    dsdb: ensure we take out a read lock during the dsdb_init
    
    We have to also take it out in the partitions code when we load the
    partition backends.
    
    This ensures that the init handlers hold a whole-db lock just as the
    search code does.
    
    To ensure the locking count in schema_load is balanced, the
    private data is now created in the first lock_read() call.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13379
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit e9483c269a9ef9e585030ec5f0337f88e73d0863
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Apr 11 12:29:18 2018 +1200

    dsdb: Rework schema reload during the read lock
    
    Rather than refusing the reload based on making cached sequence numbers match
    just load it once at the time the DB is globally locked, if required.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13379
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 6c9e658ec1bb959e20aaab6244daf27dd6232fe2
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Apr 11 11:58:22 2018 +1200

    dsdb: Load schema during the read_lock() hook, not the search
    
    This should trigger slightly less often and is the more correct place, as
    we only load it during the first lock when not in a transaction.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13379
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 6baf7608dfc3517cb3798fc53db849f49c6d157a
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Apr 10 16:34:21 2018 +1200

    dsdb: Allow search before init() is called in extended_dn_out
    
    This matches the earlier check of p && p->normalise.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13379
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 4d37f55cc127cb823821050a333ace8a06f92d2c
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Apr 10 07:54:20 2018 +1200

    dsdb: Move ldb_set_default_dns() into rootdse_get_private_data()
    
    This call needs to be done at the very first chance, in this case
    during the first call to the lock_read() hook, otherwise the
    schema_data module can't find the schema.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13379
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 63956116328c0d1b75ff23e115de0389d95ae137
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Apr 10 07:58:07 2018 +1200

    dsdb: Create rootdse_get_private_data()
    
    This will get the private data on the first call, allowing that not to be
    the init() hook.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13379
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 18d4a1cc3fa1fd9635bdfa702a62fc81e50f4be9
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Apr 11 12:51:49 2018 +1200

    selftest: Make a transaction before @INDEXLIST etc is checked in dsdb_schema_attributes.py
    
    This helps us remove the write to the database from the (soon to be
    read locked) init code.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13379
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit a4778ad48e985931912f3fd2a7e27270ab4df8ce
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Apr 9 21:59:01 2018 +1200

    dsdb: Wait until a transaction starts to call dsdb_schema_set_indices_and_attributes()
    
    This avoids starting a transaction in schema_load_init() and allows it
    to operate with a read lock held, which will avoid locking issues
    (deadlock detected due to lock odering if we do not have a global
    read lock).
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13379
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit a755c413c87155b8dd94d6938ae2ddbd1e328403
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Apr 9 21:15:25 2018 +1200

    dsdb: Allow search before init() call in encrypted_secrets
    
    Simply do not decrypt anything until the init call is run.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13379
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit bd5f6f5a8327398bb261582d0e2c2de23854ad5d
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Apr 9 17:51:57 2018 +1200

    dsdb: Do not create a transaction in partition_init()
    
    This will allow us to lock the databases for read during all of the Samba init
    hooks.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13379
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 23ef25faf5f60d4fcbaec28ffebd249556028c75
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Mon Apr 9 14:52:47 2018 +1200

    dsdb: Ensure to cancel the transaction if we fail to save the prefixMap
    
    This rare error case forgot to call ldb_transaction_cancel()
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 46b6f2d782efb0d15e676c5be359e1a4145cf426
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Thu Mar 15 13:42:17 2018 +1300

    ldb_wrap: Remove ldb_transaction_cancel_noerr from ldb_wrap_fork_hook()
    
    Writing to a TDB, without locks (these are per-process) in a forked child is never going to
    end well, if a transaction is open at this point we have bigger problems.
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 056b2abde615aab986e43c41c297edfaf58aaea2
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Apr 11 22:47:03 2018 +1200

    dsdb: check for dSHeuristics more carefully
    
    This check would pass if the dSHeuristics was treated as always being
    000000000 for searches which is not enough, we must check for a value
    of 000000001 (userPassword enabled).
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13378
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

commit 5c7973e9ba5671aa78525b335038b5ca8bf54aa3
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Apr 11 22:49:31 2018 +1200

    dsdb: Check for userPassword support after loading the databases
    
    The net result of this is only that userPassword values (which were
    world readable when set) would still be visible after userPassword
    started setting the main DB password.
    
    In AD, those values become hidden once the dSHeuristics bit is set,
    but Samba lost that when fixing a performance issue with
    f26a2845bd42e580ddeaf0eecc9b46b823a0c6bc
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13378
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>

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

Summary of changes:
 auth/auth_log.c                                    |  13 +-
 lib/ldb-samba/ldb_wrap.c                           |  37 ++---
 python/samba/tests/dsdb_schema_attributes.py       |  16 ++
 source4/dsdb/repl/replicated_objects.c             |   1 +
 source4/dsdb/samdb/ldb_modules/acl.c               |  18 ++-
 source4/dsdb/samdb/ldb_modules/encrypted_secrets.c |   2 +-
 source4/dsdb/samdb/ldb_modules/extended_dn_out.c   |   2 +-
 source4/dsdb/samdb/ldb_modules/partition.c         |  24 +++
 source4/dsdb/samdb/ldb_modules/partition_init.c    |  15 +-
 .../dsdb/samdb/ldb_modules/partition_metadata.c    |  59 ++++---
 source4/dsdb/samdb/ldb_modules/rootdse.c           |  70 +++++++--
 source4/dsdb/samdb/ldb_modules/samba_dsdb.c        |  17 +-
 source4/dsdb/samdb/ldb_modules/schema_load.c       | 174 ++++++++-------------
 source4/dsdb/tests/python/passwords.py             |  31 +++-
 14 files changed, 271 insertions(+), 208 deletions(-)


Changeset truncated at 500 lines:

diff --git a/auth/auth_log.c b/auth/auth_log.c
index d4c6c44..c143ae3 100644
--- a/auth/auth_log.c
+++ b/auth/auth_log.c
@@ -201,6 +201,7 @@ static void auth_message_send(struct imessaging_context *msg_ctx,
  *
  */
 static void log_json(struct imessaging_context *msg_ctx,
+		     struct loadparm_context *lp_ctx,
 		     struct json_context *context,
 		     const char *type, int debug_class, int debug_level)
 {
@@ -218,7 +219,9 @@ static void log_json(struct imessaging_context *msg_ctx,
 	}
 
 	DEBUGC(debug_class, debug_level, ("JSON %s: %s\n", type, json));
-	auth_message_send(msg_ctx, json);
+	if (msg_ctx && lp_ctx && lpcfg_auth_event_notification(lp_ctx)) {
+		auth_message_send(msg_ctx, json);
+	}
 
 	if (json) {
 		free(json);
@@ -502,7 +505,12 @@ static void log_authentication_event_json(
 	add_string(&authentication, "passwordType", get_password_type(ui));
 	add_object(&context,AUTH_JSON_TYPE, &authentication);
 
-	log_json(msg_ctx, &context, AUTH_JSON_TYPE, DBGC_AUTH_AUDIT, debug_level);
+	log_json(msg_ctx,
+		 lp_ctx,
+		 &context,
+		 AUTH_JSON_TYPE,
+		 DBGC_AUTH_AUDIT,
+		 debug_level);
 	free_json_context(&context);
 }
 
@@ -566,6 +574,7 @@ static void log_successful_authz_event_json(
 	add_object(&context,AUTHZ_JSON_TYPE, &authorization);
 
 	log_json(msg_ctx,
+		 lp_ctx,
 		 &context,
 		 AUTHZ_JSON_TYPE,
 		 DBGC_AUTH_AUDIT,
diff --git a/lib/ldb-samba/ldb_wrap.c b/lib/ldb-samba/ldb_wrap.c
index 9959b04..143e128 100644
--- a/lib/ldb-samba/ldb_wrap.c
+++ b/lib/ldb-samba/ldb_wrap.c
@@ -94,6 +94,8 @@ static struct ldb_wrap {
 		/* the context is what we use to tell if two ldb
 		 * connections are exactly equivalent
 		 */
+		pid_t pid; /* We want to re-open in a new PID due to
+			    * the LMDB backend */
 		const char *url;
 		struct tevent_context *ev;
 		struct loadparm_context *lp_ctx;
@@ -186,10 +188,12 @@ char *wrap_casefold(void *context, void *mem_ctx, const char *s, size_t n)
 				   struct cli_credentials *credentials,
 				   unsigned int flags)
 {
+	pid_t pid = getpid();
 	struct ldb_wrap *w;
 	/* see if we can re-use an existing ldb */
 	for (w=ldb_wrap_list; w; w=w->next) {
-		if (w->context.ev == ev &&
+		if (w->context.pid == pid &&
+		    w->context.ev == ev &&
 		    w->context.lp_ctx == lp_ctx &&
 		    w->context.session_info == session_info &&
 		    w->context.credentials == credentials &&
@@ -249,6 +253,7 @@ int samba_ldb_connect(struct ldb_context *ldb, struct loadparm_context *lp_ctx,
 		return false;
 	}
 
+	c.pid          = getpid();
 	c.url          = url;
 	c.ev           = ev;
 	c.lp_ctx       = lp_ctx;
@@ -303,9 +308,13 @@ int samba_ldb_connect(struct ldb_context *ldb, struct loadparm_context *lp_ctx,
 	struct ldb_context *ldb;
 	int ret;
 
-	ldb = ldb_wrap_find(url, ev, lp_ctx, session_info, credentials, flags);
-	if (ldb != NULL)
-		return talloc_reference(mem_ctx, ldb);
+	/*
+	 * Unlike samdb_connect_url() do not try and cache the LDB
+	 * handle, get a new one each time.  Only sam.ldb is
+	 * punitively expensive to open and helpful caches like this
+	 * cause challenges (such as if the value for 'private dir'
+	 * changes).
+	 */
 
 	ldb = samba_ldb_init(mem_ctx, ev, lp_ctx, session_info, credentials);
 
@@ -318,31 +327,17 @@ int samba_ldb_connect(struct ldb_context *ldb, struct loadparm_context *lp_ctx,
 		return NULL;
 	}
 
-	if (!ldb_wrap_add(url, ev, lp_ctx, session_info, credentials, flags, ldb)) {
-		talloc_free(ldb);
-		return NULL;
-	}
-
 	DEBUG(3,("ldb_wrap open of %s\n", url));
 
 	return ldb;
 }
 
 /*
-  when we fork() we need to make sure that any open ldb contexts have
-  any open transactions cancelled (ntdb databases doesn't need reopening,
-  as we don't use clear_if_first).
- */
+  call tdb_reopen_all() in case there is a TDB open so we are
+  not blocked from re-opening it inside ldb_tdb.
+*/
  void ldb_wrap_fork_hook(void)
 {
-	struct ldb_wrap *w;
-
-	for (w=ldb_wrap_list; w; w=w->next) {
-		if (ldb_transaction_cancel_noerr(w->ldb) != LDB_SUCCESS) {
-			smb_panic("Failed to cancel child transactions\n");
-		}
-	}
-
 	if (tdb_reopen_all(1) != 0) {
 		smb_panic("tdb_reopen_all failed\n");
 	}
diff --git a/python/samba/tests/dsdb_schema_attributes.py b/python/samba/tests/dsdb_schema_attributes.py
index 2bebbb5..c3b956f 100644
--- a/python/samba/tests/dsdb_schema_attributes.py
+++ b/python/samba/tests/dsdb_schema_attributes.py
@@ -193,6 +193,14 @@ systemOnly: FALSE
 
         samdb2 = samba.tests.connect_samdb(self.lp.samdb_url())
 
+        # We now only update the @ATTRIBUTES when a transaction happens
+        # rather than making a read of the DB do writes.
+        #
+        # This avoids locking issues and is more expected
+
+        samdb2.transaction_start()
+        samdb2.transaction_commit()
+
         res = self.samdb.search(base="@ATTRIBUTES", scope=ldb.SCOPE_BASE,
                                 attrs=["@TEST_EXTRA"])
         self.assertEquals(len(res), 1)
@@ -220,6 +228,14 @@ systemOnly: FALSE
 
         samdb2 = samba.tests.connect_samdb(self.lp.samdb_url())
 
+        # We now only update the @INDEXLIST when a transaction happens
+        # rather than making a read of the DB do writes.
+        #
+        # This avoids locking issues and is more expected
+
+        samdb2.transaction_start()
+        samdb2.transaction_commit()
+
         res = self.samdb.search(base="@INDEXLIST", scope=ldb.SCOPE_BASE,
                                 attrs=["@TEST_EXTRA"])
         self.assertEquals(len(res), 1)
diff --git a/source4/dsdb/repl/replicated_objects.c b/source4/dsdb/repl/replicated_objects.c
index 0c44960..4c8890f 100644
--- a/source4/dsdb/repl/replicated_objects.c
+++ b/source4/dsdb/repl/replicated_objects.c
@@ -921,6 +921,7 @@ WERROR dsdb_replicated_objects_commit(struct ldb_context *ldb,
 			}
 			DEBUG(0,("Failed to save updated prefixMap: %s\n",
 				 win_errstr(werr)));
+			ldb_transaction_cancel(ldb);
 			TALLOC_FREE(tmp_ctx);
 			return werr;
 		}
diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c
index d750362..8b1dcbe 100644
--- a/source4/dsdb/samdb/ldb_modules/acl.c
+++ b/source4/dsdb/samdb/ldb_modules/acl.c
@@ -108,8 +108,6 @@ static int acl_module_init(struct ldb_module *module)
 					NULL, "acl", "search", true);
 	ldb_module_set_private(module, data);
 
-	data->userPassword_support = dsdb_user_password_support(module, module, NULL);
-	
 	mem_ctx = talloc_new(module);
 	if (!mem_ctx) {
 		return ldb_oom(ldb);
@@ -180,7 +178,21 @@ static int acl_module_init(struct ldb_module *module)
 
 done:
 	talloc_free(mem_ctx);
-	return ldb_next_init(module);
+	ret = ldb_next_init(module);
+
+	if (ret != LDB_SUCCESS) {
+		return ret;
+	}
+
+	/*
+	 * Check this after the modules have be initalised so we
+	 * can actually read the backend DB.
+	 */
+	data->userPassword_support
+		= dsdb_user_password_support(module,
+					     module,
+					     NULL);
+	return ret;
 }
 
 static int acl_allowedAttributes(struct ldb_module *module,
diff --git a/source4/dsdb/samdb/ldb_modules/encrypted_secrets.c b/source4/dsdb/samdb/ldb_modules/encrypted_secrets.c
index 87ec9e4..ef69bb0 100644
--- a/source4/dsdb/samdb/ldb_modules/encrypted_secrets.c
+++ b/source4/dsdb/samdb/ldb_modules/encrypted_secrets.c
@@ -1365,7 +1365,7 @@ static int es_search_post_process(struct ldb_module *module,
 	/*
 	 * Decrypt any encrypted secret attributes
 	 */
-	if (data->encrypt_secrets) {
+	if (data && data->encrypt_secrets) {
 		int err = decrypt_secret_attributes(ldb, msg, data);
 		if (err !=  LDB_SUCCESS) {
 			return err;
diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_out.c b/source4/dsdb/samdb/ldb_modules/extended_dn_out.c
index ad4603f..6a869d0 100644
--- a/source4/dsdb/samdb/ldb_modules/extended_dn_out.c
+++ b/source4/dsdb/samdb/ldb_modules/extended_dn_out.c
@@ -498,7 +498,7 @@ static int extended_callback(struct ldb_request *req, struct ldb_reply *ares,
 			continue;
 		}
 
-		if (p->normalise) {
+		if (p && p->normalise) {
 			/* If we are also in 'normalise' mode, then
 			 * fix the attribute names to be in the
 			 * correct case */
diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c
index 37e714d..9fb1b9d 100644
--- a/source4/dsdb/samdb/ldb_modules/partition.c
+++ b/source4/dsdb/samdb/ldb_modules/partition.c
@@ -1236,6 +1236,30 @@ int partition_read_lock(struct ldb_module *module)
 	 *   ordering
 	 */
 
+	if (data == NULL) {
+		TALLOC_CTX *mem_ctx = talloc_new(module);
+
+		data = talloc_zero(mem_ctx, struct partition_private_data);
+		if (data == NULL) {
+			talloc_free(mem_ctx);
+			return ldb_operr(ldb);
+		}
+
+		/*
+		 * When used from Samba4, this message is set by the
+		 * samba4 module, as a fixed value not read from the
+		 * DB.  This avoids listing modules in the DB
+		 */
+		data->forced_module_msg = talloc_get_type(
+			ldb_get_opaque(ldb,
+				       DSDB_OPAQUE_PARTITION_MODULE_MSG_OPAQUE_NAME),
+			struct ldb_message);
+
+		ldb_module_set_private(module, talloc_steal(module,
+							    data));
+		talloc_free(mem_ctx);
+	}
+
 	/*
 	 * This will lock the metadata partition (sam.ldb) and
 	 * will also call event loops, so we do it before we
diff --git a/source4/dsdb/samdb/ldb_modules/partition_init.c b/source4/dsdb/samdb/ldb_modules/partition_init.c
index 9a6ac0c..9a8bb7e 100644
--- a/source4/dsdb/samdb/ldb_modules/partition_init.c
+++ b/source4/dsdb/samdb/ldb_modules/partition_init.c
@@ -863,18 +863,9 @@ int partition_init(struct ldb_module *module)
 		return ldb_operr(ldb);
 	}
 
-	data = talloc_zero(mem_ctx, struct partition_private_data);
-	if (data == NULL) {
-		return ldb_operr(ldb);
-	}
-
-	/* When used from Samba4, this message is set by the samba4
-	 * module, as a fixed value not read from the DB.  This avoids
-	 * listing modules in the DB */
-	data->forced_module_msg = talloc_get_type(
-		ldb_get_opaque(ldb,
-			       DSDB_OPAQUE_PARTITION_MODULE_MSG_OPAQUE_NAME),
-		struct ldb_message);
+	/* We actually got this during the read_lock call */
+	data = talloc_get_type_abort(ldb_module_get_private(module),
+				     struct partition_private_data);
 
 	/* This loads the partitions */
 	ret = partition_reload_if_required(module, data, NULL);
diff --git a/source4/dsdb/samdb/ldb_modules/partition_metadata.c b/source4/dsdb/samdb/ldb_modules/partition_metadata.c
index e3ad0d8..3e60393 100644
--- a/source4/dsdb/samdb/ldb_modules/partition_metadata.c
+++ b/source4/dsdb/samdb/ldb_modules/partition_metadata.c
@@ -319,38 +319,6 @@ int partition_metadata_init(struct ldb_module *module)
 		return ret;
 	}
 
-	/*
-	 * We need to fill in the sequence number from the DB, so we
-	 * need to get a lock over all the databases.  We only read
-	 * from the main partitions, but write to metadata so to avoid
-	 * lock ordering we just get a transaction over the lot.
-	 */
-	ret = partition_start_trans(module);
-	if (ret != LDB_SUCCESS) {
-		TALLOC_FREE(data->metadata);
-		return ret;
-	}
-
-	ret = partition_metadata_set_sequence_number(module);
-	if (ret != LDB_SUCCESS) {
-		TALLOC_FREE(data->metadata);
-		partition_del_trans(module);
-		return ret;
-	}
-
-	ret = partition_prepare_commit(module);
-	if (ret != LDB_SUCCESS) {
-		TALLOC_FREE(data->metadata);
-		partition_del_trans(module);
-		return ret;
-	}
-
-	ret = partition_end_trans(module);
-	if (ret != LDB_SUCCESS) {
-		/* Nothing much we can do */
-		TALLOC_FREE(data->metadata);
-	}
-
 	return ret;
 }
 
@@ -370,6 +338,13 @@ int partition_metadata_sequence_number(struct ldb_module *module, uint64_t *valu
 		return ret;
 	}
 
+	/*
+	 * This means we will give a 0 until the first write
+	 * tranaction, which is actually pretty reasonable.
+	 *
+	 * All modern databases will have the metadata.tdb from
+	 * the time of the first transaction in provision anyway.
+	 */
 	ret = partition_metadata_get_uint64(module,
 					    LDB_METADATA_SEQ_NUM,
 					    value,
@@ -410,6 +385,26 @@ int partition_metadata_sequence_number_increment(struct ldb_module *module, uint
 		return ret;
 	}
 
+	if (*value == 0) {
+		/*
+		 * We are in a transaction now, so we can get the
+		 * sequence number from the partitions.
+		 */
+		ret = partition_metadata_set_sequence_number(module);
+		if (ret != LDB_SUCCESS) {
+			TALLOC_FREE(data->metadata);
+			partition_del_trans(module);
+			return ret;
+		}
+
+		ret = partition_metadata_get_uint64(module,
+						    LDB_METADATA_SEQ_NUM,
+						    value, 0);
+		if (ret != LDB_SUCCESS) {
+			return ret;
+		}
+	}
+
 	(*value)++;
 	ret = partition_metadata_set_uint64(module, LDB_METADATA_SEQ_NUM, *value, false);
 	return ret;
diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c
index 0d48621..751fe15 100644
--- a/source4/dsdb/samdb/ldb_modules/rootdse.c
+++ b/source4/dsdb/samdb/ldb_modules/rootdse.c
@@ -863,11 +863,51 @@ static int rootdse_search(struct ldb_module *module, struct ldb_request *req)
 	return ldb_next_request(module, down_req);
 }
 
+static struct rootdse_private_data *rootdse_get_private_data(struct ldb_module *module)
+{
+	void *priv = ldb_module_get_private(module);
+	struct rootdse_private_data *data = NULL;
+	struct ldb_context *ldb
+		= ldb_module_get_ctx(module);
+
+	if (priv != NULL) {
+		data = talloc_get_type_abort(priv,
+					     struct rootdse_private_data);
+	}
+
+	if (data != NULL) {
+		return data;
+	}
+
+	data = talloc_zero(module, struct rootdse_private_data);
+	if (data == NULL) {
+		return NULL;
+	}
+
+	data->num_controls = 0;
+	data->controls = NULL;
+	data->num_partitions = 0;
+	data->partitions = NULL;
+	data->block_anonymous = true;
+
+	ldb_module_set_private(module, data);
+
+	ldb_set_default_dns(ldb);
+
+	return data;
+}
+
+
 static int rootdse_register_control(struct ldb_module *module, struct ldb_request *req)
 {
-	struct rootdse_private_data *priv = talloc_get_type(ldb_module_get_private(module), struct rootdse_private_data);
+	struct rootdse_private_data *priv =
+		rootdse_get_private_data(module);
 	char **list;
 
+	if (priv == NULL) {
+		return ldb_module_oom(module);
+	}
+
 	list = talloc_realloc(priv, priv->controls, char *, priv->num_controls + 1);
 	if (!list) {
 		return ldb_oom(ldb_module_get_ctx(module));
@@ -886,9 +926,14 @@ static int rootdse_register_control(struct ldb_module *module, struct ldb_reques
 
 static int rootdse_register_partition(struct ldb_module *module, struct ldb_request *req)
 {
-	struct rootdse_private_data *priv = talloc_get_type(ldb_module_get_private(module), struct rootdse_private_data);
+	struct rootdse_private_data *priv =
+		rootdse_get_private_data(module);
 	struct ldb_dn **list;
 
+	if (priv == NULL) {
+		return ldb_module_oom(module);
+	}
+
 	list = talloc_realloc(priv, priv->partitions, struct ldb_dn *, priv->num_partitions + 1);
 	if (!list) {
 		return ldb_oom(ldb_module_get_ctx(module));
@@ -924,30 +969,21 @@ static int rootdse_request(struct ldb_module *module, struct ldb_request *req)
 static int rootdse_init(struct ldb_module *module)
 {
 	int ret;
-	struct ldb_context *ldb;
 	struct ldb_result *res;
-	struct rootdse_private_data *data;
 	const char *attrs[] = { "msDS-Behavior-Version", NULL };
 	const char *ds_attrs[] = { "dsServiceName", NULL };
 	TALLOC_CTX *mem_ctx;
 
-	ldb = ldb_module_get_ctx(module);
+	struct ldb_context *ldb
+		= ldb_module_get_ctx(module);
+
+	struct rootdse_private_data *data
+		= rootdse_get_private_data(module);
 
-	data = talloc_zero(module, struct rootdse_private_data);
 	if (data == NULL) {
-		return ldb_oom(ldb);
+		return ldb_module_oom(module);
 	}
 
-	data->num_controls = 0;
-	data->controls = NULL;
-	data->num_partitions = 0;
-	data->partitions = NULL;
-	data->block_anonymous = true;
-
-	ldb_module_set_private(module, data);
-
-	ldb_set_default_dns(ldb);
-
 	ret = ldb_next_init(module);
 
 	if (ret != LDB_SUCCESS) {
diff --git a/source4/dsdb/samdb/ldb_modules/samba_dsdb.c b/source4/dsdb/samdb/ldb_modules/samba_dsdb.c
index 2605c1e..54ec6a2 100644
--- a/source4/dsdb/samdb/ldb_modules/samba_dsdb.c
+++ b/source4/dsdb/samdb/ldb_modules/samba_dsdb.c
@@ -249,7 +249,7 @@ static bool check_required_features(struct ldb_message_element *el)


-- 
Samba Shared Repository



More information about the samba-cvs mailing list