22.3 RAPture

Understand this at the outset: Examining a function of the RAP protocol is like studying the runic carvings on the lid of Pandora's box. They might just be large friendly letters ... or they could be the manufacturer's warning label.

We are not going to open the box.

The NetServerEnum2 function can be implemented without having to fully understand the inner workings of RAP, so there really is no need. If you want to, you can rummage around in the RAP functions by reading through Appendix B of the X/Open book Protocols for X/Open PC Interworking: SMB, Version 2 . After that, there is yet again another additional further Leach/Naik draft already. You can find the Leach/Naik CIFS Remote Administration Protocol Preliminary Draft under the filename cifsrap2.txt on Microsoft's FTP server. It is definitely a draft, but it provides a lot of good information if you read it carefully . One more resource a die-hard RAP-per will want to check is Remoted Net API Format Strings , which is an email message that was sent to Microsoft's CIFS mailing list by Paul Leach. It provides details on the formatting of RAP messages. All of these sources are, of course, listed in the References section.

One of the downsides of RAP, from our perspective, is that it defines yet another layer of parameters and data... and there's a heap, too.

Gotta love layers .

RAP provides a formula for marshalling its parameters, data, and heap, passing them over a network connection, and then passing the results back again. A complete RAP implementation would most likely automate the marshalling and unmarshalling process, and the human eye would never need to see it. That would be overkill in our case, so we're stuck doing things the easy way by hand.

RAP functions are sent via a Named Pipe, not a Mailslot, so the whole communications process is different. Like the Mailslot-based functions, RAP functions are packed into an SMBtrans transaction, but that's just about all that's really the same. The steps which must be followed in order to execute a RAP call are:

  • Open a TCP session.

    • NBT Session Request.

      • SMB Negotiate Protocol.

      • SMB Session Setup.

      • SMB Tree Connect (to \\ machine \IPC$ ).

        • RAP call and reply.

      • SMB Tree Disconnect (optional).

      • SMB Logoff (optional).

  • Close TCP session.

You can see all of this very clearly in a packet capture. Having a sniff handy as you read through this section is highly recommended, by the way. Don't forget to listen on 139/TCP instead of (or in addition to) 138/UDP.

22.3.1 NetServerEnum2 Request

You can generate a NetServerEnum2 exchange in a variety of ways. For example, you can refresh the server list in the Windows Network Neighborhood or use the jCIFS List.java utility with the URL " smb:// workgroup / ". The request, as displayed by the packet sniffer, should look something like this:

 + Transmission Control Protocol + NetBIOS Session Service + SMB (Server Message Block Protocol)   SMB Pipe Protocol - Microsoft Windows Lanman Remote API Protocol     Function Code: NetServerEnum2 (104)     Parameter Descriptor: WrLehDz     Return Descriptor: B16BBDz     Detail Level: 1     Receive Buffer Length: 65535     Server Type: 0xffffffff     Enumeration Domain: WORKGROUP 

The Descriptor fields are a distinctive feature of RAP requests . These are the cryptic runes of which we spoke earlier. They are format strings, used to define the structure of the parameters and data being sent as well as that expected in the reply. They can be used to automate the packing and unpacking of the packets, or they can be stuffed into the packet as constants with no regard to their meaning. The latter is the simpler course. With that in mind, here is the (simplified, but still correct) C-style format of a NetServerEnum2 request:

 struct   {   ushort RAPCode;   uchar *ParamDesc;   uchar *DataDesc;   struct     {     ushort InfoLevel;     ushort BufrSize;     ulong  ServerType;     uchar *Workgroup;     } Params;   } NetServerEnum2Req; 

So, given the above structure, the NetServerEnum2 request is filled in as shown below. Note that, at the SMBtrans-level, there are no Setup[] words, the Data[] section is empty, and all of the above structure is bundled into the Parameter[] block.

 smb_Transaction_Request   {   TotalParamCount   = 27 + strlen( Workgroup )   MaxParameterCount = 8   MaxDataCount      = <Size of the reply buffer>   Name              = "\PIPE\LANMAN"   Data     {     RAPCode         = 104 (0x0068)     ParamDesc       = "WrLehDz"     DataDesc        = "B16BBDz"     RAP_Params       {       InfoLevel     = 1 <See below>       BufrSize      = <Same as MaxDataCount>       ServerType    = <See below>       Workgroup     = <Name of the workgroup to list>       }     }   } 

