summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h3
-rw-r--r--source3/include/smb.h3
-rw-r--r--source3/printing/nt_printing.c28
-rw-r--r--source3/smbd/filename.c22
-rw-r--r--source3/smbd/msdfs.c2
-rw-r--r--source3/smbd/nttrans.c4
-rw-r--r--source3/smbd/reply.c112
-rw-r--r--source3/smbd/trans2.c28
8 files changed, 90 insertions, 112 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 92386f5fae..aed2c4c0f7 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -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);
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 1c4ac54722..6ccdd968a3 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -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
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index 3e206becf4..26b8d9d81d 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -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++;
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index a13c66c4e0..1e2ebcf307 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -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);
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index f4376d49ce..22fb8c3ad6 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -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,
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index dd4ef97874..b7b2634963 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -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. */
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 03bca827d1..b5882abe9f 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -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) {
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 50edf466c3..f34e15b1df 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -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 */