]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: smbd: Remove support for SMBcopy SMB_COM_COPY (0x29)
authorJeremy Allison <jra@samba.org>
Wed, 1 Dec 2021 20:24:07 +0000 (12:24 -0800)
committerRalph Boehme <slow@samba.org>
Thu, 9 Dec 2021 18:06:35 +0000 (18:06 +0000)
It's not used in our client code or tested.

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

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/smbd/reply.c

index b0101f667a83a7c1f79652f2c31bd28a1e83f844..8ee17643200a124cf87bc907824f60965a164775 100644 (file)
@@ -8782,419 +8782,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);
-       bool posix_pathnames = req->posix_pathnames;
-       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 (!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) &&
-           !posix_pathnames &&
-           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,
-                                      posix_pathnames ?
-                                       true : 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;
 }