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