[SCM] Samba Shared Repository - branch v3-2-test updated - release-3-2-0pre2-205-gf94a63c

Volker Lendecke vlendec at samba.org
Mon Mar 10 20:35:05 GMT 2008


The branch, v3-2-test has been updated
       via  f94a63cd8f94490780ad9331da229c0bcb2ca5d6 (commit)
       via  1307f0130c47b8d740d2b7afe7a5d8d1a655e2a2 (commit)
       via  e66e502bee65fe44944d325ebeeaa3bf56169eb8 (commit)
       via  0a55e018dd68af06d84332d54148bbfb0b510b22 (commit)
       via  4ee21a98bc3d1c41a6d8868e98118c58372b2d1a (commit)
      from  627688c7bac4d3afcc846164c2fefebdbbc10d68 (commit)

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


- Log -----------------------------------------------------------------
commit f94a63cd8f94490780ad9331da229c0bcb2ca5d6
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Mar 10 21:08:29 2008 +0100

    Use a separate tdb for mutexes
    
    Another preparation to convert secrets.c to dbwrap: The dbwrap API does not
    provide a sane tdb_lock_with_timeout abstraction. In the clustered case the DC
    mutex is needed per-node anyway, so it is perfectly fine to use a local mutex
    only.

commit 1307f0130c47b8d740d2b7afe7a5d8d1a655e2a2
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Mar 10 15:48:04 2008 +0100

    Convert secrets_lock_trust_account_password to talloc
    
    This is preparing the conversion of secrets.c to ctdb

commit e66e502bee65fe44944d325ebeeaa3bf56169eb8
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Mar 10 13:27:27 2008 +0100

    Add dbwrap_trans_store and dbwrap_trans_delete

commit 0a55e018dd68af06d84332d54148bbfb0b510b22
Author: Volker Lendecke <vl at samba.org>
Date:   Mon Mar 10 10:17:05 2008 +0100

    Add transactions to the dbwrap API
    
    Only filled in for tdb so far, for rbt it's pointless, and ctdb itself needs to
    be extended

commit 4ee21a98bc3d1c41a6d8868e98118c58372b2d1a
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Mar 9 11:15:10 2008 +0100

    add dbwrap_change_int32_atomic

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

Summary of changes:
 source/auth/auth_domain.c       |   16 +++---
 source/auth/auth_server.c       |   16 +++---
 source/include/dbwrap.h         |    3 +
 source/include/smb.h            |    1 +
 source/lib/dbwrap_ctdb.c        |   10 ++++
 source/lib/dbwrap_rbt.c         |   11 ++++
 source/lib/dbwrap_tdb.c         |   24 +++++++++
 source/lib/dbwrap_util.c        |  107 +++++++++++++++++++++++++++++++++++++++
 source/lib/server_mutex.c       |   57 ++++++++++++++------
 source/libads/kerberos_verify.c |   15 ++---
 source/passdb/secrets.c         |   63 +++++++++--------------
 source/smbd/process.c           |   11 +++--
 source/winbindd/winbindd_cm.c   |   17 ++----
 13 files changed, 257 insertions(+), 94 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/auth/auth_domain.c b/source/auth/auth_domain.c
index df51966..2647408 100644
--- a/source/auth/auth_domain.c
+++ b/source/auth/auth_domain.c
@@ -24,6 +24,7 @@
 #define DBGC_CLASS DBGC_AUTH
 
 extern bool global_machine_password_needs_changing;
+static struct named_mutex *mutex;
 
 /**
  * Connect to a remote server for (inter)domain security authenticaion.
@@ -67,7 +68,8 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
 	 * ACCESS_DENIED errors if 2 auths are done from the same machine. JRA.
 	 */
 
-	if (!grab_server_mutex(dc_name)) {
+	mutex = grab_named_mutex(NULL, dc_name, 10);
+	if (mutex == NULL) {
 		return NT_STATUS_NO_LOGON_SERVERS;
 	}
 	
@@ -87,7 +89,7 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
 			*cli = NULL;
 		}
 
-		release_server_mutex();
+		TALLOC_FREE(mutex);
 		return result;
 	}
 
