The branch, master has been updated
       via  cd5133b1127579fa47152e4c38f4a6534bdf37c7 (commit)
       via  10324b177ed2c5de07039f035905b8272f51fbf7 (commit)
      from  c472bca42c587d46bd9d11a1c02fe53808cee08e (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit cd5133b1127579fa47152e4c38f4a6534bdf37c7
Author: Tim Prouty <tpro...@samba.org>
Date:   Fri Jul 24 11:39:56 2009 -0700

    s3: Simplify rename_internals() by passing in smb_filename structs

commit 10324b177ed2c5de07039f035905b8272f51fbf7
Author: Tim Prouty <tpro...@samba.org>
Date:   Fri Jul 24 12:13:07 2009 -0700

    s3: Allow filename_convert() to pass through unix_convert_flags and let the 
caller know if the path has a wildcard
    
    This also eliminates the need for resolve_dfspath().

-----------------------------------------------------------------------

Summary of changes:
 source3/include/proto.h            |    6 +-
 source3/rpc_server/srv_srvsvc_nt.c |    4 +
 source3/smbd/filename.c            |   41 ++++++++++--
 source3/smbd/msdfs.c               |   45 +++----------
 source3/smbd/nttrans.c             |  121 +++++++++++++++++-------------------
 source3/smbd/reply.c               |  106 ++++++++++++++++---------------
 source3/smbd/smb2_create.c         |    2 +
 source3/smbd/trans2.c              |   81 ++++++++++++++----------
 8 files changed, 211 insertions(+), 195 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/proto.h b/source3/include/proto.h
index 63a82a8..a79c7eb 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -6320,6 +6320,8 @@ NTSTATUS filename_convert(TALLOC_CTX *mem_ctx,
                        connection_struct *conn,
                        bool dfs_path,
                        const char *name_in,
+                       uint32_t ucf_flags,
+                       bool *ppath_contains_wcard,
                        struct smb_filename **pp_smb_fname);
 
 /* The following definitions come from smbd/filename_utils.c */
@@ -6882,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,
diff --git a/source3/rpc_server/srv_srvsvc_nt.c 
b/source3/rpc_server/srv_srvsvc_nt.c
index b9d1ed6..15b2290 100644
--- a/source3/rpc_server/srv_srvsvc_nt.c
+++ b/source3/rpc_server/srv_srvsvc_nt.c
@@ -2072,6 +2072,8 @@ WERROR _srvsvc_NetGetFileSecurity(pipes_struct *p,
                                        conn,
                                        false,
                                        r->in.file,
+                                       0,
+                                       NULL,
                                        &smb_fname);
        if (!NT_STATUS_IS_OK(nt_status)) {
                werr = ntstatus_to_werror(nt_status);
@@ -2200,6 +2202,8 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p,
                                        conn,
                                        false,
                                        r->in.file,
+                                       0,
+                                       NULL,
                                        &smb_fname);
        if (!NT_STATUS_IS_OK(nt_status)) {
                werr = ntstatus_to_werror(nt_status);
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 09f9a41..a13c66c 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -1027,14 +1027,30 @@ static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx,
        return status;
 }
 
-/****************************************************************************
- Go through all the steps to validate a filename.
-****************************************************************************/
-
+/**
+ * Go through all the steps to validate a filename.
+ *
+ * @param ctx          talloc_ctx to allocate memory with.
+ * @param conn         connection struct for vfs calls.
+ * @param dfs_path     Whether this path requires dfs resolution.
+ * @param name_in      The unconverted name.
+ * @param ucf_flags    flags to pass through to unix_convert().
+ *                     UCF_ALLOW_WCARD_LCOMP will be stripped out if
+ *                     p_cont_wcard == NULL or is false.
+ * @param p_cont_wcard If not NULL, will be set to true if the dfs path
+ *                     resolution detects a wildcard.
+ * @param pp_smb_fname The final converted name will be allocated if the
+ *                     return is NT_STATUS_OK.
+ *
+ * @return NT_STATUS_OK if all operations completed succesfully, appropriate
+ *        error otherwise.
+ */
 NTSTATUS filename_convert(TALLOC_CTX *ctx,
                                connection_struct *conn,
                                bool dfs_path,
                                const char *name_in,
+                               uint32_t ucf_flags,
+                               bool *ppath_contains_wcard,
                                struct smb_filename **pp_smb_fname)
 {
        NTSTATUS status;
@@ -1042,10 +1058,11 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx,
 
        *pp_smb_fname = NULL;
 
-       status = resolve_dfspath(ctx, conn,
+       status = resolve_dfspath_wcard(ctx, conn,
                                dfs_path,
                                name_in,
-                               &fname);
+                               &fname,
+                               ppath_contains_wcard);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(10,("filename_convert: resolve_dfspath failed "
                        "for name %s with %s\n",
@@ -1053,7 +1070,17 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx,
                        nt_errstr(status) ));
                return status;
        }
-       status = unix_convert(ctx, conn, fname, pp_smb_fname, 0);
+
+       /*
+        * Strip out the UCF_ALLOW_WCARD_LCOMP if the path doesn't contain a
+        * wildcard.
+        */
+       if (ppath_contains_wcard != NULL && !*ppath_contains_wcard &&
+           ucf_flags & UCF_ALLOW_WCARD_LCOMP) {
+               ucf_flags &= ~UCF_ALLOW_WCARD_LCOMP;
+       }
+
+       status = unix_convert(ctx, conn, fname, pp_smb_fname, ucf_flags);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(10,("filename_convert: unix_convert failed "
                        "for name %s with %s\n",
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 2b63eb1..3641e8d 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -1718,40 +1718,9 @@ struct junction_map *enum_msdfs_links(TALLOC_CTX *ctx, 
size_t *p_num_jn)
 }
 
 /******************************************************************************
- Core function to resolve a dfs pathname.
-******************************************************************************/
-
-NTSTATUS resolve_dfspath(TALLOC_CTX *ctx,
-                       connection_struct *conn,
-                       bool dfs_pathnames,
-                       const char *name_in,
-                       char **pp_name_out)
-{
-       NTSTATUS status = NT_STATUS_OK;
-       bool dummy;
-       if (dfs_pathnames) {
-               status = dfs_redirect(ctx,
-                                       conn,
-                                       name_in,
-                                       False,
-                                       pp_name_out,
-                                       &dummy);
-       } else {
-               /*
-                * Cheat and just return a copy of the in ptr.
-                * Once srvstr_get_path() uses talloc it'll
-                * be a talloced ptr anyway.
-                */
-               *pp_name_out = CONST_DISCARD(char *,name_in);
-       }
-       return status;
-}
-
-/******************************************************************************
- Core function to resolve a dfs pathname possibly containing a wildcard.
- This function is identical to the above except for the bool param to
- dfs_redirect but I need this to be separate so it's really clear when
- we're allowing wildcards and when we're not. JRA.
+ Core function to resolve a dfs pathname possibly containing a wildcard.  If
+ ppath_contains_wcard != NULL, it will be set to true if a wildcard is
+ detected during dfs resolution.
 ******************************************************************************/
 
 NTSTATUS resolve_dfspath_wcard(TALLOC_CTX *ctx,
@@ -1761,14 +1730,20 @@ NTSTATUS resolve_dfspath_wcard(TALLOC_CTX *ctx,
                                char **pp_name_out,
                                bool *ppath_contains_wcard)
 {
+       bool path_contains_wcard;
        NTSTATUS status = NT_STATUS_OK;
+
        if (dfs_pathnames) {
                status = dfs_redirect(ctx,
                                        conn,
                                        name_in,
                                        True,
                                        pp_name_out,
-                                       ppath_contains_wcard);
+                                       &path_contains_wcard);
+
+               if (NT_STATUS_IS_OK(status) && ppath_contains_wcard != NULL) {
+                       *ppath_contains_wcard = path_contains_wcard;
+               }
        } else {
                /*
                 * Cheat and just return a copy of the in ptr.
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 43212dc..dd4ef97 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -478,6 +478,8 @@ void reply_ntcreate_and_X(struct smb_request *req)
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
+                               0,
+                               NULL,
                                &smb_fname);
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -967,6 +969,8 @@ static void call_nt_transact_create(connection_struct *conn,
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
+                               0,
+                               NULL,
                                &smb_fname);
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -1308,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();
 
@@ -1348,87 +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,
-                                         &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,
-                                         &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:
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 76d32a2..03bca82 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -994,6 +994,8 @@ void reply_checkpath(struct smb_request *req)
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                name,
+                               0,
+                               NULL,
                                &smb_fname);
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -1090,6 +1092,8 @@ void reply_getatr(struct smb_request *req)
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
+                               0,
+                               NULL,
                                &smb_fname);
                if (!NT_STATUS_IS_OK(status)) {
                        if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) 
{
@@ -1191,6 +1195,8 @@ void reply_setatr(struct smb_request *req)
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
+                               0,
+                               NULL,
                                &smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -1724,6 +1730,8 @@ void reply_open(struct smb_request *req)
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
+                               0,
+                               NULL,
                                &smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -1894,6 +1902,8 @@ void reply_open_and_X(struct smb_request *req)
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
+                               0,
+                               NULL,
                                &smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -2103,6 +2113,8 @@ void reply_mknew(struct smb_request *req)
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
+                               0,
+                               NULL,
                                &smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -2235,6 +2247,8 @@ void reply_ctemp(struct smb_request *req)
        status = filename_convert(ctx, conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
+                               0,
+                               NULL,
                                &smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -5240,6 +5254,8 @@ void reply_mkdir(struct smb_request *req)
        status = filename_convert(ctx, conn,
                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
                                 directory,
+                                0,
+                                NULL,
                                 &smb_dname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -5547,6 +5563,8 @@ void reply_rmdir(struct smb_request *req)
        status = filename_convert(ctx, conn,
                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
                                 directory,
+                                0,
+                                NULL,
                                 &smb_dname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -6119,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;
@@ -6139,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
@@ -6452,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;
@@ -6474,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) {


-- 
Samba Shared Repository

Reply via email to