xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb2_tree_connect.c (revision 7a6d80f1660abd4755c68cbd094d4a914681d26e)
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
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