@@ -118,7 +120,7 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli,
 machine %s. Error was : %s.\n", dc_name, nt_errstr(result)));
 		cli_shutdown(*cli);
 		*cli = NULL;
-		release_server_mutex();
+		TALLOC_FREE(mutex);
 		return result;
 	}
 
@@ -137,7 +139,7 @@ machine %s. Error was : %s.\n", dc_name, nt_errstr(result)));
 				domain));
 			cli_shutdown(*cli);
 			*cli = NULL;
-			release_server_mutex();
+			TALLOC_FREE(mutex);
 			return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
 		}
 
@@ -153,7 +155,7 @@ machine %s. Error was : %s.\n", dc_name, nt_errstr(result)));
 		if (!NT_STATUS_IS_OK(result)) {
 			cli_shutdown(*cli);
 			*cli = NULL;
-			release_server_mutex();
+			TALLOC_FREE(mutex);
 			return result;
 		}
 	}
@@ -163,7 +165,7 @@ machine %s. Error was : %s.\n", dc_name, nt_errstr(result)));
 machine %s. Error was : %s.\n", dc_name, cli_errstr(*cli)));
 		cli_shutdown(*cli);
 		*cli = NULL;
-		release_server_mutex();
+		TALLOC_FREE(mutex);
 		return NT_STATUS_NO_LOGON_SERVERS;
 	}
 
@@ -247,7 +249,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
 	/* Let go as soon as possible so we avoid any potential deadlocks
 	   with winbind lookup up users or groups. */
 	   
-	release_server_mutex();
+	TALLOC_FREE(mutex);
 
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		DEBUG(0,("domain_client_validate: unable to validate password "
diff --git a/source/auth/auth_server.c b/source/auth/auth_server.c
index 095f0b9..b07884c 100644
--- a/source/auth/auth_server.c
+++ b/source/auth/auth_server.c
@@ -37,6 +37,7 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
 	const char *p;
 	char *pserver = NULL;
 	bool connected_ok = False;
+	struct named_mutex *mutex;
 
 	if (!(cli = cli_initialise()))
 		return NULL;
@@ -74,7 +75,8 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
 		   session setup yet it will send a TCP reset to the first
 		   connection (tridge) */
 
-		if (!grab_server_mutex(desthost)) {
+		mutex = grab_named_mutex(talloc_tos(), desthost, 10);
+		if (mutex == NULL) {
 			cli_shutdown(cli);
 			return NULL;
 		}
@@ -87,7 +89,7 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
 		}
 		DEBUG(10,("server_cryptkey: failed to connect to server %s. Error %s\n",
 			desthost, nt_errstr(status) ));
-		release_server_mutex();
+		TALLOC_FREE(mutex);
 	}
 
 	if (!connected_ok) {
@@ -98,7 +100,7 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
 
 	if (!attempt_netbios_session_request(&cli, global_myname(),
 					     desthost, &dest_ss)) {
-		release_server_mutex();
+		TALLOC_FREE(mutex);
 		DEBUG(1,("password server fails session request\n"));
 		cli_shutdown(cli);
 		return NULL;
@@ -111,16 +113,16 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
 	DEBUG(3,("got session\n"));
 
 	if (!cli_negprot(cli)) {
+		TALLOC_FREE(mutex);
 		DEBUG(1,("%s rejected the negprot\n",desthost));
-		release_server_mutex();
 		cli_shutdown(cli);
 		return NULL;
 	}
 
 	if (cli->protocol < PROTOCOL_LANMAN2 ||
 	    !(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
+		TALLOC_FREE(mutex);
 		DEBUG(1,("%s isn't in user level security mode\n",desthost));
-		release_server_mutex();
 		cli_shutdown(cli);
 		return NULL;
 	}
@@ -132,14 +134,14 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx)
 
 	if (!NT_STATUS_IS_OK(cli_session_setup(cli, "", "", 0, "", 0,
 					       ""))) {
+		TALLOC_FREE(mutex);
 		DEBUG(0,("%s rejected the initial session setup (%s)\n",
 			 desthost, cli_errstr(cli)));
-		release_server_mutex();
 		cli_shutdown(cli);
 		return NULL;
 	}
 
-	release_server_mutex();
+	TALLOC_FREE(mutex);
 
 	DEBUG(3,("password server OK\n"));
 
diff --git a/source/include/dbwrap.h b/source/include/dbwrap.h
index 4eb174f..5c82475 100644
--- a/source/include/dbwrap.h
+++ b/source/include/dbwrap.h
@@ -42,6 +42,9 @@ struct db_context {
 				      void *private_data),
 			     void *private_data);
 	int (*get_seqnum)(struct db_context *db);
+	int (*transaction_start)(struct db_context *db);
+	int (*transaction_commit)(struct db_context *db);
+	int (*transaction_cancel)(struct db_context *db);
 	void *private_data;
 	bool persistent;
 };
diff --git a/source/include/smb.h b/source/include/smb.h
index c582a97..bf9ca6b 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -420,6 +420,7 @@ struct timed_event;
 struct idle_event;
 struct share_mode_entry;
 struct uuid;
+struct named_mutex;
 
 struct vfs_fsp_data {
     struct vfs_fsp_data *next;
diff --git a/source/lib/dbwrap_ctdb.c b/source/lib/dbwrap_ctdb.c
index f497f87..a66ea7c 100644
--- a/source/lib/dbwrap_ctdb.c
+++ b/source/lib/dbwrap_ctdb.c
@@ -441,6 +441,13 @@ static int db_ctdb_get_seqnum(struct db_context *db)
 	return tdb_get_seqnum(ctx->wtdb->tdb);
 }
 
+static int db_ctdb_trans_dummy(struct db_context *db)
+{
+	/*
+	 * Not implemented yet, just return ok
+	 */
+	return 0;
+}
 
 struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx,
 				const char *name,
@@ -495,6 +502,9 @@ struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx,
 	result->traverse = db_ctdb_traverse;
 	result->traverse_read = db_ctdb_traverse_read;
 	result->get_seqnum = db_ctdb_get_seqnum;
+	result->transaction_start = db_ctdb_trans_dummy;
+	result->transaction_commit = db_ctdb_trans_dummy;
+	result->transaction_cancel = db_ctdb_trans_dummy;
 
 	DEBUG(3,("db_open_ctdb: opened database '%s' with dbid 0x%x\n",
 		 name, db_ctdb->db_id));
diff --git a/source/lib/dbwrap_rbt.c b/source/lib/dbwrap_rbt.c
index 633b695..46459c8 100644
--- a/source/lib/dbwrap_rbt.c
+++ b/source/lib/dbwrap_rbt.c
@@ -351,6 +351,14 @@ static int db_rbt_get_seqnum(struct db_context *db)
 	return 0;
 }
 
