The branch, master has been updated
       via  cad1d0b torture3: Reproducer for bug 10593
       via  713518a smbd: Fix bug 10593
       via  0c2e763 smbd: First watch, then defer
       via  0ead434 smbd: Store "struct deferred_open_record" instead of 
anonymous data on pml
       via  01c197d libsmb: Make cli_ntcreate cancellable
       via  bb6b31d libsmb: Make cli_ntcreate1 cancellable
       via  c597c93 libsmb: Make cli_smb2_create_fnum cancellable
       via  0a2209c libsmb: Make smb2cli_create cancellable
       via  5aeebc3 libsmb: Enable oplocks for smb2 cli_ntcreate
       via  7882762 libsmb: Align cli_ntcreate with other sync wrappers
       via  700b439 libsmb: remove smb2 switch from cli_ntcreate
       via  37f8cb1 libsmb: Replace async cli_ntcreate by cli_create
       via  891e63b libsmb: Add cli_create_send/recv
       via  f0876ff libsmb: Make cli_smb2_create_fnum async
      from  f52158d torture: add FSRVP share snapshot ACL test

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit cad1d0b048d641cb4ae53424b89ca07ab8f4216e
Author: Volker Lendecke <[email protected]>
Date:   Thu Jun 19 14:37:40 2014 +0000

    torture3: Reproducer for bug 10593
    
    We panic if we get an oplock break response for a cancelled create request
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>
    
    Autobuild-User(master): Volker Lendecke <[email protected]>
    Autobuild-Date(master): Sat Jun 21 23:05:47 CEST 2014 on sn-devel-104

commit 713518a4c85172973611cf99b77ba4fe631fb850
Author: Volker Lendecke <[email protected]>
Date:   Fri Jun 20 14:15:54 2014 +0000

    smbd: Fix bug 10593
    
    Bug 10593 is a panic that happens if we get an oplock break reply via
    dbwrap_watch for which we can't find the SMB request anymore. This
    error condition can legally happen when a client cancels the create
    request before the oplock break response comes in. This patch drops the
    dbwrap_watch_send request waiting for the oplock break when the request
    is cancelled. Yet another talloc hierarchy problem, but if done right,
    talloc hierarchies can make rundown of state easy :-)
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 0c2e763aaa05f63bb8563e62f9731e35afa9ed86
Author: Volker Lendecke <[email protected]>
Date:   Fri Jun 20 14:15:19 2014 +0000

    smbd: First watch, then defer
    
    We exit if any of these if-statement fails, so a simple swap should not
    make a difference.
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 0ead434b84a7c3226ac223acc79ad0e794da3877
Author: Volker Lendecke <[email protected]>
Date:   Fri Jun 20 14:12:14 2014 +0000

    smbd: Store "struct deferred_open_record" instead of anonymous data on pml
    
    The main point is to get a talloc parent that will go away when the
    request is cancelled
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 01c197dc159297d9abdc62f0d2f69d4724b9fc5c
Author: Volker Lendecke <[email protected]>
Date:   Fri Jun 20 10:38:36 2014 +0000

    libsmb: Make cli_ntcreate cancellable
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit bb6b31dd866b0a06e2026f072db8c61a8a986ab6
Author: Volker Lendecke <[email protected]>
Date:   Fri Jun 20 10:38:10 2014 +0000

    libsmb: Make cli_ntcreate1 cancellable
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit c597c9344ca7630335d8fad1ddb4466b01eb9aff
Author: Volker Lendecke <[email protected]>
Date:   Fri Jun 20 10:37:46 2014 +0000

    libsmb: Make cli_smb2_create_fnum cancellable
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 0a2209c1611f318b546ff08348c6579991579cb9
Author: Volker Lendecke <[email protected]>
Date:   Fri Jun 20 10:37:14 2014 +0000

    libsmb: Make smb2cli_create cancellable
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 5aeebc3eb04245a059a3cffde649b0437aa1e332
Author: Volker Lendecke <[email protected]>
Date:   Fri Jun 20 09:55:04 2014 +0000

    libsmb: Enable oplocks for smb2 cli_ntcreate
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 78827623eb9ebf96df13dfbe8e1a0ec3aa6d16a3
Author: Volker Lendecke <[email protected]>
Date:   Fri Jun 20 08:53:49 2014 +0000

    libsmb: Align cli_ntcreate with other sync wrappers
    
    ... saves 5 lines :-)
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 700b43940a6984fb4e4e4b7ad96804501cf71bca
Author: Volker Lendecke <[email protected]>
Date:   Fri Jun 20 08:52:45 2014 +0000

    libsmb: remove smb2 switch from cli_ntcreate
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 37f8cb104f9c0a8d5c1bfdb407567626aa6e226b
Author: Volker Lendecke <[email protected]>
Date:   Fri Jun 20 08:50:17 2014 +0000

    libsmb: Replace async cli_ntcreate by cli_create
    
    Done by rename cli_ntcreate_send/recv to cli_ntcreate1_send/recv and
    cli_create_send/recv to cli_ntcreate_send/recv
    
    Possibly cli_create might be the better name, but I am sooo used to
    cli_ntcreate() that I don't really want to rename this ;-)
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit 891e63b4bef9ca28fedd311a0e02192e9a0ded19
Author: Volker Lendecke <[email protected]>
Date:   Fri Jun 20 08:41:59 2014 +0000

    libsmb: Add cli_create_send/recv
    
    Async wrapper around smb1 and smb2 create
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

