mirror of
https://github.com/samba-team/samba.git
synced 2024-12-28 07:21:54 +03:00
r6203: Fix attribute return on creating a directory with nttrans_create.
Fix strange allocation semantics of openX. Jeremy.
This commit is contained in:
parent
3aa784c077
commit
da5a8b539d
@ -918,8 +918,9 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
|
||||
|
||||
file_len = sbuf.st_size;
|
||||
fmode = dos_mode(conn,fname,&sbuf);
|
||||
if(fmode == 0)
|
||||
if(fmode == 0) {
|
||||
fmode = FILE_ATTRIBUTE_NORMAL;
|
||||
}
|
||||
if (!fsp->is_directory && (fmode & aDIR)) {
|
||||
close_file(fsp,False);
|
||||
END_PROFILE(SMBntcreateX);
|
||||
@ -956,11 +957,13 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
|
||||
* correct bit for extended oplock reply.
|
||||
*/
|
||||
|
||||
if (oplock_request && lp_fake_oplocks(SNUM(conn)))
|
||||
if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
|
||||
extended_oplock_granted = True;
|
||||
}
|
||||
|
||||
if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
|
||||
if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
|
||||
extended_oplock_granted = True;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* W2K sends back 42 words here ! If we do the same it breaks offline sync. Go figure... ? JRA. */
|
||||
@ -1481,7 +1484,6 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
|
||||
oplock_request,&rmode,&smb_action);
|
||||
|
||||
if (!fsp) {
|
||||
|
||||
if(errno == EISDIR) {
|
||||
|
||||
/*
|
||||
@ -1511,32 +1513,6 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
|
||||
return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRnoaccess);
|
||||
}
|
||||
}
|
||||
|
||||
file_len = sbuf.st_size;
|
||||
fmode = dos_mode(conn,fname,&sbuf);
|
||||
if(fmode == 0)
|
||||
fmode = FILE_ATTRIBUTE_NORMAL;
|
||||
|
||||
if (fmode & aDIR) {
|
||||
talloc_destroy(ctx);
|
||||
close_file(fsp,False);
|
||||
restore_case_semantics(conn, file_attributes);
|
||||
return ERROR_NT(NT_STATUS_ACCESS_DENIED);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the caller set the extended oplock request bit
|
||||
* and we granted one (by whatever means) - set the
|
||||
* correct bit for extended oplock reply.
|
||||
*/
|
||||
|
||||
if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
|
||||
extended_oplock_granted = True;
|
||||
}
|
||||
|
||||
if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
|
||||
extended_oplock_granted = True;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1578,7 +1554,18 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
|
||||
}
|
||||
|
||||
restore_case_semantics(conn, file_attributes);
|
||||
talloc_destroy(ctx);
|
||||
|
||||
file_len = sbuf.st_size;
|
||||
fmode = dos_mode(conn,fname,&sbuf);
|
||||
if(fmode == 0) {
|
||||
fmode = FILE_ATTRIBUTE_NORMAL;
|
||||
}
|
||||
if (!fsp->is_directory && (fmode & aDIR)) {
|
||||
close_file(fsp,False);
|
||||
return ERROR_DOS(ERRDOS,ERRnoaccess);
|
||||
}
|
||||
|
||||
/* Save the requested allocation size. */
|
||||
if ((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) {
|
||||
SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(params,12);
|
||||
@ -1589,7 +1576,6 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
|
||||
fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
|
||||
if (fsp->is_directory) {
|
||||
close_file(fsp,False);
|
||||
END_PROFILE(SMBntcreateX);
|
||||
/* Can't set allocation size on a directory. */
|
||||
return ERROR_NT(NT_STATUS_ACCESS_DENIED);
|
||||
}
|
||||
@ -1602,6 +1588,20 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the caller set the extended oplock request bit
|
||||
* and we granted one (by whatever means) - set the
|
||||
* correct bit for extended oplock reply.
|
||||
*/
|
||||
|
||||
if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
|
||||
extended_oplock_granted = True;
|
||||
}
|
||||
|
||||
if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
|
||||
extended_oplock_granted = True;
|
||||
}
|
||||
|
||||
/* Realloc the size of parameters and data we will return */
|
||||
params = nttrans_realloc(ppparams, 69);
|
||||
if(params == NULL)
|
||||
|
@ -1268,6 +1268,9 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
|
||||
BOOL bad_path = False;
|
||||
files_struct *fsp;
|
||||
NTSTATUS status;
|
||||
SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv9);
|
||||
ssize_t retval = -1;
|
||||
|
||||
START_PROFILE(SMBopenX);
|
||||
|
||||
/* If it's an IPC, pass off the pipe handler. */
|
||||
@ -1320,18 +1323,22 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
|
||||
|
||||
size = sbuf.st_size;
|
||||
|
||||
if ((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) {
|
||||
SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(inbuf,smb_vwv9);
|
||||
if (allocation_size && (allocation_size > (SMB_BIG_UINT)size)) {
|
||||
fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
|
||||
if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
|
||||
close_file(fsp,False);
|
||||
END_PROFILE(SMBntcreateX);
|
||||
return ERROR_NT(NT_STATUS_DISK_FULL);
|
||||
}
|
||||
} else {
|
||||
fsp->initial_allocation_size = smb_roundup(fsp->conn,(SMB_BIG_UINT)size);
|
||||
/* Setting the "size" field in vwv9 and vwv10 causes the file to be set to this size,
|
||||
if the file is truncated or created. */
|
||||
if (((smb_action == FILE_WAS_CREATED) || (smb_action == FILE_WAS_OVERWRITTEN)) && allocation_size) {
|
||||
fsp->initial_allocation_size = smb_roundup(fsp->conn, allocation_size);
|
||||
if (vfs_allocate_file_space(fsp, fsp->initial_allocation_size) == -1) {
|
||||
close_file(fsp,False);
|
||||
END_PROFILE(SMBntcreateX);
|
||||
return ERROR_NT(NT_STATUS_DISK_FULL);
|
||||
}
|
||||
retval = vfs_set_filelen(fsp, (SMB_OFF_T)allocation_size);
|
||||
if (retval < 0) {
|
||||
close_file(fsp,False);
|
||||
END_PROFILE(SMBwrite);
|
||||
return ERROR_NT(NT_STATUS_DISK_FULL);
|
||||
}
|
||||
size = get_allocation_size(conn,fsp,&sbuf);
|
||||
}
|
||||
|
||||
fmode = dos_mode(conn,fname,&sbuf);
|
||||
@ -1371,7 +1378,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
|
||||
put_dos_date3(outbuf,smb_vwv4,mtime & ~1);
|
||||
else
|
||||
put_dos_date3(outbuf,smb_vwv4,mtime);
|
||||
SIVAL(outbuf,smb_vwv6,(uint32)get_allocation_size(conn,fsp,&sbuf));
|
||||
SIVAL(outbuf,smb_vwv6,(uint32)size);
|
||||
SSVAL(outbuf,smb_vwv8,rmode);
|
||||
SSVAL(outbuf,smb_vwv11,smb_action);
|
||||
|
||||
|
@ -58,14 +58,18 @@ SMB_BIG_UINT get_allocation_size(connection_struct *conn, files_struct *fsp, SMB
|
||||
{
|
||||
SMB_BIG_UINT ret;
|
||||
|
||||
if(S_ISDIR(sbuf->st_mode)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE)
|
||||
ret = (SMB_BIG_UINT)STAT_ST_BLOCKSIZE * (SMB_BIG_UINT)sbuf->st_blocks;
|
||||
#else
|
||||
ret = (SMB_BIG_UINT)get_file_size(*sbuf);
|
||||
#endif
|
||||
|
||||
if (!ret && fsp && fsp->initial_allocation_size)
|
||||
ret = fsp->initial_allocation_size;
|
||||
if (fsp && fsp->initial_allocation_size)
|
||||
ret = MAX(ret,fsp->initial_allocation_size);
|
||||
|
||||
return smb_roundup(conn, ret);
|
||||
}
|
||||
@ -2800,7 +2804,6 @@ static int call_trans2qfilepathinfo(connection_struct *conn, char *inbuf, char *
|
||||
|
||||
fullpathname = fname;
|
||||
file_size = get_file_size(sbuf);
|
||||
allocation_size = get_allocation_size(conn,fsp,&sbuf);
|
||||
if (mode & aDIR) {
|
||||
/* This is necessary, as otherwise the desktop.ini file in
|
||||
* this folder is ignored */
|
||||
@ -2858,6 +2861,8 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
|
||||
|
||||
c_time = get_create_time(&sbuf,lp_fake_dir_create_times(SNUM(conn)));
|
||||
|
||||
allocation_size = get_allocation_size(conn,fsp,&sbuf);
|
||||
|
||||
if (fsp) {
|
||||
if (fsp->pending_modtime) {
|
||||
/* the pending modtime overrides the current modtime */
|
||||
@ -2870,6 +2875,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
|
||||
/* the pending modtime overrides the current modtime */
|
||||
sbuf.st_mtime = fsp1->pending_modtime;
|
||||
}
|
||||
if (fsp1 && fsp1->initial_allocation_size) {
|
||||
allocation_size = get_allocation_size(conn, fsp1, &sbuf);
|
||||
}
|
||||
}
|
||||
|
||||
if (lp_dos_filetime_resolution(SNUM(conn))) {
|
||||
|
Loading…
Reference in New Issue
Block a user