diff options
author | Matt Barden <matt.barden@nexenta.com> | 2018-05-24 17:35:49 -0400 |
---|---|---|
committer | Gordon Ross <gwr@nexenta.com> | 2019-08-22 17:44:32 -0400 |
commit | dfa42fab8d7071228466d2f82351da8e1a090aad (patch) | |
tree | 3a8d5819ed952e141e6829d67e695e0e742955b2 | |
parent | 1bc6aeee80885d7c0e78d4eddf68dfdcb8520c7e (diff) | |
download | illumos-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.c | 5 | ||||
-rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb2_aapl.c | 14 | ||||
-rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb2_durable.c | 4 | ||||
-rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb2_fsctl_sparse.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb2_negotiate.c | 3 | ||||
-rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb2_read.c | 32 | ||||
-rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb2_write.c | 26 | ||||
-rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_fsops.c | 4 | ||||
-rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_read.c | 4 | ||||
-rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_vops.c | 4 | ||||
-rw-r--r-- | usr/src/uts/common/smbsrv/smb2.h | 8 | ||||
-rw-r--r-- | usr/src/uts/common/smbsrv/smb_fsops.h | 4 | ||||
-rw-r--r-- | usr/src/uts/common/smbsrv/smb_vops.h | 4 | ||||
-rw-r--r-- | usr/src/uts/common/smbsrv/smbinfo.h | 3 |
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 } |