1
0
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:
Jeremy Allison 2006-08-14 16:53:14 +00:00 committed by Gerald (Jerry) Carter
parent cf7c83d462
commit ff2f1202b7
4 changed files with 47 additions and 27 deletions

View File

@ -44,6 +44,7 @@
#define ERRnomem 8 /* Out of memory */
#define ERRbadmem 9 /* Invalid memory block address */
#define ERRbadenv 10 /* Invalid environment */
#define ERRbadformat 11 /* Bad Format */
#define ERRbadaccess 12 /* Invalid open mode */
#define ERRbaddata 13 /* Invalid data (only from ioctl call) */
#define ERRres 14 /* reserved */
@ -60,6 +61,7 @@
#define ERRfilexists 80 /* File in operation already exists */
#define ERRinvalidparam 87
#define ERRcannotopen 110 /* Cannot open the file specified */
#define ERRbufferoverflow 111
#define ERRinsufficientbuffer 122
#define ERRinvalidname 123 /* Invalid name */
#define ERRunknownlevel 124

View File

@ -458,7 +458,8 @@ static BOOL process_trans2(blocking_lock_record *blr)
construct_reply_common(inbuf, outbuf);
SCVAL(outbuf,smb_com,SMBtrans2);
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;
}

View File

@ -81,9 +81,8 @@ BOOL use_nt_status(void)
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_dos_status = False;
@ -125,6 +124,11 @@ int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, in
eclass,
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;
}

View File

@ -573,7 +573,8 @@ int send_trans2_replies(char *outbuf,
char *params,
int paramsize,
char *pdata,
int datasize)
int datasize,
int max_data_bytes)
{
/* As we are using a protocol > LANMAN1 then the max_send
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);
/* 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(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_trans2_replies(outbuf, bufsize, params, 30, *ppdata, 0);
send_trans2_replies(outbuf, bufsize, params, 30, *ppdata, 0, max_data_bytes);
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,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))
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,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))
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) );
@ -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);
}
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);
}
@ -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 ));
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);
} else
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)) {
/* We're done. We only get EA info in this call. */
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);
}
@ -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. */
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);
}
@ -4117,7 +4130,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, char *inbuf, char
}
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);
}
@ -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. */
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);
}
@ -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. */
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);
}
@ -4285,7 +4298,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
inherit_access_acl(conn, fname, unixmode);
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);
}
@ -4368,7 +4381,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
if (SMB_VFS_SYMLINK(conn,link_target,newname) != 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
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);
}
@ -4392,7 +4405,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
}
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);
}
@ -4446,7 +4459,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
}
process_pending_change_notify_queue((time_t)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);
}
@ -4497,7 +4510,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
}
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);
}
#endif
@ -4603,7 +4616,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
}
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);
}
@ -4729,7 +4742,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
}
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);
}
@ -4834,7 +4847,7 @@ static int call_trans2mkdir(connection_struct *conn, char *inbuf, char *outbuf,
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);
}
@ -4883,7 +4896,7 @@ static int call_trans2findnotifyfirst(connection_struct *conn, char *inbuf, char
if(fnf_handle == 0)
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);
}
@ -4911,7 +4924,7 @@ static int call_trans2findnotifynext(connection_struct *conn, char *inbuf, char
SSVAL(params,0,0); /* No changes */
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);
}
@ -4945,7 +4958,7 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, char*
return UNIXERROR(ERRDOS,ERRbadfile);
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);
}
@ -4983,7 +4996,7 @@ static int call_trans2ioctl(connection_struct *conn, char* inbuf, char* outbuf,
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+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);
} else {
DEBUG(2,("Unknown TRANS2_IOCTL\n"));