r23792: convert Samba4 to GPLv3
[bbaumbach/samba-autobuild/.git] / source4 / libcli / raw / rawfsinfo.c
index faf375deb0afb0f99be748dc202e4c3b72cdf823..ced977333dee696c2c8e14d6f725985475bf31f7 100644 (file)
@@ -7,7 +7,7 @@
    
    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;
        }
 
@@ -43,29 +44,29 @@ static struct cli_request *smb_raw_dskattr_send(struct cli_tree *tree,
 /****************************************************************************
  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)
 {
@@ -77,7 +78,7 @@ static struct cli_request *smb_raw_qfsinfo_send(struct cli_tree *tree,
        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;
@@ -94,7 +95,7 @@ static struct cli_request *smb_raw_qfsinfo_send(struct cli_tree *tree,
 /****************************************************************************
  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)
 {
@@ -114,13 +115,13 @@ static NTSTATUS smb_raw_qfsinfo_blob_recv(struct cli_request *req,
 /* 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; \
 }
@@ -129,7 +130,7 @@ static NTSTATUS smb_raw_qfsinfo_blob_recv(struct cli_request *req,
 /****************************************************************************
  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)
 {
@@ -149,18 +150,97 @@ struct cli_request *smb_raw_fsinfo_send(struct cli_tree *tree,
        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);
@@ -190,46 +270,30 @@ NTSTATUS smb_raw_fsinfo_recv(struct cli_request *req,
        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);
@@ -239,32 +303,16 @@ NTSTATUS smb_raw_fsinfo_recv(struct cli_request *req,
                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:
@@ -274,10 +322,10 @@ 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);
 }