This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
+#include "libcli/raw/libcliraw.h"
+#include "librpc/gen_ndr/ndr_misc.h"
/****************************************************************************
Query FS Info - SMBdskattr call (async send)
****************************************************************************/
-static struct cli_request *smb_raw_dskattr_send(struct cli_tree *tree,
+static struct smbcli_request *smb_raw_dskattr_send(struct smbcli_tree *tree,
union smb_fsinfo *fsinfo)
{
- struct cli_request *req;
+ struct smbcli_request *req;
- req = cli_request_setup(tree, SMBdskattr, 0, 0);
+ req = smbcli_request_setup(tree, SMBdskattr, 0, 0);
- if (!cli_request_send(req)) {
- cli_request_destroy(req);
+ if (!smbcli_request_send(req)) {
+ smbcli_request_destroy(req);
return NULL;
}
/****************************************************************************
Query FS Info - SMBdskattr call (async recv)
****************************************************************************/
-static NTSTATUS smb_raw_dskattr_recv(struct cli_request *req,
+static NTSTATUS smb_raw_dskattr_recv(struct smbcli_request *req,
union smb_fsinfo *fsinfo)
{
- if (!cli_request_receive(req) ||
- cli_request_is_error(req)) {
+ if (!smbcli_request_receive(req) ||
+ smbcli_request_is_error(req)) {
goto failed;
}
- CLI_CHECK_WCT(req, 5);
+ SMBCLI_CHECK_WCT(req, 5);
fsinfo->dskattr.out.units_total = SVAL(req->in.vwv, VWV(0));
fsinfo->dskattr.out.blocks_per_unit = SVAL(req->in.vwv, VWV(1));
fsinfo->dskattr.out.block_size = SVAL(req->in.vwv, VWV(2));
fsinfo->dskattr.out.units_free = SVAL(req->in.vwv, VWV(3));
failed:
- return cli_request_destroy(req);
+ return smbcli_request_destroy(req);
}
/****************************************************************************
RAW_QFS_ trans2 interface via blobs (async send)
****************************************************************************/
-static struct cli_request *smb_raw_qfsinfo_send(struct cli_tree *tree,
+static struct smbcli_request *smb_raw_qfsinfo_send(struct smbcli_tree *tree,
TALLOC_CTX *mem_ctx,
uint16_t info_level)
{
tp.in.timeout = 0;
tp.in.setup_count = 1;
tp.in.max_param = 0;
- tp.in.max_data = 0x1000; /* plenty for all possible QFS levels */
+ tp.in.max_data = 0xFFFF;
tp.in.setup = &setup;
tp.in.data = data_blob(NULL, 0);
tp.in.timeout = 0;
/****************************************************************************
RAW_QFS_ trans2 interface via blobs (async recv)
****************************************************************************/
-static NTSTATUS smb_raw_qfsinfo_blob_recv(struct cli_request *req,
+static NTSTATUS smb_raw_qfsinfo_blob_recv(struct smbcli_request *req,
TALLOC_CTX *mem_ctx,
DATA_BLOB *blob)
{
/* local macros to make the code more readable */
#define QFS_CHECK_MIN_SIZE(size) if (blob.length < (size)) { \
DEBUG(1,("Unexpected QFS reply size %d for level %u - expected min of %d\n", \
- blob.length, fsinfo->generic.level, (size))); \
+ (int)blob.length, fsinfo->generic.level, (size))); \
status = NT_STATUS_INFO_LENGTH_MISMATCH; \
goto failed; \
}
#define QFS_CHECK_SIZE(size) if (blob.length != (size)) { \
DEBUG(1,("Unexpected QFS reply size %d for level %u - expected %d\n", \
- blob.length, fsinfo->generic.level, (size))); \
+ (int)blob.length, fsinfo->generic.level, (size))); \
status = NT_STATUS_INFO_LENGTH_MISMATCH; \
goto failed; \
}
/****************************************************************************
Query FSInfo raw interface (async send)
****************************************************************************/
-struct cli_request *smb_raw_fsinfo_send(struct cli_tree *tree,
+struct smbcli_request *smb_raw_fsinfo_send(struct smbcli_tree *tree,
TALLOC_CTX *mem_ctx,
union smb_fsinfo *fsinfo)
{
return smb_raw_qfsinfo_send(tree, mem_ctx, info_level);
}
+/*
+ parse the fsinfo 'passthru' level replies
+*/
+NTSTATUS smb_raw_fsinfo_passthru_parse(DATA_BLOB blob, TALLOC_CTX *mem_ctx,
+ enum smb_fsinfo_level level,
+ union smb_fsinfo *fsinfo)
+{
+ NTSTATUS status = NT_STATUS_OK;
+ int i;
+
+ /* parse the results */
+ switch (level) {
+ case RAW_QFS_VOLUME_INFORMATION:
+ QFS_CHECK_MIN_SIZE(18);
+ fsinfo->volume_info.out.create_time = smbcli_pull_nttime(blob.data, 0);
+ fsinfo->volume_info.out.serial_number = IVAL(blob.data, 8);
+ smbcli_blob_pull_string(NULL, mem_ctx, &blob,
+ &fsinfo->volume_info.out.volume_name,
+ 12, 18, STR_UNICODE);
+ break;
+
+ case RAW_QFS_SIZE_INFORMATION:
+ QFS_CHECK_SIZE(24);
+ fsinfo->size_info.out.total_alloc_units = BVAL(blob.data, 0);
+ fsinfo->size_info.out.avail_alloc_units = BVAL(blob.data, 8);
+ fsinfo->size_info.out.sectors_per_unit = IVAL(blob.data, 16);
+ fsinfo->size_info.out.bytes_per_sector = IVAL(blob.data, 20);
+ break;
+
+ case RAW_QFS_DEVICE_INFORMATION:
+ QFS_CHECK_SIZE(8);
+ fsinfo->device_info.out.device_type = IVAL(blob.data, 0);
+ fsinfo->device_info.out.characteristics = IVAL(blob.data, 4);
+ break;
+
+ case RAW_QFS_ATTRIBUTE_INFORMATION:
+ QFS_CHECK_MIN_SIZE(12);
+ fsinfo->attribute_info.out.fs_attr = IVAL(blob.data, 0);
+ fsinfo->attribute_info.out.max_file_component_length = IVAL(blob.data, 4);
+ smbcli_blob_pull_string(NULL, mem_ctx, &blob,
+ &fsinfo->attribute_info.out.fs_type,
+ 8, 12, STR_UNICODE);
+ break;
+
+ case RAW_QFS_QUOTA_INFORMATION:
+ QFS_CHECK_SIZE(48);
+ fsinfo->quota_information.out.unknown[0] = BVAL(blob.data, 0);
+ fsinfo->quota_information.out.unknown[1] = BVAL(blob.data, 8);
+ fsinfo->quota_information.out.unknown[2] = BVAL(blob.data, 16);
+ fsinfo->quota_information.out.quota_soft = BVAL(blob.data, 24);
+ fsinfo->quota_information.out.quota_hard = BVAL(blob.data, 32);
+ fsinfo->quota_information.out.quota_flags = BVAL(blob.data, 40);
+ break;
+
+ case RAW_QFS_FULL_SIZE_INFORMATION:
+ QFS_CHECK_SIZE(32);
+ fsinfo->full_size_information.out.total_alloc_units = BVAL(blob.data, 0);
+ fsinfo->full_size_information.out.call_avail_alloc_units = BVAL(blob.data, 8);
+ fsinfo->full_size_information.out.actual_avail_alloc_units = BVAL(blob.data, 16);
+ fsinfo->full_size_information.out.sectors_per_unit = IVAL(blob.data, 24);
+ fsinfo->full_size_information.out.bytes_per_sector = IVAL(blob.data, 28);
+ break;
+
+ case RAW_QFS_OBJECTID_INFORMATION:
+ QFS_CHECK_SIZE(64);
+ status = ndr_pull_struct_blob(&blob, mem_ctx, &fsinfo->objectid_information.out.guid,
+ (ndr_pull_flags_fn_t)ndr_pull_GUID);
+ for (i=0;i<6;i++) {
+ fsinfo->objectid_information.out.unknown[i] = BVAL(blob.data, 16 + i*8);
+ }
+ break;
+
+ default:
+ status = NT_STATUS_INVALID_INFO_CLASS;
+ }
+
+failed:
+ return status;
+}
+
/****************************************************************************
Query FSInfo raw interface (async recv)
****************************************************************************/
-NTSTATUS smb_raw_fsinfo_recv(struct cli_request *req,
+NTSTATUS smb_raw_fsinfo_recv(struct smbcli_request *req,
TALLOC_CTX *mem_ctx,
union smb_fsinfo *fsinfo)
{
DATA_BLOB blob;
NTSTATUS status;
- int i;
- struct cli_session *session = req?req->session:NULL;
+ struct smbcli_session *session = req?req->session:NULL;
if (fsinfo->generic.level == RAW_QFS_DSKATTR) {
return smb_raw_dskattr_recv(req, fsinfo);
case RAW_QFS_VOLUME:
QFS_CHECK_MIN_SIZE(5);
fsinfo->volume.out.serial_number = IVAL(blob.data, 0);
- cli_blob_pull_string(session, mem_ctx, &blob,
+ smbcli_blob_pull_string(session, mem_ctx, &blob,
&fsinfo->volume.out.volume_name,
4, 5, STR_LEN8BIT | STR_NOALIGN);
break;
case RAW_QFS_VOLUME_INFO:
case RAW_QFS_VOLUME_INFORMATION:
- QFS_CHECK_MIN_SIZE(18);
- fsinfo->volume_info.out.create_time = cli_pull_nttime(blob.data, 0);
- fsinfo->volume_info.out.serial_number = IVAL(blob.data, 8);
- cli_blob_pull_string(session, mem_ctx, &blob,
- &fsinfo->volume_info.out.volume_name,
- 12, 18, STR_UNICODE);
- break;
+ return smb_raw_fsinfo_passthru_parse(blob, mem_ctx,
+ RAW_QFS_VOLUME_INFORMATION, fsinfo);
case RAW_QFS_SIZE_INFO:
case RAW_QFS_SIZE_INFORMATION:
- QFS_CHECK_SIZE(24);
- fsinfo->size_info.out.total_alloc_units = BVAL(blob.data, 0);
- fsinfo->size_info.out.avail_alloc_units = BVAL(blob.data, 8);
- fsinfo->size_info.out.sectors_per_unit = IVAL(blob.data, 16);
- fsinfo->size_info.out.bytes_per_sector = IVAL(blob.data, 20);
- break;
+ return smb_raw_fsinfo_passthru_parse(blob, mem_ctx,
+ RAW_QFS_SIZE_INFORMATION, fsinfo);
case RAW_QFS_DEVICE_INFO:
case RAW_QFS_DEVICE_INFORMATION:
- QFS_CHECK_SIZE(8);
- fsinfo->device_info.out.device_type = IVAL(blob.data, 0);
- fsinfo->device_info.out.characteristics = IVAL(blob.data, 4);
- break;
+ return smb_raw_fsinfo_passthru_parse(blob, mem_ctx,
+ RAW_QFS_DEVICE_INFORMATION, fsinfo);
case RAW_QFS_ATTRIBUTE_INFO:
case RAW_QFS_ATTRIBUTE_INFORMATION:
- QFS_CHECK_MIN_SIZE(12);
- fsinfo->attribute_info.out.fs_attr = IVAL(blob.data, 0);
- fsinfo->attribute_info.out.max_file_component_length = IVAL(blob.data, 4);
- cli_blob_pull_string(session, mem_ctx, &blob,
- &fsinfo->attribute_info.out.fs_type,
- 8, 12, STR_UNICODE);
- break;
+ return smb_raw_fsinfo_passthru_parse(blob, mem_ctx,
+ RAW_QFS_ATTRIBUTE_INFORMATION, fsinfo);
case RAW_QFS_UNIX_INFO:
QFS_CHECK_SIZE(12);
break;
case RAW_QFS_QUOTA_INFORMATION:
- QFS_CHECK_SIZE(48);
- fsinfo->quota_information.out.unknown[0] = BVAL(blob.data, 0);
- fsinfo->quota_information.out.unknown[1] = BVAL(blob.data, 8);
- fsinfo->quota_information.out.unknown[2] = BVAL(blob.data, 16);
- fsinfo->quota_information.out.quota_soft = BVAL(blob.data, 24);
- fsinfo->quota_information.out.quota_hard = BVAL(blob.data, 32);
- fsinfo->quota_information.out.quota_flags = BVAL(blob.data, 40);
- break;
+ return smb_raw_fsinfo_passthru_parse(blob, mem_ctx,
+ RAW_QFS_QUOTA_INFORMATION, fsinfo);
case RAW_QFS_FULL_SIZE_INFORMATION:
- QFS_CHECK_SIZE(32);
- fsinfo->full_size_information.out.total_alloc_units = BVAL(blob.data, 0);
- fsinfo->full_size_information.out.call_avail_alloc_units = BVAL(blob.data, 8);
- fsinfo->full_size_information.out.actual_avail_alloc_units = BVAL(blob.data, 16);
- fsinfo->full_size_information.out.sectors_per_unit = IVAL(blob.data, 24);
- fsinfo->full_size_information.out.bytes_per_sector = IVAL(blob.data, 28);
- break;
+ return smb_raw_fsinfo_passthru_parse(blob, mem_ctx,
+ RAW_QFS_FULL_SIZE_INFORMATION, fsinfo);
case RAW_QFS_OBJECTID_INFORMATION:
- QFS_CHECK_SIZE(64);
- status = ndr_pull_struct_blob(&blob, mem_ctx, &fsinfo->objectid_information.out.guid,
- (ndr_pull_flags_fn_t)ndr_pull_GUID);
- for (i=0;i<6;i++) {
- fsinfo->objectid_information.out.unknown[i] = BVAL(blob.data, 16 + i*8);
- }
- break;
+ return smb_raw_fsinfo_passthru_parse(blob, mem_ctx,
+ RAW_QFS_OBJECTID_INFORMATION, fsinfo);
}
failed:
/****************************************************************************
Query FSInfo raw interface (sync interface)
****************************************************************************/
-NTSTATUS smb_raw_fsinfo(struct cli_tree *tree,
+NTSTATUS smb_raw_fsinfo(struct smbcli_tree *tree,
TALLOC_CTX *mem_ctx,
union smb_fsinfo *fsinfo)
{
- struct cli_request *req = smb_raw_fsinfo_send(tree, mem_ctx, fsinfo);
+ struct smbcli_request *req = smb_raw_fsinfo_send(tree, mem_ctx, fsinfo);
return smb_raw_fsinfo_recv(req, mem_ctx, fsinfo);
}