From: David Mulder Date: Mon, 13 Jan 2020 16:19:51 +0000 (-0700) Subject: Implement alt name query for smb2 X-Git-Tag: ldb-2.2.0~850 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=18db8bd9c4e78f4897154432464e51074ecaf0f9;p=thirdparty%2Fsamba.git Implement alt name query for smb2 Implements smb2_qpathinfo_alt_name() and RAW_FILEINFO_SMB2_ALT_NAME_INFORMATION. Signed-off-by: David Mulder Reviewed-by: Noel Power Reviewed-by: Jeremy Allison (cherry picked from commit 097df343ce21c8340aee7f42f233fe74b92b47e2) --- diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index 2a344f71148..5b398ee2ced 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -464,7 +464,8 @@ enum smb_fileinfo_level { 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 + RAW_FILEINFO_SMB2_ALL_INFORMATION = 0x1201, + RAW_FILEINFO_SMB2_ALT_NAME_INFORMATION = 0x1501 }; /* union used in qfileinfo() and qpathinfo() backend calls */ @@ -646,6 +647,7 @@ union smb_fileinfo { /* 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 */ + /* RAW_FILEINFO_SMB2_ALT_NAME_INFORMATION interface */ struct { enum smb_fileinfo_level level; struct { diff --git a/source4/libcli/raw/rawfileinfo.c b/source4/libcli/raw/rawfileinfo.c index 235b3cd0fa2..b18bc87b6c3 100644 --- a/source4/libcli/raw/rawfileinfo.c +++ b/source4/libcli/raw/rawfileinfo.c @@ -158,6 +158,7 @@ NTSTATUS smb_raw_fileinfo_passthru_parse(const DATA_BLOB *blob, TALLOC_CTX *mem_ return NT_STATUS_OK; case RAW_FILEINFO_ALT_NAME_INFORMATION: + case RAW_FILEINFO_SMB2_ALT_NAME_INFORMATION: FINFO_CHECK_MIN_SIZE(4); smbcli_blob_pull_string(NULL, mem_ctx, blob, &parms->alt_name_info.out.fname, 0, 4, STR_UNICODE); @@ -470,6 +471,10 @@ static NTSTATUS smb_raw_info_backend(struct smbcli_session *session, return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, RAW_FILEINFO_SMB2_ALL_EAS, parms); + case RAW_FILEINFO_SMB2_ALT_NAME_INFORMATION: + return smb_raw_fileinfo_passthru_parse(blob, mem_ctx, + RAW_FILEINFO_SMB2_ALT_NAME_INFORMATION, parms); + } return NT_STATUS_INVALID_LEVEL; diff --git a/source4/libcli/smb2/util.c b/source4/libcli/smb2/util.c index 882dcb9468b..b2efabb5a44 100644 --- a/source4/libcli/smb2/util.c +++ b/source4/libcli/smb2/util.c @@ -285,3 +285,56 @@ bool smb2_util_handle_empty(const struct smb2_handle h) return smb2_util_handle_equal(h, empty); } + +/**************************************************************************** +send a qpathinfo SMB_QUERY_FILE_ALT_NAME_INFO call +****************************************************************************/ +NTSTATUS smb2_qpathinfo_alt_name(TALLOC_CTX *ctx, struct smb2_tree *tree, + const char *fname, const char **alt_name) +{ + union smb_fileinfo parms; + TALLOC_CTX *mem_ctx; + NTSTATUS status; + struct smb2_create create_io = {0}; + + mem_ctx = talloc_new(ctx); + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + + create_io.in.desired_access = SEC_FILE_READ_ATTRIBUTE; + create_io.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + create_io.in.create_disposition = FILE_OPEN; + create_io.in.fname = fname; + status = smb2_create(tree, mem_ctx, &create_io); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx); + return status; + } + + parms.alt_name_info.level = RAW_FILEINFO_SMB2_ALT_NAME_INFORMATION; + parms.alt_name_info.in.file.handle = create_io.out.file.handle; + + status = smb2_getinfo_file(tree, mem_ctx, &parms); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx); + return status; + } + + status = smb2_util_close(tree, create_io.out.file.handle); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx); + return status; + } + + if (!parms.alt_name_info.out.fname.s) { + *alt_name = talloc_strdup(ctx, ""); + } else { + *alt_name = talloc_strdup(ctx, + parms.alt_name_info.out.fname.s); + } + + talloc_free(mem_ctx); + + return NT_STATUS_OK; +} diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 69e046c9143..be6bc830ced 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -862,6 +862,7 @@ NTSTATUS ntvfs_map_fileinfo(TALLOC_CTX *mem_ctx, case RAW_FILEINFO_ALT_NAME_INFO: case RAW_FILEINFO_ALT_NAME_INFORMATION: + case RAW_FILEINFO_SMB2_ALT_NAME_INFORMATION: info->alt_name_info.out.fname.s = talloc_strdup(mem_ctx, info2->generic.out.alt_fname.s); NT_STATUS_HAVE_NO_MEMORY(info->alt_name_info.out.fname.s); info->alt_name_info.out.fname.private_length = info2->generic.out.alt_fname.private_length; diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 53cde69b1b7..be601a26f97 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -254,6 +254,7 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, case RAW_FILEINFO_ALT_NAME_INFO: case RAW_FILEINFO_ALT_NAME_INFORMATION: + case RAW_FILEINFO_SMB2_ALT_NAME_INFORMATION: info->name_info.out.fname.s = pvfs_short_name(pvfs, name, name); return NT_STATUS_OK; diff --git a/source4/torture/gentest.c b/source4/torture/gentest.c index 76712b52397..f6cf4aa28b7 100644 --- a/source4/torture/gentest.c +++ b/source4/torture/gentest.c @@ -1640,6 +1640,7 @@ static bool cmp_fileinfo(int instance, case RAW_FILEINFO_ALT_NAME_INFO: case RAW_FILEINFO_ALT_NAME_INFORMATION: + case RAW_FILEINFO_SMB2_ALT_NAME_INFORMATION: CHECK_WSTR_EQUAL(alt_name_info.out.fname); break;