smbd: Introduce fsp_is_alternate_stream()
[gd/samba-autobuild/.git] / source3 / smbd / reply.c
index 51bf619a51b7721da4163328d5e47f1959d6f164..955ebdd7829b11639e4d9b0fa06f4ab5118ff7d3 100644 (file)
@@ -1625,38 +1625,6 @@ void reply_dskattr(struct smb_request *req)
        return;
 }
 
-/*
- * Utility function to split the filename from the directory.
- */
-static NTSTATUS split_fname_dir_mask(TALLOC_CTX *ctx, const char *fname_in,
-                                    char **fname_dir_out,
-                                    char **fname_mask_out)
-{
-       const char *p = NULL;
-       char *fname_dir = NULL;
-       char *fname_mask = NULL;
-
-       p = strrchr_m(fname_in, '/');
-       if (!p) {
-               fname_dir = talloc_strdup(ctx, ".");
-               fname_mask = talloc_strdup(ctx, fname_in);
-       } else {
-               fname_dir = talloc_strndup(ctx, fname_in,
-                   PTR_DIFF(p, fname_in));
-               fname_mask = talloc_strdup(ctx, p+1);
-       }
-
-       if (!fname_dir || !fname_mask) {
-               TALLOC_FREE(fname_dir);
-               TALLOC_FREE(fname_mask);
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       *fname_dir_out = fname_dir;
-       *fname_mask_out = fname_mask;
-       return NT_STATUS_OK;
-}
-
 /****************************************************************************
  Make a dir struct.
 ****************************************************************************/
@@ -1780,15 +1748,17 @@ void reply_search(struct smb_request *req)
        /* dirtype &= ~FILE_ATTRIBUTE_DIRECTORY; */
 
        if (status_len == 0) {
-               int ret;
+               const char *dirpath;
                struct smb_filename *smb_dname = NULL;
-               uint32_t ucf_flags = UCF_ALWAYS_ALLOW_WCARD_LCOMP |
-                       ucf_flags_from_smb_request(req);
-               nt_status = filename_convert(ctx, conn,
-                                            path,
-                                            ucf_flags,
-                                            0,
-                                            &smb_fname);
+               uint32_t ucf_flags = ucf_flags_from_smb_request(req);
+
+               nt_status = filename_convert_smb1_search_path(ctx,
+                                       conn,
+                                       path,
+                                       ucf_flags,
+                                       &smb_dname,
+                                       &mask);
+
                if (!NT_STATUS_IS_OK(nt_status)) {
                        if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) {
                                reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -1799,56 +1769,9 @@ void reply_search(struct smb_request *req)
                        goto out;
                }
 
-               directory = smb_fname->base_name;
-
-               p = strrchr_m(directory,'/');
-               if ((p != NULL) && (*directory != '/')) {
-                       mask = talloc_strdup(ctx, p + 1);
-                       directory = talloc_strndup(ctx, directory,
-                                                  PTR_DIFF(p, directory));
-               } else {
-                       mask = talloc_strdup(ctx, directory);
-                       directory = talloc_strdup(ctx,".");
-               }
-
-               if (!directory) {
-                       reply_nterror(req, NT_STATUS_NO_MEMORY);
-                       goto out;
-               }
-
                memset((char *)status,'\0',21);
                SCVAL(status,0,(dirtype & 0x1F));
 
-               smb_dname = synthetic_smb_fname(talloc_tos(),
-                                       directory,
-                                       NULL,
-                                       NULL,
-                                       smb_fname->twrp,
-                                       smb_fname->flags);
-               if (smb_dname == NULL) {
-                       reply_nterror(req, NT_STATUS_NO_MEMORY);
-                       goto out;
-               }
-
-               /*
-                * As we've cut off the last component from
-                * smb_fname we need to re-stat smb_dname
-                * so FILE_OPEN disposition knows the directory
-                * exists.
-                */
-               ret = vfs_stat(conn, smb_dname);
-               if (ret == -1) {
-                       nt_status = map_nt_error_from_unix(errno);
-                       reply_nterror(req, nt_status);
-                       goto out;
-               }
-
-               nt_status = openat_pathref_fsp(conn->cwd_fsp, smb_dname);
-               if (!NT_STATUS_IS_OK(nt_status)) {
-                       reply_nterror(req, nt_status);
-                       goto out;
-               }
-
                /*
                 * Open an fsp on this directory for the dptr.
                 */
@@ -1898,13 +1821,18 @@ void reply_search(struct smb_request *req)
                         * as this is not a client visible handle so
                         * can'tbe part of an SMB1 chain.
                         */
-                       close_file(NULL, fsp, NORMAL_CLOSE);
-                       fsp = NULL;
+                       close_file_free(NULL, &fsp, NORMAL_CLOSE);
                        reply_nterror(req, nt_status);
                        goto out;
                }
 
                dptr_num = dptr_dnum(fsp->dptr);
+               dirpath = dptr_path(sconn, dptr_num);
+               directory = talloc_strdup(ctx, dirpath);
+               if (!directory) {
+                       reply_nterror(req, NT_STATUS_NO_MEMORY);
+                       goto out;
+               }
 
        } else {
                int status_dirtype;
@@ -2024,15 +1952,13 @@ void reply_search(struct smb_request *req)
        if (numentries == 0) {
                dptr_num = -1;
                if (fsp != NULL) {
-                       close_file(NULL, fsp, NORMAL_CLOSE);
-                       fsp = NULL;
+                       close_file_free(NULL, &fsp, NORMAL_CLOSE);
                }
        } else if(expect_close && status_len == 0) {
                /* Close the dptr - we know it's gone */
                dptr_num = -1;
                if (fsp != NULL) {
-                       close_file(NULL, fsp, NORMAL_CLOSE);
-                       fsp = NULL;
+                       close_file_free(NULL, &fsp, NORMAL_CLOSE);
                }
        }
 
@@ -2041,8 +1967,7 @@ void reply_search(struct smb_request *req)
                dptr_num = -1;
                /* fsp may have been closed above. */
                if (fsp != NULL) {
-                       close_file(NULL, fsp, NORMAL_CLOSE);
-                       fsp = NULL;
+                       close_file_free(NULL, &fsp, NORMAL_CLOSE);
                }
        }
 
@@ -2144,8 +2069,7 @@ void reply_fclose(struct smb_request *req)
        fsp = dptr_fetch_fsp(sconn, status+12,&dptr_num);
        if(fsp != NULL) {
                /*  Close the file - we know it's gone */
-               close_file(NULL, fsp, NORMAL_CLOSE);
-               fsp = NULL;
+               close_file_free(NULL, &fsp, NORMAL_CLOSE);
                dptr_num = -1;
        }
 
