s3: Simplify rename_internals() by passing in smb_filename structs
authorTim Prouty <tprouty@samba.org>
Fri, 24 Jul 2009 18:39:56 +0000 (11:39 -0700)
committerTim Prouty <tprouty@samba.org>
Fri, 24 Jul 2009 22:10:45 +0000 (15:10 -0700)
source3/include/proto.h
source3/smbd/nttrans.c
source3/smbd/reply.c
source3/smbd/trans2.c

index 5d0fa18192d8934c6e26266507cc0d7415c87669..a79c7eb7e80e740180c18b9f522b8b5616abda32 100644 (file)
@@ -6884,8 +6884,8 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
 NTSTATUS rename_internals(TALLOC_CTX *ctx,
                        connection_struct *conn,
                        struct smb_request *req,
-                       const char *name_in,
-                       const char *newname_in,
+                       struct smb_filename *smb_fname_src,
+                       struct smb_filename *smb_fname_dst,
                        uint32 attrs,
                        bool replace_if_exists,
                        bool src_has_wild,
index 89fc9dc4a8bf4666393993f077f056bbd4c9ad5e..dd4ef9787403ce2a61f5c3dd1be7b290b3a09892 100644 (file)
@@ -1312,6 +1312,8 @@ void reply_ntrename(struct smb_request *req)
        bool src_has_wcard = False;
        bool dest_has_wcard = False;
        uint32 attrs;
+       uint32_t ucf_flags_src = 0;
+       uint32_t ucf_flags_dst = 0;
        uint16 rename_type;
        TALLOC_CTX *ctx = talloc_tos();
 
@@ -1352,91 +1354,72 @@ void reply_ntrename(struct smb_request *req)
                goto out;
        }
 
+       /*
+        * If this is a rename operation, allow wildcards and save the
+        * destination's last component.
+        */
+       if (rename_type == RENAME_FLAG_RENAME) {
+               ucf_flags_src = UCF_ALLOW_WCARD_LCOMP;
+               ucf_flags_dst = UCF_ALLOW_WCARD_LCOMP | UCF_SAVE_LCOMP;
+       }
+
        /* rename_internals() calls unix_convert(), so don't call it here. */
-       if (rename_type != RENAME_FLAG_RENAME) {
-               status = filename_convert(ctx, conn,
-                                         req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                         oldname,
-                                         0,
-                                         NULL,
-                                         &smb_fname_old);
-               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);
+       status = filename_convert(ctx, conn,
+                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                 oldname,
+                                 ucf_flags_src,
+                                 NULL,
+                                 &smb_fname_old);
+       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,
-                                         req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                         newname,
-                                         0,
-                                         NULL,
-                                         &smb_fname_new);
-               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);
+       status = filename_convert(ctx, conn,
+                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                 newname,
+                                 ucf_flags_dst,
+                                 &dest_has_wcard,
+                                 &smb_fname_new);
+       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;
                }
-
-               DEBUG(3,("reply_ntrename: %s -> %s\n",
-                        smb_fname_str_dbg(smb_fname_old),
-                        smb_fname_str_dbg(smb_fname_new)));
+               reply_nterror(req, status);
+               goto out;
        }
 
