libsmbclient: Browsing and a URI spec?

Christopher R. Hertel crh at nts.umn.edu
Sun Dec 31 12:37:16 GMT 2000


> Hi,

Hello, Richard,

A good writeup.  Having thought a lot about this issue I have, of course, 
some comments.

> A very clear approach is:
> 
>    smb://              means list all servers in the current workgroup.
> 
>    smb://server/       means list all shares on server.
> 
>    smb://server/share  means list all directories in share on server.

The general thinking has been along these lines:

   smb://              is the top of the tree; list all workgroups

   smb://server/       server and workgroup names are mutually exclusive,
                       in a properly configured network so, if <server>#1D
                       resolves then ennumerate the browse list and if
                       <server>#20 resolves, then ennumerate the share
                       list.  More on this below.

   smb://server/share  means list all directories in share on server.

The advantage of this approach is that it represents the full hierarchy, 
starting at the workgroup/domain level and drilling down.  It also 
conforms to people'e expectations of how UNCs behave and how URLs behave.

The "shoehorning" occurs at the smb://server/ level.  The server, at this
level, is taken to mean either a browse list server (LMB or backup
browser) or a file server.  On a "properly configured network", these will
have mutually exclusive NetBIOS names.

An improper configuration, as described in rfc1001/1002, occurs when some
nodes on a local LAN use B mode name resolution and others use M or H mode
resolution.  In this case it is possible, though unlikely, that both
<server>#1D and <server>#20 will resolve.  That is, there will be a remote
server with a NetBIOS name that is the same as a workgroup name on the
local LAN.  This should never happen, since both workgroup#00 and
server#00 must be registered and these would conflict.  It can only occur
if there is a client that can see two separate NetBIOS name spaces. 

In this unlikely and misconfigured case, the simple work-arounds are:
  a) to list just the shares on <server>#20,
  b) to list both the browse list and the shares.

The latter might look like this:

Listing of FOOBAR:
    ARG     == smb://arg/
    FOOBAR  == smb://foobar/
    GOOB    == smb://goob/
    C       == smb://foobar/c/
    D       == smb://foobar/d/
    CDROM   == smb://foobar/cdrom/

As shown, it is not difficult to combine the two results.  Due to the
misconfiguration, the URL smb://foobar/ is overloaded but the results are
not problematic.  Further, depending upon how you build your library, an 
application programmer who uses your library could decided to
  a) return the list as shown,
  b) return only the share listing (second half of the above),
  c) return an error explaining that the network is broken.

(so, okay, I added a third work-around).

In any case, the above allows us to recreate all of the functionality of 
Microsoft's Network Neighborhood tool.

> As an aside, we should conform to RFC2396 and its URI syntax. This leads to
> a very natural addition of authentication information, as RFC2396 provides
> for 'userinfo', and provides a natural mechanism for specifying a username
> and password, although it cautions against passing such information over
> the wire [see below for comments on security].
> 
> A more complete form of the syntax, then might be:
> 
>   smb://[userinfo@][server[:port]][/share[/path[/file]]]

Rather:

  smb://[[userinfo@]server[:port][/share[/path][/file]]]

or possibly even

  smb://[[userinfo@]server[:port]/[share/[path/][file]]]

...though now I'm splitting hairs.

> where <userinfo> could be:
> 
>   [user[:password]]

Agreed.

> Unless I have misinterpreted RFC2396, my suggestions would be:
> 
>   [user[;domain][:password]]
> 
> or
> 
>   [user[+domain][:password]]

The consensus on the list was leaning towards:

  [domain;]user[:password]

thus:

  smb://[[[domain;]user[:password]@]server[:port]/[share/[path/][file]]]

> But I am open to suggestions.

Me too.