@@ -2287,7 +2211,7 @@ void reply_open(struct smb_request *req)
        if (fattr & FILE_ATTRIBUTE_DIRECTORY) {
                DEBUG(3,("attempt to open a directory %s\n",
                         fsp_str_dbg(fsp)));
-               close_file(req, fsp, ERROR_CLOSE);
+               close_file_free(req, &fsp, ERROR_CLOSE);
                reply_botherror(req, NT_STATUS_ACCESS_DENIED,
                        ERRDOS, ERRnoaccess);
                goto out;
@@ -2472,19 +2396,19 @@ void reply_open_and_X(struct smb_request *req)
        if (((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) && allocation_size) {
                fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
                if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
-                       close_file(req, fsp, ERROR_CLOSE);
+                       close_file_free(req, &fsp, ERROR_CLOSE);
                        reply_nterror(req, NT_STATUS_DISK_FULL);
                        goto out;
                }
                retval = vfs_set_filelen(fsp, (off_t)allocation_size);
                if (retval < 0) {
-                       close_file(req, fsp, ERROR_CLOSE);
+                       close_file_free(req, &fsp, ERROR_CLOSE);
                        reply_nterror(req, NT_STATUS_DISK_FULL);
                        goto out;
                }
                status = vfs_stat_fsp(fsp);
                if (!NT_STATUS_IS_OK(status)) {
-                       close_file(req, fsp, ERROR_CLOSE);
+                       close_file_free(req, &fsp, ERROR_CLOSE);
                        reply_nterror(req, status);
                        goto out;
                }
@@ -2492,7 +2416,7 @@ void reply_open_and_X(struct smb_request *req)
 
        fattr = fdos_mode(fsp);
        if (fattr & FILE_ATTRIBUTE_DIRECTORY) {
-               close_file(req, fsp, ERROR_CLOSE);
+               close_file_free(req, &fsp, ERROR_CLOSE);
                reply_nterror(req, NT_STATUS_ACCESS_DENIED);
                goto out;
        }
@@ -3131,10 +3055,10 @@ static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp,
  * unlink a file with all relevant access checks
  *******************************************************************/
 
-static NTSTATUS do_unlink(connection_struct *conn,
+NTSTATUS unlink_internals(connection_struct *conn,
                        struct smb_request *req,
-                       struct smb_filename *smb_fname,
-                       uint32_t dirtype)
+                       uint32_t dirtype,
+                       struct smb_filename *smb_fname)
 {
        uint32_t fattr;
        files_struct *fsp;
@@ -3143,9 +3067,13 @@ static NTSTATUS do_unlink(connection_struct *conn,
        int ret;
        struct smb2_create_blobs *posx = NULL;
 
-       DEBUG(10,("do_unlink: %s, dirtype = %d\n",
+       if (dirtype == 0) {
+               dirtype = FILE_ATTRIBUTE_NORMAL;
+       }
+
+       DBG_DEBUG("%s, dirtype = %d\n",
                  smb_fname_str_dbg(smb_fname),
-                 dirtype));
+                 dirtype);
 
        if (!CAN_WRITE(conn)) {
                return NT_STATUS_MEDIA_WRITE_PROTECTED;
@@ -3245,18 +3173,18 @@ static NTSTATUS do_unlink(connection_struct *conn,
        TALLOC_FREE(posx);
 
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(10, ("SMB_VFS_CREATEFILE failed: %s\n",
-                          nt_errstr(status)));
+               DBG_DEBUG("SMB_VFS_CREATEFILE failed: %s\n",
+                          nt_errstr(status));
                return status;
        }
 
        status = can_set_delete_on_close(fsp, fattr);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(10, ("do_unlink can_set_delete_on_close for file %s - "
+               DBG_DEBUG("can_set_delete_on_close for file %s - "
                        "(%s)\n",
                        smb_fname_str_dbg(smb_fname),
-                       nt_errstr(status)));
-               close_file(req, fsp, NORMAL_CLOSE);
+                       nt_errstr(status));
+               close_file_free(req, &fsp, NORMAL_CLOSE);
                return status;
        }
 
@@ -3264,270 +3192,11 @@ static NTSTATUS do_unlink(connection_struct *conn,
        if (!set_delete_on_close(fsp, True,
                                conn->session_info->security_token,
                                conn->session_info->unix_token)) {
-               close_file(req, fsp, NORMAL_CLOSE);
+               close_file_free(req, &fsp, NORMAL_CLOSE);
                return NT_STATUS_ACCESS_DENIED;
        }
 
-       return close_file(req, fsp, NORMAL_CLOSE);
-}
-
-/****************************************************************************
- The guts of the unlink command, split out so it may be called by the NT SMB
- code.
-****************************************************************************/
-
-NTSTATUS unlink_internals(connection_struct *conn,
-                       struct smb_request *req,
-                       uint32_t dirtype,
-                       struct smb_filename *smb_fname,
-                       bool has_wild)
-{
-       char *fname_dir = NULL;
-       char *fname_mask = NULL;
-       int count=0;
-       NTSTATUS status = NT_STATUS_OK;
-       struct smb_filename *smb_fname_dir = NULL;
-       TALLOC_CTX *ctx = talloc_tos();
-       int ret;
-
-       /* Split up the directory from the filename/mask. */
-       status = split_fname_dir_mask(ctx, smb_fname->base_name,
-                                     &fname_dir, &fname_mask);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
-       /*
-        * We should only check the mangled cache
-        * here if unix_convert failed. This means
-        * that the path in 'mask' doesn't exist
-        * on the file system and so we need to look
-        * for a possible mangle. This patch from
-        * Tine Smukavec <valentin.smukavec@hermes.si>.
-        */
-
-       if (!VALID_STAT(smb_fname->st) &&
-           mangle_is_mangled(fname_mask, conn->params)) {
-               char *new_mask = NULL;
-               mangle_lookup_name_from_8_3(ctx, fname_mask,
-                                           &new_mask, conn->params);
-               if (new_mask) {
-                       TALLOC_FREE(fname_mask);
-                       fname_mask = new_mask;
-               }
-       }
-
-       if (!has_wild) {
-
-               /*
-                * Only one file needs to be unlinked. Append the mask back
-                * onto the directory.
-                */
-               TALLOC_FREE(smb_fname->base_name);
-               if (ISDOT(fname_dir)) {
-                       /* Ensure we use canonical names on open. */
-                       smb_fname->base_name = talloc_asprintf(smb_fname,
-                                                       "%s",
-                                                       fname_mask);
-               } else {
-                       smb_fname->base_name = talloc_asprintf(smb_fname,
-                                                       "%s/%s",
-                                                       fname_dir,
-                                                       fname_mask);
-               }
-               if (!smb_fname->base_name) {
-                       status = NT_STATUS_NO_MEMORY;
-                       goto out;
-               }
-               if (dirtype == 0) {
-                       dirtype = FILE_ATTRIBUTE_NORMAL;
-               }
-
-               status = check_name(conn, smb_fname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       goto out;
-               }
-
-               status = do_unlink(conn, req, smb_fname, dirtype);
-               if (!NT_STATUS_IS_OK(status)) {
-                       goto out;
-               }
-
-               count++;
-       } else {
-               struct smb_Dir *dir_hnd = NULL;
-               long offset = 0;
-               const char *dname = NULL;
-               char *talloced = NULL;
-               bool case_sensitive =
-                       (smb_fname->flags & SMB_FILENAME_POSIX_PATH) ?
-                       true : conn->case_sensitive;
-
-               if ((dirtype & SAMBA_ATTRIBUTES_MASK) == FILE_ATTRIBUTE_DIRECTORY) {
-                       status = NT_STATUS_OBJECT_NAME_INVALID;
-                       goto out;
-               }
-               if (dirtype == 0) {
-                       dirtype = FILE_ATTRIBUTE_NORMAL;
-               }
-
-               if (strequal(fname_mask,"????????.???")) {
-                       TALLOC_FREE(fname_mask);
-                       fname_mask = talloc_strdup(ctx, "*");
-                       if (!fname_mask) {
-                               status = NT_STATUS_NO_MEMORY;
-                               goto out;
-                       }
-               }
-
-               smb_fname_dir = synthetic_smb_fname(talloc_tos(),
-                                       fname_dir,
-                                       NULL,
-                                       NULL,
-                                       smb_fname->twrp,
-                                       smb_fname->flags);
-               if (smb_fname_dir == NULL) {
-                       status = NT_STATUS_NO_MEMORY;
-                       goto out;
-               }
-
-               status = check_name(conn, smb_fname_dir);
-               if (!NT_STATUS_IS_OK(status)) {
-                       goto out;
-               }
-
-               dir_hnd = OpenDir(talloc_tos(), conn, smb_fname_dir, fname_mask,
-                                 dirtype);
-               if (dir_hnd == NULL) {
-                       status = map_nt_error_from_unix(errno);
-                       goto out;
-               }
-
-               /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
-                  the pattern matches against the long name, otherwise the short name 
-                  We don't implement this yet XXXX
-               */
-
-               status = NT_STATUS_NO_SUCH_FILE;
-
-               while ((dname = ReadDirName(dir_hnd, &offset,
-                                           &smb_fname->st, &talloced))) {
-                       TALLOC_CTX *frame = talloc_stackframe();
-                       char *p = NULL;
-                       struct smb_filename *f = NULL;
-
-                       /* Quick check for "." and ".." */
-                       if (ISDOT(dname) || ISDOTDOT(dname)) {
-                               TALLOC_FREE(frame);
-                               TALLOC_FREE(talloced);
-                               continue;
-                       }
-
-                       if (IS_VETO_PATH(conn, dname)) {
-                               TALLOC_FREE(frame);
-                               TALLOC_FREE(talloced);
-                               continue;
-                       }
-
-                       if(!mask_match(dname, fname_mask,
-                                      case_sensitive)) {
-                               TALLOC_FREE(frame);
-                               TALLOC_FREE(talloced);
-                               continue;
-                       }
-
-                       if (ISDOT(fname_dir)) {
-                               /* Ensure we use canonical names on open. */
-                               p = talloc_asprintf(smb_fname, "%s", dname);
-                       } else {
-                               p = talloc_asprintf(smb_fname, "%s/%s",
-                                                   fname_dir, dname);
-                       }
-                       if (p == NULL) {
-                               TALLOC_FREE(dir_hnd);
-                               status = NT_STATUS_NO_MEMORY;
-                               TALLOC_FREE(frame);
-                               TALLOC_FREE(talloced);
-                               goto out;
-                       }
-                       f = synthetic_smb_fname(frame,
-                                               p,
-                                               NULL,
-                                               &smb_fname->st,
-                                               smb_fname->twrp,
-                                               smb_fname->flags);
-                       if (f == NULL) {
-                               TALLOC_FREE(dir_hnd);
-                               status = NT_STATUS_NO_MEMORY;
-                               TALLOC_FREE(frame);
-                               TALLOC_FREE(talloced);
-                               goto out;
-                       }
-
-                       ret = vfs_stat(conn, f);
-                       if (ret != 0) {
-                               status = map_nt_error_from_unix(errno);
-                               TALLOC_FREE(dir_hnd);
-                               TALLOC_FREE(frame);
-                               TALLOC_FREE(talloced);
-                               goto out;
-                       }
-
-                       status = openat_pathref_fsp(conn->cwd_fsp, f);
-                       if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
-                           (f->flags & SMB_FILENAME_POSIX_PATH) &&
-                           S_ISLNK(f->st.st_ex_mode))
-                       {
-                               status = NT_STATUS_OK;
-                       }
-                       if (!NT_STATUS_IS_OK(status)) {
-                               TALLOC_FREE(dir_hnd);
-                               TALLOC_FREE(frame);
-                               TALLOC_FREE(talloced);
-                               goto out;
-                       }
-
-                       if (!is_visible_fsp(f->fsp)) {
-                               TALLOC_FREE(frame);
-                               TALLOC_FREE(talloced);
-                               continue;
-                       }
-
-                       status = check_name(conn, f);
-                       if (!NT_STATUS_IS_OK(status)) {
-                               TALLOC_FREE(dir_hnd);
-                               TALLOC_FREE(frame);
-                               TALLOC_FREE(talloced);
-                               goto out;
-                       }
-
-                       status = do_unlink(conn, req, f, dirtype);
-                       if (!NT_STATUS_IS_OK(status)) {
-                               TALLOC_FREE(dir_hnd);
-                               TALLOC_FREE(frame);
-                               TALLOC_FREE(talloced);
-                               goto out;
-                       }
-
-                       count++;
-                       DBG_DEBUG("successful unlink [%s]\n",
-                                 smb_fname_str_dbg(f));
-
-                       TALLOC_FREE(frame);
-                       TALLOC_FREE(talloced);
-               }
-               TALLOC_FREE(dir_hnd);
-       }
-
-       if (count == 0 && NT_STATUS_IS_OK(status) && errno != 0) {
-               status = map_nt_error_from_unix(errno);
-       }
-
- out:
-       TALLOC_FREE(smb_fname_dir);
-       TALLOC_FREE(fname_dir);
-       TALLOC_FREE(fname_mask);
-       return status;
+       return close_file_free(req, &fsp, NORMAL_CLOSE);
 }
 
 /****************************************************************************
@@ -3541,10 +3210,8 @@ void reply_unlink(struct smb_request *req)
        struct smb_filename *smb_fname = NULL;
        uint32_t dirtype;
        NTSTATUS status;
-       uint32_t ucf_flags = UCF_ALWAYS_ALLOW_WCARD_LCOMP |
-                       ucf_flags_from_smb_request(req);
+       uint32_t ucf_flags = ucf_flags_from_smb_request(req);
        TALLOC_CTX *ctx = talloc_tos();
-       bool has_wild = false;
 
        START_PROFILE(SMBunlink);
 
@@ -3577,22 +3244,9 @@ void reply_unlink(struct smb_request *req)
                goto out;
        }
 
-       if (!req->posix_pathnames) {
-               char *lcomp = get_original_lcomp(ctx,
-                                       conn,
-                                       name,
-                                       ucf_flags);
-               if (lcomp == NULL) {
-                       reply_nterror(req, NT_STATUS_NO_MEMORY);
-                       goto out;
-               }
-               has_wild = ms_has_wild(lcomp);
-               TALLOC_FREE(lcomp);
-       }
-
        DEBUG(3,("reply_unlink : %s\n", smb_fname_str_dbg(smb_fname)));
 
-       status = unlink_internals(conn, req, dirtype, smb_fname, has_wild);
+       status = unlink_internals(conn, req, dirtype, smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (open_was_deferred(req->xconn, req->mid)) {
                        /* We have re-scheduled this call. */
@@ -3826,8 +3480,10 @@ static void send_file_readbraw(connection_struct *conn,
         * reply_readbraw has already checked the length.
         */
 
-       if ( !req_is_in_chain(req) && (nread > 0) && (fsp->base_fsp == NULL) &&
-           lp_use_sendfile(SNUM(conn), xconn->smb1.signing_state) ) {
+       if ( !req_is_in_chain(req) &&
+            (nread > 0) &&
+            !fsp_is_alternate_stream(fsp) &&
+            lp_use_sendfile(SNUM(conn), xconn->smb1.signing_state) ) {
                ssize_t sendfile_read = -1;
                char header[4];
                DATA_BLOB header_blob;
@@ -4038,9 +3694,13 @@ void reply_readbraw(struct smb_request *req)
        /* ensure we don't overrun the packet size */
        maxcount = MIN(65535,maxcount);
 
-       init_strict_lock_struct(fsp, (uint64_t)req->smbpid,
-           (uint64_t)startpos, (uint64_t)maxcount, READ_LOCK,
-           &lock);
+       init_strict_lock_struct(fsp,
+                       (uint64_t)req->smbpid,
+                       (uint64_t)startpos,
+                       (uint64_t)maxcount,
+                       READ_LOCK,
+                       lp_posix_cifsu_locktype(fsp),
+                       &lock);
 
        if (!SMB_VFS_STRICT_LOCK_CHECK(conn, fsp, &lock)) {
                reply_readbraw_error(xconn);
@@ -4135,6 +3795,7 @@ void reply_lockread(struct smb_request *req)
                .req_guid = smbd_request_guid(req, 0),
                .smblctx = req->smbpid,
                .brltype = WRITE_LOCK,
+               .lock_flav = WINDOWS_LOCK,
                .count = SVAL(req->vwv+1, 0),
                .offset = IVAL_TO_SMB_OFF_T(req->vwv+2, 0),
        };
@@ -4146,7 +3807,6 @@ void reply_lockread(struct smb_request *req)
                fsp,
                0,
                false,          /* large_offset */
-               WINDOWS_LOCK,
                1,
                lck);
        if (subreq == NULL) {
@@ -4305,9 +3965,13 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
 
        data = smb_buf(req->outbuf) + 3;
 
-       init_strict_lock_struct(fsp, (uint64_t)req->smbpid,
-           (uint64_t)startpos, (uint64_t)numtoread, READ_LOCK,
-           &lock);
+       init_strict_lock_struct(fsp,
+                       (uint64_t)req->smbpid,
+                       (uint64_t)startpos,
+                       (uint64_t)numtoread,
+                       READ_LOCK,
+                       lp_posix_cifsu_locktype(fsp),
+                       &lock);
 
        if (!SMB_VFS_STRICT_LOCK_CHECK(conn, fsp, &lock)) {
                reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
@@ -4382,9 +4046,13 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
        int saved_errno = 0;
        NTSTATUS status;
 
-       init_strict_lock_struct(fsp, (uint64_t)req->smbpid,
-           (uint64_t)startpos, (uint64_t)smb_maxcnt, READ_LOCK,
-           &lock);
+       init_strict_lock_struct(fsp,
+                       (uint64_t)req->smbpid,
+                       (uint64_t)startpos,
+                       (uint64_t)smb_maxcnt,
+                       READ_LOCK,
+                       lp_posix_cifsu_locktype(fsp),
+                       &lock);
 
        if (!SMB_VFS_STRICT_LOCK_CHECK(conn, fsp, &lock)) {
                reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
@@ -4399,7 +4067,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
 
        if (!req_is_in_chain(req) &&
            !req->encrypted &&
-           (fsp->base_fsp == NULL) &&
+           !fsp_is_alternate_stream(fsp) &&
            lp_use_sendfile(SNUM(conn), xconn->smb1.signing_state) ) {
                uint8_t headerbuf[smb_size + 12 * 2 + 1 /* padding byte */];
                DATA_BLOB header;
@@ -4622,7 +4290,7 @@ static size_t calc_max_read_pdu(const struct smb_request *req)
                return 0x1FFFF;
        }
 
-       if (!lp_unix_extensions()) {
+       if (!lp_smb1_unix_extensions()) {
                return 0x1FFFF;
        }
 
@@ -4905,9 +4573,13 @@ void reply_writebraw(struct smb_request *req)
        }
 
        if (!fsp->print_file) {
-               init_strict_lock_struct(fsp, (uint64_t)req->smbpid,
-                   (uint64_t)startpos, (uint64_t)tcount, WRITE_LOCK,
-                   &lock);
+               init_strict_lock_struct(fsp,
+                               (uint64_t)req->smbpid,
+                               (uint64_t)startpos,
+                               (uint64_t)tcount,
+                               WRITE_LOCK,
+                               lp_posix_cifsu_locktype(fsp),
+                               &lock);
 
                if (!SMB_VFS_STRICT_LOCK_CHECK(conn, fsp, &lock)) {
                        reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
@@ -5120,9 +4792,13 @@ void reply_writeunlock(struct smb_request *req)
        }
 
        if (!fsp->print_file && numtowrite > 0) {
-               init_strict_lock_struct(fsp, (uint64_t)req->smbpid,
-                   (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
-                   &lock);
+               init_strict_lock_struct(fsp,
+                               (uint64_t)req->smbpid,
+                               (uint64_t)startpos,
+                               (uint64_t)numtowrite,
+                               WRITE_LOCK,
+                               lp_posix_cifsu_locktype(fsp),
+                               &lock);
 
                if (!SMB_VFS_STRICT_LOCK_CHECK(conn, fsp, &lock)) {
                        reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
@@ -5164,10 +4840,11 @@ void reply_writeunlock(struct smb_request *req)
                        .req_guid = smbd_request_guid(req, 0),
                        .smblctx = req->smbpid,
                        .brltype = UNLOCK_LOCK,
+                       .lock_flav = WINDOWS_LOCK,
                        .offset = startpos,
                        .count = numtowrite,
                };
-               status = smbd_do_unlocking(req, fsp, 1, &l, WINDOWS_LOCK);
+               status = smbd_do_unlocking(req, fsp, 1, &l);
                if (NT_STATUS_V(status)) {
                        reply_nterror(req, status);
                        goto out;
@@ -5250,9 +4927,13 @@ void reply_write(struct smb_request *req)
        }
 
        if (!fsp->print_file) {
-               init_strict_lock_struct(fsp, (uint64_t)req->smbpid,
-                       (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
-                       &lock);
+               init_strict_lock_struct(fsp,
+                               (uint64_t)req->smbpid,
+                               (uint64_t)startpos,
+                               (uint64_t)numtowrite,
+                               WRITE_LOCK,
+                               lp_posix_cifsu_locktype(fsp),
+                               &lock);
 
                if (!SMB_VFS_STRICT_LOCK_CHECK(conn, fsp, &lock)) {
                        reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
@@ -5383,7 +5064,7 @@ bool is_valid_writeX_buffer(struct smbXsrv_connection *xconn,
                DEBUG(10,("is_valid_writeX_buffer: printing tid\n"));
                return false;
        }
-       if (fsp->base_fsp != NULL) {
+       if (fsp_is_alternate_stream(fsp)) {
                DEBUG(10,("is_valid_writeX_buffer: stream fsp\n"));
                return false;
        }
@@ -5546,9 +5227,13 @@ void reply_write_and_X(struct smb_request *req)
                        /* NT_STATUS_RETRY - fall through to sync write. */
                }
 
-               init_strict_lock_struct(fsp, (uint64_t)req->smbpid,
-                   (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
-                   &lock);
+               init_strict_lock_struct(fsp,
+                               (uint64_t)req->smbpid,
+                               (uint64_t)startpos,
+                               (uint64_t)numtowrite,
+                               WRITE_LOCK,
+                               lp_posix_cifsu_locktype(fsp),
+                               &lock);
 
                if (!SMB_VFS_STRICT_LOCK_CHECK(conn, fsp, &lock)) {
                        reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
@@ -5973,7 +5658,7 @@ static void reply_exit_done(struct tevent_req *req)
                        smb_request_done(smb1req);
                        END_PROFILE(SMBexit);
                }
-               close_file(NULL, fsp, SHUTDOWN_CLOSE);
+               close_file_free(NULL, &fsp, SHUTDOWN_CLOSE);
        }
 
        reply_outbuf(smb1req, 0, 0);
@@ -6049,12 +5734,12 @@ void reply_close(struct smb_request *smb1req)
        }
 
        /*
-        * close_file() returns the unix errno if an error was detected on
+        * close_file_free() returns the unix errno if an error was detected on
         * close - normally this is due to a disk full error. If not then it
         * was probably an I/O error.
         */
 
-       status = close_file(smb1req, fsp, NORMAL_CLOSE);
+       status = close_file_free(smb1req, &fsp, NORMAL_CLOSE);
 done:
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(smb1req, status);
@@ -6180,7 +5865,7 @@ static void reply_close_done(struct tevent_req *req)
                return;
        }
 
-       status = close_file(smb1req, state->fsp, NORMAL_CLOSE);
+       status = close_file_free(smb1req, &state->fsp, NORMAL_CLOSE);
        if (NT_STATUS_IS_OK(status)) {
                reply_outbuf(smb1req, 0, 0);
        } else {
@@ -6248,9 +5933,13 @@ void reply_writeclose(struct smb_request *req)
        }
 
        if (fsp->print_file == NULL) {
-               init_strict_lock_struct(fsp, (uint64_t)req->smbpid,
-                   (uint64_t)startpos, (uint64_t)numtowrite, WRITE_LOCK,
-                   &lock);
+               init_strict_lock_struct(fsp,
+                               (uint64_t)req->smbpid,
+                               (uint64_t)startpos,
+                               (uint64_t)numtowrite,
+                               WRITE_LOCK,
+                               lp_posix_cifsu_locktype(fsp),
+                               &lock);
 
                if (!SMB_VFS_STRICT_LOCK_CHECK(conn, fsp, &lock)) {
                        reply_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
@@ -6275,8 +5964,7 @@ void reply_writeclose(struct smb_request *req)
        if (numtowrite) {
                DEBUG(3,("reply_writeclose: zero length write doesn't close "
                         "file %s\n", fsp_str_dbg(fsp)));
-               close_status = close_file(req, fsp, NORMAL_CLOSE);
-               fsp = NULL;
+               close_status = close_file_free(req, &fsp, NORMAL_CLOSE);
        }
 
        if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
@@ -6341,6 +6029,7 @@ void reply_lock(struct smb_request *req)
                .req_guid = smbd_request_guid(req, 0),
                .smblctx = req->smbpid,
                .brltype = WRITE_LOCK,
+               .lock_flav = WINDOWS_LOCK,
                .count = IVAL(req->vwv+1, 0),
                .offset = IVAL(req->vwv+3, 0),
        };
@@ -6358,7 +6047,6 @@ void reply_lock(struct smb_request *req)
                fsp,
                0,
                false,          /* large_offset */
-               WINDOWS_LOCK,
                1,
                lck);
        if (subreq == NULL) {
@@ -6433,11 +6121,12 @@ void reply_unlock(struct smb_request *req)
                .req_guid = smbd_request_guid(req, 0),
                .smblctx = req->smbpid,
                .brltype = UNLOCK_LOCK,
+               .lock_flav = WINDOWS_LOCK,
                .offset = IVAL(req->vwv+3, 0),
                .count = IVAL(req->vwv+1, 0),
        };
 
-       status = smbd_do_unlocking(req, fsp, 1, &lck, WINDOWS_LOCK);
+       status = smbd_do_unlocking(req, fsp, 1, &lck);
 
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
@@ -6823,7 +6512,7 @@ void reply_printclose(struct smb_request *req)
        DEBUG(3,("printclose fd=%d %s\n",
                 fsp_get_io_fd(fsp), fsp_fnum_dbg(fsp)));
 
-       status = close_file(req, fsp, NORMAL_CLOSE);
+       status = close_file_free(req, &fsp, NORMAL_CLOSE);
 
        if(!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
@@ -7226,7 +6915,7 @@ void reply_rmdir(struct smb_request *req)
 
        status = can_set_delete_on_close(fsp, FILE_ATTRIBUTE_DIRECTORY);
        if (!NT_STATUS_IS_OK(status)) {
-               close_file(req, fsp, ERROR_CLOSE);
+               close_file_free(req, &fsp, ERROR_CLOSE);
                reply_nterror(req, status);
                goto out;
        }
@@ -7234,12 +6923,12 @@ void reply_rmdir(struct smb_request *req)
        if (!set_delete_on_close(fsp, true,
                        conn->session_info->security_token,
                        conn->session_info->unix_token)) {
-               close_file(req, fsp, ERROR_CLOSE);
+               close_file_free(req, &fsp, ERROR_CLOSE);
                reply_nterror(req, NT_STATUS_ACCESS_DENIED);
                goto out;
        }
 
-       status = close_file(req, fsp, NORMAL_CLOSE);
+       status = close_file_free(req, &fsp, NORMAL_CLOSE);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
        } else {
@@ -7253,133 +6942,6 @@ void reply_rmdir(struct smb_request *req)
        return;
 }
 
-/*******************************************************************
- Resolve wildcards in a filename rename.
-********************************************************************/
-
-static bool resolve_wildcards(TALLOC_CTX *ctx,
-                               const char *name1,
-                               const char *name2,
-                               char **pp_newname)
-{
-       char *name2_copy = NULL;
-       char *root1 = NULL;
-       char *root2 = NULL;
-       char *ext1 = NULL;
-       char *ext2 = NULL;
-       char *p,*p2, *pname1, *pname2;
-
-       name2_copy = talloc_strdup(ctx, name2);
-       if (!name2_copy) {
-               return False;
-       }
-
-       pname1 = strrchr_m(name1,'/');
-       pname2 = strrchr_m(name2_copy,'/');
-
-       if (!pname1 || !pname2) {
-               return False;
-       }
-
-       /* Truncate the copy of name2 at the last '/' */
-       *pname2 = '\0';
-
-       /* Now go past the '/' */
-       pname1++;
-       pname2++;
-
-       root1 = talloc_strdup(ctx, pname1);
-       root2 = talloc_strdup(ctx, pname2);
-
-       if (!root1 || !root2) {
-               return False;
-       }
-
-       p = strrchr_m(root1,'.');
-       if (p) {
-               *p = 0;
-               ext1 = talloc_strdup(ctx, p+1);
-       } else {
-               ext1 = talloc_strdup(ctx, "");
-       }
-       p = strrchr_m(root2,'.');
-       if (p) {
-               *p = 0;
-               ext2 = talloc_strdup(ctx, p+1);
-       } else {
-               ext2 = talloc_strdup(ctx, "");
-       }
-
-       if (!ext1 || !ext2) {
-               return False;
-       }
-
-       p = root1;
-       p2 = root2;
-       while (*p2) {
-               if (*p2 == '?') {
-                       /* Hmmm. Should this be mb-aware ? */
-                       *p2 = *p;
-                       p2++;
-               } else if (*p2 == '*') {
-                       *p2 = '\0';
-                       root2 = talloc_asprintf(ctx, "%s%s",
-                                               root2,
-                                               p);
-                       if (!root2) {
-                               return False;
-                       }
-                       break;
-               } else {
-                       p2++;
-               }
-               if (*p) {
-                       p++;
-               }
-       }
-
-       p = ext1;
-       p2 = ext2;
-       while (*p2) {
-               if (*p2 == '?') {
-                       /* Hmmm. Should this be mb-aware ? */
-                       *p2 = *p;
-                       p2++;
-               } else if (*p2 == '*') {
-                       *p2 = '\0';
-                       ext2 = talloc_asprintf(ctx, "%s%s",
-                                               ext2,
-                                               p);
-                       if (!ext2) {
-                               return False;
-                       }
-                       break;
-               } else {
-                       p2++;
-               }
-               if (*p) {
-                       p++;
-               }
-       }
-
-       if (*ext2) {
-               *pp_newname = talloc_asprintf(ctx, "%s/%s.%s",
-                               name2_copy,
-                               root2,
-                               ext2);
-       } else {
-               *pp_newname = talloc_asprintf(ctx, "%s/%s",
-                               name2_copy,
-                               root2);
-       }
-
-       if (!*pp_newname) {
-               return False;
-       }
-
-       return True;
-}
-
 /****************************************************************************
  Ensure open files have their names updated. Updated to notify other smbd's
  asynchronously.
@@ -7540,7 +7102,7 @@ static NTSTATUS parent_dirname_compatible_open(connection_struct *conn,
                return status;
        }
 
-       ret = SMB_VFS_LSTAT(conn, smb_fname_parent);
+       ret = vfs_stat(conn, smb_fname_parent);
        if (ret == -1) {
                return map_nt_error_from_unix(errno);
        }
@@ -7587,11 +7149,6 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
        bool case_preserve = (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) ?
                                true : conn->case_preserve;
 
-       status = check_name(conn, smb_fname_dst_in);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
        status = parent_dirname_compatible_open(conn, smb_fname_dst_in);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -7744,7 +7301,7 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
                goto out;
        }
 
-       dst_exists = SMB_VFS_STAT(conn, smb_fname_dst) == 0;
+       dst_exists = vfs_stat(conn, smb_fname_dst) == 0;
 
        if(!replace_if_exists && dst_exists) {
                DEBUG(3, ("rename_internals_fsp: dest exists doing rename "
@@ -8019,171 +7576,72 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
                        connection_struct *conn,
                        struct smb_request *req,
                        struct smb_filename *smb_fname_src,
-                       const char *src_original_lcomp,
                        struct smb_filename *smb_fname_dst,
                        const char *dst_original_lcomp,
                        uint32_t attrs,
                        bool replace_if_exists,
                        uint32_t access_mask)
 {
-       char *fname_src_dir = NULL;
-       struct smb_filename *smb_fname_src_dir = NULL;
-       char *fname_src_mask = NULL;
-       int count=0;
        NTSTATUS status = NT_STATUS_OK;
-       struct smb_Dir *dir_hnd = NULL;
-       const char *dname = NULL;
-       char *talloced = NULL;
-       long offset = 0;
        int create_options = 0;
        struct smb2_create_blobs *posx = NULL;
        int rc;
-       bool src_has_wild = false;
-       bool dest_has_wild = false;
+       struct files_struct *fsp = NULL;
        bool posix_pathname = (smb_fname_src->flags & SMB_FILENAME_POSIX_PATH);
+       bool case_sensitive = posix_pathname ? true : conn->case_sensitive;
+       bool case_preserve = posix_pathname ? true : conn->case_preserve;
+       bool short_case_preserve = posix_pathname ? true :
+                                       conn->short_case_preserve;
 
-       /*
-        * Split the old name into directory and last component
-        * strings. Note that unix_convert may have stripped off a
-        * leading ./ from both name and newname if the rename is
-        * at the root of the share. We need to make sure either both
-        * name and newname contain a / character or neither of them do
-        * as this is checked in resolve_wildcards().
-        */
+       if (posix_pathname) {
+               status = make_smb2_posix_create_ctx(talloc_tos(), &posx, 0777);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DBG_WARNING("make_smb2_posix_create_ctx failed: %s\n",
+                                   nt_errstr(status));
+                       goto out;
+               }
+       }
 
-       /* Split up the directory from the filename/mask. */
-       status = split_fname_dir_mask(ctx, smb_fname_src->base_name,
-                                     &fname_src_dir, &fname_src_mask);
-       if (!NT_STATUS_IS_OK(status)) {
-               status = NT_STATUS_NO_MEMORY;
+       DBG_NOTICE("case_sensitive = %d, "
+                 "case_preserve = %d, short case preserve = %d, "
+                 "directory = %s, newname = %s, "
+                 "last_component_dest = %s\n",
+                 case_sensitive, case_preserve,
+                 short_case_preserve,
+                 smb_fname_str_dbg(smb_fname_src),
+                 smb_fname_str_dbg(smb_fname_dst),
+                 dst_original_lcomp);
+
+       ZERO_STRUCT(smb_fname_src->st);
+
+       rc = vfs_stat(conn, smb_fname_src);
+       if (rc == -1) {
+               status = map_nt_error_from_unix_common(errno);
                goto out;
        }
 
-       if (!(smb_fname_src->flags & SMB_FILENAME_POSIX_PATH)) {
-               /*
-                * Check the wildcard mask *before*
-                * unmangling. As mangling is done
-                * for names that can't be returned
-                * to Windows the unmangled name may
-                * contain Windows wildcard characters.
-                */
-               if (src_original_lcomp != NULL) {
-                       src_has_wild = ms_has_wild(src_original_lcomp);
-               }
-               dest_has_wild = ms_has_wild(dst_original_lcomp);
-       }
-
-       /*
-        * We should only check the mangled cache
-        * here if unix_convert failed. This means
-        * that the path in 'mask' doesn't exist
-        * on the file system and so we need to look
-        * for a possible mangle. This patch from
-        * Tine Smukavec <valentin.smukavec@hermes.si>.
-        */
-
-       if (!VALID_STAT(smb_fname_src->st) &&
-           mangle_is_mangled(fname_src_mask, conn->params)) {
-               char *new_mask = NULL;
-               mangle_lookup_name_from_8_3(ctx, fname_src_mask, &new_mask,
-                                           conn->params);
-               if (new_mask) {
-                       TALLOC_FREE(fname_src_mask);
-                       fname_src_mask = new_mask;
-               }
-       }
-
-       if (posix_pathname) {
-               status = make_smb2_posix_create_ctx(talloc_tos(), &posx, 0777);
-               if (!NT_STATUS_IS_OK(status)) {
-                       DBG_WARNING("make_smb2_posix_create_ctx failed: %s\n",
-                                   nt_errstr(status));
+       status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_src);
+       if (!NT_STATUS_IS_OK(status)) {
+               if (!NT_STATUS_EQUAL(status,
+                               NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
                        goto out;
                }
-       }
-
-       if (!src_has_wild) {
-               files_struct *fsp;
-
                /*
-                * Only one file needs to be renamed. Append the mask back
-                * onto the directory.
+                * Possible symlink src.
                 */
-               TALLOC_FREE(smb_fname_src->base_name);
-               if (ISDOT(fname_src_dir)) {
-                       /* Ensure we use canonical names on open. */
-                       smb_fname_src->base_name = talloc_asprintf(smb_fname_src,
-                                                       "%s",
-                                                       fname_src_mask);
-               } else {
-                       smb_fname_src->base_name = talloc_asprintf(smb_fname_src,
-                                                       "%s/%s",
-                                                       fname_src_dir,
-                                                       fname_src_mask);
-               }
-               if (!smb_fname_src->base_name) {
-                       status = NT_STATUS_NO_MEMORY;
+               if (!(smb_fname_src->flags & SMB_FILENAME_POSIX_PATH)) {
                        goto out;
                }
-
-               DEBUG(3, ("rename_internals: case_sensitive = %d, "
-                         "case_preserve = %d, short case preserve = %d, "
-                         "directory = %s, newname = %s, "
-                         "last_component_dest = %s\n",
-                         conn->case_sensitive, conn->case_preserve,
-                         conn->short_case_preserve,
-                         smb_fname_str_dbg(smb_fname_src),
-                         smb_fname_str_dbg(smb_fname_dst),
-                         dst_original_lcomp));
-
-               /* The dest name still may have wildcards. */
-               if (dest_has_wild) {
-                       char *fname_dst_mod = NULL;
-                       if (!resolve_wildcards(smb_fname_dst,
-                                              smb_fname_src->base_name,
-                                              smb_fname_dst->base_name,
-                                              &fname_dst_mod)) {
-                               DEBUG(6, ("rename_internals: resolve_wildcards "
-                                         "%s %s failed\n",
-                                         smb_fname_src->base_name,
-                                         smb_fname_dst->base_name));
-                               status = NT_STATUS_NO_MEMORY;
-                               goto out;
-                       }
-                       TALLOC_FREE(smb_fname_dst->base_name);
-                       smb_fname_dst->base_name = fname_dst_mod;
-               }
-
-               ZERO_STRUCT(smb_fname_src->st);
-
-               rc = vfs_stat(conn, smb_fname_src);
-               if (rc == -1) {
-                       status = map_nt_error_from_unix_common(errno);
+               if (!S_ISLNK(smb_fname_src->st.st_ex_mode)) {
                        goto out;
                }
+       }
 
-               status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_src);
-               if (!NT_STATUS_IS_OK(status)) {
-                       if (!NT_STATUS_EQUAL(status,
-                                       NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
-                               goto out;
-                       }
-                       /*
-                        * Possible symlink src.
-                        */
-                       if (!(smb_fname_src->flags & SMB_FILENAME_POSIX_PATH)) {
-                               goto out;
-                       }
-                       if (!S_ISLNK(smb_fname_src->st.st_ex_mode)) {
-                               goto out;
-                       }
-               }
-
-               if (S_ISDIR(smb_fname_src->st.st_ex_mode)) {
-                       create_options |= FILE_DIRECTORY_FILE;
-               }
+       if (S_ISDIR(smb_fname_src->st.st_ex_mode)) {
+               create_options |= FILE_DIRECTORY_FILE;
+       }
 
-               status = SMB_VFS_CREATE_FILE(
+       status = SMB_VFS_CREATE_FILE(
                        conn,                           /* conn */
                        req,                            /* req */
                        smb_fname_src,                  /* fname */
@@ -8204,223 +7662,28 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
                        posx,                           /* in_context_blobs */
                        NULL);                          /* out_context_blobs */
 
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(3, ("Could not open rename source %s: %s\n",
-                                 smb_fname_str_dbg(smb_fname_src),
-                                 nt_errstr(status)));
-                       goto out;
-               }
-
-               status = rename_internals_fsp(conn,
-                                       fsp,
-                                       smb_fname_dst,
-                                       dst_original_lcomp,
-                                       attrs,
-                                       replace_if_exists);
-
-               close_file(req, fsp, NORMAL_CLOSE);
-
-               DEBUG(3, ("rename_internals: Error %s rename %s -> %s\n",
-                         nt_errstr(status), smb_fname_str_dbg(smb_fname_src),
-                         smb_fname_str_dbg(smb_fname_dst)));
-
-               goto out;
-       }
-
-       /*
-        * Wildcards - process each file that matches.
-        */
-       if (strequal(fname_src_mask, "????????.???")) {
-               TALLOC_FREE(fname_src_mask);
-               fname_src_mask = talloc_strdup(ctx, "*");
-               if (!fname_src_mask) {
-                       status = NT_STATUS_NO_MEMORY;
-                       goto out;
-               }
-       }
-
-       smb_fname_src_dir = synthetic_smb_fname(talloc_tos(),
-                               fname_src_dir,
-                               NULL,
-                               NULL,
-                               smb_fname_src->twrp,
-                               smb_fname_src->flags);
-       if (smb_fname_src_dir == NULL) {
-               status = NT_STATUS_NO_MEMORY;
-               goto out;
-       }
-
-       status = check_name(conn, smb_fname_src_dir);
        if (!NT_STATUS_IS_OK(status)) {
+               DBG_NOTICE("Could not open rename source %s: %s\n",
+                         smb_fname_str_dbg(smb_fname_src),
+                         nt_errstr(status));
                goto out;
        }
 
-       dir_hnd = OpenDir(talloc_tos(), conn, smb_fname_src_dir, fname_src_mask,
-                         attrs);
-       if (dir_hnd == NULL) {
-               status = map_nt_error_from_unix(errno);
-               goto out;
-       }
-
-       status = NT_STATUS_NO_SUCH_FILE;
-       /*
-        * Was status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
-        * - gentest fix. JRA
-        */
-
-       while ((dname = ReadDirName(dir_hnd, &offset, &smb_fname_src->st,
-                                   &talloced))) {
-               files_struct *fsp = NULL;
-               char *destname = NULL;
-               bool sysdir_entry = False;
-
-               /* Quick check for "." and ".." */
-               if (ISDOT(dname) || ISDOTDOT(dname)) {
-                       if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
-                               sysdir_entry = True;
-                       } else {
-                               TALLOC_FREE(talloced);
-                               continue;
-                       }
-               }
-
-               if(!mask_match(dname, fname_src_mask, conn->case_sensitive)) {
-                       TALLOC_FREE(talloced);
-                       continue;
-               }
-
-               if (sysdir_entry) {
-                       status = NT_STATUS_OBJECT_NAME_INVALID;
-                       break;
-               }
-
-               TALLOC_FREE(smb_fname_src->base_name);
-               if (ISDOT(fname_src_dir)) {
-                       /* Ensure we use canonical names on open. */
-                       smb_fname_src->base_name = talloc_asprintf(smb_fname_src,
-                                                       "%s",
-                                                       dname);
-               } else {
-                       smb_fname_src->base_name = talloc_asprintf(smb_fname_src,
-                                                       "%s/%s",
-                                                       fname_src_dir,
-                                                       dname);
-               }
-               if (!smb_fname_src->base_name) {
-                       status = NT_STATUS_NO_MEMORY;
-                       goto out;
-               }
-
-               if (!resolve_wildcards(ctx, smb_fname_src->base_name,
-                                      smb_fname_dst->base_name,
-                                      &destname)) {
-                       DEBUG(6, ("resolve_wildcards %s %s failed\n",
-                                 smb_fname_src->base_name, destname));
-                       TALLOC_FREE(talloced);
-                       continue;
-               }
-               if (!destname) {
-                       status = NT_STATUS_NO_MEMORY;
-                       goto out;
-               }
-
-               TALLOC_FREE(smb_fname_dst->base_name);
-               smb_fname_dst->base_name = destname;
-
-               ZERO_STRUCT(smb_fname_src->st);
-               vfs_stat(conn, smb_fname_src);
-
-               status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_src);
-               if (!NT_STATUS_IS_OK(status)) {
-                       DBG_INFO("openat_pathref_fsp [%s] failed: %s\n",
-                                smb_fname_str_dbg(smb_fname_src),
-                                nt_errstr(status));
-                       break;
-               }
-
-               if (!is_visible_fsp(smb_fname_src->fsp)) {
-                       TALLOC_FREE(talloced);
-                       continue;
-               }
-
-               create_options = 0;
-
-               if (S_ISDIR(smb_fname_src->st.st_ex_mode)) {
-                       create_options |= FILE_DIRECTORY_FILE;
-               }
-
-               status = SMB_VFS_CREATE_FILE(
-                       conn,                           /* conn */
-                       req,                            /* req */
-                       smb_fname_src,                  /* fname */
-                       access_mask,                    /* access_mask */
-                       (FILE_SHARE_READ |              /* share_access */
-                           FILE_SHARE_WRITE),
-                       FILE_OPEN,                      /* create_disposition*/
-                       create_options,                 /* create_options */
-                       0,                              /* file_attributes */
-                       0,                              /* oplock_request */
-                       NULL,                           /* lease */
-                       0,                              /* allocation_size */
-                       0,                              /* private_flags */
-                       NULL,                           /* sd */
-                       NULL,                           /* ea_list */
-                       &fsp,                           /* result */
-                       NULL,                           /* pinfo */
-                       posx,                           /* in_context_blobs */
-                       NULL);                          /* out_context_blobs */
-
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(3,("rename_internals: SMB_VFS_CREATE_FILE "
-                                "returned %s rename %s -> %s\n",
-                                nt_errstr(status),
-                                smb_fname_str_dbg(smb_fname_src),
-                                smb_fname_str_dbg(smb_fname_dst)));
-                       break;
-               }
-
-               dst_original_lcomp = talloc_strdup(smb_fname_dst, dname);
-               if (dst_original_lcomp == NULL) {
-                       status = NT_STATUS_NO_MEMORY;
-                       goto out;
-               }
-
-               status = rename_internals_fsp(conn,
+       status = rename_internals_fsp(conn,
                                        fsp,
                                        smb_fname_dst,
                                        dst_original_lcomp,
                                        attrs,
                                        replace_if_exists);
 
-               close_file(req, fsp, NORMAL_CLOSE);
-
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(3, ("rename_internals_fsp returned %s for "
-                                 "rename %s -> %s\n", nt_errstr(status),
-                                 smb_fname_str_dbg(smb_fname_src),
-                                 smb_fname_str_dbg(smb_fname_dst)));
-                       break;
-               }
+       close_file_free(req, &fsp, NORMAL_CLOSE);
 
-               count++;
-
-               DEBUG(3,("rename_internals: doing rename on %s -> "
-                        "%s\n", smb_fname_str_dbg(smb_fname_src),
-                        smb_fname_str_dbg(smb_fname_src)));
-               TALLOC_FREE(talloced);
-       }
-       TALLOC_FREE(dir_hnd);
-
-       if (count == 0 && NT_STATUS_IS_OK(status) && errno != 0) {
-               status = map_nt_error_from_unix(errno);
-       }
+       DBG_NOTICE("Error %s rename %s -> %s\n",
+                 nt_errstr(status), smb_fname_str_dbg(smb_fname_src),
+                 smb_fname_str_dbg(smb_fname_dst));
 
  out:
        TALLOC_FREE(posx);
-       TALLOC_FREE(talloced);
-       TALLOC_FREE(smb_fname_src_dir);
-       TALLOC_FREE(fname_src_dir);
-       TALLOC_FREE(fname_src_mask);
        return status;
 }
 
@@ -8438,13 +7701,10 @@ void reply_mv(struct smb_request *req)
        NTSTATUS status;
        TALLOC_CTX *ctx = talloc_tos();
        struct smb_filename *smb_fname_src = NULL;
-       const char *src_original_lcomp = NULL;
        struct smb_filename *smb_fname_dst = NULL;
        const char *dst_original_lcomp = NULL;
-       uint32_t src_ucf_flags = ucf_flags_from_smb_request(req) |
-               (!req->posix_pathnames ? UCF_ALWAYS_ALLOW_WCARD_LCOMP : 0);
-       uint32_t dst_ucf_flags = ucf_flags_from_smb_request(req) |
-               (!req->posix_pathnames ? UCF_ALWAYS_ALLOW_WCARD_LCOMP : 0);
+       uint32_t src_ucf_flags = ucf_flags_from_smb_request(req);
+       uint32_t dst_ucf_flags = ucf_flags_from_smb_request(req);
        bool stream_rename = false;
 
        START_PROFILE(SMBmv);
@@ -8500,16 +7760,6 @@ void reply_mv(struct smb_request *req)
                goto out;
        }
 
-       /* Get the last component of the source for rename_internals(). */
-       src_original_lcomp = get_original_lcomp(ctx,
-                                       conn,
-                                       name,
-                                       dst_ucf_flags);
-       if (src_original_lcomp == NULL) {
-               reply_nterror(req, NT_STATUS_NO_MEMORY);
-               goto out;
-       }
-
        status = filename_convert(ctx,
                                  conn,
                                  newname,
@@ -8556,7 +7806,6 @@ void reply_mv(struct smb_request *req)
                                conn,
                                req,
                                smb_fname_src,
-                               src_original_lcomp,
                                smb_fname_dst,
                                dst_original_lcomp,
                                attrs,
@@ -8721,7 +7970,7 @@ NTSTATUS copy_file(TALLOC_CTX *ctx,
                NULL, NULL);                            /* create context */
 
        if (!NT_STATUS_IS_OK(status)) {
-               close_file(NULL, fsp1, ERROR_CLOSE);
+               close_file_free(NULL, &fsp1, ERROR_CLOSE);
                goto out;
        }
 
@@ -8731,8 +7980,8 @@ NTSTATUS copy_file(TALLOC_CTX *ctx,
                        DEBUG(0, ("error - vfs lseek returned error %s\n",
                                strerror(errno)));
                        status = map_nt_error_from_unix(errno);
-                       close_file(NULL, fsp1, ERROR_CLOSE);
-                       close_file(NULL, fsp2, ERROR_CLOSE);
+                       close_file_free(NULL, &fsp1, ERROR_CLOSE);
+                       close_file_free(NULL, &fsp2, ERROR_CLOSE);
                        goto out;
                }
        }
@@ -8744,7 +7993,7 @@ NTSTATUS copy_file(TALLOC_CTX *ctx,
                ret = 0;
        }
 
-       close_file(NULL, fsp1, NORMAL_CLOSE);
+       close_file_free(NULL, &fsp1, NORMAL_CLOSE);
 
        /* Ensure the modtime is set correctly on the destination file. */
        set_close_write_time(fsp2, smb_fname_src->st.st_ex_mtime);
@@ -8755,7 +8004,7 @@ NTSTATUS copy_file(TALLOC_CTX *ctx,
         * Thus we don't look at the error return from the
         * close of fsp1.
         */
-       status = close_file(NULL, fsp2, NORMAL_CLOSE);
+       status = close_file_free(NULL, &fsp2, NORMAL_CLOSE);
 
        if (!NT_STATUS_IS_OK(status)) {
                goto out;
@@ -8775,416 +8024,22 @@ NTSTATUS copy_file(TALLOC_CTX *ctx,
 
 /****************************************************************************
  Reply to a file copy.
+
+ From MS-CIFS.
+
+ This command was introduced in the LAN Manager 1.0 dialect
+ It was rendered obsolete in the NT LAN Manager dialect.
+ This command was used to perform server-side file copies, but
+ is no longer used. Clients SHOULD
+ NOT send requests using this command code.
+ Servers receiving requests with this command code
+ SHOULD return STATUS_NOT_IMPLEMENTED (ERRDOS/ERRbadfunc).
 ****************************************************************************/
 
 void reply_copy(struct smb_request *req)
 {
-       connection_struct *conn = req->conn;
-       struct smb_filename *smb_fname_src = NULL;
-       struct smb_filename *smb_fname_src_dir = NULL;
-       struct smb_filename *smb_fname_dst = NULL;
-       char *fname_src = NULL;
-       char *fname_dst = NULL;
-       char *fname_src_mask = NULL;
-       char *fname_src_dir = NULL;
-       const char *p;
-       int count=0;
-       int error = ERRnoaccess;
-       int tid2;
-       int ofun;
-       int flags;
-       bool target_is_directory=False;
-       bool source_has_wild = False;
-       bool dest_has_wild = False;
-       NTSTATUS status;
-       uint32_t ucf_flags_src = UCF_ALWAYS_ALLOW_WCARD_LCOMP |
-               ucf_flags_from_smb_request(req);
-       uint32_t ucf_flags_dst = UCF_ALWAYS_ALLOW_WCARD_LCOMP |
-               ucf_flags_from_smb_request(req);
-       TALLOC_CTX *ctx = talloc_tos();
-
        START_PROFILE(SMBcopy);
-
-       if (req->wct < 3) {
-               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               goto out;
-       }
-
-       tid2 = SVAL(req->vwv+0, 0);
-       ofun = SVAL(req->vwv+1, 0);
-       flags = SVAL(req->vwv+2, 0);
-
-       p = (const char *)req->buf;
-       p += srvstr_get_path_req(ctx, req, &fname_src, p, STR_TERMINATE,
-                                      &status);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-       p += srvstr_get_path_req(ctx, req, &fname_dst, p, STR_TERMINATE,
-                                      &status);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-
-       DEBUG(3,("reply_copy : %s -> %s\n", fname_src, fname_dst));
-
-       if (tid2 != conn->cnum) {
-               /* can't currently handle inter share copies XXXX */
-               DEBUG(3,("Rejecting inter-share copy\n"));
-               reply_nterror(req, NT_STATUS_BAD_DEVICE_TYPE);
-               goto out;
-       }
-
-       status = filename_convert(ctx, conn,
-                                 fname_src,
-                                 ucf_flags_src,
-                                 0,
-                                 &smb_fname_src);
-       if (!NT_STATUS_IS_OK(status)) {
-               if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
-                       reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
-                                       ERRSRV, ERRbadpath);
-                       goto out;
-               }
-               reply_nterror(req, status);
-               goto out;
-       }
-
-       status = filename_convert(ctx, conn,
-                                 fname_dst,
-                                 ucf_flags_dst,
-                                 0,
-                                 &smb_fname_dst);
-       if (!NT_STATUS_IS_OK(status)) {
-               if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
-                       reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
-                                       ERRSRV, ERRbadpath);
-                       goto out;
-               }
-               reply_nterror(req, status);
-               goto out;
-       }
-
-       target_is_directory = VALID_STAT_OF_DIR(smb_fname_dst->st);
-
-       if ((flags&1) && target_is_directory) {
-               reply_nterror(req, NT_STATUS_NO_SUCH_FILE);
-               goto out;
-       }
-
-       if ((flags&2) && !target_is_directory) {
-               reply_nterror(req, NT_STATUS_OBJECT_PATH_NOT_FOUND);
-               goto out;
-       }
-
-       if ((flags&(1<<5)) && VALID_STAT_OF_DIR(smb_fname_src->st)) {
-               /* wants a tree copy! XXXX */
-               DEBUG(3,("Rejecting tree copy\n"));
-               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               goto out;
-       }
-
-       /* Split up the directory from the filename/mask. */
-       status = split_fname_dir_mask(ctx, smb_fname_src->base_name,
-                                     &fname_src_dir, &fname_src_mask);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, NT_STATUS_NO_MEMORY);
-               goto out;
-       }
-
-       if (!req->posix_pathnames) {
-               char *orig_src_lcomp = NULL;
-               char *orig_dst_lcomp = NULL;
-               /*
-                * Check the wildcard mask *before*
-                * unmangling. As mangling is done
-                * for names that can't be returned
-                * to Windows the unmangled name may
-                * contain Windows wildcard characters.
-                */
-               orig_src_lcomp = get_original_lcomp(ctx,
-                                       conn,
-                                       fname_src,
-                                       ucf_flags_src);
-               if (orig_src_lcomp == NULL) {
-                       reply_nterror(req, NT_STATUS_NO_MEMORY);
-                       goto out;
-               }
-               orig_dst_lcomp = get_original_lcomp(ctx,
-                                       conn,
-                                       fname_dst,
-                                       ucf_flags_dst);
-               if (orig_dst_lcomp == NULL) {
-                       reply_nterror(req, NT_STATUS_NO_MEMORY);
-                       goto out;
-               }
-               source_has_wild = ms_has_wild(orig_src_lcomp);
-               dest_has_wild = ms_has_wild(orig_dst_lcomp);
-               TALLOC_FREE(orig_src_lcomp);
-               TALLOC_FREE(orig_dst_lcomp);
-       }
-
-       /*
-        * We should only check the mangled cache
-        * here if unix_convert failed. This means
-        * that the path in 'mask' doesn't exist
-        * on the file system and so we need to look
-        * for a possible mangle. This patch from
-        * Tine Smukavec <valentin.smukavec@hermes.si>.
-        */
-       if (!VALID_STAT(smb_fname_src->st) &&
-           mangle_is_mangled(fname_src_mask, conn->params)) {
-               char *new_mask = NULL;
-               mangle_lookup_name_from_8_3(ctx, fname_src_mask,
-                                           &new_mask, conn->params);
-
-               /* Use demangled name if one was successfully found. */
-               if (new_mask) {
-                       TALLOC_FREE(fname_src_mask);
-                       fname_src_mask = new_mask;
-               }
-       }
-
-       if (!source_has_wild) {
-
-               /*
-                * Only one file needs to be copied. Append the mask back onto
-                * the directory.
-                */
-               TALLOC_FREE(smb_fname_src->base_name);
-               if (ISDOT(fname_src_dir)) {
-                       /* Ensure we use canonical names on open. */
-                       smb_fname_src->base_name = talloc_asprintf(smb_fname_src,
-                                                       "%s",
-                                                       fname_src_mask);
-               } else {
-                       smb_fname_src->base_name = talloc_asprintf(smb_fname_src,
-                                                       "%s/%s",
-                                                       fname_src_dir,
-                                                       fname_src_mask);
-               }
-               if (!smb_fname_src->base_name) {
-                       reply_nterror(req, NT_STATUS_NO_MEMORY);
-                       goto out;
-               }
-
-               if (dest_has_wild) {
-                       char *fname_dst_mod = NULL;
-                       if (!resolve_wildcards(smb_fname_dst,
-                                              smb_fname_src->base_name,
-                                              smb_fname_dst->base_name,
-                                              &fname_dst_mod)) {
-                               reply_nterror(req, NT_STATUS_NO_MEMORY);
-                               goto out;
-                       }
-                       TALLOC_FREE(smb_fname_dst->base_name);
-                       smb_fname_dst->base_name = fname_dst_mod;
-               }
-
-               status = check_name(conn, smb_fname_src);
-               if (!NT_STATUS_IS_OK(status)) {
-                       reply_nterror(req, status);
-                       goto out;
-               }
-
-               status = check_name(conn, smb_fname_dst);
-               if (!NT_STATUS_IS_OK(status)) {
-                       reply_nterror(req, status);
-                       goto out;
-               }
-
-               status = copy_file(ctx, conn, smb_fname_src, smb_fname_dst,
-                                  ofun, count, target_is_directory);
-
-               if(!NT_STATUS_IS_OK(status)) {
-                       reply_nterror(req, status);
-                       goto out;
-               } else {
-                       count++;
-               }
-       } else {
-               struct smb_Dir *dir_hnd = NULL;
-               const char *dname = NULL;
-               char *talloced = NULL;
-               long offset = 0;
-
-               /*
-                * There is a wildcard that requires us to actually read the
-                * src dir and copy each file matching the mask to the dst.
-                * Right now streams won't be copied, but this could
-                * presumably be added with a nested loop for reach dir entry.
-                */
-               SMB_ASSERT(!smb_fname_src->stream_name);
-               SMB_ASSERT(!smb_fname_dst->stream_name);
-
-               smb_fname_src->stream_name = NULL;
-               smb_fname_dst->stream_name = NULL;
-
-               if (strequal(fname_src_mask,"????????.???")) {
-                       TALLOC_FREE(fname_src_mask);
-                       fname_src_mask = talloc_strdup(ctx, "*");
-                       if (!fname_src_mask) {
-                               reply_nterror(req, NT_STATUS_NO_MEMORY);
-                               goto out;
-                       }
-               }
-
-               smb_fname_src_dir = synthetic_smb_fname(talloc_tos(),
-                                       fname_src_dir,
-                                       NULL,
-                                       NULL,
-                                       smb_fname_src->twrp,
-                                       smb_fname_src->flags);
-               if (smb_fname_src_dir == NULL) {
-                       reply_nterror(req, NT_STATUS_NO_MEMORY);
-                       goto out;
-               }
-
-               status = check_name(conn, smb_fname_src_dir);
-               if (!NT_STATUS_IS_OK(status)) {
-                       reply_nterror(req, status);
-                       goto out;
-               }
-
-               dir_hnd = OpenDir(ctx,
-                               conn,
-                               smb_fname_src_dir,
-                               fname_src_mask,
-                               0);
-               if (dir_hnd == NULL) {
-                       status = map_nt_error_from_unix(errno);
-                       reply_nterror(req, status);
-                       goto out;
-               }
-
-               error = ERRbadfile;
-
-               /* Iterate over the src dir copying each entry to the dst. */
-               while ((dname = ReadDirName(dir_hnd, &offset,
-                                           &smb_fname_src->st, &talloced))) {
-                       char *destname = NULL;
-
-                       if (ISDOT(dname) || ISDOTDOT(dname)) {
-                               TALLOC_FREE(talloced);
-                               continue;
-                       }
-
-                       if (IS_VETO_PATH(conn, dname)) {
-                               TALLOC_FREE(talloced);
-                               continue;
-                       }
-
-                       if(!mask_match(dname, fname_src_mask,
-                                      conn->case_sensitive)) {
-                               TALLOC_FREE(talloced);
-                               continue;
-                       }
-
-                       error = ERRnoaccess;
-
-                       /* Get the src smb_fname struct setup. */
-                       TALLOC_FREE(smb_fname_src->base_name);
-                       if (ISDOT(fname_src_dir)) {
-                               /* Ensure we use canonical names on open. */
-                               smb_fname_src->base_name =
-                                       talloc_asprintf(smb_fname_src, "%s",
-                                               dname);
-                       } else {
-                               smb_fname_src->base_name =
-                                       talloc_asprintf(smb_fname_src, "%s/%s",
-                                               fname_src_dir, dname);
-                       }
-
-                       if (!smb_fname_src->base_name) {
-                               TALLOC_FREE(dir_hnd);
-                               TALLOC_FREE(talloced);
-                               reply_nterror(req, NT_STATUS_NO_MEMORY);
-                               goto out;
-                       }
-
-                       if (!resolve_wildcards(ctx, smb_fname_src->base_name,
-                                              smb_fname_dst->base_name,
-                                              &destname)) {
-                               TALLOC_FREE(talloced);
-                               continue;
-                       }
-                       if (!destname) {
-                               TALLOC_FREE(dir_hnd);
-                               TALLOC_FREE(talloced);
-                               reply_nterror(req, NT_STATUS_NO_MEMORY);
-                               goto out;
-                       }
-
-                       TALLOC_FREE(smb_fname_dst->base_name);
-                       smb_fname_dst->base_name = destname;
-
-                       ZERO_STRUCT(smb_fname_src->st);
-                       vfs_stat(conn, smb_fname_src);
-
-                       status = openat_pathref_fsp(conn->cwd_fsp,
-                                                   smb_fname_src);
-                       if (!NT_STATUS_IS_OK(status)) {
-                               DBG_INFO("openat_pathref_fsp [%s] failed: %s\n",
-                                       smb_fname_str_dbg(smb_fname_src),
-                                       nt_errstr(status));
-                               break;
-                       }
-
-                       if (!is_visible_fsp(smb_fname_src->fsp)) {
-                               TALLOC_FREE(talloced);
-                               continue;
-                       }
-
-                       status = check_name(conn, smb_fname_src);
-                       if (!NT_STATUS_IS_OK(status)) {
-                               TALLOC_FREE(dir_hnd);
-                               TALLOC_FREE(talloced);
-                               reply_nterror(req, status);
-                               goto out;
-                       }
-
-                       status = check_name(conn, smb_fname_dst);
-                       if (!NT_STATUS_IS_OK(status)) {
-                               TALLOC_FREE(dir_hnd);
-                               TALLOC_FREE(talloced);
-                               reply_nterror(req, status);
-                               goto out;
-                       }
-
-                       DEBUG(3,("reply_copy : doing copy on %s -> %s\n",
-                               smb_fname_src->base_name,
-                               smb_fname_dst->base_name));
-
-                       status = copy_file(ctx, conn, smb_fname_src,
-                                          smb_fname_dst, ofun, count,
-                                          target_is_directory);
-                       if (NT_STATUS_IS_OK(status)) {
-                               count++;
-                       }
-
-                       TALLOC_FREE(talloced);
-               }
-               TALLOC_FREE(dir_hnd);
-       }
-
-       if (count == 0) {
-               reply_nterror(req, dos_to_ntstatus(ERRDOS, error));
-               goto out;
-       }
-
-       reply_outbuf(req, 1, 0);
-       SSVAL(req->outbuf,smb_vwv0,count);
- out:
-       TALLOC_FREE(smb_fname_src);
-       TALLOC_FREE(smb_fname_src_dir);
-       TALLOC_FREE(smb_fname_dst);
-       TALLOC_FREE(fname_src);
-       TALLOC_FREE(fname_dst);
-       TALLOC_FREE(fname_src_mask);
-       TALLOC_FREE(fname_src_dir);
-
+       reply_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
        END_PROFILE(SMBcopy);
        return;
 }
@@ -9253,7 +8108,6 @@ struct smbd_do_unlocking_state {
        struct files_struct *fsp;
        uint16_t num_ulocks;
        struct smbd_lock_element *ulocks;
-       enum brl_flavour lock_flav;
        NTSTATUS status;
 };
 
@@ -9265,7 +8119,6 @@ static void smbd_do_unlocking_fn(
 {
        struct smbd_do_unlocking_state *state = private_data;
        struct files_struct *fsp = state->fsp;
-       enum brl_flavour lock_flav = state->lock_flav;
        uint16_t i;
 
        for (i = 0; i < state->num_ulocks; i++) {
@@ -9285,7 +8138,7 @@ static void smbd_do_unlocking_fn(
                }
 
                state->status = do_unlock(
-                       fsp, e->smblctx, e->count, e->offset, lock_flav);
+                       fsp, e->smblctx, e->count, e->offset, e->lock_flav);
 
                DBG_DEBUG("do_unlock returned %s\n",
                          nt_errstr(state->status));
@@ -9301,14 +8154,12 @@ static void smbd_do_unlocking_fn(
 NTSTATUS smbd_do_unlocking(struct smb_request *req,
                           files_struct *fsp,
                           uint16_t num_ulocks,
-                          struct smbd_lock_element *ulocks,
-                          enum brl_flavour lock_flav)
+                          struct smbd_lock_element *ulocks)
 {
        struct smbd_do_unlocking_state state = {
                .fsp = fsp,
                .num_ulocks = num_ulocks,
                .ulocks = ulocks,
-               .lock_flav = lock_flav,
        };
        NTSTATUS status;
 
@@ -9491,6 +8342,7 @@ void reply_lockingX(struct smb_request *req)
                        ulocks[i].offset = get_lock_offset(
                                data, i, large_file_format);
                        ulocks[i].brltype = UNLOCK_LOCK;
+                       ulocks[i].lock_flav = WINDOWS_LOCK;
                }
 
                /*
@@ -9500,7 +8352,6 @@ void reply_lockingX(struct smb_request *req)
                ok = smbd_smb1_brl_finish_by_lock(
                        fsp,
                        large_file_format,
-                       WINDOWS_LOCK,
                        ulocks[0],
                        NT_STATUS_OK);
                if (ok) {
@@ -9512,7 +8363,7 @@ void reply_lockingX(struct smb_request *req)
                }
 
                status = smbd_do_unlocking(
-                       req, fsp, num_ulocks, ulocks, WINDOWS_LOCK);
+                       req, fsp, num_ulocks, ulocks);
                TALLOC_FREE(ulocks);
                if (!NT_STATUS_IS_OK(status)) {
                        END_PROFILE(SMBlockingX);
@@ -9546,6 +8397,7 @@ void reply_lockingX(struct smb_request *req)
                locks[i].count = get_lock_count(data, i, large_file_format);
                locks[i].offset = get_lock_offset(data, i, large_file_format);
                locks[i].brltype = brltype;
+               locks[i].lock_flav = WINDOWS_LOCK;
        }
 
        if (locktype & LOCKING_ANDX_CANCEL_LOCK) {
@@ -9565,7 +8417,6 @@ void reply_lockingX(struct smb_request *req)
                ok = smbd_smb1_brl_finish_by_lock(
                        fsp,
                        large_file_format,
-                       WINDOWS_LOCK,
                        locks[0], /* Windows only cancels the first lock */
                        NT_STATUS_FILE_LOCK_CONFLICT);
 
@@ -9589,7 +8440,6 @@ void reply_lockingX(struct smb_request *req)
                fsp,
                lock_timeout,
                large_file_format,
-               WINDOWS_LOCK,
                num_locks,
                locks);
        if (subreq == NULL) {