r14541: separate smbsrv_request and ntvfs_request,
authorStefan Metzmacher <metze@samba.org>
Sat, 18 Mar 2006 11:10:21 +0000 (11:10 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:58:41 +0000 (13:58 -0500)
with this it's now possible to write a
ntvfs_test programm like the vfstest in samba3

also smb2 support will be possible later

metze

source/ntvfs/ntvfs.h
source/ntvfs/ntvfs_util.c
source/smb_server/smb/nttrans.c
source/smb_server/smb/receive.c
source/smb_server/smb/reply.c
source/smb_server/smb/request.c
source/smb_server/smb/search.c
source/smb_server/smb/service.c
source/smb_server/smb/trans2.c
source/smb_server/smb_server.h

index 09c5b9bdcb619e4b9fe3d44e5447143eabc784d2..13147d5c19ded4fb06381657a54f9a19f0f46892 100644 (file)
@@ -24,8 +24,7 @@
 #define NTVFS_INTERFACE_VERSION 0
 
 struct ntvfs_module_context;
-
-#define ntvfs_request smbsrv_request
+struct ntvfs_request;
 
 /* each backend has to be one one of the following 3 basic types. In
  * earlier versions of Samba backends needed to handle all types, now
@@ -231,6 +230,29 @@ struct ntvfs_async_state {
        struct ntvfs_module_context *ntvfs;
 };
 
+struct ntvfs_request {
+       /* the ntvfs_context this requests belongs to */
+       struct ntvfs_context *ctx;
+
+       /* ntvfs per request async states */
+       struct ntvfs_async_state *async_states;
+
+       /* the session_info, with security_token and maybe delegated credentials */
+       struct auth_session_info *session_info;
+
+       /* the smb pid is needed for locking contexts */
+       uint16_t smbpid;
+
+       /* the smb mid is needed for matching requests */
+       uint16_t smbmid;
+
+       /* some statictics for the management tools */
+       struct {
+               /* the system time when the request arrived */
+               struct timeval request_time;
+       } statistics;
+};
+
 /* this structure is used by backends to determine the size of some critical types */
 struct ntvfs_critical_sizes {
        int interface_version;
index c7b99d3d24410f63702b7ad770412ccbc0fecce4..a6d1ccd3f35f7dc78bf3b2f8f627770391cbbd7e 100644 (file)
 #include "ntvfs/ntvfs.h"
 
 
+_PUBLIC_ struct ntvfs_request *ntvfs_request_create(struct ntvfs_context *ctx, TALLOC_CTX *mem_ctx,
+                                                   struct auth_session_info *session_info,
+                                                   uint16_t smbpid, uint16_t smbmid,
+                                                   struct timeval request_time,
+                                                   void *private_data,
+                                                   void (*send_fn)(struct ntvfs_request *),
+                                                   uint32_t state)
+{
+       struct ntvfs_request *req;
+       struct ntvfs_async_state *async;
+
+       req = talloc(mem_ctx, struct ntvfs_request);
+       if (!req) return NULL;
+       req->ctx                        = ctx;
+       req->async_states               = NULL;
+       req->session_info               = session_info;
+       req->smbpid                     = smbpid;
+       req->smbmid                     = smbmid;
+       req->statistics.request_time    = request_time;
+
+       async = talloc(req, struct ntvfs_async_state);
+       if (!async) goto failed;
+
+       async->state            = state;
+       async->private_data     = private_data;
+       async->send_fn          = send_fn;
+       async->status           = NT_STATUS_INTERNAL_ERROR;
+       async->ntvfs            = NULL;
+
+       DLIST_ADD(req->async_states, async);
+
+       return req;
+
+failed:
+       return NULL;
+}
+
 _PUBLIC_ NTSTATUS ntvfs_async_state_push(struct ntvfs_module_context *ntvfs,
                                         struct ntvfs_request *req,
                                         void *private_data,
@@ -35,9 +72,7 @@ _PUBLIC_ NTSTATUS ntvfs_async_state_push(struct ntvfs_module_context *ntvfs,
        struct ntvfs_async_state *async;
 
        async = talloc(req, struct ntvfs_async_state);
-       if (!async) {
-               return NT_STATUS_NO_MEMORY;
-       }
+       NT_STATUS_HAVE_NO_MEMORY(async);
 
        async->state            = req->async_states->state;
        async->private_data     = private_data;
index 17bccd79b7f1aa29df15418863462fac46790287..4fbb1f656dd41b6bb17fb9ad50543a2b7c5faee7 100644 (file)
@@ -188,7 +188,7 @@ static NTSTATUS nttrans_create(struct smbsrv_request *req,
        op->send_fn = nttrans_create_send;
        op->op_info = io;
 
-       return ntvfs_open(req, io);
+       return ntvfs_open(req->ntvfs, io);
 }
 
 
@@ -241,7 +241,7 @@ static NTSTATUS nttrans_query_sec_desc(struct smbsrv_request *req,
        op->op_info = io;
        op->send_fn = nttrans_query_sec_desc_send;
 
-       return ntvfs_qfileinfo(req, io);
+       return ntvfs_qfileinfo(req->ntvfs, io);
 }
 
 
@@ -280,7 +280,7 @@ static NTSTATUS nttrans_set_sec_desc(struct smbsrv_request *req,
        trans->out.params      = data_blob(NULL, 0);
        trans->out.data        = data_blob(NULL, 0);
 
-       return ntvfs_setfileinfo(req, io);
+       return ntvfs_setfileinfo(req->ntvfs, io);
 }
 
 
@@ -333,7 +333,7 @@ static NTSTATUS nttrans_ioctl(struct smbsrv_request *req,
 
        trans->out.setup[0] = 0;
        
-       return ntvfs_ioctl(req, nt);
+       return ntvfs_ioctl(req->ntvfs, nt);
 }
 
 
@@ -412,7 +412,7 @@ static NTSTATUS nttrans_notify_change(struct smbsrv_request *req,
        op->op_info = info;
        op->send_fn = nttrans_notify_change_send;
        
-       return ntvfs_notify(req, info);
+       return ntvfs_notify(req->ntvfs, info);
 }
 
 /*
@@ -442,19 +442,16 @@ static NTSTATUS nttrans_backend(struct smbsrv_request *req,
 }
 
 
-static void reply_nttrans_send(struct smbsrv_request *req)
+static void reply_nttrans_send(struct ntvfs_request *ntvfs)
 {
+       struct smbsrv_request *req;
        uint16_t params_left, data_left;
        uint8_t *params, *data;
        struct smb_nttrans *trans;
        struct nttrans_op *op;
 
-       if (!NT_STATUS_IS_OK(req->async_states->status)) {
-               smbsrv_send_error(req, req->async_states->status);
-               return;
-       }
+       SMBSRV_CHECK_ASYNC_STATUS(op, struct nttrans_op);
 
-       op = talloc_get_type(req->async_states->private_data, struct nttrans_op);
        trans = op->trans;
 
        /* if this function needs work to form the nttrans reply buffer, then
@@ -575,11 +572,8 @@ void smbsrv_reply_nttrans(struct smbsrv_request *req)
                return;
        }
 
-       op = talloc(req, struct nttrans_op);
-       if (op == NULL) {
-               smbsrv_send_error(req, NT_STATUS_NO_MEMORY);
-               return;
-       }
+       SMBSRV_TALLOC_IO_PTR(op, struct nttrans_op);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_nttrans_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        trans = talloc(op, struct smb_nttrans);
        if (trans == NULL) {
@@ -631,17 +625,7 @@ void smbsrv_reply_nttrans(struct smbsrv_request *req)
                return;
        }
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_nttrans_send;
-       req->async_states->private_data = op;
-
-       /* its a full request, give it to the backend */
-       req->async_states->status = nttrans_backend(req, op);
-
-       /* if the backend replied synchronously, then send now */
-       if (!(req->async_states->state & NTVFS_ASYNC_STATE_ASYNC)) {
-               req->async_states->send_fn(req);
-       }
+       SMBSRV_CALL_NTVFS_BACKEND(nttrans_backend(req, op));
 }
 
 
index 44e385dc7333891e5d315a8881bb39b872ae0908..ec4686acfbda439fe769ef38a52e4bace6307c4e 100644 (file)
@@ -552,14 +552,6 @@ static void switch_message(int type, struct smbsrv_request *req)
                return;
        }
 
-/* TODO: remove this stuff */
-req->smbpid = SVAL(req->in.hdr, HDR_PID);
-req->smbmid = SVAL(req->in.hdr, HDR_MID);
-req->statistics.request_time = req->request_time;
-if (req->session) req->session_info = req->session->session_info;
-if (req->tcon) req->ctx = req->tcon->ntvfs;
-/* TODO: end */
-
        smb_messages[type].fn(req);
 }
 
@@ -620,9 +612,11 @@ void smbsrv_chain_reply(struct smbsrv_request *req)
        SSVAL(req->out.vwv, VWV(0), chain_cmd);
        SSVAL(req->out.vwv, VWV(1), req->out.size - NBT_HDR_SIZE);
 
-       /* the current request in the chain might have used an async reply,
-          but that doesn't mean the next element needs to */
-       ZERO_STRUCTP(req->async_states);
+       /* cleanup somestuff for the next request */
+       talloc_free(req->ntvfs);
+       req->ntvfs = NULL;
+       talloc_free(req->io_ptr);
+       req->io_ptr = NULL;
 
        switch_message(chain_cmd, req);
        return;
index 244fd37af90d907a1109d97347012cb2053359d3..65976fd38574a10e59b7cf2db410584995e12f6c 100644 (file)
 #include "librpc/gen_ndr/ndr_nbt.h"
 
 
-/* useful way of catching wct errors with file and line number */
-#define REQ_CHECK_WCT(req, wcount) do { \
-       if ((req)->in.wct != (wcount)) { \
-               DEBUG(1,("Unexpected WCT %d at %s(%d) - expected %d\n", \
-                        (req)->in.wct, __FILE__, __LINE__, wcount)); \
-               smbsrv_send_error(req, NT_STATUS_DOS(ERRSRV, ERRerror)); \
-               return; \
-       }} while (0)
-
-/* check req->async_states->status and if not OK then send an error reply */
-#define CHECK_ASYNC_STATUS do { \
-       if (!NT_STATUS_IS_OK(req->async_states->status)) { \
-               smbsrv_send_error(req, req->async_states->status); \
-               return; \
-       }} while (0)
-       
-/* useful wrapper for talloc with NO_MEMORY reply */
-#define REQ_TALLOC(ptr, type) do { \
-       ptr = talloc(req, type); \
-       if (!ptr) { \
-               smbsrv_send_error(req, NT_STATUS_NO_MEMORY); \
-               return; \
-       }} while (0)
-
-/* 
-   check if the backend wants to handle the request asynchronously.
-   if it wants it handled synchronously then call the send function
-   immediately
-*/
-#define REQ_ASYNC_TAIL do { \
-       if (!(req->async_states->state & NTVFS_ASYNC_STATE_ASYNC)) { \
-               req->async_states->send_fn(req); \
-       }} while (0)
-
-/* zero out some reserved fields in a reply */
-#define REQ_VWV_RESERVED(start, count) memset(req->out.vwv + VWV(start), 0, (count)*2)
-
 /****************************************************************************
  Reply to a simple request (async send)
 ****************************************************************************/