+       DEBUG(3,("reply_ntrename: %s -> %s\n",
+                smb_fname_str_dbg(smb_fname_old),
+                smb_fname_str_dbg(smb_fname_new)));
+
        switch(rename_type) {
                case RENAME_FLAG_RENAME:
-                       status = resolve_dfspath(ctx, conn,
-                                                (req->flags2 &
-                                                    FLAGS2_DFS_PATHNAMES),
-                                                oldname, &oldname);
-                       if (!NT_STATUS_IS_OK(status)) {
-                               DEBUG(10,("resolve_dfspath failed for name %s "
-                                         "with %s\n", oldname,
-                                         nt_errstr(status)));
-                               reply_nterror(req, status);
-                               goto out;
-                       }
-
-                       status = resolve_dfspath(ctx, conn,
-                                                (req->flags2 &
-                                                    FLAGS2_DFS_PATHNAMES),
-                                                newname, &newname);
-                       if (!NT_STATUS_IS_OK(status)) {
-                               DEBUG(10,("resolve_dfspath failed for name %s "
-                                         "with %s\n", newname,
-                                         nt_errstr(status)));
-                               reply_nterror(req, status);
-                               goto out;
-                       }
-
-                       DEBUG(3,("reply_ntrename: %s -> %s\n", oldname,
-                               newname));
-
-                       status = rename_internals(ctx, conn, req, oldname,
-                                       newname, attrs, False, src_has_wcard,
-                                       dest_has_wcard, DELETE_ACCESS);
+                       status = rename_internals(ctx, conn, req,
+                                                 smb_fname_old, smb_fname_new,
+                                                 attrs, False, src_has_wcard,
+                                                 dest_has_wcard,
+                                                 DELETE_ACCESS);
                        break;
                case RENAME_FLAG_HARD_LINK:
                        if (src_has_wcard || dest_has_wcard) {
                                /* No wildcards. */
                                status = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
                        } else {
-                               status = hardlink_internals(ctx,
-                                               conn,
-                                               smb_fname_old,
-                                               smb_fname_new);
+                               status = hardlink_internals(ctx, conn,
+                                                           smb_fname_old,
+                                                           smb_fname_new);
                        }
                        break;
                case RENAME_FLAG_COPY:
index b43d3d304cf5b2c92e2c99c0f2feebd9b0654650..03bca827d17a4c6e26ca6f58885d7560a4399627 100644 (file)
@@ -6137,16 +6137,14 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
 NTSTATUS rename_internals(TALLOC_CTX *ctx,
                        connection_struct *conn,
                        struct smb_request *req,
-                       const char *name_in,
-                       const char *newname_in,
+                       struct smb_filename *smb_fname_src,
+                       struct smb_filename *smb_fname_dst,
                        uint32 attrs,
                        bool replace_if_exists,
                        bool src_has_wild,
                        bool dest_has_wild,
                        uint32_t access_mask)
 {
-       struct smb_filename *smb_fname_src = NULL;
-       struct smb_filename *smb_fname_dst = NULL;
        char *fname_src_dir = NULL;
        char *fname_src_mask = NULL;
        int count=0;
@@ -6157,19 +6155,6 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
        int create_options = 0;
        bool posix_pathnames = lp_posix_pathnames();
 
-       status = unix_convert(ctx, conn, name_in, &smb_fname_src,
-                             src_has_wild ? UCF_ALLOW_WCARD_LCOMP : 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
-       status = unix_convert(ctx, conn, newname_in, &smb_fname_dst,
-                             (UCF_SAVE_LCOMP |
-                              (dest_has_wild ? UCF_ALLOW_WCARD_LCOMP : 0)));
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
        /*
         * Split the old name into directory and last component
         * strings. Note that unix_convert may have stripped off a
@@ -6470,8 +6455,6 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
        }
 
  out:
-       TALLOC_FREE(smb_fname_src);
-       TALLOC_FREE(smb_fname_dst);
        TALLOC_FREE(fname_src_dir);
        TALLOC_FREE(fname_src_mask);
        return status;
@@ -6492,13 +6475,14 @@ void reply_mv(struct smb_request *req)
        bool src_has_wcard = False;
        bool dest_has_wcard = False;
        TALLOC_CTX *ctx = talloc_tos();
+       struct smb_filename *smb_fname_src = NULL;
+       struct smb_filename *smb_fname_dst = NULL;
 
        START_PROFILE(SMBmv);
 
        if (req->wct < 1) {
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               END_PROFILE(SMBmv);
-               return;
+               goto out;
        }
 
        attrs = SVAL(req->vwv+0, 0);
@@ -6508,69 +6492,71 @@ void reply_mv(struct smb_request *req)
                                       &status, &src_has_wcard);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
-               END_PROFILE(SMBmv);
-               return;
+               goto out;
        }
        p++;
        p += srvstr_get_path_req_wcard(ctx, req, &newname, p, STR_TERMINATE,
                                       &status, &dest_has_wcard);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
-               END_PROFILE(SMBmv);
-               return;
+               goto out;
        }
 
-       status = resolve_dfspath_wcard(ctx, conn,
-                                      req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                      name,
-                                      &name,
-                                      &src_has_wcard);
+       status = filename_convert(ctx,
+                                 conn,
+                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                 name,
+                                 UCF_ALLOW_WCARD_LCOMP,
+                                 &src_has_wcard,
+                                 &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);
-                       END_PROFILE(SMBmv);
-                       return;
+                       goto out;
                }
                reply_nterror(req, status);
-               END_PROFILE(SMBmv);
-               return;
+               goto out;
        }
 
-       status = resolve_dfspath_wcard(ctx, conn,
-                                      req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                      newname,
-                                      &newname,
-                                      &dest_has_wcard);
+       status = filename_convert(ctx,
+                                 conn,
+                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                 newname,
+                                 UCF_ALLOW_WCARD_LCOMP | UCF_SAVE_LCOMP,
+                                 &dest_has_wcard,
+                                 &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);
-                       END_PROFILE(SMBmv);
-                       return;
+                       goto out;
                }
                reply_nterror(req, status);
-               END_PROFILE(SMBmv);
-               return;
+               goto out;
        }
 
-       DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
+       DEBUG(3,("reply_mv : %s -> %s\n", smb_fname_str_dbg(smb_fname_src),
+                smb_fname_str_dbg(smb_fname_dst)));
 
-       status = rename_internals(ctx, conn, req, name, newname, attrs, False,
-                                 src_has_wcard, dest_has_wcard, DELETE_ACCESS);
+       status = rename_internals(ctx, conn, req, smb_fname_src, smb_fname_dst,
+                                 attrs, False, src_has_wcard, dest_has_wcard,
+                                 DELETE_ACCESS);
        if (!NT_STATUS_IS_OK(status)) {
                if (open_was_deferred(req->mid)) {
                        /* We have re-scheduled this call. */
-                       END_PROFILE(SMBmv);
-                       return;
+                       goto out;
                }
                reply_nterror(req, status);
-               END_PROFILE(SMBmv);
-               return;
+               goto out;
        }
 
        reply_outbuf(req, 0, 0);
-
+ out:
+       TALLOC_FREE(smb_fname_src);
+       TALLOC_FREE(smb_fname_dst);
        END_PROFILE(SMBmv);
        return;
 }
