diff options
| author | Gordon Ross <gwr@nexenta.com> | 2017-10-19 16:40:37 -0400 |
|---|---|---|
| committer | Gordon Ross <gwr@nexenta.com> | 2019-06-08 20:48:23 -0400 |
| commit | d2488fe8c5950495aef5404c8d98081be7d43487 (patch) | |
| tree | 141dcbff65d732f0b2e5bd57f4193cf3fb49e630 | |
| parent | d6390ef7453a176bd5e16ae9fde5ebe59c15f298 (diff) | |
| download | illumos-joyent-d2488fe8c5950495aef5404c8d98081be7d43487.tar.gz | |
11014 should pass smtorture smb2.create.blob
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Approved by: Garrett D'Amore <garrett@damore.org>
| -rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb2_create.c | 3 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb2_dispatch.c | 7 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb2_query_dir.c | 9 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_delete.c | 12 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_directory.c | 12 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_errno.c | 13 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_find.c | 6 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_fsops.c | 10 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_mangle_name.c | 114 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_mbuf_marshaling.c | 17 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_node.c | 67 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_odir.c | 12 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_query_fileinfo.c | 8 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_set_fileinfo.c | 7 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_trans2_find.c | 3 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_vops.c | 3 | ||||
| -rw-r--r-- | usr/src/uts/common/smbsrv/smb_fsops.h | 3 | ||||
| -rw-r--r-- | usr/src/uts/common/smbsrv/smb_kproto.h | 1 |
18 files changed, 161 insertions, 146 deletions
diff --git a/usr/src/uts/common/fs/smbsrv/smb2_create.c b/usr/src/uts/common/fs/smbsrv/smb2_create.c index f2ad134f84..473f878ba3 100644 --- a/usr/src/uts/common/fs/smbsrv/smb2_create.c +++ b/usr/src/uts/common/fs/smbsrv/smb2_create.c @@ -985,6 +985,7 @@ smb2_encode_create_ctx_elem(mbuf_chain_t *out_mbc, * a: this header (16 bytes) * b: the name (4 bytes, 4 pad) * c: the payload (variable) + * d: padding (to align 8) * * Note that "Next elem." is filled in later. */ @@ -1008,6 +1009,8 @@ smb2_encode_create_ctx_elem(mbuf_chain_t *out_mbc, cce->cce_len, /* # */ &cce->cce_mbc); /* C */ + (void) smb_mbc_put_align(out_mbc, 8); + return (rc); } diff --git a/usr/src/uts/common/fs/smbsrv/smb2_dispatch.c b/usr/src/uts/common/fs/smbsrv/smb2_dispatch.c index b0bbbd4f40..b35b91ff7c 100644 --- a/usr/src/uts/common/fs/smbsrv/smb2_dispatch.c +++ b/usr/src/uts/common/fs/smbsrv/smb2_dispatch.c @@ -723,11 +723,8 @@ cmd_done: /* * Pad the reply to align(8) if necessary. */ - if (sr->reply.chain_offset & 7) { - int padsz = 8 - (sr->reply.chain_offset & 7); - (void) smb_mbc_encodef(&sr->reply, "#.", padsz); - } - ASSERT((sr->reply.chain_offset & 7) == 0); + if (sr->smb2_next_command != 0) + (void) smb_mbc_put_align(&sr->reply, 8); /* * Record some statistics: latency, rx bytes, tx bytes. diff --git a/usr/src/uts/common/fs/smbsrv/smb2_query_dir.c b/usr/src/uts/common/fs/smbsrv/smb2_query_dir.c index 11f3515504..5859314b47 100644 --- a/usr/src/uts/common/fs/smbsrv/smb2_query_dir.c +++ b/usr/src/uts/common/fs/smbsrv/smb2_query_dir.c @@ -437,7 +437,7 @@ smb2_find_mbc_encode(smb_request_t *sr, smb2_find_args_t *args) smb_macinfo_t *macinfo = &args->fa_mi; uint8_t buf83[26]; smb_msgbuf_t mb; - int namelen, padsz; + int namelen; int shortlen = 0; int rc, starting_offset; uint32_t next_entry_offset; @@ -647,11 +647,8 @@ smb2_find_mbc_encode(smb_request_t *sr, smb2_find_args_t *args) return (NT_STATUS_BUFFER_OVERFLOW); /* Next entry needs to be 8-byte aligned. */ - padsz = sr->raw_data.chain_offset & 7; - if (padsz) { - padsz = 8 - padsz; - (void) smb_mbc_encodef(&sr->raw_data, "#.", padsz); - } + (void) smb_mbc_put_align(&sr->raw_data, 8); + next_entry_offset = sr->raw_data.chain_offset - starting_offset; (void) smb_mbc_poke(&sr->raw_data, starting_offset, "l", next_entry_offset); diff --git a/usr/src/uts/common/fs/smbsrv/smb_delete.c b/usr/src/uts/common/fs/smbsrv/smb_delete.c index 95c2063bca..3902764d23 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_delete.c +++ b/usr/src/uts/common/fs/smbsrv/smb_delete.c @@ -544,18 +544,12 @@ smb_delete_remove_file(smb_request_t *sr, smb_error_t *err) rc = smb_fsop_remove(sr, sr->user_cr, node->n_dnode, node->od_name, flags); if (rc != 0) { - if (rc == ENOENT) - smb_delete_error(err, NT_STATUS_OBJECT_NAME_NOT_FOUND, - ERRDOS, ERROR_FILE_NOT_FOUND); - else - smbsr_map_errno(rc, err); - - smb_node_end_crit(node); - return (-1); + smbsr_map_errno(rc, err); + rc = -1; } smb_node_end_crit(node); - return (0); + return (rc); } diff --git a/usr/src/uts/common/fs/smbsrv/smb_directory.c b/usr/src/uts/common/fs/smbsrv/smb_directory.c index 007f34fb45..f009c32580 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_directory.c +++ b/usr/src/uts/common/fs/smbsrv/smb_directory.c @@ -250,11 +250,7 @@ smb_com_delete_directory(smb_request_t *sr) rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS, tnode, fqi->fq_dnode, fqi->fq_last_comp, &fqi->fq_fnode); if (rc != 0) { - if (rc == ENOENT) - smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND, - ERRDOS, ERROR_FILE_NOT_FOUND); - else - smbsr_errno(sr, rc); + smbsr_errno(sr, rc); smb_node_release(fqi->fq_dnode); return (SDRC_ERROR); } @@ -414,11 +410,7 @@ smb_com_check_directory(smb_request_t *sr) tnode, fqi->fq_dnode, fqi->fq_last_comp, &fqi->fq_fnode); smb_node_release(fqi->fq_dnode); if (rc != 0) { - if (rc == ENOENT) - smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND, - ERRDOS, ERROR_PATH_NOT_FOUND); - else - smbsr_errno(sr, rc); + smbsr_errno(sr, rc); return (SDRC_ERROR); } diff --git a/usr/src/uts/common/fs/smbsrv/smb_errno.c b/usr/src/uts/common/fs/smbsrv/smb_errno.c index 533d099b4a..fe0ea8c7c6 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_errno.c +++ b/usr/src/uts/common/fs/smbsrv/smb_errno.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2014 Nexenta Systems, Inc. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ /* @@ -47,9 +47,9 @@ struct errno2status { static const struct errno2status smb_errno2status_map[] = { { EPERM, NT_STATUS_ACCESS_DENIED }, - { ENOENT, NT_STATUS_NO_SUCH_FILE }, - /* NB: ESRCH is used to represent stream lookup failures. */ - { ESRCH, NT_STATUS_OBJECT_NAME_NOT_FOUND }, + { ENOENT, NT_STATUS_OBJECT_NAME_NOT_FOUND }, + /* NB: ESRCH is used in rename and stream ops. */ + { ESRCH, NT_STATUS_NO_SUCH_FILE }, { EINTR, NT_STATUS_CANCELLED }, { EIO, NT_STATUS_IO_DEVICE_ERROR }, { ENXIO, NT_STATUS_BAD_DEVICE_TYPE }, @@ -60,9 +60,8 @@ smb_errno2status_map[] = { { EACCES, NT_STATUS_ACCESS_DENIED }, /* EFAULT, ENOTBLK, EBUSY */ { EEXIST, NT_STATUS_OBJECT_NAME_COLLISION }, - { EXDEV, NT_STATUS_NOT_SAME_DEVICE }, + { EXDEV, NT_STATUS_NOT_SAME_DEVICE }, { ENODEV, NT_STATUS_NO_SUCH_DEVICE }, - /* ENOTDIR should be: NT_STATUS_NOT_A_DIRECTORY, but not yet */ { ENOTDIR, NT_STATUS_OBJECT_PATH_NOT_FOUND }, { EISDIR, NT_STATUS_FILE_IS_A_DIRECTORY }, { EINVAL, NT_STATUS_INVALID_PARAMETER }, @@ -81,7 +80,7 @@ smb_errno2status_map[] = { /* ENOMSG, EIDRM, ... */ { ENOTSUP, NT_STATUS_NOT_SUPPORTED }, { EDQUOT, NT_STATUS_DISK_FULL }, - { EREMOTE, NT_STATUS_PATH_NOT_COVERED}, + { EREMOTE, NT_STATUS_PATH_NOT_COVERED}, { ENAMETOOLONG, NT_STATUS_OBJECT_NAME_INVALID }, { EILSEQ, NT_STATUS_OBJECT_NAME_INVALID }, { ENOTEMPTY, NT_STATUS_DIRECTORY_NOT_EMPTY }, diff --git a/usr/src/uts/common/fs/smbsrv/smb_find.c b/usr/src/uts/common/fs/smbsrv/smb_find.c index a8774f72e2..9dc3689652 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_find.c +++ b/usr/src/uts/common/fs/smbsrv/smb_find.c @@ -300,6 +300,7 @@ smb_com_search(smb_request_t *sr) ERRDOS, ERROR_NO_MORE_FILES); return (SDRC_ERROR); } + odid = od->d_odid; } else { if (smb_mbc_decodef(&sr->smb_data, "b12.wwl", &resume_char, &index, &odid, &client_key) != 0) { @@ -455,6 +456,7 @@ smb_com_find(smb_request_t *sr) smbsr_error(sr, status, 0, 0); return (SDRC_ERROR); } + odid = od->d_odid; } else { if (smb_mbc_decodef(&sr->smb_data, "b12.wwl", &resume_char, &index, &odid, &client_key) != 0) { @@ -691,8 +693,8 @@ smb_com_find_unique(struct smb_request *sr) smb_name83(fileinfo.fi_shortname, name83, SMB_SHORTNAMELEN); (void) smb_mbc_encodef(&sr->reply, "b11c.wwlbYl13c", - resume_char, name83, index, od->d_odid, - client_key, fileinfo.fi_dosattr & 0xff, + resume_char, name83, index, od->d_odid, client_key, + fileinfo.fi_dosattr & 0xff, smb_time_gmt_to_local(sr, fileinfo.fi_mtime.tv_sec), (int32_t)fileinfo.fi_size, fileinfo.fi_shortname); diff --git a/usr/src/uts/common/fs/smbsrv/smb_fsops.c b/usr/src/uts/common/fs/smbsrv/smb_fsops.c index 819547773d..abe69a9017 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_fsops.c +++ b/usr/src/uts/common/fs/smbsrv/smb_fsops.c @@ -820,6 +820,7 @@ smb_fsop_remove_streams(smb_request_t *sr, cred_t *cr, smb_node_t *fnode) switch (status) { case 0: break; + case NT_STATUS_OBJECT_NAME_NOT_FOUND: case NT_STATUS_NO_SUCH_FILE: case NT_STATUS_NOT_SUPPORTED: /* No streams to remove. */ @@ -2541,6 +2542,15 @@ smb_fsop_eaccess(smb_request_t *sr, cred_t *cr, smb_node_t *snode, if (access & VWRITE) *eaccess |= FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | FILE_DELETE_CHILD; + + if (access & (VREAD | VWRITE)) + *eaccess |= SYNCHRONIZE; + +#ifdef _FAKE_KERNEL + /* Should be: if (we are the owner)... */ + if (access & VWRITE) + *eaccess |= DELETE | WRITE_DAC | WRITE_OWNER; +#endif } /* diff --git a/usr/src/uts/common/fs/smbsrv/smb_mangle_name.c b/usr/src/uts/common/fs/smbsrv/smb_mangle_name.c index 7555441f01..b504911f8d 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_mangle_name.c +++ b/usr/src/uts/common/fs/smbsrv/smb_mangle_name.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2013 Nexenta Systems, Inc. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ #include <sys/types.h> @@ -351,11 +351,8 @@ smb_mangle(const char *name, ino64_t fid, char *buf, size_t buflen) * 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. + * 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. @@ -368,21 +365,17 @@ int smb_unmangle(smb_node_t *dnode, char *name, char *namebuf, int buflen, uint32_t flags) { - int err, eof, bufsize, reclen; + _NOTE(ARGUNUSED(flags)) // avoid changing all callers + int err, eof, bufsize; 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 + char *bufptr; + dirent64_t *dp; + cred_t *cr = zone_kcred(); + int rc = ENOENT; if (dnode == NULL || name == NULL || namebuf == NULL || buflen == 0) return (EINVAL); @@ -394,57 +387,62 @@ smb_unmangle(smb_node_t *dnode, char *name, char *namebuf, 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; + 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; - /* skip non utf8 filename */ - if (u8_validate(namep, strlen(namep), NULL, - U8_VALIDATE_ENTIRE, &err) < 0) - continue; - - smb_mangle(namep, ino, shortname, SMB_SHORTNAMELEN); + offset = dp->d_off; + ino = dp->d_ino; + namep = dp->d_name; - if (smb_strcasecmp(name, shortname, 0) == 0) { - (void) strlcpy(namebuf, namep, buflen); - kmem_free(buf, SMB_UNMANGLE_BUFSIZE); - return (0); - } - } + /* skip non utf8 filename */ + if (u8_validate(namep, strlen(namep), NULL, + U8_VALIDATE_ENTIRE, &err) < 0) + continue; - if (eof) { - err = ENOENT; + smb_mangle(namep, ino, shortname, SMB_SHORTNAMELEN); + if (smb_strcasecmp(name, shortname, 0) == 0) { + (void) strlcpy(namebuf, namep, buflen); + rc = 0; break; } - - bufsize = SMB_UNMANGLE_BUFSIZE; } kmem_free(buf, SMB_UNMANGLE_BUFSIZE); - return (err); + return (rc); } diff --git a/usr/src/uts/common/fs/smbsrv/smb_mbuf_marshaling.c b/usr/src/uts/common/fs/smbsrv/smb_mbuf_marshaling.c index f9b629b24f..132820a147 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_mbuf_marshaling.c +++ b/usr/src/uts/common/fs/smbsrv/smb_mbuf_marshaling.c @@ -916,6 +916,23 @@ smb_mbc_put_mem(mbuf_chain_t *mbc, void *vmem, int mem_len) } /* + * Put padding sufficient to align to A, where + * A is some power of 2 greater than zero. + */ +int +smb_mbc_put_align(mbuf_chain_t *mbc, int align) +{ + int mask = align - 1; + int padsz; + + ASSERT(align > 0 && (align & mask) == 0); + if ((mbc->chain_offset & mask) == 0) + return (0); + padsz = align - (mbc->chain_offset & mask); + return (smb_mbc_encodef(mbc, "#.", padsz)); +} + +/* * Put data into mbuf chain allocating as needed. * Adds room to end of mbuf chain if needed. */ diff --git a/usr/src/uts/common/fs/smbsrv/smb_node.c b/usr/src/uts/common/fs/smbsrv/smb_node.c index 66eabe3fe2..2d16395ad3 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_node.c +++ b/usr/src/uts/common/fs/smbsrv/smb_node.c @@ -611,40 +611,47 @@ smb_node_root_init(smb_server_t *sv, smb_node_t **svrootp) * and check for anything other than "." or ".." in the readdir buf. */ static uint32_t -smb_rmdir_possible(smb_node_t *n, uint32_t flags) +smb_rmdir_possible(smb_node_t *n) { ASSERT(n->vp->v_type == VDIR); - char buf[512]; /* Only large enough to see if the dir is empty. */ - int eof, bsize = sizeof (buf), reclen = 0; - char *name; - boolean_t edp = vfs_has_feature(n->vp->v_vfsp, VFSFT_DIRENTFLAGS); - - union { - char *u_bufptr; - struct edirent *u_edp; - struct dirent64 *u_dp; - } u; -#define bufptr u.u_bufptr -#define extdp u.u_edp -#define dp u.u_dp - - if (smb_vop_readdir(n->vp, 0, buf, &bsize, &eof, flags, zone_kcred())) - return (NT_STATUS_INTERNAL_ERROR); - if (bsize == 0) - return (0); /* empty dir */ + char *buf; + char *bufptr; + struct dirent64 *dp; + uint32_t status = NT_STATUS_SUCCESS; + int bsize = SMB_ODIR_BUFSIZE; + int eof = 0; + + buf = kmem_alloc(SMB_ODIR_BUFSIZE, KM_SLEEP); + + /* Flags zero: no edirent, no ABE wanted here */ + if (smb_vop_readdir(n->vp, 0, buf, &bsize, &eof, 0, zone_kcred())) { + status = NT_STATUS_INTERNAL_ERROR; + goto out; + } + bufptr = buf; - while ((bufptr += reclen) < buf + bsize) { - if (edp) { - reclen = extdp->ed_reclen; - name = extdp->ed_name; - } else { - reclen = dp->d_reclen; - name = dp->d_name; + while (bsize > 0) { + /* LINTED pointer alignment */ + dp = (struct dirent64 *)bufptr; + + bufptr += dp->d_reclen; + bsize -= dp->d_reclen; + if (bsize < 0) { + /* partial record */ + status = NT_STATUS_DIRECTORY_NOT_EMPTY; + break; + } + + if (strcmp(dp->d_name, ".") != 0 && + strcmp(dp->d_name, "..") != 0) { + status = NT_STATUS_DIRECTORY_NOT_EMPTY; + break; } - if (strcmp(name, ".") != 0 && strcmp(name, "..") != 0) - return (NT_STATUS_DIRECTORY_NOT_EMPTY); } - return (0); + +out: + kmem_free(buf, SMB_ODIR_BUFSIZE); + return (status); } /* @@ -672,7 +679,7 @@ smb_node_set_delete_on_close(smb_node_t *node, cred_t *cr, uint32_t flags) * "File System Behavior Overview" doc section 4.3.2 */ if (smb_node_is_dir(node)) { - status = smb_rmdir_possible(node, flags); + status = smb_rmdir_possible(node); if (status != 0) { return (status); } diff --git a/usr/src/uts/common/fs/smbsrv/smb_odir.c b/usr/src/uts/common/fs/smbsrv/smb_odir.c index 55a6c38dd1..d2f56b47b0 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_odir.c +++ b/usr/src/uts/common/fs/smbsrv/smb_odir.c @@ -1059,12 +1059,17 @@ smb_odir_next_odirent(smb_odir_t *od, smb_odirent_t *odirent) dirent64_t *dp; edirent_t *edp; char *np; - uint32_t abe_flag = 0; + uint32_t rddir_flags = 0; ASSERT(MUTEX_HELD(&od->d_mutex)); bzero(odirent, sizeof (smb_odirent_t)); + if (od->d_flags & SMB_ODIR_FLAG_ABE) + rddir_flags |= SMB_ABE; + if (od->d_flags & SMB_ODIR_FLAG_EDIRENT) + rddir_flags |= SMB_EDIRENT; + if (od->d_bufptr != NULL) { if (od->d_flags & SMB_ODIR_FLAG_EDIRENT) reclen = od->d_edp->ed_reclen; @@ -1086,11 +1091,8 @@ smb_odir_next_odirent(smb_odir_t *od, smb_odirent_t *odirent) od->d_bufsize = sizeof (od->d_buf); - if (od->d_flags & SMB_ODIR_FLAG_ABE) - abe_flag = SMB_ABE; - rc = smb_vop_readdir(od->d_dnode->vp, od->d_offset, - od->d_buf, &od->d_bufsize, &eof, abe_flag, od->d_cred); + od->d_buf, &od->d_bufsize, &eof, rddir_flags, od->d_cred); if ((rc == 0) && (od->d_bufsize == 0)) rc = ENOENT; diff --git a/usr/src/uts/common/fs/smbsrv/smb_query_fileinfo.c b/usr/src/uts/common/fs/smbsrv/smb_query_fileinfo.c index 2504f524c9..cfa3ab4aca 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_query_fileinfo.c +++ b/usr/src/uts/common/fs/smbsrv/smb_query_fileinfo.c @@ -329,11 +329,7 @@ smb_query_by_path(smb_request_t *sr, smb_xa_t *xa, uint16_t infolev) } if (rc != 0) { - if (rc == ENOENT) - smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND, - ERRDOS, ERROR_FILE_NOT_FOUND); - else - smbsr_errno(sr, rc); + smbsr_errno(sr, rc); kmem_free(qinfo, sizeof (smb_queryinfo_t)); return (-1); @@ -654,9 +650,11 @@ smb_query_stream_info(smb_request_t *sr, mbuf_chain_t *mbc, switch (status) { case 0: break; + case NT_STATUS_OBJECT_NAME_NOT_FOUND: case NT_STATUS_NO_SUCH_FILE: case NT_STATUS_NOT_SUPPORTED: /* No streams. */ + status = 0; done = B_TRUE; break; default: diff --git a/usr/src/uts/common/fs/smbsrv/smb_set_fileinfo.c b/usr/src/uts/common/fs/smbsrv/smb_set_fileinfo.c index 160459ab7f..32df1912e0 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_set_fileinfo.c +++ b/usr/src/uts/common/fs/smbsrv/smb_set_fileinfo.c @@ -293,12 +293,7 @@ smb_set_by_path(smb_request_t *sr, smb_xa_t *xa, uint16_t infolev) kmem_free(name, MAXNAMELEN); if (rc != 0) { - if (rc == ENOENT) { - smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND, - ERRDOS, ERROR_FILE_NOT_FOUND); - } else { - smbsr_errno(sr, rc); - } + smbsr_errno(sr, rc); return (-1); } diff --git a/usr/src/uts/common/fs/smbsrv/smb_trans2_find.c b/usr/src/uts/common/fs/smbsrv/smb_trans2_find.c index ecb7c5c639..d7d1565b2a 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_trans2_find.c +++ b/usr/src/uts/common/fs/smbsrv/smb_trans2_find.c @@ -344,7 +344,8 @@ smb_com_trans2_find_first2(smb_request_t *sr, smb_xa_t *xa) if (count == 0) { smb_odir_close(od); smb_odir_release(od); - smbsr_errno(sr, ENOENT); + smbsr_status(sr, NT_STATUS_NO_SUCH_FILE, + ERRDOS, ERROR_FILE_NOT_FOUND); return (SDRC_ERROR); } diff --git a/usr/src/uts/common/fs/smbsrv/smb_vops.c b/usr/src/uts/common/fs/smbsrv/smb_vops.c index 7a3905d7bb..f90c2d837d 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_vops.c +++ b/usr/src/uts/common/fs/smbsrv/smb_vops.c @@ -1006,7 +1006,8 @@ smb_vop_readdir(vnode_t *vp, uint32_t offset, 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 { diff --git a/usr/src/uts/common/smbsrv/smb_fsops.h b/usr/src/uts/common/smbsrv/smb_fsops.h index f4421fe733..377dfe257a 100644 --- a/usr/src/uts/common/smbsrv/smb_fsops.h +++ b/usr/src/uts/common/smbsrv/smb_fsops.h @@ -22,7 +22,7 @@ * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * - * Copyright 2013 Nexenta Systems, Inc. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ #ifndef _SMBSRV_SMB_FSOPS_H @@ -123,6 +123,7 @@ int smb_fsop_frlock(smb_node_t *, smb_lock_t *, boolean_t, cred_t *); #define SMB_CATIA 0x00000004 #define SMB_ABE 0x00000008 #define SMB_CASE_SENSITIVE 0x00000010 +#define SMB_EDIRENT 0x00000020 /* * Increased MAXPATHLEN for SMB. Essentially, we want to allow a diff --git a/usr/src/uts/common/smbsrv/smb_kproto.h b/usr/src/uts/common/smbsrv/smb_kproto.h index 61d2b7b42e..2e5839f8b0 100644 --- a/usr/src/uts/common/smbsrv/smb_kproto.h +++ b/usr/src/uts/common/smbsrv/smb_kproto.h @@ -370,6 +370,7 @@ int smb_mbc_peek(mbuf_chain_t *, int, const char *, ...); int smb_mbc_poke(mbuf_chain_t *, int, const char *, ...); int smb_mbc_put_mem(mbuf_chain_t *, void *, int); int smb_mbc_copy(mbuf_chain_t *, const mbuf_chain_t *, int, int); +int smb_mbc_put_align(mbuf_chain_t *, int); void smbsr_encode_header(smb_request_t *sr, int wct, int bcc, const char *fmt, ...); |
