diff options
-rw-r--r-- | source3/include/doserr.h | 2 | ||||
-rw-r--r-- | source3/smbd/blocking.c | 3 | ||||
-rw-r--r-- | source3/smbd/error.c | 8 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 61 |
4 files changed, 47 insertions, 27 deletions
diff --git a/source3/include/doserr.h b/source3/include/doserr.h index 8f8ea06696..bc381e3351 100644 --- a/source3/include/doserr.h +++ b/source3/include/doserr.h @@ -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 diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 0304a6559f..2f89759ffd 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -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; } diff --git a/source3/smbd/error.c b/source3/smbd/error.c index 409781eaa9..0860b7d1d9 100644 --- a/source3/smbd/error.c +++ b/source3/smbd/error.c @@ -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; } diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 82052127c9..d2806753d3 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -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")); |