index 6a7b1f8b320a734e4a47550691a1ad75e86f3ad5..6fde8d240c66aecda5dd4f1353fc12ce7206264b 100644 (file)
@@ -5683,14 +5683,13 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
                                            const char *pdata,
                                            int total_data,
                                            files_struct *fsp,
-                                           const char *fname)
+                                           struct smb_filename *smb_fname_src)
 {
        bool overwrite;
        uint32 root_fid;
        uint32 len;
        char *newname = NULL;
-       char *base_name = NULL;
-       struct smb_filename *smb_fname = NULL;
+       struct smb_filename *smb_fname_dst = NULL;
        bool dest_has_wcard = False;
        NTSTATUS status = NT_STATUS_OK;
        char *p;
@@ -5741,7 +5740,7 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
                /* Create an smb_fname to call rename_internals_fsp() with. */
                status = create_synthetic_smb_fname(talloc_tos(),
                    fsp->base_fsp->fsp_name->base_name, newname, NULL,
-                   &smb_fname);
+                   &smb_fname_dst);
                if (!NT_STATUS_IS_OK(status)) {
                        goto out;
                }
@@ -5750,28 +5749,31 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
                 * Set the original last component, since
                 * rename_internals_fsp() requires it.
                 */
-               smb_fname->original_lcomp = talloc_strdup(smb_fname, newname);
-               if (smb_fname->original_lcomp == NULL) {
+               smb_fname_dst->original_lcomp = talloc_strdup(smb_fname_dst,
+                                                             newname);
+               if (smb_fname_dst->original_lcomp == NULL) {
                        status = NT_STATUS_NO_MEMORY;
                        goto out;
                }
 
-               /* Create a char * to call rename_internals() with. */
-               base_name = talloc_asprintf(ctx, "%s%s",
-                                          fsp->base_fsp->fsp_name->base_name,
-                                          newname);
-               if (!base_name) {
-                       status = NT_STATUS_NO_MEMORY;
-                       goto out;
-               }
        } else {
+               /*
+                * Build up an smb_fname_dst based on the filename passed in.
+                * We basically just strip off the last component, and put on
+                * the newname instead.
+                */
+               char *base_name = NULL;
+
                /* newname must *not* be a stream name. */
                if (newname[0] == ':') {
                        return NT_STATUS_NOT_SUPPORTED;
                }
 
-               /* Create the base directory. */
-               base_name = talloc_strdup(ctx, fname);
+               /*
+                * Strip off the last component (filename) of the path passed
+                * in.
+                */
+               base_name = talloc_strdup(ctx, smb_fname_src->base_name);
                if (!base_name) {
                        return NT_STATUS_NO_MEMORY;
                }
@@ -5792,8 +5794,10 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
                        return NT_STATUS_NO_MEMORY;
                }
 
