Bug 3212 - OS/2 worplace shell uses a special trans2 setpathinfo call, which is failing
OS/2 worplace shell uses a special trans2 setpathinfo call, which is failing
Status: RESOLVED FIXED
Product: Samba 3.0
Classification: Unclassified
Component: File Services
3.0.21
All OS/2
: P3 normal
: none
Assigned To: Jeremy Allison
Samba QA Contact
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2005-10-25 17:59 UTC by Guenter Kukkukk
Modified: 2005-11-02 23:25 UTC (History)
0 users

See Also:


Attachments
sniffs contains the failing samba3 stuff (591 bytes, application/octet-stream)
2005-10-25 18:03 UTC, Guenter Kukkukk
no flags Details
this sniff is against samba4 (396 bytes, application/octet-stream)
2005-10-25 18:05 UTC, Guenter Kukkukk
no flags Details
this sniff is against w2k (616 bytes, application/octet-stream)
2005-10-25 18:05 UTC, Guenter Kukkukk
no flags Details
samba3 is failing during mkdir with unusual ea length of 4 (639 bytes, application/octet-stream)
2005-10-27 19:02 UTC, Guenter Kukkukk
no flags Details
working stuff against w2k during mkdir with unusual ea length of 4 (392 bytes, application/octet-stream)
2005-10-27 19:04 UTC, Guenter Kukkukk
no flags Details
Proposed patch (2.00 KB, patch)
2005-10-28 17:24 UTC, Jeremy Allison
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Guenter Kukkukk 2005-10-25 17:59:50 UTC
Hi all,
Hello Jeremy,

this is the 1st of some bugs reports, I plan to send in the near future:

All file refs are based on todays svn rev 11296.

Description:
When using the os/2 workplaceshell (WPS) to copy a whole subdir (a folder)
to a samba3 share, the WPS displays a dialog box "The parameter is incorrect." 
and the copy is aborted.

