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 (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 23 * Copyright 2012 Nexenta Systems, Inc. All rights reserved. 24 */ 25 26 #include <smbsrv/smb_kproto.h> 27 #include <smbsrv/smb_share.h> 28 29 /* 30 * SmbTreeConnect: Map a share to a tree and obtain a tree-id (TID). 31 * 32 * Client Request Description 33 * ================================== ================================= 34 * 35 * UCHAR WordCount; Count of parameter words = 0 36 * USHORT ByteCount; Count of data bytes; min = 4 37 * UCHAR BufferFormat1; 0x04 38 * STRING Path[]; Server name and share name 39 * UCHAR BufferFormat2; 0x04 40 * STRING Password[]; Password 41 * UCHAR BufferFormat3; 0x04 42 * STRING Service[]; Service name 43 * 44 * The CIFS server responds with: 45 * 46 * Server Response Description 47 * ================================ ================================= 48 * 49 * UCHAR WordCount; Count of parameter words = 2 50 * USHORT MaxBufferSize; Max size message the server handles 51 * USHORT Tid; Tree ID 52 * USHORT ByteCount; Count of data bytes = 0 53 * 54 * If the negotiated dialect is MICROSOFT NETWORKS 1.03 or earlier, 55 * MaxBufferSize in the response message indicates the maximum size 56 * message that the server can handle. The client should not generate 57 * messages, nor expect to receive responses, larger than this. This 58 * must be constant for a given server. For newer dialects, this field 59 * is ignored. 60 */ 61 smb_sdrc_t 62 smb_pre_tree_connect(smb_request_t *sr) 63 { 64 smb_arg_tcon_t *tcon = &sr->sr_tcon; 65 int rc; 66 67 /* 68 * Perhaps this should be "%A.sA" now that unicode is enabled. 69 */ 70 rc = smbsr_decode_data(sr, "%AAA", sr, &tcon->path, 71 &tcon->password, &tcon->service); 72 73 tcon->flags = 0; 74 tcon->optional_support = 0; 75 76 DTRACE_SMB_2(op__TreeConnect__start, smb_request_t *, sr, 77 smb_arg_tcon_t *, tcon); 78 79 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); 80 } 81 82 void 83 smb_post_tree_connect(smb_request_t *sr) 84 { 85 DTRACE_SMB_1(op__TreeConnect__done, smb_request_t *, sr); 86 } 87 88 smb_sdrc_t 89 smb_com_tree_connect(smb_request_t *sr) 90 { 91 smb_tree_t *tree; 92 int rc; 93 94 if ((tree = smb_tree_connect(sr)) == NULL) 95 return (SDRC_ERROR); 96 97 sr->smb_tid = tree->t_tid; 98 sr->tid_tree = tree; 99 100 rc = smbsr_encode_result(sr, 2, 0, "bwww", 101 2, /* wct */ 102 (WORD)smb_maxbufsize, /* MaxBufferSize */ 103 sr->smb_tid, /* TID */ 104 0); /* bcc */ 105 106 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); 107 } 108 109 /* 110 * SmbTreeConnectX: Map a share to a tree and obtain a tree-id (TID). 111 * 112 * Client Request Description 113 * ================================= ================================= 114 * 115 * UCHAR WordCount; Count of parameter words = 4 116 * UCHAR AndXCommand; Secondary (X) command; 0xFF = none 117 * UCHAR AndXReserved; Reserved (must be 0) 118 * USHORT AndXOffset; Offset to next command WordCount 119 * USHORT Flags; Additional information 120 * bit 0 set = disconnect Tid 121 * USHORT PasswordLength; Length of Password[] 122 * USHORT ByteCount; Count of data bytes; min = 3 123 * UCHAR Password[]; Password 124 * STRING Path[]; Server name and share name 125 * STRING Service[]; Service name 126 * 127 * If the negotiated dialect is LANMAN1.0 or later, then it is a protocol 128 * violation for the client to send this message prior to a successful 129 * SMB_COM_SESSION_SETUP_ANDX, and the server ignores Password. 130 * 131 * If the negotiated dialect is prior to LANMAN1.0 and the client has not 132 * sent a successful SMB_COM_SESSION_SETUP_ANDX request when the tree 133 * connect arrives, a user level security mode server must nevertheless 134 * validate the client's credentials. 135 * 136 * Flags (prefix with TREE_CONNECT_ANDX_): 137 * ========================== ======================================== 138 * 0x0001 DISCONECT_TID The tree specified by TID in the SMB header 139 * should be disconnected - disconnect errors 140 * should be ignored. 141 * 142 * 0x0004 EXTENDED_SIGNATURES Client request for signing key protection. 143 * 144 * 0x0008 EXTENDED_RESPONSE Client request for extended information. 145 * 146 * Path follows UNC style syntax (\\server\share) and indicates the name 147 * of the resource to which the client wishes to connect. 148 * 149 * Because Password may be an authentication response, it is a variable 150 * length field with the length specified by PasswordLength. If 151 * authentication is not being used, Password should be a null terminated 152 * ASCII string with PasswordLength set to the string size including the 153 * terminating null. 154 * 155 * The server can enforce whatever policy it desires to govern share 156 * access. Administrative privilege is required for administrative 157 * shares (C$, etc.). 158 * 159 * The Service component indicates the type of resource the client 160 * intends to access. Valid values are: 161 * 162 * Service Description Earliest Dialect Allowed 163 * ======== ======================== ================================ 164 * 165 * A: disk share PC NETWORK PROGRAM 1.0 166 * LPT1: printer PC NETWORK PROGRAM 1.0 167 * IPC named pipe MICROSOFT NETWORKS 3.0 168 * COMM communications device MICROSOFT NETWORKS 3.0 169 * ????? any type of device MICROSOFT NETWORKS 3.0 170 * 171 * If the negotiated dialect is earlier than DOS LANMAN2.1, the response to 172 * this SMB is: 173 * 174 * Server Response Description 175 * ================================ =================================== 176 * 177 * UCHAR WordCount; Count of parameter words = 2 178 * UCHAR AndXCommand; Secondary (X) command; 0xFF = none 179 * UCHAR AndXReserved; Reserved (must be 0) 180 * USHORT AndXOffset; Offset to next command WordCount 181 * USHORT ByteCount; Count of data bytes; min = 3 182 * 183 * If the negotiated is DOS LANMAN2.1 or later, the response to this SMB 184 * is: 185 * 186 * Server Response Description 187 * ================================ =================================== 188 * 189 * UCHAR WordCount; Count of parameter words = 3 190 * UCHAR AndXCommand; Secondary (X) command; 0xFF = none 191 * UCHAR AndXReserved; Reserved (must be 0) 192 * USHORT AndXOffset; Offset to next command WordCount 193 * USHORT OptionalSupport; Optional support bits 194 * USHORT ByteCount; Count of data bytes; min = 3 195 * UCHAR Service[]; Service type connected to. Always 196 * ANSII. 197 * STRING NativeFileSystem[]; Native file system for this tree 198 * 199 * NativeFileSystem is the name of the filesystem; values to be expected 200 * include FAT, NTFS, etc. 201 * 202 * OptionalSupport: 203 * ============================== ========================== 204 * 0x0001 SMB_SUPPORT_SEARCH_BITS The server supports the use of Search 205 * Attributes in client requests. 206 * 0x0002 SMB_SHARE_IS_IN_DFS The share is managed by DFS. 207 * 0x000C SMB_CSC_MASK Offline-caching mask - see CSC flags. 208 * 0x0010 SMB_UNIQUE_FILE_NAME The server uses long names and does not 209 * support short names. Indicator for 210 * clients directory/name-space caching. 211 * 0x0020 SMB_EXTENDED_SIGNATURES The server will use signing key protection. 212 * 213 * Client-side caching (offline files): 214 * ============================== ========================== 215 * 0x0000 SMB_CSC_CACHE_MANUAL_REINT Clients may cache files for offline use 216 * but automatic file-by-file reintegration 217 * is not allowed. 218 * 0x0004 SMB_CSC_CACHE_AUTO_REINT Automatic file-by-file reintegration is 219 * allowed. 220 * 0x0008 SMB_CSC_CACHE_VDO File opens do not need to be flowed. 221 * 0x000C SMB_CSC_CACHE_NONE CSC is disabled for this share. 222 * 223 * Some servers negotiate "DOS LANMAN2.1" dialect or later and still send 224 * the "downlevel" (i.e. wordcount==2) response. Valid AndX following 225 * commands are 226 * 227 * SMB_COM_OPEN SMB_COM_OPEN_ANDX SMB_COM_CREATE 228 * SMB_COM_CREATE_NEW SMB_COM_CREATE_DIRECTORY SMB_COM_DELETE 229 * SMB_COM_DELETE_DIRECTORY SMB_COM_FIND SMB_COM_COPY 230 * SMB_COM_FIND_UNIQUE SMB_COM_RENAME 231 * SMB_COM_CHECK_DIRECTORY SMB_COM_QUERY_INFORMATION 232 * SMB_COM_GET_PRINT_QUEUE SMB_COM_OPEN_PRINT_FILE 233 * SMB_COM_TRANSACTION SMB_COM_NO_ANDX_CMD 234 * SMB_COM_SET_INFORMATION SMB_COM_NT_RENAME 235 * 236 * Errors: 237 * ERRDOS/ERRnomem 238 * ERRDOS/ERRbadpath 239 * ERRDOS/ERRinvdevice 240 * ERRSRV/ERRaccess 241 * ERRSRV/ERRbadpw 242 * ERRSRV/ERRinvnetname 243 */ 244 smb_sdrc_t 245 smb_pre_tree_connect_andx(smb_request_t *sr) 246 { 247 smb_arg_tcon_t *tcon = &sr->sr_tcon; 248 uint8_t *pwbuf = NULL; 249 uint16_t pwlen = 0; 250 int rc; 251 252 rc = smbsr_decode_vwv(sr, "b.www", &sr->andx_com, &sr->andx_off, 253 &tcon->flags, &pwlen); 254 if (rc == 0) { 255 if (pwlen != 0) 256 pwbuf = smb_srm_zalloc(sr, pwlen); 257 258 rc = smbsr_decode_data(sr, "%#cus", sr, pwlen, pwbuf, 259 &tcon->path, &tcon->service); 260 261 tcon->pwdlen = pwlen; 262 tcon->password = (char *)pwbuf; 263 } 264 265 tcon->optional_support = 0; 266 267 DTRACE_SMB_2(op__TreeConnectX__start, smb_request_t *, sr, 268 smb_arg_tcon_t *, tcon); 269 270 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); 271 } 272 273 void 274 smb_post_tree_connect_andx(smb_request_t *sr) 275 { 276 DTRACE_SMB_1(op__TreeConnectX__done, smb_request_t *, sr); 277 } 278 279 smb_sdrc_t 280 smb_com_tree_connect_andx(smb_request_t *sr) 281 { 282 smb_arg_tcon_t *tcon = &sr->sr_tcon; 283 smb_tree_t *tree; 284 char *service; 285 int rc; 286 287 if ((tree = smb_tree_connect(sr)) == NULL) 288 return (SDRC_ERROR); 289 290 sr->smb_tid = tree->t_tid; 291 sr->tid_tree = tree; 292 293 switch (tree->t_res_type & STYPE_MASK) { 294 case STYPE_IPC: 295 service = "IPC"; 296 break; 297 case STYPE_PRINTQ: 298 service = "LPT1:"; 299 break; 300 case STYPE_DISKTREE: 301 default: 302 service = "A:"; 303 } 304 305 if (sr->session->dialect < NT_LM_0_12) { 306 rc = smbsr_encode_result(sr, 2, VAR_BCC, "bb.wwss", 307 (char)2, /* wct */ 308 sr->andx_com, 309 VAR_BCC, 310 VAR_BCC, 311 service, 312 sr->tid_tree->t_typename); 313 } else { 314 rc = smbsr_encode_result(sr, 3, VAR_BCC, "bb.wwws%u", 315 (char)3, /* wct */ 316 sr->andx_com, 317 (short)64, 318 tcon->optional_support, 319 VAR_BCC, 320 service, 321 sr, 322 sr->tid_tree->t_typename); 323 } 324 325 return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); 326 } 327 328 /* 329 * SmbTreeDisconnect: Disconnect a tree. 330 * 331 * Note: SDDF_SUPPRESS_UID is set for this operation, which means the sr 332 * uid_user field will not be valid on entry to these functions. Do not 333 * use it until it is set up in smb_com_tree_disconnect() or the system 334 * will panic. 335 * 336 * Note: there are scenarios in which the client does not send a tree 337 * disconnect request, for example, when ERRbaduid is returned from 338 * SmbReadX after a user has logged off. Any open files will remain 339 * around until the session is destroyed. 340 * 341 * Client Request Description 342 * ================================== ================================= 343 * 344 * UCHAR WordCount; Count of parameter words = 0 345 * USHORT ByteCount; Count of data bytes = 0 346 * 347 * The resource sharing connection identified by Tid in the SMB header is 348 * logically disconnected from the server. Tid is invalidated; it will not 349 * be recognized if used by the client for subsequent requests. All locks, 350 * open files, etc. created on behalf of Tid are released. 351 * 352 * Server Response Description 353 * ================================== ================================= 354 * 355 * UCHAR WordCount; Count of parameter words = 0 356 * USHORT ByteCount; Count of data bytes = 0 357 * 358 * Errors: 359 * ERRSRV/ERRinvnid 360 * ERRSRV/ERRbaduid 361 */ 362 smb_sdrc_t 363 smb_pre_tree_disconnect(smb_request_t *sr) 364 { 365 sr->uid_user = smb_session_lookup_uid(sr->session, sr->smb_uid); 366 sr->tid_tree = smb_session_lookup_tree(sr->session, sr->smb_tid); 367 368 DTRACE_SMB_1(op__TreeDisconnect__start, smb_request_t *, sr); 369 return (SDRC_SUCCESS); 370 } 371 372 void 373 smb_post_tree_disconnect(smb_request_t *sr) 374 { 375 DTRACE_SMB_1(op__TreeDisconnect__done, smb_request_t *, sr); 376 } 377 378 /* 379 * SmbTreeDisconnect requires a valid UID as well as a valid TID. Some 380 * clients logoff a user and then try to disconnect the trees connected 381 * by the user who has just been logged off, which would normally fail 382 * in the dispatch code with ERRbaduid but, unfortunately, ERRbaduid 383 * causes a problem for some of those clients. Windows returns ERRinvnid. 384 * 385 * To prevent ERRbaduid being returned, the UID and TID are looked up here 386 * rather than prior to dispatching SmbTreeDisconnect requests. If either 387 * the UID or the TID is invalid, ERRinvnid is returned. 388 */ 389 smb_sdrc_t 390 smb_com_tree_disconnect(smb_request_t *sr) 391 { 392 if (sr->uid_user == NULL || sr->tid_tree == NULL) { 393 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRinvnid); 394 return (SDRC_ERROR); 395 } 396 397 sr->user_cr = smb_user_getcred(sr->uid_user); 398 399 smb_session_cancel_requests(sr->session, sr->tid_tree, sr); 400 smb_tree_disconnect(sr->tid_tree, B_TRUE); 401 402 if (smbsr_encode_empty_result(sr)) 403 return (SDRC_ERROR); 404 405 return (SDRC_SUCCESS); 406 } 407