mirror of
https://github.com/samba-team/samba.git
synced 2025-02-26 21:57:41 +03:00
Implemented the level 1010 NT rename level. Many fixes for Samba4 test
correctness. Jeremy. (This used to be commit f57429befa43d63ed9a6e19b854e22fd4151db40)
This commit is contained in:
parent
bd886acab8
commit
3a052c9e0a
@ -200,6 +200,18 @@ void file_close_user(int vuid)
|
||||
}
|
||||
}
|
||||
|
||||
void file_dump_open_table(void)
|
||||
{
|
||||
int count=0;
|
||||
files_struct *fsp;
|
||||
|
||||
for (fsp=Files;fsp;fsp=fsp->next,count++) {
|
||||
DEBUG(10,("Files[%d], fnum = %d, name %s, fd = %d, fileid = %lu, dev = %x, inode = %.0f\n",
|
||||
count, fsp->fnum, fsp->fsp_name, fsp->fd, (unsigned long)fsp->file_id,
|
||||
(unsigned int)fsp->dev, (double)fsp->inode ));
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Find a fsp given a file descriptor.
|
||||
****************************************************************************/
|
||||
|
@ -762,9 +762,8 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
|
||||
restore_case_semantics(file_attributes);
|
||||
|
||||
if(!fsp) {
|
||||
set_bad_path_error(errno, bad_path);
|
||||
END_PROFILE(SMBntcreateX);
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
@ -838,16 +837,14 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
|
||||
|
||||
if(!fsp) {
|
||||
restore_case_semantics(file_attributes);
|
||||
set_bad_path_error(errno, bad_path);
|
||||
END_PROFILE(SMBntcreateX);
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
|
||||
}
|
||||
} else {
|
||||
|
||||
restore_case_semantics(file_attributes);
|
||||
set_bad_path_error(errno, bad_path);
|
||||
END_PROFILE(SMBntcreateX);
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1279,8 +1276,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
|
||||
|
||||
if(!fsp) {
|
||||
restore_case_semantics(file_attributes);
|
||||
set_bad_path_error(errno, bad_path);
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -1312,13 +1308,11 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
|
||||
|
||||
if(!fsp) {
|
||||
restore_case_semantics(file_attributes);
|
||||
set_bad_path_error(errno, bad_path);
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
|
||||
}
|
||||
} else {
|
||||
restore_case_semantics(file_attributes);
|
||||
set_bad_path_error(errno, bad_path);
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -497,9 +497,8 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
set_bad_path_error(errno, bad_path);
|
||||
END_PROFILE(SMBgetatr);
|
||||
return(UNIXERROR(ERRDOS,ERRbadfile));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadfile);
|
||||
}
|
||||
|
||||
outsize = set_message(outbuf,10,0,True);
|
||||
@ -560,9 +559,8 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
|
||||
ok = set_filetime(conn,fname,mtime);
|
||||
|
||||
if (!ok) {
|
||||
set_bad_path_error(errno, bad_path);
|
||||
END_PROFILE(SMBsetatr);
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
|
||||
}
|
||||
|
||||
outsize = set_message(outbuf,0,0,True);
|
||||
@ -723,9 +721,8 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
|
||||
dptr_num = dptr_create(conn,directory,True,expect_close,SVAL(inbuf,smb_pid));
|
||||
if (dptr_num < 0) {
|
||||
if(dptr_num == -2) {
|
||||
set_bad_path_error(errno, bad_path);
|
||||
END_PROFILE(SMBsearch);
|
||||
return (UNIXERROR(ERRDOS,ERRnofids));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnofids);
|
||||
}
|
||||
END_PROFILE(SMBsearch);
|
||||
return ERROR_DOS(ERRDOS,ERRnofids);
|
||||
@ -890,9 +887,8 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
unixmode, oplock_request,&rmode,NULL);
|
||||
|
||||
if (!fsp) {
|
||||
set_bad_path_error(errno, bad_path);
|
||||
END_PROFILE(SMBopen);
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
|
||||
}
|
||||
|
||||
size = sbuf.st_size;
|
||||
@ -978,9 +974,8 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
|
||||
oplock_request, &rmode,&smb_action);
|
||||
|
||||
if (!fsp) {
|
||||
set_bad_path_error(errno, bad_path);
|
||||
END_PROFILE(SMBopenX);
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
|
||||
}
|
||||
|
||||
size = sbuf.st_size;
|
||||
@ -1102,9 +1097,8 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
ofun, unixmode, oplock_request, NULL, NULL);
|
||||
|
||||
if (!fsp) {
|
||||
set_bad_path_error(errno, bad_path);
|
||||
END_PROFILE(SMBcreate);
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
|
||||
}
|
||||
|
||||
outsize = set_message(outbuf,1,0,True);
|
||||
@ -1171,9 +1165,8 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
close(tmpfd);
|
||||
|
||||
if (!fsp) {
|
||||
set_bad_path_error(errno, bad_path);
|
||||
END_PROFILE(SMBctemp);
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRnoaccess);
|
||||
}
|
||||
|
||||
outsize = set_message(outbuf,1,0,True);
|
||||
@ -1268,8 +1261,10 @@ static NTSTATUS can_delete(char *fname,connection_struct *conn, int dirtype)
|
||||
/* Can't delete a directory. */
|
||||
if (fmode & aDIR)
|
||||
return NT_STATUS_FILE_IS_A_DIRECTORY;
|
||||
#if 0 /* JRATEST */
|
||||
else if (dirtype & aDIR) /* Asked for a directory and it isn't. */
|
||||
return NT_STATUS_OBJECT_NAME_INVALID;
|
||||
#endif /* JRATEST */
|
||||
|
||||
if (!lp_delete_readonly(SNUM(conn))) {
|
||||
if (fmode & aRONLY)
|
||||
@ -2885,7 +2880,17 @@ NTSTATUS mkdir_internal(connection_struct *conn, pstring directory)
|
||||
ret = vfs_MkDir(conn,directory,unix_mode(conn,aDIR,directory));
|
||||
|
||||
if (ret == -1) {
|
||||
NTSTATUS nterr = set_bad_path_error(errno, bad_path);
|
||||
NTSTATUS nterr = NT_STATUS_OK;
|
||||
if(errno == ENOENT) {
|
||||
unix_ERR_class = ERRDOS;
|
||||
if (bad_path) {
|
||||
unix_ERR_code = ERRbadpath;
|
||||
nterr = NT_STATUS_OBJECT_PATH_NOT_FOUND;
|
||||
} else {
|
||||
unix_ERR_code = ERRbadfile;
|
||||
nterr = NT_STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
if (!NT_STATUS_IS_OK(nterr))
|
||||
return nterr;
|
||||
return map_nt_error_from_unix(errno);
|
||||
@ -3080,9 +3085,8 @@ int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
set_bad_path_error(errno, bad_path);
|
||||
END_PROFILE(SMBrmdir);
|
||||
return(UNIXERROR(ERRDOS,ERRbadpath));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS, ERRbadpath);
|
||||
}
|
||||
|
||||
outsize = set_message(outbuf,0,0,True);
|
||||
@ -3165,6 +3169,130 @@ static BOOL resolve_wildcards(const char *name1, char *name2)
|
||||
return(True);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Ensure open files have their names updates.
|
||||
****************************************************************************/
|
||||
|
||||
static void rename_open_files(connection_struct *conn, SMB_DEV_T dev, SMB_INO_T inode, char *newname)
|
||||
{
|
||||
files_struct *fsp;
|
||||
BOOL did_rename = False;
|
||||
|
||||
for(fsp = file_find_di_first(dev, inode); fsp; fsp = file_find_di_next(fsp)) {
|
||||
DEBUG(10,("rename_open_files: renaming file fnum %d (dev = %x, inode = %.0f) from %s -> %s\n",
|
||||
fsp->fnum, (unsigned int)fsp->dev, (double)fsp->inode,
|
||||
fsp->fsp_name, newname ));
|
||||
string_set(&fsp->fsp_name, newname);
|
||||
did_rename = True;
|
||||
}
|
||||
|
||||
if (!did_rename)
|
||||
DEBUG(10,("rename_open_files: no open files on dev %x, inode %.0f for %s\n",
|
||||
(unsigned int)dev, (double)inode, newname ));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Rename an open file - given an fsp.
|
||||
****************************************************************************/
|
||||
|
||||
NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, char *newname, BOOL replace_if_exists)
|
||||
{
|
||||
SMB_STRUCT_STAT sbuf;
|
||||
BOOL bad_path = False;
|
||||
pstring newname_last_component;
|
||||
NTSTATUS error = NT_STATUS_OK;
|
||||
BOOL dest_exists;
|
||||
|
||||
ZERO_STRUCT(sbuf);
|
||||
unix_convert(newname,conn,newname_last_component,&bad_path,&sbuf);
|
||||
|
||||
/* Ensure newname contains a '/' */
|
||||
if(strrchr_m(newname,'/') == 0) {
|
||||
pstring tmpstr;
|
||||
|
||||
pstrcpy(tmpstr, "./");
|
||||
pstrcat(tmpstr, newname);
|
||||
pstrcpy(newname, tmpstr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for special case with case preserving and not
|
||||
* case sensitive. If the old last component differs from the original
|
||||
* last component only by case, then we should allow
|
||||
* the rename (user is trying to change the case of the
|
||||
* filename).
|
||||
*/
|
||||
|
||||
if((case_sensitive == False) && (case_preserve == True) &&
|
||||
strequal(newname, fsp->fsp_name)) {
|
||||
char *p;
|
||||
pstring newname_modified_last_component;
|
||||
|
||||
/*
|
||||
* Get the last component of the modified name.
|
||||
* Note that we guarantee that newname contains a '/'
|
||||
* character above.
|
||||
*/
|
||||
p = strrchr_m(newname,'/');
|
||||
pstrcpy(newname_modified_last_component,p+1);
|
||||
|
||||
if(strcsequal(newname_modified_last_component,
|
||||
newname_last_component) == False) {
|
||||
/*
|
||||
* Replace the modified last component with
|
||||
* the original.
|
||||
*/
|
||||
pstrcpy(p+1, newname_last_component);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the src and dest names are identical - including case,
|
||||
* don't do the rename, just return success.
|
||||
*/
|
||||
|
||||
if (strcsequal(fsp->fsp_name, newname)) {
|
||||
DEBUG(3,("rename_internals_fsp: identical names in rename %s - returning success\n",
|
||||
newname));
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
dest_exists = vfs_object_exist(conn,newname,NULL);
|
||||
|
||||
if(!replace_if_exists && dest_exists) {
|
||||
DEBUG(3,("rename_internals_fsp: dest exists doing rename %s -> %s\n",
|
||||
fsp->fsp_name,newname));
|
||||
return NT_STATUS_OBJECT_NAME_COLLISION;
|
||||
}
|
||||
|
||||
error = can_rename(newname,conn,&sbuf);
|
||||
|
||||
if (dest_exists && !NT_STATUS_IS_OK(error)) {
|
||||
DEBUG(3,("rename_internals: Error %s rename %s -> %s\n",
|
||||
nt_errstr(error), fsp->fsp_name,newname));
|
||||
if (NT_STATUS_EQUAL(error,NT_STATUS_SHARING_VIOLATION))
|
||||
error = NT_STATUS_ACCESS_DENIED;
|
||||
return error;
|
||||
}
|
||||
|
||||
if(SMB_VFS_RENAME(conn,fsp->fsp_name, newname) == 0) {
|
||||
DEBUG(3,("rename_internals_fsp: succeeded doing rename on %s -> %s\n",
|
||||
fsp->fsp_name,newname));
|
||||
rename_open_files(conn, fsp->dev, fsp->inode, newname);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
if (errno == ENOTDIR || errno == EISDIR)
|
||||
error = NT_STATUS_OBJECT_NAME_COLLISION;
|
||||
else
|
||||
error = map_nt_error_from_unix(errno);
|
||||
|
||||
DEBUG(3,("rename_internals_fsp: Error %s rename %s -> %s\n",
|
||||
nt_errstr(error), fsp->fsp_name,newname));
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
The guts of the rename command, split out so it may be called by the NT SMB
|
||||
code.
|
||||
@ -3186,6 +3314,8 @@ NTSTATUS rename_internals(connection_struct *conn, char *name, char *newname, BO
|
||||
|
||||
*directory = *mask = 0;
|
||||
|
||||
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);
|
||||
|
||||
@ -3326,6 +3456,7 @@ directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n",
|
||||
*/
|
||||
|
||||
if (strcsequal(directory, newname)) {
|
||||
rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
|
||||
DEBUG(3,("rename_internals: identical names in rename %s - returning success\n", directory));
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
@ -3339,6 +3470,7 @@ directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n",
|
||||
if(SMB_VFS_RENAME(conn,directory, newname) == 0) {
|
||||
DEBUG(3,("rename_internals: succeeded doing rename on %s -> %s\n",
|
||||
directory,newname));
|
||||
rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
@ -3403,8 +3535,10 @@ directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n",
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!SMB_VFS_RENAME(conn,fname,destname))
|
||||
if (!SMB_VFS_RENAME(conn,fname,destname)) {
|
||||
rename_open_files(conn, sbuf1.st_dev, sbuf1.st_ino, newname);
|
||||
count++;
|
||||
}
|
||||
DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname));
|
||||
}
|
||||
CloseDir(dirptr);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
SMB transaction2 handling
|
||||
Copyright (C) Jeremy Allison 1994-2001
|
||||
Copyright (C) Jeremy Allison 1994-2003
|
||||
Copyright (C) Stefan (metze) Metzmacher 2003
|
||||
|
||||
Extensively modified by Andrew Tridgell, 1995
|
||||
@ -261,8 +261,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
|
||||
unix_convert(fname,conn,0,&bad_path,&sbuf);
|
||||
|
||||
if (!check_name(fname,conn)) {
|
||||
set_bad_path_error(errno, bad_path);
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
|
||||
}
|
||||
|
||||
unixmode = unix_mode(conn,open_attr | aARCH, fname);
|
||||
@ -271,8 +270,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
|
||||
oplock_request, &rmode,&smb_action);
|
||||
|
||||
if (!fsp) {
|
||||
set_bad_path_error(errno, bad_path);
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
|
||||
}
|
||||
|
||||
size = get_file_size(sbuf);
|
||||
@ -441,9 +439,9 @@ static mode_t unix_perms_from_wire( connection_struct *conn, SMB_STRUCT_STAT *ps
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
checks for SMB_TIME_NO_CHANGE and if not found
|
||||
calls interpret_long_date
|
||||
Checks for SMB_TIME_NO_CHANGE and if not found calls interpret_long_date.
|
||||
****************************************************************************/
|
||||
|
||||
time_t interpret_long_unix_date(char *p)
|
||||
{
|
||||
DEBUG(1,("interpret_long_unix_date\n"));
|
||||
@ -910,8 +908,7 @@ close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n",
|
||||
|
||||
unix_convert(directory,conn,0,&bad_path,&sbuf);
|
||||
if(!check_name(directory,conn)) {
|
||||
set_bad_path_error(errno, bad_path);
|
||||
return(UNIXERROR(ERRDOS,ERRbadpath));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
|
||||
}
|
||||
|
||||
p = strrchr_m(directory,'/');
|
||||
@ -1716,14 +1713,22 @@ static int call_trans2setfsinfo(connection_struct *conn,
|
||||
* Utility function to set bad path error.
|
||||
****************************************************************************/
|
||||
|
||||
NTSTATUS set_bad_path_error(int err, BOOL bad_path)
|
||||
int set_bad_path_error(int err, BOOL bad_path, char *outbuf, int def_class, uint32 def_code)
|
||||
{
|
||||
if((err == ENOENT) && bad_path) {
|
||||
DEBUG(10,("set_bad_path_error: err = %dm bad_path = %d\n",
|
||||
err, (int)bad_path ));
|
||||
|
||||
if(err == ENOENT) {
|
||||
unix_ERR_class = ERRDOS;
|
||||
unix_ERR_code = ERRbadpath;
|
||||
return NT_STATUS_OBJECT_PATH_NOT_FOUND;
|
||||
if (bad_path) {
|
||||
unix_ERR_code = ERRbadpath;
|
||||
return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
|
||||
} else {
|
||||
unix_ERR_code = ERRbadfile;
|
||||
return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
return NT_STATUS_OK;
|
||||
return UNIXERROR(def_class,def_code);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -1778,8 +1783,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
|
||||
unix_convert(fname,conn,0,&bad_path,&sbuf);
|
||||
if (!check_name(fname,conn)) {
|
||||
DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed for fake_file(%s)\n",fname,strerror(errno)));
|
||||
set_bad_path_error(errno, bad_path);
|
||||
return(UNIXERROR(ERRDOS,ERRbadpath));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
|
||||
}
|
||||
|
||||
} else if(fsp && (fsp->is_directory || fsp->fd == -1)) {
|
||||
@ -1792,21 +1796,18 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
|
||||
unix_convert(fname,conn,0,&bad_path,&sbuf);
|
||||
if (!check_name(fname,conn)) {
|
||||
DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
|
||||
set_bad_path_error(errno, bad_path);
|
||||
return(UNIXERROR(ERRDOS,ERRbadpath));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
|
||||
}
|
||||
|
||||
if (INFO_LEVEL_IS_UNIX(info_level)) {
|
||||
/* Always do lstat for UNIX calls. */
|
||||
if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
|
||||
DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
|
||||
set_bad_path_error(errno, bad_path);
|
||||
return(UNIXERROR(ERRDOS,ERRbadpath));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
|
||||
}
|
||||
} else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf)) {
|
||||
DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
|
||||
set_bad_path_error(errno, bad_path);
|
||||
return(UNIXERROR(ERRDOS,ERRbadpath));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
|
||||
}
|
||||
|
||||
delete_pending = fsp->directory_delete_on_close;
|
||||
@ -1840,29 +1841,26 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
|
||||
unix_convert(fname,conn,0,&bad_path,&sbuf);
|
||||
if (!check_name(fname,conn)) {
|
||||
DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
|
||||
set_bad_path_error(errno, bad_path);
|
||||
return(UNIXERROR(ERRDOS,ERRbadpath));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
|
||||
}
|
||||
|
||||
if (INFO_LEVEL_IS_UNIX(info_level)) {
|
||||
/* Always do lstat for UNIX calls. */
|
||||
if (SMB_VFS_LSTAT(conn,fname,&sbuf)) {
|
||||
DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_LSTAT of %s failed (%s)\n",fname,strerror(errno)));
|
||||
set_bad_path_error(errno, bad_path);
|
||||
return(UNIXERROR(ERRDOS,ERRbadpath));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
|
||||
}
|
||||
} else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,fname,&sbuf)) {
|
||||
DEBUG(3,("call_trans2qfilepathinfo: SMB_VFS_STAT of %s failed (%s)\n",fname,strerror(errno)));
|
||||
set_bad_path_error(errno, bad_path);
|
||||
return(UNIXERROR(ERRDOS,ERRbadpath));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
|
||||
}
|
||||
}
|
||||
|
||||
if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions())
|
||||
return ERROR_DOS(ERRDOS,ERRunknownlevel);
|
||||
|
||||
DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
|
||||
fname,info_level,tran_call,total_data));
|
||||
DEBUG(3,("call_trans2qfilepathinfo %s (fnum = %d) level=%d call=%d total_data=%d\n",
|
||||
fname,fsp ? fsp->fnum : -1, info_level,tran_call,total_data));
|
||||
|
||||
p = strrchr_m(fname,'/');
|
||||
if (!p)
|
||||
@ -2422,8 +2420,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
|
||||
unix_convert(fname,conn,0,&bad_path,&sbuf);
|
||||
if (!check_name(fname,conn) || (!VALID_STAT(sbuf))) {
|
||||
DEBUG(3,("call_trans2setfilepathinfo: fileinfo of %s failed (%s)\n",fname,strerror(errno)));
|
||||
set_bad_path_error(errno, bad_path);
|
||||
return(UNIXERROR(ERRDOS,ERRbadpath));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
|
||||
}
|
||||
} else if (fsp && fsp->print_file) {
|
||||
/*
|
||||
@ -2462,8 +2459,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
|
||||
srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE);
|
||||
unix_convert(fname,conn,0,&bad_path,&sbuf);
|
||||
if(!check_name(fname, conn)) {
|
||||
set_bad_path_error(errno, bad_path);
|
||||
return(UNIXERROR(ERRDOS,ERRbadpath));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2472,8 +2468,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
|
||||
|
||||
if(!VALID_STAT(sbuf) && !INFO_LEVEL_IS_UNIX(info_level)) {
|
||||
DEBUG(3,("call_trans2setfilepathinfo: stat of %s failed (%s)\n", fname, strerror(errno)));
|
||||
set_bad_path_error(errno, bad_path);
|
||||
return(UNIXERROR(ERRDOS,ERRbadpath));
|
||||
return ERROR_NT(NT_STATUS_OBJECT_NAME_NOT_FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2486,8 +2481,8 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
|
||||
if (VALID_STAT(sbuf))
|
||||
unixmode = sbuf.st_mode;
|
||||
|
||||
DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
|
||||
tran_call,fname,info_level,total_data));
|
||||
DEBUG(3,("call_trans2setfilepathinfo(%d) %s (fnum %d) info_level=%d totdata=%d\n",
|
||||
tran_call,fname, fsp ? fsp->fnum : -1, info_level,total_data));
|
||||
|
||||
/* Realloc the parameter and data sizes */
|
||||
params = Realloc(*pparams,2);
|
||||
@ -2679,12 +2674,14 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
|
||||
case SMB_FILE_DISPOSITION_INFORMATION:
|
||||
case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
|
||||
{
|
||||
BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
|
||||
BOOL delete_on_close;
|
||||
NTSTATUS status;
|
||||
|
||||
if (total_data < 1)
|
||||
return(ERROR_DOS(ERRDOS,ERRinvalidparam));
|
||||
|
||||
delete_on_close = (CVAL(pdata,0) ? True : False);
|
||||
|
||||
/* Just ignore this set on a path. */
|
||||
if (tran_call != TRANSACT2_SETFILEINFO)
|
||||
break;
|
||||
@ -2905,6 +2902,55 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
|
||||
return(-1);
|
||||
}
|
||||
|
||||
case SMB_FILE_RENAME_INFORMATION:
|
||||
{
|
||||
BOOL overwrite;
|
||||
uint32 root_fid;
|
||||
uint32 len;
|
||||
pstring newname;
|
||||
pstring base_name;
|
||||
char *p;
|
||||
NTSTATUS status;
|
||||
|
||||
if (total_data < 12)
|
||||
return(ERROR_DOS(ERRDOS,ERRinvalidparam));
|
||||
|
||||
overwrite = (CVAL(pdata,0) ? True : False);
|
||||
root_fid = IVAL(pdata,4);
|
||||
len = IVAL(pdata,8);
|
||||
srvstr_pull(inbuf, newname, &pdata[12], sizeof(newname), len, 0);
|
||||
|
||||
/* Check the new name has no '\' characters. */
|
||||
if (strchr_m(newname, '\\') || strchr_m(newname, '/'))
|
||||
return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
|
||||
|
||||
RESOLVE_DFSPATH(newname, conn, inbuf, outbuf);
|
||||
|
||||
/* Create the base directory. */
|
||||
pstrcpy(base_name, fname);
|
||||
p = strrchr_m(base_name, '/');
|
||||
if (p)
|
||||
*p = '\0';
|
||||
/* Append the new name. */
|
||||
pstrcat(base_name, "/");
|
||||
pstrcat(base_name, newname);
|
||||
|
||||
if (fsp) {
|
||||
DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION (fnum %d) %s -> %s\n",
|
||||
fsp->fnum, fsp->fsp_name, base_name ));
|
||||
status = rename_internals_fsp(conn, fsp, base_name, overwrite);
|
||||
} else {
|
||||
DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n",
|
||||
fname, newname ));
|
||||
status = rename_internals(conn, fname, base_name, overwrite);
|
||||
}
|
||||
if (!NT_STATUS_IS_OK(status))
|
||||
return ERROR_NT(status);
|
||||
process_pending_change_notify_queue((time_t)0);
|
||||
SSVAL(params,0,0);
|
||||
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
|
||||
return(-1);
|
||||
}
|
||||
default:
|
||||
return ERROR_DOS(ERRDOS,ERRunknownlevel);
|
||||
}
|
||||
@ -3056,8 +3102,7 @@ static int call_trans2mkdir(connection_struct *conn,
|
||||
|
||||
if(ret < 0) {
|
||||
DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
|
||||
set_bad_path_error(errno, bad_path);
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
|
||||
}
|
||||
|
||||
/* Realloc the parameter and data sizes */
|
||||
|
Loading…
x
Reference in New Issue
Block a user