[PATCH] Add cblobs to cli_smb2_create_fnum_send

Volker Lendecke Volker.Lendecke at SerNet.DE
Thu Feb 28 19:47:58 UTC 2019


Hi!

Also make cli_smb2_rmdir asynchronous.

Review appreciated!

Thanks, Volker

-- 
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
-------------- next part --------------
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