summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Barden <matt.barden@nexenta.com>2018-05-24 17:35:49 -0400
committerGordon Ross <gwr@nexenta.com>2019-08-22 17:44:32 -0400
commitdfa42fab8d7071228466d2f82351da8e1a090aad (patch)
tree3a8d5819ed952e141e6829d67e695e0e742955b2
parent1bc6aeee80885d7c0e78d4eddf68dfdcb8520c7e (diff)
downloadillumos-joyent-dfa42fab8d7071228466d2f82351da8e1a090aad.tar.gz
11035 Minimal SMB 3.0.2 support
Reviewed by: Gordon Ross <gordon.ross@nexenta.com> Reviewed by: Evan Layton <evan.layton@nexenta.com> Reviewed by: Garrett D'Amore <garrett@damore.org> Approved by: Garrett D'Amore <garrett@damore.org>
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_cfg.c5
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb2_aapl.c14
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb2_durable.c4
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb2_fsctl_sparse.c2
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb2_negotiate.c3
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb2_read.c32
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb2_write.c26
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_fsops.c4
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_read.c4
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_vops.c4
-rw-r--r--usr/src/uts/common/smbsrv/smb2.h8
-rw-r--r--usr/src/uts/common/smbsrv/smb_fsops.h4
-rw-r--r--usr/src/uts/common/smbsrv/smb_vops.h4
-rw-r--r--usr/src/uts/common/smbsrv/smbinfo.h3
14 files changed, 85 insertions, 32 deletions
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c b/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c
index 45b0e79c44..c27c4af6b0 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -165,6 +165,7 @@ static smb_cfg_param_t smb_cfg_table[] =
*/
static struct str_val
smb_versions[] = {
+ { "3.02", SMB_VERS_3_02 },
{ "3.0", SMB_VERS_3_0 },
{ "2.1", SMB_VERS_2_1 },
{ "2.002", SMB_VERS_2_002 },
@@ -1223,7 +1224,7 @@ smb_config_get_protocol(smb_cfg_id_t id, char *name, uint32_t default_val)
* whole range that we implement). For that reason, this should usually be the
* highest protocol version we implement.
*/
-uint32_t max_protocol_default = SMB_VERS_3_0;
+uint32_t max_protocol_default = SMB_VERS_3_02;
uint32_t
smb_config_get_max_protocol(void)
diff --git a/usr/src/uts/common/fs/smbsrv/smb2_aapl.c b/usr/src/uts/common/fs/smbsrv/smb2_aapl.c
index 3deac16513..d4d6bd607e 100644
--- a/usr/src/uts/common/fs/smbsrv/smb2_aapl.c
+++ b/usr/src/uts/common/fs/smbsrv/smb2_aapl.c
@@ -10,7 +10,7 @@
*/
/*
- * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -68,8 +68,8 @@ static int smb_aapl_ext_maxlen = 512;
*/
uint32_t
smb2_aapl_crctx(smb_request_t *sr,
- mbuf_chain_t *mbcin,
- mbuf_chain_t *mbcout)
+ mbuf_chain_t *mbcin,
+ mbuf_chain_t *mbcout)
{
uint32_t cmdcode;
uint32_t status;
@@ -105,7 +105,7 @@ smb2_aapl_crctx(smb_request_t *sr,
*/
static uint32_t
smb2_aapl_srv_query(smb_request_t *sr,
- mbuf_chain_t *mbcin, mbuf_chain_t *mbcout)
+ mbuf_chain_t *mbcin, mbuf_chain_t *mbcout)
{
uint64_t client_bitmap;
uint64_t client_caps;
@@ -164,8 +164,8 @@ smb2_aapl_srv_query(smb_request_t *sr,
*/
int
smb2_aapl_get_macinfo(smb_request_t *sr, smb_odir_t *od,
- smb_fileinfo_t *fileinfo, smb_macinfo_t *mi,
- char *tbuf, size_t tbuflen)
+ smb_fileinfo_t *fileinfo, smb_macinfo_t *mi,
+ char *tbuf, size_t tbuflen)
{
int rc;
cred_t *kcr = zone_kcred();
@@ -224,7 +224,7 @@ smb2_aapl_get_macinfo(smb_request_t *sr, smb_odir_t *od,
uio.uio_resid = sizeof (AfpInfo);
uio.uio_segflg = UIO_SYSSPACE;
uio.uio_extflg = UIO_COPY_DEFAULT;
- rc = smb_fsop_read(sr, kcr, snode, NULL, &uio);
+ rc = smb_fsop_read(sr, kcr, snode, NULL, &uio, 0);
if (rc == 0 && uio.uio_resid == 0) {
bcopy(&AfpInfo[4], &mi->mi_finderinfo,
sizeof (mi->mi_finderinfo));
diff --git a/usr/src/uts/common/fs/smbsrv/smb2_durable.c b/usr/src/uts/common/fs/smbsrv/smb2_durable.c
index 7b65924ca4..56dda62832 100644
--- a/usr/src/uts/common/fs/smbsrv/smb2_durable.c
+++ b/usr/src/uts/common/fs/smbsrv/smb2_durable.c
@@ -10,7 +10,7 @@
*/
/*
- * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -844,7 +844,7 @@ smb2_dh_read_nvlist(smb_request_t *sr, smb_node_t *node,
uio.uio_resid = flen;
uio.uio_segflg = UIO_SYSSPACE;
uio.uio_extflg = UIO_COPY_DEFAULT;
- rc = smb_fsop_read(sr, kcr, node, NULL, &uio);
+ rc = smb_fsop_read(sr, kcr, node, NULL, &uio, 0);
if (rc != 0) {
cmn_err(CE_NOTE, "CA import (%s/%s) read, rc=%d",
shr->shr_path, node->od_name, rc);
diff --git a/usr/src/uts/common/fs/smbsrv/smb2_fsctl_sparse.c b/usr/src/uts/common/fs/smbsrv/smb2_fsctl_sparse.c
index db89469cc0..90bb254670 100644
--- a/usr/src/uts/common/fs/smbsrv/smb2_fsctl_sparse.c
+++ b/usr/src/uts/common/fs/smbsrv/smb2_fsctl_sparse.c
@@ -377,7 +377,7 @@ smb2_sparse_copy(
uio.uio_extflg = UIO_COPY_DEFAULT;
rc = smb_fsop_read(sr, src_ofile->f_cr,
- src_ofile->f_node, src_ofile, &uio);
+ src_ofile->f_node, src_ofile, &uio, 0);
if (rc != 0) {
status = smb_errno2status(rc);
return (status);
diff --git a/usr/src/uts/common/fs/smbsrv/smb2_negotiate.c b/usr/src/uts/common/fs/smbsrv/smb2_negotiate.c
index 5bc7b01260..52a5dd3a96 100644
--- a/usr/src/uts/common/fs/smbsrv/smb2_negotiate.c
+++ b/usr/src/uts/common/fs/smbsrv/smb2_negotiate.c
@@ -10,7 +10,7 @@
*/
/*
- * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -74,6 +74,7 @@ static uint16_t smb2_versions[] = {
0x202, /* SMB 2.002 */
0x210, /* SMB 2.1 */
0x300, /* SMB 3.0 */
+ 0x302, /* SMB 3.02 */
};
static uint16_t smb2_nversions =
sizeof (smb2_versions) / sizeof (smb2_versions[0]);
diff --git a/usr/src/uts/common/fs/smbsrv/smb2_read.c b/usr/src/uts/common/fs/smbsrv/smb2_read.c
index 9ef2aa57c4..f8c91c878f 100644
--- a/usr/src/uts/common/fs/smbsrv/smb2_read.c
+++ b/usr/src/uts/common/fs/smbsrv/smb2_read.c
@@ -20,6 +20,8 @@
#include <smbsrv/smb2_kproto.h>
#include <smbsrv/smb_fsops.h>
+extern boolean_t smb_allow_unbuffered;
+
smb_sdrc_t
smb2_read(smb_request_t *sr)
{
@@ -29,6 +31,7 @@ smb2_read(smb_request_t *sr)
struct mbuf *m = NULL;
uint16_t StructSize;
uint8_t Padding;
+ uint8_t Flags;
uint8_t DataOff;
uint32_t Length;
uint64_t Offset;
@@ -41,15 +44,18 @@ smb2_read(smb_request_t *sr)
uint32_t XferCount;
uint32_t status;
int rc = 0;
+ boolean_t unbuffered = B_FALSE;
+ int ioflag = 0;
/*
* SMB2 Read request
*/
rc = smb_mbc_decodef(
&sr->smb_data,
- "wb.lqqqlllww",
+ "wbblqqqlllww",
&StructSize, /* w */
- &Padding, /* b. */
+ &Padding, /* b */
+ &Flags, /* b */
&Length, /* l */
&Offset, /* q */
&smb2fid.persistent, /* q */
@@ -104,6 +110,21 @@ smb2_read(smb_request_t *sr)
sr->raw_data.max_bytes = Length;
m = smb_mbuf_allocate(&vdb->vdb_uio);
+ /*
+ * Unbuffered refers to the MS-FSA Read argument by the same name.
+ * It indicates that the cache for this range should be flushed to disk,
+ * and data read directly from disk, bypassing the cache.
+ * We don't allow that degree of cache management.
+ * Translate this directly as FRSYNC,
+ * which should at least flush the cache first.
+ */
+
+ if (smb_allow_unbuffered &&
+ (Flags & SMB2_READFLAG_READ_UNBUFFERED) != 0) {
+ unbuffered = B_TRUE;
+ ioflag = FRSYNC;
+ }
+
switch (of->f_tree->t_res_type & STYPE_MASK) {
case STYPE_DISKTREE:
if (!smb_node_is_dir(of->f_node)) {
@@ -116,10 +137,13 @@ smb2_read(smb_request_t *sr)
}
}
rc = smb_fsop_read(sr, of->f_cr, of->f_node, of,
- &vdb->vdb_uio);
+ &vdb->vdb_uio, ioflag);
break;
case STYPE_IPC:
- rc = smb_opipe_read(sr, &vdb->vdb_uio);
+ if (unbuffered)
+ rc = EINVAL;
+ else
+ rc = smb_opipe_read(sr, &vdb->vdb_uio);
break;
default:
case STYPE_PRINTQ:
diff --git a/usr/src/uts/common/fs/smbsrv/smb2_write.c b/usr/src/uts/common/fs/smbsrv/smb2_write.c
index 9e0795e21f..776ea24ae1 100644
--- a/usr/src/uts/common/fs/smbsrv/smb2_write.c
+++ b/usr/src/uts/common/fs/smbsrv/smb2_write.c
@@ -20,6 +20,8 @@
#include <smbsrv/smb2_kproto.h>
#include <smbsrv/smb_fsops.h>
+boolean_t smb_allow_unbuffered = B_TRUE;
+
smb_sdrc_t
smb2_write(smb_request_t *sr)
{
@@ -41,6 +43,7 @@ smb2_write(smb_request_t *sr)
int data_chain_off, skip;
int stability = 0;
int rc = 0;
+ boolean_t unbuffered = B_FALSE;
/*
* Decode SMB2 Write request
@@ -111,6 +114,19 @@ smb2_write(smb_request_t *sr)
if (Length == 0)
goto errout;
+ /*
+ * Unbuffered refers to the MS-FSA Write argument by the same name.
+ * It indicates that the cache for this range should be flushed to disk,
+ * and data written directly to disk, bypassing the cache.
+ * We don't allow that degree of cache management.
+ * Translate this directly as FSYNC,
+ * which should at least flush the cache.
+ */
+
+ if (smb_allow_unbuffered &&
+ (Flags & SMB2_WRITEFLAG_WRITE_UNBUFFERED) != 0)
+ unbuffered = B_TRUE;
+
switch (of->f_tree->t_res_type & STYPE_MASK) {
case STYPE_DISKTREE:
case STYPE_PRINTQ:
@@ -123,8 +139,9 @@ smb2_write(smb_request_t *sr)
break;
}
}
- if ((Flags & SMB2_WRITEFLAG_WRITE_THROUGH) ||
- (of->f_node->flags & NODE_FLAGS_WRITE_THROUGH)) {
+
+ if (unbuffered || (Flags & SMB2_WRITEFLAG_WRITE_THROUGH) != 0 ||
+ (of->f_node->flags & NODE_FLAGS_WRITE_THROUGH) != 0) {
stability = FSYNC;
}
rc = smb_fsop_write(sr, of->f_cr, of->f_node, of,
@@ -137,7 +154,10 @@ smb2_write(smb_request_t *sr)
break;
case STYPE_IPC:
- rc = smb_opipe_write(sr, &vdb->vdb_uio);
+ if (unbuffered || (Flags & SMB2_WRITEFLAG_WRITE_THROUGH) != 0)
+ rc = EINVAL;
+ else
+ rc = smb_opipe_write(sr, &vdb->vdb_uio);
if (rc == 0)
XferCount = Length;
break;
diff --git a/usr/src/uts/common/fs/smbsrv/smb_fsops.c b/usr/src/uts/common/fs/smbsrv/smb_fsops.c
index d5cbea9400..8fafac5f60 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_fsops.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_fsops.c
@@ -1380,7 +1380,7 @@ smb_fsop_freesp(
*/
int
smb_fsop_read(smb_request_t *sr, cred_t *cr, smb_node_t *snode,
- smb_ofile_t *ofile, uio_t *uio)
+ smb_ofile_t *ofile, uio_t *uio, int ioflag)
{
caller_context_t ct;
cred_t *kcr = zone_kcred();
@@ -1449,7 +1449,7 @@ smb_fsop_read(smb_request_t *sr, cred_t *cr, smb_node_t *snode,
}
}
- rc = smb_vop_read(snode->vp, uio, cr);
+ rc = smb_vop_read(snode->vp, uio, ioflag, cr);
smb_node_end_crit(snode);
return (rc);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_read.c b/usr/src/uts/common/fs/smbsrv/smb_read.c
index 1cd046a1eb..0b982337d0 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_read.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_read.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
*/
#include <smbsrv/smb_kproto.h>
@@ -438,7 +438,7 @@ smb_common_read(smb_request_t *sr, smb_rw_param_t *param)
top = smb_mbuf_allocate(&vdb->vdb_uio);
rc = smb_fsop_read(sr, sr->user_cr, node, ofile,
- &vdb->vdb_uio);
+ &vdb->vdb_uio, 0);
sr->raw_data.max_bytes -= vdb->vdb_uio.uio_resid;
smb_mbuf_trim(top, sr->raw_data.max_bytes);
diff --git a/usr/src/uts/common/fs/smbsrv/smb_vops.c b/usr/src/uts/common/fs/smbsrv/smb_vops.c
index 4b0f99839f..675b4dd6e3 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_vops.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_vops.c
@@ -250,12 +250,12 @@ smb_vop_other_opens(vnode_t *vp, int mode)
*/
int
-smb_vop_read(vnode_t *vp, uio_t *uiop, cred_t *cr)
+smb_vop_read(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr)
{
int error;
(void) VOP_RWLOCK(vp, V_WRITELOCK_FALSE, &smb_ct);
- error = VOP_READ(vp, uiop, 0, cr, &smb_ct);
+ error = VOP_READ(vp, uiop, ioflag, cr, &smb_ct);
VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, &smb_ct);
return (error);
}
diff --git a/usr/src/uts/common/smbsrv/smb2.h b/usr/src/uts/common/smbsrv/smb2.h
index d58b3cbb0b..f18fcbd379 100644
--- a/usr/src/uts/common/smbsrv/smb2.h
+++ b/usr/src/uts/common/smbsrv/smb2.h
@@ -10,7 +10,7 @@
*/
/*
- * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _SMB_SMB2_H
@@ -318,9 +318,15 @@ typedef enum {
#define SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB 0x0001
/*
+ * SMB2 Read
+ */
+#define SMB2_READFLAG_READ_UNBUFFERED 0x00000001
+
+/*
* SMB2 Write
*/
#define SMB2_WRITEFLAG_WRITE_THROUGH 0x00000001
+#define SMB2_WRITEFLAG_WRITE_UNBUFFERED 0x00000002
/*
* SMB2 Lock Request
diff --git a/usr/src/uts/common/smbsrv/smb_fsops.h b/usr/src/uts/common/smbsrv/smb_fsops.h
index 22cbd665bf..395ad5d397 100644
--- a/usr/src/uts/common/smbsrv/smb_fsops.h
+++ b/usr/src/uts/common/smbsrv/smb_fsops.h
@@ -22,7 +22,7 @@
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
- * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _SMBSRV_SMB_FSOPS_H
@@ -78,7 +78,7 @@ int smb_fsop_freesp(smb_request_t *sr, cred_t *cr, smb_ofile_t *,
off64_t, off64_t);
int smb_fsop_read(smb_request_t *, cred_t *, smb_node_t *, smb_ofile_t *,
- uio_t *);
+ uio_t *, int);
int smb_fsop_write(smb_request_t *, cred_t *, smb_node_t *, smb_ofile_t *,
uio_t *, uint32_t *, int);
diff --git a/usr/src/uts/common/smbsrv/smb_vops.h b/usr/src/uts/common/smbsrv/smb_vops.h
index 4c869de38c..cf275d2a19 100644
--- a/usr/src/uts/common/smbsrv/smb_vops.h
+++ b/usr/src/uts/common/smbsrv/smb_vops.h
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _SMBSRV_SMB_VOPS_H
@@ -125,7 +125,7 @@ void smb_vop_fini(void);
void smb_vop_start(void);
int smb_vop_open(vnode_t **, int, cred_t *);
void smb_vop_close(vnode_t *, int, cred_t *);
-int smb_vop_read(vnode_t *, uio_t *, cred_t *);
+int smb_vop_read(vnode_t *, uio_t *, int, cred_t *);
int smb_vop_write(vnode_t *, uio_t *, int, uint32_t *, cred_t *);
int smb_vop_ioctl(vnode_t *, int, void *, cred_t *);
int smb_vop_getattr(vnode_t *, vnode_t *, smb_attr_t *, int, cred_t *);
diff --git a/usr/src/uts/common/smbsrv/smbinfo.h b/usr/src/uts/common/smbsrv/smbinfo.h
index bc2e4a769b..dcbe82a10b 100644
--- a/usr/src/uts/common/smbsrv/smbinfo.h
+++ b/usr/src/uts/common/smbsrv/smbinfo.h
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
*/
#ifndef _SMBSRV_SMBINFO_H
@@ -230,6 +230,7 @@ const char *smbnative_lm_str(smb_version_t *);
#define SMB_VERS_2_002 0x202 /* "2.002" */
#define SMB_VERS_2_1 0x210 /* "2.1" */
#define SMB_VERS_3_0 0x300 /* "3.0" */
+#define SMB_VERS_3_02 0x302 /* "3.02" */
#ifdef __cplusplus
}