Bug 1590 - Any writing and spooling to LANMAN2 server broken (OS/2 Warpserver)
Any writing and spooling to LANMAN2 server broken (OS/2 Warpserver)
Status: CLOSED FIXED
Product: Samba 3.0
Classification: Unclassified
Component: libsmbclient
3.0.5
x86 Linux
: P3 critical
: none
Assigned To: Samba Bugzilla Account
Samba QA Contact
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2004-08-06 19:23 UTC by Guenter Kukkukk
Modified: 2005-08-24 10:27 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Guenter Kukkukk 2004-08-06 19:23:18 UTC
BTW - I am using SUSE Linux 9.1 with samba-3.0.5 and tried to connect to a 
      printer located on a LANMAN2 server (OS/2 Warpserver). 
      This connect and other writes to the server always failed... 
 
Please note: 
      !!! SAMBA BUG_ID 1571 has already been fixed locally in my environment. 
      This report describes an *additional* error. 
       
I tracked down the bug with the help of ethereal: 
 
The file with a nasty error in it is: 
/libsmb/clireadwrite.c 
 function cli_write() 
 
    .... 
    int mpx = MAX(cli->max_mux-1, 1); 
 
This MAX() macro leads to a real nasty error! 
  cli->max_mux is of type size_t. 
  cli->max_mux-1 leads to somewhat unexpected results, if 
                 cli->max_mux is zero !!! 
                 (or greater than 0x80000000) 
 
In my real environment, the LANMAN2 server returned 
    cli->max_mux = 0 and so the variable 
    mpx resulted to -1   !!!!! NEGATIVE 
    instead of being set to 1 
 
BTW-many modern server return something like 
    cli->max_mux = 10 
    so this special bug does not occur!   
 
The somewhat later executed statement 
   while ((issued - received < mpx) && (issued < blocks)) { 
*always* evaluated to false 
and the whole inner write-code was never executed! 
 
Lateron 
  if (!cli_receive_smb(cli)) 
	  return bwritten; 
always timed out and returned zero bytes written! 
 
SOLUTION: 
    int mpx = MAX(cli->max_mux-1, 1); 
should be replaced by something like 
    int mpx = MAX((int)(cli->max_mux)-1, 1); 
which is also not easy to understand! 
The problem is the not typesave MAX() macro. 
So something better could be: 
    if(cli->max_mux == 0){ 
       mpx = 1; 
    } else { 
       mpx = cli->max_mux - 1; 
    } 
 
I have changed the latest 3.0.5 code locally and copiled and installed 
it - the error is gone! 
 
Best regards. 
Guenter 
 
BTW - for all not believing the above: 
/* 
 * testcase for checking not typesafe macros 
 * like MIN(), MAX(), .... 
 * 
 * guenter.kukkukk@kukkukk.com 
 */ 
 
#ifndef MIN 
#define MIN(a,b) ((a)<(b)?(a):(b)) 
#endif 
 
#ifndef MAX 
#define MAX(a,b) ((a)>(b)?(a):(b)) 
#endif 
 
#include <stdio.h> 
 
/* 
 *  int main () 
 */ 
int main (int argc, char *argv[]) 
{ 
  int res; 
  size_t tt = 0; 
  // size_t tt = 0x80000001;   // fails also 
 
  // printf ("%d\n", sizeof(size_t)); 
 
  res = MAX(tt - 1, 1); 
  printf ("res=%d 0x%08x\n", res, res); 
 
  res = MAX((int)tt - 1 ,1); 
  printf ("res=%d\n", res); 
 
  return 0; 
}
Comment 1 Guenter Kukkukk 2004-08-10 20:20:37 UTC
To clarify it a little bit further: 
 
In another module /libsmb/cliconnect.c 
   function BOOL cli_negprot(struct cli_state *cli) 
 
the negotiaton return value for max_mux is *ignored* 
for the LANMAN2.1 protocol! 
In my environment the server returned  
   max_mux = 50 
but due to the default structure-init (all zeroes) it was left at 
   max_mux = 0 
This is not a bug - but a performance penalty. 
The setting of max_mux = 0 discovered the reported bug in 
   /libsmb/clireadwrite.c  
     function cli_write()  
 
To enhance the source of /libsmb/cliconnect.c the following 
addition should be done - see below. 
I have tested the change - and it works very well - the writing 
speed to the server has increased.... 
 
Best wishes. 
Guenter Kukkukk 
 
........ excerpt from /libsmb/cliconnect.c 
........ function cli_negprot() 
 
  if (cli->protocol >= PROTOCOL_NT1) {  
    ... 
    ... snip 
    ... 
  } else if (cli->protocol >= PROTOCOL_LANMAN1) { 
    cli->use_spnego = False; 
    cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); 
    cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); 
 
    /* NEW */ 
    cli->max_mux = SVAL(cli->inbuf, smb_vwv3);   !!!!! 
    /* END NEW */ 
 
    cli->sesskey = IVAL(cli->inbuf,smb_vwv6); 
    cli->serverzone = SVALS(cli->inbuf,smb_vwv10); 
    cli->serverzone *= 60; 
    /* this time is converted to GMT by make_unix_date */ 
    cli->servertime = make_unix_date(cli->inbuf+smb_vwv8); 
    cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0); 
    cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0); 
    cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf)); 
  } else { 
    /* the old core protocol */ 
    cli->use_spnego = False; 
    cli->sec_mode = 0; 
    cli->serverzone = TimeDiff(time(NULL)); 
  } 
  ... 
  ... 
 
  
 
