[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