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,28 ****
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
! * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/uio.h>
--- 18,28 ----
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
! * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/uio.h>
*** 248,263 ****
* 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)
{
int error;
(void) VOP_RWLOCK(vp, V_WRITELOCK_FALSE, &smb_ct);
! error = VOP_READ(vp, uiop, 0, cr, &smb_ct);
VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, &smb_ct);
return (error);
}
int
--- 248,263 ----
* 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, int ioflag, cred_t *cr)
{
int error;
(void) VOP_RWLOCK(vp, V_WRITELOCK_FALSE, &smb_ct);
! error = VOP_READ(vp, uiop, ioflag, cr, &smb_ct);
VOP_RWUNLOCK(vp, V_WRITELOCK_FALSE, &smb_ct);
return (error);
}
int
*** 277,286 ****
--- 277,303 ----
*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,550 ****
int error = 0;
if (mode == 0)
return (0);
! if ((flags == V_ACE_MASK) && (mode & ACE_DELETE)) {
! if (dir_vp) {
error = VOP_ACCESS(dir_vp, ACE_DELETE_CHILD, flags,
cr, NULL);
if (error == 0)
mode &= ~ACE_DELETE;
}
}
! if (mode) {
error = VOP_ACCESS(vp, mode, flags, cr, NULL);
- }
return (error);
}
/*
* smb_vop_lookup
--- 544,582 ----
int error = 0;
if (mode == 0)
return (0);
! 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 != 0)
error = VOP_ACCESS(vp, mode, flags, cr, NULL);
+ smb_audit_load();
return (error);
}
/*
* smb_vop_lookup
*** 618,635 ****
if (flags & SMB_CATIA)
np = smb_vop_catia_v5tov4(name, namebuf, sizeof (namebuf));
pn_alloc(&rpn);
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 (flags & SMB_CATIA)
smb_vop_catia_v4tov5(np, od_name, MAXNAMELEN);
else
(void) strlcpy(od_name, np, MAXNAMELEN);
}
--- 650,676 ----
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);
! 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,685 ****
--- 717,740 ----
}
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,978 ****
struct iovec aiov;
if (vp->v_type != VDIR)
return (ENOTDIR);
! if (vfs_has_feature(vp->v_vfsp, VFSFT_DIRENTFLAGS)) {
flags |= V_RDDIR_ENTFLAGS;
rdirent_size = sizeof (edirent_t);
} else {
rdirent_size = sizeof (dirent64_t);
}
--- 1023,1034 ----
struct iovec aiov;
if (vp->v_type != VDIR)
return (ENOTDIR);
! 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,1226 ****
default:
return (EINVAL);
}
! if (error = VOP_GETSECATTR(vp, &vsecattr, flags, cr, &smb_ct))
return (error);
*aclp = smb_fsacl_from_vsa(&vsecattr, acl_type);
if (vp->v_type == VDIR)
(*aclp)->acl_flags |= ACL_IS_DIR;
--- 1272,1282 ----
default:
return (EINVAL);
}
! 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,1461 ****
shr_own.sl_pid = shr.s_pid;
return (VOP_SHRLOCK(vp, F_UNSHARE, &shr, 0, cr, NULL));
}
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;
flk_init_callback(&flk_cb, smb_lock_frlock_callback, NULL);
return (VOP_FRLOCK(vp, cmd, bf, flag, 0, &flk_cb, cr, &smb_ct));
}
--- 1502,1537 ----
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)
{
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,1539 ****
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;
char mbstring[MTS_MB_CHAR_MAX];
char *p, *src = name, *dst = buf;
ASSERT(name);
ASSERT(buf);
--- 1605,1615 ----
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 */
! uint32_t wc;
char mbstring[MTS_MB_CHAR_MAX];
char *p, *src = name, *dst = buf;
ASSERT(name);
ASSERT(buf);
*** 1586,1596 ****
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;
char mbstring[MTS_MB_CHAR_MAX];
char *src = name, *dst = buf;
ASSERT(name);
ASSERT(buf);
--- 1662,1672 ----
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 */
! uint32_t wc;
char mbstring[MTS_MB_CHAR_MAX];
char *src = name, *dst = buf;
ASSERT(name);
ASSERT(buf);