libsmbclient and smb_opendir: problem with workgroup

Derrell.Lipman at UnwiredUniverse.com Derrell.Lipman at UnwiredUniverse.com
Sun Jun 13 20:16:21 GMT 2004


"Christopher R. Hertel" <crh at ubiqx.mn.org> writes:

>> IIRC, if you specify a workgroup, then that workgroup's master browser will
>> be given your request, whereas if you give SOMEGARBAGE as the workgroup, it
>> will discover workgroups and use the first one discovered, which would
>> explain why your request works in one case but not the other (although if
>> it happened to find the master browser for MYGROUP first and that master
>> browser doesn't have the other browse lists, it wouldn't work even though
>> you specified SOMEGARBAGE).
>
> Hang on...  I *think* what you're saying is this:
> - If the LMB for the default workgroup cannot be found, libsmbclient will 
>   query for the __MSBROWSE__ name and then query each respondent in turn 
>   for its workgroup list.
>
> Is that right?

Yes and no.  In the current implementation, IIRC, it will query for
__MSBROWSE__ and then query one of the respondents for its workgroup list.  My
modification add the ability to query each respondent in turn.

> Note that doing so won't work in P mode.  In P mode, you might *try* 
> querying the NBNS for *<1B> and hope there's a Samba NBNS on the other 
> end.  If that fails, then the only option you have is to query for the DMB 
> for your workgroup.

That sounds correct.  I've never been in a P mode environment so have had no
way to verify it, but in theory that is correct and additional improvements
could be made.

> In B, M, or H mode you can query for the __MSBROWSE__ name.  Sending the 
> NetServerEnum() request to each responding node could be time consuming, 
> especially if the list is long (which is unlikely...geez that would be a 
> messy network).

Yup, however "time consuming" is relative. :-) I'd rather have the option of
taking more time to obtain a complete list, than taking very little time
obtaining an incomplete list, which is what was happening regularly prior to
adding and using this option.

>> smbclient has not been modified to use the new feature that I added to
>> libsmbclient a number of months ago, which solves this problem.  The new
>> feature allows smbc_opendir("smb://?mb=.all") to look at all master browsers
>> that can be discovered, rather than only the first one found, in order to
>> discover all workgroups on the network.
>
> Ouch!  There is no "mb" key in the SMB URI draft (and I won't be adding
> one), and there is no definition for ".all".  The syntax above is broken 
> and shouldn't be in that code.  The better approach is to do a bit of 
> thinking within the code to ensure that smbc_opendir( "smb://" ) returns 
> a useful workgroup list.

Broken is a bit harsh.  URI syntax, particularly what comes after the question
mark, is generally extensible.  That not withstanding, the majority of my past
work has been in working with standards, and I'd love to find a way to provide
the same functionality with no required extentions.

> The SMB URI syntax purposfully avoids making any assumption about client
> configuration, including the default workgroup.  This is done in order to
> avoid sensitivity to a particular context.  The URI string "smb://" means
> "all available workgroups".  How that is interpreted is up to the
> implementation writer.

It sounds like you are saying that the current implementation is wrong if it
doesn't show "all available workgroups" with a URI sting of only "smb://".  As
you have stated earlier, though, it can be "time consuming" to do "properly".
I left the default as the way it had been doing it (first master browser
found) because I didn't want to change the behavior of existing applications.
For my own purposes, I'd have no problem with always requesting the browse
list from all discovered master browsers since I'm much more concerned with
getting a complete list than with how long it takes.  (In practice, unless
there are many workgroups, the added time isn't huge, but it is slightly
noticeable.)

> You have some good ideas about how to gather a workgroup list.  There's no 
> reason to add a non-spec syntax.

I'm with you.  You wrote the book (wonderful) on this stuff, so you're the
expert. :-)  What are your suggestions?

>> For backwards compatibility,
>> smbc_opendir("smb://") operates as it always did, requesting the browse list
>> only from the first master browser found.
>
> This could be extended without having to add non-spec syntax.  Again, the 
> URI draft doesn't say that the default workgroup should be used.  How the 
> list of workgroups is obtained is completely up to the client 
> implementation.

Other than extending the syntax, the alternate method that comes to mind is an
additional function call, e.g.

  typedef enum SMBC_BrowseMode
  {
      /* Obtain browse list from first master browser discovered */
      SMBC_BrowseMode_Any,

      /* Obtain and merge browse lists from each discovered master browser */
      SMBC_BrowseMode_All
  };

  /*
   * For backwards compatibility, use browse list from first discovered
   * master browser.
   */
  static SMBC_BrowseMode        browseMode = SMBC_BrowseMode_Any;

  void smbc_set_browse_mode(SMBC_BrowseMose bm)
  {
      browseMode = bm;
  }

Note that this does not allow the additional syntax I had added (mb=NAME) to
request the browse list from a specific master browser.  BTW, that's the
reason that I used mb=.any and mb=.all leaving any name not beginning with a
dot as the name of the master browser to query.  Since dot is the one (and I
think only) character that a name may not begin with, this seemed a reasonable
approach.  I supose we could also add a third enum value,
SMBC_BrowseMode_Specific, and then provide:

  static char *   userRequestedMasterBrowser = NULL;

  void smbc_set_master_browser(char * masterBrowser)
  {
      browseMode = SMBC_BrowseMode_Specific;
      userRequestedMasterBRowser = masterBrowser;
  }

> The underlying problems here are in the behavior of the protocol.  There 
> is no perfect fix.  The Browse Service is sloppy, but it does (eventually) 
> sort itself out.

That's all I'm trying to do.  My problem is in the "but it does (eventually)
sort itself out" part.  I can't wait the 12+ minutes for that to happen.  I
suspected, and the email to which I replied seemed to confirm, that I'm not
alone. :-)

> We know how it all works, so we should be able to tweak the code to produce
> reasonable results.

Great.  Do you prefer my above-listed alternate approach?

Is there a relatively simple way to get this working in P mode as well?

Cheers,

Derrell


More information about the samba-technical mailing list