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