Print this page
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-15069 smtorture smb2.create.blob is failed
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-4083 Upstream changes from illumos 5917 and 5995
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
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).

*** 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/param.h> #include <sys/sunddi.h> --- 18,28 ---- * * CDDL HEADER END */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. ! * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ #include <sys/types.h> #include <sys/param.h> #include <sys/sunddi.h>
*** 349,363 **** * in the directory entry. * * smb_unmangle should only be called on names for which * smb_maybe_mangled() is true * ! * File systems which support VFSFT_EDIRENT_FLAGS will return the ! * directory entries as a buffer of edirent_t structure. Others will ! * return a buffer of dirent64_t structures. A union is used for the ! * the pointer into the buffer (bufptr, edp and dp). ! * The ed_name/d_name is NULL terminated by the file system. * * Returns: * 0 - SUCCESS. Unmangled name is returned in namebuf. * EINVAL - a parameter was invalid. * ENOTDIR - dnode is not a directory node. --- 349,360 ---- * in the directory entry. * * smb_unmangle should only be called on names for which * smb_maybe_mangled() is true * ! * The flags arg is no longer used, but retained just to avoid ! * changing the many callers of this function. * * Returns: * 0 - SUCCESS. Unmangled name is returned in namebuf. * EINVAL - a parameter was invalid. * ENOTDIR - dnode is not a directory node.
*** 366,390 **** #define SMB_UNMANGLE_BUFSIZE (4 * 1024) int smb_unmangle(smb_node_t *dnode, char *name, char *namebuf, int buflen, uint32_t flags) { ! int err, eof, bufsize, reclen; uint64_t offset; ino64_t ino; - boolean_t is_edp; char *namep, *buf; char shortname[SMB_SHORTNAMELEN]; vnode_t *vp; ! union { ! char *u_bufptr; ! edirent_t *u_edp; ! dirent64_t *u_dp; ! } u; ! #define bufptr u.u_bufptr ! #define edp u.u_edp ! #define dp u.u_dp if (dnode == NULL || name == NULL || namebuf == NULL || buflen == 0) return (EINVAL); ASSERT(smb_maybe_mangled(name) == B_TRUE); --- 363,383 ---- #define SMB_UNMANGLE_BUFSIZE (4 * 1024) int smb_unmangle(smb_node_t *dnode, char *name, char *namebuf, int buflen, uint32_t flags) { ! _NOTE(ARGUNUSED(flags)) // avoid changing all callers ! int err, eof, bufsize; uint64_t offset; ino64_t ino; char *namep, *buf; char shortname[SMB_SHORTNAMELEN]; vnode_t *vp; ! char *bufptr; ! dirent64_t *dp; ! cred_t *cr = zone_kcred(); ! int rc = ENOENT; if (dnode == NULL || name == NULL || namebuf == NULL || buflen == 0) return (EINVAL); ASSERT(smb_maybe_mangled(name) == B_TRUE);
*** 392,450 **** if (!smb_node_is_dir(dnode)) return (ENOTDIR); vp = dnode->vp; *namebuf = '\0'; - is_edp = vfs_has_feature(vp->v_vfsp, VFSFT_DIRENTFLAGS); buf = kmem_alloc(SMB_UNMANGLE_BUFSIZE, KM_SLEEP); ! bufsize = SMB_UNMANGLE_BUFSIZE; ! offset = 0; ! while ((err = smb_vop_readdir(vp, offset, buf, &bufsize, ! &eof, flags, zone_kcred())) == 0) { if (bufsize == 0) { ! err = ENOENT; break; } - bufptr = buf; ! reclen = 0; ! while ((bufptr += reclen) < buf + bufsize) { ! if (is_edp) { ! reclen = edp->ed_reclen; ! offset = edp->ed_off; ! ino = edp->ed_ino; ! namep = edp->ed_name; ! } else { ! reclen = dp->d_reclen; offset = dp->d_off; ino = dp->d_ino; namep = dp->d_name; - } /* skip non utf8 filename */ if (u8_validate(namep, strlen(namep), NULL, U8_VALIDATE_ENTIRE, &err) < 0) continue; smb_mangle(namep, ino, shortname, SMB_SHORTNAMELEN); - if (smb_strcasecmp(name, shortname, 0) == 0) { (void) strlcpy(namebuf, namep, buflen); ! kmem_free(buf, SMB_UNMANGLE_BUFSIZE); ! return (0); ! } ! } ! ! if (eof) { ! err = ENOENT; break; } - - bufsize = SMB_UNMANGLE_BUFSIZE; } kmem_free(buf, SMB_UNMANGLE_BUFSIZE); ! return (err); } --- 385,448 ---- if (!smb_node_is_dir(dnode)) return (ENOTDIR); vp = dnode->vp; *namebuf = '\0'; buf = kmem_alloc(SMB_UNMANGLE_BUFSIZE, KM_SLEEP); ! bufptr = buf; ! bufsize = 0; ! offset = 0; // next entry offset ! eof = B_FALSE; ! for (;;) { ! /* ! * Read some entries, if buffer empty or ! * we've scanned all of it. Flags zero ! * (no edirent, no ABE wanted here) ! */ ! if (bufsize <= 0) { ! bufsize = SMB_UNMANGLE_BUFSIZE; ! rc = smb_vop_readdir(vp, offset, buf, ! &bufsize, &eof, 0, cr); ! if (rc != 0) ! break; /* error */ if (bufsize == 0) { ! eof = B_TRUE; ! rc = ENOENT; break; } bufptr = buf; ! } ! /* LINTED pointer alignment */ ! dp = (dirent64_t *)bufptr; ! /* ! * Partial records are not supposed to happen, ! * but let's be defensive. If this happens, ! * restart at the current offset. ! */ ! bufptr += dp->d_reclen; ! bufsize -= dp->d_reclen; ! if (bufsize < 0) ! continue; ! offset = dp->d_off; ino = dp->d_ino; namep = dp->d_name; /* skip non utf8 filename */ if (u8_validate(namep, strlen(namep), NULL, U8_VALIDATE_ENTIRE, &err) < 0) continue; smb_mangle(namep, ino, shortname, SMB_SHORTNAMELEN); if (smb_strcasecmp(name, shortname, 0) == 0) { (void) strlcpy(namebuf, namep, buflen); ! rc = 0; break; } } kmem_free(buf, SMB_UNMANGLE_BUFSIZE); ! return (rc); }