A few of those fields need a little discussion.

TotalParamCount

The value 27 includes three short integers, one long integer, two constant strings (with lengths of 8 bytes each), and one nul byte to terminate the Workgroup field. That adds up to 27 bytes.

MaxDataCount and BufrSize

Samba allocates the largest size buffer it can (64 Kbytes minus one byte) to receive the response data. Other clients seem to have trouble with a 64K buffer, and will subtract a few bytes from the size. 64K minus 360 bytes has been seen, and jCIFS uses 64K minus 512 bytes.

Email

graphics/email.gif

 From: Allen, Michael B   To: jcifs@samba.org I think I just made it up. I found 0xFFFF would result in errors. I never really investigated why. 

InfoLevel

There are two InfoLevel s available: 0 and 1. Level 0 is not very interesting. Note that if you want to try level 0, you will need to change the DataDesc string as well.

ServerType

There are two common values used in the request message. They are:

 SV_TYPE_DOMAIN_ENUM == 0x80000000 SV_TYPE_ALL         == 0xFFFFFFFF 

The first is used to query the browser for the list of all known workgroups. The second is used to query for a list of all known Providers in the specified (or default) workgroup.

Note that these are not the only allowed values. When we cover the reply message ( next section) there will be a table of all known bit values. Queries for specific subsets of Providers can be generated using these bits.

Workgroup

In many cases, this will be an empty string (just a nul byte). An empty Workgroup field represents a request to list the Providers that are members of the browser's default workgroup. That means, of course, that the browser being queried must have a default workgroup.

This results in an interesting problem. Since the workgroup name is not always specified, a single system cannot (on a single IP address) be the LMB for more than one workgroup. If a node were to become the LMB for multiple workgroups, then it would not know which set of servers to report in response to a NetServerEnum2 query with an empty workgroup name.

...and that is "all you need to know" about the NetServerEnum2 request message.

22.3.2 NetServerEnum2 Reply

The response message is a bit more involved, so you may want to take notes. A packet capture, once again, is a highly recommended visual aide.

Starting at the top... The TotalParamCount field in the SMBtrans reply message will have a value of 8, indicating the size of the SMBtrans-level Parameter[] block. Those bytes fall out as follows :

 struct   {   ushort Status;      /* Error Code        */   ushort Convert;     /* See below         */   ushort EntryCount;  /* Entries returned  */   ushort AvailCount;  /* Entries available */   } 

Status

An error code. Available codes are listed in the Leach/Naik Browser draft.

Convert

More on this in a moment, when we get to the Data[] block.

EntryCount

The number of entries returned in the reply.

AvailCount

The number of available entries. This may be more than the number in EntryCount , in which case there are more entries than will fit in the data buffer length given in the request.

That's all there is to the Parameter[] block. It's nicely simple, but things get a little wilder as we move on. Do keep track of that Convert value...

The SMB-level Data[] block will start with a series of ServerInfo_1 structures, as described below:

 struct   {   uchar  Name[16];      /* Provider name     */   uchar  OSMajorVers;   /* Provider OS Rev   */   uchar  OSMinorVers;   /* Provider OS Point */   ulong  ServerType;    /* See below         */   uchar *Comment;       /* Pointer           */   } ServerInfo_1; 

There will be <EntryCount> such structures packed neatly together. It is fairly easy to parse them out, because the Name field is a fixed-length, nul- padded string and the Comment field really is a pointer. The Leach/Naik Browser draft suggests that the Comment strings themselves may follow each ServerInfo_1 structure, but all examples seen on the wire show four bytes. Hang on to those four bytes... we'll explain in a moment.

Anywhich, the above structure has a fixed length 26 bytes, to be precise. That makes it easy to parse ServerInfo_1 structures from the Data[] block.

The values in the ServerInfo_1 are the same ones announced by the Provider in its HostAnnouncement or DomainAnnouncement frames . They are stored in an internal database on the browser node. Some of these fields have been discussed before, but a detailed description of the ServerType field has been postponed at every opportunity. Similarly, the pointer value in the Comment field really needs some clarification .

Let's start with the Comment pointer...

The Comment pointer may just possibly be a relic of the long lost days of DOS. Those who know more about 16-bit DOS internals may judge. In any case, what you need to do is this:

  • Read the Comment pointer from the ServerInfo_1 structure.

  • Remove the two higher-order bytes: Comment & 0x0000FFFF .

  • Subtract the value of the Convert field: offset = (Comment & 0x0000FFFF) - Convert .

  • Use the resulting offset to find the actual Comment string. The offset is relative to the start of the SMBtrans Data[] block.

