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