diff options
author | Volker Lendecke <vl@samba.org> | 2019-05-16 15:38:26 +0200 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2019-05-16 23:48:17 +0000 |
commit | ab648a4c63524038c9626a77be243c79c51975ac (patch) | |
tree | d4d1564d74c0a59dd8d58bd06818daa193e423d2 | |
parent | 3d9a720f092b8c45184a0d53540fb490a3fdef9d (diff) | |
download | samba-ab648a4c63524038c9626a77be243c79c51975ac.tar.gz |
smbd: Do oplock break messages in ndr
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
-rw-r--r-- | source3/librpc/idl/open_files.idl | 6 | ||||
-rw-r--r-- | source3/smbd/open.c | 44 | ||||
-rw-r--r-- | source3/smbd/oplock.c | 41 |
3 files changed, 57 insertions, 34 deletions
diff --git a/source3/librpc/idl/open_files.idl b/source3/librpc/idl/open_files.idl index 2f6f861b5e6..a823e3f9134 100644 --- a/source3/librpc/idl/open_files.idl +++ b/source3/librpc/idl/open_files.idl @@ -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; } diff --git a/source3/smbd/open.c b/source3/smbd/open.c index ab7999ada24..2d5815069f2 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -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))); diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c index d08003bb3e9..b99b9cb4f08 100644 --- a/source3/smbd/oplock.c +++ b/source3/smbd/oplock.c @@ -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, ¤t_state, &breaking, &breaking_to_requested, |