The Samba-Bugzilla – Attachment 13848 Details for
Bug 13159
smbclient symlink/allinfo commands don't work against reparse points over SMB2.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Updated git-am fix for master.
bug-13159-master-p2 (text/plain), 26.46 KB, created by
Jeremy Allison
on 2017-12-05 23:54:07 UTC
(
hide
)
Description:
Updated git-am fix for master.
Filename:
MIME Type:
Creator:
Jeremy Allison
Created:
2017-12-05 23:54:07 UTC
Size:
26.46 KB
patch
obsolete
>From d37445571780a856c3e448c5bccec53475546f20 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Wed, 22 Nov 2017 00:47:48 +0000 >Subject: [PATCH 1/7] s3: libsmb: Rename cli_close_create() -> > cli_smb1_close_create(). >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >Move cli_smb1_close_done() next to its caller. This is SMB1 specific. >Prepare to wrap cli_close_send/cli_close_recv to handle SMB2. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=13159 > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Ralph Böhme <slow@samba.org> >--- > source3/libsmb/clifile.c | 42 +++++++++++++++++++++--------------------- > source3/libsmb/proto.h | 2 +- > source3/torture/test_chain3.c | 2 +- > source3/torture/torture.c | 2 +- > 4 files changed, 24 insertions(+), 24 deletions(-) > >diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c >index e942b27e175..2e3c2426030 100644 >--- a/source3/libsmb/clifile.c >+++ b/source3/libsmb/clifile.c >@@ -2770,22 +2770,22 @@ NTSTATUS cli_open(struct cli_state *cli, const char *fname, int flags, > Close a file. > ****************************************************************************/ > >-struct cli_close_state { >+struct cli_smb1_close_state { > uint16_t vwv[3]; > }; > >-static void cli_close_done(struct tevent_req *subreq); >+static void cli_smb1_close_done(struct tevent_req *subreq); > >-struct tevent_req *cli_close_create(TALLOC_CTX *mem_ctx, >+struct tevent_req *cli_smb1_close_create(TALLOC_CTX *mem_ctx, > struct tevent_context *ev, > struct cli_state *cli, > uint16_t fnum, > struct tevent_req **psubreq) > { > struct tevent_req *req, *subreq; >- struct cli_close_state *state; >+ struct cli_smb1_close_state *state; > >- req = tevent_req_create(mem_ctx, &state, struct cli_close_state); >+ req = tevent_req_create(mem_ctx, &state, struct cli_smb1_close_state); > if (req == NULL) { > return NULL; > } >@@ -2799,11 +2799,25 @@ struct tevent_req *cli_close_create(TALLOC_CTX *mem_ctx, > TALLOC_FREE(req); > return NULL; > } >- tevent_req_set_callback(subreq, cli_close_done, req); >+ tevent_req_set_callback(subreq, cli_smb1_close_done, req); > *psubreq = subreq; > return req; > } > >+static void cli_smb1_close_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ NTSTATUS status; >+ >+ status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); >+ TALLOC_FREE(subreq); >+ if (tevent_req_nterror(req, status)) { >+ return; >+ } >+ tevent_req_done(req); >+} >+ > struct tevent_req *cli_close_send(TALLOC_CTX *mem_ctx, > struct tevent_context *ev, > struct cli_state *cli, >@@ -2812,7 +2826,7 @@ struct tevent_req *cli_close_send(TALLOC_CTX *mem_ctx, > struct tevent_req *req, *subreq; > NTSTATUS status; > >- req = cli_close_create(mem_ctx, ev, cli, fnum, &subreq); >+ req = cli_smb1_close_create(mem_ctx, ev, cli, fnum, &subreq); > if (req == NULL) { > return NULL; > } >@@ -2824,20 +2838,6 @@ struct tevent_req *cli_close_send(TALLOC_CTX *mem_ctx, > return req; > } > >-static void cli_close_done(struct tevent_req *subreq) >-{ >- struct tevent_req *req = tevent_req_callback_data( >- subreq, struct tevent_req); >- NTSTATUS status; >- >- status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); >- TALLOC_FREE(subreq); >- if (tevent_req_nterror(req, status)) { >- return; >- } >- tevent_req_done(req); >-} >- > NTSTATUS cli_close_recv(struct tevent_req *req) > { > return tevent_req_simple_recv_ntstatus(req); >diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h >index 4ae566cca1c..d82de56a238 100644 >--- a/source3/libsmb/proto.h >+++ b/source3/libsmb/proto.h >@@ -423,7 +423,7 @@ struct tevent_req *cli_openx_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev > NTSTATUS cli_openx_recv(struct tevent_req *req, uint16_t *fnum); > NTSTATUS cli_openx(struct cli_state *cli, const char *fname, int flags, int share_mode, uint16_t *pfnum); > NTSTATUS cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode, uint16_t *pfnum); >-struct tevent_req *cli_close_create(TALLOC_CTX *mem_ctx, >+struct tevent_req *cli_smb1_close_create(TALLOC_CTX *mem_ctx, > struct tevent_context *ev, > struct cli_state *cli, uint16_t fnum, > struct tevent_req **psubreq); >diff --git a/source3/torture/test_chain3.c b/source3/torture/test_chain3.c >index cad1a3fb407..eff39de8702 100644 >--- a/source3/torture/test_chain3.c >+++ b/source3/torture/test_chain3.c >@@ -70,7 +70,7 @@ static struct tevent_req *chain3_andx_send(TALLOC_CTX *mem_ctx, > } > tevent_req_set_callback(subreq, chain3_andx_write_done, req); > >- subreq = cli_close_create(state, ev, cli, 0, &smbreqs[2]); >+ subreq = cli_smb1_close_create(state, ev, cli, 0, &smbreqs[2]); > if (tevent_req_nomem(subreq, req)) { > return tevent_req_post(req, ev); > } >diff --git a/source3/torture/torture.c b/source3/torture/torture.c >index cf8b03ca111..87276c09cb3 100644 >--- a/source3/torture/torture.c >+++ b/source3/torture/torture.c >@@ -8066,7 +8066,7 @@ static bool run_chain1(int dummy) > if (reqs[1] == NULL) return false; > tevent_req_set_callback(reqs[1], chain1_write_completion, NULL); > >- reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]); >+ reqs[2] = cli_smb1_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]); > if (reqs[2] == NULL) return false; > tevent_req_set_callback(reqs[2], chain1_close_completion, &done); > >-- >2.15.0.531.g2ccb3012c9-goog > > >From 4768eab30fceebe221422373b84c3798ae6a4218 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Mon, 27 Nov 2017 14:38:49 -0800 >Subject: [PATCH 2/7] s3: libsmb: Make cli_close_send()/cli_close_recv() work > for SMB1 and SMB2. > >Remove the escape into synchronous smb2 code. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=13159 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/libsmb/clifile.c | 51 ++++++++++++++++++++++++++++++++++++++++-------- > 1 file changed, 43 insertions(+), 8 deletions(-) > >diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c >index 2e3c2426030..5f6e98ce460 100644 >--- a/source3/libsmb/clifile.c >+++ b/source3/libsmb/clifile.c >@@ -2818,26 +2818,65 @@ static void cli_smb1_close_done(struct tevent_req *subreq) > tevent_req_done(req); > } > >+struct cli_close_state { >+ int dummy; >+}; >+ >+static void cli_close_done(struct tevent_req *subreq); >+ > struct tevent_req *cli_close_send(TALLOC_CTX *mem_ctx, > struct tevent_context *ev, > struct cli_state *cli, > uint16_t fnum) > { > struct tevent_req *req, *subreq; >+ struct cli_close_state *state; > NTSTATUS status; > >- req = cli_smb1_close_create(mem_ctx, ev, cli, fnum, &subreq); >+ req = tevent_req_create(mem_ctx, &state, struct cli_close_state); > if (req == NULL) { > return NULL; > } > >- status = smb1cli_req_chain_submit(&subreq, 1); >- if (tevent_req_nterror(req, status)) { >- return tevent_req_post(req, ev); >+ if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { >+ subreq = cli_smb2_close_fnum_send(state, >+ ev, >+ cli, >+ fnum); >+ if (tevent_req_nomem(subreq, req)) { >+ return tevent_req_post(req, ev); >+ } >+ } else { >+ struct tevent_req *ch_req = NULL; >+ subreq = cli_smb1_close_create(state, ev, cli, fnum, &ch_req); >+ if (tevent_req_nomem(subreq, req)) { >+ return tevent_req_post(req, ev); >+ } >+ status = smb1cli_req_chain_submit(&ch_req, 1); >+ if (tevent_req_nterror(req, status)) { >+ return tevent_req_post(req, ev); >+ } > } >+ >+ tevent_req_set_callback(subreq, cli_close_done, req); > return req; > } > >+static void cli_close_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ NTSTATUS status = NT_STATUS_OK; >+ bool err = tevent_req_is_nterror(subreq, &status); >+ >+ TALLOC_FREE(subreq); >+ if (err) { >+ tevent_req_nterror(req, status); >+ return; >+ } >+ tevent_req_done(req); >+} >+ > NTSTATUS cli_close_recv(struct tevent_req *req) > { > return tevent_req_simple_recv_ntstatus(req); >@@ -2850,10 +2889,6 @@ NTSTATUS cli_close(struct cli_state *cli, uint16_t fnum) > struct tevent_req *req; > NTSTATUS status = NT_STATUS_OK; > >- if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { >- return cli_smb2_close_fnum(cli, fnum); >- } >- > frame = talloc_stackframe(); > > if (smbXcli_conn_has_async_calls(cli->conn)) { >-- >2.15.0.531.g2ccb3012c9-goog > > >From b9daaf7962efbf4a23665136a74e4af7a01e440c Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 28 Nov 2017 14:09:39 -0800 >Subject: [PATCH 3/7] s3: libsmb: Add SMB2 calls > cli_smb2_set_reparse_point_fnum_send()/cli_smb2_set_reparse_point_fnum_recv(). >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >Allow reparse points to be created over SMB2. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=13159 > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Ralph Böhme <slow@samba.org> >--- > source3/libsmb/cli_smb2_fnum.c | 93 ++++++++++++++++++++++++++++++++++++++++++ > source3/libsmb/cli_smb2_fnum.h | 8 ++++ > 2 files changed, 101 insertions(+) > >diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c >index 78f61fbedd4..f8861e53345 100644 >--- a/source3/libsmb/cli_smb2_fnum.c >+++ b/source3/libsmb/cli_smb2_fnum.c >@@ -4181,3 +4181,96 @@ fail: > TALLOC_FREE(frame); > return status; > } >+ >+struct cli_smb2_set_reparse_point_fnum_state { >+ struct cli_state *cli; >+ uint16_t fnum; >+ struct smb2_hnd *ph; >+ DATA_BLOB input_buffer; >+}; >+ >+static void cli_smb2_set_reparse_point_fnum_done(struct tevent_req *subreq); >+ >+struct tevent_req *cli_smb2_set_reparse_point_fnum_send( >+ TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ struct cli_state *cli, >+ uint16_t fnum, >+ DATA_BLOB in_buf) >+{ >+ struct tevent_req *req, *subreq; >+ struct cli_smb2_set_reparse_point_fnum_state *state = NULL; >+ NTSTATUS status; >+ >+ req = tevent_req_create(mem_ctx, &state, >+ struct cli_smb2_set_reparse_point_fnum_state); >+ if (req == NULL) { >+ return NULL; >+ } >+ >+ if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_SMB2_02) { >+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); >+ return tevent_req_post(req, ev); >+ } >+ >+ state->cli = cli; >+ state->fnum = fnum; >+ >+ status = map_fnum_to_smb2_handle(cli, fnum, &state->ph); >+ if (tevent_req_nterror(req, status)) { >+ return tevent_req_post(req, ev); >+ } >+ >+ state->input_buffer = data_blob_talloc(state, >+ in_buf.data, >+ in_buf.length); >+ if (state->input_buffer.data == NULL) { >+ tevent_req_nterror(req, NT_STATUS_NO_MEMORY); >+ return tevent_req_post(req, ev); >+ } >+ >+ subreq = smb2cli_ioctl_send(state, ev, state->cli->conn, >+ state->cli->timeout, >+ state->cli->smb2.session, >+ state->cli->smb2.tcon, >+ state->ph->fid_persistent, /* in_fid_persistent */ >+ state->ph->fid_volatile, /* in_fid_volatile */ >+ FSCTL_SET_REPARSE_POINT, >+ 0, /* in_max_input_length */ >+ &state->input_buffer , >+ 0, >+ NULL, >+ SMB2_IOCTL_FLAG_IS_FSCTL); >+ >+ if (tevent_req_nomem(subreq, req)) { >+ return tevent_req_post(req, ev); >+ } >+ tevent_req_set_callback(subreq, >+ cli_smb2_set_reparse_point_fnum_done, >+ req); >+ >+ return req; >+} >+ >+static void cli_smb2_set_reparse_point_fnum_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct cli_smb2_set_reparse_point_fnum_state *state = tevent_req_data( >+ req, struct cli_smb2_set_reparse_point_fnum_state); >+ NTSTATUS status; >+ >+ status = smb2cli_ioctl_recv(subreq, state, >+ NULL, >+ NULL); >+ TALLOC_FREE(subreq); >+ if (tevent_req_nterror(req, status)) { >+ return; >+ } >+ tevent_req_done(req); >+} >+ >+NTSTATUS cli_smb2_set_reparse_point_fnum_recv(struct tevent_req *req) >+{ >+ return tevent_req_simple_recv_ntstatus(req); >+} >diff --git a/source3/libsmb/cli_smb2_fnum.h b/source3/libsmb/cli_smb2_fnum.h >index 3d9b6eb3fe6..0f6809fe4ca 100644 >--- a/source3/libsmb/cli_smb2_fnum.h >+++ b/source3/libsmb/cli_smb2_fnum.h >@@ -242,4 +242,12 @@ NTSTATUS cli_smb2_notify(struct cli_state *cli, uint16_t fnum, > bool recursive, TALLOC_CTX *mem_ctx, > struct notify_change **pchanges, > uint32_t *pnum_changes); >+struct tevent_req *cli_smb2_set_reparse_point_fnum_send( >+ TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ struct cli_state *cli, >+ uint16_t fnum, >+ DATA_BLOB in_buf); >+NTSTATUS cli_smb2_set_reparse_point_fnum_recv(struct tevent_req *req); >+ > #endif /* __SMB2CLI_FNUM_H__ */ >-- >2.15.0.531.g2ccb3012c9-goog > > >From b9830c4bf6ec20cdbb5193c81ceab3fad984a365 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 28 Nov 2017 14:10:26 -0800 >Subject: [PATCH 4/7] s3: libsmb: Plumb in the new SMB2 reparse point calls > into the cli_symlink_create_XXX() calls. >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >Reparse point symlinks can now be created over SMB1 and SMB2 from >smbclient. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=13159 > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Ralph Böhme <slow@samba.org> >--- > source3/libsmb/clisymlink.c | 45 ++++++++++++++++++++++++++++++--------------- > 1 file changed, 30 insertions(+), 15 deletions(-) > >diff --git a/source3/libsmb/clisymlink.c b/source3/libsmb/clisymlink.c >index a52f6ff7f6d..202435722c9 100644 >--- a/source3/libsmb/clisymlink.c >+++ b/source3/libsmb/clisymlink.c >@@ -86,8 +86,7 @@ static void cli_symlink_create_done(struct tevent_req *subreq) > subreq, struct tevent_req); > struct cli_symlink_state *state = tevent_req_data( > req, struct cli_symlink_state); >- uint8_t *data; >- size_t data_len; >+ DATA_BLOB data; > NTSTATUS status; > > status = cli_ntcreate_recv(subreq, &state->fnum, NULL); >@@ -96,24 +95,35 @@ static void cli_symlink_create_done(struct tevent_req *subreq) > return; > } > >- SIVAL(state->setup, 0, FSCTL_SET_REPARSE_POINT); >- SSVAL(state->setup, 4, state->fnum); >- SCVAL(state->setup, 6, 1); /* IsFcntl */ >- SCVAL(state->setup, 7, 0); /* IsFlags */ >- > if (!symlink_reparse_buffer_marshall( > state->link_target, NULL, state->flags, state, >- &data, &data_len)) { >+ &data.data, &data.length)) { > tevent_req_oom(req); > return; > } > >- subreq = cli_trans_send(state, state->ev, state->cli, 0, SMBnttrans, >+ if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) { >+ subreq = cli_smb2_set_reparse_point_fnum_send(state, >+ state->ev, >+ state->cli, >+ state->fnum, >+ data); >+ } else { >+ SIVAL(state->setup, 0, FSCTL_SET_REPARSE_POINT); >+ SSVAL(state->setup, 4, state->fnum); >+ SCVAL(state->setup, 6, 1); /* IsFcntl */ >+ SCVAL(state->setup, 7, 0); /* IsFlags */ >+ >+ >+ subreq = cli_trans_send(state, state->ev, state->cli, 0, >+ SMBnttrans, > NULL, -1, /* name, fid */ > NT_TRANSACT_IOCTL, 0, > state->setup, 4, 0, /* setup */ > NULL, 0, 0, /* param */ >- data, data_len, 0); /* data */ >+ data.data, data.length, 0); /* data */ >+ } >+ > if (tevent_req_nomem(subreq, req)) { > return; > } >@@ -127,11 +137,16 @@ static void cli_symlink_set_reparse_done(struct tevent_req *subreq) > struct cli_symlink_state *state = tevent_req_data( > req, struct cli_symlink_state); > >- state->set_reparse_status = cli_trans_recv( >- subreq, NULL, NULL, >- NULL, 0, NULL, /* rsetup */ >- NULL, 0, NULL, /* rparam */ >- NULL, 0, NULL); /* rdata */ >+ if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) { >+ state->set_reparse_status = >+ cli_smb2_set_reparse_point_fnum_recv(subreq); >+ } else { >+ state->set_reparse_status = cli_trans_recv( >+ subreq, NULL, NULL, >+ NULL, 0, NULL, /* rsetup */ >+ NULL, 0, NULL, /* rparam */ >+ NULL, 0, NULL); /* rdata */ >+ } > TALLOC_FREE(subreq); > > if (NT_STATUS_IS_OK(state->set_reparse_status)) { >-- >2.15.0.531.g2ccb3012c9-goog > > >From a8ade808fb0e48f346ba2e88fe67f2c273c1cafb Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 28 Nov 2017 15:46:40 -0800 >Subject: [PATCH 5/7] s3: libsmb: Do a naive response to SMB2 "stopped on > symlink". Assume the last component was the reparse point. >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >Attempt re-open with FILE_OPEN_REPARSE_POINT. This matches the SMB1 >behavior for smbclient. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=13159 > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Ralph Böhme <slow@samba.org> >--- > source3/libsmb/cli_smb2_fnum.c | 65 +++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 64 insertions(+), 1 deletion(-) > >diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c >index f8861e53345..c40d6dd3a45 100644 >--- a/source3/libsmb/cli_smb2_fnum.c >+++ b/source3/libsmb/cli_smb2_fnum.c >@@ -686,6 +686,27 @@ NTSTATUS cli_smb2_rmdir(struct cli_state *cli, const char *dname) > &fnum, > NULL); > >+ if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) { >+ /* >+ * Naive option to match our SMB1 code. Assume the >+ * symlink path that tripped us up was the last >+ * component and try again. Eventually we will have to >+ * deal with the returned path unprocessed component. JRA. >+ */ >+ status = cli_smb2_create_fnum(cli, >+ dname, >+ 0, /* create_flags */ >+ 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| >+ FILE_DELETE_ON_CLOSE| >+ FILE_OPEN_REPARSE_POINT, /* create_options */ >+ &fnum, >+ NULL); >+ } >+ > if (!NT_STATUS_IS_OK(status)) { > return status; > } >@@ -724,6 +745,26 @@ NTSTATUS cli_smb2_unlink(struct cli_state *cli, const char *fname) > &fnum, > NULL); > >+ if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) { >+ /* >+ * Naive option to match our SMB1 code. Assume the >+ * symlink path that tripped us up was the last >+ * component and try again. Eventually we will have to >+ * deal with the returned path unprocessed component. JRA. >+ */ >+ status = cli_smb2_create_fnum(cli, >+ fname, >+ 0, /* create_flags */ >+ DELETE_ACCESS, /* desired_access */ >+ FILE_ATTRIBUTE_NORMAL, /* file attributes */ >+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */ >+ FILE_OPEN, /* create_disposition */ >+ FILE_DELETE_ON_CLOSE| >+ FILE_OPEN_REPARSE_POINT, /* create_options */ >+ &fnum, >+ NULL); >+ } >+ > if (!NT_STATUS_IS_OK(status)) { > return status; > } >@@ -1157,6 +1198,7 @@ static NTSTATUS get_fnum_from_path(struct cli_state *cli, > NTSTATUS status; > size_t namelen = strlen(name); > TALLOC_CTX *frame = talloc_stackframe(); >+ uint32_t create_options = 0; > > /* SMB2 is pickier about pathnames. Ensure it doesn't > end in a '\' */ >@@ -1178,11 +1220,32 @@ static NTSTATUS get_fnum_from_path(struct cli_state *cli, > 0, /* file attributes */ > FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */ > FILE_OPEN, /* create_disposition */ >- 0, /* create_options */ >+ create_options, >+ pfnum, >+ NULL); >+ >+ if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) { >+ /* >+ * Naive option to match our SMB1 code. Assume the >+ * symlink path that tripped us up was the last >+ * component and try again. Eventually we will have to >+ * deal with the returned path unprocessed component. JRA. >+ */ >+ create_options |= FILE_OPEN_REPARSE_POINT; >+ status = cli_smb2_create_fnum(cli, >+ name, >+ 0, /* create_flags */ >+ desired_access, >+ 0, /* file attributes */ >+ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access */ >+ FILE_OPEN, /* create_disposition */ >+ create_options, > pfnum, > NULL); >+ } > > if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) { >+ create_options |= FILE_DIRECTORY_FILE; > status = cli_smb2_create_fnum(cli, > name, > 0, /* create_flags */ >-- >2.15.0.531.g2ccb3012c9-goog > > >From 8c2225efc63a1a700b71a72e005da486ba97de60 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Wed, 29 Nov 2017 12:37:36 -0800 >Subject: [PATCH 6/7] s3: libsmb: Add SMB2 calls > cli_smb2_get_reparse_point_fnum_send()/cli_smb2_get_reparse_point_fnum_recv(). > >Allow reparse points to be queried over SMB2. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=13159 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/libsmb/cli_smb2_fnum.c | 98 ++++++++++++++++++++++++++++++++++++++++++ > source3/libsmb/cli_smb2_fnum.h | 9 ++++ > 2 files changed, 107 insertions(+) > >diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c >index c40d6dd3a45..02eb526830c 100644 >--- a/source3/libsmb/cli_smb2_fnum.c >+++ b/source3/libsmb/cli_smb2_fnum.c >@@ -4337,3 +4337,101 @@ NTSTATUS cli_smb2_set_reparse_point_fnum_recv(struct tevent_req *req) > { > return tevent_req_simple_recv_ntstatus(req); > } >+ >+struct cli_smb2_get_reparse_point_fnum_state { >+ struct cli_state *cli; >+ uint16_t fnum; >+ struct smb2_hnd *ph; >+ DATA_BLOB output_buffer; >+}; >+ >+static void cli_smb2_get_reparse_point_fnum_done(struct tevent_req *subreq); >+ >+struct tevent_req *cli_smb2_get_reparse_point_fnum_send( >+ TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ struct cli_state *cli, >+ uint16_t fnum) >+{ >+ struct tevent_req *req, *subreq; >+ struct cli_smb2_set_reparse_point_fnum_state *state = NULL; >+ NTSTATUS status; >+ >+ req = tevent_req_create(mem_ctx, &state, >+ struct cli_smb2_get_reparse_point_fnum_state); >+ if (req == NULL) { >+ return NULL; >+ } >+ >+ if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_SMB2_02) { >+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); >+ return tevent_req_post(req, ev); >+ } >+ >+ state->cli = cli; >+ state->fnum = fnum; >+ >+ status = map_fnum_to_smb2_handle(cli, fnum, &state->ph); >+ if (tevent_req_nterror(req, status)) { >+ return tevent_req_post(req, ev); >+ } >+ >+ subreq = smb2cli_ioctl_send(state, ev, state->cli->conn, >+ state->cli->timeout, >+ state->cli->smb2.session, >+ state->cli->smb2.tcon, >+ state->ph->fid_persistent, /* in_fid_persistent */ >+ state->ph->fid_volatile, /* in_fid_volatile */ >+ FSCTL_GET_REPARSE_POINT, >+ 0, /* in_max_input_length */ >+ NULL, >+ 64*1024, >+ NULL, >+ SMB2_IOCTL_FLAG_IS_FSCTL); >+ >+ if (tevent_req_nomem(subreq, req)) { >+ return tevent_req_post(req, ev); >+ } >+ tevent_req_set_callback(subreq, >+ cli_smb2_get_reparse_point_fnum_done, >+ req); >+ >+ return req; >+} >+ >+static void cli_smb2_get_reparse_point_fnum_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct cli_smb2_get_reparse_point_fnum_state *state = tevent_req_data( >+ req, struct cli_smb2_get_reparse_point_fnum_state); >+ NTSTATUS status; >+ >+ status = smb2cli_ioctl_recv(subreq, state, >+ NULL, >+ &state->output_buffer); >+ TALLOC_FREE(subreq); >+ if (tevent_req_nterror(req, status)) { >+ state->cli->raw_status = status; >+ return; >+ } >+ tevent_req_done(req); >+} >+ >+NTSTATUS cli_smb2_get_reparse_point_fnum_recv(struct tevent_req *req, >+ TALLOC_CTX *mem_ctx, >+ DATA_BLOB *output) >+{ >+ struct cli_smb2_get_reparse_point_fnum_state *state = tevent_req_data( >+ req, struct cli_smb2_get_reparse_point_fnum_state); >+ >+ if (tevent_req_is_nterror(req, &state->cli->raw_status)) { >+ return state->cli->raw_status; >+ } >+ *output = data_blob_dup_talloc(mem_ctx, state->output_buffer); >+ if (output->data == NULL) { >+ return NT_STATUS_NO_MEMORY; >+ } >+ tevent_req_received(req); >+ return NT_STATUS_OK; >+} >diff --git a/source3/libsmb/cli_smb2_fnum.h b/source3/libsmb/cli_smb2_fnum.h >index 0f6809fe4ca..0ceddd0b9ab 100644 >--- a/source3/libsmb/cli_smb2_fnum.h >+++ b/source3/libsmb/cli_smb2_fnum.h >@@ -250,4 +250,13 @@ struct tevent_req *cli_smb2_set_reparse_point_fnum_send( > DATA_BLOB in_buf); > NTSTATUS cli_smb2_set_reparse_point_fnum_recv(struct tevent_req *req); > >+struct tevent_req *cli_smb2_get_reparse_point_fnum_send( >+ TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ struct cli_state *cli, >+ uint16_t fnum); >+NTSTATUS cli_smb2_get_reparse_point_fnum_recv(struct tevent_req *req, >+ TALLOC_CTX *mem_ctx, >+ DATA_BLOB *output); >+ > #endif /* __SMB2CLI_FNUM_H__ */ >-- >2.15.0.531.g2ccb3012c9-goog > > >From 615c4def8104f1a91e4fb6f1280d21fd506de54f Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Wed, 29 Nov 2017 12:38:08 -0800 >Subject: [PATCH 7/7] s3: libsmb: Plumb in the new SMB2 get reparse point calls > into the cli_readlink_XXXX() calls. >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > >Reparse point symlinks can now be queried over SMB1 and SMB2 from smbclient. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=13159 > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Ralph Böhme <slow@samba.org> >--- > source3/libsmb/clisymlink.c | 41 +++++++++++++++++++++++++++++++---------- > 1 file changed, 31 insertions(+), 10 deletions(-) > >diff --git a/source3/libsmb/clisymlink.c b/source3/libsmb/clisymlink.c >index 202435722c9..54435e468cd 100644 >--- a/source3/libsmb/clisymlink.c >+++ b/source3/libsmb/clisymlink.c >@@ -296,17 +296,26 @@ static void cli_readlink_opened(struct tevent_req *subreq) > return; > } > >- SIVAL(state->setup, 0, FSCTL_GET_REPARSE_POINT); >- SSVAL(state->setup, 4, state->fnum); >- SCVAL(state->setup, 6, 1); /* IsFcntl */ >- SCVAL(state->setup, 7, 0); /* IsFlags */ >+ if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) { >+ subreq = cli_smb2_get_reparse_point_fnum_send(state, >+ state->ev, >+ state->cli, >+ state->fnum); >+ } else { >+ SIVAL(state->setup, 0, FSCTL_GET_REPARSE_POINT); >+ SSVAL(state->setup, 4, state->fnum); >+ SCVAL(state->setup, 6, 1); /* IsFcntl */ >+ SCVAL(state->setup, 7, 0); /* IsFlags */ > >- subreq = cli_trans_send(state, state->ev, state->cli, 0, SMBnttrans, >+ subreq = cli_trans_send(state, state->ev, state->cli, >+ 0, SMBnttrans, > NULL, -1, /* name, fid */ > NT_TRANSACT_IOCTL, 0, > state->setup, 4, 0, /* setup */ > NULL, 0, 0, /* param */ > NULL, 0, 16384); /* data */ >+ } >+ > if (tevent_req_nomem(subreq, req)) { > return; > } >@@ -320,11 +329,23 @@ static void cli_readlink_got_reparse_data(struct tevent_req *subreq) > struct cli_readlink_state *state = tevent_req_data( > req, struct cli_readlink_state); > >- state->get_reparse_status = cli_trans_recv( >- subreq, state, NULL, >- NULL, 0, NULL, /* rsetup */ >- NULL, 0, NULL, /* rparam */ >- &state->data, 20, &state->num_data); /* rdata */ >+ if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) { >+ DATA_BLOB recv_data; >+ state->get_reparse_status = >+ cli_smb2_get_reparse_point_fnum_recv(subreq, >+ state, >+ &recv_data); >+ if (NT_STATUS_IS_OK(state->get_reparse_status)) { >+ state->data = recv_data.data; >+ state->num_data = recv_data.length; >+ } >+ } else { >+ state->get_reparse_status = cli_trans_recv( >+ subreq, state, NULL, >+ NULL, 0, NULL, /* rsetup */ >+ NULL, 0, NULL, /* rparam */ >+ &state->data, 20, &state->num_data); /* rdata */ >+ } > TALLOC_FREE(subreq); > > subreq = cli_close_send(state, state->ev, state->cli, state->fnum); >-- >2.15.0.531.g2ccb3012c9-goog >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 13159
:
13825
|
13836
| 13848