-               status = unix_convert(ctx, conn, base_name, &smb_fname,
-                                     UCF_SAVE_LCOMP);
+               status = unix_convert(ctx, conn, base_name, &smb_fname_dst,
+                                     (UCF_SAVE_LCOMP |
+                                         (dest_has_wcard ?
+                                             UCF_ALLOW_WCARD_LCOMP : 0)));
 
                /* If an error we expect this to be
                 * NT_STATUS_OBJECT_PATH_NOT_FOUND */
@@ -5804,32 +5808,35 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
                                goto out;
                        }
                        /* Create an smb_fname to call rename_internals_fsp() */
-                       status = create_synthetic_smb_fname(talloc_tos(),
+                       status = create_synthetic_smb_fname(ctx,
                                                            base_name, NULL,
-                                                           NULL, &smb_fname);
+                                                           NULL,
+                                                           &smb_fname_dst);
                        if (!NT_STATUS_IS_OK(status)) {
                                goto out;
                        }
                }
-
        }
 
        if (fsp) {
                DEBUG(10,("smb_file_rename_information: "
                          "SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
-                         fsp->fnum, fsp_str_dbg(fsp), base_name));
-               status = rename_internals_fsp(conn, fsp, smb_fname, 0,
+                         fsp->fnum, fsp_str_dbg(fsp),
+                         smb_fname_str_dbg(smb_fname_dst)));
+               status = rename_internals_fsp(conn, fsp, smb_fname_dst, 0,
                                              overwrite);
        } else {
                DEBUG(10,("smb_file_rename_information: "
                          "SMB_FILE_RENAME_INFORMATION %s -> %s\n",
-                         fname, base_name));
-               status = rename_internals(ctx, conn, req, fname, base_name, 0,
-                                       overwrite, False, dest_has_wcard,
-                                       FILE_WRITE_ATTRIBUTES);
+                         smb_fname_str_dbg(smb_fname_src),
+                         smb_fname_str_dbg(smb_fname_dst)));
+               status = rename_internals(ctx, conn, req, smb_fname_src,
+                                         smb_fname_dst, 0, overwrite, false,
+                                         dest_has_wcard,
+                                         FILE_WRITE_ATTRIBUTES);
        }
  out:
-       TALLOC_FREE(smb_fname);
+       TALLOC_FREE(smb_fname_dst);
        return status;
 }
 
@@ -7072,7 +7079,6 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
                                int *ret_data_size)
 {
        char *pdata = *ppdata;
-       char *fname = NULL;
        NTSTATUS status = NT_STATUS_OK;
        int data_return_size = 0;
 
@@ -7090,11 +7096,6 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
                }
        }
 
-       status = get_full_smb_filename(mem_ctx, smb_fname, &fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
        DEBUG(3,("smbd_do_setfilepathinfo: %s (fnum %d) info_level=%d "
                 "totdata=%d\n", smb_fname_str_dbg(smb_fname),
                 fsp ? fsp->fnum : -1, info_level, total_data));
@@ -7248,7 +7249,7 @@ NTSTATUS smbd_do_setfilepathinfo(connection_struct *conn,
                {
                        status = smb_file_rename_information(conn, req,
                                                             pdata, total_data,
-                                                            fsp, fname);
+                                                            fsp, smb_fname);
                        break;
                }