smb2_server: call smbXsrv_connection_disconnect_transport() early on network errors
[gd/samba-autobuild/.git] / source3 / smbd / smbXsrv_client.c
index 7286b6e02081bad1e5140bf865708afdf20c22a5..c6114d4b8dcfce6089e2d201a3d7b67401dfc6d2 100644 (file)
@@ -20,6 +20,7 @@
 #include "includes.h"
 #include "system/filesys.h"
 #include <tevent.h>
+#include "lib/util/server_id.h"
 #include "smbd/smbd.h"
 #include "smbd/globals.h"
 #include "dbwrap/dbwrap.h"
@@ -62,7 +63,7 @@ NTSTATUS smbXsrv_client_global_init(void)
        /*
         * This contains secret information like client keys!
         */
-       global_path = lock_path("smbXsrv_client_global.tdb");
+       global_path = lock_path(talloc_tos(), "smbXsrv_client_global.tdb");
        if (global_path == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -132,8 +133,9 @@ static struct db_record *smbXsrv_client_global_fetch_locked(
        rec = dbwrap_fetch_locked(db, mem_ctx, key);
 
        if (rec == NULL) {
+               struct GUID_txt_buf buf;
                DBG_DEBUG("Failed to lock guid [%s], key '%s'\n",
-                         GUID_string(talloc_tos(), client_guid),
+                         GUID_buf_string(client_guid, &buf),
                          hex_encode_talloc(talloc_tos(), key.dptr, key.dsize));
        }
 
@@ -167,8 +169,6 @@ static NTSTATUS smbXsrv_client_table_create(TALLOC_CTX *mem_ctx,
 
        table->global.db_ctx = smbXsrv_client_global_db_ctx;
 
-       dbwrap_watch_db(table->global.db_ctx, msg_ctx);
-
        *_table = table;
        return NT_STATUS_OK;
 }
@@ -294,6 +294,13 @@ NTSTATUS smb2srv_client_lookup_global(struct smbXsrv_client *client,
                return NT_STATUS_OBJECTID_NOT_FOUND;
        }
 
+       if (global == NULL) {
+               /*
+                * most likely ndr_pull_struct_blob() failed
+                */
+               return NT_STATUS_INTERNAL_DB_CORRUPTION;
+       }
+
        *_global = global;
        return NT_STATUS_OK;
 }
@@ -346,7 +353,7 @@ NTSTATUS smb2srv_client_connection_pass(struct smbd_smb2_request *smb2req,
        iov.iov_base = blob.data;
        iov.iov_len = blob.length;
 
-       status = messaging_send_iov(smb2req->xconn->msg_ctx,
+       status = messaging_send_iov(smb2req->xconn->client->msg_ctx,
                                    global->server_id,
                                    MSG_SMBXSRV_CONNECTION_PASS,
                                    &iov, 1,
@@ -375,6 +382,10 @@ static NTSTATUS smbXsrv_client_global_store(struct smbXsrv_client_global0 *globa
         * store the information in the old format.
         */
 
+       SMB_ASSERT(global->local_address != NULL);
+       SMB_ASSERT(global->remote_address != NULL);
+       SMB_ASSERT(global->remote_name != NULL);
+
        if (global->db_rec == NULL) {
                return NT_STATUS_INTERNAL_ERROR;
        }
@@ -508,11 +519,13 @@ NTSTATUS smbXsrv_client_create(TALLOC_CTX *mem_ctx,
                TALLOC_FREE(table);
                return NT_STATUS_NO_MEMORY;
        }
-       client->ev_ctx = ev_ctx;
+       client->raw_ev_ctx = ev_ctx;
        client->msg_ctx = msg_ctx;
 
        client->server_multi_channel_enabled = lp_server_multi_channel_support();
-
+       if (client->server_multi_channel_enabled) {
+               client->next_channel_id = 1;
+       }
        client->table = talloc_move(client, &table);
        table = client->table;
 
@@ -533,20 +546,22 @@ NTSTATUS smbXsrv_client_create(TALLOC_CTX *mem_ctx,
        talloc_set_destructor(client, smbXsrv_client_destructor);
 
        if (DEBUGLVL(DBGLVL_DEBUG)) {
-               struct smbXsrv_clientB client_blob;
-
-               ZERO_STRUCT(client_blob);
-               client_blob.version = SMBXSRV_VERSION_0;
-               client_blob.info.info0 = client;
-
-               DBG_DEBUG("client_guid[%s] stored\n",
-                         GUID_string(talloc_tos(), &global->client_guid));
+               struct smbXsrv_clientB client_blob = {
+                       .version = SMBXSRV_VERSION_0,
+                       .info.info0 = client,
+               };
+               struct GUID_txt_buf buf;
+
+               DBG_DEBUG("client_guid[%s] created\n",
+                         GUID_buf_string(&global->client_guid, &buf));
                NDR_PRINT_DEBUG(smbXsrv_clientB, &client_blob);
        }
 
-       subreq = messaging_filtered_read_send(client, client->ev_ctx, client->msg_ctx,
-                                             smbXsrv_client_connection_pass_filter,
-                                             client);
+       subreq = messaging_filtered_read_send(client,
+                                       client->raw_ev_ctx,
+                                       client->msg_ctx,
+                                       smbXsrv_client_connection_pass_filter,
+                                       client);
        if (subreq == NULL) {
                TALLOC_FREE(client);
                return NT_STATUS_NO_MEMORY;
@@ -625,9 +640,13 @@ static void smbXsrv_client_connection_pass_loop(struct tevent_req *subreq)
 
        if (!GUID_equal(&client->global->client_guid, &pass_info0->client_guid))
        {
+               struct GUID_txt_buf buf1, buf2;
+
                DBG_WARNING("client's client_guid [%s] != passed guid [%s]\n",
-                       GUID_string(talloc_tos(), &client->global->client_guid),
-                       GUID_string(talloc_tos(), &pass_info0->client_guid));
+                           GUID_buf_string(&client->global->client_guid,
+                                           &buf1),
+                           GUID_buf_string(&pass_info0->client_guid,
+                                           &buf2));
                if (DEBUGLVL(DBGLVL_WARNING)) {
                        NDR_PRINT_DEBUG(smbXsrv_connection_passB, &pass_blob);
                }
@@ -656,7 +675,10 @@ static void smbXsrv_client_connection_pass_loop(struct tevent_req *subreq)
 
        DBG_ERR("got connection sockfd[%d]\n", sock_fd);
        NDR_PRINT_DEBUG(smbXsrv_connection_passB, &pass_blob);
-       status = smbd_add_connection(client, sock_fd, &xconn);
+       status = smbd_add_connection(client,
+                                    sock_fd,
+                                    pass_info0->initial_connect_time,
+                                    &xconn);
        if (!NT_STATUS_IS_OK(status)) {
                close(sock_fd);
                sock_fd = -1;
@@ -679,9 +701,11 @@ static void smbXsrv_client_connection_pass_loop(struct tevent_req *subreq)
 next:
        TALLOC_FREE(rec);
 
-       subreq = messaging_filtered_read_send(client, client->ev_ctx, client->msg_ctx,
-                                             smbXsrv_client_connection_pass_filter,
-                                             client);
+       subreq = messaging_filtered_read_send(client,
+                                       client->raw_ev_ctx,
+                                       client->msg_ctx,
+                                       smbXsrv_client_connection_pass_filter,
+                                       client);
        if (subreq == NULL) {
                const char *r;
                r = "messaging_read_send(MSG_SMBXSRV_CONNECTION_PASS failed";
@@ -697,9 +721,10 @@ NTSTATUS smbXsrv_client_update(struct smbXsrv_client *client)
        NTSTATUS status;
 
        if (client->global->db_rec != NULL) {
+               struct GUID_txt_buf buf;
                DBG_ERR("guid [%s]: Called with db_rec != NULL'\n",
-                       GUID_string(talloc_tos(),
-                       &client->global->client_guid));
+                       GUID_buf_string(&client->global->client_guid,
+                                       &buf));
                return NT_STATUS_INTERNAL_ERROR;
        }
 
@@ -713,21 +738,24 @@ NTSTATUS smbXsrv_client_update(struct smbXsrv_client *client)
 
        status = smbXsrv_client_global_store(client->global);
        if (!NT_STATUS_IS_OK(status)) {
+               struct GUID_txt_buf buf;
                DBG_ERR("client_guid[%s] store failed - %s\n",
-                       GUID_string(talloc_tos(), &client->global->client_guid),
+                       GUID_buf_string(&client->global->client_guid,
+                                       &buf),
                        nt_errstr(status));
                return status;
        }
 
        if (DEBUGLVL(DBGLVL_DEBUG)) {
-               struct smbXsrv_clientB client_blob;
-
-               ZERO_STRUCT(client_blob);
-               client_blob.version = SMBXSRV_VERSION_0;
-               client_blob.info.info0 = client;
+               struct smbXsrv_clientB client_blob = {
+                       .version = SMBXSRV_VERSION_0,
+                       .info.info0 = client,
+               };
+               struct GUID_txt_buf buf;
 
                DBG_DEBUG("client_guid[%s] stored\n",
-                       GUID_string(talloc_tos(), &client->global->client_guid));
+                         GUID_buf_string(&client->global->client_guid,
+                                         &buf));
                NDR_PRINT_DEBUG(smbXsrv_clientB, &client_blob);
        }
 
@@ -740,8 +768,10 @@ NTSTATUS smbXsrv_client_remove(struct smbXsrv_client *client)
        NTSTATUS status;
 
        if (client->global->db_rec != NULL) {
+               struct GUID_txt_buf buf;
                DBG_ERR("client_guid[%s]: Called with db_rec != NULL'\n",
-                       GUID_string(talloc_tos(), &client->global->client_guid));
+                       GUID_buf_string(&client->global->client_guid,
+                                       &buf));
                return NT_STATUS_INTERNAL_ERROR;
        }
 
@@ -759,21 +789,22 @@ NTSTATUS smbXsrv_client_remove(struct smbXsrv_client *client)
 
        status = smbXsrv_client_global_remove(client->global);
        if (!NT_STATUS_IS_OK(status)) {
+               struct GUID_txt_buf buf;
                DBG_ERR("client_guid[%s] store failed - %s\n",
-                       GUID_string(talloc_tos(), &client->global->client_guid),
+                       GUID_buf_string(&client->global->client_guid, &buf),
                        nt_errstr(status));
                return status;
        }
 
        if (DEBUGLVL(DBGLVL_DEBUG)) {
-               struct smbXsrv_clientB client_blob;
-
-               ZERO_STRUCT(client_blob);
-               client_blob.version = SMBXSRV_VERSION_0;
-               client_blob.info.info0 = client;
+               struct smbXsrv_clientB client_blob = {
+                       .version = SMBXSRV_VERSION_0,
+                       .info.info0 = client,
+               };
+               struct GUID_txt_buf buf;
 
                DBG_DEBUG("client_guid[%s] stored\n",
-                       GUID_string(talloc_tos(), &client->global->client_guid));
+                         GUID_buf_string(&client->global->client_guid, &buf));
                NDR_PRINT_DEBUG(smbXsrv_clientB, &client_blob);
        }