> Finally, however, the issue of workgroups/domains intrudes. These would be
> most naturally accomodated by supplanting the server down one level, eg:
> 
>   smb://[userinfo@][workgroup[/server[/share[/path[/file]]]]]
> 
> but this seems unnatural and the objection can be made that DNS-style
> domains are not browsed in this way with a normal URI, other mechanisms
> must be used to obtain the relevant list of domains.

There is an additional problem.  The server field has special syntax:

  [[domain;]user[:password]@]server[:port]

If the server field can be in the first *or* second position following the
double slashes, then how would one know which field contains the server? 
By (slightly) overloading the server field, allowing it to indicate either
a file server or a browse list server (a browser), this problem is solved. 

> Thus, my preference now is to exclude workgroups/domains from the URI
> syntax, and to use the URI syntax listed above, but I am prepared to listen
> to argument.

...and I am grateful to be able to provide it.  ;)

As you point out (and I was not aware--but I just checked it with an 
Ethereal trace and you are correct), the ennumeration of the browse list 
is an SMB call.  The overloading, then, is quite natural.  Here is the 
syntax in greater detail:

   smb://              is the top of the tree; list all workgroups.

   smb://workgroup/    list the servers within the workgroup.

   smb://server/       list the shares on the server.

   smb://server/share  means list all directories in share on server.

where workgroup means either a workgroup or an ntdomain.

> I would like to provide additional routines to list workgroups, but this
> itself may require the provision of authentication information, as the
> process of listing the workgroups requires a connection (NetBT) to the
> backup browser, and a TCON to the IPC$ share.  This may require a
> SessionSetup&X with a valid username and password pair.

Really?  Interesting.  I thought that ennumerating shares could be done 
anonymously.

No matter.  If the username and password are required then
smb://workgroup/ can also expand to smb://[userinfo@]server[:port]/
Indeed, smb://server/ and smb://workgroup/ are syntactically the same and
semantically very similar. 

> An open question at this stage is whether or not this authentication
> information should be provided using the callback facility already
> provided, or whether or not they should be passed in via parameters.

Since you are writing a library, I believe that it makes sense to offer a 
the tools to allow the application programmer to make that choice.  The 
URL parser will be able to parse out these fields:

user, domain, password,
server,
port,
share, path, file

It is the application programmer's responsibility to assure that all 
required information is collected.  (Will port ever be used?  Should be 
included anyway, I s'pose.)

> A NOTE ON NETBIOS NAMES
> 
> NetBIOS names are becoming increasingly obsolete. They are only required by
> older Microsoft OSes. Samba does not care about NetBIOS names (but does use
> them for virtual servers), and NT 4.0 (I believe) and certaily Win2000
> allows the use of *SMBSERVER as the called name.

This is not entirely true, as the browsing system is entirely based on
NetBIOS names.  It is true that DNS names can be used to reference file
servers, but on any NBT system the use of the DNS for name resolution is a
kludge. 

> Thus, <server> should be allowed to be a DNS name, with CALLED names being
> set to *SMBSERVER, or the first component of the DNS name, or perhaps with
> each being tried in turn.

MS tries each in turn, and I agree that this must be done.  IP addresses 
must also be allowed.  Note, though, that the browse list can only be 
accessed using the workgroup name (which is a NetBIOS name).

One further note regarding W2K and SMB native over TCP:
Under this new system, NetBIOS is not used at all.  Name resolution is 
DNS based, browsing is completely different, etc.  In one discussion here 
on the list the idea was put forth to use cifs:// to access SMB native 
over TCP.  Thus, the smb:// URI would indicate the use of NBT-based SMB, 
while cifs:// would indicate the use of W2K CIFS protocols.  This 
distinction makes sense to me and I recommend it.

Chris -)-----

-- 
Christopher R. Hertel -)-----                   University of Minnesota
crh at nts.umn.edu              Networking and Telecommunications Services

    Ideals are like stars; you will not succeed in touching them
    with your hands...you choose them as your guides, and following
    them you will reach your destiny.  --Carl Schultz





More information about the samba-technical mailing list