Well that was easy. This stuff is so lovable you just want to give it a hug, don't you?

Some further notes:

  • The Comment strings are stored in the RAP-level heap.

  • The ServerInfo_1 blocks are considered RAP-level "data."

  • Both of those are collected into the SMBtrans-level Data[] block.

  • Just to make things simple, the RAP-level parameters are gathered into the SMBtrans Parameter[] block.

Right... Having tilted that windmill, let's take a look at the (more sensible , but also much more verbose) ServerType field. We have delayed describing this field for quite a while. Here, finally, it is... well, mostly. The list below is based on Samba sources. It is close to Ethereal's list, and less close to the list given in the Leach/Naik draft. Let the buyer beware.

Browser Provider type bits

Bit

Name / Bitmask

Description

31

SV_TYPE_DOMAIN_ENUM 0x80000000

Enumerate Domains. This bit is used in the request to ask for a list of known workgroups instead of a list of Providers in a workgroup.

30

SV_TYPE_LOCAL_LIST_ONLY 0x40000000

This bit identifies entries for which the browser is authoritative . That is, it is set if the Provider (or workgroup) entry was received via an announcement message, and clear if the entry is the result of a sync with the DMB.

29

SV_TYPE_ALTERNATE_XPORT 0x20000000

No one seems to remember where this came from or what it means. Ethereal doesn't know about it.

2824

0x1F000000

Unused.

23

SV_TYPE_DFS_SERVER 0x00800000

The Provider offers DFS shares. Possibly a DFS root.

22

SV_TYPE_WIN95_PLUS 0x00400000

Indicates a Provider that considers itself to be in the Windows 9x family.

21

SV_TYPE_SERVER_VMS 0x00200000

Indicates a VMS (Pathworks) server.

20

SV_TYPE_SERVER_OSF 0x00100000

Indicates an OSF Unix server.

19

SV_TYPE_DOMAIN_MASTER 0x00080000

Indicates a Domain Master Browser (DMB).

18

SV_TYPE_MASTER_BROWSER 0x00040000

Indicates a Local Master Browser (LMB).

17

SV_TYPE_BACKUP_BROWSER 0x00020000

Indicates a Backup Browser...

16

SV_TYPE_POTENTIAL_BROWSER 0x00010000

...and, of course, a Potential Browser.

15

SV_TYPE_SERVER_NT 0x00008000

Indicates a Windows NT Server.

14

SV_TYPE_SERVER_MFPN 0x00004000

Unknown. Ethereal ignores this one, and it's not listed in the Leach/Naik Browser draft.

13

SV_TYPE_WFW 0x00002000

Windows for Workgroups.

12

SV_TYPE_NT 0x00001000

A Windows NT client.

11

SV_TYPE_SERVER_UNIX 0x00000800

An SMB server running Xenix or Unix. Samba will set this bit when announcing its services.

10

SV_TYPE_DIALIN_SERVER 0x00000400

The Provider offers dial-up services (e.g. NT RAS).

9

SV_TYPE_PRINTQ_SERVER 0x00000200

The Provider has printer services available.

8

SV_TYPE_DOMAIN_MEMBER 0x00000100

The Provider is a member of an NT Domain. That means that the Provider itself has authenticated to the NT Domain.

7

SV_TYPE_NOVELL 0x00000080

The Provider is a Novell server offering SMB services. This is probably used with SMB over IPX/SPX, but may be set by Novell's SMB implementation as well.

6

SV_TYPE_AFP 0x00000040

The Provider is an Apple system. Thursby's Dave product and Apple's SMB implementation may set this bit.

5

SV_TYPE_TIME_SOURCE 0x00000020

The Provider offers SMB time services. (Yes, there is an SMB-based time sync service.)

4

SV_TYPE_DOMAIN_BAKCTRL 0x00000010

The Provider is a Backup Domain Controller (BDC).

3

SV_TYPE_DOMAIN_CTRL 0x00000008

The Provider is a Domain Controller.

2

SV_TYPE_SQLSERVER 0x00000004

The Provider offers SQL services.

1

SV_TYPE_SERVER 0x00000002

The Provider offers SMB file services.

SV_TYPE_WORKSTATION 0x00000001

This bit indicates that the system is a workstation. (Just about everything sets this bit.)

