summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2019-05-16 15:38:26 +0200
committerJeremy Allison <jra@samba.org>2019-05-16 23:48:17 +0000
commitab648a4c63524038c9626a77be243c79c51975ac (patch)
treed4d1564d74c0a59dd8d58bd06818daa193e423d2
parent3d9a720f092b8c45184a0d53540fb490a3fdef9d (diff)
downloadsamba-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.idl6
-rw-r--r--source3/smbd/open.c44
-rw-r--r--source3/smbd/oplock.c41
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,
&current_state,
&breaking,
&breaking_to_requested,