diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/smbd/reply.c | 41 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 6 |
2 files changed, 34 insertions, 13 deletions
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 643b7c2d08..836f95e179 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3357,16 +3357,20 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, char * pstring newname_last_component; NTSTATUS error = NT_STATUS_OK; BOOL dest_exists; + BOOL rcdest = True; ZERO_STRUCT(sbuf); - unix_convert(newname,conn,newname_last_component,&bad_path,&sbuf); + rcdest = unix_convert(newname,conn,newname_last_component,&bad_path,&sbuf); /* Quick check for "." and ".." */ - if (newname_last_component[0] == '.') { + if (!bad_path && newname_last_component[0] == '.') { if (!newname_last_component[1] || (newname_last_component[1] == '.' && !newname_last_component[2])) { return NT_STATUS_ACCESS_DENIED; } } + if (!rcdest && bad_path) { + return NT_STATUS_OBJECT_PATH_NOT_FOUND; + } /* Ensure newname contains a '/' */ if(strrchr_m(newname,'/') == 0) { @@ -3472,6 +3476,7 @@ NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, BO int count=0; NTSTATUS error = NT_STATUS_OK; BOOL rc = True; + BOOL rcdest = True; SMB_STRUCT_STAT sbuf1, sbuf2; *directory = *mask = 0; @@ -3479,15 +3484,7 @@ NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, BO ZERO_STRUCT(sbuf1); ZERO_STRUCT(sbuf2); rc = unix_convert(name,conn,0,&bad_path1,&sbuf1); - unix_convert(newname,conn,newname_last_component,&bad_path2,&sbuf2); - - /* Quick check for "." and ".." */ - if (!bad_path2 && newname_last_component[0] == '.') { - if (!newname_last_component[1] || (newname_last_component[1] == '.' && !newname_last_component[2])) { - DEBUG(10,("rename_internals: newname_last_component = '.' or '..'\n")); - return NT_STATUS_ACCESS_DENIED; - } - } + rcdest = unix_convert(newname,conn,newname_last_component,&bad_path2,&sbuf2); /* * Split the old name into directory and last component @@ -3612,6 +3609,17 @@ directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n", return error; } + /* Quick check for "." and ".." */ + if (!bad_path2 && newname_last_component[0] == '.') { + if (!newname_last_component[1] || (newname_last_component[1] == '.' && !newname_last_component[2])) { + DEBUG(10,("rename_internals: newname_last_component = '.' or '..'\n")); + return NT_STATUS_ACCESS_DENIED; + } + } + if (!rcdest && bad_path2) { + return NT_STATUS_OBJECT_PATH_NOT_FOUND; + } + error = can_rename(directory,conn,&sbuf1); if (!NT_STATUS_IS_OK(error)) { @@ -3661,6 +3669,17 @@ directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n", const char *dname; pstring destname; + /* Quick check for "." and ".." */ + if (!bad_path2 && newname_last_component[0] == '.') { + if (!newname_last_component[1] || (newname_last_component[1] == '.' && !newname_last_component[2])) { + DEBUG(10,("rename_internals: newname_last_component = '.' or '..'\n")); + return NT_STATUS_ACCESS_DENIED; + } + } + if (!rcdest && bad_path2) { + return NT_STATUS_OBJECT_PATH_NOT_FOUND; + } + if (check_name(directory,conn)) dirptr = OpenDir(conn, directory, True); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 63130aa8d8..5fbc5ce6ee 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -1830,6 +1830,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, SMB_OFF_T file_size=0; SMB_BIG_UINT allocation_size=0; unsigned int data_size; + unsigned int param_size = 2; SMB_STRUCT_STAT sbuf; pstring fname, dos_fname; char *fullpathname; @@ -1932,7 +1933,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno))); return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath); } - } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf)) { + } else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf) && (info_level != SMB_INFO_IS_NAME_VALID)) { DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno))); return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath); } @@ -2016,6 +2017,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, return ERROR_DOS(ERRDOS,ERRbadfunc); } data_size = 0; + param_size = 0; break; case SMB_INFO_QUERY_EAS_FROM_LIST: @@ -2322,7 +2324,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn, return ERROR_DOS(ERRDOS,ERRunknownlevel); } - send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, data_size); + send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size); return(-1); } |