Just to polish this subject off, here's a little code that can parse a NetServerEnum2 response message and print the results:

Listing 22.3 Parsing NetServerEnum2 Replies
 #define NERR_Success 0 #define SV_TYPE_ALL               0xFFFFFFFF #define SV_TYPE_UNKNOWN           0x1F000000 #define SV_TYPE_DOMAIN_ENUM       0x80000000 #define SV_TYPE_LOCAL_LIST_ONLY   0x40000000 #define SV_TYPE_ALTERNATE_XPORT   0x20000000 #define SV_TYPE_DFS_SERVER        0x00800000 #define SV_TYPE_WIN95_PLUS        0x00400000 #define SV_TYPE_SERVER_VMS        0x00200000 #define SV_TYPE_SERVER_OSF        0x00100000 #define SV_TYPE_DOMAIN_MASTER     0x00080000 #define SV_TYPE_MASTER_BROWSER    0x00040000 #define SV_TYPE_BACKUP_BROWSER    0x00020000 #define SV_TYPE_POTENTIAL_BROWSER 0x00010000 #define SV_TYPE_SERVER_NT         0x00008000 #define SV_TYPE_SERVER_MFPN       0x00004000 #define SV_TYPE_WFW               0x00002000 #define SV_TYPE_NT                0x00001000 #define SV_TYPE_SERVER_UNIX       0x00000800 #define SV_TYPE_DIALIN_SERVER     0x00000400 #define SV_TYPE_PRINTQ_SERVER     0x00000200 #define SV_TYPE_DOMAIN_MEMBER     0x00000100 #define SV_TYPE_NOVELL            0x00000080 #define SV_TYPE_AFP               0x00000040 #define SV_TYPE_TIME_SOURCE       0x00000020 #define SV_TYPE_DOMAIN_BAKCTRL    0x00000010 #define SV_TYPE_DOMAIN_CTRL       0x00000008 #define SV_TYPE_SQLSERVER         0x00000004 #define SV_TYPE_SERVER            0x00000002 #define SV_TYPE_WORKSTATION       0x00000001 typedef struct   {   ushort Status;   ushort Convert;   ushort EntryCount;   ushort AvailCount;   } NSE2_ReplyParams; void PrintBrowserBits( ulong ServerType )   /* ---------------------------------------------------- **    * Itemize Browse Service Provider Type Bits.    * This is boring, and could probably be done better    * using an array and a for() loop.    * ---------------------------------------------------- **    */   {   if( SV_TYPE_ALL == ServerType )     {     printf( "  All/Any Server types.\n" );     return;     }   if( SV_TYPE_UNKNOWN & ServerType )     printf( "  Warning: Undefined bits set.\n" );   if( SV_TYPE_DOMAIN_ENUM & ServerType )     printf( "  Enumerate Domains\n" );   if( SV_TYPE_LOCAL_LIST_ONLY & ServerType )     printf( "  Local List Only\n" );   if( SV_TYPE_ALTERNATE_XPORT & ServerType )     printf( "  Alternate Export (Unknown type)\n" );   if( SV_TYPE_DFS_SERVER & ServerType )     printf( "  DFS Support\n" );   if( SV_TYPE_WIN95_PLUS & ServerType )     printf( "  Windows 95+\n" );   if( SV_TYPE_SERVER_VMS & ServerType )     printf( "  VMS (Pathworks) Server\n" );   if( SV_TYPE_SERVER_OSF & ServerType )     printf( "  OSF Unix Server\n" );   if( SV_TYPE_DOMAIN_MASTER & ServerType )     printf( "  Domain Master Browser\n" );   if( SV_TYPE_MASTER_BROWSER & ServerType )     printf( "  Local Master Browser\n" );   if( SV_TYPE_BACKUP_BROWSER & ServerType )     printf( "  Backup Browser\n" );   if( SV_TYPE_POTENTIAL_BROWSER & ServerType )     printf( "  Potential Browser\n" );   if( SV_TYPE_SERVER_NT & ServerType )     printf( "  Windows NT (or compatible) Server\n" );   if( SV_TYPE_SERVER_MFPN & ServerType )     printf( "  MFPN (Unkown type)\n" );   if( SV_TYPE_WFW & ServerType )     printf( "  Windows for Workgroups\n" );   if( SV_TYPE_NT & ServerType )     printf( "  Windows NT Workstation\n" );   if( SV_TYPE_SERVER_UNIX & ServerType )     printf( "  Unix/Xenix/Samba Server\n" );   if( SV_TYPE_DIALIN_SERVER & ServerType )     printf( "  Dialin Server\n" );   if( SV_TYPE_PRINTQ_SERVER & ServerType )     printf( "  Print Server\n" );   if( SV_TYPE_DOMAIN_MEMBER & ServerType )     printf( "  NT Domain Member Server\n" );   if( SV_TYPE_NOVELL & ServerType )     printf( "  Novell Server\n" );   if( SV_TYPE_AFP & ServerType )     printf( "  Apple Server\n" );   if( SV_TYPE_TIME_SOURCE & ServerType )     printf( "  Time Source\n" );   if( SV_TYPE_DOMAIN_BAKCTRL & ServerType )     printf( "  Backup Domain Controller\n" );   if( SV_TYPE_DOMAIN_CTRL & ServerType )     printf( "  Domain Controller\n" );   if( SV_TYPE_SQLSERVER & ServerType )     printf( "  SQL Server\n" );   if( SV_TYPE_SERVER & ServerType )     printf( "  SMB Server\n" );   if( SV_TYPE_WORKSTATION & ServerType )     printf( "  Workstation\n" );   } /* PrintBrowserBits */ void PrintNetServerEnum2Reply( uchar *ParamBlock,                                int    ParamLen,                                uchar *DataBlock,                                int    DataLen )   /* ---------------------------------------------------- **    * Parse a NetServerEnum2 Reply and print the contents.    * ---------------------------------------------------- **    */   {   NSE2_ReplyParams Rep;   int              i;   int              offset;   uchar           *pos;   /* Check for an obvious error.    */   if( ParamLen != 8 )     Fail( "Error parsing NetServerEnum2 reply.\n" );   /* Grab all of the parameter words.    */   Rep.Status     = smb_GetShort( ParamBlock, 0 );   Rep.Convert    = smb_GetShort( ParamBlock, 2 );   Rep.EntryCount = smb_GetShort( ParamBlock, 4 );   Rep.AvailCount = smb_GetShort( ParamBlock, 6 );   /* Check for problems (errors and warnings).    */   if( Rep.Status != NERR_Success )     Fail( "NetServerEnum2 Error: %d.\n", Rep.Status );   if( Rep.EntryCount < Rep.AvailCount )     printf( "Warning: The list is incomplete.\n" );   /* Dump the ServerInfo_1 records. */   pos = DataBlock;   for( i = 0; i < Rep.EntryCount; i++ )     {     printf( "%-15s V%d.%d\n", pos, pos[16], pos[17] );     PrintBrowserBits( smb_GetLong( pos, 18 ) );     offset  = 0x0000FFFF & smb_GetLong( pos, 22 );     offset -= Rep.Convert;     if( offset >= DataLen )       Fail( "Packet offset error.\n" );     printf( "  Comment: %s\n", (DataBlock + offset) );     pos += 26;     }   } /* PrintNetServerEnum2Reply */ 

