/*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*/
/*
* Copyright 2014 Nexenta Systems, Inc. All rights reserved.
*/
/*
* Dispatch function for SMB2_TREE_CONNECT
*/
#include <smbsrv/smb2_kproto.h>
smb_sdrc_t
smb2_tree_connect(smb_request_t *sr)
{
smb_arg_tcon_t *tcon = &sr->sr_tcon;
smb_tree_t *tree = NULL;
uint16_t StructureSize;
uint16_t PathOffset;
uint16_t PathLength;
uint8_t ShareType;
uint32_t ShareFlags;
uint32_t Capabilities;
uint32_t status;
int skip;
int rc = 0;
/*
* SMB2 Tree Connect request
*/
rc = smb_mbc_decodef(
&sr->smb_data, "w..ww",
&StructureSize,
/* reserved */
&PathOffset,
&PathLength);
if (rc)
return (SDRC_ERROR);
/*
* We're normally positioned at the path name now,
* but there could be some padding before it.
*/
skip = (PathOffset + sr->smb2_cmd_hdr) -
sr->smb_data.chain_offset;
if (skip < 0)
return (SDRC_ERROR);
if (skip > 0)
(void) smb_mbc_decodef(&sr->smb_data, "#.", skip);
/*
* Get the path name
*/
rc = smb_mbc_decodef(
&sr->smb_data, "%#U",
sr, (uint_t)PathLength, &tcon->path);
if (rc)
return (SDRC_ERROR);
status = smb_tree_connect(sr);
if (status) {
(void) smb2sr_put_error(sr, status);
return (SDRC_SUCCESS);
}
tree = sr->tid_tree;
/*
* Report the share type.
*/
switch (tree->t_res_type & STYPE_MASK) {
case STYPE_IPC:
ShareType = SMB2_SHARE_TYPE_PIPE;
break;
case STYPE_PRINTQ:
ShareType = SMB2_SHARE_TYPE_PRINT;
break;
case STYPE_DISKTREE:
default:
ShareType = SMB2_SHARE_TYPE_DISK;
break;
}
/*
* XXX These need work..
*/
ShareFlags = 0;
Capabilities = 0;
/*
* SMB2 Tree Connect reply
*/
rc = smb_mbc_encodef(
&sr->reply,
"wb.lll",
16, /* StructSize */ /* w */
ShareType, /* b */
ShareFlags, /* l */
Capabilities, /* l */
tree->t_access); /* l */
if (rc)
return (SDRC_ERROR);
return (SDRC_SUCCESS);
}