commit f0876ff68a664ab5dd10ae77cddf2186e8a39768
Author: Volker Lendecke <[email protected]>
Date:   Fri Jun 20 08:23:47 2014 +0000

    libsmb: Make cli_smb2_create_fnum async
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>

-----------------------------------------------------------------------

Summary of changes:
 libcli/smb/smb2cli_create.c          |   13 +++
 source3/libsmb/cli_smb2_fnum.c       |  177 +++++++++++++++++++++++++-------
 source3/libsmb/cli_smb2_fnum.h       |   12 ++
 source3/libsmb/clifile.c             |  187 ++++++++++++++++++++++++++--------
 source3/selftest/tests.py            |    6 +
 source3/smbd/globals.h               |   13 ++-
 source3/smbd/open.c                  |   31 ++++--
 source3/smbd/process.c               |   30 ++----
 source3/smbd/proto.h                 |   14 ++--
 source3/smbd/smb2_create.c           |   19 ++--
 source3/torture/proto.h              |    1 +
 source3/torture/test_oplock_cancel.c |  159 +++++++++++++++++++++++++++++
 source3/torture/torture.c            |    1 +
 source3/wscript_build                |    1 +
 14 files changed, 527 insertions(+), 137 deletions(-)
 create mode 100644 source3/torture/test_oplock_cancel.c


Changeset truncated at 500 lines:

diff --git a/libcli/smb/smb2cli_create.c b/libcli/smb/smb2cli_create.c
index 834a881..bcd674e 100644
--- a/libcli/smb/smb2cli_create.c
+++ b/libcli/smb/smb2cli_create.c
@@ -31,9 +31,11 @@ struct smb2cli_create_state {
        uint64_t fid_volatile;
        struct smb_create_returns cr;
        struct smb2_create_blobs blobs;
+       struct tevent_req *subreq;
 };
 
 static void smb2cli_create_done(struct tevent_req *subreq);
+static bool smb2cli_create_cancel(struct tevent_req *req);
 
 struct tevent_req *smb2cli_create_send(
        TALLOC_CTX *mem_ctx,
@@ -159,9 +161,20 @@ struct tevent_req *smb2cli_create_send(
                return tevent_req_post(req, ev);
        }
        tevent_req_set_callback(subreq, smb2cli_create_done, req);
+
+       state->subreq = subreq;
+       tevent_req_set_cancel_fn(req, smb2cli_create_cancel);
+
        return req;
 }
 
