The Samba-Bugzilla – Attachment 12399 Details for
Bug 12166
smbclient allinfo doesn't correctly return 'previous version' info over SMB2
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
git-am fix for 4.5.0
bug-12166-4.5.0 (text/plain), 20.28 KB, created by
Jeremy Allison
on 2016-08-24 23:46:01 UTC
(
hide
)
Description:
git-am fix for 4.5.0
Filename:
MIME Type:
Creator:
Jeremy Allison
Created:
2016-08-24 23:46:01 UTC
Size:
20.28 KB
patch
obsolete
>From b43f4602b81841f978b0228279788b4842195315 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Fri, 19 Aug 2016 16:58:39 -0700 >Subject: [PATCH 1/5] s3: libsmb: Correctly align create contexts in a create > call. > >SMB2 shadow copy requests are the first time we've used >create contexts in anger in this codepath. This took me >longer than I'd like to admit to find :-). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12166 > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Uri Simchoni <uri@samba.org> >(cherry picked from commit f8caadfc78a15fa3aefc9ef6249195767c47aa8f) >--- > libcli/smb/smb2cli_create.c | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/libcli/smb/smb2cli_create.c b/libcli/smb/smb2cli_create.c >index 0db546c..778b501 100644 >--- a/libcli/smb/smb2cli_create.c >+++ b/libcli/smb/smb2cli_create.c >@@ -113,6 +113,7 @@ struct tevent_req *smb2cli_create_send( > blobs_offset = ((blobs_offset + 3) & ~3); > > if (blob.length > 0) { >+ blobs_offset = ((blobs_offset + 7) & ~7); > SIVAL(fixed, 48, blobs_offset + SMB2_HDR_BODY + 56); > SIVAL(fixed, 52, blob.length); > } >-- >2.8.0.rc3.226.g39d4020 > > >From 6e3464ab52bc36ef16ca1d804ba260f4248272a0 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 18 Aug 2016 17:15:01 -0700 >Subject: [PATCH 2/5] s3: libsmb: Add return args to > clistr_is_previous_version_path(). > >Not yet used - we will use these to construct the SMB2 TWrp blob. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12166 > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Uri Simchoni <uri@samba.org> >(cherry picked from commit 14fd6dca4ef33ee85a2f8578f1ad608d6056da1f) >--- > source3/libsmb/clifile.c | 28 ++++++++++++++-------------- > source3/libsmb/clilist.c | 4 ++-- > source3/libsmb/clistr.c | 17 ++++++++++++++++- > source3/libsmb/proto.h | 5 ++++- > 4 files changed, 36 insertions(+), 18 deletions(-) > >diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c >index 0964b3a..75ec3a2 100644 >--- a/source3/libsmb/clifile.c >+++ b/source3/libsmb/clifile.c >@@ -197,7 +197,7 @@ struct tevent_req *cli_setpathinfo_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >- if (clistr_is_previous_version_path(path) && >+ if (clistr_is_previous_version_path(path, NULL, NULL, NULL) && > !INFO_LEVEL_IS_UNIX(level)) { > additional_flags2 = FLAGS2_REPARSE_PATH; > } >@@ -1155,7 +1155,7 @@ struct tevent_req *cli_rename_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >- if (clistr_is_previous_version_path(fname_src)) { >+ if (clistr_is_previous_version_path(fname_src, NULL, NULL, NULL)) { > additional_flags2 = FLAGS2_REPARSE_PATH; > } > >@@ -1290,7 +1290,7 @@ static struct tevent_req *cli_ntrename_internal_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >- if (clistr_is_previous_version_path(fname_src)) { >+ if (clistr_is_previous_version_path(fname_src, NULL, NULL, NULL)) { > additional_flags2 = FLAGS2_REPARSE_PATH; > } > >@@ -1495,7 +1495,7 @@ struct tevent_req *cli_unlink_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >- if (clistr_is_previous_version_path(fname)) { >+ if (clistr_is_previous_version_path(fname, NULL, NULL, NULL)) { > additional_flags2 = FLAGS2_REPARSE_PATH; > } > >@@ -1610,7 +1610,7 @@ struct tevent_req *cli_mkdir_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >- if (clistr_is_previous_version_path(dname)) { >+ if (clistr_is_previous_version_path(dname, NULL, NULL, NULL)) { > additional_flags2 = FLAGS2_REPARSE_PATH; > } > >@@ -1725,7 +1725,7 @@ struct tevent_req *cli_rmdir_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >- if (clistr_is_previous_version_path(dname)) { >+ if (clistr_is_previous_version_path(dname, NULL, NULL, NULL)) { > additional_flags2 = FLAGS2_REPARSE_PATH; > } > >@@ -1978,7 +1978,7 @@ static struct tevent_req *cli_ntcreate1_send(TALLOC_CTX *mem_ctx, > fname, strlen(fname)+1, > &converted_len); > >- if (clistr_is_previous_version_path(fname)) { >+ if (clistr_is_previous_version_path(fname, NULL, NULL, NULL)) { > additional_flags2 = FLAGS2_REPARSE_PATH; > } > >@@ -2282,7 +2282,7 @@ struct tevent_req *cli_nttrans_create_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >- if (clistr_is_previous_version_path(fname)) { >+ if (clistr_is_previous_version_path(fname, NULL, NULL, NULL)) { > additional_flags2 = FLAGS2_REPARSE_PATH; > } > >@@ -2508,7 +2508,7 @@ struct tevent_req *cli_openx_create(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >- if (clistr_is_previous_version_path(fname)) { >+ if (clistr_is_previous_version_path(fname, NULL, NULL, NULL)) { > additional_flags2 = FLAGS2_REPARSE_PATH; > } > >@@ -3765,7 +3765,7 @@ struct tevent_req *cli_getatr_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >- if (clistr_is_previous_version_path(fname)) { >+ if (clistr_is_previous_version_path(fname, NULL, NULL, NULL)) { > additional_flags2 = FLAGS2_REPARSE_PATH; > } > >@@ -4057,7 +4057,7 @@ struct tevent_req *cli_setatr_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >- if (clistr_is_previous_version_path(fname)) { >+ if (clistr_is_previous_version_path(fname, NULL, NULL, NULL)) { > additional_flags2 = FLAGS2_REPARSE_PATH; > } > >@@ -4178,7 +4178,7 @@ struct tevent_req *cli_chkpath_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >- if (clistr_is_previous_version_path(fname)) { >+ if (clistr_is_previous_version_path(fname, NULL, NULL, NULL)) { > additional_flags2 = FLAGS2_REPARSE_PATH; > } > >@@ -4489,7 +4489,7 @@ struct tevent_req *cli_ctemp_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >- if (clistr_is_previous_version_path(path)) { >+ if (clistr_is_previous_version_path(path, NULL, NULL, NULL)) { > additional_flags2 = FLAGS2_REPARSE_PATH; > } > >@@ -5651,7 +5651,7 @@ struct tevent_req *cli_qpathinfo_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >- if (clistr_is_previous_version_path(fname) && >+ if (clistr_is_previous_version_path(fname, NULL, NULL, NULL) && > !INFO_LEVEL_IS_UNIX(level)) { > additional_flags2 = FLAGS2_REPARSE_PATH; > } >diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c >index d6116f0..41f5851 100644 >--- a/source3/libsmb/clilist.c >+++ b/source3/libsmb/clilist.c >@@ -600,7 +600,7 @@ static struct tevent_req *cli_list_trans_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >- if (clistr_is_previous_version_path(state->mask)) { >+ if (clistr_is_previous_version_path(state->mask, NULL, NULL, NULL)) { > additional_flags2 = FLAGS2_REPARSE_PATH; > } > >@@ -792,7 +792,7 @@ static void cli_list_trans_done(struct tevent_req *subreq) > } > param_len = talloc_get_size(state->param); > >- if (clistr_is_previous_version_path(state->mask)) { >+ if (clistr_is_previous_version_path(state->mask, NULL, NULL, NULL)) { > additional_flags2 = FLAGS2_REPARSE_PATH; > } > >diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c >index c3611be..154b9a1 100644 >--- a/source3/libsmb/clistr.c >+++ b/source3/libsmb/clistr.c >@@ -38,7 +38,10 @@ size_t clistr_pull_talloc(TALLOC_CTX *ctx, > flags); > } > >-bool clistr_is_previous_version_path(const char *path) >+bool clistr_is_previous_version_path(const char *path, >+ const char **startp, >+ const char **endp, >+ time_t *ptime) > { > char *q; > time_t timestamp; >@@ -63,5 +66,17 @@ bool clistr_is_previous_version_path(const char *path) > if (q[0] != '\0' && q[0] != '\\') { > return false; > } >+ if (startp) { >+ *startp = p; >+ } >+ if (endp) { >+ if (q[0] == '\\') { >+ q++; >+ } >+ *endp = q; >+ } >+ if (ptime) { >+ *ptime = timestamp; >+ } > return true; > } >diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h >index f9bb985..c0e1b74 100644 >--- a/source3/libsmb/proto.h >+++ b/source3/libsmb/proto.h >@@ -868,7 +868,10 @@ size_t clistr_pull_talloc(TALLOC_CTX *ctx, > const void *src, > int src_len, > int flags); >-bool clistr_is_previous_version_path(const char *path); >+bool clistr_is_previous_version_path(const char *path, >+ const char **startp, >+ const char **endp, >+ time_t *ptime); > > /* The following definitions come from libsmb/clitrans.c */ > >-- >2.8.0.rc3.226.g39d4020 > > >From 105f4118ac18e8e5a0a3668d26dc2dad1b6253d7 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 16 Aug 2016 15:26:53 -0700 >Subject: [PATCH 3/5] s3: libsmb: Add cli_smb2_shadow_copy_data() function that > gets shadow copy info over SMB2. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12166 > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Uri Simchoni <uri@samba.org> >(cherry picked from commit 0c6329bc152fcf08fcef385d2f7ee829485eb1a6) >--- > source3/libsmb/cli_smb2_fnum.c | 229 +++++++++++++++++++++++++++++++++++++++++ > source3/libsmb/cli_smb2_fnum.h | 6 ++ > 2 files changed, 235 insertions(+) > >diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c >index c5b1434..70fa798 100644 >--- a/source3/libsmb/cli_smb2_fnum.c >+++ b/source3/libsmb/cli_smb2_fnum.c >@@ -39,6 +39,7 @@ > #include "../libcli/security/security.h" > #include "lib/util_ea.h" > #include "librpc/gen_ndr/ndr_ioctl.h" >+#include "ntioctl.h" > > struct smb2_hnd { > uint64_t fid_persistent; >@@ -2873,3 +2874,231 @@ NTSTATUS cli_smb2_splice_recv(struct tevent_req *req, off_t *written) > tevent_req_received(req); > return NT_STATUS_OK; > } >+ >+/*************************************************************** >+ SMB2 enum shadow copy data. >+***************************************************************/ >+ >+struct cli_smb2_shadow_copy_data_fnum_state { >+ struct cli_state *cli; >+ uint16_t fnum; >+ struct smb2_hnd *ph; >+ DATA_BLOB out_input_buffer; >+ DATA_BLOB out_output_buffer; >+}; >+ >+static void cli_smb2_shadow_copy_data_fnum_done(struct tevent_req *subreq); >+ >+static struct tevent_req *cli_smb2_shadow_copy_data_fnum_send( >+ TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ struct cli_state *cli, >+ uint16_t fnum, >+ bool get_names) >+{ >+ struct tevent_req *req, *subreq; >+ struct cli_smb2_close_fnum_state *state; >+ NTSTATUS status; >+ >+ req = tevent_req_create(mem_ctx, &state, >+ struct cli_smb2_shadow_copy_data_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); >+ } >+ >+ /* >+ * TODO. Under SMB2 we should send a zero max_output_length >+ * ioctl to get the required size, then send another ioctl >+ * to get the data, but the current SMB1 implementation just >+ * does one roundtrip with a 64K buffer size. Do the same >+ * for now. JRA. >+ */ >+ >+ 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_SHADOW_COPY_DATA, >+ 0, /* in_max_input_length */ >+ NULL, /* in_input_buffer */ >+ get_names ? >+ CLI_BUFFER_SIZE : 16, /* in_max_output_length */ >+ NULL, /* in_output_buffer */ >+ SMB2_IOCTL_FLAG_IS_FSCTL); >+ >+ if (tevent_req_nomem(subreq, req)) { >+ return tevent_req_post(req, ev); >+ } >+ tevent_req_set_callback(subreq, >+ cli_smb2_shadow_copy_data_fnum_done, >+ req); >+ >+ return req; >+} >+ >+static void cli_smb2_shadow_copy_data_fnum_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = tevent_req_callback_data( >+ subreq, struct tevent_req); >+ struct cli_smb2_shadow_copy_data_fnum_state *state = tevent_req_data( >+ req, struct cli_smb2_shadow_copy_data_fnum_state); >+ NTSTATUS status; >+ >+ status = smb2cli_ioctl_recv(subreq, state, >+ &state->out_input_buffer, >+ &state->out_output_buffer); >+ TALLOC_FREE(subreq); >+ if (tevent_req_nterror(req, status)) { >+ return; >+ } >+ tevent_req_done(req); >+} >+ >+static NTSTATUS cli_smb2_shadow_copy_data_fnum_recv(struct tevent_req *req, >+ TALLOC_CTX *mem_ctx, >+ bool get_names, >+ char ***pnames, >+ int *pnum_names) >+{ >+ struct cli_smb2_shadow_copy_data_fnum_state *state = tevent_req_data( >+ req, struct cli_smb2_shadow_copy_data_fnum_state); >+ char **names = NULL; >+ uint32_t num_names = 0; >+ uint32_t num_names_returned = 0; >+ uint32_t dlength = 0; >+ uint32_t i; >+ uint8_t *endp = NULL; >+ NTSTATUS status; >+ >+ if (tevent_req_is_nterror(req, &status)) { >+ return status; >+ } >+ >+ if (state->out_output_buffer.length < 16) { >+ return NT_STATUS_INVALID_NETWORK_RESPONSE; >+ } >+ >+ num_names = IVAL(state->out_output_buffer.data, 0); >+ num_names_returned = IVAL(state->out_output_buffer.data, 4); >+ dlength = IVAL(state->out_output_buffer.data, 8); >+ >+ if (num_names > 0x7FFFFFFF) { >+ return NT_STATUS_INVALID_NETWORK_RESPONSE; >+ } >+ >+ if (get_names == false) { >+ *pnum_names = (int)num_names; >+ return NT_STATUS_OK; >+ } >+ if (num_names != num_names_returned) { >+ return NT_STATUS_INVALID_NETWORK_RESPONSE; >+ } >+ if (dlength + 12 < 12) { >+ return NT_STATUS_INVALID_NETWORK_RESPONSE; >+ } >+ /* >+ * NB. The below is an allowable return if there are >+ * more snapshots than the buffer size we told the >+ * server we can receive. We currently don't support >+ * this. >+ */ >+ if (dlength + 12 > state->out_output_buffer.length) { >+ return NT_STATUS_INVALID_NETWORK_RESPONSE; >+ } >+ if (state->out_output_buffer.length + >+ (2 * sizeof(SHADOW_COPY_LABEL)) < >+ state->out_output_buffer.length) { >+ return NT_STATUS_INVALID_NETWORK_RESPONSE; >+ } >+ >+ names = talloc_array(mem_ctx, char *, num_names_returned); >+ if (names == NULL) { >+ return NT_STATUS_NO_MEMORY; >+ } >+ >+ endp = state->out_output_buffer.data + >+ state->out_output_buffer.length; >+ >+ for (i=0; i<num_names_returned; i++) { >+ bool ret; >+ uint8_t *src; >+ size_t converted_size; >+ >+ src = state->out_output_buffer.data + 12 + >+ (i * 2 * sizeof(SHADOW_COPY_LABEL)); >+ >+ if (src + (2 * sizeof(SHADOW_COPY_LABEL)) > endp) { >+ return NT_STATUS_INVALID_NETWORK_RESPONSE; >+ } >+ ret = convert_string_talloc( >+ names, CH_UTF16LE, CH_UNIX, >+ src, 2 * sizeof(SHADOW_COPY_LABEL), >+ &names[i], &converted_size); >+ if (!ret) { >+ TALLOC_FREE(names); >+ return NT_STATUS_INVALID_NETWORK_RESPONSE; >+ } >+ } >+ *pnum_names = num_names; >+ *pnames = names; >+ return NT_STATUS_OK; >+} >+ >+NTSTATUS cli_smb2_shadow_copy_data(TALLOC_CTX *mem_ctx, >+ struct cli_state *cli, >+ uint16_t fnum, >+ bool get_names, >+ char ***pnames, >+ int *pnum_names) >+{ >+ TALLOC_CTX *frame = talloc_stackframe(); >+ struct tevent_context *ev; >+ struct tevent_req *req; >+ NTSTATUS status = NT_STATUS_NO_MEMORY; >+ >+ 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_shadow_copy_data_fnum_send(frame, >+ ev, >+ cli, >+ fnum, >+ get_names); >+ if (req == NULL) { >+ goto fail; >+ } >+ if (!tevent_req_poll_ntstatus(req, ev, &status)) { >+ goto fail; >+ } >+ status = cli_smb2_shadow_copy_data_fnum_recv(req, >+ mem_ctx, >+ get_names, >+ pnames, >+ pnum_names); >+ fail: >+ TALLOC_FREE(frame); >+ return status; >+} >diff --git a/source3/libsmb/cli_smb2_fnum.h b/source3/libsmb/cli_smb2_fnum.h >index ceb5629..0436c68 100644 >--- a/source3/libsmb/cli_smb2_fnum.h >+++ b/source3/libsmb/cli_smb2_fnum.h >@@ -184,4 +184,10 @@ struct tevent_req *cli_smb2_splice_send(TALLOC_CTX *mem_ctx, > off_t size, off_t src_offset, off_t dst_offset, > int (*splice_cb)(off_t n, void *priv), void *priv); > NTSTATUS cli_smb2_splice_recv(struct tevent_req *req, off_t *written); >+NTSTATUS cli_smb2_shadow_copy_data(TALLOC_CTX *mem_ctx, >+ struct cli_state *cli, >+ uint16_t fnum, >+ bool get_names, >+ char ***pnames, >+ int *pnum_names); > #endif /* __SMB2CLI_FNUM_H__ */ >-- >2.8.0.rc3.226.g39d4020 > > >From 82b20089cd707210860c20a1a5369f97ac3a2689 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Tue, 16 Aug 2016 15:27:55 -0700 >Subject: [PATCH 4/5] s3: libsmb: Plumb new SMB2 shadow copy call into > cli_shadow_copy_data(). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12166 > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Uri Simchoni <uri@samba.org> >(cherry picked from commit 03bf1f858d1c474f9522cb0f5b264c4f6c2ca5b9) >--- > source3/libsmb/clifile.c | 13 ++++++++++++- > 1 file changed, 12 insertions(+), 1 deletion(-) > >diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c >index 75ec3a2..fca7c91 100644 >--- a/source3/libsmb/clifile.c >+++ b/source3/libsmb/clifile.c >@@ -6116,11 +6116,22 @@ NTSTATUS cli_shadow_copy_data(TALLOC_CTX *mem_ctx, struct cli_state *cli, > uint16_t fnum, bool get_names, > char ***pnames, int *pnum_names) > { >- TALLOC_CTX *frame = talloc_stackframe(); >+ TALLOC_CTX *frame = NULL; > struct tevent_context *ev; > struct tevent_req *req; > NTSTATUS status = NT_STATUS_NO_MEMORY; > >+ if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { >+ return cli_smb2_shadow_copy_data(mem_ctx, >+ cli, >+ fnum, >+ get_names, >+ pnames, >+ pnum_names); >+ } >+ >+ frame = talloc_stackframe(); >+ > if (smbXcli_conn_has_async_calls(cli->conn)) { > /* > * Can't use sync call while an async call is in flight >-- >2.8.0.rc3.226.g39d4020 > > >From cbeab8b94dbca4a9f975c1cb7d47691abe6bef37 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Fri, 19 Aug 2016 17:00:25 -0700 >Subject: [PATCH 5/5] s3: libsmb: Add the capability to find a @GMT- path in an > SMB2 create and transform to a timewarp token. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12166 > >Signed-off-by: Jeremy Allison <jra@samba.org> >Reviewed-by: Uri Simchoni <uri@samba.org> > >Autobuild-User(master): Jeremy Allison <jra@samba.org> >Autobuild-Date(master): Mon Aug 22 22:59:22 CEST 2016 on sn-devel-144 > >(cherry picked from commit 272f5c95cfb3d8035939dada7bd473058c7b6517) >--- > source3/libsmb/cli_smb2_fnum.c | 45 ++++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 43 insertions(+), 2 deletions(-) > >diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c >index 70fa798..ac72090 100644 >--- a/source3/libsmb/cli_smb2_fnum.c >+++ b/source3/libsmb/cli_smb2_fnum.c >@@ -178,6 +178,10 @@ struct tevent_req *cli_smb2_create_fnum_send(TALLOC_CTX *mem_ctx, > struct tevent_req *req, *subreq; > struct cli_smb2_create_fnum_state *state; > size_t fname_len = 0; >+ 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); >@@ -195,14 +199,51 @@ struct tevent_req *cli_smb2_create_fnum_send(TALLOC_CTX *mem_ctx, > create_options |= FILE_OPEN_FOR_BACKUP_INTENT; > } > >+ /* Check for @GMT- paths. Remove the @GMT and turn into TWrp if so. */ >+ fname_len = strlen(fname); >+ if (clistr_is_previous_version_path(fname, &startp, &endp, &tstamp)) { >+ size_t len_before_gmt = startp - fname; >+ 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); >+ >+ if (tevent_req_nomem(new_fname, req)) { >+ return tevent_req_post(req, ev); >+ } >+ >+ memcpy(new_fname, fname, len_before_gmt); >+ memcpy(new_fname + len_before_gmt, endp, len_after_gmt + 1); >+ fname = new_fname; >+ fname_len = len_before_gmt + len_after_gmt; >+ >+ 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); >+ 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 == '\\') { > fname++; >+ fname_len--; > } > > /* Or end in a '\' */ >- fname_len = strlen(fname); > if (fname_len > 0 && fname[fname_len-1] == '\\') { > char *new_fname = talloc_strdup(state, fname); > if (tevent_req_nomem(new_fname, req)) { >@@ -225,7 +266,7 @@ struct tevent_req *cli_smb2_create_fnum_send(TALLOC_CTX *mem_ctx, > share_access, > create_disposition, > create_options, >- NULL); >+ cblobs); > if (tevent_req_nomem(subreq, req)) { > return tevent_req_post(req, ev); > } >-- >2.8.0.rc3.226.g39d4020 >
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
Flags:
uri
:
review+
Actions:
View
Attachments on
bug 12166
:
12380
| 12399