22.3.3 On the Outskirts of Town

There is another RAP call that you need to know about. It comes in handy at times. It doesn't really belong to the Browse Service, but you may have heard its name mentioned in that context. It lives on the edge, somewhere between browsing and filesharing, and it goes by the name NetShareEnum .

The NetShareEnum RAP call does the job of listing the shares offered by a server. The shares, as you already know, are the virtual roots of the directory trees made available via SMB.

The wire format of the request is as follows:

 struct   {   ushort RAPCode;   uchar *ParamDesc;   uchar *DataDesc;   struct     {     ushort InfoLevel;     ushort BufrSize;     } Params;   } NetShareEnumReq; 

and it is filled in like so:

 NetShareEnumReq   {   RAPCode   = 0 (NetShareEnum)   ParamDesc = "WrLeh"   DataDesc  = "B13BWz"   Params     {     InfoLevel = 1 (No other values defined)     BufrSize  = <Same as smb_Transaction_Request.MaxDataCount>     }   } 

Yes, the RAP code for NetShareEnum is zero ( ).

There's not much to that call, particularly once you've gotten the NetServerEnum2 figured out. The response also contains some familiar concepts. In fact, the Parameter[] section is exactly the same.

The RAP-level data section is supposed to contain an array of ShareInfo_1 structures, which look like this:

 struct   {   uchar  ShareName[13];   uchar  pad;   ushort ShareType;   uchar *Comment;   } ShareInfo_1; 

