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 */
15
16 /*
17 * Dispatch function for SMB2_TREE_CONNECT
18 */
19
20 #include <smbsrv/smb2_kproto.h>
21
22 #define SMB2_SHARE_CAP_CA SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY
23
24 smb_sdrc_t
smb2_tree_connect(smb_request_t * sr)25 smb2_tree_connect(smb_request_t *sr)
26 {
27 smb_arg_tcon_t *tcon = &sr->sr_tcon;
28 smb_tree_t *tree = NULL;
29 uint16_t StructureSize;
30 uint16_t PathOffset;
31 uint16_t PathLength;
32 uint8_t ShareType;
33 uint32_t ShareFlags;
34 uint32_t Capabilities;
35 uint32_t status;
36 int skip;
37 int rc = 0;
38
39 /*
40 * SMB2 Tree Connect request
41 */
42 rc = smb_mbc_decodef(
43 &sr->smb_data, "w..ww",
44 &StructureSize,
45 /* reserved */
46 &PathOffset,
47 &PathLength);
48 if (rc)
49 return (SDRC_ERROR);
50
51 /*
52 * We're normally positioned at the path name now,
53 * but there could be some padding before it.
54 */
55 skip = (PathOffset + sr->smb2_cmd_hdr) -
56 sr->smb_data.chain_offset;
57 if (skip < 0)
58 return (SDRC_ERROR);
59 if (skip > 0)
60 (void) smb_mbc_decodef(&sr->smb_data, "#.", skip);
61
62 /*
63 * Get the path name
64 */
65 rc = smb_mbc_decodef(
66 &sr->smb_data, "%#U",
67 sr, (uint_t)PathLength, &tcon->path);
68 if (rc)
69 return (SDRC_ERROR);
70
71 DTRACE_SMB2_START(op__TreeConnect, smb_request_t *, sr);
72
73 /*
74 * [MS-SMB2] 3.3.5.7 Receiving an SMB2 TREE_CONNECT Request
75 *
76 * If RejectUnencryptedAccess is TRUE,
77 * global EncryptData or Share.EncryptData is TRUE,
78 * we support 3.x, and srv_cap doesn't indicate encryption support,
79 * return ACCESS_DENIED.
80 *
81 * This also applies to SMB1, so do it in smb_tree_connect_core.
82 */
83 status = smb_tree_connect(sr);
84
85 sr->smb2_status = status;
86 DTRACE_SMB2_DONE(op__TreeConnect, smb_request_t *, sr);
87
88 if (status) {
89 (void) smb2sr_put_error(sr, status);
90 return (SDRC_SUCCESS);
91 }
92 tree = sr->tid_tree;
93
94 /*
95 * Report the share type.
96 */
97 switch (tree->t_res_type & STYPE_MASK) {
98 case STYPE_IPC:
99 ShareType = SMB2_SHARE_TYPE_PIPE;
100 break;
101 case STYPE_PRINTQ:
102 ShareType = SMB2_SHARE_TYPE_PRINT;
103 break;
104 case STYPE_DISKTREE:
105 default:
106 ShareType = SMB2_SHARE_TYPE_DISK;
107 break;
108 }
109
110 /*
111 * XXX These need work..
112 */
113 if (tree->t_encrypt != SMB_CONFIG_DISABLED)
114 ShareFlags = SMB2_SHAREFLAG_ENCRYPT_DATA;
115 else
116 ShareFlags = 0;
117
118 Capabilities = 0;
119 if ((tree->t_flags & SMB_TREE_DFSROOT) != 0)
120 Capabilities |= SMB2_SHARE_CAP_DFS;
121 if ((tree->t_flags & SMB_TREE_CA) != 0)
122 Capabilities |= SMB2_SHARE_CAP_CA;
123
124 /*
125 * SMB2 Tree Connect reply
126 */
127 (void) smb_mbc_encodef(
128 &sr->reply,
129 "wb.lll",
130 16, /* StructSize */ /* w */
131 ShareType, /* b */
132 ShareFlags, /* l */
133 Capabilities, /* l */
134 tree->t_access); /* l */
135
136 return (SDRC_SUCCESS);
137 }
138