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 <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
Date:   Mon Mar 10 13:27:27 2008 +0100

    Add dbwrap_trans_store and dbwrap_trans_delete

commit 0a55e018dd68af06d84332d54148bbfb0b510b22
Author: Volker Lendecke <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
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

Reply via email to