Again, there are many similarities to what we have seen before. In this case, though, the ShareType field has a smaller set of possible values than the comparable ServerType field.

Share type values

Name

Value

Description

STYPE_DISKTREE

A disk share (root of a directory tree).

STYPE_PRINTQ

1

A print queue.

STYPE_DEVICE

2

A communications device (e.g. a modem).

STYPE_STYPE

3

An Inter-Process Communication (IPC) share.

...and that is "all you need to know" about the NetShareEnum call. Oh, wait... There is one more thing...

Can't Get It Out Of My Head Alert

graphics/alert.gif

There is one great big warning regarding the NetShareEnum response. Some Windows systems have been seen returning parameter blocks that are very large (e.g. 1024 bytes). The first eight bytes contain the correct values. The rest appear to be left-over cruft from the buffer on the server side. The server is returning the buffer size (and the whole buffer) rather than the Parameter[] block size .

Other transactions may exhibit similar behavior .


22.3.4 Transaction Fragmentation

A promise is a promise, and we did promise to cover fragmented transactions. [2]

[2] Maybe we could cover them with leaves and fallen branches and just let them compost themselves quietly in an out-of-the-way place or something.

The idea is fairly simple. If you have twenty-five sacks of grain to bring to town, and a wagon that can hold only twelve sacks, then you will need to make a few trips. Likewise with transactions. Due to the limits of the negotiated buffer size, a transaction may attempt to transfer more data than can be carried in a single SMB. The solution is to split up the data and send it using multiple SMB messages.

The mechanism used is the same for SMBtrans, Trans2, and NTtrans. There are slight differences between the transaction request and transaction response, though, so pay attention.

Sending a fragmented transaction request works like this:

Fill in the transaction SMB, packing as many Parameter[] and Data[] bytes into the transaction as possible. Parameter[] bytes have precedence over Data[] bytes.

Send the initial message and wait for a reply (known as the "Interim Server Response"). This step is a shortcut. It gives the server a chance to reject the transaction before it has been completely transferred. Only the response header has any meaning. If there is no error, the transaction may proceed.

Send as many secondary transaction messages as necessary to transfer the remaining Parameter[] and Data[] bytes. Note that the SMB command and structure of secondary transactions is not the same as those of the initial message.

Wait for the server to execute the transaction and return the results.

Now go back and take a look at Listing 22.1. Note that the smb_Transaction_Request structure keeps track of the number of Parameter[] and Data[] bytes already packed for shipping. That makes it easy to build the secondary messages should they be needed.

Fragmenting a transaction response is a simpler process. The response SMBs all have the same structure (no special secondary messages) and they all have an SMB header, which may contain an error code if necessary. So, the server can just send as many transaction response SMBs as needed to transfer all of the results. That's it.

22.3.5 RAP Annoyances

RAP can be quite annoying that's just its nature. There are two particular annoyances of which you should be aware:

Authentication

It is common for a server to deny a NetShareEnum request on an anonymous SMB connection. A valid username/password pair may be required. Some servers also require non-anonymous authentication for the NetServerEnum2 request, though this is less common.

Limitations and Permutations

Grab a capture of a NetShareEnum request and take a look at the data descriptor string for the returned data (which should be "B13BWz", as described above). The number 13 in the string indicates the maximum length of the share names to be returned, and it includes the terminating nul byte.

"B13BWz" means that the NetShareEnum function will not return share names with a string length greater than 12 characters each. Of course, there are many systems that can offer shares with names longer than 12 characters . Thus, we have a problem.

One way to solve the problem would be to change the field size in the descriptor string to, for example, something like "B256BWz". That trick isn't likely to work against all servers, however, because the descriptor strings are constant enough that some implementations probably ignore them. Another option is to use short share names, but that only works if you have control over all of the SMB servers in the network.

The prescribed solution is to use a different function, called Net r ShareEnum . Note that there's an extra letter 'r' hidden in there. Also note that the Net r ShareEnum function is an MS-RPC call, not a RAP call, and thus is beyond the scope of this book. You can watch for it in packet captures, however, and possibly consider it as a starting point should you decide to explore the world of MS-RPC.

So, now you know.



Implementing CIFS. The Common Internet File System
Implementing CIFS: The Common Internet File System
ISBN: 013047116X
EAN: 2147483647
Year: 2002
Pages: 210

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net