s3: Convert a few callers of unix_convert() over to filename_convert()
authorTim Prouty <tprouty@samba.org>
Sat, 25 Jul 2009 01:38:40 +0000 (18:38 -0700)
committerTim Prouty <tprouty@samba.org>
Sat, 25 Jul 2009 01:51:41 +0000 (18:51 -0700)
This patch also changes the unix convert flags to make sure the
correct semantics are preservered for allowing/disallowing wildcards
in the last component of the path.

source3/include/proto.h
source3/include/smb.h
source3/printing/nt_printing.c
source3/smbd/filename.c
source3/smbd/msdfs.c
source3/smbd/nttrans.c
source3/smbd/reply.c
source3/smbd/trans2.c

index 92386f5fae9dfe758791a4f70fb17fc0a0dea6cd..aed2c4c0f7143ab1c429e9bf2faa1de1d98a1c9c 100644 (file)
@@ -6846,7 +6846,8 @@ void reply_ulogoffX(struct smb_request *req);
 void reply_mknew(struct smb_request *req);
 void reply_ctemp(struct smb_request *req);
 NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
-                         uint32 dirtype, const char *name_in, bool has_wild);
+                         uint32 dirtype, struct smb_filename *smb_fname,
+                         bool has_wild);
 void reply_unlink(struct smb_request *req);
 void reply_readbraw(struct smb_request *req);
 void reply_lockread(struct smb_request *req);
