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);