Print this page
NEX-19152 MacOS HighSierra Finder crashes...
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-19025 CIFS gets confused with filenames containing enhanced Unicode
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
and: (fix build, check-rtime)
NEX-13644 File access audit logging
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-4820 intended nbmand locking functionality is confused
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-17289 Minimal SMB 3.0.2 support
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-16157 Removal of "Read Attributes" prevents reading directory over SMB
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-16157 Removal of "Read Attributes" prevents reading directory over SMB
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-9808 SMB3 persistent handles
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15069 smtorture smb2.create.blob is failed
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-9808 SMB3 persistent handles
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15069 smtorture smb2.create.blob is failed
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-6116 Failures in smbtorture raw.open (2)
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-6276 SMB sparse file support
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-6096 Enable compile warnings re. parentheses in smbsrv
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Jean McCormack <jean.mccormack@nexenta.com>
SMB-11 SMB2 message parse & dispatch
SMB-12 SMB2 Negotiate Protocol
SMB-13 SMB2 Session Setup
SMB-14 SMB2 Logoff
SMB-15 SMB2 Tree Connect
SMB-16 SMB2 Tree Disconnect
SMB-17 SMB2 Create
SMB-18 SMB2 Close
SMB-19 SMB2 Flush
SMB-20 SMB2 Read
SMB-21 SMB2 Write
SMB-22 SMB2 Lock/Unlock
SMB-23 SMB2 Ioctl
SMB-24 SMB2 Cancel
SMB-25 SMB2 Echo
SMB-26 SMB2 Query Dir
SMB-27 SMB2 Change Notify
SMB-28 SMB2 Query Info
SMB-29 SMB2 Set Info
SMB-30 SMB2 Oplocks
SMB-53 SMB2 Create Context options
(SMB2 code review cleanup 1, 2, 3)
SMB-50 User-mode SMB server
Includes work by these authors:
Thomas Keiser <thomas.keiser@nexenta.com>
Albert Lee <trisk@nexenta.com>
SMB-65 SMB server in non-global zones (use zone_kcred())
SMB-65 SMB server in non-global zones (data structure changes)
Many things move to the smb_server_t object, and
many functions gain an sv arg (which server).
re #7815 SMB server delivers old modification time...
@@ -18,11 +18,11 @@
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/uio.h>
@@ -248,16 +248,16 @@
* XXX - Extended attributes support in the file system assumed.
* This is needed for full NT Streams functionality.
*/
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);
}
int
@@ -277,10 +277,27 @@
*lcount -= uiop->uio_resid;
return (error);
}
+int
+smb_vop_ioctl(vnode_t *vp, int cmd, void *arg, cred_t *cr)
+{
+ int error, rval = 0;
+ uint_t flags = 0;
+
+#ifdef FKIOCTL
+ flags |= FKIOCTL;
+#endif
+ error = VOP_IOCTL(vp, cmd, (intptr_t)arg, (int)flags, cr,
+ &rval, &smb_ct);
+ if (error != 0)
+ rval = error;
+
+ return (rval);
+}
+
/*
* smb_vop_getattr()
*
* smb_fsop_getattr()/smb_vop_getattr() should always be called from the CIFS
* service (instead of calling VOP_GETATTR directly) to retrieve attributes
@@ -527,24 +544,39 @@
int error = 0;
if (mode == 0)
return (0);
- if ((flags == V_ACE_MASK) && (mode & ACE_DELETE)) {
- if (dir_vp) {
+ error = VOP_ACCESS(vp, mode, flags, cr, NULL);
+
+ if (error == 0)
+ return (0);
+
+ if ((mode & (ACE_DELETE|ACE_READ_ATTRIBUTES)) == 0 ||
+ flags != V_ACE_MASK || dir_vp == NULL)
+ return (error);
+
+ smb_audit_save();
+ if ((mode & ACE_DELETE) != 0) {
error = VOP_ACCESS(dir_vp, ACE_DELETE_CHILD, flags,
cr, NULL);
if (error == 0)
mode &= ~ACE_DELETE;
}
+ if ((mode & ACE_READ_ATTRIBUTES) != 0) {
+ error = VOP_ACCESS(dir_vp, ACE_LIST_DIRECTORY, flags,
+ cr, NULL);
+
+ if (error == 0)
+ mode &= ~ACE_READ_ATTRIBUTES;
}
- if (mode) {
+ if (mode != 0)
error = VOP_ACCESS(vp, mode, flags, cr, NULL);
- }
+ smb_audit_load();
return (error);
}
/*
* smb_vop_lookup
@@ -618,18 +650,27 @@
if (flags & SMB_CATIA)
np = smb_vop_catia_v5tov4(name, namebuf, sizeof (namebuf));
pn_alloc(&rpn);
+ /*
+ * Easier to not have junk in rpn, as not every FS type
+ * will necessarily fill that in for us.
+ */
+ bzero(rpn.pn_buf, rpn.pn_bufsize);
+
error = VOP_LOOKUP(dvp, np, vpp, NULL, option_flags, NULL, cr,
&smb_ct, direntflags, &rpn);
if (error == 0) {
if (od_name) {
bzero(od_name, MAXNAMELEN);
- np = (option_flags == FIGNORECASE) ? rpn.pn_buf : name;
-
+ if ((option_flags & FIGNORECASE) != 0 &&
+ rpn.pn_buf[0] != '\0')
+ np = rpn.pn_buf;
+ else
+ np = name;
if (flags & SMB_CATIA)
smb_vop_catia_v4tov5(np, od_name, MAXNAMELEN);
else
(void) strlcpy(od_name, np, MAXNAMELEN);
}
@@ -676,10 +717,24 @@
}
error = VOP_CREATE(dvp, np, vap, EXCL, attr->sa_vattr.va_mode,
vpp, cr, option_flags, &smb_ct, vsap);
+ /*
+ * One could argue that filesystems should obey the size
+ * if specified in the create attributes. Unfortunately,
+ * they only appear to let you truncate the size to zero.
+ * SMB needs to set a non-zero size, so work-around.
+ */
+ if (error == 0 && *vpp != NULL &&
+ (vap->va_mask & AT_SIZE) != 0 &&
+ vap->va_size > 0) {
+ vattr_t ta = *vap;
+ ta.va_mask = AT_SIZE;
+ (void) VOP_SETATTR(*vpp, &ta, 0, cr, &smb_ct);
+ }
+
return (error);
}
int
smb_vop_remove(vnode_t *dvp, char *name, int flags, cred_t *cr)
@@ -968,11 +1023,12 @@
struct iovec aiov;
if (vp->v_type != VDIR)
return (ENOTDIR);
- if (vfs_has_feature(vp->v_vfsp, VFSFT_DIRENTFLAGS)) {
+ if ((rddir_flag & SMB_EDIRENT) != 0 &&
+ vfs_has_feature(vp->v_vfsp, VFSFT_DIRENTFLAGS)) {
flags |= V_RDDIR_ENTFLAGS;
rdirent_size = sizeof (edirent_t);
} else {
rdirent_size = sizeof (dirent64_t);
}
@@ -1216,11 +1272,11 @@
default:
return (EINVAL);
}
- if (error = VOP_GETSECATTR(vp, &vsecattr, flags, cr, &smb_ct))
+ if ((error = VOP_GETSECATTR(vp, &vsecattr, flags, cr, &smb_ct)) != 0)
return (error);
*aclp = smb_fsacl_from_vsa(&vsecattr, acl_type);
if (vp->v_type == VDIR)
(*aclp)->acl_flags |= ACL_IS_DIR;
@@ -1446,16 +1502,36 @@
shr_own.sl_pid = shr.s_pid;
return (VOP_SHRLOCK(vp, F_UNSHARE, &shr, 0, cr, NULL));
}
+/*
+ * Note about mandatory vs advisory locks:
+ *
+ * The SMB server really should always request mandatory locks, and
+ * if the file system does not support them, the SMB server should
+ * just tell the client it could not get the lock. If we were to
+ * tell the SMB client "you got the lock" when what they really
+ * got was only an advisory lock, we would be lying to the client
+ * about their having exclusive access to the locked range, which
+ * could easily lead to data corruption. If someone really wants
+ * the (dangerous) behavior they can set: smb_allow_advisory_locks
+ */
int
smb_vop_frlock(vnode_t *vp, cred_t *cr, int flag, flock64_t *bf)
{
- int cmd = nbl_need_check(vp) ? F_SETLK_NBMAND : F_SETLK;
flk_callback_t flk_cb;
+ int cmd = F_SETLK_NBMAND;
+ if (smb_allow_advisory_locks != 0 && !nbl_need_check(vp)) {
+ /*
+ * The file system does not support nbmand, and
+ * smb_allow_advisory_locks is enabled. (danger!)
+ */
+ cmd = F_SETLK;
+ }
+
flk_init_callback(&flk_cb, smb_lock_frlock_callback, NULL);
return (VOP_FRLOCK(vp, cmd, bf, flag, 0, &flk_cb, cr, &smb_ct));
}
@@ -1529,11 +1605,11 @@
char *
smb_vop_catia_v5tov4(char *name, char *buf, int buflen)
{
int v4_idx, numbytes, inc;
int space_left = buflen - 1; /* one byte reserved for null */
- smb_wchar_t wc;
+ uint32_t wc;
char mbstring[MTS_MB_CHAR_MAX];
char *p, *src = name, *dst = buf;
ASSERT(name);
ASSERT(buf);
@@ -1586,11 +1662,11 @@
void
smb_vop_catia_v4tov5(char *name, char *buf, int buflen)
{
int v5_idx, numbytes;
int space_left = buflen - 1; /* one byte reserved for null */
- smb_wchar_t wc;
+ uint32_t wc;
char mbstring[MTS_MB_CHAR_MAX];
char *src = name, *dst = buf;
ASSERT(name);
ASSERT(buf);