From 6baec64a7370ff1871f0b806a623b1fc1a898acb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 31 Oct 2005 20:11:58 +0000 Subject: r11420: Fix issue pointed out by Dina Fine . We can only tell at parse time from the wire if an incoming name has wildcards or not. If it's a mangled name and we demangle the demangled name may contain wildcard characters. Ensure these are ignored. Jeremy. (This used to be commit 4cd8e2a96b98ff711905e8c6f416b22440c16062) --- source3/smbd/dir.c | 4 +- source3/smbd/msdfs.c | 3 +- source3/smbd/nttrans.c | 33 +++++++------ source3/smbd/reply.c | 122 +++++++++++++++++++++++++++++++------------------ source3/smbd/trans2.c | 28 +++++++----- 5 files changed, 118 insertions(+), 72 deletions(-) (limited to 'source3/smbd') 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)) { @@ -379,11 +394,41 @@ NTSTATUS check_path_syntax_posix(pstring destname, const pstring srcname) return ret; } +/**************************************************************************** + 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, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status, False); + srvstr_get_path(inbuf, fname, ¶ms[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, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status, False); + srvstr_get_path(inbuf, fname, ¶ms[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, ¶ms[4], sizeof(directory), -1, STR_TERMINATE, &status, False); + srvstr_get_path(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { return ERROR_NT(status); } -- cgit