+static int db_rbt_trans_dummy(struct db_context *db)
+{
+	/*
+	 * Transactions are pretty pointless in-memory, just return success.
+	 */
+	return 0;
+}
+
 struct db_context *db_open_rbt(TALLOC_CTX *mem_ctx)
 {
 	struct db_context *result;
@@ -373,6 +381,9 @@ struct db_context *db_open_rbt(TALLOC_CTX *mem_ctx)
 	result->traverse = db_rbt_traverse;
 	result->traverse_read = db_rbt_traverse;
 	result->get_seqnum = db_rbt_get_seqnum;
+	result->transaction_start = db_rbt_trans_dummy;
+	result->transaction_commit = db_rbt_trans_dummy;
+	result->transaction_cancel = db_rbt_trans_dummy;
 
 	return result;
 }
diff --git a/source/lib/dbwrap_tdb.c b/source/lib/dbwrap_tdb.c
index da55049..7bdadd3 100644
--- a/source/lib/dbwrap_tdb.c
+++ b/source/lib/dbwrap_tdb.c
@@ -291,6 +291,27 @@ static int db_tdb_get_seqnum(struct db_context *db)
 	return tdb_get_seqnum(db_ctx->wtdb->tdb);
 }
 
+static int db_tdb_transaction_start(struct db_context *db)
+{
+	struct db_tdb_ctx *db_ctx =
+		talloc_get_type_abort(db->private_data, struct db_tdb_ctx);
+	return tdb_transaction_start(db_ctx->wtdb->tdb);
+}
+
+static int db_tdb_transaction_commit(struct db_context *db)
+{
+	struct db_tdb_ctx *db_ctx =
+		talloc_get_type_abort(db->private_data, struct db_tdb_ctx);
+	return tdb_transaction_commit(db_ctx->wtdb->tdb);
+}
+
+static int db_tdb_transaction_cancel(struct db_context *db)
+{
+	struct db_tdb_ctx *db_ctx =
+		talloc_get_type_abort(db->private_data, struct db_tdb_ctx);
+	return tdb_transaction_cancel(db_ctx->wtdb->tdb);
+}
+
 struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx,
 			       const char *name,
 			       int hash_size, int tdb_flags,
