smbd: Do oplock break messages in ndr
authorVolker Lendecke <vl@samba.org>
Thu, 16 May 2019 13:38:26 +0000 (15:38 +0200)
committerJeremy Allison <jra@samba.org>
Thu, 16 May 2019 23:48:17 +0000 (23:48 +0000)
The previous scheme was overloaded, a idl definition is easier to
print, and it clarifies what data is actually needed

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Thu May 16 23:48:18 UTC 2019 on sn-devel-184

source3/librpc/idl/open_files.idl
source3/smbd/open.c
source3/smbd/oplock.c

index 2f6f861..a823e3f 100644 (file)
@@ -98,4 +98,10 @@ interface open_files
                timespec close_write_time;
                vfs_default_durable_stat stat_info;
        } vfs_default_durable_cookie;
+
+       typedef [public] struct {
+               file_id id;
+               udlong share_file_id;
+               uint8 break_to;
+       } oplock_break_message;
 }
index ab7999a..2d58150 100644 (file)
@@ -29,7 +29,7 @@
 #include "fake_file.h"
 #include "../libcli/security/security.h"
 #include "../librpc/gen_ndr/ndr_security.h"
-#include "../librpc/gen_ndr/open_files.h"
+#include "../librpc/gen_ndr/ndr_open_files.h"
 #include "../librpc/gen_ndr/idmap.h"
 #include "../librpc/gen_ndr/ioctl.h"
 #include "passdb/lookup_sid.h"
@@ -1695,26 +1695,36 @@ NTSTATUS send_break_message(struct messaging_context *msg_ctx,
                            const struct share_mode_entry *exclusive,
                            uint16_t break_to)
 {
+       struct oplock_break_message msg = {
+               .id = *id,
+               .share_file_id = exclusive->share_file_id,
+               .break_to = break_to,
+       };
+       enum ndr_err_code ndr_err;
+       DATA_BLOB blob;
        NTSTATUS status;
-       char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
-       struct server_id_buf tmp;
-
-       DEBUG(10, ("Sending break request to PID %s\n",
-                  server_id_str_buf(exclusive->pid, &tmp)));
 
-       /* Create the message. */
-       share_mode_entry_to_message(msg, id, exclusive);
+       if (DEBUGLVL(10)) {
+               struct server_id_buf buf;
+               DBG_DEBUG("Sending break message to %s\n",
+                         server_id_str_buf(exclusive->pid, &buf));
+               NDR_PRINT_DEBUG(oplock_break_message, &msg);
+       }
 
-       /* Overload entry->op_type */
-       /*
-        * This is a cut from uint32_t to uint16_t, but so far only the lower 3
-        * bits (LEASE_WRITE/HANDLE/READ) are used anyway.
-        */
-       SSVAL(msg,OP_BREAK_MSG_OP_TYPE_OFFSET, break_to);
+       ndr_err = ndr_push_struct_blob(
+               &blob,
+               talloc_tos(),
+               &msg,
+               (ndr_push_flags_fn_t)ndr_push_oplock_break_message);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
+                           ndr_errstr(ndr_err));
+               return ndr_map_error2ntstatus(ndr_err);
+       }
 
-       status = messaging_send_buf(msg_ctx, exclusive->pid,
-                                   MSG_SMB_BREAK_REQUEST,
-                                   (uint8_t *)msg, sizeof(msg));
+       status = messaging_send(
+               msg_ctx, exclusive->pid, MSG_SMB_BREAK_REQUEST, &blob);
+       TALLOC_FREE(blob.data);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(3, ("Could not send oplock break message: %s\n",
                          nt_errstr(status)));
index d08003b..b99b9cb 100644 (file)
@@ -945,8 +945,8 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx,
                                         struct server_id src,
                                         DATA_BLOB *data)
 {
-       struct file_id id;
-       struct share_mode_entry msg;
+       struct oplock_break_message *msg = NULL;
+       enum ndr_err_code ndr_err;
        files_struct *fsp;
        bool use_kernel;
        struct smbd_server_connection *sconn =
@@ -957,28 +957,35 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx,
        uint16_t break_from;
        uint16_t break_to;
        bool break_needed = true;
-       struct server_id_buf tmp;
 
-       if (data->data == NULL) {
-               DEBUG(0, ("Got NULL buffer\n"));
+       msg = talloc(talloc_tos(), struct oplock_break_message);
+       if (msg == NULL) {
+               DBG_WARNING("talloc failed\n");
                return;
        }
 
-       if (data->length != MSG_SMB_SHARE_MODE_ENTRY_SIZE) {
-               DEBUG(0, ("Got invalid msg len %d\n", (int)data->length));
+       ndr_err = ndr_pull_struct_blob_all(
+               data,
+               msg,
+               msg,
+               (ndr_pull_flags_fn_t)ndr_pull_oplock_break_message);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               DBG_DEBUG("ndr_pull_oplock_break_message failed: %s\n",
+                         ndr_errstr(ndr_err));
+               TALLOC_FREE(msg);
                return;
        }
+       if (DEBUGLEVEL >= 10) {
+               struct server_id_buf buf;
+               DBG_DEBUG("Got break message from %s\n",
+                         server_id_str_buf(src, &buf));
+               NDR_PRINT_DEBUG(oplock_break_message, msg);
+       }
 
-       /* De-linearize incoming message. */
-       message_to_share_mode_entry(&id, &msg, (char *)data->data);
-       break_to = msg.op_type;
-
-       DEBUG(10, ("Got oplock break to %u message from pid %s: %s/%llu\n",
-                  (unsigned)break_to, server_id_str_buf(src, &tmp),
-                  file_id_string_tos(&id),
-                  (unsigned long long)msg.share_file_id));
+       break_to = msg->break_to;
+       fsp = initial_break_processing(sconn, msg->id, msg->share_file_id);
 
-       fsp = initial_break_processing(sconn, id, msg.share_file_id);
+       TALLOC_FREE(msg);
 
        if (fsp == NULL) {
                /* We hit a race here. Break messages are sent, and before we
@@ -1040,7 +1047,7 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx,
 
                status = leases_db_get(client_guid,
                                       &fsp->lease->lease.lease_key,
-                                      &id,
+                                      &fsp->file_id,
                                       &current_state,
                                       &breaking,
                                       &breaking_to_requested,