r16980: - make struct smb_notify a union and add levels RAW_NOTIFY_NTTRANS,RAW_NOTIFY...
authorStefan Metzmacher <metze@samba.org>
Wed, 12 Jul 2006 14:25:50 +0000 (14:25 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:10:06 +0000 (14:10 -0500)
- parse SMB2 Notify reponse

metze
(This used to be commit de50e0ccddfad16ad7b254770f4c52c1abe707b9)

12 files changed:
source4/libcli/raw/interfaces.h
source4/libcli/raw/rawnotify.c
source4/libcli/smb2/notify.c
source4/libcli/smb2/smb2_calls.h
source4/ntvfs/cifs/vfs_cifs.c
source4/ntvfs/ntvfs.h
source4/ntvfs/ntvfs_interface.c
source4/ntvfs/posix/pvfs_notify.c
source4/ntvfs/unixuid/vfs_unixuid.c
source4/smb_server/smb/nttrans.c
source4/torture/gentest.c
source4/torture/raw/notify.c

index 8ebdd38beebd632d9079dae4f7ae5169e4605a6f..d3e7611c758aa2e89e3bad7c8aa65c3e9b127f24 100644 (file)
@@ -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 {
index f4d416401612a88fd6c40c666476b6d443d3f7cf..2b68d96a1bed8fc00aadd8d6f53f3cab2288d382 100644 (file)
 /****************************************************************************
 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; i<parms->out.num_changes; i++) {
-               parms->out.changes[i].action = IVAL(nt.out.params.data, ofs+4);
+       for (i=ofs=0; i<parms->nttrans.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);
        }
 
index 0e6129349523512eae4f10787bdc8ad152dc1145..43792267f29910a7a67de78856388af9b3b42a9f 100644 (file)
@@ -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; i<io->out.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);
 }
 
index c3dc6294300d0dd78465aef36fb823a6252c9b32..abb7f88ee20e1747207dd449768df2144a8c002f 100644 (file)
@@ -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"
index 41ea2a652d2bd7b4dbec6b25f80c8612b8eb8d44..1e34e953a5216ca3a0d847355161d02ee891ce00 100644 (file)
@@ -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)) {
index 734df84ddeabc9dd0060fd56689b796c5d194e84..6916ea10fc0f5c1c16e64bd7a1c33c74bb2cca55 100644 (file)
@@ -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,
index 67cbe8df22c6f3e1e2525cae7f043be87f8a3082..fc8fccca3314b79a5830f305bc145c7b659a642c 100644 (file)
@@ -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;
index 64aeac0696adea64754ed02489f4cc37c02d2307..ffbe1f8bb7735781a4e745aa4353ffbce12b9bd1 100644 (file)
@@ -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);
index b12339b2c871fe429d94222f747a5980bfc83586..17fdb42de03a1fec6e0af65a6d6d521ef593581a 100644 (file)
@@ -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;
 
index 3bc0ab69b299b74e7c17600138c7072cbb0c801d..fce4fdc1293a5a1e32254347953495da3d3c6164 100644 (file)
@@ -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;i<info->out.num_changes;i++) {
-               size += 12 + 3 + (1+strlen(info->out.changes[i].name.s)) * MAX_BYTES_PER_CHAR;
+       for (i=0;i<info->nttrans.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;i<info->out.num_changes;i++) {
+       for (i=0;i<info->nttrans.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);
 }
 
index 0373dd452d5e1430ba3488eae36a036cf16fd183..7ce27c7679d17662feb2619665d1ab9b84b366f8 100644 (file)
@@ -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, &notify);
        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;i<NSERVERS;i++) {
@@ -892,7 +893,7 @@ again:
        for (j=0;j<NINSTANCES;j++) {
                for (i=1;i<NSERVERS;i++) {
                        int n;
-                       struct smb_notify not1, not2;
+                       union smb_notify not1, not2;
 
                        if (notifies[0][j].notify_count != notifies[i][j].notify_count) {
                                if (tries++ < 10) goto again;
@@ -919,26 +920,26 @@ again:
                        not1 = notifies[0][j].notify;
                        not2 = notifies[i][j].notify;
 
-                       for (n=0;n<not1.out.num_changes;n++) {
-                               if (not1.out.changes[n].action != 
-                                   not2.out.changes[n].action) {
+                       for (n=0;n<not1.nttrans.out.num_changes;n++) {
+                               if (not1.nttrans.out.changes[n].action != 
+                                   not2.nttrans.out.changes[n].action) {
                                        printf("Notify action %d inconsistent %d %d\n", n,
-                                              not1.out.changes[n].action,
-                                              not2.out.changes[n].action);
+                                              not1.nttrans.out.changes[n].action,
+                                              not2.nttrans.out.changes[n].action);
                                        return False;
                                }
-                               if (strcmp(not1.out.changes[n].name.s,
-                                          not2.out.changes[n].name.s)) {
+                               if (strcmp(not1.nttrans.out.changes[n].name.s,
+                                          not2.nttrans.out.changes[n].name.s)) {
                                        printf("Notify name %d inconsistent %s %s\n", n,
-                                              not1.out.changes[n].name.s,
-                                              not2.out.changes[n].name.s);
+                                              not1.nttrans.out.changes[n].name.s,
+                                              not2.nttrans.out.changes[n].name.s);
                                        return False;
                                }
-                               if (not1.out.changes[n].name.private_length !=
-                                   not2.out.changes[n].name.private_length) {
+                               if (not1.nttrans.out.changes[n].name.private_length !=
+                                   not2.nttrans.out.changes[n].name.private_length) {
                                        printf("Notify name length %d inconsistent %d %d\n", n,
-                                              not1.out.changes[n].name.private_length,
-                                              not2.out.changes[n].name.private_length);
+                                              not1.nttrans.out.changes[n].name.private_length,
+                                              not2.nttrans.out.changes[n].name.private_length);
                                        return False;
                                }
                        }
@@ -1820,17 +1821,18 @@ static BOOL handler_sfileinfo(int instance)
 */
 static BOOL handler_notify(int instance)
 {
-       struct smb_notify parm[NSERVERS];
+       union smb_notify parm[NSERVERS];
        int n;
 
        ZERO_STRUCT(parm[0]);
-       parm[0].in.buffer_size = gen_io_count();
-       parm[0].in.completion_filter = gen_bits_mask(0xFF);
-       parm[0].in.file.fnum = gen_fnum(instance);
-       parm[0].in.recursive = gen_bool();
+       parm[0].nttrans.level                   = RAW_NOTIFY_NTTRANS;
+       parm[0].nttrans.in.buffer_size          = gen_io_count();
+       parm[0].nttrans.in.completion_filter    = gen_bits_mask(0xFF);
+       parm[0].nttrans.in.file.fnum            = gen_fnum(instance);
+       parm[0].nttrans.in.recursive            = gen_bool();
 
        GEN_COPY_PARM;
-       GEN_SET_FNUM(in.file.fnum);
+       GEN_SET_FNUM(nttrans.in.file.fnum);
 
        for (n=0;n<NSERVERS;n++) {
                struct smbcli_request *req;
index 12ea8215189ec5162fa1f846b08aaf4e1cbfb76d..0f33a56ce1de30b57712a61b88299aada04ea3ad 100644 (file)
@@ -59,7 +59,7 @@ static BOOL test_notify_dir(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;
        union smb_close cl;
        int i, count, fnum, fnum2;
@@ -94,10 +94,11 @@ static BOOL test_notify_dir(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;
 
        printf("testing notify cancel\n");
 
@@ -114,9 +115,9 @@ static BOOL test_notify_dir(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        status = smb_raw_changenotify_recv(req, mem_ctx, &notify);
        CHECK_STATUS(status, NT_STATUS_OK);
 
-       CHECK_VAL(notify.out.num_changes, 1);
-       CHECK_VAL(notify.out.changes[0].action, NOTIFY_ACTION_ADDED);
-       CHECK_WSTR(notify.out.changes[0].name, "subdir-name", STR_UNICODE);
+       CHECK_VAL(notify.nttrans.out.num_changes, 1);
+       CHECK_VAL(notify.nttrans.out.changes[0].action, NOTIFY_ACTION_ADDED);
+       CHECK_WSTR(notify.nttrans.out.changes[0].name, "subdir-name", STR_UNICODE);
 
        printf("testing notify rmdir\n");
 
@@ -125,9 +126,9 @@ static BOOL test_notify_dir(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 
        status = smb_raw_changenotify_recv(req, mem_ctx, &notify);
        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, "subdir-name", 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, "subdir-name", STR_UNICODE);
 
        printf("testing notify mkdir - rmdir - mkdir - rmdir\n");
 
@@ -138,15 +139,15 @@ static BOOL test_notify_dir(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        req = smb_raw_changenotify_send(cli->tree, &notify);
        status = smb_raw_changenotify_recv(req, mem_ctx, &notify);
        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, &notify);
 
        /* (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, &notify);
 
        /* (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, &notify);
        CHECK_STATUS(status, NT_STATUS_OK);
 
-       CHECK_VAL(notify.out.num_changes, count);
-       for (i=1;i<notify.out.num_changes;i++) {
-               CHECK_VAL(notify.out.changes[i].action, NOTIFY_ACTION_ADDED);
+       CHECK_VAL(notify.nttrans.out.num_changes, count);
+       for (i=1;i<notify.nttrans.out.num_changes;i++) {
+               CHECK_VAL(notify.nttrans.out.changes[i].action, NOTIFY_ACTION_ADDED);
        }
-       CHECK_WSTR(notify.out.changes[0].name, "test0.txt", STR_UNICODE);
+       CHECK_WSTR(notify.nttrans.out.changes[0].name, "test0.txt", STR_UNICODE);
 
        /* and now from the 1st notify */
        status = smb_raw_changenotify_recv(req2, mem_ctx, &notify);
        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);
 
        /* (3rd notify) this notify will only see the 1st unlink */
        req = smb_raw_changenotify_send(cli->tree, &notify);
@@ -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, &notify);
        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, &notify);
        status = smb_raw_changenotify_recv(req, mem_ctx, &notify);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_VAL(notify.out.num_changes, count-1);
-       for (i=0;i<notify.out.num_changes;i++) {
-               CHECK_VAL(notify.out.changes[i].action, NOTIFY_ACTION_REMOVED);
+       CHECK_VAL(notify.nttrans.out.num_changes, count-1);
+       for (i=0;i<notify.nttrans.out.num_changes;i++) {
+               CHECK_VAL(notify.nttrans.out.changes[i].action, NOTIFY_ACTION_REMOVED);
        }
-       notify.in.file.fnum = fnum2;
+       notify.nttrans.in.file.fnum = fnum2;
        req = smb_raw_changenotify_send(cli->tree, &notify);
        status = smb_raw_changenotify_recv(req, mem_ctx, &notify);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_VAL(notify.out.num_changes, count-1);
-       for (i=0;i<notify.out.num_changes;i++) {
-               CHECK_VAL(notify.out.changes[i].action, NOTIFY_ACTION_REMOVED);
+       CHECK_VAL(notify.nttrans.out.num_changes, count-1);
+       for (i=0;i<notify.nttrans.out.num_changes;i++) {
+               CHECK_VAL(notify.nttrans.out.changes[i].action, NOTIFY_ACTION_REMOVED);
        }
 
        printf("testing if a close() on the dir handle triggers the notify reply\n");
 
-       notify.in.file.fnum = fnum;
+       notify.nttrans.in.file.fnum = fnum;
        req = smb_raw_changenotify_send(cli->tree, &notify);
 
        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, &notify);
        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, &notify);
 
-       notify.in.recursive = False;
+       notify.nttrans.in.recursive = False;
        req2 = smb_raw_changenotify_send(cli->tree, &notify);
 
        /* 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, &notify);
 
@@ -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, &notify);
 
        status = smb_raw_changenotify_recv(req1, mem_ctx, &notify);
        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, &notify);
        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<<i); \
+               notify.nttrans.in.file.fnum = fnum;     \
+               notify.nttrans.in.completion_filter = (1<<i); \
                req = smb_raw_changenotify_send(cli->tree, &notify); \
                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<<i); \
@@ -601,7 +604,7 @@ static BOOL test_notify_file(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        BOOL ret = True;
        union smb_open io;
        union smb_close cl;
-       struct smb_notify notify;
+       union smb_notify notify;
        struct smbcli_request *req;
        int fnum;
        const char *fname = BASEDIR "\\file.txt";
@@ -626,10 +629,11 @@ static BOOL test_notify_file(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 
        /* ask for a change notify,
           on file or directory name changes */
-       notify.in.file.fnum = fnum;
-       notify.in.buffer_size = 1000;
-       notify.in.completion_filter = FILE_NOTIFY_CHANGE_STREAM_NAME;
-       notify.in.recursive = False;
+       notify.nttrans.level = RAW_NOTIFY_NTTRANS;
+       notify.nttrans.in.file.fnum = fnum;
+       notify.nttrans.in.buffer_size = 1000;
+       notify.nttrans.in.completion_filter = FILE_NOTIFY_CHANGE_STREAM_NAME;
+       notify.nttrans.in.recursive = False;
 
        printf("testing if notifies on file handles are invalid (should be)\n");
 
@@ -658,7 +662,7 @@ static BOOL test_notify_tdis(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;
@@ -692,10 +696,11 @@ static BOOL test_notify_tdis(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, &notify);
 
@@ -704,7 +709,7 @@ static BOOL test_notify_tdis(TALLOC_CTX *mem_ctx)
 
        status = smb_raw_changenotify_recv(req, mem_ctx, &notify);
        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, &notify);
 
@@ -764,7 +770,7 @@ static BOOL test_notify_exit(TALLOC_CTX *mem_ctx)
 
        status = smb_raw_changenotify_recv(req, mem_ctx, &notify);
        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, &notify);
 
@@ -824,7 +831,7 @@ static BOOL test_notify_ulogoff(TALLOC_CTX *mem_ctx)
 
        status = smb_raw_changenotify_recv(req, mem_ctx, &notify);
        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, &notify);
        req2 = smb_raw_changenotify_send(cli->tree, &notify);
@@ -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, &notify);
        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, &notify);
        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, &notify);
                smb_raw_ntcancel(req);
                status = smb_raw_changenotify_recv(req, mem_ctx, &notify);
@@ -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;i<ARRAY_SIZE(dirs);i++) {
-               notify.in.file.fnum = dirs[i].fnum;
+               notify.nttrans.in.file.fnum = dirs[i].fnum;
                req = smb_raw_changenotify_send(cli->tree, &notify);
                smb_raw_ntcancel(req);
-               notify.out.num_changes = 0;
+               notify.nttrans.out.num_changes = 0;
                status = smb_raw_changenotify_recv(req, mem_ctx, &notify);
-               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;
                }