index 1c4ac547228ab739a0920b193e9bcf643404dd4d..6ccdd968a3db07653e8a7202fa62249ba4970c25 100644 (file)
@@ -1900,7 +1900,8 @@ struct smb_file_time {
  * unix_convert_flags
  */
 #define UCF_SAVE_LCOMP                 0x00000001
-#define UCF_ALLOW_WCARD_LCOMP          0x00000002
+#define UCF_ALWAYS_ALLOW_WCARD_LCOMP   0x00000002
+#define UCF_COND_ALLOW_WCARD_LCOMP     0x00000004
 
 /*
  * smb_filename
index 3e206becf4a930e16799a9398b7c4d4861aa525a..26b8d9d81d3c4e9facc90a9157ae47fddb4fcf80 100644 (file)
@@ -5145,6 +5145,24 @@ bool printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
        return in_use;
 }
 
+static NTSTATUS driver_unlink_internals(connection_struct *conn,
+                                       const char *name)
+{
+       struct smb_filename *smb_fname = NULL;
+       NTSTATUS status;
+
+       status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
+           &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       status = unlink_internals(conn, NULL, 0, smb_fname, false);
+
+       TALLOC_FREE(smb_fname);
+       return status;
+}
+
 /****************************************************************************
   Actually delete the driver files.  Make sure that
   printer_driver_files_in_use() return False before calling
@@ -5197,7 +5215,7 @@ static bool delete_driver_files(struct pipes_struct *rpc_pipe,
                if ( (s = strchr( &info_3->driverpath[1], '\\' )) != NULL ) {
                        file = s;
                        DEBUG(10,("deleting driverfile [%s]\n", s));
-                       unlink_internals(conn, NULL, 0, file, False);
+                       driver_unlink_internals(conn, file);
                }
        }
 
@@ -5205,7 +5223,7 @@ static bool delete_driver_files(struct pipes_struct *rpc_pipe,
                if ( (s = strchr( &info_3->configfile[1], '\\' )) != NULL ) {
                        file = s;
                        DEBUG(10,("deleting configfile [%s]\n", s));
-                       unlink_internals(conn, NULL, 0, file, False);
+                       driver_unlink_internals(conn, file);
                }
        }
 
@@ -5213,7 +5231,7 @@ static bool delete_driver_files(struct pipes_struct *rpc_pipe,
                if ( (s = strchr( &info_3->datafile[1], '\\' )) != NULL ) {
                        file = s;
                        DEBUG(10,("deleting datafile [%s]\n", s));
-                       unlink_internals(conn, NULL, 0, file, False);
+                       driver_unlink_internals(conn, file);
                }
        }
 
@@ -5221,7 +5239,7 @@ static bool delete_driver_files(struct pipes_struct *rpc_pipe,
                if ( (s = strchr( &info_3->helpfile[1], '\\' )) != NULL ) {
                        file = s;
                        DEBUG(10,("deleting helpfile [%s]\n", s));
-                       unlink_internals(conn, NULL, 0, file, False);
+                       driver_unlink_internals(conn, file);
                }
        }
 
@@ -5236,7 +5254,7 @@ static bool delete_driver_files(struct pipes_struct *rpc_pipe,
                        if ( (p = strchr( info_3->dependentfiles[i]+1, '\\' )) != NULL ) {
                                file = p;
                                DEBUG(10,("deleting dependent file [%s]\n", file));
-                               unlink_internals(conn, NULL, 0, file, False);
+                               driver_unlink_internals(conn, file);
                        }
 
                        i++;
index a13c66c4e0fe43667695d3d88c8a0da79869b332..1e2ebcf30755a9a8862534a52bbbefa20ff45446 100644 (file)
@@ -98,8 +98,8 @@ processing whilst resolving.
 If the UCF_SAVE_LCOMP flag is passed in, then the unmodified last component
 of the pathname is set in smb_filename->original_lcomp.
 
-If UCF_ALLOW_WCARD_LCOMP is passed in, then a MS wildcard was detected and
-should be allowed in the last component of the path only.
+If UCF_ALWAYS_ALLOW_WCARD_LCOMP is passed in, then a MS wildcard was detected
+and should be allowed in the last component of the path only.
 
 If the orig_path was a stream, smb_filename->base_name will point to the base
 filename, and smb_filename->stream_name will point to the stream name.  If
@@ -124,7 +124,8 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
        bool component_was_mangled = False;
        bool name_has_wildcard = False;
        bool posix_pathnames = false;
-       bool allow_wcard_last_component = ucf_flags & UCF_ALLOW_WCARD_LCOMP;
+       bool allow_wcard_last_component =
+           (ucf_flags & UCF_ALWAYS_ALLOW_WCARD_LCOMP);
        bool save_last_component = ucf_flags & UCF_SAVE_LCOMP;
        NTSTATUS status;
        int ret = -1;
@@ -1035,8 +1036,9 @@ static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx,
  * @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.
+ *                     UCF_ALWAYS_ALLOW_WCARD_LCOMP will be OR'd in if
+ *                     p_cont_wcard != NULL and is true and
+ *                     UCF_COND_ALLOW_WCARD_LCOMP.
  * @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
@@ -1072,12 +1074,12 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx,
        }
 
        /*
-        * Strip out the UCF_ALLOW_WCARD_LCOMP if the path doesn't contain a
-        * wildcard.
+        * If the caller conditionally allows wildcard lookups, only add the
+        * always allow if the path actually does contain a wildcard.
         */
-       if (ppath_contains_wcard != NULL && !*ppath_contains_wcard &&
-           ucf_flags & UCF_ALLOW_WCARD_LCOMP) {
-               ucf_flags &= ~UCF_ALLOW_WCARD_LCOMP;
+       if (ucf_flags & UCF_COND_ALLOW_WCARD_LCOMP &&
+           ppath_contains_wcard != NULL && *ppath_contains_wcard) {
+               ucf_flags |= UCF_ALWAYS_ALLOW_WCARD_LCOMP;
        }
 
        status = unix_convert(ctx, conn, fname, pp_smb_fname, ucf_flags);
index f4376d49ced83d23dbd4e20a3d39ca6befdbfc93..22fb8c3ad69a6f0437e77d5d66aa49d97e3763c0 100644 (file)
@@ -544,7 +544,7 @@ static NTSTATUS dfs_path_lookup(TALLOC_CTX *ctx,
         */
 
        status = unix_convert(ctx, conn, pdp->reqpath, &smb_fname,
-                             search_flag ? UCF_ALLOW_WCARD_LCOMP : 0);
+                             search_flag ? UCF_ALWAYS_ALLOW_WCARD_LCOMP : 0);
 
        if (!NT_STATUS_IS_OK(status)) {
                if (!NT_STATUS_EQUAL(status,
index dd4ef9787403ce2a61f5c3dd1be7b290b3a09892..b7b26349634bf77c8e05b8d104d869a2d1c7c836 100644 (file)
@@ -1359,8 +1359,8 @@ void reply_ntrename(struct smb_request *req)
         * 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;
+               ucf_flags_src = UCF_COND_ALLOW_WCARD_LCOMP;
+               ucf_flags_dst = UCF_COND_ALLOW_WCARD_LCOMP | UCF_SAVE_LCOMP;
        }
 
        /* rename_internals() calls unix_convert(), so don't call it here. */
index 03bca827d17a4c6e26ca6f58885d7560a4399627..b5882abe9f2c10107566408d609b4c56746dc2d6 100644 (file)
@@ -1402,11 +1402,12 @@ void reply_search(struct smb_request *req)
        /* dirtype &= ~aDIR; */
 
        if (status_len == 0) {
-               nt_status = resolve_dfspath_wcard(ctx, conn,
-                                         req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                         path,
-                                         &path,
-                                         &mask_contains_wcard);
+               nt_status = filename_convert(ctx, conn,
+                                            req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                            path,
+                                            UCF_ALWAYS_ALLOW_WCARD_LCOMP,
+                                            &mask_contains_wcard,
+                                            &smb_fname);
                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,
@@ -1417,21 +1418,8 @@ void reply_search(struct smb_request *req)
                        goto out;
                }
 
-               nt_status = unix_convert(ctx, conn, path, &smb_fname,
-                                        UCF_ALLOW_WCARD_LCOMP);
-               if (!NT_STATUS_IS_OK(nt_status)) {
-                       reply_nterror(req, nt_status);
-                       goto out;
-               }
-
                directory = smb_fname->base_name;
 
-               nt_status = check_name(conn, directory);
-               if (!NT_STATUS_IS_OK(nt_status)) {
-                       reply_nterror(req, nt_status);
-                       goto out;
-               }
-
                p = strrchr_m(directory,'/');
                if ((p != NULL) && (*directory != '/')) {
                        mask = p + 1;
@@ -2516,21 +2504,15 @@ static NTSTATUS do_unlink(connection_struct *conn,
 ****************************************************************************/
 
 NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
-                         uint32 dirtype, const char *name_in, bool has_wild)
+                         uint32 dirtype, struct smb_filename *smb_fname,
+                         bool has_wild)
 {
-       struct smb_filename *smb_fname = NULL;
        char *fname_dir = NULL;
        char *fname_mask = NULL;
        int count=0;
        NTSTATUS status = NT_STATUS_OK;
        TALLOC_CTX *ctx = talloc_tos();
 
-       status = unix_convert(ctx, conn, name_in, &smb_fname,
-                             has_wild ? UCF_ALLOW_WCARD_LCOMP : 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
        /* Split up the directory from the filename/mask. */
        status = split_fname_dir_mask(ctx, smb_fname->base_name,
                                      &fname_dir, &fname_mask);
@@ -2687,7 +2669,6 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
        }
 
  out:
-       TALLOC_FREE(smb_fname);
        TALLOC_FREE(fname_dir);
        TALLOC_FREE(fname_mask);
        return status;
@@ -2701,6 +2682,7 @@ void reply_unlink(struct smb_request *req)
 {
        connection_struct *conn = req->conn;
        char *name = NULL;
+       struct smb_filename *smb_fname = NULL;
        uint32 dirtype;
        NTSTATUS status;
        bool path_contains_wcard = False;
@@ -2710,8 +2692,7 @@ void reply_unlink(struct smb_request *req)
 
        if (req->wct < 1) {
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               END_PROFILE(SMBunlink);
-               return;
+               goto out;
        }
 
        dirtype = SVAL(req->vwv+0, 0);
@@ -2721,45 +2702,42 @@ void reply_unlink(struct smb_request *req)
                                  &path_contains_wcard);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
-               END_PROFILE(SMBunlink);
-               return;
+               goto out;
        }
 
-       status = resolve_dfspath_wcard(ctx, conn,
-                                      req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                      name,
-                                      &name,
-                                      &path_contains_wcard);
+       status = filename_convert(ctx, conn,
+                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                 name,
+                                 UCF_COND_ALLOW_WCARD_LCOMP,
+                                 &path_contains_wcard,
+                                 &smb_fname);
        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(SMBunlink);
-                       return;
+                       goto out;
                }
                reply_nterror(req, status);
-               END_PROFILE(SMBunlink);
-               return;
+               goto out;
        }
 
-       DEBUG(3,("reply_unlink : %s\n",name));
+       DEBUG(3,("reply_unlink : %s\n", smb_fname_str_dbg(smb_fname)));
 
-       status = unlink_internals(conn, req, dirtype, name,
+       status = unlink_internals(conn, req, dirtype, smb_fname,
                                  path_contains_wcard);
        if (!NT_STATUS_IS_OK(status)) {
                if (open_was_deferred(req->mid)) {
                        /* We have re-scheduled this call. */
-                       END_PROFILE(SMBunlink);
-                       return;
+                       goto out;
                }
                reply_nterror(req, status);
-               END_PROFILE(SMBunlink);
-               return;
+               goto out;
        }
 
        reply_outbuf(req, 0, 0);
+ out:
+       TALLOC_FREE(smb_fname);
        END_PROFILE(SMBunlink);
-
        return;
 }
 
@@ -6506,7 +6484,7 @@ void reply_mv(struct smb_request *req)
                                  conn,
                                  req->flags2 & FLAGS2_DFS_PATHNAMES,
                                  name,
-                                 UCF_ALLOW_WCARD_LCOMP,
+                                 UCF_COND_ALLOW_WCARD_LCOMP,
                                  &src_has_wcard,
                                  &smb_fname_src);
 
@@ -6524,7 +6502,7 @@ void reply_mv(struct smb_request *req)
                                  conn,
                                  req->flags2 & FLAGS2_DFS_PATHNAMES,
                                  newname,
-                                 UCF_ALLOW_WCARD_LCOMP | UCF_SAVE_LCOMP,
+                                 UCF_COND_ALLOW_WCARD_LCOMP | UCF_SAVE_LCOMP,
                                  &dest_has_wcard,
                                  &smb_fname_dst);
 
