[PATCH] Add cblobs to cli_smb2_create_fnum_send
Jeremy Allison
jra at samba.org
Fri Mar 1 00:31:42 UTC 2019
On Thu, Feb 28, 2019 at 08:47:58PM +0100, Volker Lendecke via samba-technical wrote:
> Hi!
>
> Also make cli_smb2_rmdir asynchronous.
>
> Review appreciated!
Great updates Volker, thanks ! Preparatory work
for SMB2 unix extensions is *much* appreciated !
RB+ and pushed.
Jeremy.
> --
> SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
> phone: 0551-370000-0, mailto:kontakt at sernet.de
> Gesch.F.: Dr. Johannes Loxen und Reinhild Jung
> AG Göttingen: HR-B 2816 - http://www.sernet.de
> From 51d0a20d11a53cef01b4a1d24893022912929328 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Fri, 15 Feb 2019 18:24:31 +0100
> Subject: [PATCH 1/4] libsmb: Reformat the cli_smb2_create_fnum_send args
>
> We'll add parameters in the next commit, make that commit a bit more obvious
>
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
> examples/fuse/clifuse.c | 27 ++++++++++++------
> source3/libsmb/cli_smb2_fnum.c | 63 ++++++++++++++++++++++++------------------
> source3/libsmb/cli_smb2_fnum.h | 46 +++++++++++++++---------------
> source3/libsmb/clifile.c | 13 +++++++--
> 4 files changed, 89 insertions(+), 60 deletions(-)
>
> diff --git a/examples/fuse/clifuse.c b/examples/fuse/clifuse.c
> index b724e642d4b..3814c9801dd 100644
> --- a/examples/fuse/clifuse.c
> +++ b/examples/fuse/clifuse.c
> @@ -150,11 +150,16 @@ static void cli_ll_create(fuse_req_t freq, fuse_ino_t parent, const char *name,
> }
>
> req = cli_smb2_create_fnum_send(
> - state, mstate->ev, mstate->cli, state->path,
> - 0, SMB2_IMPERSONATION_IMPERSONATION,
> - FILE_GENERIC_READ|FILE_GENERIC_WRITE, FILE_ATTRIBUTE_NORMAL,
> + state,
> + mstate->ev,
> + mstate->cli, state->path,
> + 0,
> + SMB2_IMPERSONATION_IMPERSONATION,
> + FILE_GENERIC_READ|FILE_GENERIC_WRITE,
> + FILE_ATTRIBUTE_NORMAL,
> FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
> - FILE_CREATE, FILE_NON_DIRECTORY_FILE);
> + FILE_CREATE,
> + FILE_NON_DIRECTORY_FILE);
> if (req == NULL) {
> TALLOC_FREE(state);
> fuse_reply_err(freq, ENOMEM);
> @@ -836,11 +841,17 @@ static void cli_ll_open(fuse_req_t freq, fuse_ino_t ino,
> }
>
> req = cli_smb2_create_fnum_send(
> - state, mstate->ev, mstate->cli, istate->path,
> - 0, SMB2_IMPERSONATION_IMPERSONATION,
> - acc, FILE_ATTRIBUTE_NORMAL,
> + state,
> + mstate->ev,
> + mstate->cli,
> + istate->path,
> + 0,
> + SMB2_IMPERSONATION_IMPERSONATION,
> + acc,
> + FILE_ATTRIBUTE_NORMAL,
> FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
> - FILE_OPEN, FILE_NON_DIRECTORY_FILE);
> + FILE_OPEN,
> + FILE_NON_DIRECTORY_FILE);
> if (req == NULL) {
> TALLOC_FREE(state);
> fuse_reply_err(freq, ENOMEM);
> diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c
> index e7b89a44e58..8122cd6cb30 100644
> --- a/source3/libsmb/cli_smb2_fnum.c
> +++ b/source3/libsmb/cli_smb2_fnum.c
> @@ -166,17 +166,18 @@ struct cli_smb2_create_fnum_state {
> 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 impersonation_level,
> - uint32_t desired_access,
> - uint32_t file_attributes,
> - uint32_t share_access,
> - uint32_t create_disposition,
> - uint32_t create_options)
> +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 impersonation_level,
> + uint32_t desired_access,
> + uint32_t file_attributes,
> + uint32_t share_access,
> + uint32_t create_disposition,
> + uint32_t create_options)
> {
> struct tevent_req *req, *subreq;
> struct cli_smb2_create_fnum_state *state;
> @@ -332,17 +333,18 @@ NTSTATUS cli_smb2_create_fnum_recv(struct tevent_req *req, uint16_t *pfnum,
> return NT_STATUS_OK;
> }
>
> -NTSTATUS cli_smb2_create_fnum(struct cli_state *cli,
> - const char *fname,
> - uint32_t create_flags,
> - uint32_t impersonation_level,
> - 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)
> +NTSTATUS cli_smb2_create_fnum(
> + struct cli_state *cli,
> + const char *fname,
> + uint32_t create_flags,
> + uint32_t impersonation_level,
> + 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;
> @@ -360,11 +362,18 @@ NTSTATUS cli_smb2_create_fnum(struct cli_state *cli,
> if (ev == NULL) {
> goto fail;
> }
> - req = cli_smb2_create_fnum_send(frame, ev, cli, fname, create_flags,
> - impersonation_level,
> - desired_access, file_attributes,
> - share_access, create_disposition,
> - create_options);
> + req = cli_smb2_create_fnum_send(
> + frame,
> + ev,
> + cli,
> + fname,
> + create_flags,
> + impersonation_level,
> + desired_access,
> + file_attributes,
> + share_access,
> + create_disposition,
> + create_options);
> if (req == NULL) {
> goto fail;
> }
> diff --git a/source3/libsmb/cli_smb2_fnum.h b/source3/libsmb/cli_smb2_fnum.h
> index 921dc71d9eb..9dfa93eab66 100644
> --- a/source3/libsmb/cli_smb2_fnum.h
> +++ b/source3/libsmb/cli_smb2_fnum.h
> @@ -25,30 +25,32 @@ 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 impersonation_level,
> - uint32_t desired_access,
> - uint32_t file_attributes,
> - uint32_t share_access,
> - uint32_t create_disposition,
> - uint32_t create_options);
> +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 impersonation_level,
> + 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,
> - uint32_t impersonation_level,
> - 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);
> +NTSTATUS cli_smb2_create_fnum(
> + struct cli_state *cli,
> + const char *fname,
> + uint32_t create_flags,
> + uint32_t impersonation_level,
> + 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 tevent_req *cli_smb2_close_fnum_send(TALLOC_CTX *mem_ctx,
> struct tevent_context *ev,
> diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
> index 833db0ac925..6940858c640 100644
> --- a/source3/libsmb/clifile.c
> +++ b/source3/libsmb/clifile.c
> @@ -2115,9 +2115,16 @@ struct tevent_req *cli_ntcreate_send(TALLOC_CTX *mem_ctx,
> }
>
> subreq = cli_smb2_create_fnum_send(
> - state, ev, cli, fname, create_flags,
> - impersonation_level, desired_access,
> - file_attributes, share_access, create_disposition,
> + state,
> + ev,
> + cli,
> + fname,
> + create_flags,
> + impersonation_level,
> + desired_access,
> + file_attributes,
> + share_access,
> + create_disposition,
> create_options);
> if (tevent_req_nomem(subreq, req)) {
> return tevent_req_post(req, ev);
> --
> 2.11.0
>
>
> From 560487d41c1c626f09923081ae61ed4d67eea672 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Wed, 20 Feb 2019 17:06:32 +0100
> Subject: [PATCH 2/4] libsmb: Avoid a separate "cblobs" var sending smb2 create
>
> Less lines of code, and we will add custom cblobs soon. This change
> makes that logic easier.
>
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
> source3/libsmb/cli_smb2_fnum.c | 16 +++++++---------
> 1 file changed, 7 insertions(+), 9 deletions(-)
>
> diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c
> index 8122cd6cb30..181078507a1 100644
> --- a/source3/libsmb/cli_smb2_fnum.c
> +++ b/source3/libsmb/cli_smb2_fnum.c
> @@ -158,6 +158,7 @@ static uint8_t flags_to_smb2_oplock(uint32_t create_flags)
>
> struct cli_smb2_create_fnum_state {
> struct cli_state *cli;
> + struct smb2_create_blobs cblobs;
> struct smb_create_returns cr;
> uint16_t fnum;
> struct tevent_req *subreq;
> @@ -185,7 +186,6 @@ struct tevent_req *cli_smb2_create_fnum_send(
> const char *startp = NULL;
> const char *endp = NULL;
> time_t tstamp = (time_t)0;
> - struct smb2_create_blobs *cblobs = NULL;
>
> req = tevent_req_create(mem_ctx, &state,
> struct cli_smb2_create_fnum_state);
> @@ -227,13 +227,11 @@ struct tevent_req *cli_smb2_create_fnum_send(
> unix_to_nt_time(&ntt, tstamp);
> twrp_blob = data_blob_const((const void *)&ntt, 8);
>
> - cblobs = talloc_zero(state, struct smb2_create_blobs);
> - if (tevent_req_nomem(cblobs, req)) {
> - return tevent_req_post(req, ev);
> - }
> -
> - status = smb2_create_blob_add(state, cblobs,
> - SMB2_CREATE_TAG_TWRP, twrp_blob);
> + status = smb2_create_blob_add(
> + state,
> + &state->cblobs,
> + SMB2_CREATE_TAG_TWRP,
> + twrp_blob);
> if (!NT_STATUS_IS_OK(status)) {
> tevent_req_nterror(req, status);
> return tevent_req_post(req, ev);
> @@ -270,7 +268,7 @@ struct tevent_req *cli_smb2_create_fnum_send(
> share_access,
> create_disposition,
> create_options,
> - cblobs);
> + &state->cblobs);
> if (tevent_req_nomem(subreq, req)) {
> return tevent_req_post(req, ev);
> }
> --
> 2.11.0
>
>
> From 2911f3d486f900adff862bfeffcdaa7aace61c88 Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Wed, 20 Feb 2019 17:23:46 +0100
> Subject: [PATCH 3/4] libsmb: add in/out cblobs to cli_smb2_create_fnum
>
> This is driven by the imminent smb2 unix extensions, we'll want to make use of
> it from source3/libsmb.
>
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
> examples/fuse/clifuse.c | 10 ++--
> source3/libsmb/cli_smb2_fnum.c | 110 +++++++++++++++++++++++++++++++++++------
> source3/libsmb/cli_smb2_fnum.h | 16 ++++--
> source3/libsmb/clifile.c | 10 +++-
> 4 files changed, 122 insertions(+), 24 deletions(-)
>
> diff --git a/examples/fuse/clifuse.c b/examples/fuse/clifuse.c
> index 3814c9801dd..954c412f09c 100644
> --- a/examples/fuse/clifuse.c
> +++ b/examples/fuse/clifuse.c
> @@ -159,7 +159,8 @@ static void cli_ll_create(fuse_req_t freq, fuse_ino_t parent, const char *name,
> FILE_ATTRIBUTE_NORMAL,
> FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
> FILE_CREATE,
> - FILE_NON_DIRECTORY_FILE);
> + FILE_NON_DIRECTORY_FILE,
> + NULL);
> if (req == NULL) {
> TALLOC_FREE(state);
> fuse_reply_err(freq, ENOMEM);
> @@ -177,7 +178,7 @@ static void cli_ll_create_done(struct tevent_req *req)
> uint16_t fnum;
> NTSTATUS status;
>
> - status = cli_smb2_create_fnum_recv(req, &fnum, NULL);
> + status = cli_smb2_create_fnum_recv(req, &fnum, NULL, NULL, NULL);
> TALLOC_FREE(req);
> if (!NT_STATUS_IS_OK(status)) {
> fuse_reply_err(state->freq, map_errno_from_nt_status(status));
> @@ -851,7 +852,8 @@ static void cli_ll_open(fuse_req_t freq, fuse_ino_t ino,
> FILE_ATTRIBUTE_NORMAL,
> FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
> FILE_OPEN,
> - FILE_NON_DIRECTORY_FILE);
> + FILE_NON_DIRECTORY_FILE,
> + NULL);
> if (req == NULL) {
> TALLOC_FREE(state);
> fuse_reply_err(freq, ENOMEM);
> @@ -867,7 +869,7 @@ static void cli_ll_open_done(struct tevent_req *req)
> uint16_t fnum;
> NTSTATUS status;
>
> - status = cli_smb2_create_fnum_recv(req, &fnum, NULL);
> + status = cli_smb2_create_fnum_recv(req, &fnum, NULL, NULL, NULL);
> TALLOC_FREE(req);
> if (!NT_STATUS_IS_OK(status)) {
> fuse_reply_err(state->freq, map_errno_from_nt_status(status));
> diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c
> index 181078507a1..cd713d93c6c 100644
> --- a/source3/libsmb/cli_smb2_fnum.c
> +++ b/source3/libsmb/cli_smb2_fnum.c
> @@ -158,7 +158,8 @@ static uint8_t flags_to_smb2_oplock(uint32_t create_flags)
>
> struct cli_smb2_create_fnum_state {
> struct cli_state *cli;
> - struct smb2_create_blobs cblobs;
> + struct smb2_create_blobs in_cblobs;
> + struct smb2_create_blobs out_cblobs;
> struct smb_create_returns cr;
> uint16_t fnum;
> struct tevent_req *subreq;
> @@ -178,7 +179,8 @@ struct tevent_req *cli_smb2_create_fnum_send(
> uint32_t file_attributes,
> uint32_t share_access,
> uint32_t create_disposition,
> - uint32_t create_options)
> + uint32_t create_options,
> + const struct smb2_create_blobs *in_cblobs)
> {
> struct tevent_req *req, *subreq;
> struct cli_smb2_create_fnum_state *state;
> @@ -186,6 +188,7 @@ struct tevent_req *cli_smb2_create_fnum_send(
> const char *startp = NULL;
> const char *endp = NULL;
> time_t tstamp = (time_t)0;
> + NTSTATUS status;
>
> req = tevent_req_create(mem_ctx, &state,
> struct cli_smb2_create_fnum_state);
> @@ -210,7 +213,6 @@ struct tevent_req *cli_smb2_create_fnum_send(
> size_t len_after_gmt = fname + fname_len - endp;
> DATA_BLOB twrp_blob;
> NTTIME ntt;
> - NTSTATUS status;
>
> char *new_fname = talloc_array(state, char,
> len_before_gmt + len_after_gmt + 1);
> @@ -229,7 +231,7 @@ struct tevent_req *cli_smb2_create_fnum_send(
>
> status = smb2_create_blob_add(
> state,
> - &state->cblobs,
> + &state->in_cblobs,
> SMB2_CREATE_TAG_TWRP,
> twrp_blob);
> if (!NT_STATUS_IS_OK(status)) {
> @@ -238,6 +240,19 @@ struct tevent_req *cli_smb2_create_fnum_send(
> }
> }
>
> + if (in_cblobs != NULL) {
> + uint32_t i;
> + for (i=0; i<in_cblobs->num_blobs; i++) {
> + struct smb2_create_blob *b = &in_cblobs->blobs[i];
> + status = smb2_create_blob_add(
> + state, &state->in_cblobs, b->tag, b->data);
> + if (!NT_STATUS_IS_OK(status)) {
> + tevent_req_nterror(req, status);
> + return tevent_req_post(req, ev);
> + }
> + }
> + }
> +
> /* SMB2 is pickier about pathnames. Ensure it doesn't
> start in a '\' */
> if (*fname == '\\') {
> @@ -268,7 +283,7 @@ struct tevent_req *cli_smb2_create_fnum_send(
> share_access,
> create_disposition,
> create_options,
> - &state->cblobs);
> + &state->in_cblobs);
> if (tevent_req_nomem(subreq, req)) {
> return tevent_req_post(req, ev);
> }
> @@ -289,8 +304,12 @@ static void cli_smb2_create_fnum_done(struct tevent_req *subreq)
> struct smb2_hnd h;
> NTSTATUS status;
>
> - status = smb2cli_create_recv(subreq, &h.fid_persistent,
> - &h.fid_volatile, &state->cr, NULL, NULL);
> + status = smb2cli_create_recv(
> + subreq,
> + &h.fid_persistent,
> + &h.fid_volatile, &state->cr,
> + state,
> + &state->out_cblobs);
> TALLOC_FREE(subreq);
> if (tevent_req_nterror(req, status)) {
> return;
> @@ -310,8 +329,12 @@ static bool cli_smb2_create_fnum_cancel(struct tevent_req *req)
> return tevent_req_cancel(state->subreq);
> }
>
> -NTSTATUS cli_smb2_create_fnum_recv(struct tevent_req *req, uint16_t *pfnum,
> - struct smb_create_returns *cr)
> +NTSTATUS cli_smb2_create_fnum_recv(
> + struct tevent_req *req,
> + uint16_t *pfnum,
> + struct smb_create_returns *cr,
> + TALLOC_CTX *mem_ctx,
> + struct smb2_create_blobs *out_cblobs)
> {
> struct cli_smb2_create_fnum_state *state = tevent_req_data(
> req, struct cli_smb2_create_fnum_state);
> @@ -327,6 +350,13 @@ NTSTATUS cli_smb2_create_fnum_recv(struct tevent_req *req, uint16_t *pfnum,
> if (cr != NULL) {
> *cr = state->cr;
> }
> + if (out_cblobs != NULL) {
> + *out_cblobs = (struct smb2_create_blobs) {
> + .num_blobs = state->out_cblobs.num_blobs,
> + .blobs = talloc_move(
> + mem_ctx, &state->out_cblobs.blobs),
> + };
> + }
> state->cli->raw_status = NT_STATUS_OK;
> return NT_STATUS_OK;
> }
> @@ -341,8 +371,11 @@ NTSTATUS cli_smb2_create_fnum(
> uint32_t share_access,
> uint32_t create_disposition,
> uint32_t create_options,
> + const struct smb2_create_blobs *in_cblobs,
> uint16_t *pfid,
> - struct smb_create_returns *cr)
> + struct smb_create_returns *cr,
> + TALLOC_CTX *mem_ctx,
> + struct smb2_create_blobs *out_cblobs)
> {
> TALLOC_CTX *frame = talloc_stackframe();
> struct tevent_context *ev;
> @@ -371,14 +404,15 @@ NTSTATUS cli_smb2_create_fnum(
> file_attributes,
> share_access,
> create_disposition,
> - create_options);
> + create_options,
> + in_cblobs);
> if (req == NULL) {
> goto fail;
> }
> if (!tevent_req_poll_ntstatus(req, ev, &status)) {
> goto fail;
> }
> - status = cli_smb2_create_fnum_recv(req, pfid, cr);
> + status = cli_smb2_create_fnum_recv(req, pfid, cr, mem_ctx, out_cblobs);
> fail:
> TALLOC_FREE(frame);
> return status;
> @@ -657,7 +691,10 @@ NTSTATUS cli_smb2_mkdir(struct cli_state *cli, const char *dname)
> FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
> FILE_CREATE, /* create_disposition */
> FILE_DIRECTORY_FILE, /* create_options */
> + NULL,
> &fnum,
> + NULL,
> + NULL,
> NULL);
>
> if (!NT_STATUS_IS_OK(status)) {
> @@ -696,7 +733,10 @@ NTSTATUS cli_smb2_rmdir(struct cli_state *cli, const char *dname)
> FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */
> FILE_OPEN, /* create_disposition */
> FILE_DIRECTORY_FILE, /* create_options */
> + NULL,
> &fnum,
> + NULL,
> + NULL,
> NULL);
>
> if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
> @@ -717,7 +757,10 @@ NTSTATUS cli_smb2_rmdir(struct cli_state *cli, const char *dname)
> FILE_DIRECTORY_FILE|
> FILE_DELETE_ON_CLOSE|
> FILE_OPEN_REPARSE_POINT, /* create_options */
> + NULL,
> &fnum,
> + NULL,
> + NULL,
> NULL);
> }
>
> @@ -764,7 +807,10 @@ NTSTATUS cli_smb2_unlink(struct cli_state *cli, const char *fname)
> FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */
> FILE_OPEN, /* create_disposition */
> FILE_DELETE_ON_CLOSE, /* create_options */
> + NULL,
> &fnum,
> + NULL,
> + NULL,
> NULL);
>
> if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
> @@ -784,7 +830,10 @@ NTSTATUS cli_smb2_unlink(struct cli_state *cli, const char *fname)
> FILE_OPEN, /* create_disposition */
> FILE_DELETE_ON_CLOSE|
> FILE_OPEN_REPARSE_POINT, /* create_options */
> + NULL,
> &fnum,
> + NULL,
> + NULL,
> NULL);
> }
>
> @@ -965,7 +1014,10 @@ NTSTATUS cli_smb2_list(struct cli_state *cli,
> FILE_SHARE_READ|FILE_SHARE_WRITE, /* share_access */
> FILE_OPEN, /* create_disposition */
> FILE_DIRECTORY_FILE, /* create_options */
> + NULL,
> &fnum,
> + NULL,
> + NULL,
> NULL);
>
> if (!NT_STATUS_IS_OK(status)) {
> @@ -1152,8 +1204,11 @@ NTSTATUS cli_smb2_qpathinfo_basic(struct cli_state *cli,
> FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */
> FILE_OPEN, /* create_disposition */
> FILE_DIRECTORY_FILE, /* create_options */
> + NULL,
> &fnum,
> - &cr);
> + &cr,
> + NULL,
> + NULL);
>
> if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
> /* Maybe a file ? */
> @@ -1166,8 +1221,11 @@ NTSTATUS cli_smb2_qpathinfo_basic(struct cli_state *cli,
> FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */
> FILE_OPEN, /* create_disposition */
> 0, /* create_options */
> + NULL,
> &fnum,
> - &cr);
> + &cr,
> + NULL,
> + NULL);
> }
>
> if (!NT_STATUS_IS_OK(status)) {
> @@ -1219,7 +1277,10 @@ NTSTATUS cli_smb2_chkpath(struct cli_state *cli,
> FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */
> FILE_OPEN, /* create_disposition */
> FILE_DIRECTORY_FILE, /* create_options */
> + NULL,
> &fnum,
> + NULL,
> + NULL,
> NULL);
>
> if (!NT_STATUS_IS_OK(status)) {
> @@ -1265,7 +1326,10 @@ static NTSTATUS get_fnum_from_path(struct cli_state *cli,
> FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */
> FILE_OPEN, /* create_disposition */
> create_options,
> + NULL,
> pfnum,
> + NULL,
> + NULL,
> NULL);
>
> if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
> @@ -1285,7 +1349,10 @@ static NTSTATUS get_fnum_from_path(struct cli_state *cli,
> FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */
> FILE_OPEN, /* create_disposition */
> create_options,
> + NULL,
> pfnum,
> + NULL,
> + NULL,
> NULL);
> }
>
> @@ -1300,7 +1367,10 @@ static NTSTATUS get_fnum_from_path(struct cli_state *cli,
> FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */
> FILE_OPEN, /* create_disposition */
> FILE_DIRECTORY_FILE, /* create_options */
> + NULL,
> pfnum,
> + NULL,
> + NULL,
> NULL);
> }
>
> @@ -2036,7 +2106,10 @@ NTSTATUS cli_smb2_dskattr(struct cli_state *cli, const char *path,
> FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */
> FILE_OPEN, /* create_disposition */
> FILE_DIRECTORY_FILE, /* create_options */
> + NULL,
> &fnum,
> + NULL,
> + NULL,
> NULL);
>
> if (!NT_STATUS_IS_OK(status)) {
> @@ -2147,7 +2220,10 @@ NTSTATUS cli_smb2_get_fs_full_size_info(struct cli_state *cli,
> FILE_SHARE_DELETE, /* share_access */
> FILE_OPEN, /* create_disposition */
> FILE_DIRECTORY_FILE, /* create_options */
> + NULL,
> &fnum,
> + NULL,
> + NULL,
> NULL);
>
> if (!NT_STATUS_IS_OK(status)) {
> @@ -2240,7 +2316,10 @@ NTSTATUS cli_smb2_get_fs_attr_info(struct cli_state *cli, uint32_t *fs_attr)
> FILE_SHARE_DELETE, /* share_access */
> FILE_OPEN, /* create_disposition */
> FILE_DIRECTORY_FILE, /* create_options */
> + NULL,
> &fnum,
> + NULL,
> + NULL,
> NULL);
>
> if (!NT_STATUS_IS_OK(status)) {
> @@ -2326,7 +2405,10 @@ NTSTATUS cli_smb2_get_fs_volume_info(struct cli_state *cli,
> FILE_SHARE_DELETE, /* share_access */
> FILE_OPEN, /* create_disposition */
> FILE_DIRECTORY_FILE, /* create_options */
> + NULL,
> &fnum,
> + NULL,
> + NULL,
> NULL);
>
> if (!NT_STATUS_IS_OK(status)) {
> diff --git a/source3/libsmb/cli_smb2_fnum.h b/source3/libsmb/cli_smb2_fnum.h
> index 9dfa93eab66..9e259482f4a 100644
> --- a/source3/libsmb/cli_smb2_fnum.h
> +++ b/source3/libsmb/cli_smb2_fnum.h
> @@ -36,9 +36,14 @@ struct tevent_req *cli_smb2_create_fnum_send(
> 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);
> + uint32_t create_options,
> + const struct smb2_create_blobs *in_cblobs);
> +NTSTATUS cli_smb2_create_fnum_recv(
> + struct tevent_req *req,
> + uint16_t *pfnum,
> + struct smb_create_returns *cr,
> + TALLOC_CTX *mem_ctx,
> + struct smb2_create_blobs *out_cblobs);
> NTSTATUS cli_smb2_create_fnum(
> struct cli_state *cli,
> const char *fname,
> @@ -49,8 +54,11 @@ NTSTATUS cli_smb2_create_fnum(
> uint32_t share_access,
> uint32_t create_disposition,
> uint32_t create_options,
> + const struct smb2_create_blobs *in_cblobs,
> uint16_t *pfid,
> - struct smb_create_returns *cr);
> + struct smb_create_returns *cr,
> + TALLOC_CTX *mem_ctx,
> + struct smb2_create_blobs *out_cblobs);
>
> struct tevent_req *cli_smb2_close_fnum_send(TALLOC_CTX *mem_ctx,
> struct tevent_context *ev,
> diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
> index 6940858c640..7d72dc82858 100644
> --- a/source3/libsmb/clifile.c
> +++ b/source3/libsmb/clifile.c
> @@ -2125,7 +2125,8 @@ struct tevent_req *cli_ntcreate_send(TALLOC_CTX *mem_ctx,
> file_attributes,
> share_access,
> create_disposition,
> - create_options);
> + create_options,
> + NULL);
> if (tevent_req_nomem(subreq, req)) {
> return tevent_req_post(req, ev);
> }
> @@ -2171,7 +2172,12 @@ static void cli_ntcreate_done_smb2(struct tevent_req *subreq)
> req, struct cli_ntcreate_state);
> NTSTATUS status;
>
> - status = cli_smb2_create_fnum_recv(subreq, &state->fnum, &state->cr);
> + status = cli_smb2_create_fnum_recv(
> + subreq,
> + &state->fnum,
> + &state->cr,
> + NULL,
> + NULL);
> TALLOC_FREE(subreq);
> if (tevent_req_nterror(req, status)) {
> return;
> --
> 2.11.0
>
>
> From ac1ea58e951f26b40bb0f3166c5d5700fa3b421b Mon Sep 17 00:00:00 2001
> From: Volker Lendecke <vl at samba.org>
> Date: Thu, 28 Feb 2019 13:47:22 +0100
> Subject: [PATCH 4/4] libsmb: Make cli_smb2_rmdir asynchronous
>
> Signed-off-by: Volker Lendecke <vl at samba.org>
> ---
> source3/libsmb/cli_smb2_fnum.c | 223 +++++++++++++++++++++++++++++++++--------
> source3/libsmb/cli_smb2_fnum.h | 5 +
> 2 files changed, 185 insertions(+), 43 deletions(-)
>
> diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c
> index cd713d93c6c..795dc557c45 100644
> --- a/source3/libsmb/cli_smb2_fnum.c
> +++ b/source3/libsmb/cli_smb2_fnum.c
> @@ -703,41 +703,71 @@ NTSTATUS cli_smb2_mkdir(struct cli_state *cli, const char *dname)
> return cli_smb2_close_fnum(cli, fnum);
> }
>
> -/***************************************************************
> - Small wrapper that allows SMB2 to delete a directory
> - Synchronous only.
> -***************************************************************/
> +struct cli_smb2_rmdir_state {
> + struct tevent_context *ev;
> + struct cli_state *cli;
> + const char *dname;
> + uint16_t fnum;
> + NTSTATUS status;
> +};
>
> -NTSTATUS cli_smb2_rmdir(struct cli_state *cli, const char *dname)
> +static void cli_smb2_rmdir_opened1(struct tevent_req *subreq);
> +static void cli_smb2_rmdir_opened2(struct tevent_req *subreq);
> +static void cli_smb2_rmdir_disp_set(struct tevent_req *subreq);
> +static void cli_smb2_rmdir_closed(struct tevent_req *subreq);
> +
> +struct tevent_req *cli_smb2_rmdir_send(TALLOC_CTX *mem_ctx,
> + struct tevent_context *ev,
> + struct cli_state *cli,
> + const char *dname)
> {
> - NTSTATUS status;
> - uint16_t fnum;
> + struct tevent_req *req = NULL, *subreq = NULL;
> + struct cli_smb2_rmdir_state *state = NULL;
>
> - 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_rmdir_state);
> + if (req == NULL) {
> + return NULL;
> }
> + state->ev = ev;
> + state->cli = cli;
> + state->dname = dname;
>
> 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);
> }
>
> - status = cli_smb2_create_fnum(cli,
> - dname,
> - 0, /* create_flags */
> - SMB2_IMPERSONATION_IMPERSONATION,
> - DELETE_ACCESS, /* desired_access */
> - FILE_ATTRIBUTE_DIRECTORY, /* file attributes */
> - FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */
> - FILE_OPEN, /* create_disposition */
> - FILE_DIRECTORY_FILE, /* create_options */
> - NULL,
> - &fnum,
> - NULL,
> - NULL,
> - NULL);
> + subreq = cli_smb2_create_fnum_send(
> + state,
> + state->ev,
> + state->cli,
> + state->dname,
> + 0, /* create_flags */
> + SMB2_IMPERSONATION_IMPERSONATION,
> + DELETE_ACCESS, /* desired_access */
> + FILE_ATTRIBUTE_DIRECTORY, /* file attributes */
> + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */
> + FILE_OPEN, /* create_disposition */
> + FILE_DIRECTORY_FILE, /* create_options */
> + NULL); /* in_cblobs */
> + if (tevent_req_nomem(subreq, req)) {
> + return tevent_req_post(req, ev);
> + }
> + tevent_req_set_callback(subreq, cli_smb2_rmdir_opened1, req);
> + return req;
> +}
> +
> +static void cli_smb2_rmdir_opened1(struct tevent_req *subreq)
> +{
> + struct tevent_req *req = tevent_req_callback_data(
> + subreq, struct tevent_req);
> + struct cli_smb2_rmdir_state *state = tevent_req_data(
> + req, struct cli_smb2_rmdir_state);
> + NTSTATUS status;
> +
> + status = cli_smb2_create_fnum_recv(
> + subreq, &state->fnum, NULL, NULL, NULL);
> + TALLOC_FREE(subreq);
>
> if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
> /*
> @@ -746,35 +776,142 @@ NTSTATUS cli_smb2_rmdir(struct cli_state *cli, const char *dname)
> * component and try again. Eventually we will have to
> * deal with the returned path unprocessed component. JRA.
> */
> - status = cli_smb2_create_fnum(cli,
> - dname,
> + subreq = cli_smb2_create_fnum_send(
> + state,
> + state->ev,
> + state->cli,
> + state->dname,
> 0, /* create_flags */
> SMB2_IMPERSONATION_IMPERSONATION,
> DELETE_ACCESS, /* desired_access */
> FILE_ATTRIBUTE_DIRECTORY, /* file attributes */
> - FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */
> + FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
> FILE_OPEN, /* create_disposition */
> FILE_DIRECTORY_FILE|
> - FILE_DELETE_ON_CLOSE|
> - FILE_OPEN_REPARSE_POINT, /* create_options */
> - NULL,
> - &fnum,
> - NULL,
> - NULL,
> - NULL);
> + FILE_DELETE_ON_CLOSE|
> + FILE_OPEN_REPARSE_POINT, /* create_options */
> + NULL); /* in_cblobs */
> + if (tevent_req_nomem(subreq, req)) {
> + return;
> + }
> + tevent_req_set_callback(subreq, cli_smb2_rmdir_opened2, req);
> + return;
> }
>
> - if (!NT_STATUS_IS_OK(status)) {
> - return status;
> + if (tevent_req_nterror(req, status)) {
> + return;
> }
>
> - status = cli_smb2_delete_on_close(cli, fnum, true);
> - if (!NT_STATUS_IS_OK(status)) {
> - cli_smb2_close_fnum(cli, fnum);
> + subreq = cli_smb2_delete_on_close_send(
> + state, state->ev, state->cli, state->fnum, true);
> + if (tevent_req_nomem(subreq, req)) {
> + return;
> + }
> + tevent_req_set_callback(subreq, cli_smb2_rmdir_disp_set, req);
> +}
> +
> +static void cli_smb2_rmdir_opened2(struct tevent_req *subreq)
> +{
> + struct tevent_req *req = tevent_req_callback_data(
> + subreq, struct tevent_req);
> + struct cli_smb2_rmdir_state *state = tevent_req_data(
> + req, struct cli_smb2_rmdir_state);
> + NTSTATUS status;
> +
> + status = cli_smb2_create_fnum_recv(
> + subreq, &state->fnum, NULL, NULL, NULL);
> + TALLOC_FREE(subreq);
> + if (tevent_req_nterror(req, status)) {
> + return;
> + }
> +
> + subreq = cli_smb2_delete_on_close_send(
> + state, state->ev, state->cli, state->fnum, true);
> + if (tevent_req_nomem(subreq, req)) {
> + return;
> + }
> + tevent_req_set_callback(subreq, cli_smb2_rmdir_disp_set, req);
> +}
> +
> +static void cli_smb2_rmdir_disp_set(struct tevent_req *subreq)
> +{
> + struct tevent_req *req = tevent_req_callback_data(
> + subreq, struct tevent_req);
> + struct cli_smb2_rmdir_state *state = tevent_req_data(
> + req, struct cli_smb2_rmdir_state);
> +
> + state->status = cli_smb2_delete_on_close_recv(subreq);
> + TALLOC_FREE(subreq);
> +
> + /*
> + * Close the fd even if the set_disp failed
> + */
> +
> + subreq = cli_smb2_close_fnum_send(
> + state, state->ev, state->cli, state->fnum);
> + if (tevent_req_nomem(subreq, req)) {
> + return;
> + }
> + tevent_req_set_callback(subreq, cli_smb2_rmdir_closed, req);
> +}
> +
> +static void cli_smb2_rmdir_closed(struct tevent_req *subreq)
> +{
> + struct tevent_req *req = tevent_req_callback_data(
> + subreq, struct tevent_req);
> + NTSTATUS status;
> +
> + status = cli_smb2_close_fnum_recv(subreq);
> + if (tevent_req_nterror(req, status)) {
> + return;
> + }
> + tevent_req_done(req);
> +}
> +
> +NTSTATUS cli_smb2_rmdir_recv(struct tevent_req *req)
> +{
> + struct cli_smb2_rmdir_state *state = tevent_req_data(
> + req, struct cli_smb2_rmdir_state);
> + NTSTATUS status;
> +
> + if (tevent_req_is_nterror(req, &status)) {
> return status;
> }
> + return state->status;
> +}
>
> - return cli_smb2_close_fnum(cli, fnum);
> +NTSTATUS cli_smb2_rmdir(struct cli_state *cli, const char *dname)
> +{
> + TALLOC_CTX *frame = talloc_stackframe();
> + struct tevent_context *ev;
> + struct tevent_req *req;
> + NTSTATUS status = NT_STATUS_NO_MEMORY;
> + bool ok;
> +
> + 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_rmdir_send(frame, ev, cli, dname);
> + if (req == NULL) {
> + goto fail;
> + }
> + ok = tevent_req_poll_ntstatus(req, ev, &status);
> + if (!ok) {
> + goto fail;
> + }
> + status = cli_smb2_rmdir_recv(req);
> +fail:
> + cli->raw_status = status;
> + TALLOC_FREE(frame);
> + return status;
> }
>
> /***************************************************************
> diff --git a/source3/libsmb/cli_smb2_fnum.h b/source3/libsmb/cli_smb2_fnum.h
> index 9e259482f4a..62ae093862f 100644
> --- a/source3/libsmb/cli_smb2_fnum.h
> +++ b/source3/libsmb/cli_smb2_fnum.h
> @@ -74,6 +74,11 @@ struct tevent_req *cli_smb2_delete_on_close_send(TALLOC_CTX *mem_ctx,
> NTSTATUS cli_smb2_delete_on_close_recv(struct tevent_req *req);
> NTSTATUS cli_smb2_delete_on_close(struct cli_state *cli, uint16_t fnum, bool flag);
> NTSTATUS cli_smb2_mkdir(struct cli_state *cli, const char *dirname);
> +struct tevent_req *cli_smb2_rmdir_send(TALLOC_CTX *mem_ctx,
> + struct tevent_context *ev,
> + struct cli_state *cli,
> + const char *dname);
> +NTSTATUS cli_smb2_rmdir_recv(struct tevent_req *req);
> NTSTATUS cli_smb2_rmdir(struct cli_state *cli, const char *dirname);
> NTSTATUS cli_smb2_unlink(struct cli_state *cli,const char *fname);
> NTSTATUS cli_smb2_list(struct cli_state *cli,
> --
> 2.11.0
>
More information about the samba-technical
mailing list