#include <smbsrv/smb2_kproto.h>
#include <smbsrv/smb_fsops.h>
#include <smbsrv/ntifs.h>
smb_sdrc_t
smb2_query_info(smb_request_t *sr)
{
smb_queryinfo_t *qi;
uint16_t StructSize;
uint32_t oBufLength;
uint16_t iBufOffset;
uint32_t iBufLength;
smb2fid_t smb2fid;
uint16_t DataOff;
uint32_t status;
int rc = 0;
qi = smb_srm_zalloc(sr, sizeof (*qi));
rc = smb_mbc_decodef(
&sr->smb_data, "wbblw..lllqq",
&StructSize,
&qi->qi_InfoType,
&qi->qi_InfoClass,
&oBufLength,
&iBufOffset,
&iBufLength,
&qi->qi_AddlInfo,
&qi->qi_Flags,
&smb2fid.persistent,
&smb2fid.temporal);
if (rc || StructSize != 41)
return (SDRC_ERROR);
if (iBufLength) {
rc = MBC_SHADOW_CHAIN(&qi->in_data, &sr->smb_data,
sr->smb2_cmd_hdr + iBufOffset, iBufLength);
if (rc) {
return (SDRC_ERROR);
}
}
if (oBufLength > smb2_max_trans)
oBufLength = smb2_max_trans;
sr->raw_data.max_bytes = oBufLength;
status = smb2sr_lookup_fid(sr, &smb2fid);
DTRACE_SMB2_START(op__QueryInfo, smb_request_t *, sr);
if (status)
goto errout;
switch (qi->qi_InfoType) {
case SMB2_0_INFO_FILE:
status = smb2_qinfo_file(sr, qi);
break;
case SMB2_0_INFO_FILESYSTEM:
status = smb2_qinfo_fs(sr, qi);
break;
case SMB2_0_INFO_SECURITY:
status = smb2_qinfo_sec(sr, qi);
break;
case SMB2_0_INFO_QUOTA:
status = smb2_qinfo_quota(sr, qi);
break;
default:
status = NT_STATUS_INVALID_PARAMETER;
break;
}
errout:
sr->smb2_status = status;
DTRACE_SMB2_DONE(op__QueryInfo, smb_request_t *, sr);
switch (status) {
case 0:
break;
case NT_STATUS_BUFFER_OVERFLOW:
break;
case NT_STATUS_BUFFER_TOO_SMALL:
if (sr->session->dialect < SMB_VERS_3_11) {
smb2sr_put_error_data(sr, status, &sr->raw_data);
} else {
smb2sr_put_error_ctx0(sr, status, &sr->raw_data);
}
return (SDRC_SUCCESS);
case NT_STATUS_INFO_LENGTH_MISMATCH:
if (sr->session->dialect < SMB_VERS_3_11) {
smb2sr_put_error_data(sr, status, NULL);
} else {
smb2sr_put_error_ctx0(sr, status, NULL);
}
return (SDRC_SUCCESS);
default:
smb2sr_put_error(sr, status);
return (SDRC_SUCCESS);
}
DataOff = SMB2_HDR_SIZE + 8;
oBufLength = MBC_LENGTH(&sr->raw_data);
rc = smb_mbc_encodef(
&sr->reply, "wwlC",
9,
DataOff,
oBufLength,
&sr->raw_data);
if (rc)
sr->smb2_status = NT_STATUS_INTERNAL_ERROR;
return (SDRC_SUCCESS);
}