@@ -6787,11 +6765,12 @@ void reply_copy(struct smb_request *req)
                goto out;
        }
 
-       status = resolve_dfspath_wcard(ctx, conn,
-                                      req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                      fname_src,
-                                      &fname_src,
-                                      &source_has_wild);
+       status = filename_convert(ctx, conn,
+                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                 fname_src,
+                                 UCF_COND_ALLOW_WCARD_LCOMP,
+                                 &source_has_wild,
+                                 &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,
@@ -6802,11 +6781,12 @@ void reply_copy(struct smb_request *req)
                goto out;
        }
 
-       status = resolve_dfspath_wcard(ctx, conn,
-                                      req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                      fname_dst,
-                                      &fname_dst,
-                                      &dest_has_wild);
+       status = filename_convert(ctx, conn,
+                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                 fname_dst,
+                                 UCF_COND_ALLOW_WCARD_LCOMP,
+                                 &dest_has_wild,
+                                 &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,
@@ -6817,20 +6797,6 @@ void reply_copy(struct smb_request *req)
                goto out;
        }
 
-       status = unix_convert(ctx, conn, fname_src, &smb_fname_src,
-                             source_has_wild ? UCF_ALLOW_WCARD_LCOMP : 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-
-       status = unix_convert(ctx, conn, fname_dst, &smb_fname_dst,
-                             dest_has_wild ? UCF_ALLOW_WCARD_LCOMP : 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-
        target_is_directory = VALID_STAT_OF_DIR(smb_fname_dst->st);
 
        if ((flags&1) && target_is_directory) {
index 50edf466c3533a5960514805d22aae47f559c1bb..f34e15b1df21e88ba231f2cfe8f7ddaba1c231ca 100644 (file)
@@ -2091,11 +2091,13 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
                goto out;
        }
 
-       ntstatus = resolve_dfspath_wcard(ctx, conn,
-                       req->flags2 & FLAGS2_DFS_PATHNAMES,
-                       directory,
-                       &directory,
-                       &mask_contains_wcard);
+       ntstatus = filename_convert(ctx, conn,
+                                   req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                   directory,
+                                   (UCF_SAVE_LCOMP |
+                                       UCF_ALWAYS_ALLOW_WCARD_LCOMP),
+                                   &mask_contains_wcard,
+                                   &smb_dname);
        if (!NT_STATUS_IS_OK(ntstatus)) {
                if (NT_STATUS_EQUAL(ntstatus,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -2106,23 +2108,10 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
                goto out;
        }
 
-       ntstatus = unix_convert(ctx, conn, directory, &smb_dname,
-                               (UCF_SAVE_LCOMP | UCF_ALLOW_WCARD_LCOMP));
-       if (!NT_STATUS_IS_OK(ntstatus)) {
-               reply_nterror(req, ntstatus);
-               goto out;
-       }
-
        mask = smb_dname->original_lcomp;
 
        directory = smb_dname->base_name;
 
-       ntstatus = check_name(conn, directory);
-       if (!NT_STATUS_IS_OK(ntstatus)) {
-               reply_nterror(req, ntstatus);
-               goto out;
-       }
-
        p = strrchr_m(directory,'/');
        if(p == NULL) {
                /* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
@@ -5823,7 +5812,8 @@ static NTSTATUS smb_file_rename_information(connection_struct *conn,
                status = unix_convert(ctx, conn, base_name, &smb_fname_dst,
                                      (UCF_SAVE_LCOMP |
                                          (dest_has_wcard ?
-                                             UCF_ALLOW_WCARD_LCOMP : 0)));
+                                             UCF_ALWAYS_ALLOW_WCARD_LCOMP :
+                                             0)));
 
                /* If an error we expect this to be
                 * NT_STATUS_OBJECT_PATH_NOT_FOUND */