Home | History | Annotate | Download | only in smbsrv
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 /*
     27  * SMB: trans2_query_fs_information
     28  *
     29  * This transaction requests information about a filesystem on the server.
     30  *
     31  *  Client Request                     Value
     32  *  ================================== =================================
     33  *
     34  *  WordCount;                         15
     35  *  TotalParameterCount;               2 or 4
     36  *  MaxSetupCount;                     0
     37  *  SetupCount;                        1 or 2
     38  *  Setup[0];                          TRANS2_QUERY_FS_INFORMATION
     39  *
     40  *  Parameter Block Encoding           Description
     41  *  ================================== =================================
     42  *
     43  *  USHORT Information Level;          Level of information requested
     44  *
     45  * The  filesystem is identified by Tid in the SMB header.
     46  *
     47  * MaxDataCount in the transaction request must be large enough to
     48  * accommodate the response.
     49  *
     50  * The encoding of the response parameter block depends on the
     51  * InformationLevel requested.  Information levels whose values are greater
     52  * than 0x102 are mapped to corresponding calls to
     53  * NtQueryVolumeInformationFile calls by the server.  The two levels below
     54  * 0x102 are described below.  The requested information is placed in the
     55  * Data portion of the transaction response.
     56  *
     57  *  InformationLevel               Value
     58  *
     59  *  =============================  ======
     60  *
     61  *  SMB_INFO_ALLOCATION            1
     62  *  SMB_INFO_VOLUME                2
     63  *  SMB_QUERY_FS_VOLUME_INFO       0x102
     64  *  SMB_QUERY_FS_SIZE_INFO         0x103
     65  *  SMB_QUERY_FS_DEVICE_INFO       0x104
     66  *  SMB_QUERY_FS_ATTRIBUTE_INFO    0x105
     67  *
     68  * The following sections describe the InformationLevel dependent encoding
     69  * of the data part of the transaction response.
     70  *
     71  * 4.1.6.1   SMB_INFO_ALLOCATION
     72  *
     73  *  Data Block Encoding Description
     74  *  =================== ================================================
     75  *
     76  *  ULONG idFileSystem; File system identifier.  NT server always
     77  *                       returns 0
     78  *  ULONG cSectorUnit;  Number of sectors per allocation unit
     79  *  ULONG cUnit;        Total number of allocation units
     80  *  ULONG cUnitAvail;   Total number of available allocation units
     81  *  USHORT cbSector;    Number of bytes per sector
     82  *
     83  * 4.1.6.2   SMB_INFO_VOLUME
     84  *
     85  *  Data Block Encoding Description
     86  *  =================== ================================================
     87  *
     88  *  ULONG ulVsn;        Volume serial number
     89  *  UCHAR cch;          Number of  characters in Label
     90  *  STRING Label;       The volume label
     91  *
     92  * 4.1.6.3   SMB_QUERY_FS_VOLUME_INFO
     93  *
     94  *  Data Block Encoding Description
     95  *  =================== ================================================
     96  *
     97  *  LARGE_INTEGER       Volume Creation Time
     98  *  ULONG               Volume Serial Number
     99  *  ULONG               Length of Volume Label in bytes
    100  *
    101  *  BYTE                Reserved
    102  *
    103  *  BYTE                Reserved
    104  *
    105  *  STRING Label;       The volume label
    106  *
    107  * 4.1.6.4   SMB_QUERY_FS_SIZE_INFO
    108  *
    109  *  Data Block Encoding Description
    110  *  =================== ================================================
    111  *
    112  *  LARGE_INTEGER       Total Number of Allocation units on the Volume
    113  *  LARGE_INTEGER       Number of free Allocation units on the Volume
    114  *  ULONG               Number of sectors in each Allocation unit
    115  *
    116  *  ULONG               Number of bytes in each sector
    117  *
    118  * 4.1.6.5   SMB_QUERY_FS_DEVICE_INFO
    119  *
    120  *  Data Block Encoding  Value
    121  *  ==================== ===============================================
    122  *
    123  *  ULONG                DeviceType; Values as specified below
    124  *  ULONG                Characteristics of the device; Values as
    125  *                        specified below
    126  *
    127  * For DeviceType, note that the values 0-32767 are reserved for the
    128  * exclusive use of Microsoft Corporation. The following device types are
    129  * currently defined:
    130  *
    131  * FILE_DEVICE_BEEP             0x00000001
    132  *
    133  * FILE_DEVICE_CD_ROM           0x00000002
    134  * FILE_DEVICE_CD_ROM_FILE_SYST 0x00000003
    135  * EM
    136  * FILE_DEVICE_CONTROLLER       0x00000004
    137  * FILE_DEVICE_DATALINK         0x00000005
    138  * FILE_DEVICE_DFS              0x00000006
    139  * FILE_DEVICE_DISK             0x00000007
    140  * FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008
    141  * FILE_DEVICE_FILE_SYSTEM      0x00000009
    142  * FILE_DEVICE_INPORT_PORT      0x0000000a
    143  * FILE_DEVICE_KEYBOARD         0x0000000b
    144  * FILE_DEVICE_MAILSLOT         0x0000000c
    145  * FILE_DEVICE_MIDI_IN          0x0000000d
    146  * FILE_DEVICE_MIDI_OUT         0x0000000e
    147  * FILE_DEVICE_MOUSE            0x0000000f
    148  * FILE_DEVICE_MULTI_UNC_PROVID 0x00000010
    149  * ER
    150  * FILE_DEVICE_NAMED_PIPE       0x00000011
    151  * FILE_DEVICE_NETWORK          0x00000012
    152  * FILE_DEVICE_NETWORK_BROWSER  0x00000013
    153  * FILE_DEVICE_NETWORK_FILE_SYS 0x00000014
    154  * TEM
    155  * FILE_DEVICE_NULL             0x00000015
    156  * FILE_DEVICE_PARALLEL_PORT    0x00000016
    157  * FILE_DEVICE_PHYSICAL_NETCARD 0x00000017
    158  * FILE_DEVICE_PRINTER          0x00000018
    159  * FILE_DEVICE_SCANNER          0x00000019
    160  * FILE_DEVICE_SERIAL_MOUSE_POR 0x0000001a
    161  * T
    162  * FILE_DEVICE_SERIAL_PORT      0x0000001b
    163  * FILE_DEVICE_SCREEN           0x0000001c
    164  * FILE_DEVICE_SOUND            0x0000001d
    165  * FILE_DEVICE_STREAMS          0x0000001e
    166  * FILE_DEVICE_TAPE             0x0000001f
    167  * FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020
    168  * FILE_DEVICE_TRANSPORT        0x00000021
    169  * FILE_DEVICE_UNKNOWN          0x00000022
    170  * FILE_DEVICE_VIDEO            0x00000023
    171  * FILE_DEVICE_VIRTUAL_DISK     0x00000024
    172  * FILE_DEVICE_WAVE_IN          0x00000025
    173  * FILE_DEVICE_WAVE_OUT         0x00000026
    174  * FILE_DEVICE_8042_PORT        0x00000027
    175  * FILE_DEVICE_NETWORK_REDIRECT 0x00000028
    176  * OR
    177  * FILE_DEVICE_BATTERY          0x00000029
    178  * FILE_DEVICE_BUS_EXTENDER     0x0000002a
    179  * FILE_DEVICE_MODEM            0x0000002b
    180  * FILE_DEVICE_VDM              0x0000002c
    181  *
    182  * Some of these device types are not currently accessible over the network
    183  * and may never be accessible over the network. Some may change to be
    184  *
    185  * accessible over the network. The values for device types that may never
    186  * be accessible over the network may be redefined to be just reserved at
    187  * some date in the future.
    188  *
    189  * Characteristics is the sum of any of the following:
    190  *
    191  * FILE_REMOVABLE_MEDIA         0x00000001
    192  * FILE_READ_ONLY_DEVICE        0x00000002
    193  * FILE_FLOPPY_DISKETTE         0x00000004
    194  * FILE_WRITE_ONE_MEDIA         0x00000008
    195  * FILE_REMOTE_DEVICE           0x00000010
    196  * FILE_DEVICE_IS_MOUNTED       0x00000020
    197  * FILE_VIRTUAL_VOLUME          0x00000040
    198  *
    199  * 4.1.6.6   SMB_QUERY_FS_ATTRIBUTE_INFO
    200  *
    201  *  Data Block Encoding Description
    202  *  =================== ================================================
    203  *
    204  *  ULONG               File System Attributes; possible values
    205  *                       described below
    206  *  LONG                Maximum length of each file name component in
    207  *                       number of bytes
    208  *  ULONG               Length, in bytes, of the name of the file system
    209  *
    210  *  STRING              Name of the file system
    211  *
    212  * Where FileSystemAttributes is the sum of any of the following:
    213  *
    214  * FILE_CASE_SENSITIVE_SEARCH   0x00000001
    215  * FILE_CASE_PRESERVED_NAMES    0x00000002
    216  * FILE_PRSISTENT_ACLS          0x00000004
    217  * FILE_FILE_COMPRESSION        0x00000008
    218  * FILE_VOLUME_QUOTAS           0x00000010
    219  * FILE_DEVICE_IS_MOUNTED       0x00000020
    220  * FILE_VOLUME_IS_COMPRESSED    0x00008000
    221  *
    222  * 4.1.6.7   Errors
    223  *
    224  * ERRSRV/invnid  - TID was invalid
    225  * ERRSRV/baduid  - UID was invalid
    226  * ERRHRD/ERRnotready  - the file system has been removed
    227  * ERRHRD/ERRdata - disk I/O error
    228  * ERRSRV/ERRaccess    - user does not have the right to perform this
    229  *			 operation
    230  * ERRSRV/ERRinvdevice - resource identified by TID is not a file system
    231  */
    232 
    233 #include <smbsrv/smb_kproto.h>
    234 #include <smbsrv/smb_fsops.h>
    235 #include <smbsrv/smbinfo.h>
    236 
    237 char ntfs[] = "NTFS";
    238 
    239 /*
    240  * smb_com_trans2_query_fs_information
    241  *
    242  * The fsid provides a system-wide unique file system ID.
    243  * fsid.val[0] is the 32-bit dev for the file system of the share root
    244  * smb_node.
    245  * fsid.val[1] is the file system type.
    246  */
    247 smb_sdrc_t
    248 smb_com_trans2_query_fs_information(struct smb_request *sr, struct smb_xa *xa)
    249 {
    250 	int			rc;
    251 	uint32_t		flags;
    252 	char			*encode_str;
    253 	uint64_t		max_int;
    254 	unsigned short		infolev;
    255 	struct statvfs64	df;
    256 	int			sect_per_unit, length;
    257 	uint32_t		total_units, avail_units;
    258 	smb_tree_t		*tree;
    259 	smb_node_t		*snode;
    260 	char 			*fsname = "NTFS";
    261 	fsid_t			fsid;
    262 
    263 	tree = sr->tid_tree;
    264 
    265 	if (!STYPE_ISDSK(tree->t_res_type)) {
    266 		smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
    267 		return (SDRC_ERROR);
    268 	}
    269 
    270 	if (smb_mbc_decodef(&xa->req_param_mb, "w", &infolev) != 0)
    271 		return (SDRC_ERROR);
    272 
    273 	snode = tree->t_snode;
    274 	fsid = SMB_NODE_FSID(snode);
    275 
    276 	switch (infolev) {
    277 	case SMB_INFO_ALLOCATION:
    278 		if ((rc = smb_fsop_statfs(sr->user_cr, snode, &df)) != 0) {
    279 			smbsr_errno(sr, rc);
    280 			return (SDRC_ERROR);
    281 		}
    282 
    283 		max_int = (uint64_t)UINT_MAX;
    284 
    285 		if (df.f_blocks > max_int)
    286 			df.f_blocks = max_int;
    287 
    288 		if (df.f_bavail > max_int)
    289 			df.f_bavail = max_int;
    290 
    291 		total_units = (uint32_t)df.f_blocks;
    292 		avail_units = (uint32_t)df.f_bavail;
    293 		length = 512;
    294 		sect_per_unit = df.f_frsize >> 9;
    295 
    296 		if (avail_units > total_units)
    297 			avail_units = 0;
    298 
    299 		(void) smb_mbc_encodef(&xa->rep_data_mb, "llllw",
    300 		    0,			/* file system ID. NT rets 0 */
    301 		    sect_per_unit,	/* sectors/unit */
    302 		    total_units,	/* total units */
    303 		    avail_units,	/* avail units */
    304 		    length);	/* bytes/sector */
    305 		break;
    306 
    307 	case SMB_INFO_VOLUME:
    308 		length = strlen(tree->t_volume);
    309 		encode_str = "%lbs";
    310 
    311 		(void) smb_mbc_encodef(&xa->rep_data_mb, encode_str, sr,
    312 		    fsid.val[0], length, tree->t_volume);
    313 		break;
    314 
    315 	case SMB_QUERY_FS_VOLUME_INFO:
    316 		if ((sr->smb_flg2 & SMB_FLAGS2_UNICODE) ||
    317 		    (sr->session->native_os == NATIVE_OS_WIN95)) {
    318 			length = smb_wcequiv_strlen(tree->t_volume);
    319 			encode_str = "%qllb.U";
    320 		} else {
    321 			length = strlen(tree->t_volume);
    322 			encode_str = "%qllb.s";
    323 		}
    324 
    325 		/*
    326 		 * NT has the "supports objects" flag set to 1.
    327 		 */
    328 
    329 		(void) smb_mbc_encodef(&xa->rep_data_mb, encode_str, sr,
    330 		    0ll,			/* Volume creation time */
    331 		    fsid.val[0],		/* Volume serial number */
    332 		    length,			/* label length */
    333 		    0,				/* Supports objects */
    334 		    tree->t_volume);
    335 		break;
    336 
    337 	case SMB_QUERY_FS_SIZE_INFO:
    338 		if ((rc = smb_fsop_statfs(sr->user_cr, snode, &df)) != 0) {
    339 			smbsr_errno(sr, rc);
    340 			return (SDRC_ERROR);
    341 		}
    342 
    343 		length = 512;
    344 		sect_per_unit = df.f_frsize >> 9;
    345 
    346 		if (df.f_bavail > df.f_blocks)
    347 			df.f_bavail = 0;
    348 
    349 		(void) smb_mbc_encodef(&xa->rep_data_mb, "qqll",
    350 		    df.f_blocks,	/* total units */
    351 		    df.f_bavail,	/* avail units */
    352 		    sect_per_unit,	/* sectors/unit */
    353 		    length);		/* bytes/sector */
    354 		break;
    355 	case SMB_QUERY_FS_DEVICE_INFO:
    356 		(void) smb_mbc_encodef(&xa->rep_data_mb, "ll",
    357 		    FILE_DEVICE_FILE_SYSTEM,
    358 		    FILE_DEVICE_IS_MOUNTED);
    359 		break;
    360 
    361 	case SMB_QUERY_FS_ATTRIBUTE_INFO:
    362 		if ((sr->smb_flg2 & SMB_FLAGS2_UNICODE) ||
    363 		    (sr->session->native_os == NATIVE_OS_WINNT) ||
    364 		    (sr->session->native_os == NATIVE_OS_WIN2000) ||
    365 		    (sr->session->native_os == NATIVE_OS_WIN95) ||
    366 		    (sr->session->native_os == NATIVE_OS_MACOS)) {
    367 			length = smb_wcequiv_strlen(fsname);
    368 			encode_str = "%lllU";
    369 			sr->smb_flg2 |= SMB_FLAGS2_UNICODE;
    370 		} else {
    371 			length = strlen(fsname);
    372 			encode_str = "%llls";
    373 		}
    374 
    375 		flags = FILE_CASE_PRESERVED_NAMES;
    376 
    377 		if (tree->t_flags & SMB_TREE_UNICODE_ON_DISK)
    378 			flags |= FILE_UNICODE_ON_DISK;
    379 
    380 		if (tree->t_flags & SMB_TREE_SUPPORTS_ACLS)
    381 			flags |= FILE_PERSISTENT_ACLS;
    382 
    383 		if ((tree->t_flags & SMB_TREE_CASEINSENSITIVE) == 0)
    384 			flags |= FILE_CASE_SENSITIVE_SEARCH;
    385 
    386 		if (tree->t_flags & SMB_TREE_STREAMS) {
    387 			flags |= FILE_NAMED_STREAMS;
    388 			flags |= FILE_VOLUME_QUOTAS;
    389 		}
    390 
    391 		(void) smb_mbc_encodef(&xa->rep_data_mb, encode_str, sr,
    392 		    flags,
    393 		    MAXNAMELEN,			/* max name */
    394 		    length,			/* label length */
    395 		    fsname);
    396 		break;
    397 
    398 	default:
    399 		smbsr_error(sr, 0, ERRDOS, ERRunknownlevel);
    400 		return (SDRC_ERROR);
    401 	}
    402 
    403 	return (SDRC_SUCCESS);
    404 }
    405