+static bool smb2cli_create_cancel(struct tevent_req *req)
+{
+       struct smb2cli_create_state *state = tevent_req_data(req,
+               struct smb2cli_create_state);
+       return tevent_req_cancel(state->subreq);
+}
+
 static void smb2cli_create_done(struct tevent_req *subreq)
 {
        struct tevent_req *req =
diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c
index 950398a..87edf4e 100644
--- a/source3/libsmb/cli_smb2_fnum.c
+++ b/source3/libsmb/cli_smb2_fnum.c
@@ -151,32 +151,42 @@ static uint8_t flags_to_smb2_oplock(uint32_t create_flags)
 
 /***************************************************************
  Small wrapper that allows SMB2 create to return a uint16_t fnum.
- Synchronous only.
 ***************************************************************/
 
-NTSTATUS cli_smb2_create_fnum(struct cli_state *cli,
-                       const char *fname,
-                       uint32_t create_flags,
-                       uint32_t desired_access,
-                       uint32_t file_attributes,
-                       uint32_t share_access,
-                       uint32_t create_disposition,
-                       uint32_t create_options,
-                       uint16_t *pfid,
-                       struct smb_create_returns *cr)
+struct cli_smb2_create_fnum_state {
+       struct cli_state *cli;
+       struct smb_create_returns cr;
+       uint16_t fnum;
+       struct tevent_req *subreq;
+};
+
+static void cli_smb2_create_fnum_done(struct tevent_req *subreq);
+static bool cli_smb2_create_fnum_cancel(struct tevent_req *req);
+
+struct tevent_req *cli_smb2_create_fnum_send(TALLOC_CTX *mem_ctx,
+                                            struct tevent_context *ev,
+                                            struct cli_state *cli,
+                                            const char *fname,
+                                            uint32_t create_flags,
+                                            uint32_t desired_access,
+                                            uint32_t file_attributes,
+                                            uint32_t share_access,
+                                            uint32_t create_disposition,
+                                            uint32_t create_options)
 {
-       NTSTATUS status;
-       struct smb2_hnd h;
+       struct tevent_req *req, *subreq;
+       struct cli_smb2_create_fnum_state *state;
 
-       if (smbXcli_conn_has_async_calls(cli->conn)) {
-               /*
-                * Can't use sync call while an async call is in flight
-                */
-               return NT_STATUS_INVALID_PARAMETER;
+       req = tevent_req_create(mem_ctx, &state,
+                               struct cli_smb2_create_fnum_state);
+       if (req == NULL) {
+               return NULL;
        }
+       state->cli = cli;
 
        if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_SMB2_02) {
-               return NT_STATUS_INVALID_PARAMETER;
+               tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return tevent_req_post(req, ev);
        }
 
        if (cli->backup_intent) {
@@ -189,27 +199,120 @@ NTSTATUS cli_smb2_create_fnum(struct cli_state *cli,
                fname++;
        }
 
-       status = smb2cli_create(cli->conn,
-                               cli->timeout,
-                               cli->smb2.session,
-                               cli->smb2.tcon,
-                               fname,
-                               flags_to_smb2_oplock(create_flags),
-                               SMB2_IMPERSONATION_IMPERSONATION,
-                               desired_access,
-                               file_attributes,
-                               share_access,
-                               create_disposition,
-                               create_options,
-                               NULL,
-                               &h.fid_persistent,
-                               &h.fid_volatile,
-                               cr);
+       subreq = smb2cli_create_send(state, ev,
+                                    cli->conn,
+                                    cli->timeout,
+                                    cli->smb2.session,
+                                    cli->smb2.tcon,
+                                    fname,
+                                    flags_to_smb2_oplock(create_flags),
+                                    SMB2_IMPERSONATION_IMPERSONATION,
+                                    desired_access,
+                                    file_attributes,
+                                    share_access,
+                                    create_disposition,
+                                    create_options,
+                                    NULL);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, cli_smb2_create_fnum_done, req);
 
-       if (NT_STATUS_IS_OK(status)) {
-               status = map_smb2_handle_to_fnum(cli, &h, pfid);
+       state->subreq = subreq;
+       tevent_req_set_cancel_fn(req, cli_smb2_create_fnum_cancel);
+
+       return req;
+}
+
+static void cli_smb2_create_fnum_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct cli_smb2_create_fnum_state *state = tevent_req_data(
+               req, struct cli_smb2_create_fnum_state);
+       struct smb2_hnd h;
+       NTSTATUS status;
+
+       status = smb2cli_create_recv(subreq, &h.fid_persistent,
+                                    &h.fid_volatile, &state->cr);
+       TALLOC_FREE(subreq);
+       if (tevent_req_nterror(req, status)) {
+               return;
        }
 
+       status = map_smb2_handle_to_fnum(state->cli, &h, &state->fnum);
+       if (tevent_req_nterror(req, status)) {
+               return;
+       }
+       tevent_req_done(req);
+}
+
+static bool cli_smb2_create_fnum_cancel(struct tevent_req *req)
+{
+       struct cli_smb2_create_fnum_state *state = tevent_req_data(
+               req, struct cli_smb2_create_fnum_state);
+       return tevent_req_cancel(state->subreq);
+}
+
+NTSTATUS cli_smb2_create_fnum_recv(struct tevent_req *req, uint16_t *pfnum,
+                                  struct smb_create_returns *cr)
+{
+       struct cli_smb2_create_fnum_state *state = tevent_req_data(
+               req, struct cli_smb2_create_fnum_state);
+       NTSTATUS status;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               return status;
+       }
+       if (pfnum != NULL) {
+               *pfnum = state->fnum;
+       }
+       if (cr != NULL) {
+               *cr = state->cr;
+       }
+       return NT_STATUS_OK;
+}
+
+NTSTATUS cli_smb2_create_fnum(struct cli_state *cli,
+                       const char *fname,
+                       uint32_t create_flags,
+                       uint32_t desired_access,
+                       uint32_t file_attributes,
+                       uint32_t share_access,
+                       uint32_t create_disposition,
+                       uint32_t create_options,
+                       uint16_t *pfid,
+                       struct smb_create_returns *cr)
+{
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct tevent_context *ev;
+       struct tevent_req *req;
+       NTSTATUS status = NT_STATUS_NO_MEMORY;
+
+       if (smbXcli_conn_has_async_calls(cli->conn)) {
+               /*
+                * Can't use sync call while an async call is in flight
+                */
+               status = NT_STATUS_INVALID_PARAMETER;
+               goto fail;
+       }
+       ev = samba_tevent_context_init(frame);
+       if (ev == NULL) {
+               goto fail;
+       }
+       req = cli_smb2_create_fnum_send(frame, ev, cli, fname, create_flags,
+                                       desired_access, file_attributes,
+                                       share_access, create_disposition,
+                                       create_options);
+       if (req == NULL) {
+               goto fail;
+       }
+       if (!tevent_req_poll_ntstatus(req, ev, &status)) {
+               goto fail;
+       }
+       status = cli_smb2_create_fnum_recv(req, pfid, cr);
+ fail:
+       TALLOC_FREE(frame);
        return status;
 }
 