In file smbd/trans.c -> function call_trans2setfilepathinfo() near line
3738 a check is made for the passed total_data size:
                case SMB_INFO_SET_EA:
                {
                        struct ea_list *ea_list = NULL;
                        TALLOC_CTX *ctx = NULL;

                        if (total_data < 10) {
                                return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
                        }

If total_data < 10, an error is flagged.
This assumption is _not_ always valid!

Some Background:
When os/2 calls DosSetPathInfo(), it first has to prepare 
an EAOP2 data structure. 

 typedef struct _EAOP2 {
   PGEA2LIST     fpGEA2List;  /*  GEA set. */
   PFEA2LIST     fpFEA2List;  /*  FEA set. */
   ULONG         oError;      /*  Offset of FEA error. */
 } EAOP2;

In our case PGEA2LIST is set NULL and PFEA2LIST must point to a
(usually) properly created FEA2LIST data area:

typedef struct _FEA2LIST {
   ULONG     cbList;   /*  Total bytes of structure including full list. */
   FEA2      list[1];  /*  Variable-length FEA2 structures. */
} FEA2LIST;

The point of interest here is, that _usually_ FEA2LIST must contain
at least _one_ FEA2 structure, as defined as the "list" struct member above.

So the struct member "cbList" must usually at least contain the value 10,
if an eaname with 1 char (plus following nul char) is used.

typedef struct _FEA2 {
   ULONG      oNextEntryOffset;  /*  Offset to next entry. */
   BYTE       fEA;               /*  Extended attributes flag. */
     /* 0 (not critical EA) or FEA_NEEDEA */
   BYTE       cbName;            /*  Length of szName, not including NULL. */
   USHORT     cbValue;           /*  Value length. */
   CHAR       szName[1];         /*  Extended attribute name. */
} FEA2;
The member "oNextEntryOffset" is not put onto the wire, so a valid FEA2
struct with an eaname of "A\0" has a size of 6 bytes, plus the size of
"cbList" itself from FEA2LIST, the minimum size on the wire seems to be 10!

BUT - the WPS (at least) uses a strange variation of this!
I have not seen any docu about that so far...!

The WPS simply sets "cbList" in FEA2LIST to a value of 4 (four), which
could friendly be interpreted as "no FEA2 stuff available at all". Huh.
And so a size of 4 is put onto the wire - and that SMB call should succeed!

So the sequence 
if (total_data < 10) {
     return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
must be expanded like:
if (total_data < 10) {
     if (total_data == 4) {
          /* special handling must be done */
          ....    /* to be filled in */
     } else {
          /* Hmm - maybe there are more special cases? */
          return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
     }
}

Jeremy, i coded a simple os2/2 test app, which does expose the bug and
the ethereal sniffs are _very_ short.
I will send 3 sniffs:
  - the failing one against samba3
  - an OK one taken against samba4
  - an OK one taken against w2k

I guess, when you look at the sniffs, it might be easy to code the
missing stuff.

Best wishes - Guenter
Comment 1 Guenter Kukkukk 2005-10-25 18:03:14 UTC
Created attachment 1537 [details]
sniffs contains the failing samba3 stuff
Comment 2 Guenter Kukkukk 2005-10-25 18:05:11 UTC
Created attachment 1538 [details]
this sniff is against samba4
Comment 3 Guenter Kukkukk 2005-10-25 18:05:56 UTC
Created attachment 1539 [details]
this sniff is against w2k
Comment 4 Guenter Kukkukk 2005-10-27 18:57:54 UTC
Hi again, 
 
as often - if an assumption is wrong - it will hit many places... 
 
I was just fumbling around with the workplace shell to copy 
somewhat larger directory trees. 
 
The function trans2mkdir() is also hit by the assumption, that 
"total_data" length should not be smaller than 10. 
Again, the WPS is sending the same strange length of 4 during 
the API call DosCreateDir(). 
To shorten the sniffs, i hacked a short os/2 test applet, which exposes 
the glitch. (btw - i know, that ethereal allows me to store selected frames, 
too). 
(hmm - i was already asked to collect all my simple os/2 test applets into 
an os/2 "smbtorture" test ... time will tell). :-) 
 
I will send 2 sniffs: 
  - the failing one against samba3 
  - the working one against w2k 
(As usual - they are _very_ short) 
 
Thx - Guenter 
 
 
Comment 5 Guenter Kukkukk 2005-10-27 19:02:26 UTC
Created attachment 1548 [details]
samba3 is failing during mkdir with unusual ea length of 4
Comment 6 Guenter Kukkukk 2005-10-27 19:04:27 UTC
Created attachment 1549 [details]
working stuff against w2k during mkdir with unusual ea length of 4
Comment 7 Jeremy Allison 2005-10-28 16:32:31 UTC
Ok, before I fix this I'd like to know the correct semantics here. When the
SET_EA is done with length 4 (ie. no ea's being sent) is this an implicit
"delete all existing EA's" ? It would make sense if so, otherwise it seems to be
a pointless network call.

Can you try your test program against a file with existing EA's and see if they
are removed please ?

Thanks,

Jeremy.
Comment 8 Jeremy Allison 2005-10-28 17:24:26 UTC
Created attachment 1551 [details]
Proposed patch

Can you try this patch please ? It should fix up trans2_open, trans2_mkdir and
trans2_setfilepathinfo to ignore these bogus EA values. I tested against W2K3
and an EA length of 4 doesn't truncate existing EA's.
Jeremy.
Comment 9 Guenter Kukkukk 2005-10-29 18:54:10 UTC
Hello Jeremy,

thanks for your work on this stuff. :-)

My very first guess with this strange WPS stuff was also "That is a
variation, to allow the deletion of _all_ EAs in one step!".
So that one was also my first check, when i did my 1st test...

Now I did that tests again. Neither on files nor on directories, this
ugly call seems to have _any_ effect!
It seems to be a NO-OP.

So atm I cannot talk about _any_ semantics behind this call...!  :-(
I'll further look at this - and also ask an old IBM OS/2 kernel guy about
it. (Unfortunately kernel != WPS, but he has all sources...)
-----

Secondly - I did apply your patch, and now both 2 errors are gone! :-)
I also have not seen any side effects so far due to your changes.
I now can copy really large trees with the WPS - not bad!

Unfortunately one cannot copy the whole OS/2 boot drive with the
WPS - some files (in use) are set to be "not readable" - bloody WPS then
stops and is undoing all former copy operation...
(The OS/2 boot drive is a good candidate - cause its files/dirs contain
lots of EAs)

But xcopy does a better job - it beeps in that case - and is going on.
Result (with no errors on the OS/2 side and no lines of samba3 DEBUG 0 output):
    474.930.916 bytes in 9.704 files and 4.138 dirs
copied fine. (with EAS enabled in smb.conf) :-)

So - I guess, you can commit your patch!

Best wishes - Guenter

----
Atm I have 2 leftover EA related (really ugly) bugs here...
I will soon post another one (which is not fixed in samba4, too)
Comment 10 Jeremy Allison 2005-11-02 23:25:15 UTC
This appears to be a no-op EA call.
Closing bug as we implement this correctly in HEAD and SAMBA_3_0 SVN,
Jeremy.