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 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