.... excerpt from debug output 
Connecting to 192.168.200.1 at port 139 
socket option SO_KEEPALIVE = 1 
socket option SO_REUSEADDR = 0 
socket option SO_BROADCAST = 0 
socket option TCP_NODELAY = 1 
socket option IPTOS_LOWDELAY = 16 
socket option IPTOS_THROUGHPUT = 16 
socket option SO_SNDBUF = 16384 
socket option SO_RCVBUF = 87380 
socket option SO_SNDLOWAT = 1 
socket option SO_RCVLOWAT = 1 
socket option SO_SNDTIMEO = 0 
socket option SO_RCVTIMEO = 0 
write_socket(4,72) 
write_socket(4,72) wrote 72 
Sent session request 
got smb length of 0 
size=0 
smb_com=0x0 
smb_rcls=0 
smb_reh=0 
smb_err=0 
smb_flg=0 
smb_flg2=0 
smb_tid=0 
smb_pid=0 
smb_uid=0 
smb_mid=0 
smt_wct=0 
smb_bcc=0 
 session request ok 
write_socket(4,183) 
write_socket(4,183) wrote 183 
got smb length of 78 
size=78 
smb_com=0x72 
smb_rcls=0 
smb_reh=0 
smb_err=0 
smb_flg=137 
smb_flg2=51201 
smb_tid=0 
smb_pid=12274 
smb_uid=0 
smb_mid=2 
smt_wct=13 
smb_vwv[ 0]=    4 (0x4) 
smb_vwv[ 1]=    3 (0x3) 
smb_vwv[ 2]= 4356 (0x1104) 
smb_vwv[ 3]=   50 (0x32)        !!!!!! holds max. mux - but is ignored !!!! 
smb_vwv[ 4]=    1 (0x1) 
smb_vwv[ 5]=    3 (0x3) 
smb_vwv[ 6]= 8217 (0x2019) 
smb_vwv[ 7]=    0 (0x0) 
smb_vwv[ 8]= 9629 (0x259D) 
smb_vwv[ 9]=12555 (0x310B) 
smb_vwv[10]=65535 (0xFFFF) 
smb_vwv[11]=    8 (0x8) 
smb_vwv[12]=   48 (0x30) 
smb_bcc=17 
.... snip ... 
Comment 2 Guenter Kukkukk 2004-08-22 18:21:27 UTC
I raised severity to "critical" - cause others are also severely affected.
And it has status "NEW" since nearly 2 weeks now.
Best wishes.
Guenter
Comment 3 Jeremy Allison 2004-09-16 17:49:45 UTC
Applied - obviously correct. Thanks.
Jeremy.
Comment 4 Jeremy Allison 2004-09-16 17:50:00 UTC
Meant to add, will be fixed in 3.0.8.
Jeremy.
Comment 5 Gerald (Jerry) Carter 2005-08-24 10:27:02 UTC
sorry for the same, cleaning up the database to prevent unecessary reopens of bugs.