@@ -324,6 +345,9 @@ struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx,
 	result->traverse_read = db_tdb_traverse_read;
 	result->get_seqnum = db_tdb_get_seqnum;
 	result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0);
+	result->transaction_start = db_tdb_transaction_start;
+	result->transaction_commit = db_tdb_transaction_commit;
+	result->transaction_cancel = db_tdb_transaction_cancel;
 	return result;
 
  fail:
diff --git a/source/lib/dbwrap_util.c b/source/lib/dbwrap_util.c
index 002d572..0bafbe6 100644
--- a/source/lib/dbwrap_util.c
+++ b/source/lib/dbwrap_util.c
@@ -88,3 +88,110 @@ uint32_t dbwrap_change_uint32_atomic(struct db_context *db, const char *keystr,
 	return 0;
 }
 
+int32 dbwrap_change_int32_atomic(struct db_context *db, const char *keystr,
+				 int32 *oldval, int32 change_val)
+{
+	struct db_record *rec;
+	int32 val = -1;
+	TDB_DATA data;
+
+	if (!(rec = db->fetch_locked(db, NULL,
+				     string_term_tdb_data(keystr)))) {
+		return -1;
+	}
+
+	if ((rec->value.dptr != NULL)
+	    && (rec->value.dsize == sizeof(val))) {
+		val = IVAL(rec->value.dptr, 0);
+	}
+
+	val += change_val;
+
+	data.dsize = sizeof(val);
+	data.dptr = (uint8 *)&val;
+
+	rec->store(rec, data, TDB_REPLACE);
+
+	TALLOC_FREE(rec);
+
+	return 0;
+}
+
+int dbwrap_trans_store(struct db_context *db, TDB_DATA key, TDB_DATA dbuf,
+		       int flag)
+{
+	int res;
+	struct db_record *rec;
+	NTSTATUS status;
+
+	res = db->transaction_start(db);
+	if (res != 0) {
+		DEBUG(5, ("transaction_start failed\n"));
+	}
+
+	rec = db->fetch_locked(db, talloc_tos(), key);
+	if (rec == NULL) {
+		DEBUG(5, ("fetch_locked failed\n"));
+		goto cancel;
+	}
+
+	status = rec->store(rec, dbuf, flag);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(5, ("store returned %s\n", nt_errstr(status)));
+		goto cancel;
+	}
+
+	TALLOC_FREE(rec);
+
+	res = db->transaction_commit(db);
+	if (res != 0) {
+		DEBUG(5, ("tdb_transaction_commit failed\n"));
+	}
+
+	return res;
+
+ cancel:
+	if (db->transaction_cancel(db) != 0) {
+		smb_panic("Cancelling transaction failed");
+	}
+	return -1;
+}
+
+int dbwrap_trans_delete(struct db_context *db, TDB_DATA key)
+{
+	int res;
+	struct db_record *rec;
+	NTSTATUS status;
+
+	res = db->transaction_start(db);
+	if (res != 0) {
+		DEBUG(5, ("transaction_start failed\n"));
+	}
+
+	rec = db->fetch_locked(db, talloc_tos(), key);
+	if (rec == NULL) {
+		DEBUG(5, ("fetch_locked failed\n"));
+		goto cancel;
+	}
+
+	status = rec->delete_rec(rec);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(5, ("delete_rec returned %s\n", nt_errstr(status)));
+		goto cancel;
+	}
+
+	TALLOC_FREE(rec);
+
+	res = db->transaction_commit(db);
+	if (res != 0) {
+		DEBUG(5, ("tdb_transaction_commit failed\n"));
+	}
+
+	return res;
+
+ cancel:
+	if (db->transaction_cancel(db) != 0) {
+		smb_panic("Cancelling transaction failed");
+	}
+	return -1;
+}
diff --git a/source/lib/server_mutex.c b/source/lib/server_mutex.c
index 2700aa1..43c0de1 100644
--- a/source/lib/server_mutex.c
+++ b/source/lib/server_mutex.c
@@ -28,28 +28,51 @@
    This locking allows smbd's mutlithread architecture to look
    like the single-connection that NT makes. */
 