diff --git a/source3/libsmb/cli_smb2_fnum.h b/source3/libsmb/cli_smb2_fnum.h
index a5ed5a0..9394918 100644
--- a/source3/libsmb/cli_smb2_fnum.h
+++ b/source3/libsmb/cli_smb2_fnum.h
@@ -25,6 +25,18 @@ struct smbXcli_session;
 struct cli_state;
 struct file_info;
 
+struct tevent_req *cli_smb2_create_fnum_send(TALLOC_CTX *mem_ctx,
+                                            struct tevent_context *ev,
+                                            struct cli_state *cli,
+                                            const char *fname,
+                                            uint32_t create_flags,
+                                            uint32_t desired_access,
+                                            uint32_t file_attributes,
+                                            uint32_t share_access,
+                                            uint32_t create_disposition,
+                                            uint32_t create_options);
+NTSTATUS cli_smb2_create_fnum_recv(struct tevent_req *req, uint16_t *pfnum,
+                                  struct smb_create_returns *cr);
 NTSTATUS cli_smb2_create_fnum(struct cli_state *cli,
                        const char *fname,
                        uint32_t create_flags,
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 1c52730..61cb8b5 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -1792,33 +1792,35 @@ NTSTATUS cli_nt_delete_on_close(struct cli_state *cli, 
uint16_t fnum, bool flag)
        return status;
 }
 