-static void reply_simple_send(struct smbsrv_request *req)
+static void reply_simple_send(struct ntvfs_request *ntvfs)
 {
-       CHECK_ASYNC_STATUS;
+       struct smbsrv_request *req;
+
+       SMBSRV_CHECK_ASYNC_STATUS_SIMPLE;
 
        smbsrv_setup_reply(req, 0, 0);
        smbsrv_send_reply(req);
@@ -88,7 +53,7 @@ void smbsrv_reply_tcon(struct smbsrv_request *req)
        uint8_t *p;
        
        /* parse request */
-       REQ_CHECK_WCT(req, 0);
+       SMBSRV_CHECK_WCT(req, 0);
 
        con.tcon.level = RAW_TCON_TCON;
 
@@ -134,7 +99,7 @@ void smbsrv_reply_tcon_and_X(struct smbsrv_request *req)
        con.tconx.level = RAW_TCON_TCONX;
 
        /* parse request */
-       REQ_CHECK_WCT(req, 4);
+       SMBSRV_CHECK_WCT(req, 4);
 
        con.tconx.in.flags  = SVAL(req->in.vwv, VWV(2));
        passlen             = SVAL(req->in.vwv, VWV(3));
@@ -208,11 +173,12 @@ void smbsrv_reply_unknown(struct smbsrv_request *req)
 /****************************************************************************
  Reply to an ioctl (async reply)
 ****************************************************************************/
-static void reply_ioctl_send(struct smbsrv_request *req)
+static void reply_ioctl_send(struct ntvfs_request *ntvfs)
 {
-       union smb_ioctl *io = req->async_states->private_data;
+       struct smbsrv_request *req;
+       union smb_ioctl *io;
 
-       CHECK_ASYNC_STATUS;
+       SMBSRV_CHECK_ASYNC_STATUS(io, union smb_ioctl);
 
        /* the +1 is for nicer alignment */
        smbsrv_setup_reply(req, 8, io->ioctl.out.blob.length+1);
@@ -233,21 +199,16 @@ void smbsrv_reply_ioctl(struct smbsrv_request *req)
        union smb_ioctl *io;
 
        /* parse request */
-       REQ_CHECK_WCT(req, 3);
-       REQ_TALLOC(io, union smb_ioctl);
+       SMBSRV_CHECK_WCT(req, 3);
+       SMBSRV_TALLOC_IO_PTR(io, union smb_ioctl);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_ioctl_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        io->ioctl.level         = RAW_IOCTL_IOCTL;
        io->ioctl.in.file.fnum  = req_fnum(req, req->in.vwv, VWV(0));
        io->ioctl.in.request    = IVAL(req->in.vwv, VWV(1));
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_ioctl_send;
-       req->async_states->private_data = io;
-
        /* call backend */
-       req->async_states->status = ntvfs_ioctl(req, io);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_ioctl(req->ntvfs, io));
 }
 
 
@@ -258,27 +219,24 @@ void smbsrv_reply_chkpth(struct smbsrv_request *req)
 {
        union smb_chkpath *io;
 
-       REQ_TALLOC(io, union smb_chkpath);
+       SMBSRV_TALLOC_IO_PTR(io, union smb_chkpath);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        req_pull_ascii4(req, &io->chkpath.in.path, req->in.data, STR_TERMINATE);
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_simple_send;
-
-       req->async_states->status = ntvfs_chkpath(req, io);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_chkpath(req->ntvfs, io));
 }
 
 /****************************************************************************
  Reply to a getatr (async reply)
 ****************************************************************************/
-static void reply_getatr_send(struct smbsrv_request *req)
+static void reply_getatr_send(struct ntvfs_request *ntvfs)
 {
-       union smb_fileinfo *st = req->async_states->private_data;
+       struct smbsrv_request *req;
+       union smb_fileinfo *st;
+
+       SMBSRV_CHECK_ASYNC_STATUS(st, union smb_fileinfo);
 
-       CHECK_ASYNC_STATUS;
-       
        /* construct reply */
        smbsrv_setup_reply(req, 10, 0);
 
@@ -286,7 +244,7 @@ static void reply_getatr_send(struct smbsrv_request *req)
        srv_push_dos_date3(req->smb_conn, req->out.vwv, VWV(1), st->getattr.out.write_time);
        SIVAL(req->out.vwv,         VWV(3), st->getattr.out.size);
 
-       REQ_VWV_RESERVED(5, 5);
+       SMBSRV_VWV_RESERVED(5, 5);
 
        smbsrv_send_reply(req);
 }
@@ -299,7 +257,8 @@ void smbsrv_reply_getatr(struct smbsrv_request *req)
 {
        union smb_fileinfo *st;
 
-       REQ_TALLOC(st, union smb_fileinfo);
+       SMBSRV_TALLOC_IO_PTR(st, union smb_fileinfo);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_getatr_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
        
        st->getattr.level = RAW_FILEINFO_GETATTR;
 
@@ -310,14 +269,7 @@ void smbsrv_reply_getatr(struct smbsrv_request *req)
                return;
        }
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_getatr_send;
-       req->async_states->private_data = st;
-
-       /* call backend */
-       req->async_states->status = ntvfs_qpathinfo(req, st);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_qpathinfo(req->ntvfs, st));
 }
 
 
@@ -329,8 +281,9 @@ void smbsrv_reply_setatr(struct smbsrv_request *req)
        union smb_setfileinfo *st;
 
        /* parse request */
-       REQ_CHECK_WCT(req, 8);
-       REQ_TALLOC(st, union smb_setfileinfo);
+       SMBSRV_CHECK_WCT(req, 8);
+       SMBSRV_TALLOC_IO_PTR(st, union smb_setfileinfo);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        st->setattr.level = RAW_SFILEINFO_SETATTR;
        st->setattr.in.attrib     = SVAL(req->in.vwv, VWV(0));
@@ -343,25 +296,20 @@ void smbsrv_reply_setatr(struct smbsrv_request *req)
                return;
        }
        
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_simple_send;
-
-       /* call backend */
-       req->async_states->status = ntvfs_setpathinfo(req, st);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_setpathinfo(req->ntvfs, st));
 }
 
 
 /****************************************************************************
  Reply to a dskattr (async reply)
 ****************************************************************************/
-static void reply_dskattr_send(struct smbsrv_request *req)
+static void reply_dskattr_send(struct ntvfs_request *ntvfs)
 {
-       union smb_fsinfo *fs = req->async_states->private_data;
+       struct smbsrv_request *req;
+       union smb_fsinfo *fs;
+
+       SMBSRV_CHECK_ASYNC_STATUS(fs, union smb_fsinfo);
 
-       CHECK_ASYNC_STATUS;
-       
        /* construct reply */
        smbsrv_setup_reply(req, 5, 0);
 
@@ -370,7 +318,7 @@ static void reply_dskattr_send(struct smbsrv_request *req)
        SSVAL(req->out.vwv, VWV(2), fs->dskattr.out.block_size);
        SSVAL(req->out.vwv, VWV(3), fs->dskattr.out.units_free);
 
-       REQ_VWV_RESERVED(4, 1);
+       SMBSRV_VWV_RESERVED(4, 1);
 
        smbsrv_send_reply(req);
 }
@@ -383,30 +331,24 @@ void smbsrv_reply_dskattr(struct smbsrv_request *req)
 {
        union smb_fsinfo *fs;
 
-       REQ_TALLOC(fs, union smb_fsinfo);
+       SMBSRV_TALLOC_IO_PTR(fs, union smb_fsinfo);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_dskattr_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
        
        fs->dskattr.level = RAW_QFS_DSKATTR;
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_dskattr_send;
-       req->async_states->private_data = fs;
-
-       /* call backend */
-       req->async_states->status = ntvfs_fsinfo(req, fs);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_fsinfo(req->ntvfs, fs));
 }
 
 
-
 /****************************************************************************
  Reply to an open (async reply)
 ****************************************************************************/
-static void reply_open_send(struct smbsrv_request *req)
+static void reply_open_send(struct ntvfs_request *ntvfs)
 {
-       union smb_open *oi = req->async_states->private_data;
+       struct smbsrv_request *req;
+       union smb_open *oi;
 
-       CHECK_ASYNC_STATUS;
+       SMBSRV_CHECK_ASYNC_STATUS(oi, union smb_open);
 
        /* construct reply */
        smbsrv_setup_reply(req, 7, 0);
@@ -428,8 +370,9 @@ void smbsrv_reply_open(struct smbsrv_request *req)
        union smb_open *oi;
 
        /* parse request */
-       REQ_CHECK_WCT(req, 2);
-       REQ_TALLOC(oi, union smb_open);
+       SMBSRV_CHECK_WCT(req, 2);
+       SMBSRV_TALLOC_IO_PTR(oi, union smb_open);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_open_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        oi->openold.level = RAW_OPEN_OPEN;
        oi->openold.in.open_mode = SVAL(req->in.vwv, VWV(0));
@@ -442,25 +385,19 @@ void smbsrv_reply_open(struct smbsrv_request *req)
                return;
        }
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_open_send;
-       req->async_states->private_data = oi;
-       
-       /* call backend */
-       req->async_states->status = ntvfs_open(req, oi);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_open(req->ntvfs, oi));
 }
 
 
 /****************************************************************************
  Reply to an open and X (async reply)
 ****************************************************************************/
-static void reply_open_and_X_send(struct smbsrv_request *req)
+static void reply_open_and_X_send(struct ntvfs_request *ntvfs)
 {
-       union smb_open *oi = req->async_states->private_data;
+       struct smbsrv_request *req;
+       union smb_open *oi;
 
-       CHECK_ASYNC_STATUS;
+       SMBSRV_CHECK_ASYNC_STATUS(oi, union smb_open);
 
        /* build the reply */
        if (oi->openx.in.flags & OPENX_FLAGS_EXTENDED_RETURN) {
@@ -483,7 +420,7 @@ static void reply_open_and_X_send(struct smbsrv_request *req)
        SSVAL(req->out.vwv, VWV(14),0); /* reserved */
        if (oi->openx.in.flags & OPENX_FLAGS_EXTENDED_RETURN) {
                SIVAL(req->out.vwv, VWV(15),oi->openx.out.access_mask);
-               REQ_VWV_RESERVED(17, 2);
+               SMBSRV_VWV_RESERVED(17, 2);
        }
 
        req->chained_fnum = oi->openx.out.file.fnum;
@@ -500,8 +437,9 @@ void smbsrv_reply_open_and_X(struct smbsrv_request *req)
        union smb_open *oi;
 
        /* parse the request */
-       REQ_CHECK_WCT(req, 15);
-       REQ_TALLOC(oi, union smb_open);
+       SMBSRV_CHECK_WCT(req, 15);
+       SMBSRV_TALLOC_IO_PTR(oi, union smb_open);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_open_and_X_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        oi->openx.level = RAW_OPEN_OPENX;
        oi->openx.in.flags        = SVAL(req->in.vwv, VWV(2));
@@ -520,25 +458,19 @@ void smbsrv_reply_open_and_X(struct smbsrv_request *req)
                return;
        }
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_open_and_X_send;
-       req->async_states->private_data = oi;
-
-       /* call the backend */
-       req->async_states->status = ntvfs_open(req, oi);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_open(req->ntvfs, oi));
 }
 
 
 /****************************************************************************
  Reply to a mknew or a create.
 ****************************************************************************/
-static void reply_mknew_send(struct smbsrv_request *req)
+static void reply_mknew_send(struct ntvfs_request *ntvfs)
 {
-       union smb_open *oi = req->async_states->private_data;
+       struct smbsrv_request *req;
+       union smb_open *oi;
 
-       CHECK_ASYNC_STATUS;
+       SMBSRV_CHECK_ASYNC_STATUS(oi, union smb_open);
 
        /* build the reply */
        smbsrv_setup_reply(req, 1, 0);
@@ -557,8 +489,9 @@ void smbsrv_reply_mknew(struct smbsrv_request *req)
        union smb_open *oi;
 
        /* parse the request */
-       REQ_CHECK_WCT(req, 3);
-       REQ_TALLOC(oi, union smb_open);
+       SMBSRV_CHECK_WCT(req, 3);
+       SMBSRV_TALLOC_IO_PTR(oi, union smb_open);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_mknew_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        if (CVAL(req->in.hdr, HDR_COM) == SMBmknew) {
                oi->mknew.level = RAW_OPEN_MKNEW;
@@ -575,24 +508,18 @@ void smbsrv_reply_mknew(struct smbsrv_request *req)
                return;
        }
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_mknew_send;
-       req->async_states->private_data = oi;
-
-       /* call the backend */
-       req->async_states->status = ntvfs_open(req, oi);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_open(req->ntvfs, oi));
 }
 
 /****************************************************************************
  Reply to a create temporary file (async reply)
 ****************************************************************************/
