From 11f2583420310e0278188935f31be3131eb85fd4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 16 Jan 2019 21:29:51 +0100 Subject: [PATCH] s3:smbd: fix max_buffer handling of initial notify requests The max_buffer value is only evaluated on the first notify request on a directory handle. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13864 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Fri Mar 29 00:35:39 UTC 2019 on sn-devel-144 --- selftest/knownfail | 1 - source3/smbd/notify.c | 11 +++++++++-- source3/smbd/nttrans.c | 6 ++++-- source3/smbd/proto.h | 4 +++- source3/smbd/smb2_notify.c | 1 + 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/selftest/knownfail b/selftest/knownfail index 49e889e6942..c588f2f5c6b 100644 --- a/selftest/knownfail +++ b/selftest/knownfail @@ -169,7 +169,6 @@ ^samba3.smb2.create.gentest ^samba3.smb2.create.blob ^samba3.smb2.create.open -^samba3.smb2.notify.valid-req ^samba3.smb2.notify.rec ^samba3.smb2.durable-open.delete_on_close2 ^samba3.smb2.durable-v2-open.app-instance diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c index 44c0b09432e..bf3fff7b97d 100644 --- a/source3/smbd/notify.c +++ b/source3/smbd/notify.c @@ -43,6 +43,8 @@ struct notify_change_buf { * we only append. */ + uint32_t max_buffer_size; + /* * num_changes == -1 means that we have got a catch-all change, when * asked we just return NT_STATUS_OK without specific changes. @@ -224,11 +226,13 @@ void change_notify_reply(struct smb_request *req, return; } - if (max_param == 0 || notify_buf == NULL) { + if (notify_buf == NULL) { reply_fn(req, NT_STATUS_OK, NULL, 0); return; } + max_param = MIN(max_param, notify_buf->max_buffer_size); + if (!notify_marshall_changes(notify_buf->num_changes, max_param, notify_buf->changes, &blob)) { /* @@ -276,7 +280,9 @@ void notify_callback(struct smbd_server_connection *sconn, files_forall(sconn, notify_fsp_cb, &state); } -NTSTATUS change_notify_create(struct files_struct *fsp, uint32_t filter, +NTSTATUS change_notify_create(struct files_struct *fsp, + uint32_t max_buffer_size, + uint32_t filter, bool recursive) { size_t len = fsp_fullbasepath(fsp, NULL, 0); @@ -295,6 +301,7 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32_t filter, } fsp->notify->filter = filter; fsp->notify->subdir_filter = recursive ? filter : 0; + fsp->notify->max_buffer_size = max_buffer_size; fsp_fullbasepath(fsp, fullpath, sizeof(fullpath)); diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 7ebd802109f..8bb121a1351 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -1806,8 +1806,10 @@ static void call_nt_transact_notify_change(connection_struct *conn, if (fsp->notify == NULL) { - status = change_notify_create(fsp, filter, recursive); - + status = change_notify_create(fsp, + max_param_count, + filter, + recursive); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("change_notify_create returned %s\n", nt_errstr(status))); diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index 3662a925dd6..fdb0ffabf75 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -542,7 +542,9 @@ void change_notify_reply(struct smb_request *req, void notify_callback(struct smbd_server_connection *sconn, void *private_data, struct timespec when, const struct notify_event *e); -NTSTATUS change_notify_create(struct files_struct *fsp, uint32_t filter, +NTSTATUS change_notify_create(struct files_struct *fsp, + uint32_t max_buffer_size, + uint32_t filter, bool recursive); NTSTATUS change_notify_add_request(struct smb_request *req, uint32_t max_param, diff --git a/source3/smbd/smb2_notify.c b/source3/smbd/smb2_notify.c index 24241562556..68429b7b766 100644 --- a/source3/smbd/smb2_notify.c +++ b/source3/smbd/smb2_notify.c @@ -263,6 +263,7 @@ static struct tevent_req *smbd_smb2_notify_send(TALLOC_CTX *mem_ctx, if (fsp->notify == NULL) { status = change_notify_create(fsp, + in_output_buffer_length, in_completion_filter, recursive); if (!NT_STATUS_IS_OK(status)) { -- 2.34.1