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