-static void reply_ctemp_send(struct smbsrv_request *req)
+static void reply_ctemp_send(struct ntvfs_request *ntvfs)
 {
-       union smb_open *oi = req->async_states->private_data;
+       struct smbsrv_request *req;
+       union smb_open *oi;
 
-       CHECK_ASYNC_STATUS;
+       SMBSRV_CHECK_ASYNC_STATUS(oi, union smb_open);
 
        /* build the reply */
        smbsrv_setup_reply(req, 1, 0);
@@ -613,8 +540,9 @@ void smbsrv_reply_ctemp(struct smbsrv_request *req)
        union smb_open *oi;
 
        /* parse the request */
-       REQ_CHECK_WCT(req, 3);
-       REQ_TALLOC(oi, union smb_open);
+       SMBSRV_CHECK_WCT(req, 3);
+       SMBSRV_TALLOC_IO_PTR(oi, union smb_open);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_ctemp_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        oi->ctemp.level = RAW_OPEN_CTEMP;
        oi->ctemp.in.attrib = SVAL(req->in.vwv, VWV(0));
@@ -629,14 +557,7 @@ void smbsrv_reply_ctemp(struct smbsrv_request *req)
                return;
        }
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_ctemp_send;
-       req->async_states->private_data = oi;
-
-       /* call the backend */
-       req->async_states->status = ntvfs_open(req, oi);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_open(req->ntvfs, oi));
 }
 
 
@@ -648,20 +569,15 @@ void smbsrv_reply_unlink(struct smbsrv_request *req)
        union smb_unlink *unl;
 
        /* parse the request */
-       REQ_CHECK_WCT(req, 1);
-       REQ_TALLOC(unl, union smb_unlink);
+       SMBSRV_CHECK_WCT(req, 1);
+       SMBSRV_TALLOC_IO_PTR(unl, union smb_unlink);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
        
        unl->unlink.in.attrib = SVAL(req->in.vwv, VWV(0));
 
        req_pull_ascii4(req, &unl->unlink.in.pattern, req->in.data, STR_TERMINATE);
        
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_simple_send;
-
-       /* call backend */
-       req->async_states->status = ntvfs_unlink(req, unl);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_unlink(req->ntvfs, unl));
 }
 
 
@@ -707,9 +623,19 @@ void smbsrv_reply_readbraw(struct smbsrv_request *req)
        /* tell the backend where to put the data */
        io.readbraw.out.data = req->out.buffer + NBT_HDR_SIZE;
 
-       /* call the backend */
-       status = ntvfs_read(req, &io);
+       /* prepare the ntvfs request */
+       req->ntvfs = ntvfs_request_create(req->tcon->ntvfs, req,
+                                         req->session->session_info,
+                                         SVAL(req->in.hdr,HDR_PID),
+                                         SVAL(req->in.hdr,HDR_MID),
+                                         req->request_time,
+                                         req, NULL, 0);
+       if (!req->ntvfs) {
+               goto failed;
+       }
 
+       /* call the backend */
+       status = ntvfs_read(req->ntvfs, &io);
        if (!NT_STATUS_IS_OK(status)) {
                goto failed;
        }
@@ -732,11 +658,12 @@ failed:
 /****************************************************************************
  Reply to a lockread (async reply)
 ****************************************************************************/
-static void reply_lockread_send(struct smbsrv_request *req)
+static void reply_lockread_send(struct ntvfs_request *ntvfs)
 {
-       union smb_read *io = req->async_states->private_data;
+       struct smbsrv_request *req;
+       union smb_read *io;
 
-       CHECK_ASYNC_STATUS;
+       SMBSRV_CHECK_ASYNC_STATUS(io, union smb_read);
 
        /* trim packet */
        io->lockread.out.nread = MIN(io->lockread.out.nread,
@@ -745,7 +672,7 @@ static void reply_lockread_send(struct smbsrv_request *req)
 
        /* construct reply */
        SSVAL(req->out.vwv, VWV(0), io->lockread.out.nread);
-       REQ_VWV_RESERVED(1, 4);
+       SMBSRV_VWV_RESERVED(1, 4);
 
        SCVAL(req->out.data, 0, SMB_DATA_BLOCK);
        SSVAL(req->out.data, 1, io->lockread.out.nread);
@@ -763,8 +690,9 @@ void smbsrv_reply_lockread(struct smbsrv_request *req)
        union smb_read *io;
        
        /* parse request */
-       REQ_CHECK_WCT(req, 5);
-       REQ_TALLOC(io, union smb_read);
+       SMBSRV_CHECK_WCT(req, 5);
+       SMBSRV_TALLOC_IO_PTR(io, union smb_read);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_lockread_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        io->lockread.level = RAW_READ_LOCKREAD;
        io->lockread.in.file.fnum = req_fnum(req, req->in.vwv, VWV(0));
@@ -778,14 +706,7 @@ void smbsrv_reply_lockread(struct smbsrv_request *req)
        /* tell the backend where to put the data */
        io->lockread.out.data = req->out.data + 3;
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_lockread_send;
-       req->async_states->private_data = io;
-
-       /* call backend */
-       req->async_states->status = ntvfs_read(req, io);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_read(req->ntvfs, io));
 }
 
 
@@ -793,11 +714,12 @@ void smbsrv_reply_lockread(struct smbsrv_request *req)
 /****************************************************************************
  Reply to a read (async reply)
 ****************************************************************************/
-static void reply_read_send(struct smbsrv_request *req)
+static void reply_read_send(struct ntvfs_request *ntvfs)
 {
-       union smb_read *io = req->async_states->private_data;
+       struct smbsrv_request *req;
+       union smb_read *io;
 
-       CHECK_ASYNC_STATUS;
+       SMBSRV_CHECK_ASYNC_STATUS(io, union smb_read);
 
        /* trim packet */
        io->read.out.nread = MIN(io->read.out.nread,
@@ -806,7 +728,7 @@ static void reply_read_send(struct smbsrv_request *req)
 
        /* construct reply */
        SSVAL(req->out.vwv, VWV(0), io->read.out.nread);
-       REQ_VWV_RESERVED(1, 4);
+       SMBSRV_VWV_RESERVED(1, 4);
 
        SCVAL(req->out.data, 0, SMB_DATA_BLOCK);
        SSVAL(req->out.data, 1, io->read.out.nread);
@@ -822,9 +744,10 @@ void smbsrv_reply_read(struct smbsrv_request *req)
        union smb_read *io;
 
        /* parse request */
-       REQ_CHECK_WCT(req, 5);
-       REQ_TALLOC(io, union smb_read);
-       
+       SMBSRV_CHECK_WCT(req, 5);
+       SMBSRV_TALLOC_IO_PTR(io, union smb_read);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_read_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
+
        io->read.level = RAW_READ_READ;
        io->read.in.file.fnum     = req_fnum(req, req->in.vwv, VWV(0));
        io->read.in.count         = SVAL(req->in.vwv, VWV(1));
@@ -837,29 +760,21 @@ void smbsrv_reply_read(struct smbsrv_request *req)
        /* tell the backend where to put the data */
        io->read.out.data = req->out.data + 3;
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_read_send;
-       req->async_states->private_data = io;
-
-       /* call backend */
-       req->async_states->status = ntvfs_read(req, io);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_read(req->ntvfs, io));
 }
 
-
-
 /****************************************************************************
  Reply to a read and X (async reply)
 ****************************************************************************/
-static void reply_read_and_X_send(struct smbsrv_request *req)
+static void reply_read_and_X_send(struct ntvfs_request *ntvfs)
 {
-       union smb_read *io = req->async_states->private_data;
+       struct smbsrv_request *req;
+       union smb_read *io;
 
-       CHECK_ASYNC_STATUS;
+       SMBSRV_CHECK_ASYNC_STATUS(io, union smb_read);
 
        /* readx reply packets can be over-sized */
-       req->control_flags |= REQ_CONTROL_LARGE;
+       req->control_flags |= SMBSRV_REQ_CONTROL_LARGE;
        if (io->readx.in.maxcnt != 0xFFFF &&
            io->readx.in.mincnt != 0xFFFF) {
                req_grow_data(req, 1 + io->readx.out.nread);
@@ -873,10 +788,10 @@ static void reply_read_and_X_send(struct smbsrv_request *req)
        SSVAL(req->out.vwv, VWV(1), 0);
        SSVAL(req->out.vwv, VWV(2), io->readx.out.remaining);
        SSVAL(req->out.vwv, VWV(3), io->readx.out.compaction_mode);
-       REQ_VWV_RESERVED(4, 1);
+       SMBSRV_VWV_RESERVED(4, 1);
        SSVAL(req->out.vwv, VWV(5), io->readx.out.nread);
        SSVAL(req->out.vwv, VWV(6), PTR_DIFF(io->readx.out.data, req->out.hdr));
-       REQ_VWV_RESERVED(7, 5);
+       SMBSRV_VWV_RESERVED(7, 5);
 
        smbsrv_chain_reply(req);
 }
@@ -890,10 +805,11 @@ void smbsrv_reply_read_and_X(struct smbsrv_request *req)
 
        /* parse request */
        if (req->in.wct != 12) {
-               REQ_CHECK_WCT(req, 10);
+               SMBSRV_CHECK_WCT(req, 10);
        }
 
-       REQ_TALLOC(io, union smb_read);
+       SMBSRV_TALLOC_IO_PTR(io, union smb_read);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_read_and_X_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        io->readx.level = RAW_READ_READX;
        io->readx.in.file.fnum     = req_fnum(req, req->in.vwv, VWV(2));
@@ -931,14 +847,7 @@ void smbsrv_reply_read_and_X(struct smbsrv_request *req)
                io->readx.out.data = req->out.data;
        }
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_read_and_X_send;
-       req->async_states->private_data = io;
-
-       /* call backend */
-       req->async_states->status = ntvfs_read(req, io);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_read(req->ntvfs, io));
 }
 
 
@@ -954,11 +863,12 @@ void smbsrv_reply_writebraw(struct smbsrv_request *req)
 /****************************************************************************
  Reply to a writeunlock (async reply)
 ****************************************************************************/
-static void reply_writeunlock_send(struct smbsrv_request *req)
+static void reply_writeunlock_send(struct ntvfs_request *ntvfs)
 {
-       union smb_write *io = req->async_states->private_data;
+       struct smbsrv_request *req;
+       union smb_write *io;
 
-       CHECK_ASYNC_STATUS;
+       SMBSRV_CHECK_ASYNC_STATUS(io, union smb_write);
 
        /* construct reply */
        smbsrv_setup_reply(req, 1, 0);
@@ -975,8 +885,9 @@ void smbsrv_reply_writeunlock(struct smbsrv_request *req)
 {
        union smb_write *io;
 
-       REQ_CHECK_WCT(req, 5);
-       REQ_TALLOC(io, union smb_write);
+       SMBSRV_CHECK_WCT(req, 5);
+       SMBSRV_TALLOC_IO_PTR(io, union smb_write);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_writeunlock_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        io->writeunlock.level = RAW_WRITE_WRITEUNLOCK;
        io->writeunlock.in.file.fnum   = req_fnum(req, req->in.vwv, VWV(0));
@@ -997,14 +908,7 @@ void smbsrv_reply_writeunlock(struct smbsrv_request *req)
                return;
        }
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_writeunlock_send;
-       req->async_states->private_data = io;
-
-       /* call backend */
-       req->async_states->status = ntvfs_write(req, io);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_write(req->ntvfs, io));
 }
 
 
@@ -1012,11 +916,12 @@ void smbsrv_reply_writeunlock(struct smbsrv_request *req)
 /****************************************************************************
  Reply to a write (async reply)
 ****************************************************************************/
-static void reply_write_send(struct smbsrv_request *req)
+static void reply_write_send(struct ntvfs_request *ntvfs)
 {
-       union smb_write *io = req->async_states->private_data;
+       struct smbsrv_request *req;
+       union smb_write *io;
        
-       CHECK_ASYNC_STATUS;
+       SMBSRV_CHECK_ASYNC_STATUS(io, union smb_write);
 
        /* construct reply */
        smbsrv_setup_reply(req, 1, 0);
@@ -1033,8 +938,9 @@ void smbsrv_reply_write(struct smbsrv_request *req)
 {
        union smb_write *io;
 
-       REQ_CHECK_WCT(req, 5);
-       REQ_TALLOC(io, union smb_write);
+       SMBSRV_CHECK_WCT(req, 5);
+       SMBSRV_TALLOC_IO_PTR(io, union smb_write);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_write_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        io->write.level = RAW_WRITE_WRITE;
        io->write.in.file.fnum   = req_fnum(req, req->in.vwv, VWV(0));
@@ -1055,25 +961,19 @@ void smbsrv_reply_write(struct smbsrv_request *req)
                return;
        }
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_write_send;
-       req->async_states->private_data = io;
-
-       /* call backend */
-       req->async_states->status = ntvfs_write(req, io);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_write(req->ntvfs, io));
 }
 
 
 /****************************************************************************
  Reply to a write and X (async reply)
 ****************************************************************************/
-static void reply_write_and_X_send(struct smbsrv_request *req)
+static void reply_write_and_X_send(struct ntvfs_request *ntvfs)
 {
-       union smb_write *io = req->async_states->private_data;
+       struct smbsrv_request *req;
+       union smb_write *io;
 
-       CHECK_ASYNC_STATUS;
+       SMBSRV_CHECK_ASYNC_STATUS(io, union smb_write);
 
        /* construct reply */
        smbsrv_setup_reply(req, 6, 0);
@@ -1083,7 +983,7 @@ static void reply_write_and_X_send(struct smbsrv_request *req)
        SSVAL(req->out.vwv, VWV(2), io->writex.out.nwritten & 0xFFFF);
        SSVAL(req->out.vwv, VWV(3), io->writex.out.remaining);
        SSVAL(req->out.vwv, VWV(4), io->writex.out.nwritten >> 16);
-       REQ_VWV_RESERVED(5, 1);
+       SMBSRV_VWV_RESERVED(5, 1);
 
        smbsrv_chain_reply(req);
 }
@@ -1096,10 +996,11 @@ void smbsrv_reply_write_and_X(struct smbsrv_request *req)
        union smb_write *io;
        
        if (req->in.wct != 14) {
-               REQ_CHECK_WCT(req, 12);
+               SMBSRV_CHECK_WCT(req, 12);
        }
 
-       REQ_TALLOC(io, union smb_write);
+       SMBSRV_TALLOC_IO_PTR(io, union smb_write);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_write_and_X_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        io->writex.level = RAW_WRITE_WRITEX;
        io->writex.in.file.fnum = req_fnum(req, req->in.vwv, VWV(2));
@@ -1122,25 +1023,19 @@ void smbsrv_reply_write_and_X(struct smbsrv_request *req)
                return;
        } 
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_write_and_X_send;
-       req->async_states->private_data = io;
-
-       /* call backend */
-       req->async_states->status = ntvfs_write(req, io);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_write(req->ntvfs, io));
 }
 
 
 /****************************************************************************
  Reply to a lseek (async reply)
 ****************************************************************************/
-static void reply_lseek_send(struct smbsrv_request *req)
+static void reply_lseek_send(struct ntvfs_request *ntvfs)
 {
-       union smb_seek *io = req->async_states->private_data;
+       struct smbsrv_request *req;
+       union smb_seek *io;
 
-       CHECK_ASYNC_STATUS;
+       SMBSRV_CHECK_ASYNC_STATUS(io, union smb_seek);
 
        /* construct reply */
        smbsrv_setup_reply(req, 2, 0);
@@ -1157,21 +1052,15 @@ void smbsrv_reply_lseek(struct smbsrv_request *req)
 {
        union smb_seek *io;
 
-       REQ_CHECK_WCT(req, 4);
-       REQ_TALLOC(io, union smb_seek);
+       SMBSRV_CHECK_WCT(req, 4);
+       SMBSRV_TALLOC_IO_PTR(io, union smb_seek);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_lseek_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        io->lseek.in.file.fnum  = req_fnum(req, req->in.vwv,  VWV(0));
        io->lseek.in.mode       = SVAL(req->in.vwv,  VWV(1));
        io->lseek.in.offset     = IVALS(req->in.vwv, VWV(2));
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_lseek_send;
-       req->async_states->private_data = io;
-       
-       /* call backend */
-       req->async_states->status = ntvfs_seek(req, io);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_seek(req->ntvfs, io));
 }
 
 /****************************************************************************
@@ -1182,18 +1071,13 @@ void smbsrv_reply_flush(struct smbsrv_request *req)
        union smb_flush *io;
 
        /* parse request */
-       REQ_CHECK_WCT(req, 1);
-       REQ_TALLOC(io, union smb_flush);
+       SMBSRV_CHECK_WCT(req, 1);
+       SMBSRV_TALLOC_IO_PTR(io, union smb_flush);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        io->flush.in.file.fnum = req_fnum(req, req->in.vwv,  VWV(0));
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_simple_send;
-
-       /* call backend */
-       req->async_states->status = ntvfs_flush(req, io);
-       
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_flush(req->ntvfs, io));
 }
 
 
@@ -1204,14 +1088,15 @@ void smbsrv_reply_exit(struct smbsrv_request *req)
 {
        NTSTATUS status;
        struct smbsrv_tcon *tcon;
-       REQ_CHECK_WCT(req, 0);
+       SMBSRV_CHECK_WCT(req, 0);
 
        for (tcon=req->smb_conn->smb_tcons.list;tcon;tcon=tcon->next) {
                req->tcon = tcon;
-req->ctx = req->tcon->ntvfs;
-               status = ntvfs_exit(req);
+               SMBSRV_SETUP_NTVFS_REQUEST(NULL,0);
+               status = ntvfs_exit(req->ntvfs);
+               talloc_free(req->ntvfs);
+               req->ntvfs = NULL;
                req->tcon = NULL;
-req->ctx = NULL;
                if (!NT_STATUS_IS_OK(status)) {
                        smbsrv_send_error(req, status);
                        return;
@@ -1233,32 +1118,27 @@ void smbsrv_reply_close(struct smbsrv_request *req)
        union smb_close *io;
 
        /* parse request */
-       REQ_CHECK_WCT(req, 3);
-       REQ_TALLOC(io, union smb_close);
+       SMBSRV_CHECK_WCT(req, 3);
+       SMBSRV_TALLOC_IO_PTR(io, union smb_close);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        io->close.level = RAW_CLOSE_CLOSE;
        io->close.in.file.fnum  = req_fnum(req, req->in.vwv,  VWV(0));
        io->close.in.write_time = srv_pull_dos_date3(req->smb_conn, req->in.vwv + VWV(1));
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_simple_send;
-
-       /* call backend */
-       req->async_states->status = ntvfs_close(req, io);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_close(req->ntvfs, io));
 }
 
 
-
 /****************************************************************************
  Reply to a writeclose (async reply)
 ****************************************************************************/
-static void reply_writeclose_send(struct smbsrv_request *req)
+static void reply_writeclose_send(struct ntvfs_request *ntvfs)
 {
-       union smb_write *io = req->async_states->private_data;
+       struct smbsrv_request *req;
+       union smb_write *io;
 
-       CHECK_ASYNC_STATUS;
+       SMBSRV_CHECK_ASYNC_STATUS(io, union smb_write);
 
        /* construct reply */
        smbsrv_setup_reply(req, 1, 0);
@@ -1277,10 +1157,11 @@ void smbsrv_reply_writeclose(struct smbsrv_request *req)
 
        /* this one is pretty weird - the wct can be 6 or 12 */
        if (req->in.wct != 12) {
-               REQ_CHECK_WCT(req, 6);
+               SMBSRV_CHECK_WCT(req, 6);
        }
 
-       REQ_TALLOC(io, union smb_write);
+       SMBSRV_TALLOC_IO_PTR(io, union smb_write);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_writeclose_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        io->writeclose.level = RAW_WRITE_WRITECLOSE;
        io->writeclose.in.file.fnum = req_fnum(req, req->in.vwv, VWV(0));
@@ -1295,14 +1176,7 @@ void smbsrv_reply_writeclose(struct smbsrv_request *req)
                return;
        }
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_writeclose_send;
-       req->async_states->private_data = io;
-
-       /* call backend */
-       req->async_states->status = ntvfs_write(req, io);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_write(req->ntvfs, io));
 }
 
 /****************************************************************************
@@ -1313,21 +1187,16 @@ void smbsrv_reply_lock(struct smbsrv_request *req)
        union smb_lock *lck;
 
        /* parse request */
-       REQ_CHECK_WCT(req, 5);
-       REQ_TALLOC(lck, union smb_lock);
+       SMBSRV_CHECK_WCT(req, 5);
+       SMBSRV_TALLOC_IO_PTR(lck, union smb_lock);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        lck->lock.level         = RAW_LOCK_LOCK;
        lck->lock.in.file.fnum  = req_fnum(req, req->in.vwv, VWV(0));
        lck->lock.in.count      = IVAL(req->in.vwv, VWV(1));
        lck->lock.in.offset     = IVAL(req->in.vwv, VWV(3));
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_simple_send;
-
-       /* call backend */
-       req->async_states->status = ntvfs_lock(req, lck);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_lock(req->ntvfs, lck));
 }
 
 
@@ -1339,21 +1208,16 @@ void smbsrv_reply_unlock(struct smbsrv_request *req)
        union smb_lock *lck;
 
        /* parse request */
-       REQ_CHECK_WCT(req, 5);
-       REQ_TALLOC(lck, union smb_lock);
+       SMBSRV_CHECK_WCT(req, 5);
+       SMBSRV_TALLOC_IO_PTR(lck, union smb_lock);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        lck->unlock.level               = RAW_LOCK_UNLOCK;
        lck->unlock.in.file.fnum        = req_fnum(req, req->in.vwv, VWV(0));
        lck->unlock.in.count            = IVAL(req->in.vwv, VWV(1));
        lck->unlock.in.offset           = IVAL(req->in.vwv, VWV(3));
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_simple_send;
-
-       /* call backend */
-       req->async_states->status = ntvfs_lock(req, lck);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_lock(req->ntvfs, lck));
 }
 
 
@@ -1362,9 +1226,10 @@ void smbsrv_reply_unlock(struct smbsrv_request *req)
 ****************************************************************************/
 void smbsrv_reply_tdis(struct smbsrv_request *req)
 {
-       REQ_CHECK_WCT(req, 0);
+       SMBSRV_CHECK_WCT(req, 0);
 
        talloc_free(req->tcon);
+       req->tcon = NULL;
 
        /* construct reply */
        smbsrv_setup_reply(req, 0, 0);
@@ -1382,7 +1247,7 @@ void smbsrv_reply_echo(struct smbsrv_request *req)
        uint16_t count;
        int i;
 
-       REQ_CHECK_WCT(req, 0);
+       SMBSRV_CHECK_WCT(req, 0);
 
        count = SVAL(req->in.vwv, VWV(0));
 
@@ -1409,11 +1274,12 @@ void smbsrv_reply_echo(struct smbsrv_request *req)
 /****************************************************************************
  Reply to a printopen (async reply)
 ****************************************************************************/
-static void reply_printopen_send(struct smbsrv_request *req)
+static void reply_printopen_send(struct ntvfs_request *ntvfs)
 {
-       union smb_open *oi = req->async_states->private_data;
+       struct smbsrv_request *req;
+       union smb_open *oi;
 
-       CHECK_ASYNC_STATUS;
+       SMBSRV_CHECK_ASYNC_STATUS(oi, union smb_open);
 
        /* construct reply */
        smbsrv_setup_reply(req, 1, 0);
@@ -1431,8 +1297,9 @@ void smbsrv_reply_printopen(struct smbsrv_request *req)
        union smb_open *oi;
 
        /* parse request */
-       REQ_CHECK_WCT(req, 2);
-       REQ_TALLOC(oi, union smb_open);
+       SMBSRV_CHECK_WCT(req, 2);
+       SMBSRV_TALLOC_IO_PTR(oi, union smb_open);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_printopen_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        oi->splopen.level = RAW_OPEN_SPLOPEN;
        oi->splopen.in.setup_length = SVAL(req->in.vwv, VWV(0));
@@ -1440,14 +1307,7 @@ void smbsrv_reply_printopen(struct smbsrv_request *req)
 
        req_pull_ascii4(req, &oi->splopen.in.ident, req->in.data, STR_TERMINATE);
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_printopen_send;
-       req->async_states->private_data = oi;
-
-       /* call backend */
-       req->async_states->status = ntvfs_open(req, oi);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_open(req->ntvfs, oi));
 }
 
 /****************************************************************************
@@ -1458,31 +1318,27 @@ void smbsrv_reply_printclose(struct smbsrv_request *req)
        union smb_close *io;
 
        /* parse request */
-       REQ_CHECK_WCT(req, 3);
-       REQ_TALLOC(io, union smb_close);
+       SMBSRV_CHECK_WCT(req, 3);
+       SMBSRV_TALLOC_IO_PTR(io, union smb_close);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        io->splclose.level = RAW_CLOSE_SPLCLOSE;
        io->splclose.in.file.fnum = req_fnum(req, req->in.vwv,  VWV(0));
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_simple_send;
-
-       /* call backend */
-       req->async_states->status = ntvfs_close(req, io);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_close(req->ntvfs, io));
 }
 
 /****************************************************************************
  Reply to a printqueue.
 ****************************************************************************/
-static void reply_printqueue_send(struct smbsrv_request *req)
+static void reply_printqueue_send(struct ntvfs_request *ntvfs)
 {
-       union smb_lpq *lpq = req->async_states->private_data;
+       struct smbsrv_request *req;
+       union smb_lpq *lpq;
        int i, maxcount;
-       const uint_t el_size = 28;      
+       const uint_t el_size = 28;
 
-       CHECK_ASYNC_STATUS;
+       SMBSRV_CHECK_ASYNC_STATUS(lpq,union smb_lpq);
 
        /* construct reply */
        smbsrv_setup_reply(req, 2, 0);
@@ -1526,21 +1382,15 @@ void smbsrv_reply_printqueue(struct smbsrv_request *req)
        union smb_lpq *lpq;
 
        /* parse request */
-       REQ_CHECK_WCT(req, 2);
-       REQ_TALLOC(lpq, union smb_lpq);
+       SMBSRV_CHECK_WCT(req, 2);
+       SMBSRV_TALLOC_IO_PTR(lpq, union smb_lpq);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_printqueue_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        lpq->retq.level = RAW_LPQ_RETQ;
        lpq->retq.in.maxcount = SVAL(req->in.vwv,  VWV(0));
        lpq->retq.in.startidx = SVAL(req->in.vwv,  VWV(1));
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_printqueue_send;
-       req->async_states->private_data = lpq;
-
-       /* call backend */
-       req->async_states->status = ntvfs_lpq(req, lpq);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_lpq(req->ntvfs, lpq));
 }
 
 
@@ -1552,8 +1402,9 @@ void smbsrv_reply_printwrite(struct smbsrv_request *req)
        union smb_write *io;
 
        /* parse request */
-       REQ_CHECK_WCT(req, 1);
-       REQ_TALLOC(io, union smb_write);
+       SMBSRV_CHECK_WCT(req, 1);
+       SMBSRV_TALLOC_IO_PTR(io, union smb_write);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        io->splwrite.level = RAW_WRITE_SPLWRITE;
 
@@ -1572,13 +1423,7 @@ void smbsrv_reply_printwrite(struct smbsrv_request *req)
                return;
        }
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_simple_send;
-
-       /* call backend */
-       req->async_states->status = ntvfs_write(req, io);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_write(req->ntvfs, io));
 }
 
 
@@ -1590,19 +1435,14 @@ void smbsrv_reply_mkdir(struct smbsrv_request *req)
        union smb_mkdir *io;
 
        /* parse the request */
-       REQ_CHECK_WCT(req, 0);
-       REQ_TALLOC(io, union smb_mkdir);
+       SMBSRV_CHECK_WCT(req, 0);
+       SMBSRV_TALLOC_IO_PTR(io, union smb_mkdir);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        io->generic.level = RAW_MKDIR_MKDIR;
        req_pull_ascii4(req, &io->mkdir.in.path, req->in.data, STR_TERMINATE);
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_simple_send;
-
-       /* call backend */
-       req->async_states->status = ntvfs_mkdir(req, io);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_mkdir(req->ntvfs, io));
 }
 
 
@@ -1614,18 +1454,13 @@ void smbsrv_reply_rmdir(struct smbsrv_request *req)
        struct smb_rmdir *io;
  
        /* parse the request */
-       REQ_CHECK_WCT(req, 0);
-       REQ_TALLOC(io, struct smb_rmdir);
+       SMBSRV_CHECK_WCT(req, 0);
+       SMBSRV_TALLOC_IO_PTR(io, struct smb_rmdir);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        req_pull_ascii4(req, &io->in.path, req->in.data, STR_TERMINATE);
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_simple_send;
-
-       /* call backend */
-       req->async_states->status = ntvfs_rmdir(req, io);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_rmdir(req->ntvfs, io));
 }
 
 
@@ -1638,8 +1473,9 @@ void smbsrv_reply_mv(struct smbsrv_request *req)
        uint8_t *p;
  
        /* parse the request */
-       REQ_CHECK_WCT(req, 1);
-       REQ_TALLOC(io, union smb_rename);
+       SMBSRV_CHECK_WCT(req, 1);
+       SMBSRV_TALLOC_IO_PTR(io, union smb_rename);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        io->generic.level = RAW_RENAME_RENAME;
        io->rename.in.attrib = SVAL(req->in.vwv, VWV(0));
@@ -1653,13 +1489,7 @@ void smbsrv_reply_mv(struct smbsrv_request *req)
                return;
        }
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_simple_send;
-
-       /* call backend */
-       req->async_states->status = ntvfs_rename(req, io);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_rename(req->ntvfs, io));
 }
 
 
@@ -1672,8 +1502,9 @@ void smbsrv_reply_ntrename(struct smbsrv_request *req)
        uint8_t *p;
  
        /* parse the request */
-       REQ_CHECK_WCT(req, 4);
-       REQ_TALLOC(io, union smb_rename);
+       SMBSRV_CHECK_WCT(req, 4);
+       SMBSRV_TALLOC_IO_PTR(io, union smb_rename);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        io->generic.level = RAW_RENAME_NTRENAME;
        io->ntrename.in.attrib  = SVAL(req->in.vwv, VWV(0));
@@ -1689,23 +1520,18 @@ void smbsrv_reply_ntrename(struct smbsrv_request *req)
                return;
        }
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_simple_send;
-
-       /* call backend */
-       req->async_states->status = ntvfs_rename(req, io);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_rename(req->ntvfs, io));
 }
 
 /****************************************************************************
  Reply to a file copy (async reply)
 ****************************************************************************/
-static void reply_copy_send(struct smbsrv_request *req)
+static void reply_copy_send(struct ntvfs_request *ntvfs)
 {
-       struct smb_copy *cp = req->async_states->private_data;
+       struct smbsrv_request *req;
+       struct smb_copy *cp;
 
-       CHECK_ASYNC_STATUS;
+       SMBSRV_CHECK_ASYNC_STATUS(cp, struct smb_copy);
 
        /* build the reply */
        smbsrv_setup_reply(req, 1, 0);
@@ -1724,8 +1550,9 @@ void smbsrv_reply_copy(struct smbsrv_request *req)
        uint8_t *p;
 
        /* parse request */
-       REQ_CHECK_WCT(req, 3);
-       REQ_TALLOC(cp, struct smb_copy);
+       SMBSRV_CHECK_WCT(req, 3);
+       SMBSRV_TALLOC_IO_PTR(cp, struct smb_copy);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_copy_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        cp->in.tid2  = SVAL(req->in.vwv, VWV(0));
        cp->in.ofun  = SVAL(req->in.vwv, VWV(1));
@@ -1740,24 +1567,18 @@ void smbsrv_reply_copy(struct smbsrv_request *req)
                return;
        }
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_copy_send;
-       req->async_states->private_data = cp;
-
-       /* call backend */
-       req->async_states->status = ntvfs_copy(req, cp);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_copy(req->ntvfs, cp));
 }
 
 /****************************************************************************
  Reply to a lockingX request (async send)
 ****************************************************************************/
-static void reply_lockingX_send(struct smbsrv_request *req)
+static void reply_lockingX_send(struct ntvfs_request *ntvfs)
 {
-       union smb_lock *lck = req->async_states->private_data;
+       struct smbsrv_request *req;
+       union smb_lock *lck;
 
-       CHECK_ASYNC_STATUS;
+       SMBSRV_CHECK_ASYNC_STATUS(lck, union smb_lock);
 
        /* if it was an oplock break ack then we only send a reply if
           there was an error */
@@ -1787,8 +1608,9 @@ void smbsrv_reply_lockingX(struct smbsrv_request *req)
        uint8_t *p;
 
        /* parse request */
-       REQ_CHECK_WCT(req, 8);
-       REQ_TALLOC(lck, union smb_lock);
+       SMBSRV_CHECK_WCT(req, 8);
+       SMBSRV_TALLOC_IO_PTR(lck, union smb_lock);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_lockingX_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        lck->lockx.level = RAW_LOCK_LOCKX;
        lck->lockx.in.file.fnum = req_fnum(req, req->in.vwv, VWV(2));
@@ -1846,14 +1668,7 @@ void smbsrv_reply_lockingX(struct smbsrv_request *req)
                p += lck_size;
        }
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_lockingX_send;
-       req->async_states->private_data = lck;
-
-       /* call backend */
-       req->async_states->status = ntvfs_lock(req, lck);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_lock(req->ntvfs, lck));
 }
 
 /****************************************************************************
@@ -1874,8 +1689,9 @@ void smbsrv_reply_setattrE(struct smbsrv_request *req)
        union smb_setfileinfo *info;
 
        /* parse request */
-       REQ_CHECK_WCT(req, 7);
-       REQ_TALLOC(info, union smb_setfileinfo);
+       SMBSRV_CHECK_WCT(req, 7);
+       SMBSRV_TALLOC_IO_PTR(info, union smb_setfileinfo);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        info->setattre.level = RAW_SFILEINFO_SETATTRE;
        info->setattre.in.file.fnum   = req_fnum(req, req->in.vwv,    VWV(0));
@@ -1883,13 +1699,7 @@ void smbsrv_reply_setattrE(struct smbsrv_request *req)
        info->setattre.in.access_time = srv_pull_dos_date2(req->smb_conn, req->in.vwv + VWV(3));
        info->setattre.in.write_time  = srv_pull_dos_date2(req->smb_conn, req->in.vwv + VWV(5));
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_simple_send;
-
-       /* call backend */
-       req->async_states->status = ntvfs_setfileinfo(req, info);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_setfileinfo(req->ntvfs, info));
 }
 
 
@@ -1915,11 +1725,12 @@ void smbsrv_reply_writebs(struct smbsrv_request *req)
 /****************************************************************************
  Reply to a SMBgetattrE (async reply)
 ****************************************************************************/
-static void reply_getattrE_send(struct smbsrv_request *req)
+static void reply_getattrE_send(struct ntvfs_request *ntvfs)
 {
-       union smb_fileinfo *info = req->async_states->private_data;
+       struct smbsrv_request *req;
+       union smb_fileinfo *info;
 
-       CHECK_ASYNC_STATUS;
+       SMBSRV_CHECK_ASYNC_STATUS(info, union smb_fileinfo);
 
        /* setup reply */
        smbsrv_setup_reply(req, 11, 0);
@@ -1942,20 +1753,14 @@ void smbsrv_reply_getattrE(struct smbsrv_request *req)
        union smb_fileinfo *info;
 
        /* parse request */
-       REQ_CHECK_WCT(req, 1);
-       REQ_TALLOC(info, union smb_fileinfo);
+       SMBSRV_CHECK_WCT(req, 1);
+       SMBSRV_TALLOC_IO_PTR(info, union smb_fileinfo);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_getattrE_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        info->getattr.level = RAW_FILEINFO_GETATTRE;
        info->getattr.in.file.fnum = req_fnum(req, req->in.vwv, VWV(0));
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_getattrE_send;
-       req->async_states->private_data = info;
-
-       /* call backend */
-       req->async_states->status = ntvfs_qfileinfo(req, info);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_qfileinfo(req->ntvfs, info));
 }
 
 
@@ -2186,10 +1991,11 @@ void smbsrv_reply_ulogoffX(struct smbsrv_request *req)
           open by this user on all open tree connects */
        for (tcon=req->smb_conn->smb_tcons.list;tcon;tcon=tcon->next) {
                req->tcon = tcon;
-               req->ctx = tcon->ntvfs;
-               status = ntvfs_logoff(req);
+               SMBSRV_SETUP_NTVFS_REQUEST(NULL,0);
+               status = ntvfs_logoff(req->ntvfs);
+               talloc_free(req->ntvfs);
+               req->ntvfs = NULL;
                req->tcon = NULL;
-               req->ctx = NULL;
                if (!NT_STATUS_IS_OK(status)) {
                        smbsrv_send_error(req, status);
                        return;
@@ -2208,34 +2014,22 @@ void smbsrv_reply_ulogoffX(struct smbsrv_request *req)
        smbsrv_chain_reply(req);
 }
 
-
 /****************************************************************************
  Reply to an SMBfindclose request
 ****************************************************************************/
 void smbsrv_reply_findclose(struct smbsrv_request *req)
 {
-       NTSTATUS status;
-       union smb_search_close io;
-
-       io.findclose.level = RAW_FINDCLOSE_FINDCLOSE;
+       union smb_search_close *io;
 
        /* parse request */
-       REQ_CHECK_WCT(req, 1);
+       SMBSRV_CHECK_WCT(req, 1);
+       SMBSRV_TALLOC_IO_PTR(io, union smb_search_close);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_simple_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
-       io.findclose.in.handle  = SVAL(req->in.vwv, VWV(0));
-       
-       /* call backend */
-       status = ntvfs_search_close(req, &io);
+       io->findclose.level     = RAW_FINDCLOSE_FINDCLOSE;
+       io->findclose.in.handle = SVAL(req->in.vwv, VWV(0));
 
-       if (!NT_STATUS_IS_OK(status)) {
-               smbsrv_send_error(req, status);
-               return;
-       }
-
-       /* construct reply */
-       smbsrv_setup_reply(req, 0, 0);
-
-       smbsrv_send_reply(req); 
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_search_close(req->ntvfs, io));
 }
 
 /****************************************************************************
@@ -2250,11 +2044,12 @@ void smbsrv_reply_findnclose(struct smbsrv_request *req)
 /****************************************************************************
  Reply to an SMBntcreateX request (async send)
 ****************************************************************************/
-static void reply_ntcreate_and_X_send(struct smbsrv_request *req)
+static void reply_ntcreate_and_X_send(struct ntvfs_request *ntvfs)
 {
-       union smb_open *io = req->async_states->private_data;
+       struct smbsrv_request *req;
+       union smb_open *io;
 
-       CHECK_ASYNC_STATUS;
+       SMBSRV_CHECK_ASYNC_STATUS(io, union smb_open);
 
        /* construct reply */
        smbsrv_setup_reply(req, 34, 0);
@@ -2291,8 +2086,9 @@ void smbsrv_reply_ntcreate_and_X(struct smbsrv_request *req)
        uint16_t fname_len;
 
        /* parse the request */
-       REQ_CHECK_WCT(req, 24);
-       REQ_TALLOC(io, union smb_open);
+       SMBSRV_CHECK_WCT(req, 24);
+       SMBSRV_TALLOC_IO_PTR(io, union smb_open);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_ntcreate_and_X_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        io->ntcreatex.level = RAW_OPEN_NTCREATEX;
 
@@ -2323,14 +2119,7 @@ void smbsrv_reply_ntcreate_and_X(struct smbsrv_request *req)
                return;
        }
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_ntcreate_and_X_send;
-       req->async_states->private_data = io;
-
-       /* call the backend */
-       req->async_states->status = ntvfs_open(req, io);
-
-       REQ_ASYNC_TAIL;
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_open(req->ntvfs, io));
 }
 
 
@@ -2340,7 +2129,8 @@ void smbsrv_reply_ntcreate_and_X(struct smbsrv_request *req)
 void smbsrv_reply_ntcancel(struct smbsrv_request *req)
 {
        /* NOTE: this request does not generate a reply */
-       ntvfs_cancel(req);
+       SMBSRV_SETUP_NTVFS_REQUEST(NULL,0);
+       ntvfs_cancel(req->ntvfs);
        talloc_free(req);
 }
 
index 1c09d5ccb206baafc3a15c8876647be2444b9cd1..e858b2b7872375c7e0a0be01adfa2122e1cb6ea9 100644 (file)
@@ -48,13 +48,6 @@ struct smbsrv_request *smbsrv_init_request(struct smbsrv_connection *smb_conn)
        /* setup the request context */
        req->smb_conn = smb_conn;
 
-       req->async_states = talloc(req, struct ntvfs_async_state);
-       if (!req->async_states) {
-               talloc_free(req);
-               return NULL;
-       }
-       req->async_states->state = 0;
-
        return req;
 }
 
@@ -259,7 +252,7 @@ void req_grow_data(struct smbsrv_request *req, uint_t new_size)
 {
        int delta;
 
-       if (!(req->control_flags & REQ_CONTROL_LARGE) && new_size > req_max_data(req)) {
+       if (!(req->control_flags & SMBSRV_REQ_CONTROL_LARGE) && new_size > req_max_data(req)) {
                smb_panic("reply buffer too large!");
        }
 
index 71d5ce6cfcea160d31ff5f86fb2693abe5b87ba5..b86c0ddb7e4dbd7c7e548e49ff050b68b34b06bd 100644 (file)
 #include "ntvfs/ntvfs.h"
 
 
-/* check req->async.status and if not OK then send an error reply */
-#define CHECK_ASYNC_STATUS do { \
-       if (!NT_STATUS_IS_OK(req->async_states->status)) { \
-               smbsrv_send_error(req, req->async_states->status); \
-               return; \
-       }} while (0)
-       
-/* 
-   check if the backend wants to handle the request asynchronously.
-   if it wants it handled synchronously then call the send function
-   immediately
-*/
-#define REQ_ASYNC_TAIL do { \
-       if (!(req->async_states->state & NTVFS_ASYNC_STATE_ASYNC)) { \
-               req->async_states->send_fn(req); \
-       }} while (0)
-
-/* useful wrapper for talloc with NO_MEMORY reply */
-#define REQ_TALLOC(ptr, type) do { \
-       ptr = talloc(req, type); \
-       if (!ptr) { \
-               smbsrv_send_error(req, NT_STATUS_NO_MEMORY); \
-               return; \
-       }} while (0)
-
-#define CHECK_MIN_BLOB_SIZE(blob, size) do { \
-       if ((blob)->length < (size)) { \
-               return NT_STATUS_INFO_LENGTH_MISMATCH; \
-       }} while (0)
-
 /* a structure to encapsulate the state information about 
  * an in-progress search first/next operation */
 struct search_state {
@@ -106,13 +76,12 @@ static BOOL find_callback(void *private, union smb_search_data *file)
 /****************************************************************************
  Reply to a search first (async reply)
 ****************************************************************************/
-static void reply_search_first_send(struct smbsrv_request *req)
+static void reply_search_first_send(struct ntvfs_request *ntvfs)
 {
+       struct smbsrv_request *req;
        union smb_search_first *sf;
-       
-       CHECK_ASYNC_STATUS;
 
-       sf = talloc_get_type(req->async_states->private_data, union smb_search_first);
+       SMBSRV_CHECK_ASYNC_STATUS(sf, union smb_search_first);
 
        SSVAL(req->out.vwv, VWV(0), sf->search_first.out.count);
 
@@ -122,13 +91,12 @@ static void reply_search_first_send(struct smbsrv_request *req)
 /****************************************************************************
  Reply to a search next (async reply)
 ****************************************************************************/
-static void reply_search_next_send(struct smbsrv_request *req)
+static void reply_search_next_send(struct ntvfs_request *ntvfs)
 {
+       struct smbsrv_request *req;
        union smb_search_next *sn;
        
-       CHECK_ASYNC_STATUS;
-
-       sn = talloc_get_type(req->async_states->private_data, union smb_search_next);
+       SMBSRV_CHECK_ASYNC_STATUS(sn, union smb_search_next);
 
        SSVAL(req->out.vwv, VWV(0), sn->search_next.out.count);
 
@@ -159,8 +127,8 @@ void smbsrv_reply_search(struct smbsrv_request *req)
                return;
        }
 
-       REQ_TALLOC(sf, union smb_search_first);
-       
+       SMBSRV_TALLOC_IO_PTR(sf, union smb_search_first);
+
        p = req->in.data;
        p += req_pull_ascii4(req, &sf->search_first.in.pattern, 
                             p, STR_TERMINATE);
@@ -181,7 +149,12 @@ void smbsrv_reply_search(struct smbsrv_request *req)
        p += 3;
        
        /* setup state for callback */
-       REQ_TALLOC(state, struct search_state);
+       state = talloc(req, struct search_state);
+       if (!state) {
+               smbsrv_send_error(req, NT_STATUS_NO_MEMORY);
+               return;
+       }
+
        state->req = req;
        state->file = NULL;
        state->last_entry_offset = 0;
@@ -202,7 +175,8 @@ void smbsrv_reply_search(struct smbsrv_request *req)
                }
 
                /* do a search next operation */
-               REQ_TALLOC(sn, union smb_search_next);
+               SMBSRV_TALLOC_IO_PTR(sn, union smb_search_next);
+               SMBSRV_SETUP_NTVFS_REQUEST(reply_search_next_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
                sn->search_next.in.id.reserved      = CVAL(p, 0);
                memcpy(sn->search_next.in.id.name,    p+1, 11);
@@ -214,36 +188,30 @@ void smbsrv_reply_search(struct smbsrv_request *req)
                sn->search_next.in.max_count     = SVAL(req->in.vwv, VWV(0));
                sn->search_next.in.search_attrib = SVAL(req->in.vwv, VWV(1));
 
-               req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-               req->async_states->send_fn = reply_search_next_send;
-               req->async_states->private_data = sn;
-
                /* call backend */
-               req->async_states->status = ntvfs_search_next(req, sn, state, find_callback);
+               SMBSRV_CALL_NTVFS_BACKEND(ntvfs_search_next(req->ntvfs, sn, state, find_callback));
        } else {
+               SMBSRV_SETUP_NTVFS_REQUEST(reply_search_first_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
+
                /* do a search first operation */
                sf->search_first.level = level;
                sf->search_first.in.search_attrib = SVAL(req->in.vwv, VWV(1));
                sf->search_first.in.max_count     = SVAL(req->in.vwv, VWV(0));
 
-               req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-               req->async_states->send_fn = reply_search_first_send;
-               req->async_states->private_data = sf;
-               
-               req->async_states->status = ntvfs_search_first(req, sf, state, find_callback);
+               SMBSRV_CALL_NTVFS_BACKEND(ntvfs_search_first(req->ntvfs, sf, state, find_callback));
        }
-
-       REQ_ASYNC_TAIL;
 }
 
 
 /****************************************************************************
  Reply to a fclose (async reply)
 ****************************************************************************/
-static void reply_fclose_send(struct smbsrv_request *req)
+static void reply_fclose_send(struct ntvfs_request *ntvfs)
 {
-       CHECK_ASYNC_STATUS;
-       
+       struct smbsrv_request *req;
+
+       SMBSRV_CHECK_ASYNC_STATUS_SIMPLE;
+
        /* construct reply */
        smbsrv_setup_reply(req, 1, 0);
 
@@ -263,14 +231,15 @@ void smbsrv_reply_fclose(struct smbsrv_request *req)
        uint8_t *p;
        const char *pattern;
 
-       REQ_TALLOC(sc, union smb_search_close);
-
        /* parse request */
        if (req->in.wct != 2) {
                smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
                return;
        }
-       
+
+       SMBSRV_TALLOC_IO_PTR(sc, union smb_search_close);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_fclose_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
+
        p = req->in.data;
        p += req_pull_ascii4(req, &pattern, p, STR_TERMINATE);
        if (pattern && *pattern) {
@@ -308,13 +277,6 @@ void smbsrv_reply_fclose(struct smbsrv_request *req)
        sc->fclose.in.id.server_cookie = IVAL(p, 13);
        sc->fclose.in.id.client_cookie = IVAL(p, 17);
 
-       /* do a search close operation */
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_fclose_send;
-       req->async_states->private_data = sc;
-
-       /* call backend */
-       req->async_states->status = ntvfs_search_close(req, sc);
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_search_close(req->ntvfs, sc));
 
-       REQ_ASYNC_TAIL;
 }
index 76607a0e0f150413e942824775fa908396187021..13ef268a98d2fbc277061069dc9e359c3113d97c 100644 (file)
@@ -114,10 +114,19 @@ static NTSTATUS make_connection_snum(struct smbsrv_request *req,
                goto failed;
        }
 
-       req->ctx = tcon->ntvfs;
+       req->ntvfs = ntvfs_request_create(req->tcon->ntvfs, req,
+                                         req->session->session_info,
+                                         SVAL(req->in.hdr,HDR_PID),
+                                         SVAL(req->in.hdr,HDR_MID),
+                                         req->request_time,
+                                         req, NULL, 0);
+       if (!req->ntvfs) {
+               status = NT_STATUS_NO_MEMORY;
+               goto failed;
+       }
 
        /* Invoke NTVFS connection hook */
-       status = ntvfs_connect(req, lp_servicename(snum));
+       status = ntvfs_connect(req->ntvfs, lp_servicename(snum));
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("make_connection: NTVFS make connection failed!\n"));
                goto failed;
index e350d6d9e36975389b7479e4333d87d09ed1cf31..1145a08426e49a5984b9295a4749d872764eb1d4 100644 (file)
 #include "ntvfs/ntvfs.h"
 #include "libcli/raw/libcliraw.h"
 
+#define TRANS2_CHECK_ASYNC_STATUS_SIMPLE do { \
+       if (!NT_STATUS_IS_OK(req->ntvfs->async_states->status)) { \
+               trans2_setup_reply(trans, 0, 0, 0);\
+               return req->ntvfs->async_states->status; \
+       } \
+} while (0)
+#define TRANS2_CHECK_ASYNC_STATUS(ptr, type) do { \
+       TRANS2_CHECK_ASYNC_STATUS_SIMPLE; \
+       ptr = talloc_get_type(op->op_info, type); \
+} while (0)
+
 /*
   hold the state of a nttrans op while in progress. Needed to allow for async backend
   functions.
@@ -237,11 +248,7 @@ static NTSTATUS trans2_qfsinfo_send(struct trans_op *op)
        uint_t i;
        DATA_BLOB guid_blob;
 
-       if (!NT_STATUS_IS_OK(req->async_states->status)) {
-               return req->async_states->status;
-       }
-
-       fsinfo = talloc_get_type(op->op_info, union smb_fsinfo);
+       TRANS2_CHECK_ASYNC_STATUS(fsinfo, union smb_fsinfo);
 
        switch (fsinfo->generic.level) {
        case SMB_QFS_ALLOCATION:
@@ -384,43 +391,43 @@ static NTSTATUS trans2_qfsinfo(struct smbsrv_request *req, struct trans_op *op)
        switch (level) {
        case SMB_QFS_ALLOCATION:
                fsinfo->allocation.level = RAW_QFS_ALLOCATION;
-               return ntvfs_fsinfo(req, fsinfo);
+               return ntvfs_fsinfo(req->ntvfs, fsinfo);
 
        case SMB_QFS_VOLUME:
                fsinfo->volume.level = RAW_QFS_VOLUME;
-               return ntvfs_fsinfo(req, fsinfo);
+               return ntvfs_fsinfo(req->ntvfs, fsinfo);
 
        case SMB_QFS_VOLUME_INFO:
        case SMB_QFS_VOLUME_INFORMATION:
                fsinfo->volume_info.level = RAW_QFS_VOLUME_INFO;
-               return ntvfs_fsinfo(req, fsinfo);
+               return ntvfs_fsinfo(req->ntvfs, fsinfo);
 
        case SMB_QFS_SIZE_INFO:
        case SMB_QFS_SIZE_INFORMATION:
                fsinfo->size_info.level = RAW_QFS_SIZE_INFO;
-               return ntvfs_fsinfo(req, fsinfo);
+               return ntvfs_fsinfo(req->ntvfs, fsinfo);
 
        case SMB_QFS_DEVICE_INFO:
        case SMB_QFS_DEVICE_INFORMATION:
                fsinfo->device_info.level = RAW_QFS_DEVICE_INFO;
-               return ntvfs_fsinfo(req, fsinfo);
+               return ntvfs_fsinfo(req->ntvfs, fsinfo);
 
        case SMB_QFS_ATTRIBUTE_INFO:
        case SMB_QFS_ATTRIBUTE_INFORMATION:
                fsinfo->attribute_info.level = RAW_QFS_ATTRIBUTE_INFO;
-               return ntvfs_fsinfo(req, fsinfo);
+               return ntvfs_fsinfo(req->ntvfs, fsinfo);
 
        case SMB_QFS_QUOTA_INFORMATION:
                fsinfo->quota_information.level = RAW_QFS_QUOTA_INFORMATION;
-               return ntvfs_fsinfo(req, fsinfo);
+               return ntvfs_fsinfo(req->ntvfs, fsinfo);
 
        case SMB_QFS_FULL_SIZE_INFORMATION:
                fsinfo->full_size_information.level = RAW_QFS_FULL_SIZE_INFORMATION;
-               return ntvfs_fsinfo(req, fsinfo);
+               return ntvfs_fsinfo(req->ntvfs, fsinfo);
 
        case SMB_QFS_OBJECTID_INFORMATION:
                fsinfo->objectid_information.level = RAW_QFS_OBJECTID_INFORMATION;
-               return ntvfs_fsinfo(req, fsinfo);
+               return ntvfs_fsinfo(req->ntvfs, fsinfo);
        }
 
        return NT_STATUS_INVALID_LEVEL;
@@ -436,11 +443,7 @@ static NTSTATUS trans2_open_send(struct trans_op *op)
        struct smb_trans2 *trans = op->trans;
        union smb_open *io;
 
-       if (!NT_STATUS_IS_OK(req->async_states->status)) {
-               return req->async_states->status;
-       }
-
-       io = talloc_get_type(op->op_info, union smb_open);
+       TRANS2_CHECK_ASYNC_STATUS(io, union smb_open);
 
        trans2_setup_reply(trans, 30, 0, 0);
 
@@ -498,7 +501,7 @@ static NTSTATUS trans2_open(struct smbsrv_request *req, struct trans_op *op)
        op->op_info = io;
        op->send_fn = trans2_open_send;
 
-       return ntvfs_open(req, io);
+       return ntvfs_open(req->ntvfs, io);
 }
 
 
@@ -510,9 +513,7 @@ static NTSTATUS trans2_simple_send(struct trans_op *op)
        struct smbsrv_request *req = op->req;
        struct smb_trans2 *trans = op->trans;
 
-       if (!NT_STATUS_IS_OK(req->async_states->status)) {
-               return req->async_states->status;
-       }
+       TRANS2_CHECK_ASYNC_STATUS_SIMPLE;
 
        trans2_setup_reply(trans, 2, 0, 0);
 
@@ -549,7 +550,7 @@ static NTSTATUS trans2_mkdir(struct smbsrv_request *req, struct trans_op *op)
        op->op_info = io;
        op->send_fn = trans2_simple_send;
 
-       return ntvfs_mkdir(req, io);
+       return ntvfs_mkdir(req->ntvfs, io);
 }
 
 /*
@@ -563,11 +564,7 @@ static NTSTATUS trans2_fileinfo_send(struct trans_op *op)
        uint_t i;
        uint32_t list_size;
 
-       if (!NT_STATUS_IS_OK(req->async_states->status)) {
-               return req->async_states->status;
-       }
-
-       st = talloc_get_type(op->op_info, union smb_fileinfo);
+       TRANS2_CHECK_ASYNC_STATUS(st, union smb_fileinfo);
 
        switch (st->generic.level) {
        case RAW_FILEINFO_GENERIC:
@@ -838,7 +835,7 @@ static NTSTATUS trans2_qpathinfo(struct smbsrv_request *req, struct trans_op *op
        op->op_info = st;
        op->send_fn = trans2_fileinfo_send;
 
-       return ntvfs_qpathinfo(req, st);
+       return ntvfs_qpathinfo(req->ntvfs, st);
 }
 
 
@@ -880,7 +877,7 @@ static NTSTATUS trans2_qfileinfo(struct smbsrv_request *req, struct trans_op *op
        op->op_info = st;
        op->send_fn = trans2_fileinfo_send;
 
-       return ntvfs_qfileinfo(req, st);
+       return ntvfs_qfileinfo(req->ntvfs, st);
 }
 
 
@@ -1014,7 +1011,7 @@ static NTSTATUS trans2_setfileinfo(struct smbsrv_request *req, struct trans_op *
        op->op_info = st;
        op->send_fn = trans2_simple_send;
 
-       return ntvfs_setfileinfo(req, st);
+       return ntvfs_setfileinfo(req->ntvfs, st);
 }
 
 /*
@@ -1054,7 +1051,7 @@ static NTSTATUS trans2_setpathinfo(struct smbsrv_request *req, struct trans_op *
        op->op_info = st;
        op->send_fn = trans2_simple_send;
 
-       return ntvfs_setpathinfo(req, st);
+       return ntvfs_setpathinfo(req->ntvfs, st);
 }
 
 
@@ -1305,12 +1302,7 @@ static NTSTATUS trans2_findfirst_send(struct trans_op *op)
        struct find_state *state;
        uint8_t *param;
 
-       if (!NT_STATUS_IS_OK(req->async_states->status)) {
-               trans2_setup_reply(trans, 0, 0, 0);
-               return req->async_states->status;
-       }
-
-       state = talloc_get_type(op->op_info, struct find_state);
+       TRANS2_CHECK_ASYNC_STATUS(state, struct find_state);
        search = talloc_get_type(state->search, union smb_search_first);
 
        /* fill in the findfirst reply header */
@@ -1383,7 +1375,7 @@ static NTSTATUS trans2_findfirst(struct smbsrv_request *req, struct trans_op *op
        op->op_info = state;
        op->send_fn = trans2_findfirst_send;
 
-       return ntvfs_search_first(req, search, state, find_callback);
+       return ntvfs_search_first(req->ntvfs, search, state, find_callback);
 }
 
 
@@ -1398,12 +1390,7 @@ static NTSTATUS trans2_findnext_send(struct trans_op *op)
        struct find_state *state;
        uint8_t *param;
 
-       if (!NT_STATUS_IS_OK(req->async_states->status)) {
-               trans2_setup_reply(trans, 0, 0, 0);
-               return req->async_states->status;
-       }
-
-       state = talloc_get_type(op->op_info, struct find_state);
+       TRANS2_CHECK_ASYNC_STATUS(state, struct find_state);
        search = talloc_get_type(state->search, union smb_search_next);
 
        /* fill in the findfirst reply header */
@@ -1474,7 +1461,7 @@ static NTSTATUS trans2_findnext(struct smbsrv_request *req, struct trans_op *op)
        op->op_info = state;
        op->send_fn = trans2_findnext_send;
 
-       return ntvfs_search_next(req, search, state, find_callback);
+       return ntvfs_search_next(req->ntvfs, search, state, find_callback);
 }
 
 
@@ -1487,7 +1474,7 @@ static NTSTATUS trans2_backend(struct smbsrv_request *req, struct trans_op *op)
        NTSTATUS status;
 
        /* direct trans2 pass thru */
-       status = ntvfs_trans2(req, trans);
+       status = ntvfs_trans2(req->ntvfs, trans);
        if (!NT_STATUS_EQUAL(NT_STATUS_NOT_IMPLEMENTED, status)) {
                return status;
        }
@@ -1557,20 +1544,16 @@ static void reply_trans_continue(struct smbsrv_request *req, uint8_t command,
 /*
   answer a reconstructed trans request
 */
-static void reply_trans_send(struct smbsrv_request *req)
+static void reply_trans_send(struct ntvfs_request *ntvfs)
 {
+       struct smbsrv_request *req;
        struct trans_op *op;
        struct smb_trans2 *trans;
        uint16_t params_left, data_left;
        uint8_t *params, *data;
        int i;
 
-       if (NT_STATUS_IS_ERR(req->async_states->status)) {
-               smbsrv_send_error(req, req->async_states->status);
-               return;
-       }
-
-       op = talloc_get_type(req->async_states->private_data, struct trans_op);
+       SMBSRV_CHECK_ASYNC_STATUS_ERR(op, struct trans_op);
        trans = op->trans;
 
        /* if this function needs work to form the nttrans reply buffer, then
@@ -1591,8 +1574,8 @@ static void reply_trans_send(struct smbsrv_request *req)
 
        smbsrv_setup_reply(req, 10 + trans->out.setup_count, 0);
 
-       if (!NT_STATUS_IS_OK(req->async_states->status)) {
-               smbsrv_setup_error(req, req->async_states->status);
+       if (!NT_STATUS_IS_OK(req->ntvfs->async_states->status)) {
+               smbsrv_setup_error(req, req->ntvfs->async_states->status);
        }
 
        /* we need to divide up the reply into chunks that fit into
@@ -1670,11 +1653,8 @@ static void reply_trans_complete(struct smbsrv_request *req, uint8_t command,
 {
        struct trans_op *op;
 
-       op = talloc(trans, struct trans_op);
-       if (op == NULL) {
-               smbsrv_send_error(req, NT_STATUS_NO_MEMORY);
-               return;
-       }
+       SMBSRV_TALLOC_IO_PTR(op, struct trans_op);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_trans_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
        op->req         = req;
        op->trans       = trans;
@@ -1682,19 +1662,13 @@ static void reply_trans_complete(struct smbsrv_request *req, uint8_t command,
        op->op_info     = NULL;
        op->send_fn     = NULL;
 
-       req->async_states->state |= NTVFS_ASYNC_STATE_MAY_ASYNC;
-       req->async_states->send_fn = reply_trans_send;
-       req->async_states->private_data = op;
-
        /* its a full request, give it to the backend */
        if (command == SMBtrans) {
-               req->async_states->status = ntvfs_trans(req, trans);
+               SMBSRV_CALL_NTVFS_BACKEND(ntvfs_trans(req->ntvfs, trans));
+               return;
        } else {
-               req->async_states->status = trans2_backend(req, op);
-       }
-
-       if (!(req->async_states->state & NTVFS_ASYNC_STATE_ASYNC)) {
-               req->async_states->send_fn(req);
+               SMBSRV_CALL_NTVFS_BACKEND(trans2_backend(req, op));
+               return;
        }
 }
 
index c266d1b99477445c9b7e3b2d009616083d60e95b..f9a1c49f716bf3489067d7b2430aea3e507b159f 100644 (file)
@@ -128,7 +128,7 @@ struct smbsrv_tcon {
 };
 
 /* a set of flags to control handling of request structures */
-#define REQ_CONTROL_LARGE     (1<<1) /* allow replies larger than max_xmit */
+#define SMBSRV_REQ_CONTROL_LARGE     (1<<1) /* allow replies larger than max_xmit */
 
 /* the context for a single SMB request. This is passed to any request-context 
    functions */
@@ -145,7 +145,7 @@ struct smbsrv_request {
        /* the session context is derived from the vuid */
        struct smbsrv_session *session;
 
-       /* a set of flags to control usage of the request. See REQ_CONTROL_* */
+       /* a set of flags to control usage of the request. See SMBSRV_REQ_CONTROL_* */
        unsigned control_flags;
 
        /* the flags from the SMB request, in raw form (host byte order) */
@@ -164,32 +164,14 @@ struct smbsrv_request {
        /* the sequence number for signing */
        uint64_t seq_num;
 
-       struct request_buffer in;
-       struct request_buffer out;
-
-       /*
-        * the following elemets will be part of a future ntvfs_request struct
-        */
-
-       /* the ntvfs_context this requests belongs to */
-       struct ntvfs_context *ctx;
+       /* a pointer to the per request union smb_* io structure */
+       void *io_ptr;
 
-       /* ntvfs per request async states */
-       struct ntvfs_async_state *async_states;
+       /* the ntvfs_request */
+       struct ntvfs_request *ntvfs;
 
-       /* the session_info, with security_token and maybe delegated credentials */
-       struct auth_session_info *session_info;
-
-       /* the smb pid is needed for locking contexts */
-       uint16_t smbpid;
-
-uint16_t smbmid;
-
-       /* some statictics for the management tools */
-       struct {
-               /* the system time when the request arrived */
-               struct timeval request_time;
-       } statistics;
+       struct request_buffer in;
+       struct request_buffer out;
 };
 
 /* this contains variables that should be used in % substitutions for
@@ -318,3 +300,79 @@ struct smbsrv_connection {
 
 #include "smb_server/smb_server_proto.h"
 #include "smb_server/smb/smb_proto.h"
+
+/* useful way of catching wct errors with file and line number */
+#define SMBSRV_CHECK_WCT(req, wcount) do { \
+       if ((req)->in.wct != (wcount)) { \
+               DEBUG(1,("Unexpected WCT %d at %s(%d) - expected %d\n", \
+                        (req)->in.wct, __FILE__, __LINE__, wcount)); \
+               smbsrv_send_error(req, NT_STATUS_DOS(ERRSRV, ERRerror)); \
+               return; \
+       } \
+} while (0)
+       
+/* useful wrapper for talloc with NO_MEMORY reply */
+#define SMBSRV_TALLOC_IO_PTR(ptr, type) do { \
+       ptr = talloc(req, type); \
+       if (!ptr) { \
+               smbsrv_send_error(req, NT_STATUS_NO_MEMORY); \
+               return; \
+       } \
+       req->io_ptr = ptr; \
+} while (0)
+
+#define SMBSRV_SETUP_NTVFS_REQUEST(send_fn, state) do { \
+       req->ntvfs = ntvfs_request_create(req->tcon->ntvfs, req, \
+                                         req->session->session_info,\
+                                         SVAL(req->in.hdr,HDR_PID), \
+                                         SVAL(req->in.hdr,HDR_MID), \
+                                         req->request_time, \
+                                         req, send_fn, state); \
+       if (!req->ntvfs) { \
+               smbsrv_send_error(req, NT_STATUS_NO_MEMORY); \
+               return; \
+       } \
+       if (!talloc_reference(req->ntvfs, req)) { \
+               smbsrv_send_error(req, NT_STATUS_NO_MEMORY); \
+               return; \
+       } \
+} while (0)
+
+/* 
+   check if the backend wants to handle the request asynchronously.
+   if it wants it handled synchronously then call the send function
+   immediately
+*/
+#define SMBSRV_CALL_NTVFS_BACKEND(cmd) do { \
+       req->ntvfs->async_states->status = cmd; \
+       if (!(req->ntvfs->async_states->state & NTVFS_ASYNC_STATE_ASYNC)) { \
+               req->ntvfs->async_states->send_fn(req->ntvfs); \
+       } \
+} while (0)
+
+/* check req->ntvfs->async_states->status and if not OK then send an error reply */
+#define SMBSRV_CHECK_ASYNC_STATUS_ERR_SIMPLE do { \
+       req = talloc_get_type(ntvfs->async_states->private_data, struct smbsrv_request); \
+       if (NT_STATUS_IS_ERR(ntvfs->async_states->status)) { \
+               smbsrv_send_error(req, ntvfs->async_states->status); \
+               return; \
+       } \
+} while (0)
+#define SMBSRV_CHECK_ASYNC_STATUS_ERR(ptr, type) do { \
+       SMBSRV_CHECK_ASYNC_STATUS_ERR_SIMPLE; \
+       ptr = talloc_get_type(req->io_ptr, type); \
+} while (0)
+#define SMBSRV_CHECK_ASYNC_STATUS_SIMPLE do { \
+       req = talloc_get_type(ntvfs->async_states->private_data, struct smbsrv_request); \
+       if (!NT_STATUS_IS_OK(ntvfs->async_states->status)) { \
+               smbsrv_send_error(req, ntvfs->async_states->status); \
+               return; \
+       } \
+} while (0)
+#define SMBSRV_CHECK_ASYNC_STATUS(ptr, type) do { \
+       SMBSRV_CHECK_ASYNC_STATUS_SIMPLE; \
+       ptr = talloc_get_type(req->io_ptr, type); \
+} while (0)
+
+/* zero out some reserved fields in a reply */
+#define SMBSRV_VWV_RESERVED(start, count) memset(req->out.vwv + VWV(start), 0, (count)*2)