xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb2_tree_connect.c (revision 814e0daa42b0648d115fbe8c5d2858e4eb099cbd)
1a90cf9f2SGordon Ross /*
2a90cf9f2SGordon Ross  * This file and its contents are supplied under the terms of the
3a90cf9f2SGordon Ross  * Common Development and Distribution License ("CDDL"), version 1.0.
4a90cf9f2SGordon Ross  * You may only use this file in accordance with the terms of version
5a90cf9f2SGordon Ross  * 1.0 of the CDDL.
6a90cf9f2SGordon Ross  *
7a90cf9f2SGordon Ross  * A full copy of the text of the CDDL should have accompanied this
8a90cf9f2SGordon Ross  * source.  A copy of the CDDL is also available via the Internet at
9a90cf9f2SGordon Ross  * http://www.illumos.org/license/CDDL.
10a90cf9f2SGordon Ross  */
11a90cf9f2SGordon Ross 
12a90cf9f2SGordon Ross /*
1393bc28dbSGordon Ross  * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
14ea524515SGordon Ross  * Copyright 2022 RackTop Systems, Inc.
15a90cf9f2SGordon Ross  */
16a90cf9f2SGordon Ross 
17a90cf9f2SGordon Ross /*
18a90cf9f2SGordon Ross  * Dispatch function for SMB2_TREE_CONNECT
19a90cf9f2SGordon Ross  */
20a90cf9f2SGordon Ross 
21a90cf9f2SGordon Ross #include <smbsrv/smb2_kproto.h>
22a90cf9f2SGordon Ross 
238d94f651SGordon Ross #define	SMB2_SHARE_CAP_CA SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY
24ea524515SGordon Ross #define	ANON_OR_GUEST	(SMB_USER_FLAG_ANON | SMB_USER_FLAG_GUEST)
258d94f651SGordon Ross 
26a90cf9f2SGordon Ross smb_sdrc_t
smb2_tree_connect(smb_request_t * sr)27a90cf9f2SGordon Ross smb2_tree_connect(smb_request_t *sr)
28a90cf9f2SGordon Ross {
29a90cf9f2SGordon Ross 	smb_arg_tcon_t	*tcon = &sr->sr_tcon;
30a90cf9f2SGordon Ross 	smb_tree_t	*tree = NULL;
31ea524515SGordon Ross 	smb_sdrc_t	rv = SDRC_SUCCESS;
32a90cf9f2SGordon Ross 	uint16_t StructureSize;
33a90cf9f2SGordon Ross 	uint16_t PathOffset;
34a90cf9f2SGordon Ross 	uint16_t PathLength;
35a90cf9f2SGordon Ross 	uint8_t ShareType;
36a90cf9f2SGordon Ross 	uint32_t ShareFlags;
37a90cf9f2SGordon Ross 	uint32_t Capabilities;
38a90cf9f2SGordon Ross 	uint32_t status;
39a90cf9f2SGordon Ross 	int skip;
40ea524515SGordon Ross 	int rc;
41a90cf9f2SGordon Ross 
42a90cf9f2SGordon Ross 	/*
43a90cf9f2SGordon Ross 	 * SMB2 Tree Connect request
44a90cf9f2SGordon Ross 	 */
45a90cf9f2SGordon Ross 	rc = smb_mbc_decodef(
46a90cf9f2SGordon Ross 	    &sr->smb_data, "w..ww",
47a90cf9f2SGordon Ross 	    &StructureSize,
48a90cf9f2SGordon Ross 	    /* reserved */
49a90cf9f2SGordon Ross 	    &PathOffset,
50a90cf9f2SGordon Ross 	    &PathLength);
51a90cf9f2SGordon Ross 	if (rc)
52a90cf9f2SGordon Ross 		return (SDRC_ERROR);
53a90cf9f2SGordon Ross 
54a90cf9f2SGordon Ross 	/*
55a90cf9f2SGordon Ross 	 * We're normally positioned at the path name now,
56a90cf9f2SGordon Ross 	 * but there could be some padding before it.
57a90cf9f2SGordon Ross 	 */
58a90cf9f2SGordon Ross 	skip = (PathOffset + sr->smb2_cmd_hdr) -
59a90cf9f2SGordon Ross 	    sr->smb_data.chain_offset;
60a90cf9f2SGordon Ross 	if (skip < 0)
61a90cf9f2SGordon Ross 		return (SDRC_ERROR);
62a90cf9f2SGordon Ross 	if (skip > 0)
63a90cf9f2SGordon Ross 		(void) smb_mbc_decodef(&sr->smb_data, "#.", skip);
64a90cf9f2SGordon Ross 
65a90cf9f2SGordon Ross 	/*
66a90cf9f2SGordon Ross 	 * Get the path name
67a90cf9f2SGordon Ross 	 */
68a90cf9f2SGordon Ross 	rc = smb_mbc_decodef(
69a90cf9f2SGordon Ross 	    &sr->smb_data, "%#U",
70a90cf9f2SGordon Ross 	    sr, (uint_t)PathLength, &tcon->path);
71a90cf9f2SGordon Ross 	if (rc)
72a90cf9f2SGordon Ross 		return (SDRC_ERROR);
73a90cf9f2SGordon Ross 
7493bc28dbSGordon Ross 	DTRACE_SMB2_START(op__TreeConnect, smb_request_t *, sr);
7593bc28dbSGordon Ross 
761160dcf7SMatt Barden 	/*
77ea524515SGordon Ross 	 * If Connection.Dialect is "3.1.1" and Session.IsAnonymous and
78ea524515SGordon Ross 	 * Session.IsGuest are set to FALSE and the request is not signed
79ea524515SGordon Ross 	 * or encrypted, then the server MUST disconnect the connection.
80ea524515SGordon Ross 	 */
81ea524515SGordon Ross 	if (sr->session->dialect >= SMB_VERS_3_11 &&
82ea524515SGordon Ross 	    (sr->uid_user->u_flags & ANON_OR_GUEST) == 0 &&
83ea524515SGordon Ross 	    (sr->smb2_hdr_flags & SMB2_FLAGS_SIGNED) == 0 &&
84ea524515SGordon Ross 	    sr->encrypted == B_FALSE) {
85ea524515SGordon Ross 		rv = SDRC_DROP_VC;
86ea524515SGordon Ross 		status = NT_STATUS_ACCESS_DENIED;
87ea524515SGordon Ross 		goto errout;
88ea524515SGordon Ross 	}
89ea524515SGordon Ross 
90ea524515SGordon Ross 	/*
911160dcf7SMatt Barden 	 * [MS-SMB2] 3.3.5.7 Receiving an SMB2 TREE_CONNECT Request
921160dcf7SMatt Barden 	 *
931160dcf7SMatt Barden 	 * If RejectUnencryptedAccess is TRUE,
941160dcf7SMatt Barden 	 * global EncryptData or Share.EncryptData is TRUE,
951160dcf7SMatt Barden 	 * we support 3.x, and srv_cap doesn't indicate encryption support,
961160dcf7SMatt Barden 	 * return ACCESS_DENIED.
971160dcf7SMatt Barden 	 *
981160dcf7SMatt Barden 	 * This also applies to SMB1, so do it in smb_tree_connect_core.
991160dcf7SMatt Barden 	 */
100a90cf9f2SGordon Ross 	status = smb_tree_connect(sr);
10193bc28dbSGordon Ross 
102ea524515SGordon Ross errout:
10393bc28dbSGordon Ross 	sr->smb2_status = status;
10493bc28dbSGordon Ross 	DTRACE_SMB2_DONE(op__TreeConnect, smb_request_t *, sr);
10593bc28dbSGordon Ross 
106a90cf9f2SGordon Ross 	if (status) {
107a90cf9f2SGordon Ross 		(void) smb2sr_put_error(sr, status);
108ea524515SGordon Ross 		return (rv);
109a90cf9f2SGordon Ross 	}
110a90cf9f2SGordon Ross 	tree = sr->tid_tree;
111a90cf9f2SGordon Ross 
112a90cf9f2SGordon Ross 	/*
113a90cf9f2SGordon Ross 	 * Report the share type.
114a90cf9f2SGordon Ross 	 */
115a90cf9f2SGordon Ross 	switch (tree->t_res_type & STYPE_MASK) {
116a90cf9f2SGordon Ross 	case STYPE_IPC:
117a90cf9f2SGordon Ross 		ShareType = SMB2_SHARE_TYPE_PIPE;
118a90cf9f2SGordon Ross 		break;
119a90cf9f2SGordon Ross 	case STYPE_PRINTQ:
120a90cf9f2SGordon Ross 		ShareType = SMB2_SHARE_TYPE_PRINT;
121a90cf9f2SGordon Ross 		break;
122a90cf9f2SGordon Ross 	case STYPE_DISKTREE:
123a90cf9f2SGordon Ross 	default:
124a90cf9f2SGordon Ross 		ShareType = SMB2_SHARE_TYPE_DISK;
125a90cf9f2SGordon Ross 		break;
126a90cf9f2SGordon Ross 	}
127a90cf9f2SGordon Ross 
128a90cf9f2SGordon Ross 	/*
129a90cf9f2SGordon Ross 	 * XXX These need work..
130*814e0daaSGordon Ross 	 * See SMB1 flags in tcon->optional_support
131a90cf9f2SGordon Ross 	 */
1321160dcf7SMatt Barden 	if (tree->t_encrypt != SMB_CONFIG_DISABLED)
1331160dcf7SMatt Barden 		ShareFlags = SMB2_SHAREFLAG_ENCRYPT_DATA;
1341160dcf7SMatt Barden 	else
135a90cf9f2SGordon Ross 		ShareFlags = 0;
1361160dcf7SMatt Barden 
137a90cf9f2SGordon Ross 	Capabilities = 0;
1388d94f651SGordon Ross 	if ((tree->t_flags & SMB_TREE_DFSROOT) != 0)
1398d94f651SGordon Ross 		Capabilities |= SMB2_SHARE_CAP_DFS;
1408d94f651SGordon Ross 	if ((tree->t_flags & SMB_TREE_CA) != 0)
1418d94f651SGordon Ross 		Capabilities |= SMB2_SHARE_CAP_CA;
142a90cf9f2SGordon Ross 
143a90cf9f2SGordon Ross 	/*
144a90cf9f2SGordon Ross 	 * SMB2 Tree Connect reply
145a90cf9f2SGordon Ross 	 */
14693bc28dbSGordon Ross 	(void) smb_mbc_encodef(
147a90cf9f2SGordon Ross 	    &sr->reply,
148a90cf9f2SGordon Ross 	    "wb.lll",
149a90cf9f2SGordon Ross 	    16,	/* StructSize */	/* w */
150a90cf9f2SGordon Ross 	    ShareType,			/* b */
151a90cf9f2SGordon Ross 	    ShareFlags,			/* l */
152a90cf9f2SGordon Ross 	    Capabilities,		/* l */
153a90cf9f2SGordon Ross 	    tree->t_access);		/* l */
154a90cf9f2SGordon Ross 
155ea524515SGordon Ross 	return (rv);
156a90cf9f2SGordon Ross }
157