-static char *mutex_server_name;
+struct named_mutex {
+	struct tdb_wrap *tdb;
+	char *name;
+};
 
-bool grab_server_mutex(const char *name)
+static int unlock_named_mutex(struct named_mutex *mutex)
 {
-	mutex_server_name = SMB_STRDUP(name);
-	if (!mutex_server_name) {
-		DEBUG(0,("grab_server_mutex: malloc failed for %s\n", name));
-		return False;
+	tdb_unlock_bystring(mutex->tdb->tdb, mutex->name);
+	return 0;
+}
+
+struct named_mutex *grab_named_mutex(TALLOC_CTX *mem_ctx, const char *name,
+				     int timeout)
+{
+	struct named_mutex *result;
+
+	result = talloc(mem_ctx, struct named_mutex);
+	if (result == NULL) {
+		DEBUG(0, ("talloc failed\n"));
+		return NULL;
 	}
-	if (!secrets_named_mutex(mutex_server_name, 10)) {
-		DEBUG(10,("grab_server_mutex: failed for %s\n", name));
-		SAFE_FREE(mutex_server_name);
-		return False;
+
+	result->name = talloc_strdup(result, name);
+	if (result->name == NULL) {
+		DEBUG(0, ("talloc failed\n"));
+		TALLOC_FREE(result);
+		return NULL;
 	}
 
-	return True;
-}
+	result->tdb = tdb_wrap_open(result, lock_path("mutex.tdb"), 0,
+				    TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+	if (result->tdb == NULL) {
+		DEBUG(1, ("Could not open mutex.tdb: %s\n",
+			  strerror(errno)));
+		TALLOC_FREE(result);
+		return NULL;
+	}
 
-void release_server_mutex(void)
-{
-	if (mutex_server_name) {
-		secrets_named_mutex_release(mutex_server_name);
-		SAFE_FREE(mutex_server_name);
+	if (tdb_lock_bystring_with_timeout(result->tdb->tdb, name,
+					   timeout) == -1) {
+		DEBUG(1, ("Could not get the lock for %s\n", name));
+		TALLOC_FREE(result);
+		return NULL;
 	}
+
+	talloc_set_destructor(result, unlock_named_mutex);
+	return result;
 }
diff --git a/source/libads/kerberos_verify.c b/source/libads/kerberos_verify.c
index f112dd3..6b482ec 100644
--- a/source/libads/kerberos_verify.c
+++ b/source/libads/kerberos_verify.c
@@ -330,8 +330,8 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx,
 	krb5_const_principal client_principal = NULL;
 	char *host_princ_s = NULL;
 	bool auth_ok = False;
-	bool got_replay_mutex = False;
 	bool got_auth_data = False;
+	struct named_mutex *mutex = NULL;
 
 	ZERO_STRUCT(packet);
 	ZERO_STRUCT(auth_data);
@@ -395,15 +395,15 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx,
 		   locking in the MIT krb5 code surrounding the replay 
 		   cache... */
 
-		if (!grab_server_mutex("replay cache mutex")) {
+		mutex = grab_named_mutex(talloc_tos(), "replay cache mutex",
+					 10);
+		if (mutex == NULL) {
 			DEBUG(1,("ads_verify_ticket: unable to protect "
 				 "replay cache with mutex.\n"));
 			ret = KRB5_CC_IO;
 			goto out;
 		}
 
-		got_replay_mutex = True;
-
 		/* JRA. We must set the rcache here. This will prevent 
 		   replay attacks. */
 		
@@ -443,8 +443,7 @@ NTSTATUS ads_verify_ticket(TALLOC_CTX *mem_ctx,
 	}


-- 
Samba Shared Repository


More information about the samba-cvs mailing list