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