[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