mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
r17541: When returning a trans2 request, if the "max data
bytes returned" is less than the amount we want to send, return what we can and set STATUS_BUFFER_OVERFLOW (doserror ERRDOS,ERRbufferoverflow). Required by OS/2 to handle EA's that are too large. It's hard to test this in Samba4 smbtorture as the max data bytes returned is hard coded at 0xffff (as it is in the Samba3 client libraries also). I used a custom version of Samba4 smbtorture to test this out. Might add a "max data bytes" param to make this testable in the build farm. Confirmed by "Guenter Kukkukk (sambaos2)" <sambaos2@kukkukk.com> and Andreas Taegener <atsamba11@eideltown.de> that this fixes the issue. Jeremy.
This commit is contained in:
parent
cf7c83d462
commit
ff2f1202b7
@ -44,6 +44,7 @@
|
|||||||
#define ERRnomem 8 /* Out of memory */
|
#define ERRnomem 8 /* Out of memory */
|
||||||
#define ERRbadmem 9 /* Invalid memory block address */
|
#define ERRbadmem 9 /* Invalid memory block address */
|
||||||
#define ERRbadenv 10 /* Invalid environment */
|
#define ERRbadenv 10 /* Invalid environment */
|
||||||
|
#define ERRbadformat 11 /* Bad Format */
|
||||||
#define ERRbadaccess 12 /* Invalid open mode */
|
#define ERRbadaccess 12 /* Invalid open mode */
|
||||||
#define ERRbaddata 13 /* Invalid data (only from ioctl call) */
|
#define ERRbaddata 13 /* Invalid data (only from ioctl call) */
|
||||||
#define ERRres 14 /* reserved */
|
#define ERRres 14 /* reserved */
|
||||||
@ -60,6 +61,7 @@
|
|||||||
#define ERRfilexists 80 /* File in operation already exists */
|
#define ERRfilexists 80 /* File in operation already exists */
|
||||||
#define ERRinvalidparam 87
|
#define ERRinvalidparam 87
|
||||||
#define ERRcannotopen 110 /* Cannot open the file specified */
|
#define ERRcannotopen 110 /* Cannot open the file specified */
|
||||||
|
#define ERRbufferoverflow 111
|
||||||
#define ERRinsufficientbuffer 122
|
#define ERRinsufficientbuffer 122
|
||||||
#define ERRinvalidname 123 /* Invalid name */
|
#define ERRinvalidname 123 /* Invalid name */
|
||||||
#define ERRunknownlevel 124
|
#define ERRunknownlevel 124
|
||||||
|
@ -458,7 +458,8 @@ static BOOL process_trans2(blocking_lock_record *blr)
|
|||||||
construct_reply_common(inbuf, outbuf);
|
construct_reply_common(inbuf, outbuf);
|
||||||
SCVAL(outbuf,smb_com,SMBtrans2);
|
SCVAL(outbuf,smb_com,SMBtrans2);
|
||||||
SSVAL(params,0,0);
|
SSVAL(params,0,0);
|
||||||
send_trans2_replies(outbuf, max_send, params, 2, NULL, 0);
|
/* Fake up max_data_bytes here - we know it fits. */
|
||||||
|
send_trans2_replies(outbuf, max_send, params, 2, NULL, 0, 0xffff);
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,9 +81,8 @@ BOOL use_nt_status(void)
|
|||||||
If the override errors are set they take precedence over any passed in values.
|
If the override errors are set they take precedence over any passed in values.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file)
|
void error_packet_set(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file)
|
||||||
{
|
{
|
||||||
int outsize = set_message(outbuf,0,0,True);
|
|
||||||
BOOL force_nt_status = False;
|
BOOL force_nt_status = False;
|
||||||
BOOL force_dos_status = False;
|
BOOL force_dos_status = False;
|
||||||
|
|
||||||
@ -125,6 +124,11 @@ int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, in
|
|||||||
eclass,
|
eclass,
|
||||||
ecode));
|
ecode));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file)
|
||||||
|
{
|
||||||
|
int outsize = set_message(outbuf,0,0,True);
|
||||||
|
error_packet_set(outbuf, eclass, ecode, ntstatus, line, file);
|
||||||
return outsize;
|
return outsize;
|
||||||
}
|
}
|
||||||
|
@ -573,7 +573,8 @@ int send_trans2_replies(char *outbuf,
|
|||||||
char *params,
|
char *params,
|
||||||
int paramsize,
|
int paramsize,
|
||||||
char *pdata,
|
char *pdata,
|
||||||
int datasize)
|
int datasize,
|
||||||
|
int max_data_bytes)
|
||||||
{
|
{
|
||||||
/* As we are using a protocol > LANMAN1 then the max_send
|
/* As we are using a protocol > LANMAN1 then the max_send
|
||||||
variable must have been set in the sessetupX call.
|
variable must have been set in the sessetupX call.
|
||||||
@ -594,6 +595,18 @@ int send_trans2_replies(char *outbuf,
|
|||||||
|
|
||||||
set_message(outbuf,10,0,True);
|
set_message(outbuf,10,0,True);
|
||||||
|
|
||||||
|
/* Modify the data_to_send and datasize and set the error if
|
||||||
|
we're trying to send more than max_data_bytes. We still send
|
||||||
|
the part of the packet(s) that fit. Strange, but needed
|
||||||
|
for OS/2. */
|
||||||
|
|
||||||
|
if (max_data_bytes > 0 && datasize > max_data_bytes) {
|
||||||
|
DEBUG(5,("send_trans2_replies: max_data_bytes %d exceeded by data %d\n",
|
||||||
|
max_data_bytes, datasize ));
|
||||||
|
datasize = data_to_send = max_data_bytes;
|
||||||
|
error_packet_set(outbuf,ERRDOS,ERRbufferoverflow,STATUS_BUFFER_OVERFLOW,__LINE__,__FILE__);
|
||||||
|
}
|
||||||
|
|
||||||
/* If there genuinely are no parameters or data to send just send the empty packet */
|
/* If there genuinely are no parameters or data to send just send the empty packet */
|
||||||
|
|
||||||
if(params_to_send == 0 && data_to_send == 0) {
|
if(params_to_send == 0 && data_to_send == 0) {
|
||||||
@ -932,7 +945,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Send the required number of replies */
|
/* Send the required number of replies */
|
||||||
send_trans2_replies(outbuf, bufsize, params, 30, *ppdata, 0);
|
send_trans2_replies(outbuf, bufsize, params, 30, *ppdata, 0, max_data_bytes);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1858,7 +1871,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
|
|||||||
SSVAL(params,6,0); /* Never an EA error */
|
SSVAL(params,6,0); /* Never an EA error */
|
||||||
SSVAL(params,8,last_entry_off);
|
SSVAL(params,8,last_entry_off);
|
||||||
|
|
||||||
send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
|
send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata), max_data_bytes);
|
||||||
|
|
||||||
if ((! *directory) && dptr_path(dptr_num))
|
if ((! *directory) && dptr_path(dptr_num))
|
||||||
slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
|
slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
|
||||||
@ -2140,7 +2153,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
|
|||||||
SSVAL(params,4,0); /* Never an EA error */
|
SSVAL(params,4,0); /* Never an EA error */
|
||||||
SSVAL(params,6,last_entry_off);
|
SSVAL(params,6,last_entry_off);
|
||||||
|
|
||||||
send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
|
send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata), max_data_bytes);
|
||||||
|
|
||||||
if ((! *directory) && dptr_path(dptr_num))
|
if ((! *directory) && dptr_path(dptr_num))
|
||||||
slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
|
slprintf(directory,sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
|
||||||
@ -2503,7 +2516,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
|
send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len, max_data_bytes);
|
||||||
|
|
||||||
DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
|
DEBUG( 4, ( "%s info_level = %d\n", smb_fn_name(CVAL(inbuf,smb_com)), info_level) );
|
||||||
|
|
||||||
@ -3633,7 +3646,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
|
|||||||
return ERROR_NT(NT_STATUS_INVALID_LEVEL);
|
return ERROR_NT(NT_STATUS_INVALID_LEVEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size);
|
send_trans2_replies(outbuf, bufsize, params, param_size, *ppdata, data_size, max_data_bytes);
|
||||||
|
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
@ -3782,7 +3795,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
|
|||||||
DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
|
DEBUG(3,("call_trans2setfilepathinfo: Cancelling print job (%s)\n", fsp->fsp_name ));
|
||||||
|
|
||||||
SSVAL(params,0,0);
|
SSVAL(params,0,0);
|
||||||
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
|
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
|
||||||
return(-1);
|
return(-1);
|
||||||
} else
|
} else
|
||||||
return (UNIXERROR(ERRDOS,ERRbadpath));
|
return (UNIXERROR(ERRDOS,ERRbadpath));
|
||||||
@ -3894,7 +3907,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
|
|||||||
if ((total_data == 4) && (IVAL(pdata,0) == 4)) {
|
if ((total_data == 4) && (IVAL(pdata,0) == 4)) {
|
||||||
/* We're done. We only get EA info in this call. */
|
/* We're done. We only get EA info in this call. */
|
||||||
SSVAL(params,0,0);
|
SSVAL(params,0,0);
|
||||||
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
|
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3925,7 +3938,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
|
|||||||
|
|
||||||
/* We're done. We only get EA info in this call. */
|
/* We're done. We only get EA info in this call. */
|
||||||
SSVAL(params,0,0);
|
SSVAL(params,0,0);
|
||||||
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
|
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4117,7 +4130,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
|
|||||||
}
|
}
|
||||||
|
|
||||||
SSVAL(params,0,0);
|
SSVAL(params,0,0);
|
||||||
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
|
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4146,7 +4159,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
|
|||||||
|
|
||||||
/* We're done. We only get position info in this call. */
|
/* We're done. We only get position info in this call. */
|
||||||
SSVAL(params,0,0);
|
SSVAL(params,0,0);
|
||||||
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
|
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4170,7 +4183,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
|
|||||||
|
|
||||||
/* We're done. We only get mode info in this call. */
|
/* We're done. We only get mode info in this call. */
|
||||||
SSVAL(params,0,0);
|
SSVAL(params,0,0);
|
||||||
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
|
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4285,7 +4298,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
|
|||||||
inherit_access_acl(conn, fname, unixmode);
|
inherit_access_acl(conn, fname, unixmode);
|
||||||
|
|
||||||
SSVAL(params,0,0);
|
SSVAL(params,0,0);
|
||||||
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
|
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4368,7 +4381,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
|
|||||||
if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0)
|
if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0)
|
||||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||||
SSVAL(params,0,0);
|
SSVAL(params,0,0);
|
||||||
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
|
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4392,7 +4405,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
|
|||||||
}
|
}
|
||||||
|
|
||||||
SSVAL(params,0,0);
|
SSVAL(params,0,0);
|
||||||
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
|
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4446,7 +4459,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
|
|||||||
}
|
}
|
||||||
process_pending_change_notify_queue((time_t)0);
|
process_pending_change_notify_queue((time_t)0);
|
||||||
SSVAL(params,0,0);
|
SSVAL(params,0,0);
|
||||||
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
|
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4497,7 +4510,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
|
|||||||
}
|
}
|
||||||
|
|
||||||
SSVAL(params,0,0);
|
SSVAL(params,0,0);
|
||||||
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
|
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -4603,7 +4616,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
|
|||||||
}
|
}
|
||||||
|
|
||||||
SSVAL(params,0,0);
|
SSVAL(params,0,0);
|
||||||
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
|
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4729,7 +4742,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
|
|||||||
}
|
}
|
||||||
|
|
||||||
SSVAL(params,0,0);
|
SSVAL(params,0,0);
|
||||||
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
|
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
|
||||||
|
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
@ -4834,7 +4847,7 @@ static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf,
|
|||||||
|
|
||||||
SSVAL(params,0,0);
|
SSVAL(params,0,0);
|
||||||
|
|
||||||
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
|
send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0, max_data_bytes);
|
||||||
|
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
@ -4883,7 +4896,7 @@ static int call_trans2findnotifyfirst(connection_struct *conn, char *inbuf, char
|
|||||||
if(fnf_handle == 0)
|
if(fnf_handle == 0)
|
||||||
fnf_handle = 257;
|
fnf_handle = 257;
|
||||||
|
|
||||||
send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
|
send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0, max_data_bytes);
|
||||||
|
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
@ -4911,7 +4924,7 @@ static int call_trans2findnotifynext(connection_struct *conn, char *inbuf, char
|
|||||||
SSVAL(params,0,0); /* No changes */
|
SSVAL(params,0,0); /* No changes */
|
||||||
SSVAL(params,2,0); /* No EA errors */
|
SSVAL(params,2,0); /* No EA errors */
|
||||||
|
|
||||||
send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
|
send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0, max_data_bytes);
|
||||||
|
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
@ -4945,7 +4958,7 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, char*
|
|||||||
return UNIXERROR(ERRDOS,ERRbadfile);
|
return UNIXERROR(ERRDOS,ERRbadfile);
|
||||||
|
|
||||||
SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
|
SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2) | FLAGS2_DFS_PATHNAMES);
|
||||||
send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size);
|
send_trans2_replies(outbuf,bufsize,0,0,*ppdata,reply_size, max_data_bytes);
|
||||||
|
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
@ -4983,7 +4996,7 @@ static int call_trans2ioctl(connection_struct *conn, char* inbuf, char* outbuf,
|
|||||||
SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */
|
SSVAL(pdata,0,fsp->rap_print_jobid); /* Job number */
|
||||||
srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
|
srvstr_push( outbuf, pdata + 2, global_myname(), 15, STR_ASCII|STR_TERMINATE); /* Our NetBIOS name */
|
||||||
srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
|
srvstr_push( outbuf, pdata+18, lp_servicename(SNUM(conn)), 13, STR_ASCII|STR_TERMINATE); /* Service name */
|
||||||
send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32);
|
send_trans2_replies(outbuf,bufsize,*pparams,0,*ppdata,32, max_data_bytes);
|
||||||
return(-1);
|
return(-1);
|
||||||
} else {
|
} else {
|
||||||
DEBUG(2,("Unknown TRANS2_IOCTL\n"));
|
DEBUG(2,("Unknown TRANS2_IOCTL\n"));
|
||||||
|
Loading…
Reference in New Issue
Block a user