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