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