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; }
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 ...
I raised severity to "critical" - cause others are also severely affected. And it has status "NEW" since nearly 2 weeks now. Best wishes. Guenter
Applied - obviously correct. Thanks. Jeremy.
Meant to add, will be fixed in 3.0.8. Jeremy.
sorry for the same, cleaning up the database to prevent unecessary reopens of bugs.