From a8958391e8fd9ddd996d2d3aff7ddeed3243fc1f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Jul 2006 14:25:50 +0000 Subject: r16980: - make struct smb_notify a union and add levels RAW_NOTIFY_NTTRANS,RAW_NOTIFY_SMB2 - parse SMB2 Notify reponse metze (This used to be commit de50e0ccddfad16ad7b254770f4c52c1abe707b9) --- source4/libcli/raw/interfaces.h | 65 ++++++-- source4/libcli/raw/rawnotify.c | 38 +++-- source4/libcli/smb2/notify.c | 31 +++- source4/libcli/smb2/smb2_calls.h | 22 --- source4/ntvfs/cifs/vfs_cifs.c | 10 +- source4/ntvfs/ntvfs.h | 2 +- source4/ntvfs/ntvfs_interface.c | 4 +- source4/ntvfs/posix/pvfs_notify.c | 26 ++-- source4/ntvfs/unixuid/vfs_unixuid.c | 2 +- source4/smb_server/smb/nttrans.c | 33 ++-- source4/torture/gentest.c | 52 +++---- source4/torture/raw/notify.c | 289 +++++++++++++++++++----------------- 12 files changed, 322 insertions(+), 252 deletions(-) (limited to 'source4') diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 8ebdd38bee..d3e7611c75 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -2128,23 +2128,60 @@ struct smb_nttrans { } out; }; +enum smb_notify_level { + RAW_NOTIFY_NTTRANS, + RAW_NOTIFY_SMB2 +}; -/* struct for nttrans change notify call */ -struct smb_notify { +union smb_notify { + /* struct for nttrans change notify call */ struct { - union smb_handle file; - uint32_t buffer_size; - uint32_t completion_filter; - BOOL recursive; - } in; + enum smb_notify_level level; - struct { - uint32_t num_changes; - struct notify_changes { - uint32_t action; - struct smb_wire_string name; - } *changes; - } out; + struct { + union smb_handle file; + uint32_t buffer_size; + uint32_t completion_filter; + BOOL recursive; + } in; + + struct { + uint32_t num_changes; + struct notify_changes { + uint32_t action; + struct smb_wire_string name; + } *changes; + } out; + } nttrans; + + struct smb2_notify { + enum smb_notify_level level; + + struct { + union smb_handle file; + /* static body buffer 32 (0x20) bytes */ + /* uint16_t buffer_code; 0x32 */ + uint16_t recursive; + uint32_t buffer_size; + /*struct smb2_handle file;*/ + uint32_t completion_filter; + uint32_t unknown; + } in; + + struct { + /* static body buffer 8 (0x08) bytes */ + /* uint16_t buffer_code; 0x09 = 0x08 + 1 */ + /* uint16_t blob_ofs; */ + /* uint16_t blob_size; */ + + /* dynamic body */ + /*DATA_BLOB blob;*/ + + /* DATA_BLOB content */ + uint32_t num_changes; + struct notify_changes *changes; + } out; + } smb2; }; enum smb_search_level { diff --git a/source4/libcli/raw/rawnotify.c b/source4/libcli/raw/rawnotify.c index f4d4164016..2b68d96a1b 100644 --- a/source4/libcli/raw/rawnotify.c +++ b/source4/libcli/raw/rawnotify.c @@ -25,19 +25,23 @@ /**************************************************************************** change notify (async send) ****************************************************************************/ -struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, struct smb_notify *parms) +struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, union smb_notify *parms) { struct smb_nttrans nt; uint16_t setup[4]; + if (parms->nttrans.level != RAW_NOTIFY_NTTRANS) { + return NULL; + } + nt.in.max_setup = 0; - nt.in.max_param = parms->in.buffer_size; + nt.in.max_param = parms->nttrans.in.buffer_size; nt.in.max_data = 0; nt.in.setup_count = 4; nt.in.setup = setup; - SIVAL(setup, 0, parms->in.completion_filter); - SSVAL(setup, 4, parms->in.file.fnum); - SSVAL(setup, 6, parms->in.recursive); + SIVAL(setup, 0, parms->nttrans.in.completion_filter); + SSVAL(setup, 4, parms->nttrans.in.file.fnum); + SSVAL(setup, 6, parms->nttrans.in.recursive); nt.in.function = NT_TRANSACT_NOTIFY_CHANGE; nt.in.params = data_blob(NULL, 0); nt.in.data = data_blob(NULL, 0); @@ -49,41 +53,45 @@ struct smbcli_request *smb_raw_changenotify_send(struct smbcli_tree *tree, struc change notify (async recv) ****************************************************************************/ NTSTATUS smb_raw_changenotify_recv(struct smbcli_request *req, - TALLOC_CTX *mem_ctx, struct smb_notify *parms) + TALLOC_CTX *mem_ctx, union smb_notify *parms) { struct smb_nttrans nt; NTSTATUS status; uint32_t ofs, i; struct smbcli_session *session = req?req->session:NULL; + if (parms->nttrans.level != RAW_NOTIFY_NTTRANS) { + return NT_STATUS_INVALID_LEVEL; + } + status = smb_raw_nttrans_recv(req, mem_ctx, &nt); if (!NT_STATUS_IS_OK(status)) { return status; } - parms->out.changes = NULL; - parms->out.num_changes = 0; + parms->nttrans.out.changes = NULL; + parms->nttrans.out.num_changes = 0; /* count them */ for (ofs=0; nt.out.params.length - ofs > 12; ) { uint32_t next = IVAL(nt.out.params.data, ofs); - parms->out.num_changes++; + parms->nttrans.out.num_changes++; if (next == 0 || ofs + next >= nt.out.params.length) break; ofs += next; } /* allocate array */ - parms->out.changes = talloc_array(mem_ctx, struct notify_changes, parms->out.num_changes); - if (!parms->out.changes) { + parms->nttrans.out.changes = talloc_array(mem_ctx, struct notify_changes, parms->nttrans.out.num_changes); + if (!parms->nttrans.out.changes) { return NT_STATUS_NO_MEMORY; } - for (i=ofs=0; iout.num_changes; i++) { - parms->out.changes[i].action = IVAL(nt.out.params.data, ofs+4); + for (i=ofs=0; inttrans.out.num_changes; i++) { + parms->nttrans.out.changes[i].action = IVAL(nt.out.params.data, ofs+4); smbcli_blob_pull_string(session, mem_ctx, &nt.out.params, - &parms->out.changes[i].name, - ofs+8, ofs+12, STR_UNICODE); + &parms->nttrans.out.changes[i].name, + ofs+8, ofs+12, STR_UNICODE); ofs += IVAL(nt.out.params.data, ofs); } diff --git a/source4/libcli/smb2/notify.c b/source4/libcli/smb2/notify.c index 0e61293495..43792267f2 100644 --- a/source4/libcli/smb2/notify.c +++ b/source4/libcli/smb2/notify.c @@ -56,19 +56,46 @@ NTSTATUS smb2_notify_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct smb2_notify *io) { NTSTATUS status; + DATA_BLOB blob; + uint32_t ofs, i; if (!smb2_request_receive(req) || - smb2_request_is_error(req)) { + !smb2_request_is_ok(req)) { return smb2_request_destroy(req); } SMB2_CHECK_PACKET_RECV(req, 0x08, True); - status = smb2_pull_o16s32_blob(&req->in, mem_ctx, req->in.body+0x02, &io->out.blob); + status = smb2_pull_o16s32_blob(&req->in, mem_ctx, req->in.body+0x02, &blob); if (!NT_STATUS_IS_OK(status)) { return status; } + io->out.changes = NULL; + io->out.num_changes = 0; + + /* count them */ + for (ofs=0; blob.length - ofs > 12; ) { + uint32_t next = IVAL(blob.data, ofs); + io->out.num_changes++; + if (next == 0 || (ofs + next) >= blob.length) break; + ofs += next; + } + + /* allocate array */ + io->out.changes = talloc_array(mem_ctx, struct notify_changes, io->out.num_changes); + if (!io->out.changes) { + return NT_STATUS_NO_MEMORY; + } + + for (i=ofs=0; iout.num_changes; i++) { + io->out.changes[i].action = IVAL(blob.data, ofs+4); + smbcli_blob_pull_string(NULL, mem_ctx, &blob, + &io->out.changes[i].name, + ofs+8, ofs+12, STR_UNICODE); + ofs += IVAL(blob.data, ofs); + } + return smb2_request_destroy(req); } diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index c3dc629430..abb7f88ee2 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -94,28 +94,6 @@ struct smb2_setinfo { } in; }; -struct smb2_notify { - struct { - /* static body buffer 32 (0x20) bytes */ - /* uint16_t buffer_code; 0x32 */ - uint16_t recursive; - uint32_t buffer_size; - union smb_handle file; - uint32_t completion_filter; - uint32_t unknown; - } in; - - struct { - /* static body buffer 8 (0x08) bytes */ - /* uint16_t buffer_code; 0x09 = 0x08 + 1 */ - /* uint16_t blob_ofs; */ - /* uint16_t blob_size; */ - - /* dynamic body */ - DATA_BLOB blob; - } out; -}; - struct cli_credentials; struct event_context; #include "libcli/smb2/smb2_proto.h" diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 41ea2a652d..1e34e953a5 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -1000,18 +1000,22 @@ static void async_changenotify(struct smbcli_request *c_req) /* change notify request - always async */ static NTSTATUS cvfs_notify(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - struct smb_notify *io) + union smb_notify *io) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; int saved_timeout = private->transport->options.request_timeout; struct cvfs_file *f; + if (io->nttrans.level != RAW_NOTIFY_NTTRANS) { + return NT_STATUS_NOT_IMPLEMENTED; + } + SETUP_PID; - f = ntvfs_handle_get_backend_data(io->in.file.ntvfs, ntvfs); + f = ntvfs_handle_get_backend_data(io->nttrans.in.file.ntvfs, ntvfs); if (!f) return NT_STATUS_INVALID_HANDLE; - io->in.file.fnum = f->fnum; + io->nttrans.in.file.fnum = f->fnum; /* this request doesn't make sense unless its async */ if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 734df84dde..6916ea10fc 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -139,7 +139,7 @@ struct ntvfs_ops { /* change notify request */ NTSTATUS (*notify)(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - struct smb_notify *info); + union smb_notify *info); /* cancel - cancels any pending async request */ NTSTATUS (*cancel)(struct ntvfs_module_context *ntvfs, diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index 67cbe8df22..fc8fccca33 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -313,7 +313,7 @@ _PUBLIC_ NTSTATUS ntvfs_exit(struct ntvfs_request *req) /* change notify request */ -_PUBLIC_ NTSTATUS ntvfs_notify(struct ntvfs_request *req, struct smb_notify *info) +_PUBLIC_ NTSTATUS ntvfs_notify(struct ntvfs_request *req, union smb_notify *info) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->notify) { @@ -617,7 +617,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_trans2(struct ntvfs_module_context *ntvfs, */ _PUBLIC_ NTSTATUS ntvfs_next_notify(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - struct smb_notify *info) + union smb_notify *info) { if (!ntvfs->next || !ntvfs->next->ops->notify) { return NT_STATUS_NOT_IMPLEMENTED; diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c index 64aeac0696..ffbe1f8bb7 100644 --- a/source4/ntvfs/posix/pvfs_notify.c +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -40,7 +40,7 @@ struct pvfs_notify_buffer { struct notify_pending { struct notify_pending *next, *prev; struct ntvfs_request *req; - struct smb_notify *info; + union smb_notify *info; } *pending; }; @@ -64,7 +64,7 @@ static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer, { struct notify_pending *pending = notify_buffer->pending; struct ntvfs_request *req; - struct smb_notify *info; + union smb_notify *info; if (notify_buffer->current_buffer_size > notify_buffer->max_buffer_size && notify_buffer->num_changes != 0) { @@ -87,15 +87,15 @@ static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer, req = pending->req; info = pending->info; - info->out.num_changes = notify_buffer->num_changes; - info->out.changes = talloc_steal(req, notify_buffer->changes); + info->nttrans.out.num_changes = notify_buffer->num_changes; + info->nttrans.out.changes = talloc_steal(req, notify_buffer->changes); notify_buffer->num_changes = 0; notify_buffer->changes = NULL; notify_buffer->current_buffer_size = 0; talloc_free(pending); - if (info->out.num_changes != 0) { + if (info->nttrans.out.num_changes != 0) { status = NT_STATUS_OK; } @@ -219,7 +219,7 @@ static void pvfs_notify_end(void *private, enum pvfs_wait_notice reason) event buffer is non-empty */ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - struct smb_notify *info) + union smb_notify *info) { struct pvfs_state *pvfs = talloc_get_type(ntvfs->private_data, struct pvfs_state); @@ -227,7 +227,11 @@ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs, NTSTATUS status; struct notify_pending *pending; - f = pvfs_find_fd(pvfs, req, info->in.file.ntvfs); + if (info->nttrans.level != RAW_NOTIFY_NTTRANS) { + return NT_STATUS_NOT_IMPLEMENTED; + } + + f = pvfs_find_fd(pvfs, req, info->nttrans.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } @@ -246,15 +250,15 @@ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs, create one */ if (f->notify_buffer == NULL) { status = pvfs_notify_setup(pvfs, f, - info->in.buffer_size, - info->in.completion_filter, - info->in.recursive); + info->nttrans.in.buffer_size, + info->nttrans.in.completion_filter, + info->nttrans.in.recursive); NT_STATUS_NOT_OK_RETURN(status); } /* we update the max_buffer_size on each call, but we do not update the recursive flag or filter */ - f->notify_buffer->max_buffer_size = info->in.buffer_size; + f->notify_buffer->max_buffer_size = info->nttrans.in.buffer_size; pending = talloc(f->notify_buffer, struct notify_pending); NT_STATUS_HAVE_NO_MEMORY(pending); diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index b12339b2c8..17fdb42de0 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -520,7 +520,7 @@ static NTSTATUS unixuid_cancel(struct ntvfs_module_context *ntvfs, change notify */ static NTSTATUS unixuid_notify(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_notify *info) + struct ntvfs_request *req, union smb_notify *info) { NTSTATUS status; diff --git a/source4/smb_server/smb/nttrans.c b/source4/smb_server/smb/nttrans.c index 3bc0ab69b2..fce4fdc129 100644 --- a/source4/smb_server/smb/nttrans.c +++ b/source4/smb_server/smb/nttrans.c @@ -345,7 +345,7 @@ static NTSTATUS nttrans_ioctl(struct smbsrv_request *req, */ static NTSTATUS nttrans_notify_change_send(struct nttrans_op *op) { - struct smb_notify *info = talloc_get_type(op->op_info, struct smb_notify); + union smb_notify *info = talloc_get_type(op->op_info, union smb_notify); size_t size = 0; int i; NTSTATUS status; @@ -353,8 +353,8 @@ static NTSTATUS nttrans_notify_change_send(struct nttrans_op *op) #define MAX_BYTES_PER_CHAR 3 /* work out how big the reply buffer could be */ - for (i=0;iout.num_changes;i++) { - size += 12 + 3 + (1+strlen(info->out.changes[i].name.s)) * MAX_BYTES_PER_CHAR; + for (i=0;inttrans.out.num_changes;i++) { + size += 12 + 3 + (1+strlen(info->nttrans.out.changes[i].name.s)) * MAX_BYTES_PER_CHAR; } status = nttrans_setup_reply(op, op->trans, size, 0, 0); @@ -362,16 +362,16 @@ static NTSTATUS nttrans_notify_change_send(struct nttrans_op *op) p = op->trans->out.params.data; /* construct the changes buffer */ - for (i=0;iout.num_changes;i++) { + for (i=0;inttrans.out.num_changes;i++) { uint32_t ofs; ssize_t len; - SIVAL(p, 4, info->out.changes[i].action); - len = push_string(p + 12, info->out.changes[i].name.s, + SIVAL(p, 4, info->nttrans.out.changes[i].action); + len = push_string(p + 12, info->nttrans.out.changes[i].name.s, op->trans->out.params.length - (p+12 - op->trans->out.params.data), STR_UNICODE); SIVAL(p, 8, len); - + ofs = len + 12; if (ofs & 3) { @@ -380,7 +380,7 @@ static NTSTATUS nttrans_notify_change_send(struct nttrans_op *op) ofs += pad; } - if (i == info->out.num_changes-1) { + if (i == info->nttrans.out.num_changes-1) { SIVAL(p, 0, 0); } else { SIVAL(p, 0, ofs); @@ -401,25 +401,26 @@ static NTSTATUS nttrans_notify_change(struct smbsrv_request *req, struct nttrans_op *op) { struct smb_nttrans *trans = op->trans; - struct smb_notify *info; + union smb_notify *info; /* should have at least 4 setup words */ if (trans->in.setup_count != 4) { return NT_STATUS_INVALID_PARAMETER; } - info = talloc(op, struct smb_notify); + info = talloc(op, union smb_notify); NT_STATUS_HAVE_NO_MEMORY(info); - info->in.completion_filter = IVAL(trans->in.setup, 0); - info->in.file.ntvfs = smbsrv_pull_fnum(req, (uint8_t *)trans->in.setup, 4); - info->in.recursive = SVAL(trans->in.setup, 6); - info->in.buffer_size = trans->in.max_param; + info->nttrans.level = RAW_NOTIFY_NTTRANS; + info->nttrans.in.completion_filter = IVAL(trans->in.setup, 0); + info->nttrans.in.file.ntvfs = smbsrv_pull_fnum(req, (uint8_t *)trans->in.setup, 4); + info->nttrans.in.recursive = SVAL(trans->in.setup, 6); + info->nttrans.in.buffer_size = trans->in.max_param; op->op_info = info; op->send_fn = nttrans_notify_change_send; - - SMBSRV_CHECK_FILE_HANDLE_NTSTATUS(info->in.file.ntvfs); + + SMBSRV_CHECK_FILE_HANDLE_NTSTATUS(info->nttrans.in.file.ntvfs); return ntvfs_notify(req->ntvfs, info); } diff --git a/source4/torture/gentest.c b/source4/torture/gentest.c index 0373dd452d..7ce27c7679 100644 --- a/source4/torture/gentest.c +++ b/source4/torture/gentest.c @@ -84,7 +84,7 @@ static struct { static struct { int notify_count; NTSTATUS status; - struct smb_notify notify; + union smb_notify notify; } notifies[NSERVERS][NINSTANCES]; /* info relevant to the current operation */ @@ -682,7 +682,7 @@ static struct ea_struct gen_ea_struct(void) */ static void async_notify(struct smbcli_request *req) { - struct smb_notify notify; + union smb_notify notify; NTSTATUS status; int i, j; uint16_t tid; @@ -690,13 +690,14 @@ static void async_notify(struct smbcli_request *req) tid = SVAL(req->in.hdr, HDR_TID); + notify.nttrans.level = RAW_NOTIFY_NTTRANS; status = smb_raw_changenotify_recv(req, current_op.mem_ctx, ¬ify); if (NT_STATUS_IS_OK(status)) { printf("notify tid=%d num_changes=%d action=%d name=%s\n", tid, - notify.out.num_changes, - notify.out.changes[0].action, - notify.out.changes[0].name.s); + notify.nttrans.out.num_changes, + notify.nttrans.out.changes[0].action, + notify.nttrans.out.changes[0].name.s); } for (i=0;itree, ¬ify); status = smb_raw_changenotify_recv(req, mem_ctx, ¬ify); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_VAL(notify.out.num_changes, 4); - CHECK_VAL(notify.out.changes[0].action, NOTIFY_ACTION_ADDED); - CHECK_WSTR(notify.out.changes[0].name, "subdir-name", STR_UNICODE); - CHECK_VAL(notify.out.changes[1].action, NOTIFY_ACTION_REMOVED); - CHECK_WSTR(notify.out.changes[1].name, "subdir-name", STR_UNICODE); - CHECK_VAL(notify.out.changes[2].action, NOTIFY_ACTION_ADDED); - CHECK_WSTR(notify.out.changes[2].name, "subdir-name", STR_UNICODE); - CHECK_VAL(notify.out.changes[3].action, NOTIFY_ACTION_REMOVED); - CHECK_WSTR(notify.out.changes[3].name, "subdir-name", STR_UNICODE); + CHECK_VAL(notify.nttrans.out.num_changes, 4); + CHECK_VAL(notify.nttrans.out.changes[0].action, NOTIFY_ACTION_ADDED); + CHECK_WSTR(notify.nttrans.out.changes[0].name, "subdir-name", STR_UNICODE); + CHECK_VAL(notify.nttrans.out.changes[1].action, NOTIFY_ACTION_REMOVED); + CHECK_WSTR(notify.nttrans.out.changes[1].name, "subdir-name", STR_UNICODE); + CHECK_VAL(notify.nttrans.out.changes[2].action, NOTIFY_ACTION_ADDED); + CHECK_WSTR(notify.nttrans.out.changes[2].name, "subdir-name", STR_UNICODE); + CHECK_VAL(notify.nttrans.out.changes[3].action, NOTIFY_ACTION_REMOVED); + CHECK_WSTR(notify.nttrans.out.changes[3].name, "subdir-name", STR_UNICODE); count = torture_numops; printf("testing buffered notify on create of %d files\n", count); @@ -165,12 +166,12 @@ static BOOL test_notify_dir(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) /* (1st notify) setup a new notify on a different directory handle. This new notify won't see the events above. */ - notify.in.file.fnum = fnum2; + notify.nttrans.in.file.fnum = fnum2; req2 = smb_raw_changenotify_send(cli->tree, ¬ify); /* (2nd notify) whereas this notify will see the above buffered events, and it directly returns the buffered events */ - notify.in.file.fnum = fnum; + notify.nttrans.in.file.fnum = fnum; req = smb_raw_changenotify_send(cli->tree, ¬ify); /* (1st unlink) as the 2nd notify directly returns, @@ -184,18 +185,18 @@ static BOOL test_notify_dir(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) status = smb_raw_changenotify_recv(req, mem_ctx, ¬ify); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_VAL(notify.out.num_changes, count); - for (i=1;itree, ¬ify); @@ -208,32 +209,32 @@ static BOOL test_notify_dir(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) /* receive the 3rd notify */ status = smb_raw_changenotify_recv(req, mem_ctx, ¬ify); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_VAL(notify.out.num_changes, 1); - CHECK_VAL(notify.out.changes[0].action, NOTIFY_ACTION_REMOVED); - CHECK_WSTR(notify.out.changes[0].name, "test0.txt", STR_UNICODE); + CHECK_VAL(notify.nttrans.out.num_changes, 1); + CHECK_VAL(notify.nttrans.out.changes[0].action, NOTIFY_ACTION_REMOVED); + CHECK_WSTR(notify.nttrans.out.changes[0].name, "test0.txt", STR_UNICODE); /* and we now see the rest of the unlink calls on both directory handles */ - notify.in.file.fnum = fnum; + notify.nttrans.in.file.fnum = fnum; sleep(1); req = smb_raw_changenotify_send(cli->tree, ¬ify); status = smb_raw_changenotify_recv(req, mem_ctx, ¬ify); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_VAL(notify.out.num_changes, count-1); - for (i=0;itree, ¬ify); status = smb_raw_changenotify_recv(req, mem_ctx, ¬ify); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_VAL(notify.out.num_changes, count-1); - for (i=0;itree, ¬ify); cl.close.level = RAW_CLOSE_CLOSE; @@ -244,7 +245,7 @@ static BOOL test_notify_dir(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) status = smb_raw_changenotify_recv(req, mem_ctx, ¬ify); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_VAL(notify.out.num_changes, 0); + CHECK_VAL(notify.nttrans.out.num_changes, 0); done: smb_raw_exit(cli->session); @@ -259,7 +260,7 @@ static BOOL test_notify_recursive(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) { BOOL ret = True; NTSTATUS status; - struct smb_notify notify; + union smb_notify notify; union smb_open io; int fnum; struct smbcli_request *req1, *req2; @@ -288,14 +289,15 @@ static BOOL test_notify_recursive(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) /* ask for a change notify, on file or directory name changes. Setup both with and without recursion */ - notify.in.buffer_size = 1000; - notify.in.completion_filter = FILE_NOTIFY_CHANGE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_CREATION; - notify.in.file.fnum = fnum; + notify.nttrans.level = RAW_NOTIFY_NTTRANS; + notify.nttrans.in.buffer_size = 1000; + notify.nttrans.in.completion_filter = FILE_NOTIFY_CHANGE_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_CREATION; + notify.nttrans.in.file.fnum = fnum; - notify.in.recursive = True; + notify.nttrans.in.recursive = True; req1 = smb_raw_changenotify_send(cli->tree, ¬ify); - notify.in.recursive = False; + notify.nttrans.in.recursive = False; req2 = smb_raw_changenotify_send(cli->tree, ¬ify); /* cancel initial requests so the buffer is setup */ @@ -315,8 +317,8 @@ static BOOL test_notify_recursive(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) smbcli_rename(cli->tree, BASEDIR "\\subdir-name\\subname2", BASEDIR "\\subname2-r"); smbcli_rename(cli->tree, BASEDIR "\\subname2-r", BASEDIR "\\subname3-r"); - notify.in.completion_filter = 0; - notify.in.recursive = True; + notify.nttrans.in.completion_filter = 0; + notify.nttrans.in.recursive = True; msleep(10); req1 = smb_raw_changenotify_send(cli->tree, ¬ify); @@ -324,57 +326,57 @@ static BOOL test_notify_recursive(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) smbcli_rmdir(cli->tree, BASEDIR "\\subdir-name"); smbcli_unlink(cli->tree, BASEDIR "\\subname3-r"); - notify.in.recursive = False; + notify.nttrans.in.recursive = False; req2 = smb_raw_changenotify_send(cli->tree, ¬ify); status = smb_raw_changenotify_recv(req1, mem_ctx, ¬ify); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_VAL(notify.out.num_changes, 11); - CHECK_VAL(notify.out.changes[0].action, NOTIFY_ACTION_ADDED); - CHECK_WSTR(notify.out.changes[0].name, "subdir-name", STR_UNICODE); - CHECK_VAL(notify.out.changes[1].action, NOTIFY_ACTION_ADDED); - CHECK_WSTR(notify.out.changes[1].name, "subdir-name\\subname1", STR_UNICODE); - CHECK_VAL(notify.out.changes[2].action, NOTIFY_ACTION_ADDED); - CHECK_WSTR(notify.out.changes[2].name, "subdir-name\\subname2", STR_UNICODE); - CHECK_VAL(notify.out.changes[3].action, NOTIFY_ACTION_OLD_NAME); - CHECK_WSTR(notify.out.changes[3].name, "subdir-name\\subname1", STR_UNICODE); - CHECK_VAL(notify.out.changes[4].action, NOTIFY_ACTION_NEW_NAME); - CHECK_WSTR(notify.out.changes[4].name, "subdir-name\\subname1-r", STR_UNICODE); + CHECK_VAL(notify.nttrans.out.num_changes, 11); + CHECK_VAL(notify.nttrans.out.changes[0].action, NOTIFY_ACTION_ADDED); + CHECK_WSTR(notify.nttrans.out.changes[0].name, "subdir-name", STR_UNICODE); + CHECK_VAL(notify.nttrans.out.changes[1].action, NOTIFY_ACTION_ADDED); + CHECK_WSTR(notify.nttrans.out.changes[1].name, "subdir-name\\subname1", STR_UNICODE); + CHECK_VAL(notify.nttrans.out.changes[2].action, NOTIFY_ACTION_ADDED); + CHECK_WSTR(notify.nttrans.out.changes[2].name, "subdir-name\\subname2", STR_UNICODE); + CHECK_VAL(notify.nttrans.out.changes[3].action, NOTIFY_ACTION_OLD_NAME); + CHECK_WSTR(notify.nttrans.out.changes[3].name, "subdir-name\\subname1", STR_UNICODE); + CHECK_VAL(notify.nttrans.out.changes[4].action, NOTIFY_ACTION_NEW_NAME); + CHECK_WSTR(notify.nttrans.out.changes[4].name, "subdir-name\\subname1-r", STR_UNICODE); /* the remove/add between directories is acceptable in either order */ - if (notify.out.changes[5].action == NOTIFY_ACTION_ADDED) { - CHECK_VAL(notify.out.changes[6].action, NOTIFY_ACTION_REMOVED); - CHECK_WSTR(notify.out.changes[6].name, "subdir-name\\subname2", STR_UNICODE); - CHECK_VAL(notify.out.changes[5].action, NOTIFY_ACTION_ADDED); - CHECK_WSTR(notify.out.changes[5].name, "subname2-r", STR_UNICODE); + if (notify.nttrans.out.changes[5].action == NOTIFY_ACTION_ADDED) { + CHECK_VAL(notify.nttrans.out.changes[6].action, NOTIFY_ACTION_REMOVED); + CHECK_WSTR(notify.nttrans.out.changes[6].name, "subdir-name\\subname2", STR_UNICODE); + CHECK_VAL(notify.nttrans.out.changes[5].action, NOTIFY_ACTION_ADDED); + CHECK_WSTR(notify.nttrans.out.changes[5].name, "subname2-r", STR_UNICODE); } else { - CHECK_VAL(notify.out.changes[5].action, NOTIFY_ACTION_REMOVED); - CHECK_WSTR(notify.out.changes[5].name, "subdir-name\\subname2", STR_UNICODE); - CHECK_VAL(notify.out.changes[6].action, NOTIFY_ACTION_ADDED); - CHECK_WSTR(notify.out.changes[6].name, "subname2-r", STR_UNICODE); + CHECK_VAL(notify.nttrans.out.changes[5].action, NOTIFY_ACTION_REMOVED); + CHECK_WSTR(notify.nttrans.out.changes[5].name, "subdir-name\\subname2", STR_UNICODE); + CHECK_VAL(notify.nttrans.out.changes[6].action, NOTIFY_ACTION_ADDED); + CHECK_WSTR(notify.nttrans.out.changes[6].name, "subname2-r", STR_UNICODE); } - CHECK_VAL(notify.out.changes[7].action, NOTIFY_ACTION_MODIFIED); - CHECK_WSTR(notify.out.changes[7].name, "subname2-r", STR_UNICODE); + CHECK_VAL(notify.nttrans.out.changes[7].action, NOTIFY_ACTION_MODIFIED); + CHECK_WSTR(notify.nttrans.out.changes[7].name, "subname2-r", STR_UNICODE); - CHECK_VAL(notify.out.changes[8].action, NOTIFY_ACTION_OLD_NAME); - CHECK_WSTR(notify.out.changes[8].name, "subname2-r", STR_UNICODE); - CHECK_VAL(notify.out.changes[9].action, NOTIFY_ACTION_NEW_NAME); - CHECK_WSTR(notify.out.changes[9].name, "subname3-r", STR_UNICODE); - CHECK_VAL(notify.out.changes[10].action, NOTIFY_ACTION_MODIFIED); - CHECK_WSTR(notify.out.changes[10].name, "subname3-r", STR_UNICODE); + CHECK_VAL(notify.nttrans.out.changes[8].action, NOTIFY_ACTION_OLD_NAME); + CHECK_WSTR(notify.nttrans.out.changes[8].name, "subname2-r", STR_UNICODE); + CHECK_VAL(notify.nttrans.out.changes[9].action, NOTIFY_ACTION_NEW_NAME); + CHECK_WSTR(notify.nttrans.out.changes[9].name, "subname3-r", STR_UNICODE); + CHECK_VAL(notify.nttrans.out.changes[10].action, NOTIFY_ACTION_MODIFIED); + CHECK_WSTR(notify.nttrans.out.changes[10].name, "subname3-r", STR_UNICODE); status = smb_raw_changenotify_recv(req2, mem_ctx, ¬ify); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_VAL(notify.out.num_changes, 3); - CHECK_VAL(notify.out.changes[0].action, NOTIFY_ACTION_REMOVED); - CHECK_WSTR(notify.out.changes[0].name, "subdir-name\\subname1-r", STR_UNICODE); - CHECK_VAL(notify.out.changes[1].action, NOTIFY_ACTION_REMOVED); - CHECK_WSTR(notify.out.changes[1].name, "subdir-name", STR_UNICODE); - CHECK_VAL(notify.out.changes[2].action, NOTIFY_ACTION_REMOVED); - CHECK_WSTR(notify.out.changes[2].name, "subname3-r", STR_UNICODE); + CHECK_VAL(notify.nttrans.out.num_changes, 3); + CHECK_VAL(notify.nttrans.out.changes[0].action, NOTIFY_ACTION_REMOVED); + CHECK_WSTR(notify.nttrans.out.changes[0].name, "subdir-name\\subname1-r", STR_UNICODE); + CHECK_VAL(notify.nttrans.out.changes[1].action, NOTIFY_ACTION_REMOVED); + CHECK_WSTR(notify.nttrans.out.changes[1].name, "subdir-name", STR_UNICODE); + CHECK_VAL(notify.nttrans.out.changes[2].action, NOTIFY_ACTION_REMOVED); + CHECK_WSTR(notify.nttrans.out.changes[2].name, "subname3-r", STR_UNICODE); done: smb_raw_exit(cli->session); @@ -389,7 +391,7 @@ static BOOL test_notify_mask(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) { BOOL ret = True; NTSTATUS status; - struct smb_notify notify; + union smb_notify notify; union smb_open io; int fnum, fnum2; uint32_t mask; @@ -419,8 +421,9 @@ static BOOL test_notify_mask(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) io.ntcreatex.in.security_flags = 0; io.ntcreatex.in.fname = BASEDIR; - notify.in.buffer_size = 1000; - notify.in.recursive = True; + notify.nttrans.level = RAW_NOTIFY_NTTRANS; + notify.nttrans.in.buffer_size = 1000; + notify.nttrans.in.recursive = True; #define NOTIFY_MASK_TEST(setup, op, cleanup, Action, expected, nchanges) \ do { for (mask=i=0;i<32;i++) { \ @@ -429,8 +432,8 @@ static BOOL test_notify_mask(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) CHECK_STATUS(status, NT_STATUS_OK); \ fnum = io.ntcreatex.out.file.fnum; \ setup \ - notify.in.file.fnum = fnum; \ - notify.in.completion_filter = (1<tree, ¬ify); \ op \ msleep(10); smb_raw_ntcancel(req); \ @@ -440,18 +443,18 @@ static BOOL test_notify_mask(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) if (NT_STATUS_EQUAL(status, NT_STATUS_CANCELLED)) continue; \ CHECK_STATUS(status, NT_STATUS_OK); \ /* special case to cope with file rename behaviour */ \ - if (nchanges == 2 && notify.out.num_changes == 1 && \ - notify.out.changes[0].action == NOTIFY_ACTION_MODIFIED && \ + if (nchanges == 2 && notify.nttrans.out.num_changes == 1 && \ + notify.nttrans.out.changes[0].action == NOTIFY_ACTION_MODIFIED && \ ((expected) & FILE_NOTIFY_CHANGE_ATTRIBUTES) && \ Action == NOTIFY_ACTION_OLD_NAME) { \ printf("(rename file special handling OK)\n"); \ - } else if (nchanges != notify.out.num_changes || \ - notify.out.changes[0].action != Action || \ - strcmp(notify.out.changes[0].name.s, "tname1") != 0) { \ + } else if (nchanges != notify.nttrans.out.num_changes || \ + notify.nttrans.out.changes[0].action != Action || \ + strcmp(notify.nttrans.out.changes[0].name.s, "tname1") != 0) { \ printf("ERROR: nchanges=%d action=%d filter=0x%08x\n", \ - notify.out.num_changes, \ - notify.out.changes[0].action, \ - notify.in.completion_filter); \ + notify.nttrans.out.num_changes, \ + notify.nttrans.out.changes[0].action, \ + notify.nttrans.in.completion_filter); \ ret = False; \ } \ mask |= (1<tree, ¬ify); @@ -704,7 +709,7 @@ static BOOL test_notify_tdis(TALLOC_CTX *mem_ctx) status = smb_raw_changenotify_recv(req, mem_ctx, ¬ify); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_VAL(notify.out.num_changes, 0); + CHECK_VAL(notify.nttrans.out.num_changes, 0); done: torture_close_connection(cli); @@ -718,7 +723,7 @@ static BOOL test_notify_exit(TALLOC_CTX *mem_ctx) { BOOL ret = True; NTSTATUS status; - struct smb_notify notify; + union smb_notify notify; union smb_open io; int fnum; struct smbcli_request *req; @@ -752,10 +757,11 @@ static BOOL test_notify_exit(TALLOC_CTX *mem_ctx) /* ask for a change notify, on file or directory name changes */ - notify.in.buffer_size = 1000; - notify.in.completion_filter = FILE_NOTIFY_CHANGE_NAME; - notify.in.file.fnum = fnum; - notify.in.recursive = True; + notify.nttrans.level = RAW_NOTIFY_NTTRANS; + notify.nttrans.in.buffer_size = 1000; + notify.nttrans.in.completion_filter = FILE_NOTIFY_CHANGE_NAME; + notify.nttrans.in.file.fnum = fnum; + notify.nttrans.in.recursive = True; req = smb_raw_changenotify_send(cli->tree, ¬ify); @@ -764,7 +770,7 @@ static BOOL test_notify_exit(TALLOC_CTX *mem_ctx) status = smb_raw_changenotify_recv(req, mem_ctx, ¬ify); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_VAL(notify.out.num_changes, 0); + CHECK_VAL(notify.nttrans.out.num_changes, 0); done: torture_close_connection(cli); @@ -778,7 +784,7 @@ static BOOL test_notify_ulogoff(TALLOC_CTX *mem_ctx) { BOOL ret = True; NTSTATUS status; - struct smb_notify notify; + union smb_notify notify; union smb_open io; int fnum; struct smbcli_request *req; @@ -812,10 +818,11 @@ static BOOL test_notify_ulogoff(TALLOC_CTX *mem_ctx) /* ask for a change notify, on file or directory name changes */ - notify.in.buffer_size = 1000; - notify.in.completion_filter = FILE_NOTIFY_CHANGE_NAME; - notify.in.file.fnum = fnum; - notify.in.recursive = True; + notify.nttrans.level = RAW_NOTIFY_NTTRANS; + notify.nttrans.in.buffer_size = 1000; + notify.nttrans.in.completion_filter = FILE_NOTIFY_CHANGE_NAME; + notify.nttrans.in.file.fnum = fnum; + notify.nttrans.in.recursive = True; req = smb_raw_changenotify_send(cli->tree, ¬ify); @@ -824,7 +831,7 @@ static BOOL test_notify_ulogoff(TALLOC_CTX *mem_ctx) status = smb_raw_changenotify_recv(req, mem_ctx, ¬ify); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_VAL(notify.out.num_changes, 0); + CHECK_VAL(notify.nttrans.out.num_changes, 0); done: torture_close_connection(cli); @@ -839,7 +846,7 @@ static BOOL test_notify_double(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) { BOOL ret = True; NTSTATUS status; - struct smb_notify notify; + union smb_notify notify; union smb_open io; int fnum; struct smbcli_request *req1, *req2; @@ -868,10 +875,11 @@ static BOOL test_notify_double(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) /* ask for a change notify, on file or directory name changes */ - notify.in.buffer_size = 1000; - notify.in.completion_filter = FILE_NOTIFY_CHANGE_NAME; - notify.in.file.fnum = fnum; - notify.in.recursive = True; + notify.nttrans.level = RAW_NOTIFY_NTTRANS; + notify.nttrans.in.buffer_size = 1000; + notify.nttrans.in.completion_filter = FILE_NOTIFY_CHANGE_NAME; + notify.nttrans.in.file.fnum = fnum; + notify.nttrans.in.recursive = True; req1 = smb_raw_changenotify_send(cli->tree, ¬ify); req2 = smb_raw_changenotify_send(cli->tree, ¬ify); @@ -880,15 +888,15 @@ static BOOL test_notify_double(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) status = smb_raw_changenotify_recv(req1, mem_ctx, ¬ify); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_VAL(notify.out.num_changes, 1); - CHECK_WSTR(notify.out.changes[0].name, "subdir-name", STR_UNICODE); + CHECK_VAL(notify.nttrans.out.num_changes, 1); + CHECK_WSTR(notify.nttrans.out.changes[0].name, "subdir-name", STR_UNICODE); smbcli_mkdir(cli->tree, BASEDIR "\\subdir-name2"); status = smb_raw_changenotify_recv(req2, mem_ctx, ¬ify); CHECK_STATUS(status, NT_STATUS_OK); - CHECK_VAL(notify.out.num_changes, 1); - CHECK_WSTR(notify.out.changes[0].name, "subdir-name2", STR_UNICODE); + CHECK_VAL(notify.nttrans.out.num_changes, 1); + CHECK_WSTR(notify.nttrans.out.changes[0].name, "subdir-name2", STR_UNICODE); done: smb_raw_exit(cli->session); @@ -902,7 +910,7 @@ done: static BOOL test_notify_tree(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) { BOOL ret = True; - struct smb_notify notify; + union smb_notify notify; union smb_open io; struct smbcli_request *req; struct { @@ -950,7 +958,8 @@ static BOOL test_notify_tree(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS; io.ntcreatex.in.security_flags = 0; - notify.in.buffer_size = 20000; + notify.nttrans.level = RAW_NOTIFY_NTTRANS; + notify.nttrans.in.buffer_size = 20000; /* setup the directory tree, and the notify buffer on each directory @@ -961,9 +970,9 @@ static BOOL test_notify_tree(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) CHECK_STATUS(status, NT_STATUS_OK); dirs[i].fnum = io.ntcreatex.out.file.fnum; - notify.in.completion_filter = dirs[i].filter; - notify.in.file.fnum = dirs[i].fnum; - notify.in.recursive = dirs[i].recursive; + notify.nttrans.in.completion_filter = dirs[i].filter; + notify.nttrans.in.file.fnum = dirs[i].fnum; + notify.nttrans.in.recursive = dirs[i].recursive; req = smb_raw_changenotify_send(cli->tree, ¬ify); smb_raw_ntcancel(req); status = smb_raw_changenotify_recv(req, mem_ctx, ¬ify); @@ -983,14 +992,14 @@ static BOOL test_notify_tree(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) /* count events that have happened in each dir */ for (i=0;itree, ¬ify); smb_raw_ntcancel(req); - notify.out.num_changes = 0; + notify.nttrans.out.num_changes = 0; status = smb_raw_changenotify_recv(req, mem_ctx, ¬ify); - if (notify.out.num_changes != dirs[i].expected) { + if (notify.nttrans.out.num_changes != dirs[i].expected) { printf("ERROR: i=%d expected %d got %d for '%s'\n", - i, dirs[i].expected, notify.out.num_changes, + i, dirs[i].expected, notify.nttrans.out.num_changes, dirs[i].path); ret = False; } -- cgit