impove session setup code: functions for finding free session ids
authorStefan Metzmacher <metze@samba.org>
Wed, 1 Feb 2012 12:15:50 +0000 (13:15 +0100)
committerStefan Metzmacher <metze@samba.org>
Thu, 10 May 2012 16:41:07 +0000 (18:41 +0200)
source3/smbd/smbXsrv_session.c

index 449410a8d1a3978d8c9947be3bfc3d94834289f0..3b5938888c19e9595afaf456ca9b8e46d4fb8a8b 100644 (file)
@@ -92,7 +92,7 @@ static NTSTATUS smbXsrv_session_table_init(struct smbXsrv_connection *conn,
        return NT_STATUS_OK;
 }
 
-struct smbXsrv_session_local_free_state {
+struct smb1srv_session_local_allocate_state {
        const uint32_t lowest_id;
        const uint32_t highest_id;
        uint32_t last_id;
@@ -100,11 +100,11 @@ struct smbXsrv_session_local_free_state {
        NTSTATUS status;
 };
 
-static int smbXsrv_session_local_free_traverse(struct db_record *rec,
-                                              void *private_data)
+static int smb1srv_session_local_allocate_traverse(struct db_record *rec,
+                                                  void *private_data)
 {
-       struct smbXsrv_session_local_free_state *state =
-               (struct smbXsrv_session_local_free_state *)private_data;
+       struct smb1srv_session_local_allocate_state *state =
+               (struct smb1srv_session_local_allocate_state *)private_data;
        TDB_DATA key = dbwrap_record_get_key(rec);
        uint32_t id = 0;
 
@@ -114,7 +114,15 @@ static int smbXsrv_session_local_free_traverse(struct db_record *rec,
                return -1;
        }
 
-       id = IVAL(key.dptr, 0);
+       /*
+        * NOTE:
+        * We need big endian so that dbwrap_rbt's memcmp
+        * has the same result as integer comparison between the uint32_t
+        * values.
+        *
+        * TODO: implement string based key
+        */
+       id = RIVAL(key.dptr, 0);
 
        if (id <= state->last_id) {
                //TODO errno?
@@ -132,14 +140,14 @@ static int smbXsrv_session_local_free_traverse(struct db_record *rec,
        return 0;
 }
 
-static NTSTATUS smbXsrv_session_local_free_id(struct db_context *db,
-                                             uint32_t lowest_id,
-                                             uint32_t highest_id,
-                                             TALLOC_CTX *mem_ctx,
-                                             struct db_record **_rec,
-                                             uint32_t *_id)
+static NTSTATUS smb1srv_session_local_allocate_id(struct db_context *db,
+                                                 uint32_t lowest_id,
+                                                 uint32_t highest_id,
+                                                 TALLOC_CTX *mem_ctx,
+                                                 struct db_record **_rec,
+                                                 uint32_t *_id)
 {
-       struct smbXsrv_session_local_free_state state = {
+       struct smb1srv_session_local_allocate_state state = {
                .lowest_id = lowest_id,
                .highest_id = highest_id,
                .last_id = 0,
@@ -177,7 +185,7 @@ static NTSTATUS smbXsrv_session_local_free_id(struct db_context *db,
                        id = highest_id;
                }
 
-               SIVAL(key_buf, 0, id);
+               RSIVAL(key_buf, 0, id);
                key = make_tdb_data(key_buf, sizeof(key_buf));
 
                rec = dbwrap_fetch_locked(db, mem_ctx, key);
@@ -196,7 +204,7 @@ static NTSTATUS smbXsrv_session_local_free_id(struct db_context *db,
                return NT_STATUS_OK;
        }
 
-       status = dbwrap_traverse_read(db, smbXsrv_session_local_free_traverse,
+       status = dbwrap_traverse_read(db, smb1srv_session_local_allocate_traverse,
                                      &state, &count);
        if (!NT_STATUS_EQUAL(status, NT_STATUS_INTERNAL_DB_CORRUPTION)) {
                /*
@@ -218,7 +226,7 @@ static NTSTATUS smbXsrv_session_local_free_id(struct db_context *db,
 
                id = state.useable_id;
 
-               SIVAL(key_buf, 0, id);
+               RSIVAL(key_buf, 0, id);
                key = make_tdb_data(key_buf, sizeof(key_buf));
 
                rec = dbwrap_fetch_locked(db, mem_ctx, key);
@@ -229,7 +237,7 @@ static NTSTATUS smbXsrv_session_local_free_id(struct db_context *db,
                val = dbwrap_record_get_value(rec);
                if (val.dsize != 0) {
                        TALLOC_FREE(rec);
-                       return NT_STATUS_INSUFFICIENT_RESOURCES;
+                       return NT_STATUS_INTERNAL_DB_CORRUPTION;
                }
 
                *_rec = rec;
@@ -336,7 +344,7 @@ static NTSTATUS smbXsrv_session_global_allocate(struct db_context *db,
                        id--;
                }
 
-               SIVAL(key_buf, 0, id);
+               RSIVAL(key_buf, 0, id);
                key = make_tdb_data(key_buf, sizeof(key_buf));
 
                global->db_rec = dbwrap_fetch_locked(db, mem_ctx, key);
@@ -374,7 +382,7 @@ static NTSTATUS smbXsrv_session_global_store(struct smbXsrv_connection *sconn,
        /*
         * TODO: if we use other versions than '0'
         * we would add glue code here, that would be able to
-        * store the information in the lod format.
+        * store the information in the old format.
         */
 
        if (global->db_rec == NULL) {
@@ -410,6 +418,7 @@ static NTSTATUS smbXsrv_session_global_store(struct smbXsrv_connection *sconn,
 }
 
 struct smbXsrv_session_global_fetch_state {
+       TALLOC_CTX *mem_ctx;
        struct smbXsrv_session_global *session;
        NTSTATUS status;
 };
@@ -425,13 +434,16 @@ static void smbXsrv_session_global_fetch_parser(TDB_DATA key, TDB_DATA data,
 
 static NTSTATUS smbXsrv_session_global_lookup(struct smbXsrv_session_table *table,
                                              uint32_t session_global_id,
+                                             TALLOC_CTX *mem_ctx,
                                              struct smbXsrv_session_global **_session)
 {
        struct smbXsrv_session_global_fetch_state state = {
+               .mem_ctx = mem_ctx,
                .session = NULL,
                .status = NT_STATUS_INTERNAL_ERROR,
        };
        TDB_DATA key;
+       uint8_t key_buf[sizeof(uint32_t)];
        NTSTATUS status;
 
        *_session = NULL;
@@ -439,8 +451,10 @@ static NTSTATUS smbXsrv_session_global_lookup(struct smbXsrv_session_table *tabl
        if (table->global.db_ctx == NULL) {
                return NT_STATUS_INTERNAL_ERROR;
        }
-       key = make_tdb_data((const uint8_t *)&session_global_id,
-                           sizeof(session_global_id));
+
+       /* TODO: key as string */
+       RSIVAL(key_buf, 0, session_global_id);
+       key = make_tdb_data(key_buf, sizeof(key_buf));
 
        status = dbwrap_parse_record(table->global.db_ctx, key,
                                     smbXsrv_session_global_fetch_parser, &state);
@@ -504,7 +518,7 @@ NTSTATUS smbXsrv_session_create(struct smbXsrv_connection *conn,
 
                session->local_id = global->session_global_id;
 
-               SIVAL(key_buf, 0, session->local_id);
+               RSIVAL(key_buf, 0, session->local_id);
                key = make_tdb_data(key_buf, sizeof(key_buf));
 
                local_rec = dbwrap_fetch_locked(table->local.db_ctx,
@@ -519,12 +533,12 @@ NTSTATUS smbXsrv_session_create(struct smbXsrv_connection *conn,
                }
        } else {
 
-               status = smbXsrv_session_local_free_id(table->local.db_ctx,
-                                                      table->local.lowest_id,
-                                                      table->local.highest_id,
-                                                      session,
-                                                      &local_rec,
-                                                      &session->local_id);
+               status = smb1srv_session_local_allocate_id(table->local.db_ctx,
+                                                       table->local.lowest_id,
+                                                       table->local.highest_id,
+                                                       session,
+                                                       &local_rec,
+                                                       &session->local_id);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }