Change uint_t to unsigned int in source4
[samba.git] / source4 / smb_server / smb / reply.c
index c79ad15ea8c1eb5a73a2c0c66f4acd4d69e0fddd..ef7cbbf936b8c38b97b2557a1f0418c0559b3bab 100644 (file)
@@ -7,7 +7,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -16,8 +16,7 @@
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 /*
    This file handles most of the reply_ calls that the server
@@ -44,115 +43,149 @@ static void reply_simple_send(struct ntvfs_request *ntvfs)
 }
 
 
+/****************************************************************************
+ Reply to a tcon (async reply)
+****************************************************************************/
+static void reply_tcon_send(struct ntvfs_request *ntvfs)
+{
+       struct smbsrv_request *req;
+       union smb_tcon *con;
+
+       SMBSRV_CHECK_ASYNC_STATUS(con, union smb_tcon);
+
+       /* construct reply */
+       smbsrv_setup_reply(req, 2, 0);
+
+       SSVAL(req->out.vwv, VWV(0), con->tcon.out.max_xmit);
+       SSVAL(req->out.vwv, VWV(1), con->tcon.out.tid);
+       SSVAL(req->out.hdr, HDR_TID, req->tcon->tid);
+
+       smbsrv_send_reply(req);
+}
+
 /****************************************************************************
  Reply to a tcon.
 ****************************************************************************/
 void smbsrv_reply_tcon(struct smbsrv_request *req)
 {
-       union smb_tcon con;
+       union smb_tcon *con;
        NTSTATUS status;
        uint8_t *p;
        
        /* parse request */
        SMBSRV_CHECK_WCT(req, 0);
 
-       con.tcon.level = RAW_TCON_TCON;
+       SMBSRV_TALLOC_IO_PTR(con, union smb_tcon);
+
+       con->tcon.level = RAW_TCON_TCON;
 
        p = req->in.data;       
-       p += req_pull_ascii4(req, &con.tcon.in.service, p, STR_TERMINATE);
-       p += req_pull_ascii4(req, &con.tcon.in.password, p, STR_TERMINATE);
-       p += req_pull_ascii4(req, &con.tcon.in.dev, p, STR_TERMINATE);
+       p += req_pull_ascii4(&req->in.bufinfo, &con->tcon.in.service, p, STR_TERMINATE);
+       p += req_pull_ascii4(&req->in.bufinfo, &con->tcon.in.password, p, STR_TERMINATE);
+       p += req_pull_ascii4(&req->in.bufinfo, &con->tcon.in.dev, p, STR_TERMINATE);
 
-       if (!con.tcon.in.service || !con.tcon.in.password || !con.tcon.in.dev) {
+       if (!con->tcon.in.service || !con->tcon.in.password || !con->tcon.in.dev) {
                smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
                return;
        }
 
-       /* call backend */
-       status = smbsrv_tcon_backend(req, &con);
-
+       /* Instantiate backend */
+       status = smbsrv_tcon_backend(req, con);
        if (!NT_STATUS_IS_OK(status)) {
                smbsrv_send_error(req, status);
                return;
        }
 
-       /* construct reply */
-       smbsrv_setup_reply(req, 2, 0);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_tcon_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
-       SSVAL(req->out.vwv, VWV(0), con.tcon.out.max_xmit);
-       SSVAL(req->out.vwv, VWV(1), con.tcon.out.tid);
-       SSVAL(req->out.hdr, HDR_TID, req->tcon->tid);
-  
-       smbsrv_send_reply(req);
+       /* Invoke NTVFS connection hook */
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_connect(req->ntvfs, con));
 }
 
 
+/****************************************************************************
+ Reply to a tcon and X (async reply)
+****************************************************************************/
+static void reply_tcon_and_X_send(struct ntvfs_request *ntvfs)
+{
+       struct smbsrv_request *req;
+       union smb_tcon *con;
+
+       SMBSRV_CHECK_ASYNC_STATUS(con, union smb_tcon);
+
+       /* construct reply - two variants */
+       if (req->smb_conn->negotiate.protocol < PROTOCOL_NT1) {
+               smbsrv_setup_reply(req, 2, 0);
+
+               SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
+               SSVAL(req->out.vwv, VWV(1), 0);
+
+               req_push_str(req, NULL, con->tconx.out.dev_type, -1, STR_TERMINATE|STR_ASCII);
+       } else {
+               smbsrv_setup_reply(req, 3, 0);
+
+               SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
+               SSVAL(req->out.vwv, VWV(1), 0);
+               SSVAL(req->out.vwv, VWV(2), con->tconx.out.options);
+
+               req_push_str(req, NULL, con->tconx.out.dev_type, -1, STR_TERMINATE|STR_ASCII);
+               req_push_str(req, NULL, con->tconx.out.fs_type, -1, STR_TERMINATE);
+       }
+
+       /* set the incoming and outgoing tid to the just created one */
+       SSVAL(req->in.hdr, HDR_TID, con->tconx.out.tid);
+       SSVAL(req->out.hdr,HDR_TID, con->tconx.out.tid);
+
+       smbsrv_chain_reply(req);
+}
+
 /****************************************************************************
  Reply to a tcon and X.
 ****************************************************************************/
 void smbsrv_reply_tcon_and_X(struct smbsrv_request *req)
 {
        NTSTATUS status;
-       union smb_tcon con;
+       union smb_tcon *con;
        uint8_t *p;
        uint16_t passlen;
 
-       con.tconx.level = RAW_TCON_TCONX;
+       SMBSRV_TALLOC_IO_PTR(con, union smb_tcon);
+
+       con->tconx.level = RAW_TCON_TCONX;
 
        /* parse request */
        SMBSRV_CHECK_WCT(req, 4);
 
-       con.tconx.in.flags  = SVAL(req->in.vwv, VWV(2));
-       passlen             = SVAL(req->in.vwv, VWV(3));
+       con->tconx.in.flags  = SVAL(req->in.vwv, VWV(2));
+       passlen              = SVAL(req->in.vwv, VWV(3));
 
        p = req->in.data;
 
-       if (!req_pull_blob(req, p, passlen, &con.tconx.in.password)) {
+       if (!req_pull_blob(&req->in.bufinfo, p, passlen, &con->tconx.in.password)) {
                smbsrv_send_error(req, NT_STATUS_ILL_FORMED_PASSWORD);
                return;
        }
        p += passlen;
 
-       p += req_pull_string(req, &con.tconx.in.path, p, -1, STR_TERMINATE);
-       p += req_pull_string(req, &con.tconx.in.device, p, -1, STR_ASCII);
+       p += req_pull_string(&req->in.bufinfo, &con->tconx.in.path, p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &con->tconx.in.device, p, -1, STR_ASCII);
 
-       if (!con.tconx.in.path || !con.tconx.in.device) {
+       if (!con->tconx.in.path || !con->tconx.in.device) {
                smbsrv_send_error(req, NT_STATUS_BAD_DEVICE_TYPE);
                return;
        }
 
-       /* call backend */
-       status = smbsrv_tcon_backend(req, &con);
-
+       /* Instantiate backend */
+       status = smbsrv_tcon_backend(req, con);
        if (!NT_STATUS_IS_OK(status)) {
                smbsrv_send_error(req, status);
                return;
        }
 
-       /* construct reply - two variants */
-       if (req->smb_conn->negotiate.protocol < PROTOCOL_NT1) {
-               smbsrv_setup_reply(req, 2, 0);
+       SMBSRV_SETUP_NTVFS_REQUEST(reply_tcon_and_X_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
-               SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
-               SSVAL(req->out.vwv, VWV(1), 0);
-
-               req_push_str(req, NULL, con.tconx.out.dev_type, -1, STR_TERMINATE|STR_ASCII);
-       } else {
-               smbsrv_setup_reply(req, 3, 0);
-
-               SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
-               SSVAL(req->out.vwv, VWV(1), 0);
-               SSVAL(req->out.vwv, VWV(2), con.tconx.out.options);
-
-               req_push_str(req, NULL, con.tconx.out.dev_type, -1, STR_TERMINATE|STR_ASCII);
-               req_push_str(req, NULL, con.tconx.out.fs_type, -1, STR_TERMINATE);
-       }
-
-       /* set the incoming and outgoing tid to the just created one */
-       SSVAL(req->in.hdr, HDR_TID, con.tconx.out.tid);
-       SSVAL(req->out.hdr,HDR_TID, con.tconx.out.tid);
-
-       smbsrv_chain_reply(req);
+       /* Invoke NTVFS connection hook */
+       SMBSRV_CALL_NTVFS_BACKEND(ntvfs_connect(req->ntvfs, con));
 }
 
 
@@ -224,7 +257,7 @@ void smbsrv_reply_chkpth(struct smbsrv_request *req)
        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_pull_ascii4(&req->in.bufinfo, &io->chkpath.in.path, req->in.data, STR_TERMINATE);
 
        SMBSRV_CALL_NTVFS_BACKEND(ntvfs_chkpath(req->ntvfs, io));
 }
@@ -265,7 +298,7 @@ void smbsrv_reply_getatr(struct smbsrv_request *req)
        st->getattr.level = RAW_FILEINFO_GETATTR;
 
        /* parse request */
-       req_pull_ascii4(req, &st->getattr.in.file.path, req->in.data, STR_TERMINATE);
+       req_pull_ascii4(&req->in.bufinfo, &st->getattr.in.file.path, req->in.data, STR_TERMINATE);
        if (!st->getattr.in.file.path) {
                smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
                return;
@@ -291,7 +324,7 @@ void smbsrv_reply_setatr(struct smbsrv_request *req)
        st->setattr.in.attrib     = SVAL(req->in.vwv, VWV(0));
        st->setattr.in.write_time = srv_pull_dos_date3(req->smb_conn, req->in.vwv + VWV(1));
        
-       req_pull_ascii4(req, &st->setattr.in.file.path, req->in.data, STR_TERMINATE);
+       req_pull_ascii4(&req->in.bufinfo, &st->setattr.in.file.path, req->in.data, STR_TERMINATE);
 
        if (!st->setattr.in.file.path) {
                smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
@@ -380,7 +413,7 @@ void smbsrv_reply_open(struct smbsrv_request *req)
        oi->openold.in.open_mode = SVAL(req->in.vwv, VWV(0));
        oi->openold.in.search_attrs = SVAL(req->in.vwv, VWV(1));
 
-       req_pull_ascii4(req, &oi->openold.in.fname, req->in.data, STR_TERMINATE);
+       req_pull_ascii4(&req->in.bufinfo, &oi->openold.in.fname, req->in.data, STR_TERMINATE);
 
        if (!oi->openold.in.fname) {
                smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
@@ -453,7 +486,7 @@ void smbsrv_reply_open_and_X(struct smbsrv_request *req)
        oi->openx.in.size         = IVAL(req->in.vwv, VWV(9));
        oi->openx.in.timeout      = IVAL(req->in.vwv, VWV(11));
 
-       req_pull_ascii4(req, &oi->openx.in.fname, req->in.data, STR_TERMINATE);
+       req_pull_ascii4(&req->in.bufinfo, &oi->openx.in.fname, req->in.data, STR_TERMINATE);
 
        if (!oi->openx.in.fname) {
                smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
@@ -503,7 +536,7 @@ void smbsrv_reply_mknew(struct smbsrv_request *req)
        oi->mknew.in.attrib  = SVAL(req->in.vwv, VWV(0));
        oi->mknew.in.write_time  = srv_pull_dos_date3(req->smb_conn, req->in.vwv + VWV(1));
 
-       req_pull_ascii4(req, &oi->mknew.in.fname, req->in.data, STR_TERMINATE);
+       req_pull_ascii4(&req->in.bufinfo, &oi->mknew.in.fname, req->in.data, STR_TERMINATE);
 
        if (!oi->mknew.in.fname) {
                smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
@@ -552,7 +585,7 @@ void smbsrv_reply_ctemp(struct smbsrv_request *req)
 
        /* the filename is actually a directory name, the server provides a filename
           in that directory */
-       req_pull_ascii4(req, &oi->ctemp.in.directory, req->in.data, STR_TERMINATE);
+       req_pull_ascii4(&req->in.bufinfo, &oi->ctemp.in.directory, req->in.data, STR_TERMINATE);
 
        if (!oi->ctemp.in.directory) {
                smbsrv_send_error(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
@@ -577,7 +610,7 @@ void smbsrv_reply_unlink(struct smbsrv_request *req)
        
        unl->unlink.in.attrib = SVAL(req->in.vwv, VWV(0));
 
-       req_pull_ascii4(req, &unl->unlink.in.pattern, req->in.data, STR_TERMINATE);
+       req_pull_ascii4(&req->in.bufinfo, &unl->unlink.in.pattern, req->in.data, STR_TERMINATE);
        
        SMBSRV_CALL_NTVFS_BACKEND(ntvfs_unlink(req->ntvfs, unl));
 }
@@ -798,7 +831,8 @@ static void reply_read_and_X_send(struct ntvfs_request *ntvfs)
        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));
-       SMBSRV_VWV_RESERVED(7, 5);
+       SSVAL(req->out.vwv, VWV(7), (io->readx.out.nread>>16));
+       SMBSRV_VWV_RESERVED(8, 4);
 
        smbsrv_chain_reply(req);
 }
@@ -825,9 +859,9 @@ void smbsrv_reply_read_and_X(struct smbsrv_request *req)
        io->readx.in.mincnt        = SVAL(req->in.vwv, VWV(6));
        io->readx.in.remaining     = SVAL(req->in.vwv, VWV(9));
        if (req->flags2 & FLAGS2_READ_PERMIT_EXECUTE) {
-               io->readx.in.read_for_execute = True;
+               io->readx.in.read_for_execute = true;
        } else {
-               io->readx.in.read_for_execute = False;
+               io->readx.in.read_for_execute = false;
        }
 
        if (req->smb_conn->negotiate.client_caps & CAP_LARGE_READX) {
@@ -959,7 +993,7 @@ void smbsrv_reply_write(struct smbsrv_request *req)
        io->write.in.data        = req->in.data + 3;
 
        /* make sure they gave us the data they promised */
-       if (req_data_oob(req, io->write.in.data, io->write.in.count)) {
+       if (req_data_oob(&req->in.bufinfo, io->write.in.data, io->write.in.count)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }
@@ -1028,8 +1062,8 @@ void smbsrv_reply_write_and_X(struct smbsrv_request *req)
        }
 
        /* make sure the data is in bounds */
-       if (req_data_oob(req, io->writex.in.data, io->writex.in.count)) {
-               smbsrv_send_error(req, NT_STATUS_FOOBAR);
+       if (req_data_oob(&req->in.bufinfo, io->writex.in.data, io->writex.in.count)) {
+               smbsrv_send_error(req, NT_STATUS_DOS(ERRSRV, ERRerror));
                return;
        }
 
@@ -1164,7 +1198,7 @@ void smbsrv_reply_writeclose(struct smbsrv_request *req)
        io->writeclose.in.data          = req->in.data + 1;
 
        /* make sure they gave us the data they promised */
-       if (req_data_oob(req, io->writeclose.in.data, io->writeclose.in.count)) {
+       if (req_data_oob(&req->in.bufinfo, io->writeclose.in.data, io->writeclose.in.count)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }
@@ -1314,7 +1348,7 @@ void smbsrv_reply_printopen(struct smbsrv_request *req)
        oi->splopen.in.setup_length = SVAL(req->in.vwv, VWV(0));
        oi->splopen.in.mode         = SVAL(req->in.vwv, VWV(1));
 
-       req_pull_ascii4(req, &oi->splopen.in.ident, req->in.data, STR_TERMINATE);
+       req_pull_ascii4(&req->in.bufinfo, &oi->splopen.in.ident, req->in.data, STR_TERMINATE);
 
        SMBSRV_CALL_NTVFS_BACKEND(ntvfs_open(req->ntvfs, oi));
 }
@@ -1346,7 +1380,7 @@ static void reply_printqueue_send(struct ntvfs_request *ntvfs)
        struct smbsrv_request *req;
        union smb_lpq *lpq;
        int i, maxcount;
-       const uint_t el_size = 28;
+       const unsigned int el_size = 28;
 
        SMBSRV_CHECK_ASYNC_STATUS(lpq,union smb_lpq);
 
@@ -1427,7 +1461,7 @@ void smbsrv_reply_printwrite(struct smbsrv_request *req)
        io->splwrite.in.data            = req->in.data + 3;
 
        /* make sure they gave us the data they promised */
-       if (req_data_oob(req, io->splwrite.in.data, io->splwrite.in.count)) {
+       if (req_data_oob(&req->in.bufinfo, io->splwrite.in.data, io->splwrite.in.count)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }
@@ -1450,7 +1484,7 @@ void smbsrv_reply_mkdir(struct smbsrv_request *req)
        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_pull_ascii4(&req->in.bufinfo, &io->mkdir.in.path, req->in.data, STR_TERMINATE);
 
        SMBSRV_CALL_NTVFS_BACKEND(ntvfs_mkdir(req->ntvfs, io));
 }
@@ -1468,7 +1502,7 @@ void smbsrv_reply_rmdir(struct smbsrv_request *req)
        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_pull_ascii4(&req->in.bufinfo, &io->in.path, req->in.data, STR_TERMINATE);
 
        SMBSRV_CALL_NTVFS_BACKEND(ntvfs_rmdir(req->ntvfs, io));
 }
@@ -1491,8 +1525,8 @@ void smbsrv_reply_mv(struct smbsrv_request *req)
        io->rename.in.attrib = SVAL(req->in.vwv, VWV(0));
 
        p = req->in.data;
-       p += req_pull_ascii4(req, &io->rename.in.pattern1, p, STR_TERMINATE);
-       p += req_pull_ascii4(req, &io->rename.in.pattern2, p, STR_TERMINATE);
+       p += req_pull_ascii4(&req->in.bufinfo, &io->rename.in.pattern1, p, STR_TERMINATE);
+       p += req_pull_ascii4(&req->in.bufinfo, &io->rename.in.pattern2, p, STR_TERMINATE);
 
        if (!io->rename.in.pattern1 || !io->rename.in.pattern2) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
@@ -1522,8 +1556,8 @@ void smbsrv_reply_ntrename(struct smbsrv_request *req)
        io->ntrename.in.cluster_size = IVAL(req->in.vwv, VWV(2));
 
        p = req->in.data;
-       p += req_pull_ascii4(req, &io->ntrename.in.old_name, p, STR_TERMINATE);
-       p += req_pull_ascii4(req, &io->ntrename.in.new_name, p, STR_TERMINATE);
+       p += req_pull_ascii4(&req->in.bufinfo, &io->ntrename.in.old_name, p, STR_TERMINATE);
+       p += req_pull_ascii4(&req->in.bufinfo, &io->ntrename.in.new_name, p, STR_TERMINATE);
 
        if (!io->ntrename.in.old_name || !io->ntrename.in.new_name) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
@@ -1569,8 +1603,8 @@ void smbsrv_reply_copy(struct smbsrv_request *req)
        cp->in.flags = SVAL(req->in.vwv, VWV(2));
 
        p = req->in.data;
-       p += req_pull_ascii4(req, &cp->in.path1, p, STR_TERMINATE);
-       p += req_pull_ascii4(req, &cp->in.path2, p, STR_TERMINATE);
+       p += req_pull_ascii4(&req->in.bufinfo, &cp->in.path1, p, STR_TERMINATE);
+       p += req_pull_ascii4(&req->in.bufinfo, &cp->in.path2, p, STR_TERMINATE);
 
        if (!cp->in.path1 || !cp->in.path2) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
@@ -1613,8 +1647,8 @@ static void reply_lockingX_send(struct ntvfs_request *ntvfs)
 void smbsrv_reply_lockingX(struct smbsrv_request *req)
 {
        union smb_lock *lck;
-       uint_t total_locks, i;
-       uint_t lck_size;
+       unsigned int total_locks, i;
+       unsigned int lck_size;
        uint8_t *p;
 
        /* parse request */
@@ -1639,7 +1673,7 @@ void smbsrv_reply_lockingX(struct smbsrv_request *req)
        }
 
        /* make sure we got the promised data */
-       if (req_data_oob(req, req->in.data, total_locks * lck_size)) {
+       if (req_data_oob(&req->in.bufinfo, req->in.data, total_locks * lck_size)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }
@@ -1776,132 +1810,177 @@ void smbsrv_reply_getattrE(struct smbsrv_request *req)
        SMBSRV_CALL_NTVFS_BACKEND(ntvfs_qfileinfo(req->ntvfs, info));
 }
 
+void smbsrv_reply_sesssetup_send(struct smbsrv_request *req,
+                                union smb_sesssetup *io,
+                                NTSTATUS status)
+{
+       switch (io->old.level) {
+       case RAW_SESSSETUP_OLD:
+               if (!NT_STATUS_IS_OK(status)) {
+                       smbsrv_send_error(req, status);
+                       return;
+               }
+
+               /* construct reply */
+               smbsrv_setup_reply(req, 3, 0);
+
+               SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
+               SSVAL(req->out.vwv, VWV(1), 0);
+               SSVAL(req->out.vwv, VWV(2), io->old.out.action);
+
+               SSVAL(req->out.hdr, HDR_UID, io->old.out.vuid);
+
+               smbsrv_chain_reply(req);
+               return;
+
+       case RAW_SESSSETUP_NT1:
+               if (!NT_STATUS_IS_OK(status)) {
+                       smbsrv_send_error(req, status);
+                       return;
+               }
+
+               /* construct reply */
+               smbsrv_setup_reply(req, 3, 0);
+
+               SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
+               SSVAL(req->out.vwv, VWV(1), 0);
+               SSVAL(req->out.vwv, VWV(2), io->nt1.out.action);
+
+               SSVAL(req->out.hdr, HDR_UID, io->nt1.out.vuid);
+
+               req_push_str(req, NULL, io->nt1.out.os, -1, STR_TERMINATE);
+               req_push_str(req, NULL, io->nt1.out.lanman, -1, STR_TERMINATE);
+               req_push_str(req, NULL, io->nt1.out.domain, -1, STR_TERMINATE);
+
+               smbsrv_chain_reply(req);
+               return;
+
+       case RAW_SESSSETUP_SPNEGO:
+               if (!NT_STATUS_IS_OK(status) && 
+                   !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+                       smbsrv_send_error(req, status);
+                       return;
+               }
+
+               /* construct reply */
+               smbsrv_setup_reply(req, 4, io->spnego.out.secblob.length);
+
+               if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+                       smbsrv_setup_error(req, status);
+               }
+
+               SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
+               SSVAL(req->out.vwv, VWV(1), 0);
+               SSVAL(req->out.vwv, VWV(2), io->spnego.out.action);
+               SSVAL(req->out.vwv, VWV(3), io->spnego.out.secblob.length);
+
+               SSVAL(req->out.hdr, HDR_UID, io->spnego.out.vuid);
+
+               memcpy(req->out.data, io->spnego.out.secblob.data, io->spnego.out.secblob.length);
+               req_push_str(req, NULL, io->spnego.out.os,        -1, STR_TERMINATE);
+               req_push_str(req, NULL, io->spnego.out.lanman,    -1, STR_TERMINATE);
+               req_push_str(req, NULL, io->spnego.out.workgroup, -1, STR_TERMINATE);
+
+               smbsrv_chain_reply(req);
+               return;
+
+       case RAW_SESSSETUP_SMB2:
+               break;
+       }
+
+       smbsrv_send_error(req, NT_STATUS_INTERNAL_ERROR);
+}
 
 /****************************************************************************
 reply to an old style session setup command
 ****************************************************************************/
 static void reply_sesssetup_old(struct smbsrv_request *req)
 {
-       NTSTATUS status;
-       union smb_sesssetup sess;
        uint8_t *p;
        uint16_t passlen;
+       union smb_sesssetup *io;
 
-       sess.old.level = RAW_SESSSETUP_OLD;
+       SMBSRV_TALLOC_IO_PTR(io, union smb_sesssetup);
+
+       io->old.level = RAW_SESSSETUP_OLD;
 
        /* parse request */
-       sess.old.in.bufsize = SVAL(req->in.vwv, VWV(2));
-       sess.old.in.mpx_max = SVAL(req->in.vwv, VWV(3));
-       sess.old.in.vc_num  = SVAL(req->in.vwv, VWV(4));
-       sess.old.in.sesskey = IVAL(req->in.vwv, VWV(5));
-       passlen             = SVAL(req->in.vwv, VWV(7));
+       io->old.in.bufsize = SVAL(req->in.vwv, VWV(2));
+       io->old.in.mpx_max = SVAL(req->in.vwv, VWV(3));
+       io->old.in.vc_num  = SVAL(req->in.vwv, VWV(4));
+       io->old.in.sesskey = IVAL(req->in.vwv, VWV(5));
+       passlen            = SVAL(req->in.vwv, VWV(7));
 
        /* check the request isn't malformed */
-       if (req_data_oob(req, req->in.data, passlen)) {
+       if (req_data_oob(&req->in.bufinfo, req->in.data, passlen)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }
        
        p = req->in.data;
-       if (!req_pull_blob(req, p, passlen, &sess.old.in.password)) {
+       if (!req_pull_blob(&req->in.bufinfo, p, passlen, &io->old.in.password)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }
        p += passlen;
        
-       p += req_pull_string(req, &sess.old.in.user,   p, -1, STR_TERMINATE);
-       p += req_pull_string(req, &sess.old.in.domain, p, -1, STR_TERMINATE);
-       p += req_pull_string(req, &sess.old.in.os,     p, -1, STR_TERMINATE);
-       p += req_pull_string(req, &sess.old.in.lanman, p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &io->old.in.user,   p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &io->old.in.domain, p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &io->old.in.os,     p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &io->old.in.lanman, p, -1, STR_TERMINATE);
 
        /* call the generic handler */
-       status = smbsrv_sesssetup_backend(req, &sess);
-
-       if (!NT_STATUS_IS_OK(status)) {
-               smbsrv_send_error(req, status);
-               return;
-       }
-
-       /* construct reply */
-       smbsrv_setup_reply(req, 3, 0);
-
-       SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
-       SSVAL(req->out.vwv, VWV(1), 0);
-       SSVAL(req->out.vwv, VWV(2), sess.old.out.action);
-
-       SSVAL(req->out.hdr, HDR_UID, sess.old.out.vuid);
-
-       smbsrv_chain_reply(req);
+       smbsrv_sesssetup_backend(req, io);
 }
 
-
 /****************************************************************************
 reply to an NT1 style session setup command
 ****************************************************************************/
 static void reply_sesssetup_nt1(struct smbsrv_request *req)
 {
-       NTSTATUS status;
-       union smb_sesssetup sess;
        uint8_t *p;
        uint16_t passlen1, passlen2;
+       union smb_sesssetup *io;
+
+       SMBSRV_TALLOC_IO_PTR(io, union smb_sesssetup);
 
-       sess.nt1.level = RAW_SESSSETUP_NT1;
+       io->nt1.level = RAW_SESSSETUP_NT1;
 
        /* parse request */
-       sess.nt1.in.bufsize      = SVAL(req->in.vwv, VWV(2));
-       sess.nt1.in.mpx_max      = SVAL(req->in.vwv, VWV(3));
-       sess.nt1.in.vc_num       = SVAL(req->in.vwv, VWV(4));
-       sess.nt1.in.sesskey      = IVAL(req->in.vwv, VWV(5));
-       passlen1                 = SVAL(req->in.vwv, VWV(7));
-       passlen2                 = SVAL(req->in.vwv, VWV(8));
-       sess.nt1.in.capabilities = IVAL(req->in.vwv, VWV(11));
+       io->nt1.in.bufsize      = SVAL(req->in.vwv, VWV(2));
+       io->nt1.in.mpx_max      = SVAL(req->in.vwv, VWV(3));
+       io->nt1.in.vc_num       = SVAL(req->in.vwv, VWV(4));
+       io->nt1.in.sesskey      = IVAL(req->in.vwv, VWV(5));
+       passlen1                = SVAL(req->in.vwv, VWV(7));
+       passlen2                = SVAL(req->in.vwv, VWV(8));
+       io->nt1.in.capabilities = IVAL(req->in.vwv, VWV(11));
 
        /* check the request isn't malformed */
-       if (req_data_oob(req, req->in.data, passlen1) ||
-           req_data_oob(req, req->in.data + passlen1, passlen2)) {
+       if (req_data_oob(&req->in.bufinfo, req->in.data, passlen1) ||
+           req_data_oob(&req->in.bufinfo, req->in.data + passlen1, passlen2)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }
        
        p = req->in.data;
-       if (!req_pull_blob(req, p, passlen1, &sess.nt1.in.password1)) {
+       if (!req_pull_blob(&req->in.bufinfo, p, passlen1, &io->nt1.in.password1)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }
        p += passlen1;
-       if (!req_pull_blob(req, p, passlen2, &sess.nt1.in.password2)) {
+       if (!req_pull_blob(&req->in.bufinfo, p, passlen2, &io->nt1.in.password2)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }
        p += passlen2;
        
-       p += req_pull_string(req, &sess.nt1.in.user,   p, -1, STR_TERMINATE);
-       p += req_pull_string(req, &sess.nt1.in.domain, p, -1, STR_TERMINATE);
-       p += req_pull_string(req, &sess.nt1.in.os,     p, -1, STR_TERMINATE);
-       p += req_pull_string(req, &sess.nt1.in.lanman, p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &io->nt1.in.user,   p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &io->nt1.in.domain, p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &io->nt1.in.os,     p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &io->nt1.in.lanman, p, -1, STR_TERMINATE);
 
        /* call the generic handler */
-       status = smbsrv_sesssetup_backend(req, &sess);
-
-       if (!NT_STATUS_IS_OK(status)) {
-               smbsrv_send_error(req, status);
-               return;
-       }
-
-       /* construct reply */
-       smbsrv_setup_reply(req, 3, 0);
-
-       SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
-       SSVAL(req->out.vwv, VWV(1), 0);
-       SSVAL(req->out.vwv, VWV(2), sess.nt1.out.action);
-
-       SSVAL(req->out.hdr, HDR_UID, sess.nt1.out.vuid);
-
-       req_push_str(req, NULL, sess.nt1.out.os, -1, STR_TERMINATE);
-       req_push_str(req, NULL, sess.nt1.out.lanman, -1, STR_TERMINATE);
-       req_push_str(req, NULL, sess.nt1.out.domain, -1, STR_TERMINATE);
-
-       smbsrv_chain_reply(req);
+       smbsrv_sesssetup_backend(req, io);
 }
 
 
@@ -1910,61 +1989,35 @@ reply to an SPNEGO style session setup command
 ****************************************************************************/
 static void reply_sesssetup_spnego(struct smbsrv_request *req)
 {
-       NTSTATUS status;
-       union smb_sesssetup sess;
        uint8_t *p;
        uint16_t blob_len;
+       union smb_sesssetup *io;
+
+       SMBSRV_TALLOC_IO_PTR(io, union smb_sesssetup);
 
-       sess.spnego.level = RAW_SESSSETUP_SPNEGO;
+       io->spnego.level = RAW_SESSSETUP_SPNEGO;
 
        /* parse request */
-       sess.spnego.in.bufsize      = SVAL(req->in.vwv, VWV(2));
-       sess.spnego.in.mpx_max      = SVAL(req->in.vwv, VWV(3));
-       sess.spnego.in.vc_num       = SVAL(req->in.vwv, VWV(4));
-       sess.spnego.in.sesskey      = IVAL(req->in.vwv, VWV(5));
-       blob_len                    = SVAL(req->in.vwv, VWV(7));
-       sess.spnego.in.capabilities = IVAL(req->in.vwv, VWV(10));
+       io->spnego.in.bufsize      = SVAL(req->in.vwv, VWV(2));
+       io->spnego.in.mpx_max      = SVAL(req->in.vwv, VWV(3));
+       io->spnego.in.vc_num       = SVAL(req->in.vwv, VWV(4));
+       io->spnego.in.sesskey      = IVAL(req->in.vwv, VWV(5));
+       blob_len                   = SVAL(req->in.vwv, VWV(7));
+       io->spnego.in.capabilities = IVAL(req->in.vwv, VWV(10));
 
        p = req->in.data;
-       if (!req_pull_blob(req, p, blob_len, &sess.spnego.in.secblob)) {
+       if (!req_pull_blob(&req->in.bufinfo, p, blob_len, &io->spnego.in.secblob)) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
        }
        p += blob_len;
        
-       p += req_pull_string(req, &sess.spnego.in.os,        p, -1, STR_TERMINATE);
-       p += req_pull_string(req, &sess.spnego.in.lanman,    p, -1, STR_TERMINATE);
-       p += req_pull_string(req, &sess.spnego.in.workgroup, p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &io->spnego.in.os,        p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &io->spnego.in.lanman,    p, -1, STR_TERMINATE);
+       p += req_pull_string(&req->in.bufinfo, &io->spnego.in.workgroup, p, -1, STR_TERMINATE);
 
        /* call the generic handler */
-       status = smbsrv_sesssetup_backend(req, &sess);
-
-       if (!NT_STATUS_IS_OK(status) && 
-           !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
-               smbsrv_send_error(req, status);
-               return;
-       }
-
-       /* construct reply */
-       smbsrv_setup_reply(req, 4, sess.spnego.out.secblob.length);
-
-       if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
-               smbsrv_setup_error(req, status);
-       }
-
-       SSVAL(req->out.vwv, VWV(0), SMB_CHAIN_NONE);
-       SSVAL(req->out.vwv, VWV(1), 0);
-       SSVAL(req->out.vwv, VWV(2), sess.spnego.out.action);
-       SSVAL(req->out.vwv, VWV(3), sess.spnego.out.secblob.length);
-
-       SSVAL(req->out.hdr, HDR_UID, sess.spnego.out.vuid);
-
-       memcpy(req->out.data, sess.spnego.out.secblob.data, sess.spnego.out.secblob.length);
-       req_push_str(req, NULL, sess.spnego.out.os,        -1, STR_TERMINATE);
-       req_push_str(req, NULL, sess.spnego.out.lanman,    -1, STR_TERMINATE);
-       req_push_str(req, NULL, sess.spnego.out.workgroup, -1, STR_TERMINATE);
-
-       smbsrv_chain_reply(req);
+       smbsrv_sesssetup_backend(req, io);
 }
 
 
@@ -2163,7 +2216,7 @@ void smbsrv_reply_ntcreate_and_X(struct smbsrv_request *req)
        /* notice that the word parameters are not word aligned, so we don't use VWV() */
        fname_len =                         SVAL(req->in.vwv, 5);
        io->ntcreatex.in.flags =            IVAL(req->in.vwv, 7);
-       io->ntcreatex.in.root_fid =         IVAL(req->in.vwv, 11);
+       io->ntcreatex.in.root_fid.ntvfs =   smbsrv_pull_fnum(req, req->in.vwv, 11);
        io->ntcreatex.in.access_mask =      IVAL(req->in.vwv, 15);
        io->ntcreatex.in.alloc_size =       BVAL(req->in.vwv, 19);
        io->ntcreatex.in.file_attr =        IVAL(req->in.vwv, 27);
@@ -2174,6 +2227,13 @@ void smbsrv_reply_ntcreate_and_X(struct smbsrv_request *req)
        io->ntcreatex.in.security_flags =   CVAL(req->in.vwv, 47);
        io->ntcreatex.in.ea_list          = NULL;
        io->ntcreatex.in.sec_desc         = NULL;
+       io->ntcreatex.in.query_maximal_access = false;
+
+       /* we use a couple of bits of the create options internally */
+       if (io->ntcreatex.in.create_options & NTCREATEX_OPTIONS_PRIVATE_MASK) {
+               smbsrv_send_error(req, NT_STATUS_INVALID_PARAMETER);
+               return;
+       }
 
        /* we need a neater way to handle this alignment */
        if ((req->flags2 & FLAGS2_UNICODE_STRINGS) && 
@@ -2181,7 +2241,7 @@ void smbsrv_reply_ntcreate_and_X(struct smbsrv_request *req)
                fname_len++;
        }
 
-       req_pull_string(req, &io->ntcreatex.in.fname, req->in.data, fname_len, STR_TERMINATE);
+       req_pull_string(&req->in.bufinfo, &io->ntcreatex.in.fname, req->in.data, fname_len, STR_TERMINATE);
        if (!io->ntcreatex.in.fname) {
                smbsrv_send_error(req, NT_STATUS_FOOBAR);
                return;
@@ -2197,12 +2257,15 @@ void smbsrv_reply_ntcreate_and_X(struct smbsrv_request *req)
 void smbsrv_reply_ntcancel(struct smbsrv_request *req)
 {
        struct smbsrv_request *r;
+       uint16_t tid = SVAL(req->in.hdr,HDR_TID);
+       uint16_t uid = SVAL(req->in.hdr,HDR_UID);
        uint16_t mid = SVAL(req->in.hdr,HDR_MID);
        uint16_t pid = SVAL(req->in.hdr,HDR_PID);
 
        for (r = req->smb_conn->requests; r; r = r->next) {
+               if (tid != SVAL(r->in.hdr,HDR_TID)) continue;
+               if (uid != SVAL(r->in.hdr,HDR_UID)) continue;
                if (mid != SVAL(r->in.hdr,HDR_MID)) continue;
-               /* do we really need to check the PID? */
                if (pid != SVAL(r->in.hdr,HDR_PID)) continue;
 
                SMBSRV_CHECK(ntvfs_cancel(r->ntvfs));
@@ -2212,8 +2275,12 @@ void smbsrv_reply_ntcancel(struct smbsrv_request *req)
                return;
        }
 
-       /* TODO: workout the correct error code */
-       smbsrv_send_error(req, NT_STATUS_FOOBAR);
+       /* TODO: workout the correct error code,
+        *       until we know how the smb signing works
+        *       for ntcancel replies, don't send an error
+        */
+       /*smbsrv_send_error(req, NT_STATUS_FOOBAR);*/
+       talloc_free(req);
 }
 
 /*
@@ -2247,7 +2314,7 @@ static NTSTATUS parse_session_request(struct smbsrv_request *req)
                                    req->smb_conn->negotiate.calling_name);
        NT_STATUS_NOT_OK_RETURN(status);
 
-       req->smb_conn->negotiate.done_nbt_session = True;
+       req->smb_conn->negotiate.done_nbt_session = true;
 
        return NT_STATUS_OK;
 }