[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