-struct cli_ntcreate_state {
+struct cli_ntcreate1_state {
        uint16_t vwv[24];
        uint16_t fnum;
        struct smb_create_returns cr;
+       struct tevent_req *subreq;
 };
 
-static void cli_ntcreate_done(struct tevent_req *subreq);
+static void cli_ntcreate1_done(struct tevent_req *subreq);
+static bool cli_ntcreate1_cancel(struct tevent_req *req);
 
-struct tevent_req *cli_ntcreate_send(TALLOC_CTX *mem_ctx,
-                                    struct tevent_context *ev,
-                                    struct cli_state *cli,
-                                    const char *fname,
-                                    uint32_t CreatFlags,
-                                    uint32_t DesiredAccess,
-                                    uint32_t FileAttributes,
-                                    uint32_t ShareAccess,
-                                    uint32_t CreateDisposition,
-                                    uint32_t CreateOptions,
-                                    uint8_t SecurityFlags)
+static struct tevent_req *cli_ntcreate1_send(TALLOC_CTX *mem_ctx,
+                                            struct tevent_context *ev,
+                                            struct cli_state *cli,
+                                            const char *fname,
+                                            uint32_t CreatFlags,
+                                            uint32_t DesiredAccess,
+                                            uint32_t FileAttributes,
+                                            uint32_t ShareAccess,
+                                            uint32_t CreateDisposition,
+                                            uint32_t CreateOptions,
+                                            uint8_t SecurityFlags)
 {
        struct tevent_req *req, *subreq;
-       struct cli_ntcreate_state *state;
+       struct cli_ntcreate1_state *state;
        uint16_t *vwv;
        uint8_t *bytes;
        size_t converted_len;
 
-       req = tevent_req_create(mem_ctx, &state, struct cli_ntcreate_state);
+       req = tevent_req_create(mem_ctx, &state, struct cli_ntcreate1_state);
        if (req == NULL) {
                return NULL;
        }
@@ -1865,16 +1867,20 @@ struct tevent_req *cli_ntcreate_send(TALLOC_CTX 
*mem_ctx,
        if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
-       tevent_req_set_callback(subreq, cli_ntcreate_done, req);
+       tevent_req_set_callback(subreq, cli_ntcreate1_done, req);
+
+       state->subreq = subreq;
+       tevent_req_set_cancel_fn(req, cli_ntcreate1_cancel);
+
        return req;
 }
 
-static void cli_ntcreate_done(struct tevent_req *subreq)
+static void cli_ntcreate1_done(struct tevent_req *subreq)
 {
        struct tevent_req *req = tevent_req_callback_data(
                subreq, struct tevent_req);
-       struct cli_ntcreate_state *state = tevent_req_data(
-               req, struct cli_ntcreate_state);
+       struct cli_ntcreate1_state *state = tevent_req_data(
+               req, struct cli_ntcreate1_state);
        uint8_t wct;
        uint16_t *vwv;
        uint32_t num_bytes;
@@ -1901,9 +1907,116 @@ static void cli_ntcreate_done(struct tevent_req *subreq)
        tevent_req_done(req);
 }
 
-NTSTATUS cli_ntcreate_recv(struct tevent_req *req,
-               uint16_t *pfnum,
-               struct smb_create_returns *cr)
+static bool cli_ntcreate1_cancel(struct tevent_req *req)
+{
+       struct cli_ntcreate1_state *state = tevent_req_data(
+               req, struct cli_ntcreate1_state);
+       return tevent_req_cancel(state->subreq);
+}
+
+static NTSTATUS cli_ntcreate1_recv(struct tevent_req *req,
+                                  uint16_t *pfnum,
+                                  struct smb_create_returns *cr)
+{
+       struct cli_ntcreate1_state *state = tevent_req_data(
+               req, struct cli_ntcreate1_state);
+       NTSTATUS status;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               return status;
+       }
+       *pfnum = state->fnum;
+       if (cr != NULL) {
+               *cr = state->cr;
+       }
+       return NT_STATUS_OK;
+}
+
+struct cli_ntcreate_state {
+       NTSTATUS (*recv)(struct tevent_req *req, uint16_t *fnum,
+                        struct smb_create_returns *cr);
+       struct smb_create_returns cr;
+       uint16_t fnum;
+       struct tevent_req *subreq;
+};
+
+static void cli_ntcreate_done(struct tevent_req *subreq);
+static bool cli_ntcreate_cancel(struct tevent_req *req);
+
+struct tevent_req *cli_ntcreate_send(TALLOC_CTX *mem_ctx,
+                                    struct tevent_context *ev,
+                                    struct cli_state *cli,
+                                    const char *fname,
+                                    uint32_t create_flags,
+                                    uint32_t desired_access,
+                                    uint32_t file_attributes,
+                                    uint32_t share_access,
+                                    uint32_t create_disposition,
+                                    uint32_t create_options,
+                                    uint8_t security_flags)
+{
+       struct tevent_req *req, *subreq;
+       struct cli_ntcreate_state *state;
+
+       req = tevent_req_create(mem_ctx, &state, struct cli_ntcreate_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
+               state->recv = cli_smb2_create_fnum_recv;
+
+               if (cli->use_oplocks) {
+                       create_flags |= REQUEST_OPLOCK|REQUEST_BATCH_OPLOCK;
+               }
+
+               subreq = cli_smb2_create_fnum_send(
+                       state, ev, cli, fname, create_flags, desired_access,
+                       file_attributes, share_access, create_disposition,
+                       create_options);
+       } else {
+               state->recv = cli_ntcreate1_recv;
+               subreq = cli_ntcreate1_send(
+                       state, ev, cli, fname, create_flags, desired_access,
+                       file_attributes, share_access, create_disposition,
+                       create_options, security_flags);
+       }
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, cli_ntcreate_done, req);
+
+       state->subreq = subreq;
+       tevent_req_set_cancel_fn(req, cli_ntcreate_cancel);
+
+       return req;
+}
+
+static void cli_ntcreate_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct cli_ntcreate_state *state = tevent_req_data(
+               req, struct cli_ntcreate_state);
+       NTSTATUS status;
+
+       status = state->recv(subreq, &state->fnum, &state->cr);
+       TALLOC_FREE(subreq);
+       if (tevent_req_nterror(req, status)) {
+               return;
+       }
+       tevent_req_done(req);
+}
+
+static bool cli_ntcreate_cancel(struct tevent_req *req)
+{
+       struct cli_ntcreate_state *state = tevent_req_data(
+               req, struct cli_ntcreate_state);
+       return tevent_req_cancel(state->subreq);
+}
+
+NTSTATUS cli_ntcreate_recv(struct tevent_req *req, uint16_t *fnum,
+                          struct smb_create_returns *cr)
 {
        struct cli_ntcreate_state *state = tevent_req_data(
                req, struct cli_ntcreate_state);
@@ -1912,7 +2025,9 @@ NTSTATUS cli_ntcreate_recv(struct tevent_req *req,
        if (tevent_req_is_nterror(req, &status)) {
                return status;
        }
-       *pfnum = state->fnum;
+       if (fnum != NULL) {
+               *fnum = state->fnum;
+       }
        if (cr != NULL) {
                *cr = state->cr;
        }
@@ -1931,25 +2046,10 @@ NTSTATUS cli_ntcreate(struct cli_state *cli,
                      uint16_t *pfid,
                      struct smb_create_returns *cr)
 {
-       TALLOC_CTX *frame = NULL;
+       TALLOC_CTX *frame = talloc_stackframe();
        struct tevent_context *ev;
        struct tevent_req *req;
-       NTSTATUS status = NT_STATUS_OK;
-
-       if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) {
-               return cli_smb2_create_fnum(cli,
-                                       fname,
-                                       CreatFlags,
-                                       DesiredAccess,
-                                       FileAttributes,
-                                       ShareAccess,
-                                       CreateDisposition,
-                                       CreateOptions,
-                                       pfid,
-                                       cr);
-       }
-
-       frame = talloc_stackframe();


-- 
Samba Shared Repository

Reply via email to