summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/libsmb/clifile.c34
-rw-r--r--source3/printing/nt_printing.c10
-rw-r--r--source3/smbd/dir.c4
-rw-r--r--source3/smbd/msdfs.c3
-rw-r--r--source3/smbd/nttrans.c33
-rw-r--r--source3/smbd/reply.c122
-rw-r--r--source3/smbd/trans2.c28
-rw-r--r--source3/torture/torture.c6
8 files changed, 150 insertions, 90 deletions
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index a7e6fbfe3f..ff42e64143 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -1404,19 +1404,29 @@ static BOOL cli_set_ea(struct cli_state *cli, uint16 setup, char *param, unsigne
char *p;
size_t ea_namelen = strlen(ea_name);
- data_len = 4 + 4 + ea_namelen + 1 + ea_len;
- data = SMB_MALLOC(data_len);
- if (!data) {
- return False;
+ if (ea_namelen == 0 && ea_len == 0) {
+ data_len = 4;
+ data = SMB_MALLOC(data_len);
+ if (!data) {
+ return False;
+ }
+ p = data;
+ SIVAL(p,0,data_len);
+ } else {
+ data_len = 4 + 4 + ea_namelen + 1 + ea_len;
+ data = SMB_MALLOC(data_len);
+ if (!data) {
+ return False;
+ }
+ p = data;
+ SIVAL(p,0,data_len);
+ p += 4;
+ SCVAL(p, 0, 0); /* EA flags. */
+ SCVAL(p, 1, ea_namelen);
+ SSVAL(p, 2, ea_len);
+ memcpy(p+4, ea_name, ea_namelen+1); /* Copy in the name. */
+ memcpy(p+4+ea_namelen+1, ea_val, ea_len);
}
- p = data;
- SIVAL(p,0,data_len);
- p += 4;
- SCVAL(p, 0, 0); /* EA flags. */
- SCVAL(p, 1, ea_namelen);
- SSVAL(p, 2, ea_len);
- memcpy(p+4, ea_name, ea_namelen+1); /* Copy in the name. */
- memcpy(p+4+ea_namelen+1, ea_val, ea_len);
if (!cli_send_trans(cli, SMBtrans2,
NULL, /* name */
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index 8061842ad9..09775e60c8 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -4792,7 +4792,7 @@ static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
pstrcpy( file, s );
driver_unix_convert(file, conn, NULL, &bad_path, &st);
DEBUG(10,("deleting driverfile [%s]\n", s));
- unlink_internals(conn, 0, file);
+ unlink_internals(conn, 0, file, False);
}
}
@@ -4801,7 +4801,7 @@ static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
pstrcpy( file, s );
driver_unix_convert(file, conn, NULL, &bad_path, &st);
DEBUG(10,("deleting configfile [%s]\n", s));
- unlink_internals(conn, 0, file);
+ unlink_internals(conn, 0, file, False);
}
}
@@ -4810,7 +4810,7 @@ static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
pstrcpy( file, s );
driver_unix_convert(file, conn, NULL, &bad_path, &st);
DEBUG(10,("deleting datafile [%s]\n", s));
- unlink_internals(conn, 0, file);
+ unlink_internals(conn, 0, file, False);
}
}
@@ -4819,7 +4819,7 @@ static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
pstrcpy( file, s );
driver_unix_convert(file, conn, NULL, &bad_path, &st);
DEBUG(10,("deleting helpfile [%s]\n", s));
- unlink_internals(conn, 0, file);
+ unlink_internals(conn, 0, file, False);
}
}
@@ -4835,7 +4835,7 @@ static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
pstrcpy( file, p );
driver_unix_convert(file, conn, NULL, &bad_path, &st);
DEBUG(10,("deleting dependent file [%s]\n", file));
- unlink_internals(conn, 0, file );
+ unlink_internals(conn, 0, file, False);
}
i++;
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index 70a3b81ad6..7ea97e69b0 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -382,7 +382,7 @@ static void dptr_close_oldest(BOOL old)
****************************************************************************/
int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL expect_close,uint16 spid,
- const char *wcard, uint32 attr)
+ const char *wcard, BOOL wcard_has_wild, uint32 attr)
{
struct dptr_struct *dptr = NULL;
struct smb_Dir *dir_hnd;
@@ -500,7 +500,7 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp
if (lp_posix_pathnames() || (wcard[0] == '.' && wcard[1] == 0)) {
dptr->has_wild = True;
} else {
- dptr->has_wild = ms_has_wild(wcard);
+ dptr->has_wild = wcard_has_wild;
}
dptr->attr = attr;
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 1e6306382a..a4f371b18f 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -114,7 +114,8 @@ static BOOL parse_processed_dfs_path(char* pathname, struct dfs_path *pdp, BOOL
/* rest is reqpath */
if (allow_wcards) {
- check_path_syntax_wcard(pdp->reqpath, p+1);
+ BOOL path_contains_wcard;
+ check_path_syntax_wcard(pdp->reqpath, p+1, &path_contains_wcard);
} else {
check_path_syntax(pdp->reqpath, p+1);
}
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 3db55bad14..91dcc93322 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -541,7 +541,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n",
if(!dir_fsp->is_directory) {
- srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status,False);
+ srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBntcreateX);
return ERROR_NT(status);
@@ -583,14 +583,14 @@ create_options = 0x%x root_dir_fid = 0x%x\n",
dir_name_len++;
}
- srvstr_get_path(inbuf, rel_fname, smb_buf(inbuf), sizeof(rel_fname), 0, STR_TERMINATE, &status,False);
+ srvstr_get_path(inbuf, rel_fname, smb_buf(inbuf), sizeof(rel_fname), 0, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBntcreateX);
return ERROR_NT(status);
}
pstrcat(fname, rel_fname);
} else {
- srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status,False);
+ srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBntcreateX);
return ERROR_NT(status);
@@ -939,7 +939,7 @@ static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, cha
return ERROR_DOS(ERRDOS,ERRnoaccess);
}
- srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status, False);
+ srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
return ERROR_NT(status);
}
@@ -1195,7 +1195,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
}
if(!dir_fsp->is_directory) {
- srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status, False);
+ srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
return ERROR_NT(status);
}
@@ -1229,14 +1229,14 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
{
pstring tmpname;
- srvstr_get_path(inbuf, tmpname, params+53, sizeof(tmpname), parameter_count-53, STR_TERMINATE, &status, False);
+ srvstr_get_path(inbuf, tmpname, params+53, sizeof(tmpname), parameter_count-53, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
return ERROR_NT(status);
}
pstrcat(fname, tmpname);
}
} else {
- srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status, False);
+ srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
return ERROR_NT(status);
}
@@ -1738,13 +1738,14 @@ int reply_ntrename(connection_struct *conn,
pstring newname;
char *p;
NTSTATUS status;
+ BOOL path_contains_wcard = False;
uint32 attrs = SVAL(inbuf,smb_vwv0);
uint16 rename_type = SVAL(inbuf,smb_vwv1);
START_PROFILE(SMBntrename);
p = smb_buf(inbuf) + 1;
- p += srvstr_get_path(inbuf, oldname, p, sizeof(oldname), 0, STR_TERMINATE, &status, True);
+ p += srvstr_get_path_wcard(inbuf, oldname, p, sizeof(oldname), 0, STR_TERMINATE, &status, &path_contains_wcard);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBntrename);
return ERROR_NT(status);
@@ -1762,7 +1763,7 @@ int reply_ntrename(connection_struct *conn,
}
p++;
- p += srvstr_get_path(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status, False);
+ p += srvstr_get_path(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBntrename);
return ERROR_NT(status);
@@ -1775,13 +1776,18 @@ int reply_ntrename(connection_struct *conn,
switch(rename_type) {
case RENAME_FLAG_RENAME:
- status = rename_internals(conn, oldname, newname, attrs, False);
+ status = rename_internals(conn, oldname, newname, attrs, False, path_contains_wcard);
break;
case RENAME_FLAG_HARD_LINK:
status = hardlink_internals(conn, oldname, newname);
break;
case RENAME_FLAG_COPY:
- status = copy_internals(conn, oldname, newname, attrs);
+ if (path_contains_wcard) {
+ /* No wildcards. */
+ status = NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
+ } else {
+ status = copy_internals(conn, oldname, newname, attrs);
+ }
break;
case RENAME_FLAG_MOVE_CLUSTER_INFORMATION:
status = NT_STATUS_INVALID_PARAMETER;
@@ -1878,6 +1884,7 @@ static int call_nt_transact_rename(connection_struct *conn, char *inbuf, char *o
pstring new_name;
files_struct *fsp = NULL;
BOOL replace_if_exists = False;
+ BOOL path_contains_wcard = False;
NTSTATUS status;
if(parameter_count < 4) {
@@ -1887,13 +1894,13 @@ static int call_nt_transact_rename(connection_struct *conn, char *inbuf, char *o
fsp = file_fsp(params, 0);
replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False;
CHECK_FSP(fsp, conn);
- srvstr_get_path(inbuf, new_name, params+4, sizeof(new_name), -1, STR_TERMINATE, &status, True);
+ srvstr_get_path_wcard(inbuf, new_name, params+4, sizeof(new_name), -1, STR_TERMINATE, &status, &path_contains_wcard);
if (!NT_STATUS_IS_OK(status)) {
return ERROR_NT(status);
}
status = rename_internals(conn, fsp->fsp_name,
- new_name, 0, replace_if_exists);
+ new_name, 0, replace_if_exists, path_contains_wcard);
if (!NT_STATUS_IS_OK(status))
return ERROR_NT(status);
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index beed90f9aa..f73eea3fa6 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -172,7 +172,7 @@ NTSTATUS check_path_syntax(pstring destname, const pstring srcname)
set.
****************************************************************************/
-NTSTATUS check_path_syntax_wcard(pstring destname, const pstring srcname)
+NTSTATUS check_path_syntax_wcard(pstring destname, const pstring srcname, BOOL *p_contains_wcard)
{
char *d = destname;
const char *s = srcname;
@@ -180,6 +180,8 @@ NTSTATUS check_path_syntax_wcard(pstring destname, const pstring srcname)
BOOL start_of_name_component = True;
unsigned int num_bad_components = 0;
+ *p_contains_wcard = False;
+
while (*s) {
if (IS_DIRECTORY_SEP(*s)) {
/*
@@ -249,6 +251,19 @@ NTSTATUS check_path_syntax_wcard(pstring destname, const pstring srcname)
if (*s <= 0x1f) {
return NT_STATUS_OBJECT_NAME_INVALID;
}
+ if (!*p_contains_wcard) {
+ switch (*s) {
+ case '*':
+ case '?':
+ case '<':
+ case '>':
+ case '"':
+ *p_contains_wcard = True;
+ break;
+ default:
+ break;
+ }
+ }
*d++ = *s++;
} else {
switch(next_mb_char_size(s)) {
@@ -380,10 +395,40 @@ NTSTATUS check_path_syntax_posix(pstring destname, const pstring srcname)
}
/****************************************************************************
+ Pull a string and check the path allowing a wilcard - provide for error return.
+****************************************************************************/
+
+size_t srvstr_get_path_wcard(char *inbuf, char *dest, const char *src, size_t dest_len, size_t src_len, int flags,
+ NTSTATUS *err, BOOL *contains_wcard)
+{
+ pstring tmppath;
+ char *tmppath_ptr = tmppath;
+ size_t ret;
+#ifdef DEVELOPER
+ SMB_ASSERT(dest_len == sizeof(pstring));
+#endif
+
+ if (src_len == 0) {
+ ret = srvstr_pull_buf( inbuf, tmppath_ptr, src, dest_len, flags);
+ } else {
+ ret = srvstr_pull( inbuf, tmppath_ptr, src, dest_len, src_len, flags);
+ }
+
+ *contains_wcard = False;
+
+ if (lp_posix_pathnames()) {
+ *err = check_path_syntax_posix(dest, tmppath);
+ } else {
+ *err = check_path_syntax_wcard(dest, tmppath, contains_wcard);
+ }
+ return ret;
+}
+
+/****************************************************************************
Pull a string and check the path - provide for error return.
****************************************************************************/
-size_t srvstr_get_path(char *inbuf, char *dest, const char *src, size_t dest_len, size_t src_len, int flags, NTSTATUS *err, BOOL allow_wcard_names)
+size_t srvstr_get_path(char *inbuf, char *dest, const char *src, size_t dest_len, size_t src_len, int flags, NTSTATUS *err)
{
pstring tmppath;
char *tmppath_ptr = tmppath;
@@ -399,8 +444,6 @@ size_t srvstr_get_path(char *inbuf, char *dest, const char *src, size_t dest_len
}
if (lp_posix_pathnames()) {
*err = check_path_syntax_posix(dest, tmppath);
- } else if (allow_wcard_names) {
- *err = check_path_syntax_wcard(dest, tmppath);
} else {
*err = check_path_syntax(dest, tmppath);
}
@@ -754,7 +797,7 @@ int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
START_PROFILE(SMBchkpth);
- srvstr_get_path(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), 0, STR_TERMINATE, &status, False);
+ srvstr_get_path(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), 0, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBchkpth);
return ERROR_NT(status);
@@ -826,7 +869,7 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
START_PROFILE(SMBgetatr);
p = smb_buf(inbuf) + 1;
- p += srvstr_get_path(inbuf, fname, p, sizeof(fname), 0, STR_TERMINATE, &status, False);
+ p += srvstr_get_path(inbuf, fname, p, sizeof(fname), 0, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBgetatr);
return ERROR_NT(status);
@@ -905,7 +948,7 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
START_PROFILE(SMBsetatr);
p = smb_buf(inbuf) + 1;
- p += srvstr_get_path(inbuf, fname, p, sizeof(fname), 0, STR_TERMINATE, &status, False);
+ p += srvstr_get_path(inbuf, fname, p, sizeof(fname), 0, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBsetatr);
return ERROR_NT(status);
@@ -1031,6 +1074,7 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
BOOL can_open = True;
BOOL bad_path = False;
NTSTATUS nt_status;
+ BOOL mask_contains_wcard = False;
BOOL allow_long_path_components = (SVAL(inbuf,smb_flg2) & FLAGS2_LONG_PATH_COMPONENTS) ? True : False;
if (lp_posix_pathnames()) {
@@ -1049,7 +1093,7 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
maxentries = SVAL(inbuf,smb_vwv0);
dirtype = SVAL(inbuf,smb_vwv1);
p = smb_buf(inbuf) + 1;
- p += srvstr_get_path(inbuf, path, p, sizeof(path), 0, STR_TERMINATE, &nt_status, True);
+ p += srvstr_get_path_wcard(inbuf, path, p, sizeof(path), 0, STR_TERMINATE, &nt_status, &mask_contains_wcard);
if (!NT_STATUS_IS_OK(nt_status)) {
END_PROFILE(SMBsearch);
return ERROR_NT(nt_status);
@@ -1114,7 +1158,7 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
ok = True;
if (status_len == 0) {
- dptr_num = dptr_create(conn,directory,True,expect_close,SVAL(inbuf,smb_pid), mask, dirtype);
+ dptr_num = dptr_create(conn,directory,True,expect_close,SVAL(inbuf,smb_pid), mask, mask_contains_wcard, dirtype);
if (dptr_num < 0) {
if(dptr_num == -2) {
END_PROFILE(SMBsearch);
@@ -1185,7 +1229,7 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
dptr_close(&dptr_num);
}
- if ((numentries == 0) && !ms_has_wild(mask)) {
+ if ((numentries == 0) && !mask_contains_wcard) {
return ERROR_BOTH(STATUS_NO_MORE_FILES,ERRDOS,ERRnofiles);
}
@@ -1230,6 +1274,7 @@ int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
int dptr_num= -2;
char *p;
NTSTATUS err;
+ BOOL path_contains_wcard = False;
if (lp_posix_pathnames()) {
return reply_unknown(inbuf, outbuf);
@@ -1239,7 +1284,7 @@ int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
outsize = set_message(outbuf,1,0,True);
p = smb_buf(inbuf) + 1;
- p += srvstr_get_path(inbuf, path, p, sizeof(path), 0, STR_TERMINATE, &err, True);
+ p += srvstr_get_path_wcard(inbuf, path, p, sizeof(path), 0, STR_TERMINATE, &err, &path_contains_wcard);
if (!NT_STATUS_IS_OK(err)) {
END_PROFILE(SMBfclose);
return ERROR_NT(err);
@@ -1295,7 +1340,7 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
deny_mode = SVAL(inbuf,smb_vwv0);
- srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status, False);
+ srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBopen);
return ERROR_NT(status);
@@ -1415,7 +1460,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
}
/* XXXX we need to handle passed times, sattr and flags */
- srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status, False);
+ srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBopenX);
return ERROR_NT(status);
@@ -1586,7 +1631,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
com = SVAL(inbuf,smb_com);
- srvstr_get_path(inbuf, fname, smb_buf(inbuf) + 1, sizeof(fname), 0, STR_TERMINATE, &status, False);
+ srvstr_get_path(inbuf, fname, smb_buf(inbuf) + 1, sizeof(fname), 0, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBcreate);
return ERROR_NT(status);
@@ -1669,7 +1714,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
START_PROFILE(SMBctemp);
- srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status, False);
+ srvstr_get_path(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), 0, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBctemp);
return ERROR_NT(status);
@@ -1889,30 +1934,19 @@ NTSTATUS can_delete(connection_struct *conn, char *fname, uint32 dirtype, BOOL b
code.
****************************************************************************/
-NTSTATUS unlink_internals(connection_struct *conn, uint32 dirtype, char *name)
+NTSTATUS unlink_internals(connection_struct *conn, uint32 dirtype, char *name, BOOL has_wild)
{
pstring directory;
pstring mask;
char *p;
int count=0;
NTSTATUS error = NT_STATUS_OK;
- BOOL has_wild;
BOOL bad_path = False;
BOOL rc = True;
SMB_STRUCT_STAT sbuf;
*directory = *mask = 0;
- /* We must check for wildcards in the name given
- * directly by the client - before any unmangling.
- * This prevents an unmangling of a UNIX name containing
- * a DOS wildcard like '*' or '?' from unmangling into
- * a wildcard delete which was not intended.
- * FIX for #226. JRA.
- */
-
- has_wild = ms_has_wild(name);
-
rc = unix_convert(name,conn,0,&bad_path,&sbuf);
p = strrchr_m(name,'/');
@@ -2029,10 +2063,11 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
uint32 dirtype;
NTSTATUS status;
START_PROFILE(SMBunlink);
-
+ BOOL path_contains_wcard = False;
+
dirtype = SVAL(inbuf,smb_vwv0);
- srvstr_get_path(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), 0, STR_TERMINATE, &status, True);
+ srvstr_get_path_wcard(inbuf, name, smb_buf(inbuf) + 1, sizeof(name), 0, STR_TERMINATE, &status, &path_contains_wcard);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBunlink);
return ERROR_NT(status);
@@ -2042,7 +2077,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
DEBUG(3,("reply_unlink : %s\n",name));
- status = unlink_internals(conn, dirtype, name);
+ status = unlink_internals(conn, dirtype, name, path_contains_wcard);
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
/* We have re-scheduled this call. */
@@ -3721,7 +3756,7 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
START_PROFILE(SMBmkdir);
- srvstr_get_path(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), 0, STR_TERMINATE, &status, False);
+ srvstr_get_path(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), 0, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBmkdir);
return ERROR_NT(status);
@@ -3925,7 +3960,7 @@ int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
NTSTATUS status;
START_PROFILE(SMBrmdir);
- srvstr_get_path(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), 0, STR_TERMINATE, &status, False);
+ srvstr_get_path(inbuf, directory, smb_buf(inbuf) + 1, sizeof(directory), 0, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBrmdir);
return ERROR_NT(status);
@@ -4216,14 +4251,13 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, char *
code.
****************************************************************************/
-NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, uint32 attrs, BOOL replace_if_exists)
+NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, uint32 attrs, BOOL replace_if_exists, BOOL has_wild)
{
pstring directory;
pstring mask;
pstring last_component_src;
pstring last_component_dest;
char *p;
- BOOL has_wild;
BOOL bad_path_src = False;
BOOL bad_path_dest = False;
int count=0;
@@ -4292,8 +4326,6 @@ NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, ui
if (!rc && mangle_is_mangled(mask,SNUM(conn)))
mangle_check_cache( mask, sizeof(pstring)-1, SNUM(conn));
- has_wild = ms_has_wild(mask);
-
if (!has_wild) {
/*
* No wildcards - just process the one file.
@@ -4559,17 +4591,18 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
char *p;
uint32 attrs = SVAL(inbuf,smb_vwv0);
NTSTATUS status;
+ BOOL path_contains_wcard = False;
START_PROFILE(SMBmv);
p = smb_buf(inbuf) + 1;
- p += srvstr_get_path(inbuf, name, p, sizeof(name), 0, STR_TERMINATE, &status, True);
+ p += srvstr_get_path_wcard(inbuf, name, p, sizeof(name), 0, STR_TERMINATE, &status, &path_contains_wcard);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBmv);
return ERROR_NT(status);
}
p++;
- p += srvstr_get_path(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status, True);
+ p += srvstr_get_path(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBmv);
return ERROR_NT(status);
@@ -4580,7 +4613,7 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
- status = rename_internals(conn, name, newname, attrs, False);
+ status = rename_internals(conn, name, newname, attrs, False, path_contains_wcard);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBmv);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
@@ -4727,21 +4760,22 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
BOOL target_is_directory=False;
BOOL bad_path1 = False;
BOOL bad_path2 = False;
+ BOOL path_contains_wcard1 = False;
+ BOOL path_contains_wcard2 = False;
BOOL rc = True;
SMB_STRUCT_STAT sbuf1, sbuf2;
NTSTATUS status;
-
START_PROFILE(SMBcopy);
*directory = *mask = 0;
p = smb_buf(inbuf);
- p += srvstr_get_path(inbuf, name, p, sizeof(name), 0, STR_TERMINATE, &status, True);
+ p += srvstr_get_path_wcard(inbuf, name, p, sizeof(name), 0, STR_TERMINATE, &status, &path_contains_wcard1);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBcopy);
return ERROR_NT(status);
}
- p += srvstr_get_path(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status, True);
+ p += srvstr_get_path_wcard(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status, &path_contains_wcard2);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBcopy);
return ERROR_NT(status);
@@ -4803,7 +4837,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
if (!rc && mangle_is_mangled(mask, SNUM(conn)))
mangle_check_cache( mask, sizeof(pstring)-1, SNUM(conn));
- has_wild = ms_has_wild(mask);
+ has_wild = path_contains_wcard1;
if (!has_wild) {
pstrcat(directory,"/");
@@ -4904,7 +4938,7 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
return ERROR_DOS(ERRDOS,ERRnoaccess);
}
- srvstr_get_path(inbuf, newdir, smb_buf(inbuf) + 1, sizeof(newdir), 0, STR_TERMINATE, &status, False);
+ srvstr_get_path(inbuf, newdir, smb_buf(inbuf) + 1, sizeof(newdir), 0, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(pathworks_setdir);
return ERROR_NT(status);
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index f04e6c78f0..a9b67cc484 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -775,7 +775,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
return(ERROR_DOS(ERRSRV,ERRaccess));
}
- srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status, False);
+ srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
return ERROR_NT(status);
}
@@ -1614,6 +1614,7 @@ static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outb
BOOL out_of_space = False;
int space_remaining;
BOOL bad_path = False;
+ BOOL mask_contains_wcard = False;
SMB_STRUCT_STAT sbuf;
TALLOC_CTX *ea_ctx = NULL;
struct ea_list *ea_list = NULL;
@@ -1654,7 +1655,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
return(ERROR_DOS(ERRDOS,ERRunknownlevel));
}
- srvstr_get_path(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE, &ntstatus, True);
+ srvstr_get_path_wcard(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE, &ntstatus, &mask_contains_wcard);
if (!NT_STATUS_IS_OK(ntstatus)) {
return ERROR_NT(ntstatus);
}
@@ -1672,10 +1673,12 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
p = strrchr_m(directory,'/');
if(p == NULL) {
/* Windows and OS/2 systems treat search on the root '\' as if it were '\*' */
- if((directory[0] == '.') && (directory[1] == '\0'))
+ if((directory[0] == '.') && (directory[1] == '\0')) {
pstrcpy(mask,"*");
- else
+ mask_contains_wcard = True;
+ } else {
pstrcpy(mask,directory);
+ }
pstrcpy(directory,"./");
} else {
pstrcpy(mask,p+1);
@@ -1733,7 +1736,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
/* Save the wildcard match and attribs we are using on this directory -
needed as lanman2 assumes these are being saved between calls */
- dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid), mask, dirtype);
+ dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid), mask, mask_contains_wcard, dirtype);
if (dptr_num < 0) {
talloc_destroy(ea_ctx);
return(UNIXERROR(ERRDOS,ERRbadfile));
@@ -1868,6 +1871,7 @@ static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbu
BOOL close_if_end = (findnext_flags & FLAG_TRANS2_FIND_CLOSE_IF_END);
BOOL requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
BOOL continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
+ BOOL mask_contains_wcard = False;
pstring resume_name;
pstring mask;
pstring directory;
@@ -1889,7 +1893,7 @@ static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbu
*mask = *directory = *resume_name = 0;
- srvstr_get_path(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE, &ntstatus, True);
+ srvstr_get_path_wcard(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE, &ntstatus, &mask_contains_wcard);
if (!NT_STATUS_IS_OK(ntstatus)) {
/* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
complain (it thinks we're asking for the directory above the shared
@@ -2854,7 +2858,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
- srvstr_get_path(inbuf, fname, &params[6], sizeof(fname), -1, STR_TERMINATE, &status, False);
+ srvstr_get_path(inbuf, fname, &params[6], sizeof(fname), -1, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
return ERROR_NT(status);
}
@@ -3659,7 +3663,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
}
info_level = SVAL(params,0);
- srvstr_get_path(inbuf, fname, &params[6], sizeof(fname), -1, STR_TERMINATE, &status, False);
+ srvstr_get_path(inbuf, fname, &params[6], sizeof(fname), -1, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
return ERROR_NT(status);
}
@@ -4217,7 +4221,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
char *newname = fname;
/* Set a hard link. */
- srvstr_get_path(inbuf, oldname, pdata, sizeof(oldname), -1, STR_TERMINATE, &status, False);
+ srvstr_get_path(inbuf, oldname, pdata, sizeof(oldname), -1, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
return ERROR_NT(status);
}
@@ -4251,7 +4255,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
overwrite = (CVAL(pdata,0) ? True : False);
root_fid = IVAL(pdata,4);
len = IVAL(pdata,8);
- srvstr_get_path(inbuf, newname, &pdata[12], sizeof(newname), len, 0, &status, False);
+ srvstr_get_path(inbuf, newname, &pdata[12], sizeof(newname), len, 0, &status);
if (!NT_STATUS_IS_OK(status)) {
return ERROR_NT(status);
}
@@ -4278,7 +4282,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
} else {
DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
fname, newname ));
- status = rename_internals(conn, fname, base_name, 0, overwrite);
+ status = rename_internals(conn, fname, base_name, 0, overwrite, False);
}
if (!NT_STATUS_IS_OK(status)) {
return ERROR_NT(status);
@@ -4489,7 +4493,7 @@ static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf,
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
- srvstr_get_path(inbuf, directory, &params[4], sizeof(directory), -1, STR_TERMINATE, &status, False);
+ srvstr_get_path(inbuf, directory, &params[4], sizeof(directory), -1, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
return ERROR_NT(status);
}
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index 8ad567f177..0bd9aa1728 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -4424,6 +4424,9 @@ static BOOL run_eatest(int dummy)
/* Setting EA's to zero length deletes them. Test this */
printf("Now deleting all EA's - case indepenent....\n");
+#if 1
+ cli_set_ea_path(cli, fname, "", "", 0);
+#else
for (i = 0; i < 20; i++) {
fstring ea_name;
slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
@@ -4432,7 +4435,8 @@ static BOOL run_eatest(int dummy)
return False;
}
}
-
+#endif
+
if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
printf("ea_get list failed - %s\n", cli_errstr(cli));
correct = False;