The branch, master has been updated via b20fd15e04c smbd: implement SMB_FILE_NORMALIZED_NAME_INFORMATION handling via 8a5828de2bd s4:torture/smb2: add smb2.getinfo.normalized test via 0c602319194 s4:libcli/raw: add RAW_FILEINFO_NORMALIZED_NAME_INFORMATION support via 2a69c091558 smbd: allow case insensitive opens of named streams via b5c4fdbf99c s4:torture/smb2: add smb2.stream.names3 test from bd53819b28b script/attr_count_read: load and correlate all data
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit b20fd15e04ce9292f90a7f70f4184e43034b4b9d Author: Stefan Metzmacher <me...@samba.org> Date: Thu Apr 25 14:57:33 2019 +0200 smbd: implement SMB_FILE_NORMALIZED_NAME_INFORMATION handling Windows 10 (1803 and higher) support and use SMB_FILE_NORMALIZED_NAME_INFORMATION calls over the network. As a fallback (in case the server don't support it) the client traverses all path components, which is very expensive. Implementing SMB_FILE_NORMALIZED_NAME_INFORMATION is very cheap for us as the open already went through unix_convert() and we have the information the client is asking for. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13919 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Wed May 1 18:33:00 UTC 2019 on sn-devel-184 commit 8a5828de2bdd95223e5f30996d0490fef53742dd Author: Stefan Metzmacher <me...@samba.org> Date: Thu Apr 25 14:57:02 2019 +0200 s4:torture/smb2: add smb2.getinfo.normalized test BUG: https://bugzilla.samba.org/show_bug.cgi?id=13919 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 0c602319194bda6b2a0efdd7c186078583f79264 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Apr 25 12:12:34 2019 +0200 s4:libcli/raw: add RAW_FILEINFO_NORMALIZED_NAME_INFORMATION support This is supported over the wire in SMB 3.1.1 on starting with Windows 10 1803. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13919 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 2a69c0915586fb9fb2148239965d06bf9f93c803 Author: Stefan Metzmacher <me...@samba.org> Date: Thu Apr 25 17:30:43 2019 +0200 smbd: allow case insensitive opens of named streams BUG: https://bugzilla.samba.org/show_bug.cgi?id=13919 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit b5c4fdbf99caa3a9e7c6446cfbc4f1b23b84b3c8 Author: Stefan Metzmacher <me...@samba.org> Date: Mon Apr 29 14:53:13 2019 +0200 s4:torture/smb2: add smb2.stream.names3 test BUG: https://bugzilla.samba.org/show_bug.cgi?id=13919 Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> ----------------------------------------------------------------------- Summary of changes: source3/smbd/filename.c | 72 +++++++- source3/smbd/smb2_getinfo.c | 9 + source3/smbd/trans2.c | 57 +++++++ source4/libcli/raw/interfaces.h | 16 +- source4/libcli/raw/rawfileinfo.c | 11 ++ source4/libcli/raw/trans2.h | 1 + source4/ntvfs/ntvfs_generic.c | 2 + source4/ntvfs/posix/pvfs_qfileinfo.c | 2 + source4/torture/gentest.c | 4 + source4/torture/smb2/getinfo.c | 311 +++++++++++++++++++++++++++++++++++ source4/torture/smb2/streams.c | 115 +++++++++++++ 11 files changed, 587 insertions(+), 13 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c index 568bef897a0..5e29e7c18a8 100644 --- a/source3/smbd/filename.c +++ b/source3/smbd/filename.c @@ -1374,6 +1374,76 @@ static bool fname_equal(const char *name1, const char *name2, return(strequal(name1,name2)); } +static bool sname_equal(const char *name1, const char *name2, + bool case_sensitive) +{ + bool match; + const char *s1 = NULL; + const char *s2 = NULL; + size_t n1; + size_t n2; + const char *e1 = NULL; + const char *e2 = NULL; + char *c1 = NULL; + char *c2 = NULL; + + match = fname_equal(name1, name2, case_sensitive); + if (match) { + return true; + } + + if (name1[0] != ':') { + return false; + } + if (name2[0] != ':') { + return false; + } + s1 = &name1[1]; + e1 = strchr(s1, ':'); + if (e1 == NULL) { + n1 = strlen(s1); + } else { + n1 = PTR_DIFF(e1, s1); + } + s2 = &name2[1]; + e2 = strchr(s2, ':'); + if (e2 == NULL) { + n2 = strlen(s2); + } else { + n2 = PTR_DIFF(e2, s2); + } + + /* Normal filename handling */ + if (case_sensitive) { + return (strncmp(s1, s2, n1) == 0); + } + + /* + * We can't use strnequal() here + * as it takes the number of codepoints + * and not the number of bytes. + * + * So we make a copy before calling + * strequal(). + * + * Note that we TALLOC_FREE() in reverse order + * in order to avoid memory fragmentation. + */ + + c1 = talloc_strndup(talloc_tos(), s1, n1); + c2 = talloc_strndup(talloc_tos(), s2, n2); + if (c1 == NULL || c2 == NULL) { + TALLOC_FREE(c2); + TALLOC_FREE(c1); + return (strncmp(s1, s2, n1) == 0); + } + + match = strequal(c1, c2); + TALLOC_FREE(c2); + TALLOC_FREE(c1); + return match; +} + /**************************************************************************** Scan a directory to find a filename, matching without case sensitivity. If the name looks like a mangled name then try via the mangling functions @@ -1570,7 +1640,7 @@ static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx, for (i=0; i<num_streams; i++) { DEBUG(10, ("comparing [%s] and [%s]: ", smb_fname->stream_name, streams[i].name)); - if (fname_equal(smb_fname->stream_name, streams[i].name, + if (sname_equal(smb_fname->stream_name, streams[i].name, conn->case_sensitive)) { DEBUGADD(10, ("equal\n")); break; diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index 9ec252c172b..006f313c63f 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -318,6 +318,15 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx, break; } + switch (file_info_level) { + case SMB_FILE_NORMALIZED_NAME_INFORMATION: + if (smb2req->xconn->protocol < PROTOCOL_SMB3_11) { + tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED); + return tevent_req_post(req, ev); + } + break; + } + if (fsp->fake_file_handle) { /* * This is actually for the QUOTA_FAKE_FILE --metze diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 017ad068877..fe406adb58f 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -5214,6 +5214,63 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, break; } + case SMB_FILE_NORMALIZED_NAME_INFORMATION: + { + char *nfname = NULL; + + if (!fsp->conn->sconn->using_smb2) { + return NT_STATUS_INVALID_LEVEL; + } + + nfname = talloc_strdup(mem_ctx, smb_fname->base_name); + if (nfname == NULL) { + return NT_STATUS_NO_MEMORY; + } + + if (ISDOT(nfname)) { + nfname[0] = '\0'; + } + string_replace(nfname, '/', '\\'); + + if (smb_fname->stream_name != NULL) { + const char *s = smb_fname->stream_name; + const char *e = NULL; + size_t n; + + SMB_ASSERT(s[0] != '\0'); + + /* + * smb_fname->stream_name is in form + * of ':StrEam:$DATA', but we should only + * append ':StrEam' here. + */ + + e = strchr(&s[1], ':'); + if (e == NULL) { + n = strlen(s); + } else { + n = PTR_DIFF(e, s); + } + nfname = talloc_strndup_append(nfname, s, n); + if (nfname == NULL) { + return NT_STATUS_NO_MEMORY; + } + } + + status = srvstr_push(dstart, flags2, + pdata+4, nfname, + PTR_DIFF(dend, pdata+4), + STR_UNICODE, &len); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NORMALIZED_NAME_INFORMATION\n")); + data_size = 4 + len; + SIVAL(pdata,0,len); + *fixed_portion = 8; + break; + } + case SMB_FILE_ALLOCATION_INFORMATION: case SMB_QUERY_FILE_ALLOCATION_INFO: DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALLOCATION_INFORMATION\n")); diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 19b29197e16..2a344f71148 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -461,6 +461,7 @@ enum smb_fileinfo_level { RAW_FILEINFO_COMPRESSION_INFORMATION = SMB_QFILEINFO_COMPRESSION_INFORMATION, RAW_FILEINFO_NETWORK_OPEN_INFORMATION = SMB_QFILEINFO_NETWORK_OPEN_INFORMATION, RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION = SMB_QFILEINFO_ATTRIBUTE_TAG_INFORMATION, + RAW_FILEINFO_NORMALIZED_NAME_INFORMATION= SMB_QFILEINFO_NORMALIZED_NAME_INFORMATION, /* SMB2 specific levels */ RAW_FILEINFO_SMB2_ALL_EAS = 0x0f01, RAW_FILEINFO_SMB2_ALL_INFORMATION = 0x1201 @@ -643,6 +644,8 @@ union smb_fileinfo { } ea_info; /* RAW_FILEINFO_NAME_INFO and RAW_FILEINFO_NAME_INFORMATION interfaces */ + /* RAW_FILEINFO_ALT_NAME_INFO and RAW_FILEINFO_ALT_NAME_INFORMATION interfaces */ + /* RAW_FILEINFO_NORMALIZED_NAME_INFORMATION interface */ struct { enum smb_fileinfo_level level; struct { @@ -651,7 +654,7 @@ union smb_fileinfo { struct { struct smb_wire_string fname; } out; - } name_info; + } name_info, alt_name_info, normalized_name_info; /* RAW_FILEINFO_ALL_INFO and RAW_FILEINFO_ALL_INFORMATION interfaces */ struct { @@ -704,17 +707,6 @@ union smb_fileinfo { } out; } all_info2; - /* RAW_FILEINFO_ALT_NAME_INFO and RAW_FILEINFO_ALT_NAME_INFORMATION interfaces */ - struct { - enum smb_fileinfo_level level; - struct { - union smb_handle_or_path file; - } in; - struct { - struct smb_wire_string fname; - } out; - } alt_name_info; - /* RAW_FILEINFO_STREAM_INFO and RAW_FILEINFO_STREAM_INFORMATION interfaces */ struct { enum smb_fileinfo_level level; diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 50a6731ba41..a2599085ab7 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -219,6 +219,13 @@ NTSTATUS smb_raw_fileinfo_passthru_parse(const DATA_BLOB *blob, TALLOC_CTX *mem_ parms->attribute_tag_information.out.reparse_tag = IVAL(blob->data, 4); return NT_STATUS_OK; + case RAW_FILEINFO_NORMALIZED_NAME_INFORMATION: + FINFO_CHECK_MIN_SIZE(4); + smbcli_blob_pull_string(NULL, mem_ctx, blob, + &parms->normalized_name_info.out.fname, + 0, 4, STR_UNICODE); + return NT_STATUS_OK; + case RAW_FILEINFO_SMB2_ALL_EAS: FINFO_CHECK_MIN_SIZE(4); return ea_pull_list_chained(blob, mem_ctx, @@ -443,6 +450,10 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION, parms); + case RAW_FILEINFO_NORMALIZED_NAME_INFORMATION: + return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, + RAW_FILEINFO_NORMALIZED_NAME_INFORMATION, parms); + case RAW_FILEINFO_SMB2_ALL_INFORMATION: return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, RAW_FILEINFO_SMB2_ALL_INFORMATION, parms); diff --git a/source4/libcli/raw/trans2.h b/source4/libcli/raw/trans2.h index b7cfc6d0e8b..f93b1f1d35b 100644 --- a/source4/libcli/raw/trans2.h +++ b/source4/libcli/raw/trans2.h @@ -139,6 +139,7 @@ Found 8 aliased levels #define SMB_QFILEINFO_COMPRESSION_INFORMATION 1028 #define SMB_QFILEINFO_NETWORK_OPEN_INFORMATION 1034 #define SMB_QFILEINFO_ATTRIBUTE_TAG_INFORMATION 1035 +#define SMB_QFILEINFO_NORMALIZED_NAME_INFORMATION 1048 diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index fe68b4132bc..69e046c9143 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -960,6 +960,8 @@ NTSTATUS ntvfs_map_fileinfo(TALLOC_CTX *mem_ctx, case RAW_FILEINFO_SMB2_ALL_EAS: case RAW_FILEINFO_SMB2_ALL_INFORMATION: return NT_STATUS_INVALID_LEVEL; + case RAW_FILEINFO_NORMALIZED_NAME_INFORMATION: + return NT_STATUS_NOT_SUPPORTED; } return NT_STATUS_INVALID_LEVEL; diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 33ff9ce3cba..53cde69b1b7 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -342,6 +342,8 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, case RAW_FILEINFO_UNIX_INFO2: case RAW_FILEINFO_UNIX_LINK: return NT_STATUS_INVALID_LEVEL; + case RAW_FILEINFO_NORMALIZED_NAME_INFORMATION: + return NT_STATUS_NOT_SUPPORTED; } return NT_STATUS_INVALID_LEVEL; diff --git a/source4/torture/gentest.c b/source4/torture/gentest.c index 868e13bdc0f..490db6402ac 100644 --- a/source4/torture/gentest.c +++ b/source4/torture/gentest.c @@ -1697,6 +1697,10 @@ static bool cmp_fileinfo(int instance, CHECK_EQUAL(attribute_tag_information.out.reparse_tag); break; + case RAW_FILEINFO_NORMALIZED_NAME_INFORMATION: + CHECK_WSTR_EQUAL(normalized_name_info.out.fname); + break; + case RAW_FILEINFO_SMB2_ALL_INFORMATION: CHECK_NTTIMES_EQUAL(all_info2.out.create_time); CHECK_NTTIMES_EQUAL(all_info2.out.access_time); diff --git a/source4/torture/smb2/getinfo.c b/source4/torture/smb2/getinfo.c index 2e36082e067..5c9097f4200 100644 --- a/source4/torture/smb2/getinfo.c +++ b/source4/torture/smb2/getinfo.c @@ -170,6 +170,315 @@ static bool torture_smb2_fileinfo_grant_read(struct torture_context *tctx) return true; } +static bool torture_smb2_fileinfo_normalized(struct torture_context *tctx) +{ + struct smb2_tree *tree = NULL; + bool ret; + struct smb2_handle hroot; + const char *d1 = NULL, *d1l = NULL, *d1u = NULL; + struct smb2_handle hd1, hd1l, hd1u; + const char *d2 = NULL, *d2l = NULL, *d2u = NULL; + struct smb2_handle hd2, hd2l, hd2u; + const char *d3 = NULL, *d3l = NULL, *d3u = NULL; + struct smb2_handle hd3, hd3l, hd3u; + const char *d3s = NULL, *d3sl = NULL, *d3su = NULL, *d3sd = NULL; + struct smb2_handle hd3s, hd3sl, hd3su, hd3sd; + const char *f4 = NULL, *f4l = NULL, *f4u = NULL, *f4d = NULL; + struct smb2_handle hf4, hf4l, hf4u, hf4d; + const char *f4s = NULL, *f4sl = NULL, *f4su = NULL, *f4sd = NULL; + struct smb2_handle hf4s, hf4sl, hf4su, hf4sd; + union smb_fileinfo info = { + .normalized_name_info = { + .level = RAW_FILEINFO_NORMALIZED_NAME_INFORMATION, + }, + }; + NTSTATUS status; + enum protocol_types protocol; + struct smb2_tree *tree_3_0 = NULL; + struct smbcli_options options3_0; + struct smb2_handle hroot_3_0; + + ret = torture_smb2_connection(tctx, &tree); + torture_assert(tctx, ret, "connection failed"); + + protocol = smbXcli_conn_protocol(tree->session->transport->conn); + + d1 = talloc_asprintf(tctx, "torture_dIr1N"); + torture_assert_not_null(tctx, d1, "d1"); + d1l = strlower_talloc(tctx, d1); + torture_assert_not_null(tctx, d1l, "d1l"); + d1u = strupper_talloc(tctx, d1); + torture_assert_not_null(tctx, d1u, "d1u"); + + d2 = talloc_asprintf(tctx, "%s\\dIr2Na", d1); + torture_assert_not_null(tctx, d2, "d2"); + d2l = strlower_talloc(tctx, d2); + torture_assert_not_null(tctx, d2l, "d2l"); + d2u = strupper_talloc(tctx, d2); + torture_assert_not_null(tctx, d2u, "d2u"); + + d3 = talloc_asprintf(tctx, "%s\\dIr3NaM", d2); + torture_assert_not_null(tctx, d3, "d3"); + d3l = strlower_talloc(tctx, d3); + torture_assert_not_null(tctx, d3l, "d3l"); + d3u = strupper_talloc(tctx, d3); + torture_assert_not_null(tctx, d3u, "d3u"); + + d3s = talloc_asprintf(tctx, "%s:sTrEaM3", d3); + torture_assert_not_null(tctx, d3s, "d3s"); + d3sl = strlower_talloc(tctx, d3s); + torture_assert_not_null(tctx, d3sl, "d3sl"); + d3su = strupper_talloc(tctx, d3s); + torture_assert_not_null(tctx, d3su, "d3su"); + d3sd = talloc_asprintf(tctx, "%s:$DaTa", d3s); + torture_assert_not_null(tctx, d3sd, "d3sd"); + + f4 = talloc_asprintf(tctx, "%s\\fIlE4NaMe", d3); + torture_assert_not_null(tctx, f4, "f4"); + f4l = strlower_talloc(tctx, f4); + torture_assert_not_null(tctx, f4l, "f4l"); + f4u = strupper_talloc(tctx, f4); + torture_assert_not_null(tctx, f4u, "f4u"); + f4d = talloc_asprintf(tctx, "%s::$dAtA", f4); + torture_assert_not_null(tctx, f4d, "f4d"); + + f4s = talloc_asprintf(tctx, "%s:StReAm4", f4); + torture_assert_not_null(tctx, f4s, "f4s"); + f4sl = strlower_talloc(tctx, f4s); + torture_assert_not_null(tctx, f4sl, "f4sl"); + f4su = strupper_talloc(tctx, f4s); + torture_assert_not_null(tctx, f4su, "f4su"); + f4sd = talloc_asprintf(tctx, "%s:$dAtA", f4s); + torture_assert_not_null(tctx, f4sd, "f4sd"); + + status = smb2_util_roothandle(tree, &hroot); + torture_assert_ntstatus_ok(tctx, status, "Unable to create root handle"); + + info.normalized_name_info.in.file.handle = hroot; + ZERO_STRUCT(info.normalized_name_info.out); + status = smb2_getinfo_file(tree, tree, &info); + if (protocol < PROTOCOL_SMB3_11) { + /* + * Only SMB 3.1.1 and above should offer this. + */ + torture_assert_ntstatus_equal(tctx, status, + NT_STATUS_NOT_SUPPORTED, + "getinfo hroot"); + torture_skip(tctx, "SMB 3.1.1 not supported"); + } + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { + /* + * Not all servers support this. + * (only Windows 10 1803 and higher) + */ + torture_skip(tctx, "NORMALIZED_NAME_INFORMATION not supported"); + } + torture_assert_ntstatus_ok(tctx, status, "getinfo hroot"); + torture_assert(tctx, info.normalized_name_info.out.fname.s == NULL, + "getinfo hroot should be empty"); + + smb2_deltree(tree, d1); + + status = torture_smb2_testdir(tree, d1, &hd1); + torture_assert_ntstatus_ok(tctx, status, "Unable to create hd1"); + status = torture_smb2_open(tree, d1l, SEC_RIGHTS_FILE_ALL, &hd1l); + torture_assert_ntstatus_ok(tctx, status, "Unable to open hd1l"); + status = torture_smb2_open(tree, d1u, SEC_RIGHTS_FILE_ALL, &hd1u); + torture_assert_ntstatus_ok(tctx, status, "Unable to open hd1u"); + + status = torture_smb2_testdir(tree, d2, &hd2); + torture_assert_ntstatus_ok(tctx, status, "Unable to create hd2"); + status = torture_smb2_open(tree, d2l, SEC_RIGHTS_FILE_ALL, &hd2l); + torture_assert_ntstatus_ok(tctx, status, "Unable to open hd2l"); + status = torture_smb2_open(tree, d2u, SEC_RIGHTS_FILE_ALL, &hd2u); + torture_assert_ntstatus_ok(tctx, status, "Unable to open hd2u"); + + status = torture_smb2_testdir(tree, d3, &hd3); + torture_assert_ntstatus_ok(tctx, status, "Unable to create hd3"); + status = torture_smb2_open(tree, d3l, SEC_RIGHTS_FILE_ALL, &hd3l); + torture_assert_ntstatus_ok(tctx, status, "Unable to open hd3l"); + status = torture_smb2_open(tree, d3u, SEC_RIGHTS_FILE_ALL, &hd3u); + torture_assert_ntstatus_ok(tctx, status, "Unable to open hd3u"); + + status = torture_smb2_testfile(tree, d3s, &hd3s); + torture_assert_ntstatus_ok(tctx, status, "Unable to create hd3s"); + status = torture_smb2_open(tree, d3sl, SEC_RIGHTS_FILE_ALL, &hd3sl); + torture_assert_ntstatus_ok(tctx, status, "Unable to open hd3sl"); + status = torture_smb2_open(tree, d3su, SEC_RIGHTS_FILE_ALL, &hd3su); + torture_assert_ntstatus_ok(tctx, status, "Unable to open hd3su"); + status = torture_smb2_open(tree, d3sd, SEC_RIGHTS_FILE_ALL, &hd3sd); + torture_assert_ntstatus_ok(tctx, status, "Unable to open hd3sd"); + + status = torture_smb2_testfile(tree, f4, &hf4); + torture_assert_ntstatus_ok(tctx, status, "Unable to create hf4"); + status = torture_smb2_open(tree, f4l, SEC_RIGHTS_FILE_ALL, &hf4l); + torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4l"); + status = torture_smb2_open(tree, f4u, SEC_RIGHTS_FILE_ALL, &hf4u); + torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4u"); + status = torture_smb2_open(tree, f4d, SEC_RIGHTS_FILE_ALL, &hf4d); + torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4d"); + + status = torture_smb2_testfile(tree, f4s, &hf4s); + torture_assert_ntstatus_ok(tctx, status, "Unable to create hf4s"); + status = torture_smb2_open(tree, f4sl, SEC_RIGHTS_FILE_ALL, &hf4sl); + torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4sl"); + status = torture_smb2_open(tree, f4su, SEC_RIGHTS_FILE_ALL, &hf4su); + torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4su"); + status = torture_smb2_open(tree, f4sd, SEC_RIGHTS_FILE_ALL, &hf4sd); + torture_assert_ntstatus_ok(tctx, status, "Unable to open hf4sd"); + + info.normalized_name_info.in.file.handle = hd1; + ZERO_STRUCT(info.normalized_name_info.out); + status = smb2_getinfo_file(tree, tree, &info); + torture_assert_ntstatus_ok(tctx, status, "getinfo hd1"); + torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s, + d1, "getinfo hd1"); + info.normalized_name_info.in.file.handle = hd1l; + ZERO_STRUCT(info.normalized_name_info.out); + status = smb2_getinfo_file(tree, tree, &info); + torture_assert_ntstatus_ok(tctx, status, "getinfo hd1l"); + torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s, + d1, "getinfo hd1l"); + info.normalized_name_info.in.file.handle = hd1u; + ZERO_STRUCT(info.normalized_name_info.out); + status = smb2_getinfo_file(tree, tree, &info); + torture_assert_ntstatus_ok(tctx, status, "getinfo hd1u"); + torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s, + d1, "getinfo hd1u"); + + info.normalized_name_info.in.file.handle = hd2; + ZERO_STRUCT(info.normalized_name_info.out); + status = smb2_getinfo_file(tree, tree, &info); + torture_assert_ntstatus_ok(tctx, status, "getinfo hd2"); + torture_assert_str_equal(tctx, info.normalized_name_info.out.fname.s, + d2, "getinfo hd2"); + info.normalized_name_info.in.file.handle = hd2l; + ZERO_STRUCT(info.normalized_name_info.out); -- Samba Shared Repository